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