CIndexCodeCompletion.cpp revision df95a13ec73d2cdaea79555cb412d767f4963120
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"
25ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "llvm/Support/MemoryBuffer.h"
26df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor#include "llvm/Support/Timer.h"
27df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor#include "llvm/Support/raw_ostream.h"
28ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek#include "llvm/System/Program.h"
293d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor#include <cstdlib>
303d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor#include <cstdio>
31ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
32df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
33da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER
34da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#include "clang/Basic/Version.h"
35da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#include <arpa/inet.h>
36da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#include <sys/socket.h>
37da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#include <sys/types.h>
38da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#include <unistd.h>
39da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
40da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
41ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekusing namespace clang;
422ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenekusing namespace clang::cxstring;
43ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
4412e131385e892e3723483a1081a89bcad29c8a84Douglas Gregornamespace {
4512e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  /// \brief Stored representation of a completion string.
4612e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  ///
4712e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  /// This is the representation behind a CXCompletionString.
4812e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  class CXStoredCodeCompletionString : public CodeCompletionString {
4912e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    unsigned Priority;
5012e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
5112e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  public:
5212e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    CXStoredCodeCompletionString(unsigned Priority) : Priority(Priority) { }
5312e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
5412e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    unsigned getPriority() const { return Priority; }
5512e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  };
5612e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor}
5712e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
58ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekextern "C" {
59ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
60ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekenum CXCompletionChunkKind
61ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekclang_getCompletionChunkKind(CXCompletionString completion_string,
62ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                             unsigned chunk_number) {
6312e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
6412e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
65ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (!CCStr || chunk_number >= CCStr->size())
66ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Text;
67ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
68ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  switch ((*CCStr)[chunk_number].Kind) {
69ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_TypedText:
70ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_TypedText;
71ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Text:
72ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Text;
73ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Optional:
74ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Optional;
75ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Placeholder:
76ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Placeholder;
77ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Informative:
78ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Informative;
79ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_ResultType:
80ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_ResultType;
81ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_CurrentParameter:
82ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_CurrentParameter;
83ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftParen:
84ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_LeftParen;
85ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightParen:
86ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_RightParen;
87ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBracket:
88ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_LeftBracket;
89ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBracket:
90ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_RightBracket;
91ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBrace:
92ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_LeftBrace;
93ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBrace:
94ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_RightBrace;
95ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftAngle:
96ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_LeftAngle;
97ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightAngle:
98ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_RightAngle;
99ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Comma:
100ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return CXCompletionChunk_Comma;
10101dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Colon:
10201dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_Colon;
10301dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_SemiColon:
10401dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_SemiColon;
10501dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Equal:
10601dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_Equal;
10701dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_HorizontalSpace:
10801dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_HorizontalSpace;
10901dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_VerticalSpace:
11001dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor    return CXCompletionChunk_VerticalSpace;
111ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
112ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
113ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Should be unreachable, but let's be careful.
114ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  return CXCompletionChunk_Text;
115ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
116ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
1172ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed KremenekCXString clang_getCompletionChunkText(CXCompletionString completion_string,
1182ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek                                      unsigned chunk_number) {
11912e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
12012e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
121ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (!CCStr || chunk_number >= CCStr->size())
1222ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek    return createCXString(0);
123ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
124ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  switch ((*CCStr)[chunk_number].Kind) {
125ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_TypedText:
126ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Text:
127ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Placeholder:
128ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_CurrentParameter:
129ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Informative:
130ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftParen:
131ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightParen:
132ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBracket:
133ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBracket:
134ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBrace:
135ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBrace:
136ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftAngle:
137ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightAngle:
138ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Comma:
139ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_ResultType:
14001dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Colon:
14101dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_SemiColon:
14201dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Equal:
14301dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_HorizontalSpace:
1442ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek    return createCXString((*CCStr)[chunk_number].Text, false);
145ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
14621c241ff68c18ad87e1f18a579c535385aec7af1Douglas Gregor  case CodeCompletionString::CK_VerticalSpace:
14721c241ff68c18ad87e1f18a579c535385aec7af1Douglas Gregor    // FIXME: Temporary hack until we figure out how to handle vertical space.
14821c241ff68c18ad87e1f18a579c535385aec7af1Douglas Gregor    return createCXString(" ");
14921c241ff68c18ad87e1f18a579c535385aec7af1Douglas Gregor
150ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Optional:
151ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    // Note: treated as an empty text block.
1522ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek    return createCXString("");
153ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
154ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
155ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Should be unreachable, but let's be careful.
1562ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek  return createCXString(0);
157ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
158ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
1592ef6f8f5a35a60870594c5b04e0aa2bf22c6886fTed Kremenek
160ab1889321f6f8f200f2b318ac26883ac18e49d03Ted KremenekCXCompletionString
161ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekclang_getCompletionChunkCompletionString(CXCompletionString completion_string,
162ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                         unsigned chunk_number) {
16312e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
16412e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
165ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (!CCStr || chunk_number >= CCStr->size())
166ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return 0;
167ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
168ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  switch ((*CCStr)[chunk_number].Kind) {
169ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_TypedText:
170ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Text:
171ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Placeholder:
172ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_CurrentParameter:
173ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Informative:
174ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftParen:
175ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightParen:
176ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBracket:
177ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBracket:
178ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftBrace:
179ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightBrace:
180ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_LeftAngle:
181ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_RightAngle:
182ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Comma:
183ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_ResultType:
18401dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Colon:
18501dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_SemiColon:
18601dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_Equal:
18701dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_HorizontalSpace:
18801dfea02d1da297e8b53db8eea3d3cc652acda8dDouglas Gregor  case CodeCompletionString::CK_VerticalSpace:
189ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return 0;
190ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
191ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  case CodeCompletionString::CK_Optional:
192ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    // Note: treated as an empty text block.
193ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return (*CCStr)[chunk_number].Optional;
194ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
195ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
196ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Should be unreachable, but let's be careful.
197ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  return 0;
198ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
199ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
200ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekunsigned clang_getNumCompletionChunks(CXCompletionString completion_string) {
20112e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
20212e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
203ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  return CCStr? CCStr->size() : 0;
204ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
205ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
20612e131385e892e3723483a1081a89bcad29c8a84Douglas Gregorunsigned clang_getCompletionPriority(CXCompletionString completion_string) {
20712e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor  CXStoredCodeCompletionString *CCStr
20812e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    = (CXStoredCodeCompletionString *)completion_string;
209a2ace58cf99f9279a7467d987c6094145dd19d8bBill Wendling  return CCStr? CCStr->getPriority() : unsigned(CCP_Unlikely);
21012e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor}
21112e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
212ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekstatic bool ReadUnsigned(const char *&Memory, const char *MemoryEnd,
213ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                         unsigned &Value) {
214ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (Memory + sizeof(unsigned) > MemoryEnd)
215ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return true;
216ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
217ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  memmove(&Value, Memory, sizeof(unsigned));
218ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  Memory += sizeof(unsigned);
219ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  return false;
220ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
221ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
222ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek/// \brief The CXCodeCompleteResults structure we allocate internally;
223ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek/// the client only sees the initial CXCodeCompleteResults structure.
224ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekstruct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
2250a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  AllocatedCXCodeCompleteResults();
2260a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  ~AllocatedCXCodeCompleteResults();
2270a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
228a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  /// \brief Diagnostics produced while performing code completion.
229a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  llvm::SmallVector<StoredDiagnostic, 8> Diagnostics;
230a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
231f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor  /// \brief Diag object
2321abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::IntrusiveRefCntPtr<Diagnostic> Diag;
233f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor
234a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  /// \brief Language options used to adjust source locations.
23535b8440f615a2336f2819a98a78fc89f07d905e1Daniel Dunbar  LangOptions LangOpts;
236a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
237a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  /// \brief Source manager, used for diagnostics.
238a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  SourceManager SourceMgr;
239a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
240a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  /// \brief File manager, used for diagnostics.
241a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  FileManager FileMgr;
242313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor
243313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  /// \brief Temporary files that should be removed once we have finished
244313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  /// with the code-completion results.
245313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  std::vector<llvm::sys::Path> TemporaryFiles;
246b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor
247b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  /// \brief Temporary buffers that will be deleted once we have finished with the code-completion results.
248b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  llvm::SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
249ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek};
250ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
2510a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas GregorAllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults()
252b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  : CXCodeCompleteResults(), Diag(new Diagnostic), SourceMgr(*Diag) { }
2530a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
2540a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas GregorAllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
2550a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  for (unsigned I = 0, N = NumResults; I != N; ++I)
25612e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor    delete (CXStoredCodeCompletionString *)Results[I].CompletionString;
2570a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor  delete [] Results;
258313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor
259313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
260313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor    TemporaryFiles[I].eraseFromDisk();
261b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
262b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor    delete TemporaryBuffers[I];
2630a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor}
2640a812cf707da15dadd19fdeb0178b9707f4e01a6Douglas Gregor
265ab1889321f6f8f200f2b318ac26883ac18e49d03Ted KremenekCXCodeCompleteResults *clang_codeComplete(CXIndex CIdx,
266ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          const char *source_filename,
267ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          int num_command_line_args,
268ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          const char **command_line_args,
269ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          unsigned num_unsaved_files,
270ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          struct CXUnsavedFile *unsaved_files,
271ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          const char *complete_filename,
272ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                          unsigned complete_line,
273a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                          unsigned complete_column) {
274da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER
275da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
276da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  const llvm::TimeRecord &StartTime =  llvm::TimeRecord::getCurrentTime();
277da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
278da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
279da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
2803d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
281df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
282df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  llvm::OwningPtr<llvm::NamedRegionTimer> CCTimer;
283df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  if (getenv("LIBCLANG_TIMING")) {
284df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    llvm::SmallString<128> TimerName;
285df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    llvm::raw_svector_ostream TimerNameOut(TimerName);
286df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    TimerNameOut << "Code completion @ " << complete_filename << ":"
287df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor      << complete_line << ":" << complete_column;
288df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor    CCTimer.reset(new llvm::NamedRegionTimer(TimerNameOut.str()));
289df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor  }
290df95a13ec73d2cdaea79555cb412d767f4963120Douglas Gregor
291ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // The indexer, which is mainly used to determine where diagnostics go.
292ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
293ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
294936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor  // Configure the diagnostics.
295936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor  DiagnosticOptions DiagOpts;
29628019772db70d4547be05a042eb950bc910f134fDouglas Gregor  llvm::IntrusiveRefCntPtr<Diagnostic> Diags;
29728019772db70d4547be05a042eb950bc910f134fDouglas Gregor  Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0);
298936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor
299ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // The set of temporary files that we've built.
300ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::vector<llvm::sys::Path> TemporaryFiles;
301ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
302ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Build up the arguments for invoking 'clang'.
303ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::vector<const char *> argv;
304ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
305ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // First add the complete path to the 'clang' executable.
306ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  llvm::sys::Path ClangPath = CXXIdx->getClangPath();
307ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back(ClangPath.c_str());
308ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
3093d9c6e1c97bdae6a9daedc6969bc839e93074b0fDaniel Dunbar  // Always use Clang C++ support.
3103d9c6e1c97bdae6a9daedc6969bc839e93074b0fDaniel Dunbar  argv.push_back("-ccc-clang-cxx");
3113d9c6e1c97bdae6a9daedc6969bc839e93074b0fDaniel Dunbar
312ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Add the '-fsyntax-only' argument so that we only perform a basic
313ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // syntax check of the code.
314ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-fsyntax-only");
315ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
316ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Add the appropriate '-code-completion-at=file:line:column' argument
317ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // to perform code completion, with an "-Xclang" preceding it.
318ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::string code_complete_at;
319ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += complete_filename;
320ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += ":";
321ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += llvm::utostr(complete_line);
322ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += ":";
323ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  code_complete_at += llvm::utostr(complete_column);
324ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-Xclang");
325ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-code-completion-at");
326ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-Xclang");
327ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back(code_complete_at.c_str());
328ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-Xclang");
329ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-no-code-completion-debug-printer");
330ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-Xclang");
331ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back("-code-completion-macros");
332d93256e55673a17d18543397ec462416acb13792Douglas Gregor  argv.push_back("-fdiagnostics-binary");
333d93256e55673a17d18543397ec462416acb13792Douglas Gregor
3344db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  // Remap any unsaved files to temporary files.
335ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::vector<std::string> RemapArgs;
3364db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor  if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles))
3374db64a461cb3442934afe43c83ed3f17f7c11c1dDouglas Gregor    return 0;
338ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
339ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // The pointers into the elements of RemapArgs are stable because we
340ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // won't be adding anything to RemapArgs after this point.
341ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i)
342ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    argv.push_back(RemapArgs[i].c_str());
343ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
344ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Add the source file name (FIXME: later, we'll want to build temporary
345ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // file from the buffer, or just feed the source text via standard input).
346ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (source_filename)
347ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    argv.push_back(source_filename);
348ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
349ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'.
350ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  for (int i = 0; i < num_command_line_args; ++i)
351ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    if (const char *arg = command_line_args[i]) {
352ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (strcmp(arg, "-o") == 0) {
353ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        ++i; // Also skip the matching argument.
354ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        continue;
355ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      }
356ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (strcmp(arg, "-emit-ast") == 0 ||
357ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek          strcmp(arg, "-c") == 0 ||
358ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek          strcmp(arg, "-fsyntax-only") == 0) {
359ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        continue;
360ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      }
361ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
362ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      // Keep the argument.
363ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      argv.push_back(arg);
364ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    }
365ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
3663d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor  if (EnableLogging) {
3673d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor    std::string Log = ClangPath.str();
3683d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor    for (unsigned I = 0, N = argv.size(); I != N; ++I) {
3693d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor      Log += ' ';
3703d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor      Log += argv[I];
3713d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor    }
3723d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor    fprintf(stderr, "libclang (Code Completion): %s\n", Log.c_str());
3733d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor  }
3743d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor
375ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Add the null terminator.
376ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  argv.push_back(NULL);
377ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
378d93256e55673a17d18543397ec462416acb13792Douglas Gregor  // Generate a temporary name for the code-completion results file.
379c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  char tmpFile[L_tmpnam];
380c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  char *tmpFileName = tmpnam(tmpFile);
381c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  llvm::sys::Path ResultsFile(tmpFileName);
382ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  TemporaryFiles.push_back(ResultsFile);
383ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
384d93256e55673a17d18543397ec462416acb13792Douglas Gregor  // Generate a temporary name for the diagnostics file.
385c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  char tmpFileResults[L_tmpnam];
386c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  char *tmpResultsFileName = tmpnam(tmpFileResults);
387c2a981614e324fea7f0a0533f8f1d103cbd17f6dBenjamin Kramer  llvm::sys::Path DiagnosticsFile(tmpResultsFileName);
388d93256e55673a17d18543397ec462416acb13792Douglas Gregor  TemporaryFiles.push_back(DiagnosticsFile);
389d93256e55673a17d18543397ec462416acb13792Douglas Gregor
3903d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor
3913d398aa5c2be8919bbc0144bce611c48119bc861Douglas Gregor
392ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Invoke 'clang'.
393ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null
394ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                           // on Unix or NUL (Windows).
395ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  std::string ErrMsg;
396d93256e55673a17d18543397ec462416acb13792Douglas Gregor  const llvm::sys::Path *Redirects[] = { &DevNull, &ResultsFile,
397d93256e55673a17d18543397ec462416acb13792Douglas Gregor                                         &DiagnosticsFile, 0 };
398ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL,
399ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                     /* redirects */ &Redirects[0],
400ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                     /* secondsToWait */ 0,
401ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek                                     /* memoryLimits */ 0, &ErrMsg);
402ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
403936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor  if (!ErrMsg.empty()) {
404936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor    std::string AllArgs;
405ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
406936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor         I != E; ++I) {
407936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor      AllArgs += ' ';
408ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (*I)
409936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor        AllArgs += *I;
410ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    }
411936ea3b590117d2cd73b1b92621d06c4a7edbe60Douglas Gregor
41232141c8f69a6a51d7cf95a18229cd335ecd59903Daniel Dunbar    Diags->Report(diag::err_fe_invoking) << AllArgs << ErrMsg;
413ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
414ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
415ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  // Parse the resulting source file to find code-completion results.
416ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  using llvm::MemoryBuffer;
417ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  using llvm::StringRef;
418a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults;
419a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  Results->Results = 0;
420a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  Results->NumResults = 0;
421a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  // FIXME: Set Results->LangOpts!
422ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (MemoryBuffer *F = MemoryBuffer::getFile(ResultsFile.c_str())) {
423ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    llvm::SmallVector<CXCompletionResult, 4> CompletionResults;
424ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    StringRef Buffer = F->getBuffer();
425ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    for (const char *Str = Buffer.data(), *StrEnd = Str + Buffer.size();
426ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek         Str < StrEnd;) {
427ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      unsigned KindValue;
428ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (ReadUnsigned(Str, StrEnd, KindValue))
429ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        break;
430ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
43112e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      unsigned Priority;
43212e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      if (ReadUnsigned(Str, StrEnd, Priority))
43312e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor        break;
43412e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor
43512e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      CXStoredCodeCompletionString *CCStr
43612e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor        = new CXStoredCodeCompletionString(Priority);
43712e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      if (!CCStr->Deserialize(Str, StrEnd)) {
43812e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor        delete CCStr;
439ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        continue;
44012e131385e892e3723483a1081a89bcad29c8a84Douglas Gregor      }
441ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
442ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      if (!CCStr->empty()) {
443ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        // Vend the code-completion result to the caller.
444ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        CXCompletionResult Result;
445ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        Result.CursorKind = (CXCursorKind)KindValue;
446ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        Result.CompletionString = CCStr;
447ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek        CompletionResults.push_back(Result);
448ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek      }
449ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    };
450ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
451ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    // Allocate the results.
452ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    Results->Results = new CXCompletionResult [CompletionResults.size()];
453ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    Results->NumResults = CompletionResults.size();
454ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    memcpy(Results->Results, CompletionResults.data(),
455ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek           CompletionResults.size() * sizeof(CXCompletionResult));
456b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor    Results->TemporaryBuffers.push_back(F);
457ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  }
458ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
459a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  LoadSerializedDiagnostics(DiagnosticsFile, num_unsaved_files, unsaved_files,
460a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                            Results->FileMgr, Results->SourceMgr,
461a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                            Results->Diagnostics);
462a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
463313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  // Make sure we delete temporary files when the code-completion results are
464313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  // destroyed.
465313e26c4e81f0e467490a530548450f4c824a6c4Douglas Gregor  Results->TemporaryFiles.swap(TemporaryFiles);
4661abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
4671abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#ifdef UDP_CODE_COMPLETION_LOGGER
4681abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
4691abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  const llvm::TimeRecord &EndTime =  llvm::TimeRecord::getCurrentTime();
4701abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::SmallString<256> LogResult;
4711abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::raw_svector_ostream os(LogResult);
4721abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
4731abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Figure out the language and whether or not it uses PCH.
4741abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  const char *lang = 0;
4751abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  bool usesPCH = false;
4761abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
4771abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
4781abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor       I != E; ++I) {
4791abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    if (*I == 0)
4801abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      continue;
4811abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    if (strcmp(*I, "-x") == 0) {
4821abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      if (I + 1 != E) {
4831abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        lang = *(++I);
4841abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        continue;
4851abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      }
4861abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    }
4871abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    else if (strcmp(*I, "-include") == 0) {
4881abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      if (I+1 != E) {
4891abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        const char *arg = *(++I);
4901abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        llvm::SmallString<512> pchName;
4911abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        {
4921abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor          llvm::raw_svector_ostream os(pchName);
4931abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor          os << arg << ".pth";
4941abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        }
4951abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        pchName.push_back('\0');
4961abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        struct stat stat_results;
4971abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        if (stat(pchName.data(), &stat_results) == 0)
4981abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor          usesPCH = true;
4991abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        continue;
5001abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      }
5011abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    }
5021abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
5031abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5041abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << "{ ";
5051abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
5061abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"numRes\": " << Results->NumResults;
5071abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"diags\": " << Results->Diagnostics.size();
5081abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"pch\": " << (usesPCH ? "true" : "false");
5091abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
5101abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  const char *name = getlogin();
5111abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"user\": \"" << (name ? name : "unknown") << '"';
5121abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
5131abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  os << " }";
5141abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5151abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::StringRef res = os.str();
5161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  if (res.size() > 0) {
5171abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    do {
5181abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      // Setup the UDP socket.
5191abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      struct sockaddr_in servaddr;
5201abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      bzero(&servaddr, sizeof(servaddr));
5211abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      servaddr.sin_family = AF_INET;
5221abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
5231abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
5241abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                    &servaddr.sin_addr) <= 0)
5251abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        break;
5261abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5271abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
5281abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      if (sockfd < 0)
5291abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        break;
5301abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5311abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      sendto(sockfd, res.data(), res.size(), 0,
5321abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor             (struct sockaddr *)&servaddr, sizeof(servaddr));
5331abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      close(sockfd);
5341abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    }
5351abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    while (false);
5361abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
5371abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#endif
5381abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#endif
5391abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  return Results;
5401abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor}
5411abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5421abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor} // end extern "C"
5431abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5441abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregornamespace clang {
5451abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // FIXME: defined in CodeCompleteConsumer.cpp, but should be a
5461abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // static function here.
5471abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  CXCursorKind
5481abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  getCursorKindForCompletionResult(const CodeCompleteConsumer::Result &R);
5491abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor}
5501abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5511abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5521abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregornamespace {
5531abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  class CaptureCompletionResults : public CodeCompleteConsumer {
5541abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    AllocatedCXCodeCompleteResults &AllocatedResults;
5551abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5561abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  public:
5571abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    explicit CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results)
5581abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      : CodeCompleteConsumer(true, false, false), AllocatedResults(Results) { }
5591abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5601abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    virtual void ProcessCodeCompleteResults(Sema &S, Result *Results,
5611abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                                            unsigned NumResults) {
5621abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      AllocatedResults.Results = new CXCompletionResult [NumResults];
5631abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      AllocatedResults.NumResults = NumResults;
5641abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      for (unsigned I = 0; I != NumResults; ++I) {
5651abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        CXStoredCodeCompletionString *StoredCompletion
5661abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor          = new CXStoredCodeCompletionString(Results[I].Priority);
5671abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        (void)Results[I].CreateCodeCompletionString(S, StoredCompletion);
5681abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        AllocatedResults.Results[I].CursorKind
5691abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor          = getCursorKindForCompletionResult(Results[I]);
5701abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor        AllocatedResults.Results[I].CompletionString = StoredCompletion;
5711abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      }
5721abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    }
5731abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  };
5741abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor}
5751abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5761abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregorextern "C" {
5771abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas GregorCXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
5781abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                                            const char *complete_filename,
5791abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                                            unsigned complete_line,
5801abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                                            unsigned complete_column,
5811abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                                            struct CXUnsavedFile *unsaved_files,
582cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                                            unsigned num_unsaved_files,
583cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                                            unsigned options) {
5841abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#ifdef UDP_CODE_COMPLETION_LOGGER
5851abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
5861abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  const llvm::TimeRecord &StartTime =  llvm::TimeRecord::getCurrentTime();
5871abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#endif
5881abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor#endif
5891abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5901abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
5911abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5921abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  ASTUnit *AST = static_cast<ASTUnit *>(TU);
5931abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  if (!AST)
5941abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    return 0;
5951abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
5961abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Perform the remapping of source files.
5971abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
5981abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  for (unsigned I = 0; I != num_unsaved_files; ++I) {
5991abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
6001abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    const llvm::MemoryBuffer *Buffer
6011abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
6021abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
6031abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                                           Buffer));
6041abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
6051abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6061abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  if (EnableLogging) {
6071abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor    // FIXME: Add logging.
6081abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  }
6091abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6101abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Parse the resulting source file to find code-completion results.
6111abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults;
6121abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  Results->Results = 0;
6131abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  Results->NumResults = 0;
6141abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6151abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Create a code-completion consumer to capture the results.
6161abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  CaptureCompletionResults Capture(*Results);
6171abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
618b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  // Make sure that we free the temporary buffers when the
619b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  // code-completion constructor is freed.
620b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor  for (unsigned I = 0, N = RemappedFiles.size(); I != N; ++I)
621b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor    Results->TemporaryBuffers.push_back(RemappedFiles[I].second);
622b75d3dfa4ca6531858b8132eb4db7260408671cfDouglas Gregor
6231abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  // Perform completion.
6241abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor  AST->CodeComplete(complete_filename, complete_line, complete_column,
625cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                    RemappedFiles.data(), RemappedFiles.size(),
626cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                    (options & CXCodeComplete_IncludeMacros),
627cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                    (options & CXCodeComplete_IncludeCodePatterns),
628cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor                    Capture,
6291abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                    *Results->Diag, Results->LangOpts, Results->SourceMgr,
6301abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor                    Results->FileMgr, Results->Diagnostics);
6311abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
6321abc6bca3d7fb0e7b1e40fbcad6cfb5e10594548Douglas Gregor
633ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
634da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER
635da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
636da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  const llvm::TimeRecord &EndTime =  llvm::TimeRecord::getCurrentTime();
637da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  llvm::SmallString<256> LogResult;
638da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  llvm::raw_svector_ostream os(LogResult);
639da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
640da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  // Figure out the language and whether or not it uses PCH.
641da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  const char *lang = 0;
642da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  bool usesPCH = false;
643da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
644da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
645da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek       I != E; ++I) {
646da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    if (*I == 0)
647da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      continue;
648da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    if (strcmp(*I, "-x") == 0) {
649da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      if (I + 1 != E) {
650da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        lang = *(++I);
651da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        continue;
652da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      }
653da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    }
654da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    else if (strcmp(*I, "-include") == 0) {
655da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      if (I+1 != E) {
656da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        const char *arg = *(++I);
657da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        llvm::SmallString<512> pchName;
658da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        {
659da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek          llvm::raw_svector_ostream os(pchName);
660da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek          os << arg << ".pth";
661da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        }
662da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        pchName.push_back('\0');
663da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        struct stat stat_results;
664da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        if (stat(pchName.data(), &stat_results) == 0)
665da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek          usesPCH = true;
666da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        continue;
667da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      }
668da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    }
669da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  }
670da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
6712ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << "{ ";
6722ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
6732ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"numRes\": " << Results->NumResults;
6742ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"diags\": " << Results->Diagnostics.size();
6752ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"pch\": " << (usesPCH ? "true" : "false");
6762ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
677da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  const char *name = getlogin();
6782ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"user\": \"" << (name ? name : "unknown") << '"';
6792ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
6802ee297fab4a818f0d94d74d6c0701c9c5184235dTed Kremenek  os << " }";
681da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
682da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  llvm::StringRef res = os.str();
683da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  if (res.size() > 0) {
684da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    do {
685da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      // Setup the UDP socket.
686da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      struct sockaddr_in servaddr;
687da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      bzero(&servaddr, sizeof(servaddr));
688da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      servaddr.sin_family = AF_INET;
689da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
690da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
691da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek                    &servaddr.sin_addr) <= 0)
692da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        break;
693da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
694da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
695da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      if (sockfd < 0)
696da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek        break;
697da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek
698da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      sendto(sockfd, res.data(), res.size(), 0,
699da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek             (struct sockaddr *)&servaddr, sizeof(servaddr));
700da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek      close(sockfd);
701da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    }
702da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek    while (false);
703da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek  }
704da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
705da7af32f4e4b43b763019e7a522f4bfd5c060d09Ted Kremenek#endif
706ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  return Results;
707ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
708ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
709cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregorunsigned clang_defaultCodeCompleteOptions(void) {
710cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor  return CXCodeComplete_IncludeMacros;
711cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor}
712cee235cdf0b8047761ffac598c4c3a32ab7411a2Douglas Gregor
713ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenekvoid clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) {
714ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  if (!ResultsIn)
715ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    return;
716ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
717ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  AllocatedCXCodeCompleteResults *Results
718ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
719ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek  delete Results;
720ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek}
721ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek
722a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorunsigned
723a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) {
724a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  AllocatedCXCodeCompleteResults *Results
725a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
726a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  if (!Results)
727a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    return 0;
728a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
729a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  return Results->Diagnostics.size();
730a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}
731a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
732a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas GregorCXDiagnostic
733a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregorclang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn,
734a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor                                unsigned Index) {
735a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  AllocatedCXCodeCompleteResults *Results
736a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
737a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  if (!Results || Index >= Results->Diagnostics.size())
738a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor    return 0;
739a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
740a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor  return new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts);
741a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor}
742a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
743a88084b78fd4ca5d3d858c14b02414f8cc399f02Douglas Gregor
744ab1889321f6f8f200f2b318ac26883ac18e49d03Ted Kremenek} // end extern "C"
745