clang: lib/Index/IndexingAction.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

18#include "llvm/ADT/STLExtras.h"

19#include

20

21using namespace clang;

23

24namespace {

25

26class IndexPPCallbacks final : public PPCallbacks {

27 std::shared_ptr IndexCtx;

28

29public:

30 IndexPPCallbacks(std::shared_ptr IndexCtx)

31 : IndexCtx(std::move(IndexCtx)) {}

32

37 }

38

44 }

45

48 if (!MD.getMacroInfo())

49 return;

53 }

54

57 if (!MD.getMacroInfo())

58 return;

59

63 }

66 if (!MD.getMacroInfo())

67 return;

71 }

74 if (!MD.getMacroInfo())

75 return;

79 }

80

85 if (!MD.getMacroInfo())

86 return;

90 }

93 if (!MD.getMacroInfo())

94 return;

98 }

99};

100

101class IndexASTConsumer final : public ASTConsumer {

102 std::shared_ptr DataConsumer;

103 std::shared_ptr IndexCtx;

104 std::shared_ptr PP;

105 std::function<bool(const Decl *)> ShouldSkipFunctionBody;

106

107public:

108 IndexASTConsumer(std::shared_ptr DataConsumer,

110 std::shared_ptr PP,

111 std::function<bool(const Decl *)> ShouldSkipFunctionBody)

112 : DataConsumer(std::move(DataConsumer)),

113 IndexCtx(new IndexingContext(Opts, *this->DataConsumer)),

114 PP(std::move(PP)),

115 ShouldSkipFunctionBody(std::move(ShouldSkipFunctionBody)) {

116 assert(this->DataConsumer != nullptr);

117 assert(this->PP != nullptr);

118 }

119

120protected:

122 IndexCtx->setASTContext(Context);

123 IndexCtx->getDataConsumer().initialize(Context);

124 IndexCtx->getDataConsumer().setPreprocessor(PP);

125 PP->addPPCallbacks(std::make_unique(IndexCtx));

126 }

127

129 return IndexCtx->indexDeclGroupRef(DG);

130 }

131

133

134 }

135

137 IndexCtx->indexDeclGroupRef(DG);

138 }

139

141 DataConsumer->finish();

142 }

143

145 return ShouldSkipFunctionBody(D);

146 }

147};

148

150 std::shared_ptr DataConsumer;

152

153public:

154 IndexAction(std::shared_ptr DataConsumer,

156 : DataConsumer(std::move(DataConsumer)), Opts(Opts) {

157 assert(this->DataConsumer != nullptr);

158 }

159

160protected:

162 StringRef InFile) override {

163 return std::make_unique(

165 [](const Decl *) { return false; });

166 }

167};

168

169}

170

172 std::shared_ptr DataConsumer,

173 const IndexingOptions &Opts, std::shared_ptr PP,

174 std::function<bool(const Decl *)> ShouldSkipFunctionBody) {

175 return std::make_unique(DataConsumer, Opts, PP,

176 ShouldSkipFunctionBody);

177}

178

180 std::shared_ptr DataConsumer,

181 const IndexingOptions &Opts, std::shared_ptr PP) {

182 std::function<bool(const Decl *)> ShouldSkipFunctionBody = [](const Decl *) {

183 return false;

184 };

186 ShouldSkipFunctionBody =

188 return !ShouldTraverseDecl(D);

189 };

191 std::move(ShouldSkipFunctionBody));

192}

193

194std::unique_ptr

197 assert(DataConsumer != nullptr);

198 return std::make_unique(std::move(DataConsumer), Opts);

199}

200

204}

205

208}

209

215

216

217

218

219 if (!MI)

220 return;

221

222

224 return;

225

227 ? SymbolRole::Definition

228 : SymbolRole::Undefinition;

230}

231

234 for (const auto &M : PP.macros()) {

235 for (auto *MD = M.second.getLatest(); MD; MD = MD->getPrevious()) {

237 MD->getLocation(), DataConsumer);

238 }

239 }

240}

241

245 for (const auto &M : PP.macros()) {

246 if (M.second.getLatest() == nullptr) {

248 auto *OwningMod = MM->getOwningModule();

249 if (OwningMod && OwningMod->getASTFile() == Mod.File) {

250 if (auto *MI = MM->getMacroInfo()) {

252 MI->getDefinitionLoc(), DataConsumer);

253 }

254 }

255 }

256 }

257 }

258}

259

266

270 DataConsumer.finish();

271}

272

279

281

284

285 for (const Decl *D : Decls)

287 DataConsumer.finish();

288}

289

290std::unique_ptr

292 return std::make_unique(

293 std::make_shared(Opts, Consumer));

294}

295

303

306 }

307

310 }

311 DataConsumer.finish();

312}

Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...

static void indexPreprocessorModuleMacros(Preprocessor &PP, serialization::ModuleFile &Mod, IndexDataConsumer &DataConsumer)

static void indexPreprocessorMacros(Preprocessor &PP, IndexDataConsumer &DataConsumer)

static void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IndexCtx)

static void indexPreprocessorMacro(const IdentifierInfo *II, const MacroInfo *MI, MacroDirective::Kind DirectiveKind, SourceLocation Loc, IndexDataConsumer &DataConsumer)

static bool topLevelDeclVisitor(void *context, const Decl *D)

Defines the PPCallbacks interface.

Defines the clang::Preprocessor interface.

ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.

virtual void HandleTranslationUnit(ASTContext &Ctx)

HandleTranslationUnit - This method is called when the ASTs for entire translation unit have been par...

virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D)

Handle the specified top-level declaration that occurred inside and ObjC container.

virtual bool HandleTopLevelDecl(DeclGroupRef D)

HandleTopLevelDecl - Handle the specified top-level declaration.

virtual void Initialize(ASTContext &Context)

Initialize - This is called to initialize the consumer, providing the ASTContext.

virtual bool shouldSkipFunctionBody(Decl *D)

This callback is called for each function if the Parser was initialized with SkipFunctionBodies set t...

virtual void HandleInterestingDecl(DeclGroupRef D)

HandleInterestingDecl - Handle the specified interesting declaration.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

Abstract base class to use for AST consumer-based frontend actions.

Reads an AST files chain containing the contents of a translation unit.

ASTContext & getContext()

Retrieve the AST context that this AST reader supplements.

llvm::iterator_range< ModuleDeclIterator > getModuleFileLevelDecls(ModuleFile &Mod)

Preprocessor & getPreprocessor() const

Retrieve the preprocessor.

Utility class for loading a ASTContext from an AST file.

bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn)

Iterate over local declarations (locally parsed if this is a parsed source file or the loaded declara...

std::shared_ptr< Preprocessor > getPreprocessorPtr() const

const Preprocessor & getPreprocessor() const

const ASTContext & getASTContext() const

CompilerInstance - Helper class for managing a single instance of the Clang compiler.

std::shared_ptr< Preprocessor > getPreprocessorPtr()

Decl - This represents one declaration (or definition), e.g.

virtual std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile)=0

Create the AST consumer object for this action, if supported.

One of these records is kept for each identifier that is lexed.

MacroArgs - An instance of this class captures information about the formal arguments specified to a ...

A description of the current definition of a macro.

MacroInfo * getMacroInfo() const

Get the MacroInfo that should be used for this definition.

Encapsulates changes to the "macros namespace" (the location where the macro name became active,...

const MacroInfo * getMacroInfo() const

Encapsulates the data about a macro definition (e.g.

This interface provides a way to observe the actions of the preprocessor as it does its thing.

virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range)

Hook called whenever the 'defined' operator is seen.

virtual void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args)

Called by Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is found.

virtual void Elifndef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD)

Hook called whenever an #elifndef branch is taken.

virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD)

Hook called whenever an #ifndef is seen.

virtual void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD, const MacroDirective *Undef)

Hook called whenever a macro #undef is seen.

virtual void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD)

Hook called whenever a macro definition is seen.

virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD)

Hook called whenever an #ifdef is seen.

virtual void Elifdef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD)

Hook called whenever an #elifdef branch is taken.

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

ArrayRef< ModuleMacro * > getLeafModuleMacros(const IdentifierInfo *II) const

Get the list of leaf (non-overridden) module macros for a name.

llvm::iterator_range< macro_iterator > macros(bool IncludeExternalMacros=true) const

Encodes a location in the source.

A trivial tuple used to represent a source range.

SourceLocation getBegin() const

Token - This structure provides full information about a lexed token.

IdentifierInfo * getIdentifierInfo() const

SourceLocation getLocation() const

Return a source location identifier for the specified offset in the current file.

virtual void setPreprocessor(std::shared_ptr< Preprocessor > PP)

virtual bool handleMacroOccurrence(const IdentifierInfo *Name, const MacroInfo *MI, SymbolRoleSet Roles, SourceLocation Loc)

virtual void initialize(ASTContext &Ctx)

bool indexTopLevelDecl(const Decl *D)

void setASTContext(ASTContext &ctx)

Information about a module that has been loaded by the ASTReader.

FileEntryRef File

The file entry for the module file.

std::unique_ptr< PPCallbacks > indexMacrosCallback(IndexDataConsumer &Consumer, IndexingOptions Opts)

Creates a PPCallbacks that indexes macros and feeds macros to Consumer.

void indexTopLevelDecls(ASTContext &Ctx, Preprocessor &PP, ArrayRef< const Decl * > Decls, IndexDataConsumer &DataConsumer, IndexingOptions Opts)

Recursively indexes Decls.

void indexModuleFile(serialization::ModuleFile &Mod, ASTReader &Reader, IndexDataConsumer &DataConsumer, IndexingOptions Opts)

Recursively indexes all top-level decls in the module.

std::unique_ptr< ASTConsumer > createIndexingASTConsumer(std::shared_ptr< IndexDataConsumer > DataConsumer, const IndexingOptions &Opts, std::shared_ptr< Preprocessor > PP)

Creates an ASTConsumer that indexes all symbols (macros and AST decls).

std::unique_ptr< FrontendAction > createIndexingAction(std::shared_ptr< IndexDataConsumer > DataConsumer, const IndexingOptions &Opts)

Creates a frontend action that indexes all symbols (macros and AST decls).

void indexASTUnit(ASTUnit &Unit, IndexDataConsumer &DataConsumer, IndexingOptions Opts)

Recursively indexes all decls in the AST.

The JSON file list parser is used to communicate input to InstallAPI.

std::function< bool(const Decl *)> ShouldTraverseDecl

bool IndexMacrosInPreprocessor