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