CIndexCodeCompletion.cpp revision b1fd3458680bc9c8988dee8967e9c0709fef3945
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;
5112e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
5212e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  public:
5312e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    CXStoredCodeCompletionString(unsigned Priority) : Priority(Priority) { }
5412e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
5512e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    unsigned getPriority() const { return Priority; }
5612e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  };
5712e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor}
5812e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
59ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekextern "C" {
60ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
61ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekenum CXCompletionChunkKind
62ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekclang_getCompletionChunkKind(CXCompletionString completion_string,
63ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                             unsigned chunk_number) {
6412e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
6512e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
66ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (!CCStr || chunk_number >= CCStr->size())
67ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Text;
68ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
69ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  switch ((*CCStr)[chunk_number].Kind) {
70ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_TypedText:
71ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_TypedText;
72ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Text:
73ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Text;
74ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Optional:
75ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Optional;
76ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Placeholder:
77ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Placeholder;
78ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Informative:
79ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Informative;
80ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_ResultType:
81ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_ResultType;
82ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_CurrentParameter:
83ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_CurrentParameter;
84ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftParen:
85ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_LeftParen;
86ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightParen:
87ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_RightParen;
88ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBracket:
89ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_LeftBracket;
90ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBracket:
91ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_RightBracket;
92ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBrace:
93ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_LeftBrace;
94ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBrace:
95ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_RightBrace;
96ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftAngle:
97ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_LeftAngle;
98ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightAngle:
99ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_RightAngle;
100ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Comma:
101ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Comma;
10201dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Colon:
10301dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_Colon;
10401dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_SemiColon:
10501dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_SemiColon;
10601dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Equal:
10701dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_Equal;
10801dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_HorizontalSpace:
10901dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_HorizontalSpace;
11001dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_VerticalSpace:
11101dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_VerticalSpace;
112ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
113ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
114ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Should be unreachable, but let's be careful.
115ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  return CXCompletionChunk_Text;
116ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
117ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
1182ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed KremenekCXString clang_getCompletionChunkText(CXCompletionString completion_string,
1192ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek                                      unsigned chunk_number) {
12012e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
12112e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
122ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (!CCStr || chunk_number >= CCStr->size())
1232ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek    return createCXString(0);
124ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
125ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  switch ((*CCStr)[chunk_number].Kind) {
126ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_TypedText:
127ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Text:
128ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Placeholder:
129ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_CurrentParameter:
130ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Informative:
131ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftParen:
132ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightParen:
133ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBracket:
134ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBracket:
135ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBrace:
136ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBrace:
137ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftAngle:
138ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightAngle:
139ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Comma:
140ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_ResultType:
14101dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Colon:
14201dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_SemiColon:
14301dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Equal:
14401dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_HorizontalSpace:
1452ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek    return createCXString((*CCStr)[chunk_number].Text, false);
146ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
14721c241ff68c18ad87e1f18a579c535385aec7af1Douglas Gregor  case CodeCompletionString::CK_VerticalSpace:
14821c241ff68c18ad87e1f18a579c535385aec7af1Douglas Gregor    // FIXME: Temporary hack until we figure out how to handle vertical space.
14921c241ff68c18ad87e1f18a579c535385aec7af1Douglas Gregor    return createCXString(" ");
15021c241ff68c18ad87e1f18a579c535385aec7af1Douglas Gregor
151ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Optional:
152ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    // Note: treated as an empty text block.
1532ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek    return createCXString("");
154ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
155ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
156ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Should be unreachable, but let's be careful.
1572ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek  return createCXString(0);
158ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
159ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
1602ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek
161ab1889321f6f8f200f2b318ac26883ac18e49d03Ted KremenekCXCompletionString
162ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekclang_getCompletionChunkCompletionString(CXCompletionString completion_string,
163ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                         unsigned chunk_number) {
16412e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
16512e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
166ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (!CCStr || chunk_number >= CCStr->size())
167ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return 0;
168ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
169ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  switch ((*CCStr)[chunk_number].Kind) {
170ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_TypedText:
171ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Text:
172ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Placeholder:
173ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_CurrentParameter:
174ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Informative:
175ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftParen:
176ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightParen:
177ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBracket:
178ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBracket:
179ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBrace:
180ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBrace:
181ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftAngle:
182ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightAngle:
183ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Comma:
184ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_ResultType:
18501dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Colon:
18601dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_SemiColon:
18701dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Equal:
18801dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_HorizontalSpace:
18901dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_VerticalSpace:
190ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return 0;
191ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
192ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Optional:
193ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    // Note: treated as an empty text block.
194ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return (*CCStr)[chunk_number].Optional;
195ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
196ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
197ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Should be unreachable, but let's be careful.
198ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  return 0;
199ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
200ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
201ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekunsigned clang_getNumCompletionChunks(CXCompletionString completion_string) {
20212e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
20312e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
204ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  return CCStr? CCStr->size() : 0;
205ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
206ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
20712e131385e892e3723483a1081a89bcad29c8a84Douglas Gregorunsigned clang_getCompletionPriority(CXCompletionString completion_string) {
20812e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
20912e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
210a2ace58cf99f9279a7467d987c6094145dd19d8bBill Wendling  return CCStr? CCStr->getPriority() : unsigned(CCP_Unlikely);
21112e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor}
21212e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
213ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekstatic bool ReadUnsigned(const char *&Memory, const char *MemoryEnd,
214ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                         unsigned &Value) {
215ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (Memory + sizeof(unsigned) > MemoryEnd)
216ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return true;
217ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
218ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  memmove(&Value, Memory, sizeof(unsigned));
219ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  Memory += sizeof(unsigned);
220ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  return false;
221ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
222ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
223ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek/// \brief The CXCodeCompleteResults structure we allocate internally;
224ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek/// the client only sees the initial CXCodeCompleteResults structure.
225ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekstruct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
2260a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  AllocatedCXCodeCompleteResults();
2270a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  ~AllocatedCXCodeCompleteResults();
2280a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
229a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  /// \brief Diagnostics produced while performing code completion.
230a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  llvm::SmallVector<StoredDiagnostic, 8> Diagnostics;
231a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
232f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor  /// \brief Diag object
2331abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::IntrusiveRefCntPtr<Diagnostic> Diag;
234f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor
235a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  /// \brief Language options used to adjust source locations.
23635b8440f615a2336f2819a98a78fc89f07d905e1Daniel Dunbar  LangOptions LangOpts;
237a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
238a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  /// \brief Source manager, used for diagnostics.
239a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  SourceManager SourceMgr;
240a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
241a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  /// \brief File manager, used for diagnostics.
242a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  FileManager FileMgr;
243313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor
244313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  /// \brief Temporary files that should be removed once we have finished
245313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  /// with the code-completion results.
246313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  std::vector<llvm::sys::Path> TemporaryFiles;
247b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor
248b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  /// \brief Temporary buffers that will be deleted once we have finished with the code-completion results.
249b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  llvm::SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
250ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek};
251ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
2520a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas GregorAllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults()
253b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  : CXCodeCompleteResults(), Diag(new Diagnostic), SourceMgr(*Diag) { }
2540a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2550a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas GregorAllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
2560a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  for (unsigned I = 0, N = NumResults; I != N; ++I)
25712e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    delete (CXStoredCodeCompletionString *)Results[I].CompletionString;
2580a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  delete [] Results;
259313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor
260313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
261313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor    TemporaryFiles[I].eraseFromDisk();
262b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
263b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor    delete TemporaryBuffers[I];
2640a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor}
2650a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
266ab1889321f6f8f200f2b318ac26883ac18e49d03Ted KremenekCXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
267ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          const char *source_filename,
268ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          int num_command_line_args,
269ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          const char **command_line_args,
270ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          unsigned num_unsaved_files,
271ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          struct CXUnsavedFile *unsaved_files,
272ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          const char *complete_filename,
273ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          unsigned complete_line,
274a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                          unsigned complete_column) {
275da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER
276da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
277da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  const llvm::TimeRecord &StartTime =  llvm::TimeRecord::getCurrentTime();
278da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
279da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
280da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
2813d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
282df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
283df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  llvm::OwningPtr<llvm::NamedRegionTimer> CCTimer;
284df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  if (getenv("LIBCLANG_TIMING")) {
285df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    llvm::SmallString<128> TimerName;
286df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    llvm::raw_svector_ostream TimerNameOut(TimerName);
2877a07fcb8f10fe45ea65a0a41798eb1c40777bde4Douglas Gregor    TimerNameOut << "Code completion (out-of-process) @ " << complete_filename
2887a07fcb8f10fe45ea65a0a41798eb1c40777bde4Douglas Gregor      << ":" << complete_line << ":" << complete_column;
289df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    CCTimer.reset(new llvm::NamedRegionTimer(TimerNameOut.str()));
290df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  }
291df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
292ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // The indexer, which is mainly used to determine where diagnostics go.
293ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
294ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
295936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor  // Configure the diagnostics.
296936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor  DiagnosticOptions DiagOpts;
29728019772db70d4547be05a042eb950bc910f134fDouglas Gregor  llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
29828019772db70d4547be05a042eb950bc910f134fDouglas Gregor  Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
299936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor
300ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // The set of temporary files that we've built.
301ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::vector<llvm::sys::Path> TemporaryFiles;
302ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
303ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Build up the arguments for invoking 'clang'.
304ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::vector<const char *> argv;
305ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
306ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // First add the complete path to the 'clang' executable.
307ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  llvm::sys::Path ClangPath = CXXIdx->getClangPath();
308ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back(ClangPath.c_str());
309ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
3103d9c6e1c97bdae6a9daedc6969bc839e93074b0fDaniel Dunbar  // Always use Clang C++ support.
3113d9c6e1c97bdae6a9daedc6969bc839e93074b0fDaniel Dunbar  argv.push_back("-ccc-clang-cxx");
3123d9c6e1c97bdae6a9daedc6969bc839e93074b0fDaniel Dunbar
313ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Add the '-fsyntax-only' argument so that we only perform a basic
314ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // syntax check of the code.
315ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-fsyntax-only");
316ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
317ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Add the appropriate '-code-completion-at=file:line:column' argument
318ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // to perform code completion, with an "-Xclang" preceding it.
319ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::string code_complete_at;
320ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += complete_filename;
321ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += ":";
322ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += llvm::utostr(complete_line);
323ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += ":";
324ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += llvm::utostr(complete_column);
325ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-Xclang");
326ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-code-completion-at");
327ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-Xclang");
328ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back(code_complete_at.c_str());
329ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-Xclang");
330ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-no-code-completion-debug-printer");
331ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-Xclang");
332ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-code-completion-macros");
333d93256e55673a17d18543397ec462416acb13792Douglas Gregor  argv.push_back("-fdiagnostics-binary");
334d93256e55673a17d18543397ec462416acb13792Douglas Gregor
3354db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  // Remap any unsaved files to temporary files.
336ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::vector<std::string> RemapArgs;
3374db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles))
3384db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    return 0;
339ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
340ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // The pointers into the elements of RemapArgs are stable because we
341ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // won't be adding anything to RemapArgs after this point.
342ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i)
343ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    argv.push_back(RemapArgs[i].c_str());
344ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
345ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Add the source file name (FIXME: later, we'll want to build temporary
346ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // file from the buffer, or just feed the source text via standard input).
347ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (source_filename)
348ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    argv.push_back(source_filename);
349ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
350ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'.
351ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  for (int i = 0; i < num_command_line_args; ++i)
352ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    if (const char *arg = command_line_args[i]) {
353ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (strcmp(arg, "-o") == 0) {
354ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        ++i; // Also skip the matching argument.
355ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        continue;
356ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      }
357ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (strcmp(arg, "-emit-ast") == 0 ||
358ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek          strcmp(arg, "-c") == 0 ||
359ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek          strcmp(arg, "-fsyntax-only") == 0) {
360ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        continue;
361ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      }
362ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
363ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      // Keep the argument.
364ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      argv.push_back(arg);
365ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    }
366ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
3673d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor  if (EnableLogging) {
3683d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor    std::string Log = ClangPath.str();
3693d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor    for (unsigned I = 0, N = argv.size(); I != N; ++I) {
3703d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor      Log += ' ';
3713d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor      Log += argv[I];
3723d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor    }
3733d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor    fprintf(stderr, "libclang (Code Completion): %s\n", Log.c_str());
3743d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor  }
3753d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor
376ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Add the null terminator.
377ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back(NULL);
378ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
379d93256e55673a17d18543397ec462416acb13792Douglas Gregor  // Generate a temporary name for the code-completion results file.
380c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  char tmpFile[L_tmpnam];
381c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  char *tmpFileName = tmpnam(tmpFile);
382c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  llvm::sys::Path ResultsFile(tmpFileName);
383ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  TemporaryFiles.push_back(ResultsFile);
384ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
385d93256e55673a17d18543397ec462416acb13792Douglas Gregor  // Generate a temporary name for the diagnostics file.
386c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  char tmpFileResults[L_tmpnam];
387c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  char *tmpResultsFileName = tmpnam(tmpFileResults);
388c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  llvm::sys::Path DiagnosticsFile(tmpResultsFileName);
389d93256e55673a17d18543397ec462416acb13792Douglas Gregor  TemporaryFiles.push_back(DiagnosticsFile);
390d93256e55673a17d18543397ec462416acb13792Douglas Gregor
3913d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor
3923d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor
393ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Invoke 'clang'.
394ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null
395ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                           // on Unix or NUL (Windows).
396ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::string ErrMsg;
397d93256e55673a17d18543397ec462416acb13792Douglas Gregor  const llvm::sys::Path *Redirects[] = { &DevNull, &ResultsFile,
398d93256e55673a17d18543397ec462416acb13792Douglas Gregor                                         &DiagnosticsFile, 0 };
399ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL,
400ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                     /* redirects */ &Redirects[0],
401ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                     /* secondsToWait */ 0,
402ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                     /* memoryLimits */ 0, &ErrMsg);
403ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
404936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor  if (!ErrMsg.empty()) {
405936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor    std::string AllArgs;
406ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
407936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor         I != E; ++I) {
408936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor      AllArgs += ' ';
409ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (*I)
410936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor        AllArgs += *I;
411ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    }
412936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor
41332141c8f69a6a51d7cf95a18229cd335ecd59903Daniel Dunbar    Diags->Report(diag::err_fe_invoking) << AllArgs << ErrMsg;
414ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
415ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
416ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Parse the resulting source file to find code-completion results.
417ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  using llvm::MemoryBuffer;
418ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  using llvm::StringRef;
419a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults;
420a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  Results->Results = 0;
421a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  Results->NumResults = 0;
422a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  // FIXME: Set Results->LangOpts!
423ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (MemoryBuffer *F = MemoryBuffer::getFile(ResultsFile.c_str())) {
424ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    llvm::SmallVector<CXCompletionResult, 4> CompletionResults;
425ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    StringRef Buffer = F->getBuffer();
426ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    for (const char *Str = Buffer.data(), *StrEnd = Str + Buffer.size();
427ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek         Str < StrEnd;) {
428ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      unsigned KindValue;
429ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (ReadUnsigned(Str, StrEnd, KindValue))
430ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        break;
431ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
43212e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      unsigned Priority;
43312e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      if (ReadUnsigned(Str, StrEnd, Priority))
43412e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor        break;
43512e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
43612e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      CXStoredCodeCompletionString *CCStr
43712e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor        = new CXStoredCodeCompletionString(Priority);
43812e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      if (!CCStr->Deserialize(Str, StrEnd)) {
43912e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor        delete CCStr;
440ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        continue;
44112e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      }
442ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
443ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (!CCStr->empty()) {
444ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        // Vend the code-completion result to the caller.
445ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        CXCompletionResult Result;
446ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        Result.CursorKind = (CXCursorKind)KindValue;
447ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        Result.CompletionString = CCStr;
448ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        CompletionResults.push_back(Result);
449ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      }
450ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    };
451ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
452ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    // Allocate the results.
453ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    Results->Results = new CXCompletionResult [CompletionResults.size()];
454ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    Results->NumResults = CompletionResults.size();
455ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    memcpy(Results->Results, CompletionResults.data(),
456ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek           CompletionResults.size() * sizeof(CXCompletionResult));
457b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor    Results->TemporaryBuffers.push_back(F);
458ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
459ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
460a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  LoadSerializedDiagnostics(DiagnosticsFile, num_unsaved_files, unsaved_files,
461a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                            Results->FileMgr, Results->SourceMgr,
462a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                            Results->Diagnostics);
463a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
464313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  // Make sure we delete temporary files when the code-completion results are
465313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  // destroyed.
466313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  Results->TemporaryFiles.swap(TemporaryFiles);
4671abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
4681abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#ifdef UDP_CODE_COMPLETION_LOGGER
4691abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
4701abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  const llvm::TimeRecord &EndTime =  llvm::TimeRecord::getCurrentTime();
4711abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::SmallString<256> LogResult;
4721abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::raw_svector_ostream os(LogResult);
4731abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
4741abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Figure out the language and whether or not it uses PCH.
4751abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  const char *lang = 0;
4761abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  bool usesPCH = false;
4771abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
4781abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
4791abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor       I != E; ++I) {
4801abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    if (*I == 0)
4811abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      continue;
4821abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    if (strcmp(*I, "-x") == 0) {
4831abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      if (I + 1 != E) {
4841abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        lang = *(++I);
4851abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        continue;
4861abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      }
4871abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    }
4881abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    else if (strcmp(*I, "-include") == 0) {
4891abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      if (I+1 != E) {
4901abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        const char *arg = *(++I);
4911abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        llvm::SmallString<512> pchName;
4921abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        {
4931abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor          llvm::raw_svector_ostream os(pchName);
4941abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor          os << arg << ".pth";
4951abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        }
4961abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        pchName.push_back('\0');
4971abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        struct stat stat_results;
4981abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        if (stat(pchName.data(), &stat_results) == 0)
4991abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor          usesPCH = true;
5001abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        continue;
5011abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      }
5021abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    }
5031abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
5041abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5051abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << "{ ";
5061abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
5071abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"numRes\": " << Results->NumResults;
5081abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"diags\": " << Results->Diagnostics.size();
5091abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"pch\": " << (usesPCH ? "true" : "false");
5101abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
5111abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  const char *name = getlogin();
5121abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"user\": \"" << (name ? name : "unknown") << '"';
5131abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
5141abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << " }";
5151abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::StringRef res = os.str();
5171abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  if (res.size() > 0) {
5181abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    do {
5191abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      // Setup the UDP socket.
5201abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      struct sockaddr_in servaddr;
5211abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      bzero(&servaddr, sizeof(servaddr));
5221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      servaddr.sin_family = AF_INET;
5231abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
5241abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
5251abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                    &servaddr.sin_addr) <= 0)
5261abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        break;
5271abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5281abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
5291abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      if (sockfd < 0)
5301abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        break;
5311abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5321abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      sendto(sockfd, res.data(), res.size(), 0,
5331abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor             (struct sockaddr *)&servaddr, sizeof(servaddr));
5341abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      close(sockfd);
5351abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    }
5361abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    while (false);
5371abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
5381abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#endif
5391abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#endif
5401abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  return Results;
5411abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor}
5421abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5431abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor} // end extern "C"
5441abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5451abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregornamespace {
5461abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  class CaptureCompletionResults : public CodeCompleteConsumer {
5471abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    AllocatedCXCodeCompleteResults &AllocatedResults;
5481abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5491abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  public:
5501abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    explicit CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results)
5518071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor      : CodeCompleteConsumer(true, false, true, false),
5528071e4212ae08f8014e0c3ae6d18b7388003a5ccDouglas Gregor        AllocatedResults(Results) { }
5531abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
554e6b1bb6e7fe906d164637ca33503b8fafdbc99e5Douglas Gregor    virtual void ProcessCodeCompleteResults(Sema &S,
555e6b1bb6e7fe906d164637ca33503b8fafdbc99e5Douglas Gregor                                            CodeCompletionContext Context,
556e6b1bb6e7fe906d164637ca33503b8fafdbc99e5Douglas Gregor                                            Result *Results,
5571abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                                            unsigned NumResults) {
5581abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      AllocatedResults.Results = new CXCompletionResult [NumResults];
5591abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      AllocatedResults.NumResults = NumResults;
5601abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      for (unsigned I = 0; I != NumResults; ++I) {
5611abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        CXStoredCodeCompletionString *StoredCompletion
5621abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor          = new CXStoredCodeCompletionString(Results[I].Priority);
5631abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        (void)Results[I].CreateCodeCompletionString(S, StoredCompletion);
56487c08a5d6b9e1e44ae6f554df40139d3a6f60b33Douglas Gregor        AllocatedResults.Results[I].CursorKind = Results[I].CursorKind;
5651abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        AllocatedResults.Results[I].CompletionString = StoredCompletion;
5661abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      }
5671abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    }
5681abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  };
5691abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor}
5701abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5711abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregorextern "C" {
572b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbarstruct CodeCompleteAtInfo {
573b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CXTranslationUnit TU;
574b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  const char *complete_filename;
575b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned complete_line;
576b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned complete_column;
577b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  struct CXUnsavedFile *unsaved_files;
578b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned num_unsaved_files;
579b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned options;
580b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CXCodeCompleteResults *result;
581b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar};
582b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbarvoid clang_codeCompleteAt_Impl(void *UserData) {
583b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CodeCompleteAtInfo *CCAI = static_cast<CodeCompleteAtInfo*>(UserData);
584b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CXTranslationUnit TU = CCAI->TU;
585b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  const char *complete_filename = CCAI->complete_filename;
586b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned complete_line = CCAI->complete_line;
587b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned complete_column = CCAI->complete_column;
588b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  struct CXUnsavedFile *unsaved_files = CCAI->unsaved_files;
589b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned num_unsaved_files = CCAI->num_unsaved_files;
590b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  unsigned options = CCAI->options;
591b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CCAI->result = 0;
592b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar
5931abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#ifdef UDP_CODE_COMPLETION_LOGGER
5941abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
5951abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  const llvm::TimeRecord &StartTime =  llvm::TimeRecord::getCurrentTime();
5961abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#endif
5971abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#endif
5981abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5991abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
6001abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6011abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  ASTUnit *AST = static_cast<ASTUnit *>(TU);
6021abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  if (!AST)
603b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar    return;
6041abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6051abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Perform the remapping of source files.
6061abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
6071abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  for (unsigned I = 0; I != num_unsaved_files; ++I) {
6081abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
6091abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    const llvm::MemoryBuffer *Buffer
6101abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
6111abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
6121abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                                           Buffer));
6131abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
6141abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6151abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  if (EnableLogging) {
6161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    // FIXME: Add logging.
6171abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
6181abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6191abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Parse the resulting source file to find code-completion results.
6201abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults;
6211abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  Results->Results = 0;
6221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  Results->NumResults = 0;
6231abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6241abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Create a code-completion consumer to capture the results.
6251abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  CaptureCompletionResults Capture(*Results);
6261abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
627b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  // Make sure that we free the temporary buffers when the
628b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  // code-completion constructor is freed.
629b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  for (unsigned I = 0, N = RemappedFiles.size(); I != N; ++I)
630b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor    Results->TemporaryBuffers.push_back(RemappedFiles[I].second);
631b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor
6321abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Perform completion.
6331abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  AST->CodeComplete(complete_filename, complete_line, complete_column,
634cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                    RemappedFiles.data(), RemappedFiles.size(),
635cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                    (options & CXCodeComplete_IncludeMacros),
636cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                    (options & CXCodeComplete_IncludeCodePatterns),
637cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                    Capture,
6381abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                    *Results->Diag, Results->LangOpts, Results->SourceMgr,
6391abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                    Results->FileMgr, Results->Diagnostics);
6401abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6411abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
642ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
643da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER
644da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
645da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  const llvm::TimeRecord &EndTime =  llvm::TimeRecord::getCurrentTime();
646da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  llvm::SmallString<256> LogResult;
647da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  llvm::raw_svector_ostream os(LogResult);
648da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
649da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  // Figure out the language and whether or not it uses PCH.
650da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  const char *lang = 0;
651da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  bool usesPCH = false;
652da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
653da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
654da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek       I != E; ++I) {
655da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    if (*I == 0)
656da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      continue;
657da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    if (strcmp(*I, "-x") == 0) {
658da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      if (I + 1 != E) {
659da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        lang = *(++I);
660da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        continue;
661da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      }
662da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    }
663da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    else if (strcmp(*I, "-include") == 0) {
664da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      if (I+1 != E) {
665da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        const char *arg = *(++I);
666da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        llvm::SmallString<512> pchName;
667da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        {
668da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek          llvm::raw_svector_ostream os(pchName);
669da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek          os << arg << ".pth";
670da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        }
671da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        pchName.push_back('\0');
672da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        struct stat stat_results;
673da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        if (stat(pchName.data(), &stat_results) == 0)
674da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek          usesPCH = true;
675da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        continue;
676da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      }
677da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    }
678da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  }
679da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
6802ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << "{ ";
6812ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
6822ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"numRes\": " << Results->NumResults;
6832ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"diags\": " << Results->Diagnostics.size();
6842ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"pch\": " << (usesPCH ? "true" : "false");
6852ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
686da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  const char *name = getlogin();
6872ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"user\": \"" << (name ? name : "unknown") << '"';
6882ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
6892ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << " }";
690da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
691da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  llvm::StringRef res = os.str();
692da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  if (res.size() > 0) {
693da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    do {
694da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      // Setup the UDP socket.
695da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      struct sockaddr_in servaddr;
696da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      bzero(&servaddr, sizeof(servaddr));
697da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      servaddr.sin_family = AF_INET;
698da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
699da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
700da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek                    &servaddr.sin_addr) <= 0)
701da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        break;
702da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
703da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
704da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      if (sockfd < 0)
705da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        break;
706da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
707da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      sendto(sockfd, res.data(), res.size(), 0,
708da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek             (struct sockaddr *)&servaddr, sizeof(servaddr));
709da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      close(sockfd);
710da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    }
711da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    while (false);
712da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  }
713da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
714da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
715b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CCAI->result = Results;
716b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar}
717b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel DunbarCXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
718b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                                            const char *complete_filename,
719b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                                            unsigned complete_line,
720b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                                            unsigned complete_column,
721b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                                            struct CXUnsavedFile *unsaved_files,
722b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                                            unsigned num_unsaved_files,
723b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                                            unsigned options) {
724b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  CodeCompleteAtInfo CCAI = { TU, complete_filename, complete_line,
725b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                              complete_column, unsaved_files, num_unsaved_files,
726b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar                              options, 0 };
727b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  llvm::CrashRecoveryContext CRC;
728b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar
729b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  if (!CRC.RunSafely(clang_codeCompleteAt_Impl, &CCAI)) {
730b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar    fprintf(stderr, "libclang: crash detected in code completion\n");
731b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar    static_cast<ASTUnit *>(TU)->setUnsafeToFree(true);
732b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar    return 0;
733b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  }
734b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar
735b1fd3458680bc9c8988dee8967e9c0709fef3945Daniel Dunbar  return CCAI.result;
736ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
737ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
738cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregorunsigned clang_defaultCodeCompleteOptions(void) {
739cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor  return CXCodeComplete_IncludeMacros;
740cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor}
741cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor
742ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekvoid clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) {
743ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (!ResultsIn)
744ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return;
745ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
746ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  AllocatedCXCodeCompleteResults *Results
747ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
748ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  delete Results;
749ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
750ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
751a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorunsigned
752a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) {
753a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  AllocatedCXCodeCompleteResults *Results
754a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
755a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  if (!Results)
756a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    return 0;
757a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
758a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  return Results->Diagnostics.size();
759a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}
760a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
761a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas GregorCXDiagnostic
762a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn,
763a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                unsigned Index) {
764a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  AllocatedCXCodeCompleteResults *Results
765a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
766a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  if (!Results || Index >= Results->Diagnostics.size())
767a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    return 0;
768a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
769a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  return new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts);
770a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}
771a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
772a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
773ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek} // end extern "C"
774