1*d5a2a073SDaniel Dunbar //===- CIndexCodeCompletion.cpp - Code Completion API hooks ---------------===//
2*d5a2a073SDaniel Dunbar //
3*d5a2a073SDaniel Dunbar //                     The LLVM Compiler Infrastructure
4*d5a2a073SDaniel Dunbar //
5*d5a2a073SDaniel Dunbar // This file is distributed under the University of Illinois Open Source
6*d5a2a073SDaniel Dunbar // License. See LICENSE.TXT for details.
7*d5a2a073SDaniel Dunbar //
8*d5a2a073SDaniel Dunbar //===----------------------------------------------------------------------===//
9*d5a2a073SDaniel Dunbar //
10*d5a2a073SDaniel Dunbar // This file implements the Clang-C Source Indexing library hooks for
11*d5a2a073SDaniel Dunbar // code completion.
12*d5a2a073SDaniel Dunbar //
13*d5a2a073SDaniel Dunbar //===----------------------------------------------------------------------===//
14*d5a2a073SDaniel Dunbar 
15*d5a2a073SDaniel Dunbar #include "CIndexer.h"
16*d5a2a073SDaniel Dunbar #include "CIndexDiagnostic.h"
17*d5a2a073SDaniel Dunbar #include "clang/Basic/SourceManager.h"
18*d5a2a073SDaniel Dunbar #include "clang/Basic/FileManager.h"
19*d5a2a073SDaniel Dunbar #include "clang/Frontend/CompilerInstance.h"
20*d5a2a073SDaniel Dunbar #include "clang/Frontend/FrontendDiagnostic.h"
21*d5a2a073SDaniel Dunbar #include "clang/Sema/CodeCompleteConsumer.h"
22*d5a2a073SDaniel Dunbar #include "llvm/ADT/StringExtras.h"
23*d5a2a073SDaniel Dunbar #include "llvm/Support/MemoryBuffer.h"
24*d5a2a073SDaniel Dunbar #include "llvm/System/Program.h"
25*d5a2a073SDaniel Dunbar 
26*d5a2a073SDaniel Dunbar #ifdef UDP_CODE_COMPLETION_LOGGER
27*d5a2a073SDaniel Dunbar #include "clang/Basic/Version.h"
28*d5a2a073SDaniel Dunbar #include "llvm/ADT/SmallString.h"
29*d5a2a073SDaniel Dunbar #include "llvm/Support/Timer.h"
30*d5a2a073SDaniel Dunbar #include "llvm/Support/raw_ostream.h"
31*d5a2a073SDaniel Dunbar #include <arpa/inet.h>
32*d5a2a073SDaniel Dunbar #include <sys/socket.h>
33*d5a2a073SDaniel Dunbar #include <sys/types.h>
34*d5a2a073SDaniel Dunbar #include <unistd.h>
35*d5a2a073SDaniel Dunbar #endif
36*d5a2a073SDaniel Dunbar 
37*d5a2a073SDaniel Dunbar using namespace clang;
38*d5a2a073SDaniel Dunbar using namespace clang::cxstring;
39*d5a2a073SDaniel Dunbar 
40*d5a2a073SDaniel Dunbar extern "C" {
41*d5a2a073SDaniel Dunbar 
42*d5a2a073SDaniel Dunbar enum CXCompletionChunkKind
43*d5a2a073SDaniel Dunbar clang_getCompletionChunkKind(CXCompletionString completion_string,
44*d5a2a073SDaniel Dunbar                              unsigned chunk_number) {
45*d5a2a073SDaniel Dunbar   CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
46*d5a2a073SDaniel Dunbar   if (!CCStr || chunk_number >= CCStr->size())
47*d5a2a073SDaniel Dunbar     return CXCompletionChunk_Text;
48*d5a2a073SDaniel Dunbar 
49*d5a2a073SDaniel Dunbar   switch ((*CCStr)[chunk_number].Kind) {
50*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_TypedText:
51*d5a2a073SDaniel Dunbar     return CXCompletionChunk_TypedText;
52*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Text:
53*d5a2a073SDaniel Dunbar     return CXCompletionChunk_Text;
54*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Optional:
55*d5a2a073SDaniel Dunbar     return CXCompletionChunk_Optional;
56*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Placeholder:
57*d5a2a073SDaniel Dunbar     return CXCompletionChunk_Placeholder;
58*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Informative:
59*d5a2a073SDaniel Dunbar     return CXCompletionChunk_Informative;
60*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_ResultType:
61*d5a2a073SDaniel Dunbar     return CXCompletionChunk_ResultType;
62*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_CurrentParameter:
63*d5a2a073SDaniel Dunbar     return CXCompletionChunk_CurrentParameter;
64*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_LeftParen:
65*d5a2a073SDaniel Dunbar     return CXCompletionChunk_LeftParen;
66*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_RightParen:
67*d5a2a073SDaniel Dunbar     return CXCompletionChunk_RightParen;
68*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_LeftBracket:
69*d5a2a073SDaniel Dunbar     return CXCompletionChunk_LeftBracket;
70*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_RightBracket:
71*d5a2a073SDaniel Dunbar     return CXCompletionChunk_RightBracket;
72*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_LeftBrace:
73*d5a2a073SDaniel Dunbar     return CXCompletionChunk_LeftBrace;
74*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_RightBrace:
75*d5a2a073SDaniel Dunbar     return CXCompletionChunk_RightBrace;
76*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_LeftAngle:
77*d5a2a073SDaniel Dunbar     return CXCompletionChunk_LeftAngle;
78*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_RightAngle:
79*d5a2a073SDaniel Dunbar     return CXCompletionChunk_RightAngle;
80*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Comma:
81*d5a2a073SDaniel Dunbar     return CXCompletionChunk_Comma;
82*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Colon:
83*d5a2a073SDaniel Dunbar     return CXCompletionChunk_Colon;
84*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_SemiColon:
85*d5a2a073SDaniel Dunbar     return CXCompletionChunk_SemiColon;
86*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Equal:
87*d5a2a073SDaniel Dunbar     return CXCompletionChunk_Equal;
88*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_HorizontalSpace:
89*d5a2a073SDaniel Dunbar     return CXCompletionChunk_HorizontalSpace;
90*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_VerticalSpace:
91*d5a2a073SDaniel Dunbar     return CXCompletionChunk_VerticalSpace;
92*d5a2a073SDaniel Dunbar   }
93*d5a2a073SDaniel Dunbar 
94*d5a2a073SDaniel Dunbar   // Should be unreachable, but let's be careful.
95*d5a2a073SDaniel Dunbar   return CXCompletionChunk_Text;
96*d5a2a073SDaniel Dunbar }
97*d5a2a073SDaniel Dunbar 
98*d5a2a073SDaniel Dunbar CXString clang_getCompletionChunkText(CXCompletionString completion_string,
99*d5a2a073SDaniel Dunbar                                       unsigned chunk_number) {
100*d5a2a073SDaniel Dunbar   CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
101*d5a2a073SDaniel Dunbar   if (!CCStr || chunk_number >= CCStr->size())
102*d5a2a073SDaniel Dunbar     return createCXString(0);
103*d5a2a073SDaniel Dunbar 
104*d5a2a073SDaniel Dunbar   switch ((*CCStr)[chunk_number].Kind) {
105*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_TypedText:
106*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Text:
107*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Placeholder:
108*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_CurrentParameter:
109*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Informative:
110*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_LeftParen:
111*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_RightParen:
112*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_LeftBracket:
113*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_RightBracket:
114*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_LeftBrace:
115*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_RightBrace:
116*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_LeftAngle:
117*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_RightAngle:
118*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Comma:
119*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_ResultType:
120*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Colon:
121*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_SemiColon:
122*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Equal:
123*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_HorizontalSpace:
124*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_VerticalSpace:
125*d5a2a073SDaniel Dunbar     return createCXString((*CCStr)[chunk_number].Text, false);
126*d5a2a073SDaniel Dunbar 
127*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Optional:
128*d5a2a073SDaniel Dunbar     // Note: treated as an empty text block.
129*d5a2a073SDaniel Dunbar     return createCXString("");
130*d5a2a073SDaniel Dunbar   }
131*d5a2a073SDaniel Dunbar 
132*d5a2a073SDaniel Dunbar   // Should be unreachable, but let's be careful.
133*d5a2a073SDaniel Dunbar   return createCXString(0);
134*d5a2a073SDaniel Dunbar }
135*d5a2a073SDaniel Dunbar 
136*d5a2a073SDaniel Dunbar 
137*d5a2a073SDaniel Dunbar CXCompletionString
138*d5a2a073SDaniel Dunbar clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
139*d5a2a073SDaniel Dunbar                                          unsigned chunk_number) {
140*d5a2a073SDaniel Dunbar   CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
141*d5a2a073SDaniel Dunbar   if (!CCStr || chunk_number >= CCStr->size())
142*d5a2a073SDaniel Dunbar     return 0;
143*d5a2a073SDaniel Dunbar 
144*d5a2a073SDaniel Dunbar   switch ((*CCStr)[chunk_number].Kind) {
145*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_TypedText:
146*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Text:
147*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Placeholder:
148*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_CurrentParameter:
149*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Informative:
150*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_LeftParen:
151*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_RightParen:
152*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_LeftBracket:
153*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_RightBracket:
154*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_LeftBrace:
155*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_RightBrace:
156*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_LeftAngle:
157*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_RightAngle:
158*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Comma:
159*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_ResultType:
160*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Colon:
161*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_SemiColon:
162*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Equal:
163*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_HorizontalSpace:
164*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_VerticalSpace:
165*d5a2a073SDaniel Dunbar     return 0;
166*d5a2a073SDaniel Dunbar 
167*d5a2a073SDaniel Dunbar   case CodeCompletionString::CK_Optional:
168*d5a2a073SDaniel Dunbar     // Note: treated as an empty text block.
169*d5a2a073SDaniel Dunbar     return (*CCStr)[chunk_number].Optional;
170*d5a2a073SDaniel Dunbar   }
171*d5a2a073SDaniel Dunbar 
172*d5a2a073SDaniel Dunbar   // Should be unreachable, but let's be careful.
173*d5a2a073SDaniel Dunbar   return 0;
174*d5a2a073SDaniel Dunbar }
175*d5a2a073SDaniel Dunbar 
176*d5a2a073SDaniel Dunbar unsigned clang_getNumCompletionChunks(CXCompletionString completion_string) {
177*d5a2a073SDaniel Dunbar   CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
178*d5a2a073SDaniel Dunbar   return CCStr? CCStr->size() : 0;
179*d5a2a073SDaniel Dunbar }
180*d5a2a073SDaniel Dunbar 
181*d5a2a073SDaniel Dunbar static bool ReadUnsigned(const char *&Memory, const char *MemoryEnd,
182*d5a2a073SDaniel Dunbar                          unsigned &Value) {
183*d5a2a073SDaniel Dunbar   if (Memory + sizeof(unsigned) > MemoryEnd)
184*d5a2a073SDaniel Dunbar     return true;
185*d5a2a073SDaniel Dunbar 
186*d5a2a073SDaniel Dunbar   memmove(&Value, Memory, sizeof(unsigned));
187*d5a2a073SDaniel Dunbar   Memory += sizeof(unsigned);
188*d5a2a073SDaniel Dunbar   return false;
189*d5a2a073SDaniel Dunbar }
190*d5a2a073SDaniel Dunbar 
191*d5a2a073SDaniel Dunbar /// \brief The CXCodeCompleteResults structure we allocate internally;
192*d5a2a073SDaniel Dunbar /// the client only sees the initial CXCodeCompleteResults structure.
193*d5a2a073SDaniel Dunbar struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
194*d5a2a073SDaniel Dunbar   AllocatedCXCodeCompleteResults();
195*d5a2a073SDaniel Dunbar   ~AllocatedCXCodeCompleteResults();
196*d5a2a073SDaniel Dunbar 
197*d5a2a073SDaniel Dunbar   /// \brief The memory buffer from which we parsed the results. We
198*d5a2a073SDaniel Dunbar   /// retain this buffer because the completion strings point into it.
199*d5a2a073SDaniel Dunbar   llvm::MemoryBuffer *Buffer;
200*d5a2a073SDaniel Dunbar 
201*d5a2a073SDaniel Dunbar   /// \brief Diagnostics produced while performing code completion.
202*d5a2a073SDaniel Dunbar   llvm::SmallVector<StoredDiagnostic, 8> Diagnostics;
203*d5a2a073SDaniel Dunbar 
204*d5a2a073SDaniel Dunbar   /// \brief Diag object
205*d5a2a073SDaniel Dunbar   Diagnostic Diag;
206*d5a2a073SDaniel Dunbar 
207*d5a2a073SDaniel Dunbar   /// \brief Language options used to adjust source locations.
208*d5a2a073SDaniel Dunbar   LangOptions LangOpts;
209*d5a2a073SDaniel Dunbar 
210*d5a2a073SDaniel Dunbar   /// \brief Source manager, used for diagnostics.
211*d5a2a073SDaniel Dunbar   SourceManager SourceMgr;
212*d5a2a073SDaniel Dunbar 
213*d5a2a073SDaniel Dunbar   /// \brief File manager, used for diagnostics.
214*d5a2a073SDaniel Dunbar   FileManager FileMgr;
215*d5a2a073SDaniel Dunbar 
216*d5a2a073SDaniel Dunbar   /// \brief Temporary files that should be removed once we have finished
217*d5a2a073SDaniel Dunbar   /// with the code-completion results.
218*d5a2a073SDaniel Dunbar   std::vector<llvm::sys::Path> TemporaryFiles;
219*d5a2a073SDaniel Dunbar };
220*d5a2a073SDaniel Dunbar 
221*d5a2a073SDaniel Dunbar AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults()
222*d5a2a073SDaniel Dunbar   : CXCodeCompleteResults(), Buffer(0), SourceMgr(Diag) { }
223*d5a2a073SDaniel Dunbar 
224*d5a2a073SDaniel Dunbar AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
225*d5a2a073SDaniel Dunbar   for (unsigned I = 0, N = NumResults; I != N; ++I)
226*d5a2a073SDaniel Dunbar     delete (CodeCompletionString *)Results[I].CompletionString;
227*d5a2a073SDaniel Dunbar   delete [] Results;
228*d5a2a073SDaniel Dunbar   delete Buffer;
229*d5a2a073SDaniel Dunbar 
230*d5a2a073SDaniel Dunbar   for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
231*d5a2a073SDaniel Dunbar     TemporaryFiles[I].eraseFromDisk();
232*d5a2a073SDaniel Dunbar }
233*d5a2a073SDaniel Dunbar 
234*d5a2a073SDaniel Dunbar CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
235*d5a2a073SDaniel Dunbar                                           const char *source_filename,
236*d5a2a073SDaniel Dunbar                                           int num_command_line_args,
237*d5a2a073SDaniel Dunbar                                           const char **command_line_args,
238*d5a2a073SDaniel Dunbar                                           unsigned num_unsaved_files,
239*d5a2a073SDaniel Dunbar                                           struct CXUnsavedFile *unsaved_files,
240*d5a2a073SDaniel Dunbar                                           const char *complete_filename,
241*d5a2a073SDaniel Dunbar                                           unsigned complete_line,
242*d5a2a073SDaniel Dunbar                                           unsigned complete_column) {
243*d5a2a073SDaniel Dunbar #ifdef UDP_CODE_COMPLETION_LOGGER
244*d5a2a073SDaniel Dunbar #ifdef UDP_CODE_COMPLETION_LOGGER_PORT
245*d5a2a073SDaniel Dunbar   const llvm::TimeRecord &StartTime =  llvm::TimeRecord::getCurrentTime();
246*d5a2a073SDaniel Dunbar #endif
247*d5a2a073SDaniel Dunbar #endif
248*d5a2a073SDaniel Dunbar 
249*d5a2a073SDaniel Dunbar   // The indexer, which is mainly used to determine where diagnostics go.
250*d5a2a073SDaniel Dunbar   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
251*d5a2a073SDaniel Dunbar 
252*d5a2a073SDaniel Dunbar   // Configure the diagnostics.
253*d5a2a073SDaniel Dunbar   DiagnosticOptions DiagOpts;
254*d5a2a073SDaniel Dunbar   llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
255*d5a2a073SDaniel Dunbar   Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
256*d5a2a073SDaniel Dunbar 
257*d5a2a073SDaniel Dunbar   // The set of temporary files that we've built.
258*d5a2a073SDaniel Dunbar   std::vector<llvm::sys::Path> TemporaryFiles;
259*d5a2a073SDaniel Dunbar 
260*d5a2a073SDaniel Dunbar   // Build up the arguments for invoking 'clang'.
261*d5a2a073SDaniel Dunbar   std::vector<const char *> argv;
262*d5a2a073SDaniel Dunbar 
263*d5a2a073SDaniel Dunbar   // First add the complete path to the 'clang' executable.
264*d5a2a073SDaniel Dunbar   llvm::sys::Path ClangPath = CXXIdx->getClangPath();
265*d5a2a073SDaniel Dunbar   argv.push_back(ClangPath.c_str());
266*d5a2a073SDaniel Dunbar 
267*d5a2a073SDaniel Dunbar   // Add the '-fsyntax-only' argument so that we only perform a basic
268*d5a2a073SDaniel Dunbar   // syntax check of the code.
269*d5a2a073SDaniel Dunbar   argv.push_back("-fsyntax-only");
270*d5a2a073SDaniel Dunbar 
271*d5a2a073SDaniel Dunbar   // Add the appropriate '-code-completion-at=file:line:column' argument
272*d5a2a073SDaniel Dunbar   // to perform code completion, with an "-Xclang" preceding it.
273*d5a2a073SDaniel Dunbar   std::string code_complete_at;
274*d5a2a073SDaniel Dunbar   code_complete_at += complete_filename;
275*d5a2a073SDaniel Dunbar   code_complete_at += ":";
276*d5a2a073SDaniel Dunbar   code_complete_at += llvm::utostr(complete_line);
277*d5a2a073SDaniel Dunbar   code_complete_at += ":";
278*d5a2a073SDaniel Dunbar   code_complete_at += llvm::utostr(complete_column);
279*d5a2a073SDaniel Dunbar   argv.push_back("-Xclang");
280*d5a2a073SDaniel Dunbar   argv.push_back("-code-completion-at");
281*d5a2a073SDaniel Dunbar   argv.push_back("-Xclang");
282*d5a2a073SDaniel Dunbar   argv.push_back(code_complete_at.c_str());
283*d5a2a073SDaniel Dunbar   argv.push_back("-Xclang");
284*d5a2a073SDaniel Dunbar   argv.push_back("-no-code-completion-debug-printer");
285*d5a2a073SDaniel Dunbar   argv.push_back("-Xclang");
286*d5a2a073SDaniel Dunbar   argv.push_back("-code-completion-macros");
287*d5a2a073SDaniel Dunbar   argv.push_back("-fdiagnostics-binary");
288*d5a2a073SDaniel Dunbar 
289*d5a2a073SDaniel Dunbar   // Remap any unsaved files to temporary files.
290*d5a2a073SDaniel Dunbar   std::vector<std::string> RemapArgs;
291*d5a2a073SDaniel Dunbar   if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles))
292*d5a2a073SDaniel Dunbar     return 0;
293*d5a2a073SDaniel Dunbar 
294*d5a2a073SDaniel Dunbar   // The pointers into the elements of RemapArgs are stable because we
295*d5a2a073SDaniel Dunbar   // won't be adding anything to RemapArgs after this point.
296*d5a2a073SDaniel Dunbar   for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i)
297*d5a2a073SDaniel Dunbar     argv.push_back(RemapArgs[i].c_str());
298*d5a2a073SDaniel Dunbar 
299*d5a2a073SDaniel Dunbar   // Add the source file name (FIXME: later, we'll want to build temporary
300*d5a2a073SDaniel Dunbar   // file from the buffer, or just feed the source text via standard input).
301*d5a2a073SDaniel Dunbar   if (source_filename)
302*d5a2a073SDaniel Dunbar     argv.push_back(source_filename);
303*d5a2a073SDaniel Dunbar 
304*d5a2a073SDaniel Dunbar   // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'.
305*d5a2a073SDaniel Dunbar   for (int i = 0; i < num_command_line_args; ++i)
306*d5a2a073SDaniel Dunbar     if (const char *arg = command_line_args[i]) {
307*d5a2a073SDaniel Dunbar       if (strcmp(arg, "-o") == 0) {
308*d5a2a073SDaniel Dunbar         ++i; // Also skip the matching argument.
309*d5a2a073SDaniel Dunbar         continue;
310*d5a2a073SDaniel Dunbar       }
311*d5a2a073SDaniel Dunbar       if (strcmp(arg, "-emit-ast") == 0 ||
312*d5a2a073SDaniel Dunbar           strcmp(arg, "-c") == 0 ||
313*d5a2a073SDaniel Dunbar           strcmp(arg, "-fsyntax-only") == 0) {
314*d5a2a073SDaniel Dunbar         continue;
315*d5a2a073SDaniel Dunbar       }
316*d5a2a073SDaniel Dunbar 
317*d5a2a073SDaniel Dunbar       // Keep the argument.
318*d5a2a073SDaniel Dunbar       argv.push_back(arg);
319*d5a2a073SDaniel Dunbar     }
320*d5a2a073SDaniel Dunbar 
321*d5a2a073SDaniel Dunbar   // Add the null terminator.
322*d5a2a073SDaniel Dunbar   argv.push_back(NULL);
323*d5a2a073SDaniel Dunbar 
324*d5a2a073SDaniel Dunbar   // Generate a temporary name for the code-completion results file.
325*d5a2a073SDaniel Dunbar   char tmpFile[L_tmpnam];
326*d5a2a073SDaniel Dunbar   char *tmpFileName = tmpnam(tmpFile);
327*d5a2a073SDaniel Dunbar   llvm::sys::Path ResultsFile(tmpFileName);
328*d5a2a073SDaniel Dunbar   TemporaryFiles.push_back(ResultsFile);
329*d5a2a073SDaniel Dunbar 
330*d5a2a073SDaniel Dunbar   // Generate a temporary name for the diagnostics file.
331*d5a2a073SDaniel Dunbar   char tmpFileResults[L_tmpnam];
332*d5a2a073SDaniel Dunbar   char *tmpResultsFileName = tmpnam(tmpFileResults);
333*d5a2a073SDaniel Dunbar   llvm::sys::Path DiagnosticsFile(tmpResultsFileName);
334*d5a2a073SDaniel Dunbar   TemporaryFiles.push_back(DiagnosticsFile);
335*d5a2a073SDaniel Dunbar 
336*d5a2a073SDaniel Dunbar   // Invoke 'clang'.
337*d5a2a073SDaniel Dunbar   llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null
338*d5a2a073SDaniel Dunbar                            // on Unix or NUL (Windows).
339*d5a2a073SDaniel Dunbar   std::string ErrMsg;
340*d5a2a073SDaniel Dunbar   const llvm::sys::Path *Redirects[] = { &DevNull, &ResultsFile,
341*d5a2a073SDaniel Dunbar                                          &DiagnosticsFile, 0 };
342*d5a2a073SDaniel Dunbar   llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL,
343*d5a2a073SDaniel Dunbar                                      /* redirects */ &Redirects[0],
344*d5a2a073SDaniel Dunbar                                      /* secondsToWait */ 0,
345*d5a2a073SDaniel Dunbar                                      /* memoryLimits */ 0, &ErrMsg);
346*d5a2a073SDaniel Dunbar 
347*d5a2a073SDaniel Dunbar   if (!ErrMsg.empty()) {
348*d5a2a073SDaniel Dunbar     std::string AllArgs;
349*d5a2a073SDaniel Dunbar     for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
350*d5a2a073SDaniel Dunbar          I != E; ++I) {
351*d5a2a073SDaniel Dunbar       AllArgs += ' ';
352*d5a2a073SDaniel Dunbar       if (*I)
353*d5a2a073SDaniel Dunbar         AllArgs += *I;
354*d5a2a073SDaniel Dunbar     }
355*d5a2a073SDaniel Dunbar 
356*d5a2a073SDaniel Dunbar     Diags->Report(diag::err_fe_invoking) << AllArgs << ErrMsg;
357*d5a2a073SDaniel Dunbar   }
358*d5a2a073SDaniel Dunbar 
359*d5a2a073SDaniel Dunbar   // Parse the resulting source file to find code-completion results.
360*d5a2a073SDaniel Dunbar   using llvm::MemoryBuffer;
361*d5a2a073SDaniel Dunbar   using llvm::StringRef;
362*d5a2a073SDaniel Dunbar   AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults;
363*d5a2a073SDaniel Dunbar   Results->Results = 0;
364*d5a2a073SDaniel Dunbar   Results->NumResults = 0;
365*d5a2a073SDaniel Dunbar   Results->Buffer = 0;
366*d5a2a073SDaniel Dunbar   // FIXME: Set Results->LangOpts!
367*d5a2a073SDaniel Dunbar   if (MemoryBuffer *F = MemoryBuffer::getFile(ResultsFile.c_str())) {
368*d5a2a073SDaniel Dunbar     llvm::SmallVector<CXCompletionResult, 4> CompletionResults;
369*d5a2a073SDaniel Dunbar     StringRef Buffer = F->getBuffer();
370*d5a2a073SDaniel Dunbar     for (const char *Str = Buffer.data(), *StrEnd = Str + Buffer.size();
371*d5a2a073SDaniel Dunbar          Str < StrEnd;) {
372*d5a2a073SDaniel Dunbar       unsigned KindValue;
373*d5a2a073SDaniel Dunbar       if (ReadUnsigned(Str, StrEnd, KindValue))
374*d5a2a073SDaniel Dunbar         break;
375*d5a2a073SDaniel Dunbar 
376*d5a2a073SDaniel Dunbar       CodeCompletionString *CCStr
377*d5a2a073SDaniel Dunbar         = CodeCompletionString::Deserialize(Str, StrEnd);
378*d5a2a073SDaniel Dunbar       if (!CCStr)
379*d5a2a073SDaniel Dunbar         continue;
380*d5a2a073SDaniel Dunbar 
381*d5a2a073SDaniel Dunbar       if (!CCStr->empty()) {
382*d5a2a073SDaniel Dunbar         // Vend the code-completion result to the caller.
383*d5a2a073SDaniel Dunbar         CXCompletionResult Result;
384*d5a2a073SDaniel Dunbar         Result.CursorKind = (CXCursorKind)KindValue;
385*d5a2a073SDaniel Dunbar         Result.CompletionString = CCStr;
386*d5a2a073SDaniel Dunbar         CompletionResults.push_back(Result);
387*d5a2a073SDaniel Dunbar       }
388*d5a2a073SDaniel Dunbar     };
389*d5a2a073SDaniel Dunbar 
390*d5a2a073SDaniel Dunbar     // Allocate the results.
391*d5a2a073SDaniel Dunbar     Results->Results = new CXCompletionResult [CompletionResults.size()];
392*d5a2a073SDaniel Dunbar     Results->NumResults = CompletionResults.size();
393*d5a2a073SDaniel Dunbar     memcpy(Results->Results, CompletionResults.data(),
394*d5a2a073SDaniel Dunbar            CompletionResults.size() * sizeof(CXCompletionResult));
395*d5a2a073SDaniel Dunbar     Results->Buffer = F;
396*d5a2a073SDaniel Dunbar   }
397*d5a2a073SDaniel Dunbar 
398*d5a2a073SDaniel Dunbar   LoadSerializedDiagnostics(DiagnosticsFile, num_unsaved_files, unsaved_files,
399*d5a2a073SDaniel Dunbar                             Results->FileMgr, Results->SourceMgr,
400*d5a2a073SDaniel Dunbar                             Results->Diagnostics);
401*d5a2a073SDaniel Dunbar 
402*d5a2a073SDaniel Dunbar   // Make sure we delete temporary files when the code-completion results are
403*d5a2a073SDaniel Dunbar   // destroyed.
404*d5a2a073SDaniel Dunbar   Results->TemporaryFiles.swap(TemporaryFiles);
405*d5a2a073SDaniel Dunbar 
406*d5a2a073SDaniel Dunbar #ifdef UDP_CODE_COMPLETION_LOGGER
407*d5a2a073SDaniel Dunbar #ifdef UDP_CODE_COMPLETION_LOGGER_PORT
408*d5a2a073SDaniel Dunbar   const llvm::TimeRecord &EndTime =  llvm::TimeRecord::getCurrentTime();
409*d5a2a073SDaniel Dunbar   llvm::SmallString<256> LogResult;
410*d5a2a073SDaniel Dunbar   llvm::raw_svector_ostream os(LogResult);
411*d5a2a073SDaniel Dunbar 
412*d5a2a073SDaniel Dunbar   // Figure out the language and whether or not it uses PCH.
413*d5a2a073SDaniel Dunbar   const char *lang = 0;
414*d5a2a073SDaniel Dunbar   bool usesPCH = false;
415*d5a2a073SDaniel Dunbar 
416*d5a2a073SDaniel Dunbar   for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
417*d5a2a073SDaniel Dunbar        I != E; ++I) {
418*d5a2a073SDaniel Dunbar     if (*I == 0)
419*d5a2a073SDaniel Dunbar       continue;
420*d5a2a073SDaniel Dunbar     if (strcmp(*I, "-x") == 0) {
421*d5a2a073SDaniel Dunbar       if (I + 1 != E) {
422*d5a2a073SDaniel Dunbar         lang = *(++I);
423*d5a2a073SDaniel Dunbar         continue;
424*d5a2a073SDaniel Dunbar       }
425*d5a2a073SDaniel Dunbar     }
426*d5a2a073SDaniel Dunbar     else if (strcmp(*I, "-include") == 0) {
427*d5a2a073SDaniel Dunbar       if (I+1 != E) {
428*d5a2a073SDaniel Dunbar         const char *arg = *(++I);
429*d5a2a073SDaniel Dunbar         llvm::SmallString<512> pchName;
430*d5a2a073SDaniel Dunbar         {
431*d5a2a073SDaniel Dunbar           llvm::raw_svector_ostream os(pchName);
432*d5a2a073SDaniel Dunbar           os << arg << ".pth";
433*d5a2a073SDaniel Dunbar         }
434*d5a2a073SDaniel Dunbar         pchName.push_back('\0');
435*d5a2a073SDaniel Dunbar         struct stat stat_results;
436*d5a2a073SDaniel Dunbar         if (stat(pchName.data(), &stat_results) == 0)
437*d5a2a073SDaniel Dunbar           usesPCH = true;
438*d5a2a073SDaniel Dunbar         continue;
439*d5a2a073SDaniel Dunbar       }
440*d5a2a073SDaniel Dunbar     }
441*d5a2a073SDaniel Dunbar   }
442*d5a2a073SDaniel Dunbar 
443*d5a2a073SDaniel Dunbar   os << "{ ";
444*d5a2a073SDaniel Dunbar   os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
445*d5a2a073SDaniel Dunbar   os << ", \"numRes\": " << Results->NumResults;
446*d5a2a073SDaniel Dunbar   os << ", \"diags\": " << Results->Diagnostics.size();
447*d5a2a073SDaniel Dunbar   os << ", \"pch\": " << (usesPCH ? "true" : "false");
448*d5a2a073SDaniel Dunbar   os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
449*d5a2a073SDaniel Dunbar   const char *name = getlogin();
450*d5a2a073SDaniel Dunbar   os << ", \"user\": \"" << (name ? name : "unknown") << '"';
451*d5a2a073SDaniel Dunbar   os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
452*d5a2a073SDaniel Dunbar   os << " }";
453*d5a2a073SDaniel Dunbar 
454*d5a2a073SDaniel Dunbar   llvm::StringRef res = os.str();
455*d5a2a073SDaniel Dunbar   if (res.size() > 0) {
456*d5a2a073SDaniel Dunbar     do {
457*d5a2a073SDaniel Dunbar       // Setup the UDP socket.
458*d5a2a073SDaniel Dunbar       struct sockaddr_in servaddr;
459*d5a2a073SDaniel Dunbar       bzero(&servaddr, sizeof(servaddr));
460*d5a2a073SDaniel Dunbar       servaddr.sin_family = AF_INET;
461*d5a2a073SDaniel Dunbar       servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
462*d5a2a073SDaniel Dunbar       if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
463*d5a2a073SDaniel Dunbar                     &servaddr.sin_addr) <= 0)
464*d5a2a073SDaniel Dunbar         break;
465*d5a2a073SDaniel Dunbar 
466*d5a2a073SDaniel Dunbar       int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
467*d5a2a073SDaniel Dunbar       if (sockfd < 0)
468*d5a2a073SDaniel Dunbar         break;
469*d5a2a073SDaniel Dunbar 
470*d5a2a073SDaniel Dunbar       sendto(sockfd, res.data(), res.size(), 0,
471*d5a2a073SDaniel Dunbar              (struct sockaddr *)&servaddr, sizeof(servaddr));
472*d5a2a073SDaniel Dunbar       close(sockfd);
473*d5a2a073SDaniel Dunbar     }
474*d5a2a073SDaniel Dunbar     while (false);
475*d5a2a073SDaniel Dunbar   }
476*d5a2a073SDaniel Dunbar #endif
477*d5a2a073SDaniel Dunbar #endif
478*d5a2a073SDaniel Dunbar   return Results;
479*d5a2a073SDaniel Dunbar }
480*d5a2a073SDaniel Dunbar 
481*d5a2a073SDaniel Dunbar void clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) {
482*d5a2a073SDaniel Dunbar   if (!ResultsIn)
483*d5a2a073SDaniel Dunbar     return;
484*d5a2a073SDaniel Dunbar 
485*d5a2a073SDaniel Dunbar   AllocatedCXCodeCompleteResults *Results
486*d5a2a073SDaniel Dunbar     = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
487*d5a2a073SDaniel Dunbar   delete Results;
488*d5a2a073SDaniel Dunbar }
489*d5a2a073SDaniel Dunbar 
490*d5a2a073SDaniel Dunbar unsigned
491*d5a2a073SDaniel Dunbar clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) {
492*d5a2a073SDaniel Dunbar   AllocatedCXCodeCompleteResults *Results
493*d5a2a073SDaniel Dunbar     = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
494*d5a2a073SDaniel Dunbar   if (!Results)
495*d5a2a073SDaniel Dunbar     return 0;
496*d5a2a073SDaniel Dunbar 
497*d5a2a073SDaniel Dunbar   return Results->Diagnostics.size();
498*d5a2a073SDaniel Dunbar }
499*d5a2a073SDaniel Dunbar 
500*d5a2a073SDaniel Dunbar CXDiagnostic
501*d5a2a073SDaniel Dunbar clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn,
502*d5a2a073SDaniel Dunbar                                 unsigned Index) {
503*d5a2a073SDaniel Dunbar   AllocatedCXCodeCompleteResults *Results
504*d5a2a073SDaniel Dunbar     = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
505*d5a2a073SDaniel Dunbar   if (!Results || Index >= Results->Diagnostics.size())
506*d5a2a073SDaniel Dunbar     return 0;
507*d5a2a073SDaniel Dunbar 
508*d5a2a073SDaniel Dunbar   return new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts);
509*d5a2a073SDaniel Dunbar }
510*d5a2a073SDaniel Dunbar 
511*d5a2a073SDaniel Dunbar 
512*d5a2a073SDaniel Dunbar } // end extern "C"
513