clang 23.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/SmallPtrSet.h"
40#include "llvm/ADT/iterator_range.h"
41#include "llvm/Support/Allocator.h"
42#include "llvm/Support/Compiler.h"
43#include "llvm/Support/ErrorHandling.h"
44#include "llvm/Support/SaveAndRestore.h"
45#include "llvm/Support/raw_ostream.h"
46#include <cassert>
47#include <memory>
48
49using namespace clang;
50
51using ManagedAnalysisMap = llvm::DenseMap<const void *, std::unique_ptr<ManagedAnalysis>>;
52
54 const Decl *D,
55 const CFG::BuildOptions &Options)
56 : ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {
57 cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
58}
59
61 const Decl *D)
62 : ADCMgr(ADCMgr), D(D) {
63 cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
64}
65
67 ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors,
68 bool addInitializers, bool addTemporaryDtors, bool addLifetime,
69 bool addLoopExit, bool addScopes, bool synthesizeBodies,
70 bool addStaticInitBranch, bool addCXXNewAllocator,
71 bool addRichCXXConstructors, bool markElidedCXXConstructors,
72 bool addVirtualBaseBranches, std::unique_ptr<CodeInjector> injector)
73 : Injector(std::move(injector)), FunctionBodyFarm(ASTCtx, Injector.get()),
74 SynthesizeBodies(synthesizeBodies) {
75 cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
76 cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
77 cfgBuildOptions.AddInitializers = addInitializers;
78 cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
79 cfgBuildOptions.AddLifetime = addLifetime;
80 cfgBuildOptions.AddLoopExit = addLoopExit;
81 cfgBuildOptions.AddScopes = addScopes;
82 cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
83 cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
84 cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;
85 cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;
86 cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;
87}
88
89void AnalysisDeclContextManager::clear() { Contexts.clear(); }
90
91Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
92 IsAutosynthesized = false;
93 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
94 Stmt *Body = FD->getBody();
95 if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
96 Body = CoroBody->getBody();
97 if (ADCMgr && ADCMgr->synthesizeBodies()) {
98 Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);
99 if (SynthesizedBody) {
100 Body = SynthesizedBody;
101 IsAutosynthesized = true;
102 }
103 }
104 return Body;
105 }
106 else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
107 Stmt *Body = MD->getBody();
108 if (ADCMgr && ADCMgr->synthesizeBodies()) {
109 Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(MD);
110 if (SynthesizedBody) {
111 Body = SynthesizedBody;
112 IsAutosynthesized = true;
113 }
114 }
115 return Body;
116 } else if (const auto *BD = dyn_cast<BlockDecl>(D))
117 return BD->getBody();
118 else if (const auto *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
119 return FunTmpl->getTemplatedDecl()->getBody();
120 else if (const auto *VD = dyn_cast_or_null<VarDecl>(D)) {
121 if (VD->isFileVarDecl()) {
122 return const_cast<Stmt *>(dyn_cast_or_null<Stmt>(VD->getInit()));
123 }
124 }
125
126 llvm_unreachable("unknown code decl");
127}
128
130 bool Tmp;
131 return getBody(Tmp);
132}
133
135 bool Tmp;
136 getBody(Tmp);
137 return Tmp;
138}
139
141 bool Tmp;
142 Stmt *Body = getBody(Tmp);
143 return Tmp && Body->getBeginLoc().isValid();
144}
145
146/// Returns true if \param VD is an Objective-C implicit 'self' parameter.
147static bool isSelfDecl(const VarDecl *VD) {
148 return isa_and_nonnull<ImplicitParamDecl>(VD) && VD->getName() == "self";
149}
150
152 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
153 return MD->getSelfDecl();
154 if (const auto *BD = dyn_cast<BlockDecl>(D)) {
155 // See if 'self' was captured by the block.
156 for (const auto &I : BD->captures()) {
157 const VarDecl *VD = I.getVariable();
158 if (isSelfDecl(VD))
159 return dyn_cast<ImplicitParamDecl>(VD);
160 }
161 }
162
163 auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
164 if (!CXXMethod)
165 return nullptr;
166
167 const CXXRecordDecl *parent = CXXMethod->getParent();
168 if (!parent->isLambda())
169 return nullptr;
170
171 for (const auto &LC : parent->captures()) {
172 if (!LC.capturesVariable())
173 continue;
174
175 ValueDecl *VD = LC.getCapturedVar();
176 if (isSelfDecl(dyn_cast<VarDecl>(VD)))
177 return dyn_cast<ImplicitParamDecl>(VD);
178 }
179
180 return nullptr;
181}
182
184 if (!forcedBlkExprs)
185 forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
186 // Default construct an entry for 'stmt'.
187 if (const auto *e = dyn_cast<Expr>(stmt))
188 stmt = e->IgnoreParens();
189 (void) (*forcedBlkExprs)[stmt];
190}
191
192const CFGBlock *
194 assert(forcedBlkExprs);
195 if (const auto *e = dyn_cast<Expr>(stmt))
196 stmt = e->IgnoreParens();
197 CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
198 forcedBlkExprs->find(stmt);
199 assert(itr != forcedBlkExprs->end());
200 return itr->second;
201}
202
203/// Add each synthetic statement in the CFG to the parent map, using the
204/// source statement's parent.
205static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
206 if (!TheCFG)
207 return;
208
210 E = TheCFG->synthetic_stmt_end();
211 I != E; ++I) {
212 PM.setParent(I->first, PM.getParent(I->second));
213 }
214}
215
217 if (!cfgBuildOptions.PruneTriviallyFalseEdges)
218 return getUnoptimizedCFG();
219
220 if (!builtCFG) {
221 cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
222 // Even when the cfg is not successfully built, we don't
223 // want to try building it again.
224 builtCFG = true;
225
226 if (PM)
227 addParentsForSyntheticStmts(cfg.get(), *PM);
228
229 // The Observer should only observe one build of the CFG.
230 getCFGBuildOptions().Observer = nullptr;
231 }
232 return cfg.get();
233}
234
236 if (!builtCompleteCFG) {
237 SaveAndRestore NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges, false);
238 completeCFG =
239 CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
240 // Even when the cfg is not successfully built, we don't
241 // want to try building it again.
242 builtCompleteCFG = true;
243
244 if (PM)
245 addParentsForSyntheticStmts(completeCFG.get(), *PM);
246
247 // The Observer should only observe one build of the CFG.
248 getCFGBuildOptions().Observer = nullptr;
249 }
250 return completeCFG.get();
251}
252
254 if (cfgStmtMap)
255 return &*cfgStmtMap;
256
257 if (const CFG *c = getCFG()) {
258 cfgStmtMap.emplace(*c, getParentMap());
259 return &*cfgStmtMap;
260 }
261
262 return nullptr;
263}
264
266 if (CFA)
267 return CFA.get();
268
269 if (CFG *c = getCFG()) {
270 CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
271 return CFA.get();
272 }
273
274 return nullptr;
275}
276
277void AnalysisDeclContext::dumpCFG(bool ShowColors) {
278 getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
279}
280
282 if (!PM) {
283 PM.reset(new ParentMap(getBody()));
284 if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
285 for (const auto *I : C->inits()) {
286 PM->addStmt(I->getInit());
287 }
288 }
289 if (builtCFG)
291 if (builtCompleteCFG)
293 }
294 return *PM;
295}
296
298 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
299 // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
300 // that has the body.
301 FD->hasBody(FD);
302 D = FD;
303 }
304
305 std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
306 if (!AC)
307 AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
308 return AC.get();
309}
310
312
314 const LocationContext *ParentLC, const void *Data, const Expr *E,
315 const CFGBlock *Blk, unsigned BlockCount, unsigned Index) {
316 return getLocationContextManager().getStackFrame(this, ParentLC, Data, E, Blk,
317 BlockCount, Index);
318}
319
321 const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
322 const auto *ND = dyn_cast<NamespaceDecl>(DC);
323 if (!ND)
324 return false;
325
326 while (const DeclContext *Parent = ND->getParent()) {
327 if (!isa<NamespaceDecl>(Parent))
328 break;
329 ND = cast<NamespaceDecl>(Parent);
330 }
331
332 return ND->isStdNamespace();
333}
334
336 std::string Str;
337 llvm::raw_string_ostream OS(Str);
338 const ASTContext &Ctx = D->getASTContext();
339
340 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
341 OS << FD->getQualifiedNameAsString();
342
343 // In C++, there are overloads.
344
345 if (Ctx.getLangOpts().CPlusPlus) {
346 OS << '(';
347 for (const auto &P : FD->parameters()) {
348 if (P != *FD->param_begin())
349 OS << ", ";
350 OS << P->getType();
351 }
352 OS << ')';
353 }
354
355 } else if (isa<BlockDecl>(D)) {
356 PresumedLoc Loc = Ctx.getSourceManager().getPresumedLoc(D->getLocation());
357
358 if (Loc.isValid()) {
359 OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
360 << ')';
361 }
362
363 } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
364
365 // FIXME: copy-pasted from CGDebugInfo.cpp.
366 OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
367 const DeclContext *DC = OMD->getDeclContext();
368 if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
369 OS << OID->getName();
370 } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
371 OS << OID->getName();
372 } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
373 if (OC->IsClassExtension()) {
374 OS << OC->getClassInterface()->getName();
375 } else {
376 OS << OC->getIdentifier()->getNameStart() << '('
377 << OC->getIdentifier()->getNameStart() << ')';
378 }
379 } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
380 OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')';
381 }
382 OS << ' ' << OMD->getSelector().getAsString() << ']';
383 }
384
385 return Str;
386}
387
388LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
389 assert(
390 ADCMgr &&
391 "Cannot create LocationContexts without an AnalysisDeclContextManager!");
392 return ADCMgr->getLocationContextManager();
393}
394
395//===----------------------------------------------------------------------===//
396// FoldingSet profiling.
397//===----------------------------------------------------------------------===//
398
399void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
400 ContextKind ck,
402 const LocationContext *parent,
403 const void *data) {
404 ID.AddInteger(ck);
405 ID.AddPointer(ctx);
406 ID.AddPointer(parent);
407 ID.AddPointer(data);
408}
409
410void StackFrame::Profile(llvm::FoldingSetNodeID &ID) {
411 Profile(ID, getAnalysisDeclContext(), getParent(), Data, CallSite, Block,
412 BlockCount, Index);
413}
414
415//===----------------------------------------------------------------------===//
416// LocationContext creation.
417//===----------------------------------------------------------------------===//
418
420 AnalysisDeclContext *Ctx, const LocationContext *Parent, const void *Data,
421 const Expr *E, const CFGBlock *Blk, unsigned BlockCount, unsigned StmtIdx) {
422 llvm::FoldingSetNodeID ID;
423 StackFrame::Profile(ID, Ctx, Parent, Data, E, Blk, BlockCount, StmtIdx);
424 void *InsertPos;
425 auto *L =
426 cast_or_null<StackFrame>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
427 if (!L) {
428 L = new StackFrame(Ctx, Parent, Data, E, Blk, BlockCount, StmtIdx, ++NewID);
429 Contexts.InsertNode(L, InsertPos);
430 }
431 return L;
432}
433
434//===----------------------------------------------------------------------===//
435// LocationContext methods.
436//===----------------------------------------------------------------------===//
437
439 const LocationContext *LC = this;
440 while (LC) {
441 if (const auto *SF = dyn_cast<StackFrame>(LC))
442 return SF;
443 LC = LC->getParent();
444 }
445 return nullptr;
446}
447
449 return getStackFrame()->inTopFrame();
450}
451
453 do {
454 const LocationContext *Parent = LC->getParent();
455 if (Parent == this)
456 return true;
457 else
458 LC = Parent;
459 } while (LC);
460
461 return false;
462}
463
464static void printLocation(raw_ostream &Out, const SourceManager &SM,
465 SourceLocation Loc) {
466 if (Loc.isFileID() && SM.isInMainFile(Loc))
467 Out << SM.getExpansionLineNumber(Loc);
468 else
469 Loc.print(Out, SM);
470}
471
472void LocationContext::dumpStack(raw_ostream &Out) const {
474 PrintingPolicy PP(Ctx.getLangOpts());
475 PP.TerseOutput = 1;
476
477 const SourceManager &SM =
479
480 unsigned Frame = 0;
481 for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
482 switch (LCtx->getKind()) {
483 case StackFrameKind:
484 Out << "\t#" << Frame << ' ';
485 ++Frame;
486 if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
487 Out << "Calling " << AnalysisDeclContext::getFunctionName(D);
488 else
489 Out << "Calling anonymous code";
490 if (const Expr *E = cast<StackFrame>(LCtx)->getCallSite()) {
491 Out << " at line ";
492 printLocation(Out, SM, E->getBeginLoc());
493 }
494 break;
495 }
496 Out << '\n';
497 }
498}
499
500void LocationContext::printJson(raw_ostream &Out, const char *NL,
501 unsigned int Space, bool IsDot,
502 std::function<void(const LocationContext *)>
503 printMoreInfoPerContext) const {
505 PrintingPolicy PP(Ctx.getLangOpts());
506 PP.TerseOutput = 1;
507
508 const SourceManager &SM =
510
511 unsigned Frame = 0;
512 for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
513 Indent(Out, Space, IsDot)
514 << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
515 switch (LCtx->getKind()) {
516 case StackFrameKind:
517 Out << '#' << Frame << " Call\", \"calling\": \"";
518 ++Frame;
519 if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
520 Out << D->getQualifiedNameAsString();
521 else
522 Out << "anonymous code";
523
524 Out << "\", \"location\": ";
525 if (const Expr *E = cast<StackFrame>(LCtx)->getCallSite()) {
526 printSourceLocationAsJson(Out, E->getBeginLoc(), SM);
527 } else {
528 Out << "null";
529 }
530
531 Out << ", \"items\": ";
532 break;
533 }
534
535 printMoreInfoPerContext(LCtx);
536
537 Out << '}';
538 if (LCtx->getParent())
539 Out << ',';
540 Out << NL;
541 }
542}
543
544LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); }
545
546//===----------------------------------------------------------------------===//
547// Lazily generated map to query the external variables referenced by a Block.
548//===----------------------------------------------------------------------===//
549
550namespace {
551
552class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
557
558public:
559 FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
561 : BEVals(bevals), BC(bc) {}
562
563 void VisitStmt(Stmt *S) {
564 for (auto *Child : S->children())
565 if (Child)
566 Visit(Child);
567 }
568
569 void VisitDeclRefExpr(DeclRefExpr *DR) {
570 // Non-local variables are also directly modified.
571 if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
572 if (!VD->hasLocalStorage()) {
573 if (Visited.insert(VD).second)
574 BEVals.push_back(VD, BC);
575 }
576 }
577 }
578
579 void VisitBlockExpr(BlockExpr *BR) {
580 // Blocks containing blocks can transitively capture more variables.
581 IgnoredContexts.insert(BR->getBlockDecl());
582 Visit(BR->getBlockDecl()->getBody());
583 }
584
585 void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
587 et = PE->semantics_end(); it != et; ++it) {
588 Expr *Semantic = *it;
589 if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
590 Semantic = OVE->getSourceExpr();
591 Visit(Semantic);
592 }
593 }
594};
595
596} // namespace
597
599
601 void *&Vec,
602 llvm::BumpPtrAllocator &A) {
603 if (Vec)
604 return (DeclVec*) Vec;
605
606 BumpVectorContext BC(A);
607 DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
608 new (BV) DeclVec(BC, 10);
609
610 // Go through the capture list.
611 for (const auto &CI : BD->captures()) {
612 BV->push_back(CI.getVariable(), BC);
613 }
614
615 // Find the referenced global/static variables.
616 FindBlockDeclRefExprsVals F(*BV, BC);
617 F.Visit(BD->getBody());
618
619 Vec = BV;
620 return BV;
621}
622
623llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
625 if (!ReferencedBlockVars)
626 ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
627
628 const DeclVec *V =
629 LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
630 return llvm::make_range(V->begin(), V->end());
631}
632
633std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
634 if (!ManagedAnalyses)
635 ManagedAnalyses = new ManagedAnalysisMap();
636 ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
637 return (*M)[tag];
638}
639
640//===----------------------------------------------------------------------===//
641// Cleanup.
642//===----------------------------------------------------------------------===//
643
645
647 delete forcedBlkExprs;
648 delete ReferencedBlockVars;
649 delete (ManagedAnalysisMap*) ManagedAnalyses;
650}
651
653
657
659 for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
660 E = Contexts.end(); I != E; ) {
661 LocationContext *LC = &*I;
662 ++I;
663 delete LC;
664 }
665 Contexts.clear();
666}
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.
__device__ __2f16 float c
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:227
SourceManager & getSourceManager()
Definition ASTContext.h:866
const LangOptions & getLangOpts() const
Definition ASTContext.h:959
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)
AnalysisDeclContext(AnalysisDeclContextManager *Mgr, const Decl *D)
const StackFrame * getStackFrame(LocationContext const *ParentLC, const void *Data, const Expr *E, const CFGBlock *Blk, unsigned BlockCount, unsigned Index)
Obtain a context of the call stack using its parent context.
CFG::BuildOptions & getCFGBuildOptions()
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4690
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:4769
ArrayRef< Capture > captures() const
Definition Decl.h:4817
const BlockDecl * getBlockDecl() const
Definition Expr.h:6685
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:632
CFGCallback * Observer
Definition CFG.h:1265
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
Definition CFG.h:1262
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition CFG.h:1250
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:5453
synthetic_stmt_iterator synthetic_stmt_end() const
Definition CFG.h:1417
void dump(const LangOptions &LO, bool ShowColors) const
dump - A simple pretty printer of a CFG that outputs to stderr.
Definition CFG.cpp:6356
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
Definition CFG.h:1412
llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator
Definition CFG.h:1403
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:1018
capture_const_range captures() const
Definition DeclCXX.h:1097
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1462
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2122
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
ValueDecl * getDecl()
Definition Expr.h:1341
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:2018
const StackFrame * getStackFrame(AnalysisDeclContext *ADC, const LocationContext *ParentLC, const void *Data, const Expr *E, const CFGBlock *Block, unsigned BlockCount, unsigned StmtIdx)
Obtain a context of the call stack using its parent context.
void clear()
Discard all previously created LocationContext objects.
bool isParentOf(const LocationContext *LC) const
LocationContext(ContextKind k, AnalysisDeclContext *ctx, const LocationContext *parent, int64_t ID)
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
static void ProfileCommon(llvm::FoldingSetNodeID &ID, ContextKind ck, AnalysisDeclContext *ctx, const LocationContext *parent, const void *data)
const LocationContext * getParent() const
It might return null.
const StackFrame * getStackFrame() const
LLVM_DUMP_METHOD void dumpStack(raw_ostream &Out) const
Prints out the call stack.
LLVM_DUMP_METHOD void dump() const
virtual bool inTopFrame() const
void printJson(raw_ostream &Out, const char *NL="\n", unsigned int Space=0, bool IsDot=false, std::function< void(const LocationContext *)> printMoreInfoPerContext=[](const LocationContext *) {}) const
Prints out the call stack in json format.
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:6870
semantics_iterator semantics_begin()
Definition Expr.h:6866
Expr *const * semantics_iterator
Definition Expr.h:6864
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.
It represents a stack frame of the call stack (based on CallEvent).
bool inTopFrame() const override
void Profile(llvm::FoldingSetNodeID &ID) override
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:924
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.