clang 24.0.0git
AnalysisDeclContext.cpp
Go to the documentation of this file.
1//===- AnalysisDeclContext.cpp - Analysis context for Path Sens analysis --===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines AnalysisDeclContext, a class that manages the analysis
10// context data for path sensitive analysis.
11//
12//===----------------------------------------------------------------------===//
13
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclBase.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/DeclObjC.h"
21#include "clang/AST/Expr.h"
23#include "clang/AST/ParentMap.h"
25#include "clang/AST/Stmt.h"
26#include "clang/AST/StmtCXX.h"
30#include "clang/Analysis/CFG.h"
34#include "clang/Basic/LLVM.h"
37#include "llvm/ADT/DenseMap.h"
38#include "llvm/ADT/FoldingSet.h"
39#include "llvm/ADT/STLExtras.h"
40#include "llvm/ADT/SmallPtrSet.h"
41#include "llvm/ADT/iterator_range.h"
42#include "llvm/Support/Allocator.h"
43#include "llvm/Support/Compiler.h"
44#include "llvm/Support/ErrorHandling.h"
45#include "llvm/Support/SaveAndRestore.h"
46#include "llvm/Support/raw_ostream.h"
47#include <cassert>
48#include <memory>
49
50using namespace clang;
51
52using ManagedAnalysisMap = llvm::DenseMap<const void *, std::unique_ptr<ManagedAnalysis>>;
53
55 const Decl *D,
56 const CFG::BuildOptions &Options)
57 : ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {
58 cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
59}
60
62 const Decl *D)
63 : ADCMgr(ADCMgr), D(D) {
64 cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
65}
66
68 ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors,
69 bool addInitializers, bool addTemporaryDtors, bool addLifetime,
70 bool addLoopExit, bool addScopes, bool synthesizeBodies,
71 bool addStaticInitBranch, bool addCXXNewAllocator,
72 bool addRichCXXConstructors, bool markElidedCXXConstructors,
73 bool addVirtualBaseBranches, std::unique_ptr<CodeInjector> injector)
74 : Injector(std::move(injector)), FunctionBodyFarm(ASTCtx, Injector.get()),
75 SynthesizeBodies(synthesizeBodies) {
76 cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
77 cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
78 cfgBuildOptions.AddInitializers = addInitializers;
79 cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
80 cfgBuildOptions.AddLifetime = addLifetime;
81 cfgBuildOptions.AddLoopExit = addLoopExit;
82 cfgBuildOptions.AddScopes = addScopes;
83 cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
84 cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
85 cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;
86 cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;
87 cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;
88}
89
90void AnalysisDeclContextManager::clear() { Contexts.clear(); }
91
92Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
93 IsAutosynthesized = false;
94 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
95 Stmt *Body = FD->getBody();
96 if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
97 Body = CoroBody->getBody();
98 if (ADCMgr && ADCMgr->synthesizeBodies()) {
99 Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);
100 if (SynthesizedBody) {
101 Body = SynthesizedBody;
102 IsAutosynthesized = true;
103 }
104 }
105 return Body;
106 }
107 else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
108 Stmt *Body = MD->getBody();
109 if (ADCMgr && ADCMgr->synthesizeBodies()) {
110 Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(MD);
111 if (SynthesizedBody) {
112 Body = SynthesizedBody;
113 IsAutosynthesized = true;
114 }
115 }
116 return Body;
117 } else if (const auto *BD = dyn_cast<BlockDecl>(D))
118 return BD->getBody();
119 else if (const auto *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
120 return FunTmpl->getTemplatedDecl()->getBody();
121 else if (const auto *VD = dyn_cast_or_null<VarDecl>(D)) {
122 if (VD->isFileVarDecl()) {
123 return const_cast<Stmt *>(dyn_cast_or_null<Stmt>(VD->getInit()));
124 }
125 }
126
127 llvm_unreachable("unknown code decl");
128}
129
131 bool Tmp;
132 return getBody(Tmp);
133}
134
136 bool Tmp;
137 getBody(Tmp);
138 return Tmp;
139}
140
142 bool Tmp;
143 Stmt *Body = getBody(Tmp);
144 return Tmp && Body->getBeginLoc().isValid();
145}
146
147/// Returns true if \param VD is an Objective-C implicit 'self' parameter.
148static bool isSelfDecl(const VarDecl *VD) {
149 return isa_and_nonnull<ImplicitParamDecl>(VD) && VD->getName() == "self";
150}
151
153 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
154 return MD->getSelfDecl();
155 if (const auto *BD = dyn_cast<BlockDecl>(D)) {
156 // See if 'self' was captured by the block.
157 for (const auto &I : BD->captures()) {
158 const VarDecl *VD = I.getVariable();
159 if (isSelfDecl(VD))
160 return dyn_cast<ImplicitParamDecl>(VD);
161 }
162 }
163
164 auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
165 if (!CXXMethod)
166 return nullptr;
167
168 const CXXRecordDecl *parent = CXXMethod->getParent();
169 if (!parent->isLambda())
170 return nullptr;
171
172 for (const auto &LC : parent->captures()) {
173 if (!LC.capturesVariable())
174 continue;
175
176 ValueDecl *VD = LC.getCapturedVar();
177 if (isSelfDecl(dyn_cast<VarDecl>(VD)))
178 return dyn_cast<ImplicitParamDecl>(VD);
179 }
180
181 return nullptr;
182}
183
185 if (!forcedBlkExprs)
186 forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
187 // Default construct an entry for 'stmt'.
188 if (const auto *e = dyn_cast<Expr>(stmt))
189 stmt = e->IgnoreParens();
190 (void) (*forcedBlkExprs)[stmt];
191}
192
193const CFGBlock *
195 assert(forcedBlkExprs);
196 if (const auto *e = dyn_cast<Expr>(stmt))
197 stmt = e->IgnoreParens();
198 CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
199 forcedBlkExprs->find(stmt);
200 assert(itr != forcedBlkExprs->end());
201 return itr->second;
202}
203
204/// Add each synthetic statement in the CFG to the parent map, using the
205/// source statement's parent.
206static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
207 if (!TheCFG)
208 return;
209
211 E = TheCFG->synthetic_stmt_end();
212 I != E; ++I) {
213 PM.setParent(I->first, PM.getParent(I->second));
214 }
215}
216
218 if (!cfgBuildOptions.PruneTriviallyFalseEdges)
219 return getUnoptimizedCFG();
220
221 if (!builtCFG) {
222 cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
223 // Even when the cfg is not successfully built, we don't
224 // want to try building it again.
225 builtCFG = true;
226
227 if (PM)
228 addParentsForSyntheticStmts(cfg.get(), *PM);
229
230 // The Observer should only observe one build of the CFG.
231 getCFGBuildOptions().Observer = nullptr;
232 }
233 return cfg.get();
234}
235
237 if (!builtCompleteCFG) {
238 SaveAndRestore NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges, false);
239 completeCFG =
240 CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
241 // Even when the cfg is not successfully built, we don't
242 // want to try building it again.
243 builtCompleteCFG = true;
244
245 if (PM)
246 addParentsForSyntheticStmts(completeCFG.get(), *PM);
247
248 // The Observer should only observe one build of the CFG.
249 getCFGBuildOptions().Observer = nullptr;
250 }
251 return completeCFG.get();
252}
253
255 if (cfgStmtMap)
256 return &*cfgStmtMap;
257
258 if (const CFG *c = getCFG()) {
259 cfgStmtMap.emplace(*c, getParentMap());
260 return &*cfgStmtMap;
261 }
262
263 return nullptr;
264}
265
267 if (CFA)
268 return CFA.get();
269
270 if (CFG *c = getCFG()) {
271 CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
272 return CFA.get();
273 }
274
275 return nullptr;
276}
277
278void AnalysisDeclContext::dumpCFG(bool ShowColors) {
279 getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
280}
281
283 if (!PM) {
284 PM.reset(new ParentMap(getBody()));
285 if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
286 for (const auto *I : C->inits()) {
287 PM->addStmt(I->getInit());
288 }
289 }
290 if (builtCFG)
292 if (builtCompleteCFG)
294 }
295 return *PM;
296}
297
299 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
300 // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
301 // that has the body.
302 FD->hasBody(FD);
303 D = FD;
304 }
305
306 std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
307 if (!AC)
308 AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
309 return AC.get();
310}
311
313
314const StackFrame *
316 const Expr *E, const CFGBlock *Blk,
317 unsigned BlockCount, unsigned Index) {
318 return getStackFrameManager().getStackFrame(this, ParentSF, Data, E, Blk,
319 BlockCount, Index);
320}
321
323 const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
324 const auto *ND = dyn_cast<NamespaceDecl>(DC);
325 if (!ND)
326 return false;
327
328 while (const DeclContext *Parent = ND->getParent()) {
329 if (!isa<NamespaceDecl>(Parent))
330 break;
331 ND = cast<NamespaceDecl>(Parent);
332 }
333
334 return ND->isStdNamespace();
335}
336
338 std::string Str;
339 llvm::raw_string_ostream OS(Str);
340 const ASTContext &Ctx = D->getASTContext();
341
342 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
343 OS << FD->getQualifiedNameAsString();
344
345 // In C++, there are overloads.
346
347 if (Ctx.getLangOpts().CPlusPlus) {
348 OS << '(';
349 for (const auto &P : FD->parameters()) {
350 if (P != *FD->param_begin())
351 OS << ", ";
352 OS << P->getType();
353 }
354 OS << ')';
355 }
356
357 } else if (isa<BlockDecl>(D)) {
358 PresumedLoc Loc = Ctx.getSourceManager().getPresumedLoc(D->getLocation());
359
360 if (Loc.isValid()) {
361 OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
362 << ')';
363 }
364
365 } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
366
367 // FIXME: copy-pasted from CGDebugInfo.cpp.
368 OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
369 const DeclContext *DC = OMD->getDeclContext();
370 if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
371 OS << OID->getName();
372 } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
373 OS << OID->getName();
374 } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
375 if (OC->IsClassExtension()) {
376 OS << OC->getClassInterface()->getName();
377 } else {
378 OS << OC->getIdentifier()->getNameStart() << '('
379 << OC->getIdentifier()->getNameStart() << ')';
380 }
381 } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
382 OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')';
383 }
384 OS << ' ' << OMD->getSelector().getAsString() << ']';
385 }
386
387 return Str;
388}
389
390StackFrameManager &AnalysisDeclContext::getStackFrameManager() {
391 assert(ADCMgr &&
392 "Cannot create StackFrames without an AnalysisDeclContextManager!");
393 return ADCMgr->getStackFrameManager();
394}
395
396//===----------------------------------------------------------------------===//
397// FoldingSet profiling.
398//===----------------------------------------------------------------------===//
399
400void StackFrame::Profile(llvm::FoldingSetNodeID &ID) {
401 Profile(ID, getAnalysisDeclContext(), getParent(), Data, CallSite, Block,
402 BlockCount, Index);
403}
404
405//===----------------------------------------------------------------------===//
406// StackFrame creation.
407//===----------------------------------------------------------------------===//
408
410 AnalysisDeclContext *Ctx, const StackFrame *Parent, const void *Data,
411 const Expr *E, const CFGBlock *B, unsigned BlockCount, unsigned StmtIdx) {
412 llvm::FoldingSetNodeID ID;
413 StackFrame::Profile(ID, Ctx, Parent, Data, E, B, BlockCount, StmtIdx);
414 void *InsertPos;
415 StackFrame *SF = Frames.FindNodeOrInsertPos(ID, InsertPos);
416 if (!SF) {
417 SF = new StackFrame(Ctx, Parent, Data, E, B, BlockCount, StmtIdx, ++NewID);
418 Frames.InsertNode(SF, InsertPos);
419 }
420 return SF;
421}
422
423//===----------------------------------------------------------------------===//
424// StackFrame methods.
425//===----------------------------------------------------------------------===//
426
427bool StackFrame::isParentOf(const StackFrame *SF) const {
428 return llvm::any_of(SF->parents(),
429 [this](const StackFrame &A) { return &A == this; });
430}
431
432static void printLocation(raw_ostream &Out, const SourceManager &SM,
433 SourceLocation Loc) {
434 if (Loc.isFileID() && SM.isInMainFile(Loc))
435 Out << SM.getExpansionLineNumber(Loc);
436 else
437 Loc.print(Out, SM);
438}
439
440void StackFrame::dumpStack(raw_ostream &Out) const {
442 PrintingPolicy PP(Ctx.getLangOpts());
443 PP.TerseOutput = 1;
444
445 const SourceManager &SM =
447
448 for (auto [Idx, SF] : llvm::enumerate(parentsIncludingSelf())) {
449 Out << "\t#" << Idx << ' ';
450 if (const auto *D = dyn_cast<NamedDecl>(SF.getDecl()))
451 Out << "Calling " << AnalysisDeclContext::getFunctionName(D);
452 else
453 Out << "Calling anonymous code";
454 if (const Expr *E = SF.getCallSite()) {
455 Out << " at line ";
456 printLocation(Out, SM, E->getBeginLoc());
457 }
458 Out << '\n';
459 }
460}
461
463 raw_ostream &Out, const char *NL, unsigned int Space, bool IsDot,
464 std::function<void(const StackFrame *)> printMoreInfoPerStackFrame) const {
466 PrintingPolicy PP(Ctx.getLangOpts());
467 PP.TerseOutput = 1;
468
469 const SourceManager &SM =
471
472 for (auto [Idx, SF] : llvm::enumerate(parentsIncludingSelf())) {
473 Indent(Out, Space, IsDot)
474 << "{ \"lctx_id\": " << SF.getID() << ", \"location_context\": \"";
475 Out << '#' << Idx << " Call\", \"calling\": \"";
476 if (const auto *D = dyn_cast<NamedDecl>(SF.getDecl()))
477 Out << D->getQualifiedNameAsString();
478 else
479 Out << "anonymous code";
480
481 Out << "\", \"location\": ";
482 if (const Expr *E = SF.getCallSite()) {
483 printSourceLocationAsJson(Out, E->getBeginLoc(), SM);
484 } else {
485 Out << "null";
486 }
487
488 Out << ", \"items\": ";
489
490 printMoreInfoPerStackFrame(&SF);
491
492 Out << '}';
493 if (SF.getParent())
494 Out << ',';
495 Out << NL;
496 }
497}
498
499LLVM_DUMP_METHOD void StackFrame::dump() const { printJson(llvm::errs()); }
500
501//===----------------------------------------------------------------------===//
502// Lazily generated map to query the external variables referenced by a Block.
503//===----------------------------------------------------------------------===//
504
505namespace {
506
507class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
512
513public:
514 FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
516 : BEVals(bevals), BC(bc) {}
517
518 void VisitStmt(Stmt *S) {
519 for (auto *Child : S->children())
520 if (Child)
521 Visit(Child);
522 }
523
524 void VisitDeclRefExpr(DeclRefExpr *DR) {
525 // Non-local variables are also directly modified.
526 if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
527 if (!VD->hasLocalStorage()) {
528 if (Visited.insert(VD).second)
529 BEVals.push_back(VD, BC);
530 }
531 }
532 }
533
534 void VisitBlockExpr(BlockExpr *BR) {
535 // Blocks containing blocks can transitively capture more variables.
536 IgnoredContexts.insert(BR->getBlockDecl());
537 Visit(BR->getBlockDecl()->getBody());
538 }
539
540 void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
542 et = PE->semantics_end(); it != et; ++it) {
543 Expr *Semantic = *it;
544 if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
545 Semantic = OVE->getSourceExpr();
546 Visit(Semantic);
547 }
548 }
549};
550
551} // namespace
552
554
556 void *&Vec,
557 llvm::BumpPtrAllocator &A) {
558 if (Vec)
559 return (DeclVec*) Vec;
560
561 BumpVectorContext BC(A);
562 DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
563 new (BV) DeclVec(BC, 10);
564
565 // Go through the capture list.
566 for (const auto &CI : BD->captures()) {
567 BV->push_back(CI.getVariable(), BC);
568 }
569
570 // Find the referenced global/static variables.
571 FindBlockDeclRefExprsVals F(*BV, BC);
572 F.Visit(BD->getBody());
573
574 Vec = BV;
575 return BV;
576}
577
578llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
580 if (!ReferencedBlockVars)
581 ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
582
583 const DeclVec *V =
584 LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
585 return llvm::make_range(V->begin(), V->end());
586}
587
588std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
589 if (!ManagedAnalyses)
590 ManagedAnalyses = new ManagedAnalysisMap();
591 ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
592 return (*M)[tag];
593}
594
595//===----------------------------------------------------------------------===//
596// Cleanup.
597//===----------------------------------------------------------------------===//
598
600
602 delete forcedBlkExprs;
603 delete ReferencedBlockVars;
604 delete (ManagedAnalysisMap*) ManagedAnalyses;
605}
606
608
610 for (llvm::FoldingSet<StackFrame>::iterator I = Frames.begin(),
611 E = Frames.end();
612 I != E;) {
613 StackFrame *SF = &*I;
614 ++I;
615 delete SF;
616 }
617 Frames.clear();
618}
Defines the clang::ASTContext interface.
#define V(N, I)
static DeclVec * LazyInitializeReferencedDecls(const BlockDecl *BD, void *&Vec, llvm::BumpPtrAllocator &A)
static bool isSelfDecl(const VarDecl *VD)
Returns true if.
static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM)
Add each synthetic statement in the CFG to the parent map, using the source statement's parent.
static void printLocation(raw_ostream &Out, const SourceManager &SM, SourceLocation Loc)
llvm::DenseMap< const void *, std::unique_ptr< ManagedAnalysis > > ManagedAnalysisMap
BumpVector< const VarDecl * > DeclVec
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the LambdaCapture class.
#define SM(sm)
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
SourceManager & getSourceManager()
Definition ASTContext.h:869
const LangOptions & getLangOpts() const
Definition ASTContext.h:965
AnalysisDeclContextManager(ASTContext &ASTCtx, bool useUnoptimizedCFG=false, bool addImplicitDtors=false, bool addInitializers=false, bool addTemporaryDtors=false, bool addLifetime=false, bool addLoopExit=false, bool addScopes=false, bool synthesizeBodies=false, bool addStaticInitBranches=false, bool addCXXNewAllocator=true, bool addRichCXXConstructors=true, bool markElidedCXXConstructors=true, bool addVirtualBaseBranches=true, std::unique_ptr< CodeInjector > injector=nullptr)
void clear()
Discard all previously created AnalysisDeclContexts.
AnalysisDeclContext * getContext(const Decl *D)
AnalysisDeclContext contains the context data for the function, method or block under analysis.
static std::string getFunctionName(const Decl *D)
void registerForcedBlockExpression(const Stmt *stmt)
const CFGBlock * getBlockForRegisteredExpression(const Stmt *stmt)
static bool isInStdNamespace(const Decl *D)
CFGReverseBlockReachabilityAnalysis * getCFGReachablityAnalysis()
const ImplicitParamDecl * getSelfDecl() const
ASTContext & getASTContext() const
llvm::iterator_range< referenced_decls_iterator > getReferencedBlockVars(const BlockDecl *BD)
const StackFrame * getStackFrame(const StackFrame *ParentSF, const void *Data, const Expr *E, const CFGBlock *Blk, unsigned BlockCount, unsigned Index)
Obtain a context of the call stack using its parent context.
AnalysisDeclContext(AnalysisDeclContextManager *Mgr, const Decl *D)
CFG::BuildOptions & getCFGBuildOptions()
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4716
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition Decl.h:4795
ArrayRef< Capture > captures() const
Definition Decl.h:4843
const BlockDecl * getBlockDecl() const
Definition Expr.h:6696
void push_back(const_reference Elt, BumpVectorContext &C)
Definition BumpVector.h:168
Represents a single basic block in a source-level CFG.
Definition CFG.h:652
CFGCallback * Observer
Definition CFG.h:1286
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
Definition CFG.h:1283
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition CFG.h:1271
static std::unique_ptr< CFG > buildCFG(const Decl *D, Stmt *AST, ASTContext *C, const BuildOptions &BO)
Builds a CFG from an AST.
Definition CFG.cpp:5458
synthetic_stmt_iterator synthetic_stmt_end() const
Definition CFG.h:1438
void dump(const LangOptions &LO, bool ShowColors) const
dump - A simple pretty printer of a CFG that outputs to stderr.
Definition CFG.cpp:6361
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
Definition CFG.h:1433
llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator
Definition CFG.h:1424
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition DeclCXX.h:1023
capture_const_range captures() const
Definition DeclCXX.h:1102
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1466
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2126
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
ValueDecl * getDecl()
Definition Expr.h:1344
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
This represents one expression.
Definition Expr.h:112
Represents a function declaration or definition.
Definition Decl.h:2029
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
void setParent(const Stmt *S, const Stmt *Parent)
Manually sets the parent of S to Parent.
Stmt * getParent(Stmt *) const
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
unsigned getLine() const
Return the presumed line number of this location.
semantics_iterator semantics_end()
Definition Expr.h:6881
semantics_iterator semantics_begin()
Definition Expr.h:6877
Expr *const * semantics_iterator
Definition Expr.h:6875
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
void print(raw_ostream &OS, const SourceManager &SM) const
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
void clear()
Discard all previously created StackFrame objects.
const StackFrame * getStackFrame(AnalysisDeclContext *ADC, const StackFrame *ParentSF, const void *Data, const Expr *E, const CFGBlock *Block, unsigned BlockCount, unsigned StmtIdx)
Obtain a context of the call stack using its parent context.
It represents a stack frame of the call stack.
LLVM_DUMP_METHOD void dump() const
StackFrame(AnalysisDeclContext *ADC, const StackFrame *Parent, const void *Data, const Expr *E, const CFGBlock *Block, unsigned BlockCount, unsigned Index, int64_t ID)
LLVM_DUMP_METHOD void dumpStack(raw_ostream &Out) const
Prints out the call stack.
bool isParentOf(const StackFrame *SF) const
void Profile(llvm::FoldingSetNodeID &ID)
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
void printJson(raw_ostream &Out, const char *NL="\n", unsigned int Space=0, bool IsDot=false, std::function< void(const StackFrame *)> printMoreInfoPerStackFrame=[](const StackFrame *) {}) const
Prints out the call stack in json format.
llvm::iterator_range< parent_iterator > parents() const
Iterates over the strict ancestors of this frame, i.e.
const StackFrame * getParent() const
It might return null.
llvm::iterator_range< parent_iterator > parentsIncludingSelf() const
Iterates over this frame followed by all of its ancestors.
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
Definition Stmt.h:86
child_range children()
Definition Stmt.cpp:304
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:355
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
Represents a variable declaration or definition.
Definition Decl.h:932
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Definition JsonSupport.h:21
void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc, const SourceManager &SM, bool AddBraces=true)
Definition JsonSupport.h:82
U cast(CodeGen::Address addr)
Definition Address.h:327
int const char * function
Definition c++config.h:31
Describes how types, statements, expressions, and declarations should be printed.
unsigned TerseOutput
Provide a 'terse' output.