Lines Matching +full:llvm +full:- +full:builddir
1 //===--- CodeComplete.cpp ----------------------------------------*- C++-*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 // - AST-based completions are provided using the completion hooks in Sema.
11 // - external completions are retrieved from the index (using hints from Sema)
12 // - the two sources overlap, and must be merged and overloads bundled
13 // - results must be scored and ranked (see Quality.h) before rendering
16 // it's purely AST-based, and there are few candidates.
18 //===----------------------------------------------------------------------===//
60 #include "llvm/ADT/ArrayRef.h"
61 #include "llvm/ADT/SmallVector.h"
62 #include "llvm/ADT/StringExtras.h"
63 #include "llvm/ADT/StringRef.h"
64 #include "llvm/Support/Casting.h"
65 #include "llvm/Support/Compiler.h"
66 #include "llvm/Support/Debug.h"
67 #include "llvm/Support/Error.h"
68 #include "llvm/Support/FormatVariadic.h"
69 #include "llvm/Support/ScopedPrinter.h"
76 // We log detailed candidate here if you run with -debug-only=codecomplete.
97 const llvm::StringRef *Signature = nullptr) {
107 // Use macro signature (if provided) to tell apart function-like and
108 // object-like macros.
109 return Signature && Signature->contains('(') ? CompletionItemKind::Function
176 // Avoid using 'Text' to avoid confusion with client-side word-based
178 return Res.MacroDefInfo && Res.MacroDefInfo->isFunctionLike()
205 return Opts.MainFileSignals->InsertionDirective;
210 llvm::StringRef Name;
214 /// A code completion result, in clang-native form.
215 /// It may be promoted to a CompletionItem if it's among the top-ranked results.
217 llvm::StringRef Name; // Used for filtering and sorting.
222 llvm::SmallVector<SymbolInclude, 1> RankedIncludeHeaders;
226 size_t overloadSet(const CodeCompleteOptions &Opts, llvm::StringRef FileName,
240 Inserter->calculateIncludePath(*HeaderFile, FileName))
249 llvm::SmallString<256> Scratch;
251 switch (IndexResult->SymInfo.Kind) {
263 return llvm::hash_combine(
264 (IndexResult->Scope + IndexResult->Name).toStringRef(Scratch),
272 const NamedDecl *D = SemaResult->Declaration;
273 if (!D || !D->isFunctionOrFunctionTemplate())
276 llvm::raw_svector_ostream OS(Scratch);
277 D->printQualifiedName(OS);
279 return llvm::hash_combine(Scratch, HeaderForHash);
294 std::optional<llvm::StringRef>
301 if (SemaResult && SemaResult->Declaration) {
304 auto &SM = SemaResult->Declaration->getASTContext().getSourceManager();
305 for (const Decl *RD : SemaResult->Declaration->redecls())
306 if (SM.isInMainFile(SM.getExpansionLoc(RD->getBeginLoc())))
316 using Bundle = llvm::SmallVector<CompletionCandidate, 4>;
331 std::string removeFirstTemplateArg(llvm::StringRef Signature) {
348 llvm::ArrayRef<std::string> AccessibleScopes,
350 llvm::StringRef FileName,
356 Completion.Deprecated = true; // cleared by any non-deprecated overload.
361 Completion.Name = std::string(llvm::StringRef(SemaCCS->getTypedText()));
362 Completion.FilterText = SemaCCS->getAllTypedText();
364 if ((C.SemaResult->Kind == CodeCompletionResult::RK_Declaration) ||
365 (C.SemaResult->Kind == CodeCompletionResult::RK_Pattern))
366 if (const auto *D = C.SemaResult->getDeclaration())
377 for (const auto &FixIt : C.SemaResult->FixIts) {
379 FixIt, ASTCtx->getSourceManager(), ASTCtx->getLangOpts()));
381 llvm::sort(Completion.FixIts, [](const TextEdit &X, const TextEdit &Y) {
387 Completion.Origin |= C.IndexResult->Origin;
389 Completion.Scope = std::string(C.IndexResult->Scope);
391 Completion.Kind = toCompletionItemKind(C.IndexResult->SymInfo.Kind,
392 &C.IndexResult->Signature);
394 Completion.Name = std::string(C.IndexResult->Name);
400 llvm::StringRef ShortestQualifier = C.IndexResult->Scope;
401 for (llvm::StringRef Scope : AccessibleScopes) {
402 llvm::StringRef Qualifier = C.IndexResult->Scope;
413 Completion.Name = std::string(C.IdentifierResult->Name);
418 auto Inserted = [&](llvm::StringRef Header)
419 -> llvm::Expected<std::pair<std::string, bool>> {
421 URI::resolve(C.IndexResult->CanonicalDeclaration.FileURI, FileName);
444 Include.Header = ToInclude->first;
445 if (ToInclude->second && ShouldInsert)
447 ToInclude->first, Directive == Symbol::Import
454 C.IndexResult->CanonicalDeclaration.FileURI, Inc.Header, FileName,
472 getSignature(*SemaCCS, &S.Signature, &S.SnippetSuffix, C.SemaResult->Kind,
473 C.SemaResult->CursorKind,
474 /*IncludeFunctionArguments=*/C.SemaResult->FunctionCanBeCall,
477 if (C.SemaResult->Kind == CodeCompletionResult::RK_Declaration)
478 if (const auto *D = C.SemaResult->getDeclaration())
482 S.Signature = std::string(C.IndexResult->Signature);
483 S.SnippetSuffix = std::string(C.IndexResult->CompletionSnippetSuffix);
484 S.ReturnType = std::string(C.IndexResult->ReturnType);
485 if (C.IndexResult->SymInfo.Kind == index::SymbolKind::Concept)
489 /// When a concept is used as a type-constraint (e.g. `Iterator auto x`),
500 auto SetDoc = [&](llvm::StringRef Doc) {
507 SetDoc(C.IndexResult->Documentation);
517 C.SemaResult->Availability == CXAvailability_Deprecated;
520 bool(C.IndexResult->Flags & Symbol::Deprecated);
544 if (I->*Member != B->*Member)
546 return &(B->*Member);
552 if (I->*Member != B->*Member)
554 return &(B->*Member);
571 (!None && !Open && !Delim); // <-- failsafe: Full is default
582 if (Snippet->empty())
591 // func^(1,2) -> function(1, 2)
596 // fu^<int>(1) -> function<int>(1)
597 if (NextTokenKind == tok::less && Snippet->front() == '<')
602 // fu^(1,2) -> function<class T>(1, 2)
603 if (Snippet->front() == '<') {
608 if (Snippet->at(I) == '>')
609 --Balance;
610 else if (Snippet->at(I) == '<')
614 return Snippet->substr(0, I);
625 // - containing only function arguments, e.g.
628 // - template arguments and function arguments, e.g.
632 bool EmptyArgs = llvm::StringRef(*Snippet).ends_with("()");
633 if (Snippet->front() == '<')
635 if (Snippet->front() == '(')
643 if (Snippet->front() != '<')
648 if (llvm::StringRef(*Snippet).ends_with("<>"))
665 llvm::SmallVector<BundledEntry, 1> Bundled;
685 return clang::clangd::getSymbolID(R.Macro->getName(), R.MacroDefInfo, SM);
733 for (llvm::StringRef AS : AccessibleScopes)
747 for (llvm::StringRef S : QueryScopes)
752 llvm::copy(Deduplicated, std::back_inserter(EnclosingAtFront));
802 if (SemaSpecifier && SemaSpecifier->isValid())
807 llvm::StringRef SpelledSpecifier = Lexer::getSourceText(
808 CharSourceRange::getCharRange(SemaSpecifier->getRange()),
814 if (!Scopes.UnresolvedQualifier->empty())
822 // Should we perform index-based completion in a context of the specified kind?
874 if (R->isInjectedClassName())
897 // The CompletionRecorder captures Sema code-complete output, including context.
898 // It filters out ignored results (but doesn't apply fuzzy-filtering yet).
905 llvm::unique_function<void()> ResultsCallback)
910 assert(this->ResultsCallback);
928 // identifier-based completion).
935 // support index-based completion, we simply skip it to give way to
943 getCompletionKindString(this->CCContext.getKind()));
955 Result.Declaration->isCXXClassMember())
962 !Context.getBaseType().isNull() // is this a member-access context?
982 llvm::StringRef getName(const CodeCompletionResult &Result) {
985 if (auto *ID = Result.Declaration->getIdentifier())
986 return ID->getName();
991 return Result.Macro->getName();
1001 return CCAllocator->CopyString(CCS->getAllTypedText());
1004 return OnlyText ? OnlyText->Text : llvm::StringRef();
1010 // CodeCompletionResult doesn't seem to be const-correct. We own it, anyway.
1020 llvm::unique_function<void()> ResultsCallback;
1040 if (auto *Proto = T->getAs<FunctionProtoType>()) {
1041 if (Proto->isVariadic())
1045 return std::min(Arg, std::max(NumParams - 1, 0));
1090 if (auto *Pattern = Func->getTemplateInstantiationPattern())
1095 // another, per-signature field, but we currently do not use it and not
1097 // FIXME: Add support for per-signature activeParameter field.
1105 assert(CCS && "Expected the CodeCompletionString to be non-null");
1115 llvm::DenseMap<SymbolID, std::string> FetchedDocs;
1123 Index->lookup(IndexRequest, [&](const Symbol &S) {
1128 "symbols with non-empty docs in the response",
1132 llvm::sort(ScoredSignatures, [](const ScoredSignature &L,
1135 // - Less number of parameters is better.
1136 // - Aggregate > Function > FunctionType > FunctionTemplate
1137 // - High score is better.
1138 // - Shorter signature is better.
1139 // - Alphabetically smaller is better.
1177 parseDocumentation(IndexDocIt->second, SignatureComment);
1191 void processParameterChunk(llvm::StringRef ChunkText,
1197 // the code-completion location within a function call, message send,
1215 "Expected the optional code completion string to be non-null.");
1236 llvm::StringRef DocComment) const {
1262 "Expected the optional code completion string to be non-null.");
1274 Signature.label += " -> ";
1297 // Used only for completion of C-style comments in function call (i.e.
1317 if (const auto *II = ND->getIdentifier())
1318 ParamNames.emplace(II->getName());
1343 // We can read all the macros using PreambleMacros->ReadDefinedMacros(),
1357 if (auto *II = PreambleIdentifiers->get(MacroName.getKey()))
1358 if (II->isOutOfDate())
1359 PreambleMacros->updateOutOfDateIdentifier(*II);
1377 auto &FrontendOpts = CI->getFrontendOpts();
1380 CI->getLangOpts().SpellChecking = false;
1382 // This is on-by-default in windows to allow parsing SDK headers; we're only
1383 // disabling it for the main-file (not preamble).
1384 CI->getLangOpts().DelayedTemplateParsing = false;
1392 std::unique_ptr<llvm::MemoryBuffer> ContentsBuffer =
1393 llvm::MemoryBuffer::getMemBuffer(Input.ParseInput.Contents,
1396 CI->getDiagnosticOpts().IgnoreWarnings = true;
1399 // completion is latency-sensitive.
1404 ComputePreambleBounds(CI->getLangOpts(), *ContentsBuffer, 0);
1409 Input.Patch->apply(*CI);
1412 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
1413 Input.ParseInput.TFS->view(Input.ParseInput.CompileCommand.Directory);
1415 VFS = Input.Preamble.StatCache->getConsumingFS(std::move(VFS));
1419 Clang->getPreprocessorOpts().SingleFileParseMode = CompletingInPreamble;
1420 Clang->setCodeCompletionConsumer(Consumer.release());
1423 Input.Preamble.RequiredModules->adjustHeaderSearchOptions(Clang->getHeaderSearchOpts());
1426 if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
1433 // - they're not indexed for completion (they're not available across files)
1434 // - but Sema code complete won't see them: as part of the preamble, they're
1437 loadMainFilePreambleMacros(Clang->getPreprocessor(), Input.Preamble);
1439 Includes->collect(*Clang);
1440 if (llvm::Error Err = Action.Execute()) {
1458 NestedNameSpecifier *NameSpec = (*Scope)->getScopeRep();
1463 switch (NameSpec->getKind()) {
1482 // Objective-C protocols are only useful in ObjC protocol completions,
1558 // Runs Sema-based (AST) and Index-based completion, returns merged results.
1561 // - the AST provides information needed for the index query (e.g. which
1563 // - we only want to return the top results (Opts.Limit).
1566 // - the data underlying Sema completion items is owned by the AST and various
1568 // - we may get duplicate results from Sema and the Index, we need to merge.
1577 // - semaCodeComplete sets up the compiler machinery to run code completion.
1578 // - CompletionRecorder captures Sema completion results, including context.
1579 // - SymbolIndex (Opts.Index) provides index completion results as Symbols
1580 // - CompletionCandidates are the result of merging Sema and Index results.
1584 // - FuzzyMatcher scores how the candidate matches the partial identifier.
1586 // - TopN determines the results with the best score.
1614 llvm::StringSet<> ContextWords;
1615 // Include-insertion and proximity scoring rely on the include structure.
1638 if (Opts.Index && SpecFuzzyFind && SpecFuzzyFind->CachedReq) {
1639 assert(!SpecFuzzyFind->Result.valid());
1641 *SpecFuzzyFind->CachedReq, HeuristicPrefix);
1642 SpecFuzzyFind->Result = startAsyncFuzzyFind(*Opts.Index, *SpecReq);
1646 // - completion results based on the AST.
1647 // - partial identifier and context. We need these for the index query.
1651 CCContextKind = Recorder->CCContext.getKind();
1652 IsUsingDeclaration = Recorder->CCContext.isUsingDeclaration();
1657 Recorder->CCSema->getPreprocessor().getCodeCompletionLoc(),
1658 Recorder->CCSema->getSourceManager(), Recorder->CCSema->LangOpts);
1660 NextTokenKind = NextToken->getKind();
1666 &Recorder->CCSema->getPreprocessor().getHeaderSearchInfo(),
1670 Inserter->addExisting(Inc);
1674 // that happens here (though the per-URI-scheme initialization is lazy).
1675 // The per-result proximity scoring is (amortized) very cheap.
1677 const auto &SM = Recorder->CCSema->getSourceManager();
1678 llvm::StringMap<SourceParams> ProxSources;
1695 Inserter.reset(); // Make sure this doesn't out-live Clang.
1701 llvm::join(QueryScopes.begin(), QueryScopes.end(), ","), AllScopes,
1702 PreferredType ? Recorder->CCContext.getPreferredType().getAsString()
1731 CodeCompleteResult runWithoutSema(llvm::StringRef Content, size_t Offset,
1742 ReplacedRange.start.character -= HeuristicPrefix.Name.size();
1744 llvm::StringMap<SourceParams> ProxSources;
1751 /*BuildDir=*/"", /*HeaderSearchInfo=*/nullptr,
1763 --ID.References;
1769 // - accessible scopes are determined heuristically.
1770 // - all-scopes query if no qualifier was typed (and it's allowed).
1800 void populateContextWords(llvm::StringRef Content) {
1802 unsigned RangeEnd = HeuristicPrefix.Qualifier.begin() - Content.data(),
1815 llvm::join(ContextWords.keys(), ", "));
1822 Recorder->CCSema->getPreprocessor().getCodeCompletionTokenRange());
1829 ReplacedRange = halfOpenToRange(Recorder->CCSema->getSourceManager(),
1833 Recorder->CCSema->getSourceManager(),
1834 Recorder->CCSema->getPreprocessor().getCodeCompletionLoc());
1838 Recorder->CCSema->getPreprocessor().getCodeCompletionFilter());
1840 Recorder->CCContext, *Recorder->CCSema, HeuristicPrefix, Opts);
1848 OpaqueType::fromType(Recorder->CCSema->getASTContext(),
1849 Recorder->CCContext.getPreferredType());
1855 auto IndexResults = (Opts.Index && allowIndex(Recorder->CCContext))
1861 mergeResults(Recorder->Results, IndexResults, /*Identifiers*/ {});
1872 llvm::DenseMap<SymbolID, uint32_t> SymbolToCompletion;
1880 Cand.SemaResult->Kind == CodeCompletionResult::RK_Declaration) {
1881 auto ID = clangd::getSymbolID(Cand.SemaResult->getDeclaration());
1885 SymbolToCompletion[ID] = Output.Completions.size() - 1;
1896 Opts.Index->lookup(Req, [&](const Symbol &S) {
1916 Req.Query = std::string(Filter->pattern());
1923 Req.PreferredTypes.push_back(std::string(PreferredType->raw()));
1927 SpecFuzzyFind->NewReq = Req;
1928 if (SpecFuzzyFind && SpecFuzzyFind->Result.valid() && (*SpecReq == Req)) {
1934 auto SpecRes = SpecFuzzyFind->Result.get();
1943 Incomplete |= Opts.Index->fuzzyFind(
1959 llvm::DenseMap<size_t, size_t> BundleLookup;
1968 C.Name = IndexResult->Name;
1971 C.Name = Recorder->getName(*SemaResult);
1974 C.Name = IdentifierResult->Name;
1981 Bundles[Ret.first->second].push_back(std::move(C));
1987 llvm::DenseSet<const Symbol *> UsedIndexResults;
1989 [&](const CodeCompletionResult &SemaResult) -> const Symbol * {
1991 getSymbolID(SemaResult, Recorder->CCSema->getSourceManager())) {
2003 // Now emit any Index-only results.
2025 C.SemaResult->Kind == CodeCompletionResult::RK_Macro) ||
2027 C.IndexResult->SymInfo.Kind == index::SymbolKind::Macro)) &&
2028 !C.Name.starts_with_insensitive(Filter->pattern()))
2030 return Filter->match(C.Name);
2090 Origin |= Candidate.IndexResult->Origin;
2092 if (!Candidate.IndexResult->Type.empty())
2095 PreferredType->raw() == Candidate.IndexResult->Type) {
2104 Recorder->CCSema->getASTContext(), *Candidate.SemaResult)) {
2113 Quality.References = Candidate.IdentifierResult->References;
2125 llvm::to_string(Origin), Scores.Total, llvm::to_string(Quality),
2126 llvm::to_string(Relevance));
2140 Item.SemaResult ? Recorder->codeCompletionString(*Item.SemaResult)
2143 Builder.emplace(Recorder ? &Recorder->CCSema->getASTContext() : nullptr,
2147 Builder->add(Item, SemaCCS, CCContextKind);
2149 return Builder->build();
2175 CompletionPrefix guessCompletionPrefix(llvm::StringRef Content,
2192 Content.slice(Rest.size(), Result.Name.begin() - Content.begin());
2201 llvm::StringRef Prefix,
2232 for (llvm::StringRef Name : ParamNames) {
2251 maybeFunctionArgumentCommentStart(llvm::StringRef Content) {
2256 return Content.size() - 2;
2271 auto Content = llvm::StringRef(ParseInput.Contents).take_front(*Offset);
2284 FileName, Preamble ? Preamble->Includes : IncludeStructure(),
2323 switch (ND.getDeclContext()->getDeclKind()) {
2334 return ND.getDeclContext()->getDeclKind() == Decl::CXXRecord;
2345 if (llvm::isa<ObjCCategoryDecl>(&ND) || llvm::isa<ObjCCategoryImplDecl>(&ND))
2353 // --all-scopes-completion is set, we'll want to complete those as well.
2363 // We could move our indicators from label into labelDetails->description.
2365 LSP.label = ((InsertInclude && InsertInclude->Insertion)
2368 (Opts.ShowOrigins ? "[" + llvm::to_string(Origin) + "]" : "") +
2371 LSP.labelDetails->detail = Signature;
2375 ? std::string(llvm::formatv("[{0} overloads]", BundleSize))
2383 Doc.addParagraph().appendText("From ").appendCode(InsertInclude->Header);
2399 if (FixIt.range.end == LSP.textEdit->range.start) {
2400 LSP.textEdit->newText = FixIt.newText + LSP.textEdit->newText;
2401 LSP.textEdit->range.start = FixIt.range.start;
2407 LSP.textEdit->newText += SnippetSuffix;
2411 LSP.insertText = LSP.textEdit->newText;
2418 if (InsertInclude && InsertInclude->Insertion)
2419 LSP.additionalTextEdits.push_back(*InsertInclude->Insertion);
2426 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const CodeCompletion &C) {
2431 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
2442 bool isIncludeFile(llvm::StringRef Line) {
2458 bool allowImplicitCompletion(llvm::StringRef Content, unsigned Offset) {
2462 if (Pos != llvm::StringRef::npos)
2466 if (Content.ends_with(".") || Content.ends_with("->") ||
2475 // Complete words. Give non-ascii characters the benefit of the doubt.
2477 !llvm::isASCII(Content.back()));