xref: /freebsd/contrib/llvm-project/clang/lib/Index/IndexingAction.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- IndexingAction.cpp - Frontend index action -------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "clang/Index/IndexingAction.h"
100b57cec5SDimitry Andric #include "IndexingContext.h"
110b57cec5SDimitry Andric #include "clang/Frontend/CompilerInstance.h"
120b57cec5SDimitry Andric #include "clang/Frontend/FrontendAction.h"
130b57cec5SDimitry Andric #include "clang/Frontend/MultiplexConsumer.h"
140b57cec5SDimitry Andric #include "clang/Index/IndexDataConsumer.h"
150b57cec5SDimitry Andric #include "clang/Lex/PPCallbacks.h"
160b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h"
170b57cec5SDimitry Andric #include "clang/Serialization/ASTReader.h"
180b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
190b57cec5SDimitry Andric #include <memory>
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric using namespace clang;
220b57cec5SDimitry Andric using namespace clang::index;
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric namespace {
250b57cec5SDimitry Andric 
26a7dea167SDimitry Andric class IndexPPCallbacks final : public PPCallbacks {
270b57cec5SDimitry Andric   std::shared_ptr<IndexingContext> IndexCtx;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric public:
IndexPPCallbacks(std::shared_ptr<IndexingContext> IndexCtx)300b57cec5SDimitry Andric   IndexPPCallbacks(std::shared_ptr<IndexingContext> IndexCtx)
310b57cec5SDimitry Andric       : IndexCtx(std::move(IndexCtx)) {}
320b57cec5SDimitry Andric 
MacroExpands(const Token & MacroNameTok,const MacroDefinition & MD,SourceRange Range,const MacroArgs * Args)330b57cec5SDimitry Andric   void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
340b57cec5SDimitry Andric                     SourceRange Range, const MacroArgs *Args) override {
350b57cec5SDimitry Andric     IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(),
360b57cec5SDimitry Andric                                    Range.getBegin(), *MD.getMacroInfo());
370b57cec5SDimitry Andric   }
380b57cec5SDimitry Andric 
MacroDefined(const Token & MacroNameTok,const MacroDirective * MD)390b57cec5SDimitry Andric   void MacroDefined(const Token &MacroNameTok,
400b57cec5SDimitry Andric                     const MacroDirective *MD) override {
410b57cec5SDimitry Andric     IndexCtx->handleMacroDefined(*MacroNameTok.getIdentifierInfo(),
420b57cec5SDimitry Andric                                  MacroNameTok.getLocation(),
430b57cec5SDimitry Andric                                  *MD->getMacroInfo());
440b57cec5SDimitry Andric   }
450b57cec5SDimitry Andric 
MacroUndefined(const Token & MacroNameTok,const MacroDefinition & MD,const MacroDirective * Undef)460b57cec5SDimitry Andric   void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD,
470b57cec5SDimitry Andric                       const MacroDirective *Undef) override {
480b57cec5SDimitry Andric     if (!MD.getMacroInfo())  // Ignore noop #undef.
490b57cec5SDimitry Andric       return;
500b57cec5SDimitry Andric     IndexCtx->handleMacroUndefined(*MacroNameTok.getIdentifierInfo(),
510b57cec5SDimitry Andric                                    MacroNameTok.getLocation(),
520b57cec5SDimitry Andric                                    *MD.getMacroInfo());
530b57cec5SDimitry Andric   }
54*fe6060f1SDimitry Andric 
Defined(const Token & MacroNameTok,const MacroDefinition & MD,SourceRange Range)55*fe6060f1SDimitry Andric   void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
56*fe6060f1SDimitry Andric                SourceRange Range) override {
57*fe6060f1SDimitry Andric     if (!MD.getMacroInfo()) // Ignore nonexistent macro.
58*fe6060f1SDimitry Andric       return;
59*fe6060f1SDimitry Andric     // Note: this is defined(M), not #define M
60*fe6060f1SDimitry Andric     IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(),
61*fe6060f1SDimitry Andric                                    MacroNameTok.getLocation(),
62*fe6060f1SDimitry Andric                                    *MD.getMacroInfo());
63*fe6060f1SDimitry Andric   }
Ifdef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)64*fe6060f1SDimitry Andric   void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
65*fe6060f1SDimitry Andric              const MacroDefinition &MD) override {
66*fe6060f1SDimitry Andric     if (!MD.getMacroInfo()) // Ignore non-existent macro.
67*fe6060f1SDimitry Andric       return;
68*fe6060f1SDimitry Andric     IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(),
69*fe6060f1SDimitry Andric                                    MacroNameTok.getLocation(),
70*fe6060f1SDimitry Andric                                    *MD.getMacroInfo());
71*fe6060f1SDimitry Andric   }
Ifndef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)72*fe6060f1SDimitry Andric   void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
73*fe6060f1SDimitry Andric               const MacroDefinition &MD) override {
74*fe6060f1SDimitry Andric     if (!MD.getMacroInfo()) // Ignore nonexistent macro.
75*fe6060f1SDimitry Andric       return;
76*fe6060f1SDimitry Andric     IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(),
77*fe6060f1SDimitry Andric                                    MacroNameTok.getLocation(),
78*fe6060f1SDimitry Andric                                    *MD.getMacroInfo());
79*fe6060f1SDimitry Andric   }
80*fe6060f1SDimitry Andric 
81*fe6060f1SDimitry Andric   using PPCallbacks::Elifdef;
82*fe6060f1SDimitry Andric   using PPCallbacks::Elifndef;
Elifdef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)83*fe6060f1SDimitry Andric   void Elifdef(SourceLocation Loc, const Token &MacroNameTok,
84*fe6060f1SDimitry Andric                const MacroDefinition &MD) override {
85*fe6060f1SDimitry Andric     if (!MD.getMacroInfo()) // Ignore non-existent macro.
86*fe6060f1SDimitry Andric       return;
87*fe6060f1SDimitry Andric     IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(),
88*fe6060f1SDimitry Andric                                    MacroNameTok.getLocation(),
89*fe6060f1SDimitry Andric                                    *MD.getMacroInfo());
90*fe6060f1SDimitry Andric   }
Elifndef(SourceLocation Loc,const Token & MacroNameTok,const MacroDefinition & MD)91*fe6060f1SDimitry Andric   void Elifndef(SourceLocation Loc, const Token &MacroNameTok,
92*fe6060f1SDimitry Andric                 const MacroDefinition &MD) override {
93*fe6060f1SDimitry Andric     if (!MD.getMacroInfo()) // Ignore non-existent macro.
94*fe6060f1SDimitry Andric       return;
95*fe6060f1SDimitry Andric     IndexCtx->handleMacroReference(*MacroNameTok.getIdentifierInfo(),
96*fe6060f1SDimitry Andric                                    MacroNameTok.getLocation(),
97*fe6060f1SDimitry Andric                                    *MD.getMacroInfo());
98*fe6060f1SDimitry Andric   }
990b57cec5SDimitry Andric };
1000b57cec5SDimitry Andric 
101a7dea167SDimitry Andric class IndexASTConsumer final : public ASTConsumer {
1020b57cec5SDimitry Andric   std::shared_ptr<IndexDataConsumer> DataConsumer;
1030b57cec5SDimitry Andric   std::shared_ptr<IndexingContext> IndexCtx;
104a7dea167SDimitry Andric   std::shared_ptr<Preprocessor> PP;
105a7dea167SDimitry Andric   std::function<bool(const Decl *)> ShouldSkipFunctionBody;
1060b57cec5SDimitry Andric 
107a7dea167SDimitry Andric public:
IndexASTConsumer(std::shared_ptr<IndexDataConsumer> DataConsumer,const IndexingOptions & Opts,std::shared_ptr<Preprocessor> PP,std::function<bool (const Decl *)> ShouldSkipFunctionBody)108a7dea167SDimitry Andric   IndexASTConsumer(std::shared_ptr<IndexDataConsumer> DataConsumer,
109a7dea167SDimitry Andric                    const IndexingOptions &Opts,
110a7dea167SDimitry Andric                    std::shared_ptr<Preprocessor> PP,
111a7dea167SDimitry Andric                    std::function<bool(const Decl *)> ShouldSkipFunctionBody)
112a7dea167SDimitry Andric       : DataConsumer(std::move(DataConsumer)),
113a7dea167SDimitry Andric         IndexCtx(new IndexingContext(Opts, *this->DataConsumer)),
114a7dea167SDimitry Andric         PP(std::move(PP)),
115a7dea167SDimitry Andric         ShouldSkipFunctionBody(std::move(ShouldSkipFunctionBody)) {
116a7dea167SDimitry Andric     assert(this->DataConsumer != nullptr);
117a7dea167SDimitry Andric     assert(this->PP != nullptr);
1180b57cec5SDimitry Andric   }
1190b57cec5SDimitry Andric 
120a7dea167SDimitry Andric protected:
Initialize(ASTContext & Context)121a7dea167SDimitry Andric   void Initialize(ASTContext &Context) override {
122a7dea167SDimitry Andric     IndexCtx->setASTContext(Context);
123a7dea167SDimitry Andric     IndexCtx->getDataConsumer().initialize(Context);
124a7dea167SDimitry Andric     IndexCtx->getDataConsumer().setPreprocessor(PP);
125a7dea167SDimitry Andric     PP->addPPCallbacks(std::make_unique<IndexPPCallbacks>(IndexCtx));
1260b57cec5SDimitry Andric   }
1270b57cec5SDimitry Andric 
HandleTopLevelDecl(DeclGroupRef DG)128a7dea167SDimitry Andric   bool HandleTopLevelDecl(DeclGroupRef DG) override {
129a7dea167SDimitry Andric     return IndexCtx->indexDeclGroupRef(DG);
130a7dea167SDimitry Andric   }
131a7dea167SDimitry Andric 
HandleInterestingDecl(DeclGroupRef DG)132a7dea167SDimitry Andric   void HandleInterestingDecl(DeclGroupRef DG) override {
133a7dea167SDimitry Andric     // Ignore deserialized decls.
134a7dea167SDimitry Andric   }
135a7dea167SDimitry Andric 
HandleTopLevelDeclInObjCContainer(DeclGroupRef DG)136a7dea167SDimitry Andric   void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override {
137a7dea167SDimitry Andric     IndexCtx->indexDeclGroupRef(DG);
138a7dea167SDimitry Andric   }
139a7dea167SDimitry Andric 
HandleTranslationUnit(ASTContext & Ctx)140a7dea167SDimitry Andric   void HandleTranslationUnit(ASTContext &Ctx) override {
1410b57cec5SDimitry Andric     DataConsumer->finish();
1420b57cec5SDimitry Andric   }
143a7dea167SDimitry Andric 
shouldSkipFunctionBody(Decl * D)144a7dea167SDimitry Andric   bool shouldSkipFunctionBody(Decl *D) override {
145a7dea167SDimitry Andric     return ShouldSkipFunctionBody(D);
146a7dea167SDimitry Andric   }
1470b57cec5SDimitry Andric };
1480b57cec5SDimitry Andric 
149a7dea167SDimitry Andric class IndexAction final : public ASTFrontendAction {
150a7dea167SDimitry Andric   std::shared_ptr<IndexDataConsumer> DataConsumer;
151a7dea167SDimitry Andric   IndexingOptions Opts;
152a7dea167SDimitry Andric 
1530b57cec5SDimitry Andric public:
IndexAction(std::shared_ptr<IndexDataConsumer> DataConsumer,const IndexingOptions & Opts)1540b57cec5SDimitry Andric   IndexAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
155a7dea167SDimitry Andric               const IndexingOptions &Opts)
156a7dea167SDimitry Andric       : DataConsumer(std::move(DataConsumer)), Opts(Opts) {
157a7dea167SDimitry Andric     assert(this->DataConsumer != nullptr);
158a7dea167SDimitry Andric   }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric protected:
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)1610b57cec5SDimitry Andric   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
1620b57cec5SDimitry Andric                                                  StringRef InFile) override {
163a7dea167SDimitry Andric     return std::make_unique<IndexASTConsumer>(
164a7dea167SDimitry Andric         DataConsumer, Opts, CI.getPreprocessorPtr(),
165a7dea167SDimitry Andric         /*ShouldSkipFunctionBody=*/[](const Decl *) { return false; });
1660b57cec5SDimitry Andric   }
1670b57cec5SDimitry Andric };
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric } // anonymous namespace
1700b57cec5SDimitry Andric 
createIndexingASTConsumer(std::shared_ptr<IndexDataConsumer> DataConsumer,const IndexingOptions & Opts,std::shared_ptr<Preprocessor> PP,std::function<bool (const Decl *)> ShouldSkipFunctionBody)171a7dea167SDimitry Andric std::unique_ptr<ASTConsumer> index::createIndexingASTConsumer(
172a7dea167SDimitry Andric     std::shared_ptr<IndexDataConsumer> DataConsumer,
173a7dea167SDimitry Andric     const IndexingOptions &Opts, std::shared_ptr<Preprocessor> PP,
174a7dea167SDimitry Andric     std::function<bool(const Decl *)> ShouldSkipFunctionBody) {
175a7dea167SDimitry Andric   return std::make_unique<IndexASTConsumer>(DataConsumer, Opts, PP,
176a7dea167SDimitry Andric                                             ShouldSkipFunctionBody);
177a7dea167SDimitry Andric }
178a7dea167SDimitry Andric 
createIndexingASTConsumer(std::shared_ptr<IndexDataConsumer> DataConsumer,const IndexingOptions & Opts,std::shared_ptr<Preprocessor> PP)1795ffd83dbSDimitry Andric std::unique_ptr<ASTConsumer> clang::index::createIndexingASTConsumer(
1805ffd83dbSDimitry Andric     std::shared_ptr<IndexDataConsumer> DataConsumer,
1815ffd83dbSDimitry Andric     const IndexingOptions &Opts, std::shared_ptr<Preprocessor> PP) {
1825ffd83dbSDimitry Andric   std::function<bool(const Decl *)> ShouldSkipFunctionBody = [](const Decl *) {
1835ffd83dbSDimitry Andric     return false;
1845ffd83dbSDimitry Andric   };
1855ffd83dbSDimitry Andric   if (Opts.ShouldTraverseDecl)
1865ffd83dbSDimitry Andric     ShouldSkipFunctionBody =
1875ffd83dbSDimitry Andric         [ShouldTraverseDecl(Opts.ShouldTraverseDecl)](const Decl *D) {
1885ffd83dbSDimitry Andric           return !ShouldTraverseDecl(D);
1895ffd83dbSDimitry Andric         };
1905ffd83dbSDimitry Andric   return createIndexingASTConsumer(std::move(DataConsumer), Opts, std::move(PP),
1915ffd83dbSDimitry Andric                                    std::move(ShouldSkipFunctionBody));
1925ffd83dbSDimitry Andric }
1935ffd83dbSDimitry Andric 
1940b57cec5SDimitry Andric std::unique_ptr<FrontendAction>
createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer,const IndexingOptions & Opts)1950b57cec5SDimitry Andric index::createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
196a7dea167SDimitry Andric                             const IndexingOptions &Opts) {
197a7dea167SDimitry Andric   assert(DataConsumer != nullptr);
198a7dea167SDimitry Andric   return std::make_unique<IndexAction>(std::move(DataConsumer), Opts);
1990b57cec5SDimitry Andric }
2000b57cec5SDimitry Andric 
topLevelDeclVisitor(void * context,const Decl * D)2010b57cec5SDimitry Andric static bool topLevelDeclVisitor(void *context, const Decl *D) {
2020b57cec5SDimitry Andric   IndexingContext &IndexCtx = *static_cast<IndexingContext *>(context);
2030b57cec5SDimitry Andric   return IndexCtx.indexTopLevelDecl(D);
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric 
indexTranslationUnit(ASTUnit & Unit,IndexingContext & IndexCtx)2060b57cec5SDimitry Andric static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IndexCtx) {
2070b57cec5SDimitry Andric   Unit.visitLocalTopLevelDecls(&IndexCtx, topLevelDeclVisitor);
2080b57cec5SDimitry Andric }
2090b57cec5SDimitry Andric 
indexPreprocessorMacro(const IdentifierInfo * II,const MacroInfo * MI,MacroDirective::Kind DirectiveKind,SourceLocation Loc,IndexDataConsumer & DataConsumer)210*fe6060f1SDimitry Andric static void indexPreprocessorMacro(const IdentifierInfo *II,
211*fe6060f1SDimitry Andric                                    const MacroInfo *MI,
212*fe6060f1SDimitry Andric                                    MacroDirective::Kind DirectiveKind,
213*fe6060f1SDimitry Andric                                    SourceLocation Loc,
2140b57cec5SDimitry Andric                                    IndexDataConsumer &DataConsumer) {
215e8d8bef9SDimitry Andric   // When using modules, it may happen that we find #undef of a macro that
216e8d8bef9SDimitry Andric   // was defined in another module. In such case, MI may be nullptr, since
217e8d8bef9SDimitry Andric   // we only look for macro definitions in the current TU. In that case,
218e8d8bef9SDimitry Andric   // there is nothing to index.
219e8d8bef9SDimitry Andric   if (!MI)
220*fe6060f1SDimitry Andric     return;
221e8d8bef9SDimitry Andric 
222*fe6060f1SDimitry Andric   // Skip implicit visibility change.
223*fe6060f1SDimitry Andric   if (DirectiveKind == MacroDirective::MD_Visibility)
224*fe6060f1SDimitry Andric     return;
225*fe6060f1SDimitry Andric 
226*fe6060f1SDimitry Andric   auto Role = DirectiveKind == MacroDirective::MD_Define
227*fe6060f1SDimitry Andric                   ? SymbolRole::Definition
228*fe6060f1SDimitry Andric                   : SymbolRole::Undefinition;
229*fe6060f1SDimitry Andric   DataConsumer.handleMacroOccurrence(II, MI, static_cast<unsigned>(Role), Loc);
230*fe6060f1SDimitry Andric }
231*fe6060f1SDimitry Andric 
indexPreprocessorMacros(Preprocessor & PP,IndexDataConsumer & DataConsumer)232*fe6060f1SDimitry Andric static void indexPreprocessorMacros(Preprocessor &PP,
233*fe6060f1SDimitry Andric                                     IndexDataConsumer &DataConsumer) {
234*fe6060f1SDimitry Andric   for (const auto &M : PP.macros()) {
235*fe6060f1SDimitry Andric     for (auto *MD = M.second.getLatest(); MD; MD = MD->getPrevious()) {
236*fe6060f1SDimitry Andric       indexPreprocessorMacro(M.first, MD->getMacroInfo(), MD->getKind(),
237*fe6060f1SDimitry Andric                              MD->getLocation(), DataConsumer);
238*fe6060f1SDimitry Andric     }
239*fe6060f1SDimitry Andric   }
240*fe6060f1SDimitry Andric }
241*fe6060f1SDimitry Andric 
indexPreprocessorModuleMacros(Preprocessor & PP,serialization::ModuleFile & Mod,IndexDataConsumer & DataConsumer)242*fe6060f1SDimitry Andric static void indexPreprocessorModuleMacros(Preprocessor &PP,
243*fe6060f1SDimitry Andric                                           serialization::ModuleFile &Mod,
244*fe6060f1SDimitry Andric                                           IndexDataConsumer &DataConsumer) {
245*fe6060f1SDimitry Andric   for (const auto &M : PP.macros()) {
246*fe6060f1SDimitry Andric     if (M.second.getLatest() == nullptr) {
247*fe6060f1SDimitry Andric       for (auto *MM : PP.getLeafModuleMacros(M.first)) {
248*fe6060f1SDimitry Andric         auto *OwningMod = MM->getOwningModule();
249*fe6060f1SDimitry Andric         if (OwningMod && OwningMod->getASTFile() == Mod.File) {
250*fe6060f1SDimitry Andric           if (auto *MI = MM->getMacroInfo()) {
251*fe6060f1SDimitry Andric             indexPreprocessorMacro(M.first, MI, MacroDirective::MD_Define,
252*fe6060f1SDimitry Andric                                    MI->getDefinitionLoc(), DataConsumer);
253*fe6060f1SDimitry Andric           }
254*fe6060f1SDimitry Andric         }
255*fe6060f1SDimitry Andric       }
256*fe6060f1SDimitry Andric     }
2570b57cec5SDimitry Andric   }
258e8d8bef9SDimitry Andric }
2590b57cec5SDimitry Andric 
indexASTUnit(ASTUnit & Unit,IndexDataConsumer & DataConsumer,IndexingOptions Opts)2600b57cec5SDimitry Andric void index::indexASTUnit(ASTUnit &Unit, IndexDataConsumer &DataConsumer,
2610b57cec5SDimitry Andric                          IndexingOptions Opts) {
2620b57cec5SDimitry Andric   IndexingContext IndexCtx(Opts, DataConsumer);
2630b57cec5SDimitry Andric   IndexCtx.setASTContext(Unit.getASTContext());
2640b57cec5SDimitry Andric   DataConsumer.initialize(Unit.getASTContext());
2650b57cec5SDimitry Andric   DataConsumer.setPreprocessor(Unit.getPreprocessorPtr());
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric   if (Opts.IndexMacrosInPreprocessor)
2680b57cec5SDimitry Andric     indexPreprocessorMacros(Unit.getPreprocessor(), DataConsumer);
2690b57cec5SDimitry Andric   indexTranslationUnit(Unit, IndexCtx);
2700b57cec5SDimitry Andric   DataConsumer.finish();
2710b57cec5SDimitry Andric }
2720b57cec5SDimitry Andric 
indexTopLevelDecls(ASTContext & Ctx,Preprocessor & PP,ArrayRef<const Decl * > Decls,IndexDataConsumer & DataConsumer,IndexingOptions Opts)2730b57cec5SDimitry Andric void index::indexTopLevelDecls(ASTContext &Ctx, Preprocessor &PP,
2740b57cec5SDimitry Andric                                ArrayRef<const Decl *> Decls,
2750b57cec5SDimitry Andric                                IndexDataConsumer &DataConsumer,
2760b57cec5SDimitry Andric                                IndexingOptions Opts) {
2770b57cec5SDimitry Andric   IndexingContext IndexCtx(Opts, DataConsumer);
2780b57cec5SDimitry Andric   IndexCtx.setASTContext(Ctx);
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric   DataConsumer.initialize(Ctx);
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   if (Opts.IndexMacrosInPreprocessor)
2830b57cec5SDimitry Andric     indexPreprocessorMacros(PP, DataConsumer);
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   for (const Decl *D : Decls)
2860b57cec5SDimitry Andric     IndexCtx.indexTopLevelDecl(D);
2870b57cec5SDimitry Andric   DataConsumer.finish();
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric std::unique_ptr<PPCallbacks>
indexMacrosCallback(IndexDataConsumer & Consumer,IndexingOptions Opts)2910b57cec5SDimitry Andric index::indexMacrosCallback(IndexDataConsumer &Consumer, IndexingOptions Opts) {
292a7dea167SDimitry Andric   return std::make_unique<IndexPPCallbacks>(
2930b57cec5SDimitry Andric       std::make_shared<IndexingContext>(Opts, Consumer));
2940b57cec5SDimitry Andric }
2950b57cec5SDimitry Andric 
indexModuleFile(serialization::ModuleFile & Mod,ASTReader & Reader,IndexDataConsumer & DataConsumer,IndexingOptions Opts)2960b57cec5SDimitry Andric void index::indexModuleFile(serialization::ModuleFile &Mod, ASTReader &Reader,
2970b57cec5SDimitry Andric                             IndexDataConsumer &DataConsumer,
2980b57cec5SDimitry Andric                             IndexingOptions Opts) {
2990b57cec5SDimitry Andric   ASTContext &Ctx = Reader.getContext();
3000b57cec5SDimitry Andric   IndexingContext IndexCtx(Opts, DataConsumer);
3010b57cec5SDimitry Andric   IndexCtx.setASTContext(Ctx);
3020b57cec5SDimitry Andric   DataConsumer.initialize(Ctx);
3030b57cec5SDimitry Andric 
304*fe6060f1SDimitry Andric   if (Opts.IndexMacrosInPreprocessor) {
305*fe6060f1SDimitry Andric     indexPreprocessorModuleMacros(Reader.getPreprocessor(), Mod, DataConsumer);
306*fe6060f1SDimitry Andric   }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   for (const Decl *D : Reader.getModuleFileLevelDecls(Mod)) {
3090b57cec5SDimitry Andric     IndexCtx.indexTopLevelDecl(D);
3100b57cec5SDimitry Andric   }
3110b57cec5SDimitry Andric   DataConsumer.finish();
3120b57cec5SDimitry Andric }
313