xref: /llvm-project/clang/lib/Interpreter/CodeCompletion.cpp (revision 263fed7ce9d2c155af44829018673caa67fa4f47)
179af92bbSFred Fu //===------ CodeCompletion.cpp - Code Completion for ClangRepl -------===//
279af92bbSFred Fu //
379af92bbSFred Fu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
479af92bbSFred Fu // See https://llvm.org/LICENSE.txt for license information.
579af92bbSFred Fu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
679af92bbSFred Fu //
779af92bbSFred Fu //===----------------------------------------------------------------------===//
879af92bbSFred Fu //
979af92bbSFred Fu // This file implements the classes which performs code completion at the REPL.
1079af92bbSFred Fu //
1179af92bbSFred Fu //===----------------------------------------------------------------------===//
1279af92bbSFred Fu 
1379af92bbSFred Fu #include "clang/Interpreter/CodeCompletion.h"
1479af92bbSFred Fu #include "clang/AST/ASTImporter.h"
1535b366acSFred Fu #include "clang/AST/DeclLookups.h"
1679af92bbSFred Fu #include "clang/AST/DeclarationName.h"
1779af92bbSFred Fu #include "clang/AST/ExternalASTSource.h"
1879af92bbSFred Fu #include "clang/Basic/IdentifierTable.h"
1979af92bbSFred Fu #include "clang/Frontend/ASTUnit.h"
2079af92bbSFred Fu #include "clang/Frontend/CompilerInstance.h"
2179af92bbSFred Fu #include "clang/Frontend/FrontendActions.h"
2279af92bbSFred Fu #include "clang/Interpreter/Interpreter.h"
2379af92bbSFred Fu #include "clang/Lex/PreprocessorOptions.h"
2479af92bbSFred Fu #include "clang/Sema/CodeCompleteConsumer.h"
2579af92bbSFred Fu #include "clang/Sema/CodeCompleteOptions.h"
2679af92bbSFred Fu #include "clang/Sema/Sema.h"
2735b366acSFred Fu #include "llvm/Support/Debug.h"
2835b366acSFred Fu #define DEBUG_TYPE "REPLCC"
2979af92bbSFred Fu 
3079af92bbSFred Fu namespace clang {
3179af92bbSFred Fu 
3279af92bbSFred Fu const std::string CodeCompletionFileName = "input_line_[Completion]";
3379af92bbSFred Fu 
3479af92bbSFred Fu clang::CodeCompleteOptions getClangCompleteOpts() {
3579af92bbSFred Fu   clang::CodeCompleteOptions Opts;
3679af92bbSFred Fu   Opts.IncludeCodePatterns = true;
3779af92bbSFred Fu   Opts.IncludeMacros = true;
3879af92bbSFred Fu   Opts.IncludeGlobals = true;
3979af92bbSFred Fu   Opts.IncludeBriefComments = true;
4079af92bbSFred Fu   return Opts;
4179af92bbSFred Fu }
4279af92bbSFred Fu 
4379af92bbSFred Fu class ReplCompletionConsumer : public CodeCompleteConsumer {
4479af92bbSFred Fu public:
4535b366acSFred Fu   ReplCompletionConsumer(std::vector<std::string> &Results,
4635b366acSFred Fu                          ReplCodeCompleter &CC)
4779af92bbSFred Fu       : CodeCompleteConsumer(getClangCompleteOpts()),
4879af92bbSFred Fu         CCAllocator(std::make_shared<GlobalCodeCompletionAllocator>()),
4935b366acSFred Fu         CCTUInfo(CCAllocator), Results(Results), CC(CC) {}
5079af92bbSFred Fu 
5135b366acSFred Fu   // The entry of handling code completion. When the function is called, we
5235b366acSFred Fu   // create a `Context`-based handler (see classes defined below) to handle each
5335b366acSFred Fu   // completion result.
5479af92bbSFred Fu   void ProcessCodeCompleteResults(class Sema &S, CodeCompletionContext Context,
5579af92bbSFred Fu                                   CodeCompletionResult *InResults,
5679af92bbSFred Fu                                   unsigned NumResults) final;
5779af92bbSFred Fu 
5879af92bbSFred Fu   CodeCompletionAllocator &getAllocator() override { return *CCAllocator; }
5979af92bbSFred Fu 
6079af92bbSFred Fu   CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
6179af92bbSFred Fu 
6279af92bbSFred Fu private:
6379af92bbSFred Fu   std::shared_ptr<GlobalCodeCompletionAllocator> CCAllocator;
6479af92bbSFred Fu   CodeCompletionTUInfo CCTUInfo;
6579af92bbSFred Fu   std::vector<std::string> &Results;
6635b366acSFred Fu   ReplCodeCompleter &CC;
6735b366acSFred Fu };
6835b366acSFred Fu 
6935b366acSFred Fu /// The class CompletionContextHandler contains four interfaces, each of
7035b366acSFred Fu /// which handles one type of completion result.
7135b366acSFred Fu /// Its derived classes are used to create concrete handlers based on
7235b366acSFred Fu /// \c CodeCompletionContext.
7335b366acSFred Fu class CompletionContextHandler {
7435b366acSFred Fu protected:
7535b366acSFred Fu   CodeCompletionContext CCC;
7635b366acSFred Fu   std::vector<std::string> &Results;
7735b366acSFred Fu 
7835b366acSFred Fu private:
7935b366acSFred Fu   Sema &S;
8035b366acSFred Fu 
8135b366acSFred Fu public:
8235b366acSFred Fu   CompletionContextHandler(Sema &S, CodeCompletionContext CCC,
8335b366acSFred Fu                            std::vector<std::string> &Results)
8435b366acSFred Fu       : CCC(CCC), Results(Results), S(S) {}
8535b366acSFred Fu 
8635b366acSFred Fu   virtual ~CompletionContextHandler() = default;
8735b366acSFred Fu   /// Converts a Declaration completion result to a completion string, and then
8835b366acSFred Fu   /// stores it in Results.
8935b366acSFred Fu   virtual void handleDeclaration(const CodeCompletionResult &Result) {
9035b366acSFred Fu     auto PreferredType = CCC.getPreferredType();
9135b366acSFred Fu     if (PreferredType.isNull()) {
9235b366acSFred Fu       Results.push_back(Result.Declaration->getName().str());
9335b366acSFred Fu       return;
9435b366acSFred Fu     }
9535b366acSFred Fu 
9635b366acSFred Fu     if (auto *VD = dyn_cast<VarDecl>(Result.Declaration)) {
9735b366acSFred Fu       auto ArgumentType = VD->getType();
9835b366acSFred Fu       if (PreferredType->isReferenceType()) {
9935b366acSFred Fu         QualType RT = PreferredType->castAs<ReferenceType>()->getPointeeType();
10035b366acSFred Fu         Sema::ReferenceConversions RefConv;
10135b366acSFred Fu         Sema::ReferenceCompareResult RefRelationship =
10235b366acSFred Fu             S.CompareReferenceRelationship(SourceLocation(), RT, ArgumentType,
10335b366acSFred Fu                                            &RefConv);
10435b366acSFred Fu         switch (RefRelationship) {
10535b366acSFred Fu         case Sema::Ref_Compatible:
10635b366acSFred Fu         case Sema::Ref_Related:
10735b366acSFred Fu           Results.push_back(VD->getName().str());
10835b366acSFred Fu           break;
10935b366acSFred Fu         case Sema::Ref_Incompatible:
11035b366acSFred Fu           break;
11135b366acSFred Fu         }
11235b366acSFred Fu       } else if (S.Context.hasSameType(ArgumentType, PreferredType)) {
11335b366acSFred Fu         Results.push_back(VD->getName().str());
11435b366acSFred Fu       }
11535b366acSFred Fu     }
11635b366acSFred Fu   }
11735b366acSFred Fu 
11835b366acSFred Fu   /// Converts a Keyword completion result to a completion string, and then
11935b366acSFred Fu   /// stores it in Results.
12035b366acSFred Fu   virtual void handleKeyword(const CodeCompletionResult &Result) {
12135b366acSFred Fu     auto Prefix = S.getPreprocessor().getCodeCompletionFilter();
12235b366acSFred Fu     // Add keyword to the completion results only if we are in a type-aware
12335b366acSFred Fu     // situation.
12435b366acSFred Fu     if (!CCC.getBaseType().isNull() || !CCC.getPreferredType().isNull())
12535b366acSFred Fu       return;
1268c296d58SKazu Hirata     if (StringRef(Result.Keyword).starts_with(Prefix))
12735b366acSFred Fu       Results.push_back(Result.Keyword);
12835b366acSFred Fu   }
12935b366acSFred Fu 
13035b366acSFred Fu   /// Converts a Pattern completion result to a completion string, and then
13135b366acSFred Fu   /// stores it in Results.
13235b366acSFred Fu   virtual void handlePattern(const CodeCompletionResult &Result) {}
13335b366acSFred Fu 
13435b366acSFred Fu   /// Converts a Macro completion result to a completion string, and then stores
13535b366acSFred Fu   /// it in Results.
13635b366acSFred Fu   virtual void handleMacro(const CodeCompletionResult &Result) {}
13735b366acSFred Fu };
13835b366acSFred Fu 
13935b366acSFred Fu class DotMemberAccessHandler : public CompletionContextHandler {
14035b366acSFred Fu public:
14135b366acSFred Fu   DotMemberAccessHandler(Sema &S, CodeCompletionContext CCC,
14235b366acSFred Fu                          std::vector<std::string> &Results)
14335b366acSFred Fu       : CompletionContextHandler(S, CCC, Results) {}
14435b366acSFred Fu   void handleDeclaration(const CodeCompletionResult &Result) override {
14535b366acSFred Fu     auto *ID = Result.Declaration->getIdentifier();
14635b366acSFred Fu     if (!ID)
14735b366acSFred Fu       return;
14835b366acSFred Fu     if (!isa<CXXMethodDecl>(Result.Declaration))
14935b366acSFred Fu       return;
15035b366acSFred Fu     const auto *Fun = cast<CXXMethodDecl>(Result.Declaration);
15135b366acSFred Fu     if (Fun->getParent()->getCanonicalDecl() ==
15235b366acSFred Fu         CCC.getBaseType()->getAsCXXRecordDecl()->getCanonicalDecl()) {
15335b366acSFred Fu       LLVM_DEBUG(llvm::dbgs() << "[In HandleCodeCompleteDOT] Name : "
15435b366acSFred Fu                               << ID->getName() << "\n");
15535b366acSFred Fu       Results.push_back(ID->getName().str());
15635b366acSFred Fu     }
15735b366acSFred Fu   }
15835b366acSFred Fu 
15935b366acSFred Fu   void handleKeyword(const CodeCompletionResult &Result) override {}
16079af92bbSFred Fu };
16179af92bbSFred Fu 
16279af92bbSFred Fu void ReplCompletionConsumer::ProcessCodeCompleteResults(
16379af92bbSFred Fu     class Sema &S, CodeCompletionContext Context,
16479af92bbSFred Fu     CodeCompletionResult *InResults, unsigned NumResults) {
16535b366acSFred Fu 
16635b366acSFred Fu   auto Prefix = S.getPreprocessor().getCodeCompletionFilter();
16735b366acSFred Fu   CC.Prefix = Prefix;
16835b366acSFred Fu 
16935b366acSFred Fu   std::unique_ptr<CompletionContextHandler> CCH;
17035b366acSFred Fu 
17135b366acSFred Fu   // initialize fine-grained code completion handler based on the code
17235b366acSFred Fu   // completion context.
17335b366acSFred Fu   switch (Context.getKind()) {
17435b366acSFred Fu   case CodeCompletionContext::CCC_DotMemberAccess:
17535b366acSFred Fu     CCH.reset(new DotMemberAccessHandler(S, Context, this->Results));
17635b366acSFred Fu     break;
17735b366acSFred Fu   default:
17835b366acSFred Fu     CCH.reset(new CompletionContextHandler(S, Context, this->Results));
17935b366acSFred Fu   };
18035b366acSFred Fu 
18135b366acSFred Fu   for (unsigned I = 0; I < NumResults; I++) {
18279af92bbSFred Fu     auto &Result = InResults[I];
18379af92bbSFred Fu     switch (Result.Kind) {
18479af92bbSFred Fu     case CodeCompletionResult::RK_Declaration:
18535b366acSFred Fu       if (Result.Hidden) {
18635b366acSFred Fu         break;
18779af92bbSFred Fu       }
18835b366acSFred Fu       if (!Result.Declaration->getDeclName().isIdentifier() ||
1898c296d58SKazu Hirata           !Result.Declaration->getName().starts_with(Prefix)) {
19035b366acSFred Fu         break;
19135b366acSFred Fu       }
19235b366acSFred Fu       CCH->handleDeclaration(Result);
19379af92bbSFred Fu       break;
19479af92bbSFred Fu     case CodeCompletionResult::RK_Keyword:
19535b366acSFred Fu       CCH->handleKeyword(Result);
19679af92bbSFred Fu       break;
19735b366acSFred Fu     case CodeCompletionResult::RK_Macro:
19835b366acSFred Fu       CCH->handleMacro(Result);
19935b366acSFred Fu       break;
20035b366acSFred Fu     case CodeCompletionResult::RK_Pattern:
20135b366acSFred Fu       CCH->handlePattern(Result);
20279af92bbSFred Fu       break;
20379af92bbSFred Fu     }
20479af92bbSFred Fu   }
20535b366acSFred Fu 
20635b366acSFred Fu   std::sort(Results.begin(), Results.end());
20779af92bbSFred Fu }
20879af92bbSFred Fu 
20979af92bbSFred Fu class IncrementalSyntaxOnlyAction : public SyntaxOnlyAction {
21079af92bbSFred Fu   const CompilerInstance *ParentCI;
21179af92bbSFred Fu 
21279af92bbSFred Fu public:
21379af92bbSFred Fu   IncrementalSyntaxOnlyAction(const CompilerInstance *ParentCI)
21479af92bbSFred Fu       : ParentCI(ParentCI) {}
21579af92bbSFred Fu 
21679af92bbSFred Fu protected:
21779af92bbSFred Fu   void ExecuteAction() override;
21879af92bbSFred Fu };
21979af92bbSFred Fu 
22079af92bbSFred Fu class ExternalSource : public clang::ExternalASTSource {
22179af92bbSFred Fu   TranslationUnitDecl *ChildTUDeclCtxt;
22279af92bbSFred Fu   ASTContext &ParentASTCtxt;
22379af92bbSFred Fu   TranslationUnitDecl *ParentTUDeclCtxt;
22479af92bbSFred Fu 
22579af92bbSFred Fu   std::unique_ptr<ASTImporter> Importer;
22679af92bbSFred Fu 
22779af92bbSFred Fu public:
22879af92bbSFred Fu   ExternalSource(ASTContext &ChildASTCtxt, FileManager &ChildFM,
22979af92bbSFred Fu                  ASTContext &ParentASTCtxt, FileManager &ParentFM);
23079af92bbSFred Fu   bool FindExternalVisibleDeclsByName(const DeclContext *DC,
231*263fed7cSChuanqi Xu                                       DeclarationName Name,
232*263fed7cSChuanqi Xu                                       const DeclContext *OriginalDC) override;
23379af92bbSFred Fu   void
23479af92bbSFred Fu   completeVisibleDeclsMap(const clang::DeclContext *childDeclContext) override;
23579af92bbSFred Fu };
23679af92bbSFred Fu 
23779af92bbSFred Fu // This method is intended to set up `ExternalASTSource` to the running
23879af92bbSFred Fu // compiler instance before the super `ExecuteAction` triggers parsing
23979af92bbSFred Fu void IncrementalSyntaxOnlyAction::ExecuteAction() {
24079af92bbSFred Fu   CompilerInstance &CI = getCompilerInstance();
24179af92bbSFred Fu   ExternalSource *myExternalSource =
24279af92bbSFred Fu       new ExternalSource(CI.getASTContext(), CI.getFileManager(),
24379af92bbSFred Fu                          ParentCI->getASTContext(), ParentCI->getFileManager());
24479af92bbSFred Fu   llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> astContextExternalSource(
24579af92bbSFred Fu       myExternalSource);
24679af92bbSFred Fu   CI.getASTContext().setExternalSource(astContextExternalSource);
24779af92bbSFred Fu   CI.getASTContext().getTranslationUnitDecl()->setHasExternalVisibleStorage(
24879af92bbSFred Fu       true);
24979af92bbSFred Fu 
25035b366acSFred Fu   // Load all external decls into current context. Under the hood, it calls
25135b366acSFred Fu   // ExternalSource::completeVisibleDeclsMap, which make all decls on the redecl
25235b366acSFred Fu   // chain visible.
25335b366acSFred Fu   //
25435b366acSFred Fu   // This is crucial to code completion on dot members, since a bound variable
25535b366acSFred Fu   // before "." would be otherwise treated out-of-scope.
25635b366acSFred Fu   //
25735b366acSFred Fu   // clang-repl> Foo f1;
25835b366acSFred Fu   // clang-repl> f1.<tab>
25935b366acSFred Fu   CI.getASTContext().getTranslationUnitDecl()->lookups();
26079af92bbSFred Fu   SyntaxOnlyAction::ExecuteAction();
26179af92bbSFred Fu }
26279af92bbSFred Fu 
26379af92bbSFred Fu ExternalSource::ExternalSource(ASTContext &ChildASTCtxt, FileManager &ChildFM,
26479af92bbSFred Fu                                ASTContext &ParentASTCtxt, FileManager &ParentFM)
26579af92bbSFred Fu     : ChildTUDeclCtxt(ChildASTCtxt.getTranslationUnitDecl()),
26679af92bbSFred Fu       ParentASTCtxt(ParentASTCtxt),
26779af92bbSFred Fu       ParentTUDeclCtxt(ParentASTCtxt.getTranslationUnitDecl()) {
26879af92bbSFred Fu   ASTImporter *importer =
26979af92bbSFred Fu       new ASTImporter(ChildASTCtxt, ChildFM, ParentASTCtxt, ParentFM,
27079af92bbSFred Fu                       /*MinimalImport : ON*/ true);
27179af92bbSFred Fu   Importer.reset(importer);
27279af92bbSFred Fu }
27379af92bbSFred Fu 
274*263fed7cSChuanqi Xu bool ExternalSource::FindExternalVisibleDeclsByName(
275*263fed7cSChuanqi Xu     const DeclContext *DC, DeclarationName Name,
276*263fed7cSChuanqi Xu     const DeclContext *OriginalDC) {
27735b366acSFred Fu 
27879af92bbSFred Fu   IdentifierTable &ParentIdTable = ParentASTCtxt.Idents;
27979af92bbSFred Fu 
28079af92bbSFred Fu   auto ParentDeclName =
28179af92bbSFred Fu       DeclarationName(&(ParentIdTable.get(Name.getAsString())));
28279af92bbSFred Fu 
28379af92bbSFred Fu   DeclContext::lookup_result lookup_result =
28479af92bbSFred Fu       ParentTUDeclCtxt->lookup(ParentDeclName);
28579af92bbSFred Fu 
28679af92bbSFred Fu   if (!lookup_result.empty()) {
28779af92bbSFred Fu     return true;
28879af92bbSFred Fu   }
28979af92bbSFred Fu   return false;
29079af92bbSFred Fu }
29179af92bbSFred Fu 
29279af92bbSFred Fu void ExternalSource::completeVisibleDeclsMap(
29379af92bbSFred Fu     const DeclContext *ChildDeclContext) {
29479af92bbSFred Fu   assert(ChildDeclContext && ChildDeclContext == ChildTUDeclCtxt &&
29579af92bbSFred Fu          "No child decl context!");
29679af92bbSFred Fu 
29779af92bbSFred Fu   if (!ChildDeclContext->hasExternalVisibleStorage())
29879af92bbSFred Fu     return;
29979af92bbSFred Fu 
30079af92bbSFred Fu   for (auto *DeclCtxt = ParentTUDeclCtxt; DeclCtxt != nullptr;
30179af92bbSFred Fu        DeclCtxt = DeclCtxt->getPreviousDecl()) {
30279af92bbSFred Fu     for (auto &IDeclContext : DeclCtxt->decls()) {
30335b366acSFred Fu       if (!llvm::isa<NamedDecl>(IDeclContext))
30435b366acSFred Fu         continue;
30535b366acSFred Fu 
30635b366acSFred Fu       NamedDecl *Decl = llvm::cast<NamedDecl>(IDeclContext);
30735b366acSFred Fu 
30835b366acSFred Fu       auto DeclOrErr = Importer->Import(Decl);
30935b366acSFred Fu       if (!DeclOrErr) {
31035b366acSFred Fu         // if an error happens, it usually means the decl has already been
31135b366acSFred Fu         // imported or the decl is a result of a failed import.  But in our
31235b366acSFred Fu         // case, every import is fresh each time code completion is
31335b366acSFred Fu         // triggered. So Import usually doesn't fail. If it does, it just means
31435b366acSFred Fu         // the related decl can't be used in code completion and we can safely
31535b366acSFred Fu         // drop it.
31635b366acSFred Fu         llvm::consumeError(DeclOrErr.takeError());
31735b366acSFred Fu         continue;
31835b366acSFred Fu       }
31935b366acSFred Fu 
32035b366acSFred Fu       if (!llvm::isa<NamedDecl>(*DeclOrErr))
32135b366acSFred Fu         continue;
32235b366acSFred Fu 
32335b366acSFred Fu       NamedDecl *importedNamedDecl = llvm::cast<NamedDecl>(*DeclOrErr);
32435b366acSFred Fu 
32579af92bbSFred Fu       SetExternalVisibleDeclsForName(ChildDeclContext,
32679af92bbSFred Fu                                      importedNamedDecl->getDeclName(),
32779af92bbSFred Fu                                      importedNamedDecl);
32835b366acSFred Fu 
32935b366acSFred Fu       if (!llvm::isa<CXXRecordDecl>(importedNamedDecl))
33035b366acSFred Fu         continue;
33135b366acSFred Fu 
33235b366acSFred Fu       auto *Record = llvm::cast<CXXRecordDecl>(importedNamedDecl);
33335b366acSFred Fu 
33435b366acSFred Fu       if (auto Err = Importer->ImportDefinition(Decl)) {
33535b366acSFred Fu         // the same as above
33635b366acSFred Fu         consumeError(std::move(Err));
33735b366acSFred Fu         continue;
33879af92bbSFred Fu       }
33979af92bbSFred Fu 
34035b366acSFred Fu       Record->setHasLoadedFieldsFromExternalStorage(true);
34135b366acSFred Fu       LLVM_DEBUG(llvm::dbgs()
34235b366acSFred Fu                  << "\nCXXRecrod : " << Record->getName() << " size(methods): "
34335b366acSFred Fu                  << std::distance(Record->method_begin(), Record->method_end())
34435b366acSFred Fu                  << " has def?:  " << Record->hasDefinition()
34535b366acSFred Fu                  << " # (methods): "
34635b366acSFred Fu                  << std::distance(Record->getDefinition()->method_begin(),
34735b366acSFred Fu                                   Record->getDefinition()->method_end())
34835b366acSFred Fu                  << "\n");
34935b366acSFred Fu       for (auto *Meth : Record->methods())
35035b366acSFred Fu         SetExternalVisibleDeclsForName(ChildDeclContext, Meth->getDeclName(),
35135b366acSFred Fu                                        Meth);
35279af92bbSFred Fu     }
35379af92bbSFred Fu     ChildDeclContext->setHasExternalLexicalStorage(false);
35479af92bbSFred Fu   }
35579af92bbSFred Fu }
35679af92bbSFred Fu 
35735b366acSFred Fu void ReplCodeCompleter::codeComplete(CompilerInstance *InterpCI,
35835b366acSFred Fu                                      llvm::StringRef Content, unsigned Line,
35935b366acSFred Fu                                      unsigned Col,
36035b366acSFred Fu                                      const CompilerInstance *ParentCI,
36179af92bbSFred Fu                                      std::vector<std::string> &CCResults) {
36279af92bbSFred Fu   auto DiagOpts = DiagnosticOptions();
36335b366acSFred Fu   auto consumer = ReplCompletionConsumer(CCResults, *this);
36479af92bbSFred Fu 
36579af92bbSFred Fu   auto diag = InterpCI->getDiagnosticsPtr();
36679af92bbSFred Fu   std::unique_ptr<ASTUnit> AU(ASTUnit::LoadFromCompilerInvocationAction(
36779af92bbSFred Fu       InterpCI->getInvocationPtr(), std::make_shared<PCHContainerOperations>(),
36879af92bbSFred Fu       diag));
36979af92bbSFred Fu   llvm::SmallVector<clang::StoredDiagnostic, 8> sd = {};
37079af92bbSFred Fu   llvm::SmallVector<const llvm::MemoryBuffer *, 1> tb = {};
37179af92bbSFred Fu   InterpCI->getFrontendOpts().Inputs[0] = FrontendInputFile(
37279af92bbSFred Fu       CodeCompletionFileName, Language::CXX, InputKind::Source);
373eb5dbaf8SKazu Hirata   auto Act = std::make_unique<IncrementalSyntaxOnlyAction>(ParentCI);
37479af92bbSFred Fu   std::unique_ptr<llvm::MemoryBuffer> MB =
37579af92bbSFred Fu       llvm::MemoryBuffer::getMemBufferCopy(Content, CodeCompletionFileName);
37679af92bbSFred Fu   llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
37779af92bbSFred Fu 
37879af92bbSFred Fu   RemappedFiles.push_back(std::make_pair(CodeCompletionFileName, MB.get()));
37979af92bbSFred Fu   // we don't want the AU destructor to release the memory buffer that MB
38079af92bbSFred Fu   // owns twice, because MB handles its resource on its own.
38179af92bbSFred Fu   AU->setOwnsRemappedFileBuffers(false);
38279af92bbSFred Fu   AU->CodeComplete(CodeCompletionFileName, 1, Col, RemappedFiles, false, false,
38379af92bbSFred Fu                    false, consumer,
38479af92bbSFred Fu                    std::make_shared<clang::PCHContainerOperations>(), *diag,
3855845688eSKadir Cetinkaya                    InterpCI->getLangOpts(), AU->getSourceManager(),
3865845688eSKadir Cetinkaya                    AU->getFileManager(), sd, tb, std::move(Act));
38779af92bbSFred Fu }
38879af92bbSFred Fu 
38979af92bbSFred Fu } // namespace clang
390