CIndexCodeCompletion.cpp revision 32be4a588fbb87d0d163ead49c42f5438bf0b2b7
1ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek//===- CIndexCodeCompletion.cpp - Code Completion API hooks ---------------===//
2ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek//
3ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek//                     The LLVM Compiler Infrastructure
4ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek//
5ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// This file is distributed under the University of Illinois Open Source
6ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// License. See LICENSE.TXT for details.
7ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek//
8ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek//===----------------------------------------------------------------------===//
9ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek//
10ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// This file implements the Clang-C Source Indexing library hooks for
11ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek// code completion.
12ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek//
13ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek//===----------------------------------------------------------------------===//
14ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
15ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "CIndexer.h"
16936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor#include "CIndexDiagnostic.h"
17b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Basic/SourceManager.h"
18b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Basic/FileManager.h"
191abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#include "clang/Frontend/ASTUnit.h"
20b846debc1b22a37228efe4aa87b34482d15b6a3cBenjamin Kramer#include "clang/Frontend/CompilerInstance.h"
21936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor#include "clang/Frontend/FrontendDiagnostic.h"
22ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "clang/Sema/CodeCompleteConsumer.h"
23df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor#include "llvm/ADT/SmallString.h"
24ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "llvm/ADT/StringExtras.h"
25b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar#include "llvm/Support/CrashRecoveryContext.h"
26ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "llvm/Support/MemoryBuffer.h"
27df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor#include "llvm/Support/Timer.h"
28df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor#include "llvm/Support/raw_ostream.h"
29ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "llvm/System/Program.h"
303d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor#include <cstdlib>
313d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor#include <cstdio>
32ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
33df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
34da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER
35da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#include "clang/Basic/Version.h"
36da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#include <arpa/inet.h>
37da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#include <sys/socket.h>
38da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#include <sys/types.h>
39da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#include <unistd.h>
40da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
41da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
42ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekusing namespace clang;
432ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenekusing namespace clang::cxstring;
44ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
4512e131385e892e3723483a1081a89bcad29c8a84Douglas Gregornamespace {
4612e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  /// \brief Stored representation of a completion string.
4712e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  ///
4812e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  /// This is the representation behind a CXCompletionString.
4912e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  class CXStoredCodeCompletionString : public CodeCompletionString {
5012e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    unsigned Priority;
5158ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor    CXAvailabilityKind Availability;
5212e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
5312e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  public:
5458ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor    CXStoredCodeCompletionString(unsigned Priority,
5558ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor                                 CXAvailabilityKind Availability)
5658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor      : Priority(Priority), Availability(Availability) { }
5712e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
5812e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    unsigned getPriority() const { return Priority; }
5958ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor    CXAvailabilityKind getAvailability() const { return Availability; }
6012e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  };
6112e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor}
6212e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
63ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekextern "C" {
64ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
65ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekenum CXCompletionChunkKind
66ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekclang_getCompletionChunkKind(CXCompletionString completion_string,
67ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                             unsigned chunk_number) {
6812e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
6912e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
70ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (!CCStr || chunk_number >= CCStr->size())
71ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Text;
72ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
73ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  switch ((*CCStr)[chunk_number].Kind) {
74ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_TypedText:
75ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_TypedText;
76ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Text:
77ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Text;
78ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Optional:
79ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Optional;
80ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Placeholder:
81ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Placeholder;
82ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Informative:
83ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Informative;
84ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_ResultType:
85ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_ResultType;
86ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_CurrentParameter:
87ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_CurrentParameter;
88ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftParen:
89ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_LeftParen;
90ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightParen:
91ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_RightParen;
92ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBracket:
93ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_LeftBracket;
94ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBracket:
95ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_RightBracket;
96ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBrace:
97ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_LeftBrace;
98ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBrace:
99ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_RightBrace;
100ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftAngle:
101ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_LeftAngle;
102ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightAngle:
103ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_RightAngle;
104ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Comma:
105ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Comma;
10601dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Colon:
10701dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_Colon;
10801dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_SemiColon:
10901dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_SemiColon;
11001dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Equal:
11101dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_Equal;
11201dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_HorizontalSpace:
11301dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_HorizontalSpace;
11401dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_VerticalSpace:
11501dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_VerticalSpace;
116ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
117ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
118ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Should be unreachable, but let's be careful.
119ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  return CXCompletionChunk_Text;
120ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
121ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
1222ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed KremenekCXString clang_getCompletionChunkText(CXCompletionString completion_string,
1232ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek                                      unsigned chunk_number) {
12412e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
12512e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
126ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (!CCStr || chunk_number >= CCStr->size())
1272ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek    return createCXString(0);
128ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
129ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  switch ((*CCStr)[chunk_number].Kind) {
130ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_TypedText:
131ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Text:
132ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Placeholder:
133ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_CurrentParameter:
134ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Informative:
135ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftParen:
136ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightParen:
137ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBracket:
138ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBracket:
139ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBrace:
140ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBrace:
141ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftAngle:
142ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightAngle:
143ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Comma:
144ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_ResultType:
14501dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Colon:
14601dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_SemiColon:
14701dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Equal:
14801dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_HorizontalSpace:
14921c241ff68c18ad87e1f18a579c535385aec7af1Douglas Gregor  case CodeCompletionString::CK_VerticalSpace:
1505a9c0bca4504eeda45a3fd0ae1c244b2994f38b2Douglas Gregor    return createCXString((*CCStr)[chunk_number].Text, false);
15121c241ff68c18ad87e1f18a579c535385aec7af1Douglas Gregor
152ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Optional:
153ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    // Note: treated as an empty text block.
1542ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek    return createCXString("");
155ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
156ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
157ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Should be unreachable, but let's be careful.
1582ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek  return createCXString(0);
159ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
160ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
1612ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek
162ab1889321f6f8f200f2b318ac26883ac18e49d03Ted KremenekCXCompletionString
163ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekclang_getCompletionChunkCompletionString(CXCompletionString completion_string,
164ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                         unsigned chunk_number) {
16512e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
16612e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
167ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (!CCStr || chunk_number >= CCStr->size())
168ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return 0;
169ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
170ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  switch ((*CCStr)[chunk_number].Kind) {
171ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_TypedText:
172ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Text:
173ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Placeholder:
174ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_CurrentParameter:
175ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Informative:
176ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftParen:
177ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightParen:
178ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBracket:
179ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBracket:
180ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBrace:
181ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBrace:
182ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftAngle:
183ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightAngle:
184ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Comma:
185ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_ResultType:
18601dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Colon:
18701dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_SemiColon:
18801dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Equal:
18901dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_HorizontalSpace:
19001dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_VerticalSpace:
191ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return 0;
192ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
193ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Optional:
194ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    // Note: treated as an empty text block.
195ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return (*CCStr)[chunk_number].Optional;
196ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
197ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
198ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Should be unreachable, but let's be careful.
199ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  return 0;
200ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
201ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
202ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekunsigned clang_getNumCompletionChunks(CXCompletionString completion_string) {
20312e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
20412e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
205ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  return CCStr? CCStr->size() : 0;
206ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
207ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
20812e131385e892e3723483a1081a89bcad29c8a84Douglas Gregorunsigned clang_getCompletionPriority(CXCompletionString completion_string) {
20912e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
21012e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
211a2ace58cf99f9279a7467d987c6094145dd19d8bBill Wendling  return CCStr? CCStr->getPriority() : unsigned(CCP_Unlikely);
21212e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor}
21312e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
21458ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregorenum CXAvailabilityKind
21558ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregorclang_getCompletionAvailability(CXCompletionString completion_string) {
21658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor  CXStoredCodeCompletionString *CCStr
21758ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
21858ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor  return CCStr? CCStr->getAvailability() : CXAvailability_Available;
21958ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor}
22058ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor
221ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekstatic bool ReadUnsigned(const char *&Memory, const char *MemoryEnd,
222ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                         unsigned &Value) {
223ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (Memory + sizeof(unsigned) > MemoryEnd)
224ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return true;
225ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
226ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  memmove(&Value, Memory, sizeof(unsigned));
227ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  Memory += sizeof(unsigned);
228ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  return false;
229ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
230ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
231ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek/// \brief The CXCodeCompleteResults structure we allocate internally;
232ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek/// the client only sees the initial CXCodeCompleteResults structure.
233ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekstruct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
2340a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  AllocatedCXCodeCompleteResults();
2350a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  ~AllocatedCXCodeCompleteResults();
2360a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
237a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  /// \brief Diagnostics produced while performing code completion.
238a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  llvm::SmallVector<StoredDiagnostic, 8> Diagnostics;
239a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
240f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor  /// \brief Diag object
2411abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::IntrusiveRefCntPtr<Diagnostic> Diag;
242f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor
243a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  /// \brief Language options used to adjust source locations.
24435b8440f615a2336f2819a98a78fc89f07d905e1Daniel Dunbar  LangOptions LangOpts;
245a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
246a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  /// \brief Source manager, used for diagnostics.
247a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  SourceManager SourceMgr;
248a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
249a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  /// \brief File manager, used for diagnostics.
250a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  FileManager FileMgr;
251313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor
252313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  /// \brief Temporary files that should be removed once we have finished
253313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  /// with the code-completion results.
254313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  std::vector<llvm::sys::Path> TemporaryFiles;
255b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor
256b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  /// \brief Temporary buffers that will be deleted once we have finished with the code-completion results.
257b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  llvm::SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
258ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek};
259ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
2600a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas GregorAllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults()
261b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  : CXCodeCompleteResults(), Diag(new Diagnostic), SourceMgr(*Diag) { }
2620a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2630a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas GregorAllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
2640a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  for (unsigned I = 0, N = NumResults; I != N; ++I)
26512e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    delete (CXStoredCodeCompletionString *)Results[I].CompletionString;
2660a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  delete [] Results;
267313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor
268313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
269313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor    TemporaryFiles[I].eraseFromDisk();
270b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
271b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor    delete TemporaryBuffers[I];
2720a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor}
2730a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
274ab1889321f6f8f200f2b318ac26883ac18e49d03Ted KremenekCXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
275ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          const char *source_filename,
276ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          int num_command_line_args,
2772ef6944d529c94824f5bf96f65665f5bee30f5a2Douglas Gregor                                          const char * const *command_line_args,
278ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          unsigned num_unsaved_files,
279ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          struct CXUnsavedFile *unsaved_files,
280ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          const char *complete_filename,
281ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          unsigned complete_line,
282a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                          unsigned complete_column) {
283da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER
284da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
285da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  const llvm::TimeRecord &StartTime =  llvm::TimeRecord::getCurrentTime();
286da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
287da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
288da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
2893d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
290df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
291df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  llvm::OwningPtr<llvm::NamedRegionTimer> CCTimer;
292df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  if (getenv("LIBCLANG_TIMING")) {
293df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    llvm::SmallString<128> TimerName;
294df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    llvm::raw_svector_ostream TimerNameOut(TimerName);
2957a07fcb8f10fe45ea65a0a41798eb1c40777bde4Douglas Gregor    TimerNameOut << "Code completion (out-of-process) @ " << complete_filename
2967a07fcb8f10fe45ea65a0a41798eb1c40777bde4Douglas Gregor      << ":" << complete_line << ":" << complete_column;
297df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    CCTimer.reset(new llvm::NamedRegionTimer(TimerNameOut.str()));
298df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  }
299df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
300ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // The indexer, which is mainly used to determine where diagnostics go.
301ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
302ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
303936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor  // Configure the diagnostics.
304936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor  DiagnosticOptions DiagOpts;
30528019772db70d4547be05a042eb950bc910f134fDouglas Gregor  llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
30628019772db70d4547be05a042eb950bc910f134fDouglas Gregor  Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
307936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor
308ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // The set of temporary files that we've built.
309ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::vector<llvm::sys::Path> TemporaryFiles;
310ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
311ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Build up the arguments for invoking 'clang'.
312ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::vector<const char *> argv;
313ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
314ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // First add the complete path to the 'clang' executable.
315ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  llvm::sys::Path ClangPath = CXXIdx->getClangPath();
316ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back(ClangPath.c_str());
317ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
3183d9c6e1c97bdae6a9daedc6969bc839e93074b0fDaniel Dunbar  // Always use Clang C++ support.
3193d9c6e1c97bdae6a9daedc6969bc839e93074b0fDaniel Dunbar  argv.push_back("-ccc-clang-cxx");
3203d9c6e1c97bdae6a9daedc6969bc839e93074b0fDaniel Dunbar
321ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Add the '-fsyntax-only' argument so that we only perform a basic
322ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // syntax check of the code.
323ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-fsyntax-only");
324ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
325ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Add the appropriate '-code-completion-at=file:line:column' argument
326ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // to perform code completion, with an "-Xclang" preceding it.
327ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::string code_complete_at;
328ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += complete_filename;
329ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += ":";
330ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += llvm::utostr(complete_line);
331ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += ":";
332ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += llvm::utostr(complete_column);
333ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-Xclang");
334ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-code-completion-at");
335ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-Xclang");
336ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back(code_complete_at.c_str());
337ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-Xclang");
338ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-no-code-completion-debug-printer");
339ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-Xclang");
340ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-code-completion-macros");
341d93256e55673a17d18543397ec462416acb13792Douglas Gregor  argv.push_back("-fdiagnostics-binary");
342d93256e55673a17d18543397ec462416acb13792Douglas Gregor
3434db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  // Remap any unsaved files to temporary files.
344ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::vector<std::string> RemapArgs;
3454db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles))
3464db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    return 0;
347ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
348ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // The pointers into the elements of RemapArgs are stable because we
349ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // won't be adding anything to RemapArgs after this point.
350ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i)
351ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    argv.push_back(RemapArgs[i].c_str());
352ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
353ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Add the source file name (FIXME: later, we'll want to build temporary
354ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // file from the buffer, or just feed the source text via standard input).
355ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (source_filename)
356ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    argv.push_back(source_filename);
357ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
358ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'.
359ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  for (int i = 0; i < num_command_line_args; ++i)
360ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    if (const char *arg = command_line_args[i]) {
361ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (strcmp(arg, "-o") == 0) {
362ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        ++i; // Also skip the matching argument.
363ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        continue;
364ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      }
365ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (strcmp(arg, "-emit-ast") == 0 ||
366ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek          strcmp(arg, "-c") == 0 ||
367ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek          strcmp(arg, "-fsyntax-only") == 0) {
368ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        continue;
369ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      }
370ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
371ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      // Keep the argument.
372ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      argv.push_back(arg);
373ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    }
374ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
3753d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor  if (EnableLogging) {
3763d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor    std::string Log = ClangPath.str();
3773d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor    for (unsigned I = 0, N = argv.size(); I != N; ++I) {
3783d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor      Log += ' ';
3793d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor      Log += argv[I];
3803d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor    }
3813d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor    fprintf(stderr, "libclang (Code Completion): %s\n", Log.c_str());
3823d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor  }
3833d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor
384ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Add the null terminator.
385ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back(NULL);
386ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
387d93256e55673a17d18543397ec462416acb13792Douglas Gregor  // Generate a temporary name for the code-completion results file.
388c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  char tmpFile[L_tmpnam];
389c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  char *tmpFileName = tmpnam(tmpFile);
390c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  llvm::sys::Path ResultsFile(tmpFileName);
391ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  TemporaryFiles.push_back(ResultsFile);
392ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
393d93256e55673a17d18543397ec462416acb13792Douglas Gregor  // Generate a temporary name for the diagnostics file.
394c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  char tmpFileResults[L_tmpnam];
395c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  char *tmpResultsFileName = tmpnam(tmpFileResults);
396c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  llvm::sys::Path DiagnosticsFile(tmpResultsFileName);
397d93256e55673a17d18543397ec462416acb13792Douglas Gregor  TemporaryFiles.push_back(DiagnosticsFile);
398d93256e55673a17d18543397ec462416acb13792Douglas Gregor
3993d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor
4003d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor
401ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Invoke 'clang'.
402ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null
403ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                           // on Unix or NUL (Windows).
404ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::string ErrMsg;
405d93256e55673a17d18543397ec462416acb13792Douglas Gregor  const llvm::sys::Path *Redirects[] = { &DevNull, &ResultsFile,
406d93256e55673a17d18543397ec462416acb13792Douglas Gregor                                         &DiagnosticsFile, 0 };
407ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL,
408ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                     /* redirects */ &Redirects[0],
409ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                     /* secondsToWait */ 0,
410ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                     /* memoryLimits */ 0, &ErrMsg);
411ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
412936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor  if (!ErrMsg.empty()) {
413936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor    std::string AllArgs;
414ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
415936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor         I != E; ++I) {
416936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor      AllArgs += ' ';
417ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (*I)
418936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor        AllArgs += *I;
419ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    }
420936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor
42132141c8f69a6a51d7cf95a18229cd335ecd59903Daniel Dunbar    Diags->Report(diag::err_fe_invoking) << AllArgs << ErrMsg;
422ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
423ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
424ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Parse the resulting source file to find code-completion results.
425ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  using llvm::MemoryBuffer;
426ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  using llvm::StringRef;
427a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults;
428a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  Results->Results = 0;
429a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  Results->NumResults = 0;
430a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  // FIXME: Set Results->LangOpts!
431ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (MemoryBuffer *F = MemoryBuffer::getFile(ResultsFile.c_str())) {
432ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    llvm::SmallVector<CXCompletionResult, 4> CompletionResults;
433ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    StringRef Buffer = F->getBuffer();
434ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    for (const char *Str = Buffer.data(), *StrEnd = Str + Buffer.size();
435ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek         Str < StrEnd;) {
436ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      unsigned KindValue;
437ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (ReadUnsigned(Str, StrEnd, KindValue))
438ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        break;
439ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
44012e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      unsigned Priority;
44112e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      if (ReadUnsigned(Str, StrEnd, Priority))
44212e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor        break;
44312e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
44458ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor      unsigned Availability;
44558ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor      if (ReadUnsigned(Str, StrEnd, Availability))
44658ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor        break;
44758ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor
44812e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      CXStoredCodeCompletionString *CCStr
44958ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor        = new CXStoredCodeCompletionString(Priority,
45058ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor                                           (CXAvailabilityKind)Availability);
45112e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      if (!CCStr->Deserialize(Str, StrEnd)) {
45212e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor        delete CCStr;
453ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        continue;
45412e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      }
455ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
456ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (!CCStr->empty()) {
457ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        // Vend the code-completion result to the caller.
458ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        CXCompletionResult Result;
459ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        Result.CursorKind = (CXCursorKind)KindValue;
460ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        Result.CompletionString = CCStr;
461ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        CompletionResults.push_back(Result);
462ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      }
463ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    };
464ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
465ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    // Allocate the results.
466ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    Results->Results = new CXCompletionResult [CompletionResults.size()];
467ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    Results->NumResults = CompletionResults.size();
468ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    memcpy(Results->Results, CompletionResults.data(),
469ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek           CompletionResults.size() * sizeof(CXCompletionResult));
470b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor    Results->TemporaryBuffers.push_back(F);
471ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
472ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
473a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  LoadSerializedDiagnostics(DiagnosticsFile, num_unsaved_files, unsaved_files,
474a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                            Results->FileMgr, Results->SourceMgr,
475a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                            Results->Diagnostics);
476a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
477313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  // Make sure we delete temporary files when the code-completion results are
478313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  // destroyed.
479313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  Results->TemporaryFiles.swap(TemporaryFiles);
4801abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
4811abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#ifdef UDP_CODE_COMPLETION_LOGGER
4821abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
4831abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  const llvm::TimeRecord &EndTime =  llvm::TimeRecord::getCurrentTime();
4841abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::SmallString<256> LogResult;
4851abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::raw_svector_ostream os(LogResult);
4861abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
4871abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Figure out the language and whether or not it uses PCH.
4881abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  const char *lang = 0;
4891abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  bool usesPCH = false;
4901abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
4911abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
4921abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor       I != E; ++I) {
4931abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    if (*I == 0)
4941abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      continue;
4951abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    if (strcmp(*I, "-x") == 0) {
4961abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      if (I + 1 != E) {
4971abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        lang = *(++I);
4981abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        continue;
4991abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      }
5001abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    }
5011abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    else if (strcmp(*I, "-include") == 0) {
5021abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      if (I+1 != E) {
5031abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        const char *arg = *(++I);
5041abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        llvm::SmallString<512> pchName;
5051abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        {
5061abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor          llvm::raw_svector_ostream os(pchName);
5071abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor          os << arg << ".pth";
5081abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        }
5091abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        pchName.push_back('\0');
5101abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        struct stat stat_results;
5111abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        if (stat(pchName.data(), &stat_results) == 0)
5121abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor          usesPCH = true;
5131abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        continue;
5141abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      }
5151abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    }
5161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
5171abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5181abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << "{ ";
5191abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
5201abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"numRes\": " << Results->NumResults;
5211abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"diags\": " << Results->Diagnostics.size();
5221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"pch\": " << (usesPCH ? "true" : "false");
5231abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
5241abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  const char *name = getlogin();
5251abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"user\": \"" << (name ? name : "unknown") << '"';
5261abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
5271abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << " }";
5281abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5291abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::StringRef res = os.str();
5301abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  if (res.size() > 0) {
5311abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    do {
5321abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      // Setup the UDP socket.
5331abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      struct sockaddr_in servaddr;
5341abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      bzero(&servaddr, sizeof(servaddr));
5351abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      servaddr.sin_family = AF_INET;
5361abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
5371abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
5381abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                    &servaddr.sin_addr) <= 0)
5391abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        break;
5401abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5411abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
5421abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      if (sockfd < 0)
5431abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        break;
5441abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5451abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      sendto(sockfd, res.data(), res.size(), 0,
5461abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor             (struct sockaddr *)&servaddr, sizeof(servaddr));
5471abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      close(sockfd);
5481abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    }
5491abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    while (false);
5501abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
5511abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#endif
5521abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#endif
553df46316a423dac0dcccb3bfcb85df41e6ff88243Douglas Gregor  clang_sortCodeCompletionResults(Results->Results, Results->NumResults);
5541abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  return Results;
5551abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor}
5561abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5571abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor} // end extern "C"
5581abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5591abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregornamespace {
5601abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  class CaptureCompletionResults : public CodeCompleteConsumer {
5611abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    AllocatedCXCodeCompleteResults &AllocatedResults;
56232be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor    llvm::SmallVector<CXCompletionResult, 16> StoredResults;
56332be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor
5641abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  public:
5651abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    explicit CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results)
5668071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor      : CodeCompleteConsumer(true, false, true, false),
5678071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor        AllocatedResults(Results) { }
56832be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor    ~CaptureCompletionResults() { Finish(); }
56932be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor
570e6b1bb6e7fe906d164637ca33503b8fafdbc99e5Douglas Gregor    virtual void ProcessCodeCompleteResults(Sema &S,
571e6b1bb6e7fe906d164637ca33503b8fafdbc99e5Douglas Gregor                                            CodeCompletionContext Context,
5720a2c5e256abb4dc031c21fe4dc92c4f3afe9947cJohn McCall                                            CodeCompletionResult *Results,
5731abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                                            unsigned NumResults) {
57432be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor      StoredResults.reserve(StoredResults.size() + NumResults);
5751abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      for (unsigned I = 0; I != NumResults; ++I) {
5761abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        CXStoredCodeCompletionString *StoredCompletion
57758ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor          = new CXStoredCodeCompletionString(Results[I].Priority,
57858ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor                                             Results[I].Availability);
5791abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        (void)Results[I].CreateCodeCompletionString(S, StoredCompletion);
58032be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor
58132be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor        CXCompletionResult R;
58232be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor        R.CursorKind = Results[I].CursorKind;
58332be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor        R.CompletionString = StoredCompletion;
58432be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor        StoredResults.push_back(R);
5851abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      }
5861abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    }
5871e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor
58832be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor    virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
58932be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor                                           OverloadCandidate *Candidates,
59032be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor                                           unsigned NumCandidates) {
59132be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor      StoredResults.reserve(StoredResults.size() + NumCandidates);
59232be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor      for (unsigned I = 0; I != NumCandidates; ++I) {
59332be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor        // FIXME: Set priority, availability appropriately.
59432be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor        CXStoredCodeCompletionString *StoredCompletion
59532be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor          = new CXStoredCodeCompletionString(1, CXAvailability_Available);
59632be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor        (void)Candidates[I].CreateSignatureString(CurrentArg, S,
59732be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor                                                  StoredCompletion);
59832be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor
59932be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor        CXCompletionResult R;
60032be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor        R.CursorKind = CXCursor_NotImplemented;
60132be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor        R.CompletionString = StoredCompletion;
60232be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor        StoredResults.push_back(R);
60332be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor      }
60432be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor    }
60532be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor
60632be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor  private:
60732be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor    void Finish() {
60832be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor      AllocatedResults.Results = new CXCompletionResult [StoredResults.size()];
60932be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor      AllocatedResults.NumResults = StoredResults.size();
61032be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor      std::memcpy(AllocatedResults.Results, StoredResults.data(),
61132be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor                  StoredResults.size() * sizeof(CXCompletionResult));
61232be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor      StoredResults.clear();
61332be4a588fbb87d0d163ead49c42f5438bf0b2b7Douglas Gregor    }
6141abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  };
6151abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor}
6161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6171abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregorextern "C" {
618b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbarstruct CodeCompleteAtInfo {
619b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CXTranslationUnit TU;
620b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  const char *complete_filename;
621b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned complete_line;
622b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned complete_column;
623b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  struct CXUnsavedFile *unsaved_files;
624b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned num_unsaved_files;
625b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned options;
626b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CXCodeCompleteResults *result;
627b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar};
628b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbarvoid clang_codeCompleteAt_Impl(void *UserData) {
629b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CodeCompleteAtInfo *CCAI = static_cast<CodeCompleteAtInfo*>(UserData);
630b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CXTranslationUnit TU = CCAI->TU;
631b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  const char *complete_filename = CCAI->complete_filename;
632b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned complete_line = CCAI->complete_line;
633b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned complete_column = CCAI->complete_column;
634b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  struct CXUnsavedFile *unsaved_files = CCAI->unsaved_files;
635b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned num_unsaved_files = CCAI->num_unsaved_files;
636b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned options = CCAI->options;
637b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CCAI->result = 0;
638b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar
6391abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#ifdef UDP_CODE_COMPLETION_LOGGER
6401abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
6411abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  const llvm::TimeRecord &StartTime =  llvm::TimeRecord::getCurrentTime();
6421abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#endif
6431abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#endif
6441abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6451abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
6461abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6471abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  ASTUnit *AST = static_cast<ASTUnit *>(TU);
6481abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  if (!AST)
649b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar    return;
6501abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
651593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor  ASTUnit::ConcurrencyCheck Check(*AST);
652593b0c1047f1323ebbda78ae38e96f976241c663Douglas Gregor
6531abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Perform the remapping of source files.
6541abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
6551abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  for (unsigned I = 0; I != num_unsaved_files; ++I) {
6561abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
6571abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    const llvm::MemoryBuffer *Buffer
6581abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
6591abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
6601abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                                           Buffer));
6611abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
6621abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6631abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  if (EnableLogging) {
6641abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    // FIXME: Add logging.
6651abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
6661abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6671abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Parse the resulting source file to find code-completion results.
6681abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults;
6691abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  Results->Results = 0;
6701abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  Results->NumResults = 0;
6711abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6721abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Create a code-completion consumer to capture the results.
6731abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  CaptureCompletionResults Capture(*Results);
6741abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6751abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Perform completion.
6761abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  AST->CodeComplete(complete_filename, complete_line, complete_column,
677cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                    RemappedFiles.data(), RemappedFiles.size(),
678cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                    (options & CXCodeComplete_IncludeMacros),
679cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                    (options & CXCodeComplete_IncludeCodePatterns),
680cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                    Capture,
6811abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                    *Results->Diag, Results->LangOpts, Results->SourceMgr,
6822283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor                    Results->FileMgr, Results->Diagnostics,
6832283d79155a3e82442fce124ce5fd704ca138801Douglas Gregor                    Results->TemporaryBuffers);
6841abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6851abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
686ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
687da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER
688da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
689da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  const llvm::TimeRecord &EndTime =  llvm::TimeRecord::getCurrentTime();
690da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  llvm::SmallString<256> LogResult;
691da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  llvm::raw_svector_ostream os(LogResult);
692da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
693da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  // Figure out the language and whether or not it uses PCH.
694da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  const char *lang = 0;
695da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  bool usesPCH = false;
696da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
697da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
698da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek       I != E; ++I) {
699da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    if (*I == 0)
700da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      continue;
701da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    if (strcmp(*I, "-x") == 0) {
702da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      if (I + 1 != E) {
703da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        lang = *(++I);
704da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        continue;
705da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      }
706da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    }
707da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    else if (strcmp(*I, "-include") == 0) {
708da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      if (I+1 != E) {
709da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        const char *arg = *(++I);
710da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        llvm::SmallString<512> pchName;
711da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        {
712da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek          llvm::raw_svector_ostream os(pchName);
713da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek          os << arg << ".pth";
714da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        }
715da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        pchName.push_back('\0');
716da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        struct stat stat_results;
717da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        if (stat(pchName.data(), &stat_results) == 0)
718da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek          usesPCH = true;
719da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        continue;
720da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      }
721da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    }
722da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  }
723da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
7242ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << "{ ";
7252ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
7262ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"numRes\": " << Results->NumResults;
7272ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"diags\": " << Results->Diagnostics.size();
7282ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"pch\": " << (usesPCH ? "true" : "false");
7292ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
730da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  const char *name = getlogin();
7312ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"user\": \"" << (name ? name : "unknown") << '"';
7322ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
7332ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << " }";
734da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
735da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  llvm::StringRef res = os.str();
736da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  if (res.size() > 0) {
737da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    do {
738da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      // Setup the UDP socket.
739da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      struct sockaddr_in servaddr;
740da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      bzero(&servaddr, sizeof(servaddr));
741da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      servaddr.sin_family = AF_INET;
742da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
743da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
744da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek                    &servaddr.sin_addr) <= 0)
745da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        break;
746da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
747da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
748da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      if (sockfd < 0)
749da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        break;
750da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
751da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      sendto(sockfd, res.data(), res.size(), 0,
752da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek             (struct sockaddr *)&servaddr, sizeof(servaddr));
753da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      close(sockfd);
754da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    }
755da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    while (false);
756da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  }
757da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
758da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
759b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CCAI->result = Results;
760b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar}
761b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel DunbarCXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
762b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                                            const char *complete_filename,
763b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                                            unsigned complete_line,
764b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                                            unsigned complete_column,
765b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                                            struct CXUnsavedFile *unsaved_files,
766b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                                            unsigned num_unsaved_files,
767b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                                            unsigned options) {
768b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CodeCompleteAtInfo CCAI = { TU, complete_filename, complete_line,
769b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                              complete_column, unsaved_files, num_unsaved_files,
770b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                              options, 0 };
771b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  llvm::CrashRecoveryContext CRC;
772b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar
773b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  if (!CRC.RunSafely(clang_codeCompleteAt_Impl, &CCAI)) {
774b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar    fprintf(stderr, "libclang: crash detected in code completion\n");
775b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar    static_cast<ASTUnit *>(TU)->setUnsafeToFree(true);
776b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar    return 0;
777b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  }
778b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar
779b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  return CCAI.result;
780ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
781ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
782cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregorunsigned clang_defaultCodeCompleteOptions(void) {
783cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor  return CXCodeComplete_IncludeMacros;
784cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor}
785cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor
786ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekvoid clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) {
787ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (!ResultsIn)
788ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return;
789ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
790ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  AllocatedCXCodeCompleteResults *Results
791ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
792ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  delete Results;
793ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
79458ddb60f409125eda5436c4a1f070f7fa4744295Douglas Gregor
795a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorunsigned
796a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) {
797a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  AllocatedCXCodeCompleteResults *Results
798a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
799a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  if (!Results)
800a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    return 0;
801a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
802a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  return Results->Diagnostics.size();
803a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}
804a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
805a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas GregorCXDiagnostic
806a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn,
807a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                unsigned Index) {
808a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  AllocatedCXCodeCompleteResults *Results
809a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
810a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  if (!Results || Index >= Results->Diagnostics.size())
811a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    return 0;
812a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
813a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  return new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts);
814a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}
815a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
816a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
817ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek} // end extern "C"
8181e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor
8191e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregornamespace {
8201e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor  struct OrderCompletionResults {
8211e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor    bool operator()(const CXCompletionResult &XR,
8221e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor                    const CXCompletionResult &YR) const {
8231e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor      CXStoredCodeCompletionString *X
8241e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor        = (CXStoredCodeCompletionString *)XR.CompletionString;
8251e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor      CXStoredCodeCompletionString *Y
8261e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor        = (CXStoredCodeCompletionString *)YR.CompletionString;
8271e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor
8281e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor      const char *XText = X->getTypedText();
8291e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor      const char *YText = Y->getTypedText();
8301e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor      if (!XText || !YText)
8311e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor        return XText != 0;
8321e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor
8331e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor      int result = llvm::StringRef(XText).compare_lower(YText);
8341e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor      if (result < 0)
8351e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor        return true;
8361e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor      if (result > 0)
8371e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor        return false;
8381e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor
8391e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor      result = llvm::StringRef(XText).compare(YText);
8401aad34043d261fe7fe3edefa8484faa548b0176aDouglas Gregor      return result < 0;
8411e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor    }
8421e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor  };
8431e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor}
8441e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor
8451e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregorextern "C" {
8461e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor  void clang_sortCodeCompletionResults(CXCompletionResult *Results,
8471e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor                                       unsigned NumResults) {
8481e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor    std::stable_sort(Results, Results + NumResults, OrderCompletionResults());
8491e5e6684b0f27701e6f7c65f8c6a32a10cbcc3edDouglas Gregor  }
850458433d2f0f5c96a9e0d21decdd44bebccf20b11Douglas Gregor}
851