36 #include "llvm/ADT/PostOrderIterator.h" 37 #include "llvm/ADT/Statistic.h" 38 #include "llvm/Support/FileSystem.h" 39 #include "llvm/Support/Path.h" 40 #include "llvm/Support/Program.h" 41 #include "llvm/Support/Timer.h" 42 #include "llvm/Support/raw_ostream.h" 47 using namespace clang;
50 #define DEBUG_TYPE "AnalysisConsumer" 52 STATISTIC(NumFunctionTopLevel,
"The # of functions at top level.");
54 "The # of functions and blocks analyzed (as top level " 55 "with inlining turned on).");
57 "The # of basic blocks in the analyzed functions.");
58 STATISTIC(NumVisitedBlocksInAnalyzedFunctions,
59 "The # of visited basic blocks in the analyzed functions.");
60 STATISTIC(PercentReachableBlocks,
"The % of reachable basic blocks.");
61 STATISTIC(MaxCFGSize,
"The maximum number of basic blocks in a function.");
67 void ento::createPlistHTMLDiagnosticConsumer(
71 createHTMLDiagnosticConsumer(AnalyzerOpts, C,
72 llvm::sys::path::parent_path(prefix), PP, CTU);
73 createPlistMultiFileDiagnosticConsumer(AnalyzerOpts, C, prefix, PP, CTU);
76 void ento::createTextPathDiagnosticConsumer(
80 llvm_unreachable(
"'text' consumer should be enabled on ClangDiags");
84 class ClangDiagPathDiagConsumer :
public PathDiagnosticConsumer {
86 bool IncludePath =
false, ShouldEmitAsError =
false, FixitsAsRemarks =
false;
91 ~ClangDiagPathDiagConsumer()
override {}
92 StringRef
getName()
const override {
return "ClangDiags"; }
94 bool supportsLogicalOpControlFlow()
const override {
return true; }
95 bool supportsCrossFileDiagnostics()
const override {
return true; }
97 PathGenerationScheme getGenerationScheme()
const override {
98 return IncludePath ?
Minimal : None;
101 void enablePaths() { IncludePath =
true; }
102 void enableWerror() { ShouldEmitAsError =
true; }
103 void enableFixitsAsRemarks() { FixitsAsRemarks =
true; }
105 void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
106 FilesMade *filesMade)
override {
117 if (!FixitsAsRemarks) {
118 Diag.
Report(Loc, ID) << String << Ranges << Fixits;
120 Diag.
Report(Loc, ID) << String << Ranges;
124 llvm::raw_svector_ostream
OS(Str);
127 assert(!Hint.InsertFromRange.isValid() &&
"Not implemented yet!");
128 assert(!Hint.BeforePreviousInsertions &&
"Not implemented yet!");
131 <<
": '" << Hint.CodeToInsert <<
"'";
132 Diag.
Report(Loc, RemarkID) <<
OS.str();
137 for (std::vector<const PathDiagnostic *>::iterator I = Diags.begin(),
140 const PathDiagnostic *PD = *I;
141 reportPiece(WarnID, PD->getLocation().asLocation(),
142 PD->getShortDescription(), PD->path.back()->getRanges(),
143 PD->path.back()->getFixits());
146 for (
const auto &Piece : PD->path) {
147 if (!isa<PathDiagnosticNotePiece>(Piece.get()))
150 reportPiece(NoteID, Piece->getLocation().asLocation(),
151 Piece->getString(), Piece->getRanges(), Piece->getFixits());
158 PathPieces FlatPath = PD->path.flatten(
true);
159 for (
const auto &Piece : FlatPath) {
160 if (isa<PathDiagnosticNotePiece>(Piece.get()))
163 reportPiece(NoteID, Piece->getLocation().asLocation(),
164 Piece->getString(), Piece->getRanges(), Piece->getFixits());
177 class AnalysisConsumer :
public AnalysisASTConsumer,
184 typedef unsigned AnalysisMode;
187 AnalysisMode RecVisitorMode;
189 BugReporter *RecVisitorBR;
191 std::vector<std::function<void(CheckerRegistry &)>> CheckerRegistrationFns;
196 const std::string OutDir;
215 std::unique_ptr<CheckerManager> checkerMgr;
216 std::unique_ptr<AnalysisManager> Mgr;
219 std::unique_ptr<llvm::TimerGroup> AnalyzerTimers;
220 std::unique_ptr<llvm::Timer> SyntaxCheckTimer;
221 std::unique_ptr<llvm::Timer> ExprEngineTimer;
222 std::unique_ptr<llvm::Timer> BugReporterTimer;
226 FunctionSummariesTy FunctionSummaries;
231 : RecVisitorMode(0), RecVisitorBR(nullptr), Ctx(nullptr),
232 PP(CI.getPreprocessor()), OutDir(outdir), Opts(
std::move(opts)),
233 Plugins(plugins), Injector(injector), CTU(CI) {
234 DigestAnalyzerOptions();
235 if (Opts->PrintStats || Opts->ShouldSerializeStats) {
236 AnalyzerTimers = std::make_unique<llvm::TimerGroup>(
237 "analyzer",
"Analyzer timers");
238 SyntaxCheckTimer = std::make_unique<llvm::Timer>(
239 "syntaxchecks",
"Syntax-based analysis time", *AnalyzerTimers);
240 ExprEngineTimer = std::make_unique<llvm::Timer>(
241 "exprengine",
"Path exploration time", *AnalyzerTimers);
242 BugReporterTimer = std::make_unique<llvm::Timer>(
243 "bugreporter",
"Path-sensitive report post-processing time",
245 llvm::EnableStatistics(
false);
249 ~AnalysisConsumer()
override {
250 if (Opts->PrintStats) {
251 llvm::PrintStatistics();
255 void DigestAnalyzerOptions() {
256 if (Opts->AnalysisDiagOpt !=
PD_NONE) {
258 ClangDiagPathDiagConsumer *clangDiags =
260 PathConsumers.push_back(clangDiags);
262 if (Opts->AnalyzerWerror)
263 clangDiags->enableWerror();
265 if (Opts->ShouldEmitFixItHintsAsRemarks)
266 clangDiags->enableFixitsAsRemarks();
268 if (Opts->AnalysisDiagOpt == PD_TEXT) {
269 clangDiags->enablePaths();
271 }
else if (!OutDir.empty()) {
272 switch (Opts->AnalysisDiagOpt) {
274 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \ 276 CREATEFN(*Opts.get(), PathConsumers, OutDir, PP, CTU); \ 278 #include "clang/StaticAnalyzer/Core/Analyses.def" 284 switch (Opts->AnalysisStoreOpt) {
286 llvm_unreachable(
"Unknown store manager.");
287 #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN) \ 288 case NAME##Model: CreateStoreMgr = CREATEFN; break; 289 #include "clang/StaticAnalyzer/Core/Analyses.def" 292 switch (Opts->AnalysisConstraintsOpt) {
294 llvm_unreachable(
"Unknown constraint manager.");
295 #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN) \ 296 case NAME##Model: CreateConstraintMgr = CREATEFN; break; 297 #include "clang/StaticAnalyzer/Core/Analyses.def" 301 void DisplayFunction(
const Decl *D, AnalysisMode Mode,
303 if (!Opts->AnalyzerDisplayProgress)
309 llvm::errs() <<
"ANALYZE";
311 if (Mode == AM_Syntax)
312 llvm::errs() <<
" (Syntax)";
313 else if (Mode == AM_Path) {
314 llvm::errs() <<
" (Path, ";
317 llvm::errs() <<
" Inline_Minimal";
320 llvm::errs() <<
" Inline_Regular";
326 assert(Mode == (AM_Syntax | AM_Path) &&
"Unexpected mode!");
329 << getFunctionName(D) <<
'\n';
333 void Initialize(
ASTContext &Context)
override {
336 *Ctx, *Opts, Plugins, CheckerRegistrationFns, PP.
getDiagnostics());
338 Mgr = std::make_unique<AnalysisManager>(*Ctx, PathConsumers, CreateStoreMgr,
340 checkerMgr.get(), *Opts, Injector);
346 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override;
348 void HandleTranslationUnit(
ASTContext &C)
override;
358 void HandleDeclsCallGraph(
const unsigned LocalTUDeclsSize);
366 void HandleCode(
Decl *D, AnalysisMode Mode,
370 void RunPathSensitiveChecks(
Decl *D,
375 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
378 bool VisitDecl(
Decl *D) {
379 AnalysisMode Mode = getModeForDecl(D, RecVisitorMode);
380 if (Mode & AM_Syntax) {
381 if (SyntaxCheckTimer)
382 SyntaxCheckTimer->startTimer();
383 checkerMgr->runCheckersOnASTDecl(D, *Mgr, *RecVisitorBR);
384 if (SyntaxCheckTimer)
385 SyntaxCheckTimer->stopTimer();
390 bool VisitVarDecl(
VarDecl *VD) {
391 if (!Opts->IsNaiveCTUEnabled)
407 Opts->DisplayCTUProgress);
409 if (!CTUDeclOrError) {
410 handleAllErrors(CTUDeclOrError.takeError(),
421 if (II && II->
getName().startswith(
"__inline"))
428 assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() ==
false);
429 HandleCode(FD, RecVisitorMode);
436 assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() ==
false);
437 HandleCode(MD, RecVisitorMode);
444 assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() ==
false);
448 HandleCode(BD, RecVisitorMode);
454 void AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer)
override {
455 PathConsumers.push_back(Consumer);
458 void AddCheckerRegistrationFn(std::function<
void(CheckerRegistry&)> Fn)
override {
459 CheckerRegistrationFns.push_back(std::move(Fn));
464 std::string getFunctionName(
const Decl *D);
467 AnalysisMode getModeForDecl(
Decl *D, AnalysisMode Mode);
468 void runAnalysisOnTranslationUnit(
ASTContext &C);
471 void reportAnalyzerProgress(StringRef S);
479 bool AnalysisConsumer::HandleTopLevelDecl(
DeclGroupRef DG) {
480 storeTopLevelDecls(DG);
484 void AnalysisConsumer::HandleTopLevelDeclInObjCContainer(
DeclGroupRef DG) {
485 storeTopLevelDecls(DG);
488 void AnalysisConsumer::storeTopLevelDecls(
DeclGroupRef DG) {
493 if (isa<ObjCMethodDecl>(*I))
496 LocalTUDecls.push_back(*I);
503 if (VisitedAsTopLevel.count(D))
513 if (isa<ObjCMethodDecl>(D))
518 if (
const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
519 if (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator())
524 return Visited.count(D);
528 AnalysisConsumer::getInliningModeForFunction(
const Decl *D,
533 if (Visited.count(D) && isa<ObjCMethodDecl>(D)) {
542 void AnalysisConsumer::HandleDeclsCallGraph(
const unsigned LocalTUDeclsSize) {
548 for (
unsigned i = 0 ; i < LocalTUDeclsSize ; ++i) {
560 llvm::ReversePostOrderTraversal<clang::CallGraph*> RPOT(&CG);
561 for (llvm::ReversePostOrderTraversal<clang::CallGraph*>::rpo_iterator
562 I = RPOT.begin(), E = RPOT.end(); I != E; ++I) {
563 NumFunctionTopLevel++;
580 HandleCode(D, AM_Path, getInliningModeForFunction(D, Visited),
581 (Mgr->options.InliningMode == All ?
nullptr : &VisitedCallees));
584 for (
const Decl *Callee : VisitedCallees)
587 Visited.insert(isa<ObjCMethodDecl>(Callee) ? Callee
588 : Callee->getCanonicalDecl());
589 VisitedAsTopLevel.insert(D);
596 StringRef Buffer = SM.
getBuffer(FID)->getBuffer();
597 if (Buffer.startswith(
"/* A Bison parser, made by"))
602 void AnalysisConsumer::runAnalysisOnTranslationUnit(
ASTContext &C) {
603 BugReporter BR(*Mgr);
605 if (SyntaxCheckTimer)
606 SyntaxCheckTimer->startTimer();
607 checkerMgr->runCheckersOnASTDecl(TU, *Mgr, BR);
608 if (SyntaxCheckTimer)
609 SyntaxCheckTimer->stopTimer();
614 RecVisitorMode = AM_Syntax;
615 if (!Mgr->shouldInlineCall())
616 RecVisitorMode |= AM_Path;
625 const unsigned LocalTUDeclsSize = LocalTUDecls.size();
626 for (
unsigned i = 0 ; i < LocalTUDeclsSize ; ++i) {
627 TraverseDecl(LocalTUDecls[i]);
630 if (Mgr->shouldInlineCall())
631 HandleDeclsCallGraph(LocalTUDeclsSize);
634 checkerMgr->runCheckersOnEndOfTranslationUnit(TU, *Mgr, BR);
637 RecVisitorBR =
nullptr;
640 void AnalysisConsumer::reportAnalyzerProgress(StringRef S) {
641 if (Opts->AnalyzerDisplayProgress)
645 void AnalysisConsumer::HandleTranslationUnit(
ASTContext &C) {
653 reportAnalyzerProgress(
"Skipping bison-generated file\n");
654 }
else if (Opts->DisableAllCheckers) {
658 reportAnalyzerProgress(
"All checks are disabled using a supplied option\n");
661 runAnalysisOnTranslationUnit(C);
665 NumBlocksInAnalyzedFunctions = FunctionSummaries.getTotalNumBasicBlocks();
666 NumVisitedBlocksInAnalyzedFunctions =
667 FunctionSummaries.getTotalNumVisitedBasicBlocks();
668 if (NumBlocksInAnalyzedFunctions > 0)
669 PercentReachableBlocks =
670 (FunctionSummaries.getTotalNumVisitedBasicBlocks() * 100) /
671 NumBlocksInAnalyzedFunctions;
680 std::string AnalysisConsumer::getFunctionName(
const Decl *D) {
682 llvm::raw_string_ostream
OS(Str);
684 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
688 if (Ctx->getLangOpts().CPlusPlus) {
693 OS <<
P->getType().getAsString();
698 }
else if (isa<BlockDecl>(D)) {
706 }
else if (
const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
709 OS << (OMD->isInstanceMethod() ?
'-' :
'+') <<
'[';
711 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
712 OS << OID->getName();
713 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
714 OS << OID->getName();
715 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
716 if (OC->IsClassExtension()) {
717 OS << OC->getClassInterface()->getName();
719 OS << OC->getIdentifier()->getNameStart() <<
'(' 720 << OC->getIdentifier()->getNameStart() <<
')';
722 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
723 OS << OCD->getClassInterface()->getName() <<
'(' 724 << OCD->getName() <<
')';
725 }
else if (isa<ObjCProtocolDecl>(DC)) {
729 cast<ObjCObjectPointerType>(SelfDecl->getType())->getPointeeType();
733 OS <<
' ' << OMD->getSelector().getAsString() <<
']';
740 AnalysisConsumer::AnalysisMode
741 AnalysisConsumer::getModeForDecl(
Decl *D, AnalysisMode Mode) {
742 if (!Opts->AnalyzeSpecificFunction.empty() &&
743 getFunctionName(D) != Opts->AnalyzeSpecificFunction)
756 if (!Opts->AnalyzeAll && !Mgr->isInCodeFile(SL)) {
759 return Mode & ~AM_Path;
765 void AnalysisConsumer::HandleCode(
Decl *D, AnalysisMode Mode,
770 Mode = getModeForDecl(D, Mode);
775 Mgr->ClearContexts();
777 if (Mgr->getAnalysisDeclContext(D)->isBodyAutosynthesized())
780 DisplayFunction(D, Mode, IMode);
781 CFG *DeclCFG = Mgr->getCFG(D);
783 MaxCFGSize.updateMax(DeclCFG->
size());
785 BugReporter BR(*Mgr);
787 if (Mode & AM_Syntax) {
788 if (SyntaxCheckTimer)
789 SyntaxCheckTimer->startTimer();
790 checkerMgr->runCheckersOnASTBody(D, *Mgr, BR);
791 if (SyntaxCheckTimer)
792 SyntaxCheckTimer->stopTimer();
797 if ((Mode & AM_Path) && checkerMgr->hasPathSensitiveCheckers()) {
798 RunPathSensitiveChecks(D, IMode, VisitedCallees);
800 NumFunctionsAnalyzed++;
808 void AnalysisConsumer::RunPathSensitiveChecks(
Decl *D,
820 ExprEngine Eng(CTU, *Mgr, VisitedCallees, &FunctionSummaries, IMode);
824 ExprEngineTimer->startTimer();
825 Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D),
826 Mgr->options.MaxNodesPerTopLevelFunction);
828 ExprEngineTimer->stopTimer();
830 if (!Mgr->options.DumpExplodedGraphTo.empty())
831 Eng.DumpGraph(Mgr->options.TrimGraph, Mgr->options.DumpExplodedGraphTo);
834 if (Mgr->options.visualizeExplodedGraphWithGraphViz)
835 Eng.ViewGraph(Mgr->options.TrimGraph);
838 if (BugReporterTimer)
839 BugReporterTimer->startTimer();
840 Eng.getBugReporter().FlushReports();
841 if (BugReporterTimer)
842 BugReporterTimer->stopTimer();
849 std::unique_ptr<AnalysisASTConsumer>
855 bool hasModelPath = analyzerOpts->Config.count(
"model-path") > 0;
857 return std::make_unique<AnalysisConsumer>(
859 CI.getFrontendOpts().Plugins,
The AST-based call graph.
std::string OutputFile
The output file, if any.
Represents a function declaration or definition.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
bool isThisDeclarationADefinition() const
Returns whether this specific method is a definition.
bool hasErrorOccurred() const
A (possibly-)qualified type.
SourceManager & getSourceManager() const
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Stmt - This represents one statement.
unsigned size() const
Return the total number of CFGBlocks within the CFG This is simply a renaming of the getNumBlockIDs()...
Defines the SourceManager interface.
Decl - This represents one declaration (or definition), e.g.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to...
std::unique_ptr< CheckerManager > createCheckerManager(ASTContext &context, AnalyzerOptions &opts, ArrayRef< std::string > plugins, ArrayRef< std::function< void(CheckerRegistry &)>> checkerRegistrationFns, DiagnosticsEngine &diags)
Represents a variable declaration or definition.
ObjCMethodDecl - Represents an instance or class method declaration.
Describes how types, statements, expressions, and declarations should be printed. ...
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
One of these records is kept for each identifier that is lexed.
Follow the default settings for inlining callees.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Defines the clang::CodeInjector interface which is responsible for injecting AST of function definiti...
SourceLocation getBeginLoc() const LLVM_READONLY
std::unique_ptr< StoreManager >(* StoreManagerCreator)(ProgramStateManager &)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
ArrayRef< ParmVarDecl * > parameters() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
FrontendOptions & getFrontendOpts()
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
Concrete class used by the front-end to report problems and issues.
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
AnalyzerOptionsRef getAnalyzerOpts()
param_iterator param_begin()
llvm::DenseSet< const Decl * > SetOfConstDecls
bool containsConst(const VarDecl *VD, const ASTContext &ACtx)
std::unique_ptr< ConstraintManager >(* ConstraintManagerCreator)(ProgramStateManager &, SubEngine *)
static bool shouldSkipFunction(const Decl *D, const SetOfConstDecls &Visited, const SetOfConstDecls &VisitedAsTopLevel)
InliningModes
The modes of inlining, which override the default analysis-wide settings.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
unsigned getLine() const
Return the presumed line number of this location.
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Defines the clang::Preprocessor interface.
This file defines the clang::ento::ModelInjector class which implements the clang::CodeInjector inter...
Represents an unpacked "presumed" location which can be presented to the user.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
const char * getFilename() const
Return the presumed filename of this location.
unsigned getColumn() const
Return the presumed column number of this location.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
Encodes a location in the source.
STATISTIC(NumFunctionTopLevel, "The # of functions at top level.")
std::vector< PathDiagnosticConsumer * > PathDiagnosticConsumers
Do minimal inlining of callees.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
StringRef getName() const
Return the actual identifier string.
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
const llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
Dataflow Directional Tag Classes.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
static std::string getName(const CallEvent &Call)
CodeInjector is an interface which is responsible for injecting AST of function definitions that may ...
FileID getMainFileID() const
Returns the FileID of the main source file.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
This class is used for tools that requires cross translation unit capability.
std::unique_ptr< AnalysisASTConsumer > CreateAnalysisConsumer(CompilerInstance &CI)
CreateAnalysisConsumer - Creates an ASTConsumer to run various code analysis passes.
void setWarningsAsErrors(bool Val)
When set to true, any warnings reported are issued as errors.
Indicates that the tracking object is a descendant of a referenced-counted OSObject, used in the Darwin kernel.
Stores options for the analyzer from the command line.
SourceManager & getSourceManager()
llvm::Expected< const FunctionDecl * > getCrossTUDefinition(const FunctionDecl *FD, StringRef CrossTUDir, StringRef IndexName, bool DisplayCTUProgress=false)
This function loads a function or variable definition from an external AST file and merges it into th...
bool hasFatalErrorOccurred() const
Preprocessor & getPreprocessor() const
Return the current preprocessor.
static bool isBisonFile(ASTContext &C)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
TranslationUnitDecl * getTranslationUnitDecl() const
DiagnosticsEngine & getDiagnostics() const
bool hasExternalStorage() const
Returns true if a variable has extern or private_extern storage.
void emitCrossTUDiagnostics(const IndexError &IE)
Emit diagnostics for the user for potential configuration errors.
void addToCallGraph(Decl *D)
Populate the call graph with the functions in the given declaration.
std::string getQualifiedNameAsString() const
The top declaration context.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
bool isStaticDataMember() const
Determines whether this is a static data member.
std::deque< Decl * > SetOfDecls
This class handles loading and caching of source files into memory.
SourceLocation getLocation() const
Engages in a tight little dance with the lexer to efficiently preprocess tokens.