comparison clang-tools-extra/clangd/CodeComplete.cpp @ 221:79ff65ed7e25

LLVM12 Original
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 15 Jun 2021 19:15:29 +0900
parents 0572611fdcc8
children 5f17cb93ff66
comparison
equal deleted inserted replaced
220:42394fc6a535 221:79ff65ed7e25
36 #include "index/Index.h" 36 #include "index/Index.h"
37 #include "index/Symbol.h" 37 #include "index/Symbol.h"
38 #include "index/SymbolOrigin.h" 38 #include "index/SymbolOrigin.h"
39 #include "support/Logger.h" 39 #include "support/Logger.h"
40 #include "support/Threading.h" 40 #include "support/Threading.h"
41 #include "support/ThreadsafeFS.h"
41 #include "support/Trace.h" 42 #include "support/Trace.h"
42 #include "clang/AST/Decl.h" 43 #include "clang/AST/Decl.h"
43 #include "clang/AST/DeclBase.h" 44 #include "clang/AST/DeclBase.h"
44 #include "clang/Basic/CharInfo.h" 45 #include "clang/Basic/CharInfo.h"
45 #include "clang/Basic/LangOptions.h" 46 #include "clang/Basic/LangOptions.h"
46 #include "clang/Basic/SourceLocation.h" 47 #include "clang/Basic/SourceLocation.h"
48 #include "clang/Basic/TokenKinds.h"
47 #include "clang/Format/Format.h" 49 #include "clang/Format/Format.h"
48 #include "clang/Frontend/CompilerInstance.h" 50 #include "clang/Frontend/CompilerInstance.h"
49 #include "clang/Frontend/FrontendActions.h" 51 #include "clang/Frontend/FrontendActions.h"
50 #include "clang/Lex/ExternalPreprocessorSource.h" 52 #include "clang/Lex/ExternalPreprocessorSource.h"
53 #include "clang/Lex/Lexer.h"
51 #include "clang/Lex/Preprocessor.h" 54 #include "clang/Lex/Preprocessor.h"
52 #include "clang/Lex/PreprocessorOptions.h" 55 #include "clang/Lex/PreprocessorOptions.h"
53 #include "clang/Sema/CodeCompleteConsumer.h" 56 #include "clang/Sema/CodeCompleteConsumer.h"
54 #include "clang/Sema/DeclSpec.h" 57 #include "clang/Sema/DeclSpec.h"
55 #include "clang/Sema/Sema.h" 58 #include "clang/Sema/Sema.h"
65 #include "llvm/Support/Format.h" 68 #include "llvm/Support/Format.h"
66 #include "llvm/Support/FormatVariadic.h" 69 #include "llvm/Support/FormatVariadic.h"
67 #include "llvm/Support/ScopedPrinter.h" 70 #include "llvm/Support/ScopedPrinter.h"
68 #include <algorithm> 71 #include <algorithm>
69 #include <iterator> 72 #include <iterator>
73 #include <limits>
70 74
71 // We log detailed candidate here if you run with -debug-only=codecomplete. 75 // We log detailed candidate here if you run with -debug-only=codecomplete.
72 #define DEBUG_TYPE "CodeComplete" 76 #define DEBUG_TYPE "CodeComplete"
73 77
74 namespace clang { 78 namespace clang {
168 const RawIdentifier *IdentifierResult = nullptr; 172 const RawIdentifier *IdentifierResult = nullptr;
169 llvm::SmallVector<llvm::StringRef, 1> RankedIncludeHeaders; 173 llvm::SmallVector<llvm::StringRef, 1> RankedIncludeHeaders;
170 174
171 // Returns a token identifying the overload set this is part of. 175 // Returns a token identifying the overload set this is part of.
172 // 0 indicates it's not part of any overload set. 176 // 0 indicates it's not part of any overload set.
173 size_t overloadSet(const CodeCompleteOptions &Opts) const { 177 size_t overloadSet(const CodeCompleteOptions &Opts, llvm::StringRef FileName,
178 IncludeInserter *Inserter) const {
174 if (!Opts.BundleOverloads.getValueOr(false)) 179 if (!Opts.BundleOverloads.getValueOr(false))
175 return 0; 180 return 0;
181
182 // Depending on the index implementation, we can see different header
183 // strings (literal or URI) mapping to the same file. We still want to
184 // bundle those, so we must resolve the header to be included here.
185 std::string HeaderForHash;
186 if (Inserter) {
187 if (auto Header = headerToInsertIfAllowed(Opts)) {
188 if (auto HeaderFile = toHeaderFile(*Header, FileName)) {
189 if (auto Spelled =
190 Inserter->calculateIncludePath(*HeaderFile, FileName))
191 HeaderForHash = *Spelled;
192 } else {
193 vlog("Code completion header path manipulation failed {0}",
194 HeaderFile.takeError());
195 }
196 }
197 }
198
176 llvm::SmallString<256> Scratch; 199 llvm::SmallString<256> Scratch;
177 if (IndexResult) { 200 if (IndexResult) {
178 switch (IndexResult->SymInfo.Kind) { 201 switch (IndexResult->SymInfo.Kind) {
179 case index::SymbolKind::ClassMethod: 202 case index::SymbolKind::ClassMethod:
180 case index::SymbolKind::InstanceMethod: 203 case index::SymbolKind::InstanceMethod:
187 case index::SymbolKind::Function: 210 case index::SymbolKind::Function:
188 // We can't group overloads together that need different #includes. 211 // We can't group overloads together that need different #includes.
189 // This could break #include insertion. 212 // This could break #include insertion.
190 return llvm::hash_combine( 213 return llvm::hash_combine(
191 (IndexResult->Scope + IndexResult->Name).toStringRef(Scratch), 214 (IndexResult->Scope + IndexResult->Name).toStringRef(Scratch),
192 headerToInsertIfAllowed(Opts).getValueOr("")); 215 HeaderForHash);
193 default: 216 default:
194 return 0; 217 return 0;
195 } 218 }
196 } 219 }
197 if (SemaResult) { 220 if (SemaResult) {
201 return 0; 224 return 0;
202 { 225 {
203 llvm::raw_svector_ostream OS(Scratch); 226 llvm::raw_svector_ostream OS(Scratch);
204 D->printQualifiedName(OS); 227 D->printQualifiedName(OS);
205 } 228 }
206 return llvm::hash_combine(Scratch, 229 return llvm::hash_combine(Scratch, HeaderForHash);
207 headerToInsertIfAllowed(Opts).getValueOr(""));
208 } 230 }
209 assert(IdentifierResult); 231 assert(IdentifierResult);
210 return 0; 232 return 0;
211 } 233 }
212 234
252 CodeCompletionString *SemaCCS, 274 CodeCompletionString *SemaCCS,
253 llvm::ArrayRef<std::string> QueryScopes, 275 llvm::ArrayRef<std::string> QueryScopes,
254 const IncludeInserter &Includes, 276 const IncludeInserter &Includes,
255 llvm::StringRef FileName, 277 llvm::StringRef FileName,
256 CodeCompletionContext::Kind ContextKind, 278 CodeCompletionContext::Kind ContextKind,
257 const CodeCompleteOptions &Opts, bool GenerateSnippets) 279 const CodeCompleteOptions &Opts,
258 : ASTCtx(ASTCtx), ExtractDocumentation(Opts.IncludeComments), 280 bool IsUsingDeclaration, tok::TokenKind NextTokenKind)
281 : ASTCtx(ASTCtx),
259 EnableFunctionArgSnippets(Opts.EnableFunctionArgSnippets), 282 EnableFunctionArgSnippets(Opts.EnableFunctionArgSnippets),
260 GenerateSnippets(GenerateSnippets) { 283 IsUsingDeclaration(IsUsingDeclaration), NextTokenKind(NextTokenKind) {
261 add(C, SemaCCS); 284 add(C, SemaCCS);
262 if (C.SemaResult) { 285 if (C.SemaResult) {
263 assert(ASTCtx); 286 assert(ASTCtx);
264 Completion.Origin |= SymbolOrigin::AST; 287 Completion.Origin |= SymbolOrigin::AST;
265 Completion.Name = std::string(llvm::StringRef(SemaCCS->getTypedText())); 288 Completion.Name = std::string(llvm::StringRef(SemaCCS->getTypedText()));
327 auto ResolvedInserted = toHeaderFile(Header, FileName); 350 auto ResolvedInserted = toHeaderFile(Header, FileName);
328 if (!ResolvedInserted) 351 if (!ResolvedInserted)
329 return ResolvedInserted.takeError(); 352 return ResolvedInserted.takeError();
330 auto Spelled = Includes.calculateIncludePath(*ResolvedInserted, FileName); 353 auto Spelled = Includes.calculateIncludePath(*ResolvedInserted, FileName);
331 if (!Spelled) 354 if (!Spelled)
332 return llvm::createStringError(llvm::inconvertibleErrorCode(), 355 return error("Header not on include path");
333 "Header not on include path");
334 return std::make_pair( 356 return std::make_pair(
335 std::move(*Spelled), 357 std::move(*Spelled),
336 Includes.shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted)); 358 Includes.shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted));
337 }; 359 };
338 bool ShouldInsert = C.headerToInsertIfAllowed(Opts).hasValue(); 360 bool ShouldInsert = C.headerToInsertIfAllowed(Opts).hasValue();
370 } else if (C.IndexResult) { 392 } else if (C.IndexResult) {
371 S.Signature = std::string(C.IndexResult->Signature); 393 S.Signature = std::string(C.IndexResult->Signature);
372 S.SnippetSuffix = std::string(C.IndexResult->CompletionSnippetSuffix); 394 S.SnippetSuffix = std::string(C.IndexResult->CompletionSnippetSuffix);
373 S.ReturnType = std::string(C.IndexResult->ReturnType); 395 S.ReturnType = std::string(C.IndexResult->ReturnType);
374 } 396 }
375 if (ExtractDocumentation && !Completion.Documentation) { 397 if (!Completion.Documentation) {
376 auto SetDoc = [&](llvm::StringRef Doc) { 398 auto SetDoc = [&](llvm::StringRef Doc) {
377 if (!Doc.empty()) { 399 if (!Doc.empty()) {
378 Completion.Documentation.emplace(); 400 Completion.Documentation.emplace();
379 parseDocumentation(Doc, *Completion.Documentation); 401 parseDocumentation(Doc, *Completion.Documentation);
380 } 402 }
426 return *RT; 448 return *RT;
427 return ""; 449 return "";
428 } 450 }
429 451
430 std::string summarizeSnippet() const { 452 std::string summarizeSnippet() const {
431 if (!GenerateSnippets) 453 if (IsUsingDeclaration)
432 return ""; 454 return "";
433 auto *Snippet = onlyValue<&BundledEntry::SnippetSuffix>(); 455 auto *Snippet = onlyValue<&BundledEntry::SnippetSuffix>();
434 if (!Snippet) 456 if (!Snippet)
435 // All bundles are function calls. 457 // All bundles are function calls.
436 // FIXME(ibiryukov): sometimes add template arguments to a snippet, e.g. 458 // FIXME(ibiryukov): sometimes add template arguments to a snippet, e.g.
437 // we need to complete 'forward<$1>($0)'. 459 // we need to complete 'forward<$1>($0)'.
438 return "($0)"; 460 return "($0)";
461 // Suppress function argument snippets cursor is followed by left
462 // parenthesis (and potentially arguments) or if there are potentially
463 // template arguments. There are cases where it would be wrong (e.g. next
464 // '<' token is a comparison rather than template argument list start) but
465 // it is less common and suppressing snippet provides better UX.
466 if (Completion.Kind == CompletionItemKind::Function ||
467 Completion.Kind == CompletionItemKind::Method ||
468 Completion.Kind == CompletionItemKind::Constructor) {
469 // If there is a potential template argument list, drop snippet and just
470 // complete symbol name. Ideally, this could generate an edit that would
471 // paste function arguments after template argument list but it would be
472 // complicated. Example:
473 //
474 // fu^<int> -> function<int>
475 if (NextTokenKind == tok::less && Snippet->front() == '<')
476 return "";
477 // Potentially followed by argument list.
478 if (NextTokenKind == tok::l_paren) {
479 // If snippet contains template arguments we will emit them and drop
480 // function arguments. Example:
481 //
482 // fu^(42) -> function<int>(42);
483 if (Snippet->front() == '<') {
484 // Find matching '>'. Snippet->find('>') will not work in cases like
485 // template <typename T=std::vector<int>>. Hence, iterate through
486 // the snippet until the angle bracket balance reaches zero.
487 int Balance = 0;
488 size_t I = 0;
489 do {
490 if (Snippet->at(I) == '>')
491 --Balance;
492 else if (Snippet->at(I) == '<')
493 ++Balance;
494 ++I;
495 } while (Balance > 0);
496 return Snippet->substr(0, I);
497 }
498 return "";
499 }
500 }
439 if (EnableFunctionArgSnippets) 501 if (EnableFunctionArgSnippets)
440 return *Snippet; 502 return *Snippet;
441 503
442 // Replace argument snippets with a simplified pattern. 504 // Replace argument snippets with a simplified pattern.
443 if (Snippet->empty()) 505 if (Snippet->empty())
483 545
484 // ASTCtx can be nullptr if not run with sema. 546 // ASTCtx can be nullptr if not run with sema.
485 ASTContext *ASTCtx; 547 ASTContext *ASTCtx;
486 CodeCompletion Completion; 548 CodeCompletion Completion;
487 llvm::SmallVector<BundledEntry, 1> Bundled; 549 llvm::SmallVector<BundledEntry, 1> Bundled;
488 bool ExtractDocumentation;
489 bool EnableFunctionArgSnippets; 550 bool EnableFunctionArgSnippets;
490 /// When false, no snippets are generated argument lists. 551 // No snippets will be generated for using declarations and when the function
491 bool GenerateSnippets; 552 // arguments are already present.
553 bool IsUsingDeclaration;
554 tok::TokenKind NextTokenKind;
492 }; 555 };
493 556
494 // Determine the symbol ID for a Sema code completion result, if possible. 557 // Determine the symbol ID for a Sema code completion result, if possible.
495 llvm::Optional<SymbolID> getSymbolID(const CodeCompletionResult &R, 558 SymbolID getSymbolID(const CodeCompletionResult &R, const SourceManager &SM) {
496 const SourceManager &SM) {
497 switch (R.Kind) { 559 switch (R.Kind) {
498 case CodeCompletionResult::RK_Declaration: 560 case CodeCompletionResult::RK_Declaration:
499 case CodeCompletionResult::RK_Pattern: { 561 case CodeCompletionResult::RK_Pattern: {
500 // Computing USR caches linkage, which may change after code completion. 562 // Computing USR caches linkage, which may change after code completion.
501 if (hasUnstableLinkage(R.Declaration)) 563 if (hasUnstableLinkage(R.Declaration))
502 return llvm::None; 564 return {};
503 return clang::clangd::getSymbolID(R.Declaration); 565 return clang::clangd::getSymbolID(R.Declaration);
504 } 566 }
505 case CodeCompletionResult::RK_Macro: 567 case CodeCompletionResult::RK_Macro:
506 return clang::clangd::getSymbolID(R.Macro->getName(), R.MacroDefInfo, SM); 568 return clang::clangd::getSymbolID(R.Macro->getName(), R.MacroDefInfo, SM);
507 case CodeCompletionResult::RK_Keyword: 569 case CodeCompletionResult::RK_Keyword:
508 return None; 570 return {};
509 } 571 }
510 llvm_unreachable("unknown CodeCompletionResult kind"); 572 llvm_unreachable("unknown CodeCompletionResult kind");
511 } 573 }
512 574
513 // Scopes of the partial identifier we're trying to complete. 575 // Scopes of the partial identifier we're trying to complete.
661 if (R->isInjectedClassName()) 723 if (R->isInjectedClassName())
662 return true; 724 return true;
663 return false; 725 return false;
664 } 726 }
665 727
666 // Some member calls are blacklisted because they're so rarely useful. 728 // Some member calls are excluded because they're so rarely useful.
667 static bool isBlacklistedMember(const NamedDecl &D) { 729 static bool isExcludedMember(const NamedDecl &D) {
668 // Destructor completion is rarely useful, and works inconsistently. 730 // Destructor completion is rarely useful, and works inconsistently.
669 // (s.^ completes ~string, but s.~st^ is an error). 731 // (s.^ completes ~string, but s.~st^ is an error).
670 if (D.getKind() == Decl::CXXDestructor) 732 if (D.getKind() == Decl::CXXDestructor)
671 return true; 733 return true;
672 // Injected name may be useful for A::foo(), but who writes A::A::foo()? 734 // Injected name may be useful for A::foo(), but who writes A::A::foo()?
745 (Result.Availability == CXAvailability_NotAvailable || 807 (Result.Availability == CXAvailability_NotAvailable ||
746 Result.Availability == CXAvailability_NotAccessible)) 808 Result.Availability == CXAvailability_NotAccessible))
747 continue; 809 continue;
748 if (Result.Declaration && 810 if (Result.Declaration &&
749 !Context.getBaseType().isNull() // is this a member-access context? 811 !Context.getBaseType().isNull() // is this a member-access context?
750 && isBlacklistedMember(*Result.Declaration)) 812 && isExcludedMember(*Result.Declaration))
751 continue; 813 continue;
752 // Skip injected class name when no class scope is not explicitly set. 814 // Skip injected class name when no class scope is not explicitly set.
753 // E.g. show injected A::A in `using A::A^` but not in "A^". 815 // E.g. show injected A::A in `using A::A^` but not in "A^".
754 if (Result.Declaration && !Context.getCXXScopeSpecifier().hasValue() && 816 if (Result.Declaration && !Context.getCXXScopeSpecifier().hasValue() &&
755 isInjectedClass(*Result.Declaration)) 817 isInjectedClass(*Result.Declaration))
798 CodeCompletionTUInfo CCTUInfo; 860 CodeCompletionTUInfo CCTUInfo;
799 llvm::unique_function<void()> ResultsCallback; 861 llvm::unique_function<void()> ResultsCallback;
800 }; 862 };
801 863
802 struct ScoredSignature { 864 struct ScoredSignature {
803 // When set, requires documentation to be requested from the index with this 865 // When not null, requires documentation to be requested from the index with
804 // ID. 866 // this ID.
805 llvm::Optional<SymbolID> IDForDoc; 867 SymbolID IDForDoc;
806 SignatureInformation Signature; 868 SignatureInformation Signature;
807 SignatureQualitySignals Quality; 869 SignatureQualitySignals Quality;
808 }; 870 };
809 871
810 class SignatureHelpCollector final : public CodeCompleteConsumer { 872 class SignatureHelpCollector final : public CodeCompleteConsumer {
864 if (Index) { 926 if (Index) {
865 LookupRequest IndexRequest; 927 LookupRequest IndexRequest;
866 for (const auto &S : ScoredSignatures) { 928 for (const auto &S : ScoredSignatures) {
867 if (!S.IDForDoc) 929 if (!S.IDForDoc)
868 continue; 930 continue;
869 IndexRequest.IDs.insert(*S.IDForDoc); 931 IndexRequest.IDs.insert(S.IDForDoc);
870 } 932 }
871 Index->lookup(IndexRequest, [&](const Symbol &S) { 933 Index->lookup(IndexRequest, [&](const Symbol &S) {
872 if (!S.Documentation.empty()) 934 if (!S.Documentation.empty())
873 FetchedDocs[S.ID] = std::string(S.Documentation); 935 FetchedDocs[S.ID] = std::string(S.Documentation);
874 }); 936 });
909 return L.Signature.label < R.Signature.label; 971 return L.Signature.label < R.Signature.label;
910 }); 972 });
911 973
912 for (auto &SS : ScoredSignatures) { 974 for (auto &SS : ScoredSignatures) {
913 auto IndexDocIt = 975 auto IndexDocIt =
914 SS.IDForDoc ? FetchedDocs.find(*SS.IDForDoc) : FetchedDocs.end(); 976 SS.IDForDoc ? FetchedDocs.find(SS.IDForDoc) : FetchedDocs.end();
915 if (IndexDocIt != FetchedDocs.end()) 977 if (IndexDocIt != FetchedDocs.end())
916 SS.Signature.documentation = IndexDocIt->second; 978 SS.Signature.documentation = IndexDocIt->second;
917 979
918 SigHelp.signatures.push_back(std::move(SS.Signature)); 980 SigHelp.signatures.push_back(std::move(SS.Signature));
919 } 981 }
1027 const SymbolIndex *Index; 1089 const SymbolIndex *Index;
1028 }; // SignatureHelpCollector 1090 }; // SignatureHelpCollector
1029 1091
1030 struct SemaCompleteInput { 1092 struct SemaCompleteInput {
1031 PathRef FileName; 1093 PathRef FileName;
1032 const tooling::CompileCommand &Command; 1094 size_t Offset;
1033 const PreambleData &Preamble; 1095 const PreambleData &Preamble;
1034 const PreamblePatch &Patch; 1096 const llvm::Optional<PreamblePatch> Patch;
1035 llvm::StringRef Contents; 1097 const ParseInputs &ParseInput;
1036 size_t Offset;
1037 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
1038 }; 1098 };
1039 1099
1040 void loadMainFilePreambleMacros(const Preprocessor &PP, 1100 void loadMainFilePreambleMacros(const Preprocessor &PP,
1041 const PreambleData &Preamble) { 1101 const PreambleData &Preamble) {
1042 // The ExternalPreprocessorSource has our macros, if we know where to look. 1102 // The ExternalPreprocessorSource has our macros, if we know where to look.
1043 // We can read all the macros using PreambleMacros->ReadDefinedMacros(), 1103 // We can read all the macros using PreambleMacros->ReadDefinedMacros(),
1044 // but this includes transitively included files, so may deserialize a lot. 1104 // but this includes transitively included files, so may deserialize a lot.
1045 ExternalPreprocessorSource *PreambleMacros = PP.getExternalSource(); 1105 ExternalPreprocessorSource *PreambleMacros = PP.getExternalSource();
1046 // As we have the names of the macros, we can look up their IdentifierInfo 1106 // As we have the names of the macros, we can look up their IdentifierInfo
1047 // and then use this to load just the macros we want. 1107 // and then use this to load just the macros we want.
1108 const auto &ITable = PP.getIdentifierTable();
1048 IdentifierInfoLookup *PreambleIdentifiers = 1109 IdentifierInfoLookup *PreambleIdentifiers =
1049 PP.getIdentifierTable().getExternalIdentifierLookup(); 1110 ITable.getExternalIdentifierLookup();
1111
1050 if (!PreambleIdentifiers || !PreambleMacros) 1112 if (!PreambleIdentifiers || !PreambleMacros)
1051 return; 1113 return;
1052 for (const auto &MacroName : Preamble.Macros.Names) 1114 for (const auto &MacroName : Preamble.Macros.Names) {
1115 if (ITable.find(MacroName.getKey()) != ITable.end())
1116 continue;
1053 if (auto *II = PreambleIdentifiers->get(MacroName.getKey())) 1117 if (auto *II = PreambleIdentifiers->get(MacroName.getKey()))
1054 if (II->isOutOfDate()) 1118 if (II->isOutOfDate())
1055 PreambleMacros->updateOutOfDateIdentifier(*II); 1119 PreambleMacros->updateOutOfDateIdentifier(*II);
1120 }
1056 } 1121 }
1057 1122
1058 // Invokes Sema code completion on a file. 1123 // Invokes Sema code completion on a file.
1059 // If \p Includes is set, it will be updated based on the compiler invocation. 1124 // If \p Includes is set, it will be updated based on the compiler invocation.
1060 bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer, 1125 bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
1061 const clang::CodeCompleteOptions &Options, 1126 const clang::CodeCompleteOptions &Options,
1062 const SemaCompleteInput &Input, 1127 const SemaCompleteInput &Input,
1063 IncludeStructure *Includes = nullptr) { 1128 IncludeStructure *Includes = nullptr) {
1064 trace::Span Tracer("Sema completion"); 1129 trace::Span Tracer("Sema completion");
1065 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = Input.VFS;
1066 if (Input.Preamble.StatCache)
1067 VFS = Input.Preamble.StatCache->getConsumingFS(std::move(VFS));
1068 ParseInputs ParseInput;
1069 ParseInput.CompileCommand = Input.Command;
1070 ParseInput.FS = VFS;
1071 ParseInput.Contents = std::string(Input.Contents);
1072 // FIXME: setup the recoveryAST and recoveryASTType in ParseInput properly.
1073 1130
1074 IgnoreDiagnostics IgnoreDiags; 1131 IgnoreDiagnostics IgnoreDiags;
1075 auto CI = buildCompilerInvocation(ParseInput, IgnoreDiags); 1132 auto CI = buildCompilerInvocation(Input.ParseInput, IgnoreDiags);
1076 if (!CI) { 1133 if (!CI) {
1077 elog("Couldn't create CompilerInvocation"); 1134 elog("Couldn't create CompilerInvocation");
1078 return false; 1135 return false;
1079 } 1136 }
1080 auto &FrontendOpts = CI->getFrontendOpts(); 1137 auto &FrontendOpts = CI->getFrontendOpts();
1088 // Setup code completion. 1145 // Setup code completion.
1089 FrontendOpts.CodeCompleteOpts = Options; 1146 FrontendOpts.CodeCompleteOpts = Options;
1090 FrontendOpts.CodeCompletionAt.FileName = std::string(Input.FileName); 1147 FrontendOpts.CodeCompletionAt.FileName = std::string(Input.FileName);
1091 std::tie(FrontendOpts.CodeCompletionAt.Line, 1148 std::tie(FrontendOpts.CodeCompletionAt.Line,
1092 FrontendOpts.CodeCompletionAt.Column) = 1149 FrontendOpts.CodeCompletionAt.Column) =
1093 offsetToClangLineColumn(Input.Contents, Input.Offset); 1150 offsetToClangLineColumn(Input.ParseInput.Contents, Input.Offset);
1094 1151
1095 std::unique_ptr<llvm::MemoryBuffer> ContentsBuffer = 1152 std::unique_ptr<llvm::MemoryBuffer> ContentsBuffer =
1096 llvm::MemoryBuffer::getMemBufferCopy(Input.Contents, Input.FileName); 1153 llvm::MemoryBuffer::getMemBuffer(Input.ParseInput.Contents,
1154 Input.FileName);
1097 // The diagnostic options must be set before creating a CompilerInstance. 1155 // The diagnostic options must be set before creating a CompilerInstance.
1098 CI->getDiagnosticOpts().IgnoreWarnings = true; 1156 CI->getDiagnosticOpts().IgnoreWarnings = true;
1099 // We reuse the preamble whether it's valid or not. This is a 1157 // We reuse the preamble whether it's valid or not. This is a
1100 // correctness/performance tradeoff: building without a preamble is slow, and 1158 // correctness/performance tradeoff: building without a preamble is slow, and
1101 // completion is latency-sensitive. 1159 // completion is latency-sensitive.
1102 // However, if we're completing *inside* the preamble section of the draft, 1160 // However, if we're completing *inside* the preamble section of the draft,
1103 // overriding the preamble will break sema completion. Fortunately we can just 1161 // overriding the preamble will break sema completion. Fortunately we can just
1104 // skip all includes in this case; these completions are really simple. 1162 // skip all includes in this case; these completions are really simple.
1105 PreambleBounds PreambleRegion = 1163 PreambleBounds PreambleRegion =
1106 ComputePreambleBounds(*CI->getLangOpts(), ContentsBuffer.get(), 0); 1164 ComputePreambleBounds(*CI->getLangOpts(), *ContentsBuffer, 0);
1107 bool CompletingInPreamble = PreambleRegion.Size > Input.Offset; 1165 bool CompletingInPreamble = Input.Offset < PreambleRegion.Size ||
1108 Input.Patch.apply(*CI); 1166 (!PreambleRegion.PreambleEndsAtStartOfLine &&
1167 Input.Offset == PreambleRegion.Size);
1168 if (Input.Patch)
1169 Input.Patch->apply(*CI);
1109 // NOTE: we must call BeginSourceFile after prepareCompilerInstance. Otherwise 1170 // NOTE: we must call BeginSourceFile after prepareCompilerInstance. Otherwise
1110 // the remapped buffers do not get freed. 1171 // the remapped buffers do not get freed.
1172 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
1173 Input.ParseInput.TFS->view(Input.ParseInput.CompileCommand.Directory);
1174 if (Input.Preamble.StatCache)
1175 VFS = Input.Preamble.StatCache->getConsumingFS(std::move(VFS));
1111 auto Clang = prepareCompilerInstance( 1176 auto Clang = prepareCompilerInstance(
1112 std::move(CI), !CompletingInPreamble ? &Input.Preamble.Preamble : nullptr, 1177 std::move(CI), !CompletingInPreamble ? &Input.Preamble.Preamble : nullptr,
1113 std::move(ContentsBuffer), std::move(VFS), IgnoreDiags); 1178 std::move(ContentsBuffer), std::move(VFS), IgnoreDiags);
1114 Clang->getPreprocessorOpts().SingleFileParseMode = CompletingInPreamble; 1179 Clang->getPreprocessorOpts().SingleFileParseMode = CompletingInPreamble;
1115 Clang->setCodeCompletionConsumer(Consumer.release()); 1180 Clang->setCodeCompletionConsumer(Consumer.release());
1224 1289
1225 // Sema takes ownership of Recorder. Recorder is valid until Sema cleanup. 1290 // Sema takes ownership of Recorder. Recorder is valid until Sema cleanup.
1226 CompletionRecorder *Recorder = nullptr; 1291 CompletionRecorder *Recorder = nullptr;
1227 CodeCompletionContext::Kind CCContextKind = CodeCompletionContext::CCC_Other; 1292 CodeCompletionContext::Kind CCContextKind = CodeCompletionContext::CCC_Other;
1228 bool IsUsingDeclaration = false; 1293 bool IsUsingDeclaration = false;
1294 // The snippets will not be generated if the token following completion
1295 // location is an opening parenthesis (tok::l_paren) because this would add
1296 // extra parenthesis.
1297 tok::TokenKind NextTokenKind = tok::eof;
1229 // Counters for logging. 1298 // Counters for logging.
1230 int NSema = 0, NIndex = 0, NSemaAndIndex = 0, NIdent = 0; 1299 int NSema = 0, NIndex = 0, NSemaAndIndex = 0, NIdent = 0;
1231 bool Incomplete = false; // Would more be available with a higher limit? 1300 bool Incomplete = false; // Would more be available with a higher limit?
1232 CompletionPrefix HeuristicPrefix; 1301 CompletionPrefix HeuristicPrefix;
1233 llvm::Optional<FuzzyMatcher> Filter; // Initialized once Sema runs. 1302 llvm::Optional<FuzzyMatcher> Filter; // Initialized once Sema runs.
1257 : FileName(FileName), Includes(Includes), SpecFuzzyFind(SpecFuzzyFind), 1326 : FileName(FileName), Includes(Includes), SpecFuzzyFind(SpecFuzzyFind),
1258 Opts(Opts) {} 1327 Opts(Opts) {}
1259 1328
1260 CodeCompleteResult run(const SemaCompleteInput &SemaCCInput) && { 1329 CodeCompleteResult run(const SemaCompleteInput &SemaCCInput) && {
1261 trace::Span Tracer("CodeCompleteFlow"); 1330 trace::Span Tracer("CodeCompleteFlow");
1262 HeuristicPrefix = 1331 HeuristicPrefix = guessCompletionPrefix(SemaCCInput.ParseInput.Contents,
1263 guessCompletionPrefix(SemaCCInput.Contents, SemaCCInput.Offset); 1332 SemaCCInput.Offset);
1264 populateContextWords(SemaCCInput.Contents); 1333 populateContextWords(SemaCCInput.ParseInput.Contents);
1265 if (Opts.Index && SpecFuzzyFind && SpecFuzzyFind->CachedReq.hasValue()) { 1334 if (Opts.Index && SpecFuzzyFind && SpecFuzzyFind->CachedReq.hasValue()) {
1266 assert(!SpecFuzzyFind->Result.valid()); 1335 assert(!SpecFuzzyFind->Result.valid());
1267 SpecReq = speculativeFuzzyFindRequestForCompletion( 1336 SpecReq = speculativeFuzzyFindRequestForCompletion(
1268 *SpecFuzzyFind->CachedReq, HeuristicPrefix); 1337 *SpecFuzzyFind->CachedReq, HeuristicPrefix);
1269 SpecFuzzyFind->Result = startAsyncFuzzyFind(*Opts.Index, *SpecReq); 1338 SpecFuzzyFind->Result = startAsyncFuzzyFind(*Opts.Index, *SpecReq);
1275 CodeCompleteResult Output; 1344 CodeCompleteResult Output;
1276 auto RecorderOwner = std::make_unique<CompletionRecorder>(Opts, [&]() { 1345 auto RecorderOwner = std::make_unique<CompletionRecorder>(Opts, [&]() {
1277 assert(Recorder && "Recorder is not set"); 1346 assert(Recorder && "Recorder is not set");
1278 CCContextKind = Recorder->CCContext.getKind(); 1347 CCContextKind = Recorder->CCContext.getKind();
1279 IsUsingDeclaration = Recorder->CCContext.isUsingDeclaration(); 1348 IsUsingDeclaration = Recorder->CCContext.isUsingDeclaration();
1280 auto Style = getFormatStyleForFile( 1349 auto Style = getFormatStyleForFile(SemaCCInput.FileName,
1281 SemaCCInput.FileName, SemaCCInput.Contents, SemaCCInput.VFS.get()); 1350 SemaCCInput.ParseInput.Contents,
1351 *SemaCCInput.ParseInput.TFS);
1352 const auto NextToken = Lexer::findNextToken(
1353 Recorder->CCSema->getPreprocessor().getCodeCompletionLoc(),
1354 Recorder->CCSema->getSourceManager(), Recorder->CCSema->LangOpts);
1355 if (NextToken)
1356 NextTokenKind = NextToken->getKind();
1282 // If preprocessor was run, inclusions from preprocessor callback should 1357 // If preprocessor was run, inclusions from preprocessor callback should
1283 // already be added to Includes. 1358 // already be added to Includes.
1284 Inserter.emplace( 1359 Inserter.emplace(
1285 SemaCCInput.FileName, SemaCCInput.Contents, Style, 1360 SemaCCInput.FileName, SemaCCInput.ParseInput.Contents, Style,
1286 SemaCCInput.Command.Directory, 1361 SemaCCInput.ParseInput.CompileCommand.Directory,
1287 &Recorder->CCSema->getPreprocessor().getHeaderSearchInfo()); 1362 &Recorder->CCSema->getPreprocessor().getHeaderSearchInfo());
1288 for (const auto &Inc : Includes.MainFileIncludes) 1363 for (const auto &Inc : Includes.MainFileIncludes)
1289 Inserter->addExisting(Inc); 1364 Inserter->addExisting(Inc);
1290 1365
1291 // Most of the cost of file proximity is in initializing the FileDistance 1366 // Most of the cost of file proximity is in initializing the FileDistance
1342 assert(!Opts.Limit || Output.Completions.size() <= Opts.Limit); 1417 assert(!Opts.Limit || Output.Completions.size() <= Opts.Limit);
1343 // We don't assert that isIncomplete means we hit a limit. 1418 // We don't assert that isIncomplete means we hit a limit.
1344 // Indexes may choose to impose their own limits even if we don't have one. 1419 // Indexes may choose to impose their own limits even if we don't have one.
1345 } 1420 }
1346 1421
1347 CodeCompleteResult 1422 CodeCompleteResult runWithoutSema(llvm::StringRef Content, size_t Offset,
1348 runWithoutSema(llvm::StringRef Content, size_t Offset, 1423 const ThreadsafeFS &TFS) && {
1349 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) && {
1350 trace::Span Tracer("CodeCompleteWithoutSema"); 1424 trace::Span Tracer("CodeCompleteWithoutSema");
1351 // Fill in fields normally set by runWithSema() 1425 // Fill in fields normally set by runWithSema()
1352 HeuristicPrefix = guessCompletionPrefix(Content, Offset); 1426 HeuristicPrefix = guessCompletionPrefix(Content, Offset);
1353 populateContextWords(Content); 1427 populateContextWords(Content);
1354 CCContextKind = CodeCompletionContext::CCC_Recovery; 1428 CCContextKind = CodeCompletionContext::CCC_Recovery;
1360 1434
1361 llvm::StringMap<SourceParams> ProxSources; 1435 llvm::StringMap<SourceParams> ProxSources;
1362 ProxSources[FileName].Cost = 0; 1436 ProxSources[FileName].Cost = 0;
1363 FileProximity.emplace(ProxSources); 1437 FileProximity.emplace(ProxSources);
1364 1438
1365 auto Style = getFormatStyleForFile(FileName, Content, VFS.get()); 1439 auto Style = getFormatStyleForFile(FileName, Content, TFS);
1366 // This will only insert verbatim headers. 1440 // This will only insert verbatim headers.
1367 Inserter.emplace(FileName, Content, Style, 1441 Inserter.emplace(FileName, Content, Style,
1368 /*BuildDir=*/"", /*HeaderSearchInfo=*/nullptr); 1442 /*BuildDir=*/"", /*HeaderSearchInfo=*/nullptr);
1369 1443
1370 auto Identifiers = collectIdentifiers(Content, Style); 1444 auto Identifiers = collectIdentifiers(Content, Style);
1553 C.Name = Recorder->getName(*SemaResult); 1627 C.Name = Recorder->getName(*SemaResult);
1554 } else { 1628 } else {
1555 assert(IdentifierResult); 1629 assert(IdentifierResult);
1556 C.Name = IdentifierResult->Name; 1630 C.Name = IdentifierResult->Name;
1557 } 1631 }
1558 if (auto OverloadSet = C.overloadSet(Opts)) { 1632 if (auto OverloadSet = C.overloadSet(
1633 Opts, FileName, Inserter ? Inserter.getPointer() : nullptr)) {
1559 auto Ret = BundleLookup.try_emplace(OverloadSet, Bundles.size()); 1634 auto Ret = BundleLookup.try_emplace(OverloadSet, Bundles.size());
1560 if (Ret.second) 1635 if (Ret.second)
1561 Bundles.emplace_back(); 1636 Bundles.emplace_back();
1562 Bundles[Ret.first->second].push_back(std::move(C)); 1637 Bundles[Ret.first->second].push_back(std::move(C));
1563 } else { 1638 } else {
1568 llvm::DenseSet<const Symbol *> UsedIndexResults; 1643 llvm::DenseSet<const Symbol *> UsedIndexResults;
1569 auto CorrespondingIndexResult = 1644 auto CorrespondingIndexResult =
1570 [&](const CodeCompletionResult &SemaResult) -> const Symbol * { 1645 [&](const CodeCompletionResult &SemaResult) -> const Symbol * {
1571 if (auto SymID = 1646 if (auto SymID =
1572 getSymbolID(SemaResult, Recorder->CCSema->getSourceManager())) { 1647 getSymbolID(SemaResult, Recorder->CCSema->getSourceManager())) {
1573 auto I = IndexResults.find(*SymID); 1648 auto I = IndexResults.find(SymID);
1574 if (I != IndexResults.end()) { 1649 if (I != IndexResults.end()) {
1575 UsedIndexResults.insert(&*I); 1650 UsedIndexResults.insert(&*I);
1576 return &*I; 1651 return &*I;
1577 } 1652 }
1578 } 1653 }
1598 return std::move(Top).items(); 1673 return std::move(Top).items();
1599 } 1674 }
1600 1675
1601 llvm::Optional<float> fuzzyScore(const CompletionCandidate &C) { 1676 llvm::Optional<float> fuzzyScore(const CompletionCandidate &C) {
1602 // Macros can be very spammy, so we only support prefix completion. 1677 // Macros can be very spammy, so we only support prefix completion.
1603 // We won't end up with underfull index results, as macros are sema-only. 1678 if (((C.SemaResult &&
1604 if (C.SemaResult && C.SemaResult->Kind == CodeCompletionResult::RK_Macro && 1679 C.SemaResult->Kind == CodeCompletionResult::RK_Macro) ||
1680 (C.IndexResult &&
1681 C.IndexResult->SymInfo.Kind == index::SymbolKind::Macro)) &&
1605 !C.Name.startswith_lower(Filter->pattern())) 1682 !C.Name.startswith_lower(Filter->pattern()))
1606 return None; 1683 return None;
1607 return Filter->match(C.Name); 1684 return Filter->match(C.Name);
1685 }
1686
1687 CodeCompletion::Scores
1688 evaluateCompletion(const SymbolQualitySignals &Quality,
1689 const SymbolRelevanceSignals &Relevance) {
1690 using RM = CodeCompleteOptions::CodeCompletionRankingModel;
1691 CodeCompletion::Scores Scores;
1692 switch (Opts.RankingModel) {
1693 case RM::Heuristics:
1694 Scores.Quality = Quality.evaluateHeuristics();
1695 Scores.Relevance = Relevance.evaluateHeuristics();
1696 Scores.Total =
1697 evaluateSymbolAndRelevance(Scores.Quality, Scores.Relevance);
1698 // NameMatch is in fact a multiplier on total score, so rescoring is
1699 // sound.
1700 Scores.ExcludingName =
1701 Relevance.NameMatch > std::numeric_limits<float>::epsilon()
1702 ? Scores.Total / Relevance.NameMatch
1703 : Scores.Quality;
1704 return Scores;
1705
1706 case RM::DecisionForest:
1707 DecisionForestScores DFScores = Opts.DecisionForestScorer(
1708 Quality, Relevance, Opts.DecisionForestBase);
1709 Scores.ExcludingName = DFScores.ExcludingName;
1710 Scores.Total = DFScores.Total;
1711 return Scores;
1712 }
1713 llvm_unreachable("Unhandled CodeCompletion ranking model.");
1608 } 1714 }
1609 1715
1610 // Scores a candidate and adds it to the TopN structure. 1716 // Scores a candidate and adds it to the TopN structure.
1611 void addCandidate(TopN<ScoredBundle, ScoredBundleGreater> &Candidates, 1717 void addCandidate(TopN<ScoredBundle, ScoredBundleGreater> &Candidates,
1612 CompletionCandidate::Bundle Bundle) { 1718 CompletionCandidate::Bundle Bundle) {
1613 SymbolQualitySignals Quality; 1719 SymbolQualitySignals Quality;
1614 SymbolRelevanceSignals Relevance; 1720 SymbolRelevanceSignals Relevance;
1615 Relevance.Context = CCContextKind; 1721 Relevance.Context = CCContextKind;
1616 Relevance.Name = Bundle.front().Name; 1722 Relevance.Name = Bundle.front().Name;
1723 Relevance.FilterLength = HeuristicPrefix.Name.size();
1617 Relevance.Query = SymbolRelevanceSignals::CodeComplete; 1724 Relevance.Query = SymbolRelevanceSignals::CodeComplete;
1618 Relevance.FileProximityMatch = FileProximity.getPointer(); 1725 Relevance.FileProximityMatch = FileProximity.getPointer();
1619 if (ScopeProximity) 1726 if (ScopeProximity)
1620 Relevance.ScopeProximityMatch = ScopeProximity.getPointer(); 1727 Relevance.ScopeProximityMatch = ScopeProximity.getPointer();
1621 if (PreferredType) 1728 if (PreferredType)
1622 Relevance.HadContextType = true; 1729 Relevance.HadContextType = true;
1623 Relevance.ContextWords = &ContextWords; 1730 Relevance.ContextWords = &ContextWords;
1731 Relevance.MainFileSignals = Opts.MainFileSignals;
1624 1732
1625 auto &First = Bundle.front(); 1733 auto &First = Bundle.front();
1626 if (auto FuzzyScore = fuzzyScore(First)) 1734 if (auto FuzzyScore = fuzzyScore(First))
1627 Relevance.NameMatch = *FuzzyScore; 1735 Relevance.NameMatch = *FuzzyScore;
1628 else 1736 else
1660 Relevance.Scope = SymbolRelevanceSignals::FileScope; 1768 Relevance.Scope = SymbolRelevanceSignals::FileScope;
1661 Origin |= SymbolOrigin::Identifier; 1769 Origin |= SymbolOrigin::Identifier;
1662 } 1770 }
1663 } 1771 }
1664 1772
1665 CodeCompletion::Scores Scores; 1773 CodeCompletion::Scores Scores = evaluateCompletion(Quality, Relevance);
1666 Scores.Quality = Quality.evaluate();
1667 Scores.Relevance = Relevance.evaluate();
1668 Scores.Total = evaluateSymbolAndRelevance(Scores.Quality, Scores.Relevance);
1669 // NameMatch is in fact a multiplier on total score, so rescoring is sound.
1670 Scores.ExcludingName = Relevance.NameMatch
1671 ? Scores.Total / Relevance.NameMatch
1672 : Scores.Quality;
1673
1674 if (Opts.RecordCCResult) 1774 if (Opts.RecordCCResult)
1675 Opts.RecordCCResult(toCodeCompletion(Bundle), Quality, Relevance, 1775 Opts.RecordCCResult(toCodeCompletion(Bundle), Quality, Relevance,
1676 Scores.Total); 1776 Scores.Total);
1677 1777
1678 dlog("CodeComplete: {0} ({1}) = {2}\n{3}{4}\n", First.Name, 1778 dlog("CodeComplete: {0} ({1}) = {2}\n{3}{4}\n", First.Name,
1694 Item.SemaResult ? Recorder->codeCompletionString(*Item.SemaResult) 1794 Item.SemaResult ? Recorder->codeCompletionString(*Item.SemaResult)
1695 : nullptr; 1795 : nullptr;
1696 if (!Builder) 1796 if (!Builder)
1697 Builder.emplace(Recorder ? &Recorder->CCSema->getASTContext() : nullptr, 1797 Builder.emplace(Recorder ? &Recorder->CCSema->getASTContext() : nullptr,
1698 Item, SemaCCS, QueryScopes, *Inserter, FileName, 1798 Item, SemaCCS, QueryScopes, *Inserter, FileName,
1699 CCContextKind, Opts, 1799 CCContextKind, Opts, IsUsingDeclaration, NextTokenKind);
1700 /*GenerateSnippets=*/!IsUsingDeclaration);
1701 else 1800 else
1702 Builder->add(Item, SemaCCS); 1801 Builder->add(Item, SemaCCS);
1703 } 1802 }
1704 return Builder->build(); 1803 return Builder->build();
1705 } 1804 }
1707 1806
1708 } // namespace 1807 } // namespace
1709 1808
1710 clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const { 1809 clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const {
1711 clang::CodeCompleteOptions Result; 1810 clang::CodeCompleteOptions Result;
1712 Result.IncludeCodePatterns = EnableSnippets && IncludeCodePatterns; 1811 Result.IncludeCodePatterns = EnableSnippets;
1713 Result.IncludeMacros = IncludeMacros; 1812 Result.IncludeMacros = true;
1714 Result.IncludeGlobals = true; 1813 Result.IncludeGlobals = true;
1715 // We choose to include full comments and not do doxygen parsing in 1814 // We choose to include full comments and not do doxygen parsing in
1716 // completion. 1815 // completion.
1717 // FIXME: ideally, we should support doxygen in some form, e.g. do markdown 1816 // FIXME: ideally, we should support doxygen in some form, e.g. do markdown
1718 // formatting of the comments. 1817 // formatting of the comments.
1747 Content.slice(Rest.size(), Result.Name.begin() - Content.begin()); 1846 Content.slice(Rest.size(), Result.Name.begin() - Content.begin());
1748 1847
1749 return Result; 1848 return Result;
1750 } 1849 }
1751 1850
1752 CodeCompleteResult 1851 CodeCompleteResult codeComplete(PathRef FileName, Position Pos,
1753 codeComplete(PathRef FileName, const tooling::CompileCommand &Command, 1852 const PreambleData *Preamble,
1754 const PreambleData *Preamble, llvm::StringRef Contents, 1853 const ParseInputs &ParseInput,
1755 Position Pos, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, 1854 CodeCompleteOptions Opts,
1756 CodeCompleteOptions Opts, SpeculativeFuzzyFind *SpecFuzzyFind) { 1855 SpeculativeFuzzyFind *SpecFuzzyFind) {
1757 auto Offset = positionToOffset(Contents, Pos); 1856 auto Offset = positionToOffset(ParseInput.Contents, Pos);
1758 if (!Offset) { 1857 if (!Offset) {
1759 elog("Code completion position was invalid {0}", Offset.takeError()); 1858 elog("Code completion position was invalid {0}", Offset.takeError());
1760 return CodeCompleteResult(); 1859 return CodeCompleteResult();
1761 } 1860 }
1762 auto Flow = CodeCompleteFlow( 1861 auto Flow = CodeCompleteFlow(
1763 FileName, Preamble ? Preamble->Includes : IncludeStructure(), 1862 FileName, Preamble ? Preamble->Includes : IncludeStructure(),
1764 SpecFuzzyFind, Opts); 1863 SpecFuzzyFind, Opts);
1765 return (!Preamble || Opts.RunParser == CodeCompleteOptions::NeverParse) 1864 return (!Preamble || Opts.RunParser == CodeCompleteOptions::NeverParse)
1766 ? std::move(Flow).runWithoutSema(Contents, *Offset, VFS) 1865 ? std::move(Flow).runWithoutSema(ParseInput.Contents, *Offset,
1767 : std::move(Flow).run({FileName, Command, *Preamble, 1866 *ParseInput.TFS)
1867 : std::move(Flow).run({FileName, *Offset, *Preamble,
1768 // We want to serve code completions with 1868 // We want to serve code completions with
1769 // low latency, so don't bother patching. 1869 // low latency, so don't bother patching.
1770 PreamblePatch(), Contents, *Offset, VFS}); 1870 /*PreamblePatch=*/llvm::None, ParseInput});
1771 } 1871 }
1772 1872
1773 SignatureHelp signatureHelp(PathRef FileName, 1873 SignatureHelp signatureHelp(PathRef FileName, Position Pos,
1774 const tooling::CompileCommand &Command,
1775 const PreambleData &Preamble, 1874 const PreambleData &Preamble,
1776 llvm::StringRef Contents, Position Pos, 1875 const ParseInputs &ParseInput) {
1777 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, 1876 auto Offset = positionToOffset(ParseInput.Contents, Pos);
1778 const SymbolIndex *Index) {
1779 auto Offset = positionToOffset(Contents, Pos);
1780 if (!Offset) { 1877 if (!Offset) {
1781 elog("Signature help position was invalid {0}", Offset.takeError()); 1878 elog("Signature help position was invalid {0}", Offset.takeError());
1782 return SignatureHelp(); 1879 return SignatureHelp();
1783 } 1880 }
1784 SignatureHelp Result; 1881 SignatureHelp Result;
1785 clang::CodeCompleteOptions Options; 1882 clang::CodeCompleteOptions Options;
1786 Options.IncludeGlobals = false; 1883 Options.IncludeGlobals = false;
1787 Options.IncludeMacros = false; 1884 Options.IncludeMacros = false;
1788 Options.IncludeCodePatterns = false; 1885 Options.IncludeCodePatterns = false;
1789 Options.IncludeBriefComments = false; 1886 Options.IncludeBriefComments = false;
1790
1791 ParseInputs PI;
1792 PI.CompileCommand = Command;
1793 PI.Contents = Contents.str();
1794 PI.FS = std::move(VFS);
1795 auto PP = PreamblePatch::create(FileName, PI, Preamble);
1796 semaCodeComplete( 1887 semaCodeComplete(
1797 std::make_unique<SignatureHelpCollector>(Options, Index, Result), Options, 1888 std::make_unique<SignatureHelpCollector>(Options, ParseInput.Index,
1798 {FileName, Command, Preamble, PP, Contents, *Offset, std::move(PI.FS)}); 1889 Result),
1890 Options,
1891 {FileName, *Offset, Preamble,
1892 PreamblePatch::create(FileName, ParseInput, Preamble), ParseInput});
1799 return Result; 1893 return Result;
1800 } 1894 }
1801 1895
1802 bool isIndexedForCodeCompletion(const NamedDecl &ND, ASTContext &ASTCtx) { 1896 bool isIndexedForCodeCompletion(const NamedDecl &ND, ASTContext &ASTCtx) {
1803 auto InTopLevelScope = [](const NamedDecl &ND) { 1897 auto InTopLevelScope = [](const NamedDecl &ND) {