37 #include "llvm/ADT/PostOrderIterator.h" 38 #include "llvm/ADT/Statistic.h" 39 #include "llvm/Support/FileSystem.h" 40 #include "llvm/Support/Path.h" 41 #include "llvm/Support/Program.h" 42 #include "llvm/Support/Timer.h" 43 #include "llvm/Support/raw_ostream.h" 48 using namespace clang;
51 #define DEBUG_TYPE "AnalysisConsumer" 53 static std::unique_ptr<ExplodedNode::Auditor>
CreateUbiViz();
55 STATISTIC(NumFunctionTopLevel,
"The # of functions at top level.");
57 "The # of functions and blocks analyzed (as top level " 58 "with inlining turned on).");
60 "The # of basic blocks in the analyzed functions.");
61 STATISTIC(NumVisitedBlocksInAnalyzedFunctions,
62 "The # of visited basic blocks in the analyzed functions.");
63 STATISTIC(PercentReachableBlocks,
"The % of reachable basic blocks.");
64 STATISTIC(MaxCFGSize,
"The maximum number of basic blocks in a function.");
70 void ento::createPlistHTMLDiagnosticConsumer(
AnalyzerOptions &AnalyzerOpts,
72 const std::string &prefix,
74 createHTMLDiagnosticConsumer(AnalyzerOpts, C,
75 llvm::sys::path::parent_path(prefix), PP);
76 createPlistMultiFileDiagnosticConsumer(AnalyzerOpts, C, prefix, PP);
79 void ento::createTextPathDiagnosticConsumer(
AnalyzerOptions &AnalyzerOpts,
81 const std::string &Prefix,
83 llvm_unreachable(
"'text' consumer should be enabled on ClangDiags");
92 : Diag(Diag), IncludePath(
false) {}
93 ~ClangDiagPathDiagConsumer()
override {}
94 StringRef
getName()
const override {
return "ClangDiags"; }
96 bool supportsLogicalOpControlFlow()
const override {
return true; }
97 bool supportsCrossFileDiagnostics()
const override {
return true; }
99 PathGenerationScheme getGenerationScheme()
const override {
100 return IncludePath ?
Minimal : None;
107 void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
108 FilesMade *filesMade)
override {
112 for (std::vector<const PathDiagnostic*>::iterator I = Diags.begin(),
113 E = Diags.end(); I != E; ++I) {
117 << PD->
path.back()->getRanges();
120 for (
const auto &Piece : PD->
path) {
121 if (!isa<PathDiagnosticNotePiece>(Piece.get()))
125 Diag.
Report(NoteLoc, NoteID) << Piece->getString()
126 << Piece->getRanges();
134 for (
const auto &Piece : FlatPath) {
135 if (isa<PathDiagnosticNotePiece>(Piece.get()))
139 Diag.
Report(NoteLoc, NoteID) << Piece->getString()
140 << Piece->getRanges();
160 typedef unsigned AnalysisMode;
163 AnalysisMode RecVisitorMode;
167 std::vector<std::function<void(CheckerRegistry &)>> CheckerRegistrationFns;
172 const std::string OutDir;
191 std::unique_ptr<CheckerManager> checkerMgr;
192 std::unique_ptr<AnalysisManager> Mgr;
195 std::unique_ptr<llvm::TimerGroup> AnalyzerTimers;
196 std::unique_ptr<llvm::Timer> TUTotalTimer;
205 : RecVisitorMode(0), RecVisitorBR(nullptr), Ctx(nullptr),
206 PP(CI.getPreprocessor()), OutDir(outdir), Opts(
std::move(opts)),
207 Plugins(plugins), Injector(injector), CTU(CI) {
208 DigestAnalyzerOptions();
209 if (Opts->PrintStats || Opts->shouldSerializeStats()) {
210 AnalyzerTimers = llvm::make_unique<llvm::TimerGroup>(
211 "analyzer",
"Analyzer timers");
212 TUTotalTimer = llvm::make_unique<llvm::Timer>(
213 "time",
"Analyzer total time", *AnalyzerTimers);
214 llvm::EnableStatistics(
false);
218 ~AnalysisConsumer()
override {
219 if (Opts->PrintStats) {
220 llvm::PrintStatistics();
224 void DigestAnalyzerOptions() {
225 if (Opts->AnalysisDiagOpt !=
PD_NONE) {
227 ClangDiagPathDiagConsumer *clangDiags =
229 PathConsumers.push_back(clangDiags);
231 if (Opts->AnalysisDiagOpt == PD_TEXT) {
232 clangDiags->enablePaths();
234 }
else if (!OutDir.empty()) {
235 switch (Opts->AnalysisDiagOpt) {
237 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \ 239 CREATEFN(*Opts.get(), PathConsumers, OutDir, PP); \ 241 #include "clang/StaticAnalyzer/Core/Analyses.def" 247 switch (Opts->AnalysisStoreOpt) {
249 llvm_unreachable(
"Unknown store manager.");
250 #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN) \ 251 case NAME##Model: CreateStoreMgr = CREATEFN; break; 252 #include "clang/StaticAnalyzer/Core/Analyses.def" 255 switch (Opts->AnalysisConstraintsOpt) {
257 llvm_unreachable(
"Unknown constraint manager.");
258 #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN) \ 259 case NAME##Model: CreateConstraintMgr = CREATEFN; break; 260 #include "clang/StaticAnalyzer/Core/Analyses.def" 264 void DisplayFunction(
const Decl *D, AnalysisMode Mode,
266 if (!Opts->AnalyzerDisplayProgress)
272 llvm::errs() <<
"ANALYZE";
274 if (Mode == AM_Syntax)
275 llvm::errs() <<
" (Syntax)";
276 else if (Mode == AM_Path) {
277 llvm::errs() <<
" (Path, ";
280 llvm::errs() <<
" Inline_Minimal";
283 llvm::errs() <<
" Inline_Regular";
289 assert(Mode == (AM_Syntax | AM_Path) &&
"Unexpected mode!");
292 << getFunctionName(D) <<
'\n';
296 void Initialize(
ASTContext &Context)
override {
302 Mgr = llvm::make_unique<AnalysisManager>(
304 CreateStoreMgr, CreateConstraintMgr, checkerMgr.get(), *Opts, Injector);
310 void HandleTopLevelDeclInObjCContainer(
DeclGroupRef D)
override;
312 void HandleTranslationUnit(
ASTContext &C)
override;
322 void HandleDeclsCallGraph(
const unsigned LocalTUDeclsSize);
330 void HandleCode(
Decl *D, AnalysisMode Mode,
334 void RunPathSensitiveChecks(
Decl *D,
337 void ActionExprEngine(
Decl *D,
bool ObjCGCEnabled,
342 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
345 bool VisitDecl(
Decl *D) {
346 AnalysisMode Mode = getModeForDecl(D, RecVisitorMode);
347 if (Mode & AM_Syntax)
348 checkerMgr->runCheckersOnASTDecl(D, *Mgr, *RecVisitorBR);
354 if (II && II->
getName().startswith(
"__inline"))
361 assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() ==
false);
362 HandleCode(FD, RecVisitorMode);
369 assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() ==
false);
370 HandleCode(MD, RecVisitorMode);
377 assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() ==
false);
381 HandleCode(BD, RecVisitorMode);
388 PathConsumers.push_back(Consumer);
391 void AddCheckerRegistrationFn(std::function<
void(
CheckerRegistry&)> Fn)
override {
392 CheckerRegistrationFns.push_back(std::move(Fn));
397 std::string getFunctionName(
const Decl *D);
400 AnalysisMode getModeForDecl(
Decl *D, AnalysisMode Mode);
401 void runAnalysisOnTranslationUnit(
ASTContext &C);
404 void reportAnalyzerProgress(StringRef S);
412 bool AnalysisConsumer::HandleTopLevelDecl(
DeclGroupRef DG) {
413 storeTopLevelDecls(DG);
417 void AnalysisConsumer::HandleTopLevelDeclInObjCContainer(
DeclGroupRef DG) {
418 storeTopLevelDecls(DG);
421 void AnalysisConsumer::storeTopLevelDecls(
DeclGroupRef DG) {
426 if (isa<ObjCMethodDecl>(*I))
429 LocalTUDecls.push_back(*I);
436 if (VisitedAsTopLevel.count(D))
446 if (isa<ObjCMethodDecl>(D))
451 if (
const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
452 if (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator())
457 return Visited.count(D);
461 AnalysisConsumer::getInliningModeForFunction(
const Decl *D,
466 if (Visited.count(D) && isa<ObjCMethodDecl>(D)) {
475 void AnalysisConsumer::HandleDeclsCallGraph(
const unsigned LocalTUDeclsSize) {
481 for (
unsigned i = 0 ; i < LocalTUDeclsSize ; ++i) {
493 llvm::ReversePostOrderTraversal<clang::CallGraph*> RPOT(&CG);
494 for (llvm::ReversePostOrderTraversal<clang::CallGraph*>::rpo_iterator
495 I = RPOT.begin(), E = RPOT.end(); I != E; ++I) {
496 NumFunctionTopLevel++;
513 HandleCode(D, AM_Path, getInliningModeForFunction(D, Visited),
514 (Mgr->options.InliningMode == All ?
nullptr : &VisitedCallees));
517 for (
const Decl *Callee : VisitedCallees)
520 Visited.insert(isa<ObjCMethodDecl>(Callee) ? Callee
521 : Callee->getCanonicalDecl());
522 VisitedAsTopLevel.insert(D);
529 StringRef Buffer = SM.
getBuffer(FID)->getBuffer();
530 if (Buffer.startswith(
"/* A Bison parser, made by"))
535 void AnalysisConsumer::runAnalysisOnTranslationUnit(
ASTContext &C) {
538 checkerMgr->runCheckersOnASTDecl(TU, *Mgr, BR);
543 RecVisitorMode = AM_Syntax;
544 if (!Mgr->shouldInlineCall())
545 RecVisitorMode |= AM_Path;
554 const unsigned LocalTUDeclsSize = LocalTUDecls.size();
555 for (
unsigned i = 0 ; i < LocalTUDeclsSize ; ++i) {
556 TraverseDecl(LocalTUDecls[i]);
559 if (Mgr->shouldInlineCall())
560 HandleDeclsCallGraph(LocalTUDeclsSize);
563 checkerMgr->runCheckersOnEndOfTranslationUnit(TU, *Mgr, BR);
565 RecVisitorBR =
nullptr;
568 void AnalysisConsumer::reportAnalyzerProgress(StringRef S) {
569 if (Opts->AnalyzerDisplayProgress)
573 void AnalysisConsumer::HandleTranslationUnit(
ASTContext &C) {
580 if (TUTotalTimer) TUTotalTimer->startTimer();
583 reportAnalyzerProgress(
"Skipping bison-generated file\n");
584 }
else if (Opts->DisableAllChecks) {
588 reportAnalyzerProgress(
"All checks are disabled using a supplied option\n");
591 runAnalysisOnTranslationUnit(C);
594 if (TUTotalTimer) TUTotalTimer->stopTimer();
598 NumVisitedBlocksInAnalyzedFunctions =
600 if (NumBlocksInAnalyzedFunctions > 0)
601 PercentReachableBlocks =
603 NumBlocksInAnalyzedFunctions;
612 std::string AnalysisConsumer::getFunctionName(
const Decl *D) {
614 llvm::raw_string_ostream OS(Str);
616 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
620 if (Ctx->getLangOpts().CPlusPlus) {
625 OS <<
P->getType().getAsString();
630 }
else if (isa<BlockDecl>(D)) {
638 }
else if (
const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
641 OS << (OMD->isInstanceMethod() ?
'-' :
'+') <<
'[';
643 if (
const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
644 OS << OID->getName();
645 }
else if (
const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
646 OS << OID->getName();
647 }
else if (
const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
648 if (OC->IsClassExtension()) {
649 OS << OC->getClassInterface()->getName();
651 OS << OC->getIdentifier()->getNameStart() <<
'(' 652 << OC->getIdentifier()->getNameStart() <<
')';
654 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
655 OS << OCD->getClassInterface()->getName() <<
'(' 656 << OCD->getName() <<
')';
657 }
else if (isa<ObjCProtocolDecl>(DC)) {
661 cast<ObjCObjectPointerType>(SelfDecl->getType())->getPointeeType();
665 OS <<
' ' << OMD->getSelector().getAsString() <<
']';
672 AnalysisConsumer::AnalysisMode
673 AnalysisConsumer::getModeForDecl(
Decl *D, AnalysisMode Mode) {
674 if (!Opts->AnalyzeSpecificFunction.empty() &&
675 getFunctionName(D) != Opts->AnalyzeSpecificFunction)
688 if (!Opts->AnalyzeAll && !Mgr->isInCodeFile(SL)) {
691 return Mode & ~AM_Path;
697 void AnalysisConsumer::HandleCode(
Decl *D, AnalysisMode Mode,
702 Mode = getModeForDecl(D, Mode);
707 Mgr->ClearContexts();
709 if (Mgr->getAnalysisDeclContext(D)->isBodyAutosynthesized())
712 DisplayFunction(D, Mode, IMode);
713 CFG *DeclCFG = Mgr->getCFG(D);
715 MaxCFGSize.updateMax(DeclCFG->
size());
719 if (Mode & AM_Syntax)
720 checkerMgr->runCheckersOnASTBody(D, *Mgr, BR);
721 if ((Mode & AM_Path) && checkerMgr->hasPathSensitiveCheckers()) {
722 RunPathSensitiveChecks(D, IMode, VisitedCallees);
724 NumFunctionsAnalyzed++;
732 void AnalysisConsumer::ActionExprEngine(
Decl *D,
bool ObjCGCEnabled,
744 ExprEngine Eng(CTU, *Mgr, ObjCGCEnabled, VisitedCallees, &FunctionSummaries,
748 std::unique_ptr<ExplodedNode::Auditor> Auditor;
749 if (Mgr->options.visualizeExplodedGraphWithUbiGraph) {
755 Eng.
ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D),
756 Mgr->options.getMaxNodesPerTopLevelFunction());
763 if (Mgr->options.visualizeExplodedGraphWithGraphViz)
770 void AnalysisConsumer::RunPathSensitiveChecks(
Decl *D,
774 switch (Mgr->getLangOpts().getGC()) {
776 ActionExprEngine(D,
false, IMode, Visited);
780 ActionExprEngine(D,
true, IMode, Visited);
784 ActionExprEngine(D,
false, IMode, Visited);
785 ActionExprEngine(D,
true, IMode, Visited);
794 std::unique_ptr<AnalysisASTConsumer>
800 bool hasModelPath = analyzerOpts->Config.count(
"model-path") > 0;
802 return llvm::make_unique<AnalysisConsumer>(
804 CI.getFrontendOpts().Plugins,
815 std::unique_ptr<raw_ostream> Out;
819 typedef llvm::DenseMap<void*,unsigned> VMap;
823 UbigraphViz(std::unique_ptr<raw_ostream> Out, StringRef Filename);
825 ~UbigraphViz()
override;
835 llvm::sys::fs::createTemporaryFile(
"llvm_ubi",
"", FD, P);
836 llvm::errs() <<
"Writing '" << P <<
"'.\n";
838 auto Stream = llvm::make_unique<llvm::raw_fd_ostream>(FD,
true);
840 return llvm::make_unique<UbigraphViz>(std::move(Stream),
P);
845 assert (Src != Dst &&
"Self-edges are not allowed.");
848 VMap::iterator SrcI= M.find(Src);
851 if (SrcI == M.end()) {
852 M[Src] = SrcID = Cntr++;
853 *Out <<
"('vertex', " << SrcID <<
", ('color','#00ff00'))\n";
856 SrcID = SrcI->second;
859 VMap::iterator DstI= M.find(Dst);
862 if (DstI == M.end()) {
863 M[Dst] = DstID = Cntr++;
864 *Out <<
"('vertex', " << DstID <<
")\n";
868 DstID = DstI->second;
869 *Out <<
"('change_vertex_style', " << DstID <<
", 1)\n";
873 *Out <<
"('edge', " << SrcID <<
", " << DstID
874 <<
", ('arrow','true'), ('oriented', 'true'))\n";
877 UbigraphViz::UbigraphViz(std::unique_ptr<raw_ostream> OutStream,
879 : Out(std::move(OutStream)),
Filename(Filename), Cntr(0) {
881 *Out <<
"('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n";
882 *Out <<
"('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," 883 " ('size', '1.5'))\n";
886 UbigraphViz::~UbigraphViz() {
888 llvm::errs() <<
"Running 'ubiviz' program... ";
891 if (
auto Path = llvm::sys::findProgramByName(
"ubiviz"))
893 std::array<StringRef, 2> Args{{Ubiviz, Filename}};
895 if (llvm::sys::ExecuteAndWait(Ubiviz, Args,
llvm::None, {}, 0, 0, &ErrMsg)) {
896 llvm::errs() <<
"Error viewing graph: " << ErrMsg <<
"\n";
900 llvm::sys::fs::remove(Filename);
Manages a set of available checkers for running a static analysis.
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.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) 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.
ObjCMethodDecl - Represents an instance or class method declaration.
Describes how types, statements, expressions, and declarations should be printed. ...
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
PathDiagnosticLocation getLocation() const
PathDiagnostic - PathDiagnostic objects represent a single path-sensitive diagnostic.
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...
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...
const LangOptions & getLangOpts() const
ArrayRef< ParmVarDecl * > parameters() const
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
FrontendOptions & getFrontendOpts()
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()
std::unique_ptr< ConstraintManager >(* ConstraintManagerCreator)(ProgramStateManager &, SubEngine *)
static bool shouldSkipFunction(const Decl *D, const SetOfConstDecls &Visited, const SetOfConstDecls &VisitedAsTopLevel)
std::unique_ptr< CheckerManager > createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts, ArrayRef< std::string > plugins, ArrayRef< std::function< void(CheckerRegistry &)>> checkerRegistrationFns, DiagnosticsEngine &diags)
InliningModes
The modes of inlining, which override the default analysis-wide settings.
Pepresents 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...
void FlushReports()
Generate and flush diagnostics for all bug reports.
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.
PathPieces flatten(bool ShouldFlattenMacros) const
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.
BugReporter is a utility class for generating PathDiagnostics for analysis.
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
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
SourceLocation getLocStart() const LLVM_READONLY
unsigned getTotalNumBasicBlocks()
FullSourceLoc asLocation() const
BugReporter & getBugReporter()
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.
bool ExecuteWorkList(const LocationContext *L, unsigned Steps=150000)
Returns true if there is still simulation state on the worklist.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Dataflow Directional Tag Classes.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
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.
static std::unique_ptr< ExplodedNode::Auditor > CreateUbiViz()
static void SetAuditor(Auditor *A)
SourceManager & getSourceManager()
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
void addToCallGraph(Decl *D)
Populate the call graph with the functions in the given declaration.
std::string getQualifiedNameAsString() const
The top declaration context.
std::deque< Decl * > SetOfDecls
unsigned getTotalNumVisitedBasicBlocks()
void ViewGraph(bool trim=false)
Visualize the ExplodedGraph created by executing the simulation.
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.
StringRef getShortDescription() const