clang 19.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/Casting.h"
44#include "llvm/Support/Compiler.h"
45#include "llvm/Support/ErrorHandling.h"
46#include "llvm/Support/SaveAndRestore.h"
47#include "llvm/Support/raw_ostream.h"
48#include <cassert>
49#include <memory>
50
51using namespace clang;
52
53using ManagedAnalysisMap = llvm::DenseMap<const void *, std::unique_ptr<ManagedAnalysis>>;
54
56 const Decl *D,
57 const CFG::BuildOptions &Options)
58 : ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {
59 cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
60}
61
63 const Decl *D)
64 : ADCMgr(ADCMgr), D(D) {
65 cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
66}
67
69 ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors,
70 bool addInitializers, bool addTemporaryDtors, bool addLifetime,
71 bool addLoopExit, bool addScopes, bool synthesizeBodies,
72 bool addStaticInitBranch, bool addCXXNewAllocator,
73 bool addRichCXXConstructors, bool markElidedCXXConstructors,
74 bool addVirtualBaseBranches, CodeInjector *injector)
75 : Injector(injector), FunctionBodyFarm(ASTCtx, injector),
76 SynthesizeBodies(synthesizeBodies) {
77 cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
78 cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
79 cfgBuildOptions.AddInitializers = addInitializers;
80 cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
81 cfgBuildOptions.AddLifetime = addLifetime;
82 cfgBuildOptions.AddLoopExit = addLoopExit;
83 cfgBuildOptions.AddScopes = addScopes;
84 cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
85 cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
86 cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;
87 cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;
88 cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;
89}
90
91void AnalysisDeclContextManager::clear() { Contexts.clear(); }
92
93Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
94 IsAutosynthesized = false;
95 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
96 Stmt *Body = FD->getBody();
97 if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
98 Body = CoroBody->getBody();
99 if (ADCMgr && ADCMgr->synthesizeBodies()) {
100 Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);
101 if (SynthesizedBody) {
102 Body = SynthesizedBody;
103 IsAutosynthesized = true;
104 }
105 }
106 return Body;
107 }
108 else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
109 Stmt *Body = MD->getBody();
110 if (ADCMgr && ADCMgr->synthesizeBodies()) {
111 Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(MD);
112 if (SynthesizedBody) {
113 Body = SynthesizedBody;
114 IsAutosynthesized = true;
115 }
116 }
117 return Body;
118 } else if (const auto *BD = dyn_cast<BlockDecl>(D))
119 return BD->getBody();
120 else if (const auto *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
121 return FunTmpl->getTemplatedDecl()->getBody();
122
123 llvm_unreachable("unknown code decl");
124}
125
127 bool Tmp;
128 return getBody(Tmp);
129}
130
132 bool Tmp;
133 getBody(Tmp);
134 return Tmp;
135}
136
138 bool Tmp;
139 Stmt *Body = getBody(Tmp);
140 return Tmp && Body->getBeginLoc().isValid();
141}
142
143/// Returns true if \param VD is an Objective-C implicit 'self' parameter.
144static bool isSelfDecl(const VarDecl *VD) {
145 return isa_and_nonnull<ImplicitParamDecl>(VD) && VD->getName() == "self";
146}
147
149 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
150 return MD->getSelfDecl();
151 if (const auto *BD = dyn_cast<BlockDecl>(D)) {
152 // See if 'self' was captured by the block.
153 for (const auto &I : BD->captures()) {
154 const VarDecl *VD = I.getVariable();
155 if (isSelfDecl(VD))
156 return dyn_cast<ImplicitParamDecl>(VD);
157 }
158 }
159
160 auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
161 if (!CXXMethod)
162 return nullptr;
163
164 const CXXRecordDecl *parent = CXXMethod->getParent();
165 if (!parent->isLambda())
166 return nullptr;
167
168 for (const auto &LC : parent->captures()) {
169 if (!LC.capturesVariable())
170 continue;
171
172 ValueDecl *VD = LC.getCapturedVar();
173 if (isSelfDecl(dyn_cast<VarDecl>(VD)))
174 return dyn_cast<ImplicitParamDecl>(VD);
175 }
176
177 return nullptr;
178}
179
181 if (!forcedBlkExprs)
182 forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
183 // Default construct an entry for 'stmt'.
184 if (const auto *e = dyn_cast<Expr>(stmt))
185 stmt = e->IgnoreParens();
186 (void) (*forcedBlkExprs)[stmt];
187}
188
189const CFGBlock *
191 assert(forcedBlkExprs);
192 if (const auto *e = dyn_cast<Expr>(stmt))
193 stmt = e->IgnoreParens();
194 CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
195 forcedBlkExprs->find(stmt);
196 assert(itr != forcedBlkExprs->end());
197 return itr->second;
198}
199
200/// Add each synthetic statement in the CFG to the parent map, using the
201/// source statement's parent.
202static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
203 if (!TheCFG)
204 return;
205
207 E = TheCFG->synthetic_stmt_end();
208 I != E; ++I) {
209 PM.setParent(I->first, PM.getParent(I->second));
210 }
211}
212
214 if (!cfgBuildOptions.PruneTriviallyFalseEdges)
215 return getUnoptimizedCFG();
216
217 if (!builtCFG) {
218 cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
219 // Even when the cfg is not successfully built, we don't
220 // want to try building it again.
221 builtCFG = true;
222
223 if (PM)
224 addParentsForSyntheticStmts(cfg.get(), *PM);
225
226 // The Observer should only observe one build of the CFG.
227 getCFGBuildOptions().Observer = nullptr;
228 }
229 return cfg.get();
230}
231
233 if (!builtCompleteCFG) {
234 SaveAndRestore NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges, false);
235 completeCFG =
236 CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
237 // Even when the cfg is not successfully built, we don't
238 // want to try building it again.
239 builtCompleteCFG = true;
240
241 if (PM)
242 addParentsForSyntheticStmts(completeCFG.get(), *PM);
243
244 // The Observer should only observe one build of the CFG.
245 getCFGBuildOptions().Observer = nullptr;
246 }
247 return completeCFG.get();
248}
249
251 if (cfgStmtMap)
252 return cfgStmtMap.get();
253
254 if (CFG *c = getCFG()) {
255 cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
256 return cfgStmtMap.get();
257 }
258
259 return nullptr;
260}
261
263 if (CFA)
264 return CFA.get();
265
266 if (CFG *c = getCFG()) {
267 CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
268 return CFA.get();
269 }
270
271 return nullptr;
272}
273
275 getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
276}
277
279 if (!PM) {
280 PM.reset(new ParentMap(getBody()));
281 if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
282 for (const auto *I : C->inits()) {
283 PM->addStmt(I->getInit());
284 }
285 }
286 if (builtCFG)
288 if (builtCompleteCFG)
290 }
291 return *PM;
292}
293
295 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
296 // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
297 // that has the body.
298 FD->hasBody(FD);
299 D = FD;
300 }
301
302 std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
303 if (!AC)
304 AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
305 return AC.get();
306}
307
309
310const StackFrameContext *
312 const Stmt *S, const CFGBlock *Blk,
313 unsigned BlockCount, unsigned Index) {
314 return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,
315 BlockCount, Index);
316}
317
319 const LocationContext *ParentLC, const BlockDecl *BD, const void *Data) {
320 return getLocationContextManager().getBlockInvocationContext(this, ParentLC,
321 BD, Data);
322}
323
326 const auto *ND = dyn_cast<NamespaceDecl>(DC);
327 if (!ND)
328 return false;
329
330 while (const DeclContext *Parent = ND->getParent()) {
331 if (!isa<NamespaceDecl>(Parent))
332 break;
333 ND = cast<NamespaceDecl>(Parent);
334 }
335
336 return ND->isStdNamespace();
337}
338
340 std::string Str;
341 llvm::raw_string_ostream OS(Str);
342 const ASTContext &Ctx = D->getASTContext();
343
344 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
345 OS << FD->getQualifiedNameAsString();
346
347 // In C++, there are overloads.
348
349 if (Ctx.getLangOpts().CPlusPlus) {
350 OS << '(';
351 for (const auto &P : FD->parameters()) {
352 if (P != *FD->param_begin())
353 OS << ", ";
354 OS << P->getType();
355 }
356 OS << ')';
357 }
358
359 } else if (isa<BlockDecl>(D)) {
361
362 if (Loc.isValid()) {
363 OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
364 << ')';
365 }
366
367 } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
368
369 // FIXME: copy-pasted from CGDebugInfo.cpp.
370 OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
371 const DeclContext *DC = OMD->getDeclContext();
372 if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
373 OS << OID->getName();
374 } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
375 OS << OID->getName();
376 } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
377 if (OC->IsClassExtension()) {
378 OS << OC->getClassInterface()->getName();
379 } else {
380 OS << OC->getIdentifier()->getNameStart() << '('
381 << OC->getIdentifier()->getNameStart() << ')';
382 }
383 } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
384 OS << OCD->getClassInterface()->getName() << '(' << OCD->getName() << ')';
385 }
386 OS << ' ' << OMD->getSelector().getAsString() << ']';
387 }
388
389 return Str;
390}
391
392LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
393 assert(
394 ADCMgr &&
395 "Cannot create LocationContexts without an AnalysisDeclContextManager!");
396 return ADCMgr->getLocationContextManager();
397}
398
399//===----------------------------------------------------------------------===//
400// FoldingSet profiling.
401//===----------------------------------------------------------------------===//
402
403void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
404 ContextKind ck,
406 const LocationContext *parent,
407 const void *data) {
408 ID.AddInteger(ck);
409 ID.AddPointer(ctx);
410 ID.AddPointer(parent);
411 ID.AddPointer(data);
412}
413
414void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
415 Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,
416 BlockCount, Index);
417}
418
419void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
420 Profile(ID, getAnalysisDeclContext(), getParent(), BD, Data);
421}
422
423//===----------------------------------------------------------------------===//
424// LocationContext creation.
425//===----------------------------------------------------------------------===//
426
428 AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,
429 const CFGBlock *blk, unsigned blockCount, unsigned idx) {
430 llvm::FoldingSetNodeID ID;
431 StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);
432 void *InsertPos;
433 auto *L =
434 cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
435 if (!L) {
436 L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);
437 Contexts.InsertNode(L, InsertPos);
438 }
439 return L;
440}
441
443 AnalysisDeclContext *ADC, const LocationContext *ParentLC,
444 const BlockDecl *BD, const void *Data) {
445 llvm::FoldingSetNodeID ID;
446 BlockInvocationContext::Profile(ID, ADC, ParentLC, BD, Data);
447 void *InsertPos;
448 auto *L =
449 cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
450 InsertPos));
451 if (!L) {
452 L = new BlockInvocationContext(ADC, ParentLC, BD, Data, ++NewID);
453 Contexts.InsertNode(L, InsertPos);
454 }
455 return L;
456}
457
458//===----------------------------------------------------------------------===//
459// LocationContext methods.
460//===----------------------------------------------------------------------===//
461
463 const LocationContext *LC = this;
464 while (LC) {
465 if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
466 return SFC;
467 LC = LC->getParent();
468 }
469 return nullptr;
470}
471
473 return getStackFrame()->inTopFrame();
474}
475
477 do {
478 const LocationContext *Parent = LC->getParent();
479 if (Parent == this)
480 return true;
481 else
482 LC = Parent;
483 } while (LC);
484
485 return false;
486}
487
488static void printLocation(raw_ostream &Out, const SourceManager &SM,
489 SourceLocation Loc) {
490 if (Loc.isFileID() && SM.isInMainFile(Loc))
491 Out << SM.getExpansionLineNumber(Loc);
492 else
493 Loc.print(Out, SM);
494}
495
496void LocationContext::dumpStack(raw_ostream &Out) const {
498 PrintingPolicy PP(Ctx.getLangOpts());
499 PP.TerseOutput = 1;
500
501 const SourceManager &SM =
503
504 unsigned Frame = 0;
505 for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
506 switch (LCtx->getKind()) {
507 case StackFrame:
508 Out << "\t#" << Frame << ' ';
509 ++Frame;
510 if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
511 Out << "Calling " << AnalysisDeclContext::getFunctionName(D);
512 else
513 Out << "Calling anonymous code";
514 if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
515 Out << " at line ";
516 printLocation(Out, SM, S->getBeginLoc());
517 }
518 break;
519 case Block:
520 Out << "Invoking block";
521 if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
522 Out << " defined at line ";
523 printLocation(Out, SM, D->getBeginLoc());
524 }
525 break;
526 }
527 Out << '\n';
528 }
529}
530
531void LocationContext::printJson(raw_ostream &Out, const char *NL,
532 unsigned int Space, bool IsDot,
533 std::function<void(const LocationContext *)>
534 printMoreInfoPerContext) const {
536 PrintingPolicy PP(Ctx.getLangOpts());
537 PP.TerseOutput = 1;
538
539 const SourceManager &SM =
541
542 unsigned Frame = 0;
543 for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
544 Indent(Out, Space, IsDot)
545 << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
546 switch (LCtx->getKind()) {
547 case StackFrame:
548 Out << '#' << Frame << " Call\", \"calling\": \"";
549 ++Frame;
550 if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
551 Out << D->getQualifiedNameAsString();
552 else
553 Out << "anonymous code";
554
555 Out << "\", \"location\": ";
556 if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
557 printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
558 } else {
559 Out << "null";
560 }
561
562 Out << ", \"items\": ";
563 break;
564 case Block:
565 Out << "Invoking block\" ";
566 if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
567 Out << ", \"location\": ";
568 printSourceLocationAsJson(Out, D->getBeginLoc(), SM);
569 Out << ' ';
570 }
571 break;
572 }
573
574 printMoreInfoPerContext(LCtx);
575
576 Out << '}';
577 if (LCtx->getParent())
578 Out << ',';
579 Out << NL;
580 }
581}
582
583LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); }
584
585//===----------------------------------------------------------------------===//
586// Lazily generated map to query the external variables referenced by a Block.
587//===----------------------------------------------------------------------===//
588
589namespace {
590
591class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
596
597public:
598 FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
600 : BEVals(bevals), BC(bc) {}
601
602 void VisitStmt(Stmt *S) {
603 for (auto *Child : S->children())
604 if (Child)
605 Visit(Child);
606 }
607
608 void VisitDeclRefExpr(DeclRefExpr *DR) {
609 // Non-local variables are also directly modified.
610 if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
611 if (!VD->hasLocalStorage()) {
612 if (Visited.insert(VD).second)
613 BEVals.push_back(VD, BC);
614 }
615 }
616 }
617
618 void VisitBlockExpr(BlockExpr *BR) {
619 // Blocks containing blocks can transitively capture more variables.
620 IgnoredContexts.insert(BR->getBlockDecl());
621 Visit(BR->getBlockDecl()->getBody());
622 }
623
624 void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
626 et = PE->semantics_end(); it != et; ++it) {
627 Expr *Semantic = *it;
628 if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
629 Semantic = OVE->getSourceExpr();
630 Visit(Semantic);
631 }
632 }
633};
634
635} // namespace
636
638
640 void *&Vec,
641 llvm::BumpPtrAllocator &A) {
642 if (Vec)
643 return (DeclVec*) Vec;
644
645 BumpVectorContext BC(A);
646 DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
647 new (BV) DeclVec(BC, 10);
648
649 // Go through the capture list.
650 for (const auto &CI : BD->captures()) {
651 BV->push_back(CI.getVariable(), BC);
652 }
653
654 // Find the referenced global/static variables.
655 FindBlockDeclRefExprsVals F(*BV, BC);
656 F.Visit(BD->getBody());
657
658 Vec = BV;
659 return BV;
660}
661
662llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
664 if (!ReferencedBlockVars)
665 ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
666
667 const DeclVec *V =
668 LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
669 return llvm::make_range(V->begin(), V->end());
670}
671
672std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
673 if (!ManagedAnalyses)
674 ManagedAnalyses = new ManagedAnalysisMap();
675 ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
676 return (*M)[tag];
677}
678
679//===----------------------------------------------------------------------===//
680// Cleanup.
681//===----------------------------------------------------------------------===//
682
684
686 delete forcedBlkExprs;
687 delete ReferencedBlockVars;
688 delete (ManagedAnalysisMap*) ManagedAnalyses;
689}
690
692
694 clear();
695}
696
698 for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
699 E = Contexts.end(); I != E; ) {
700 LocationContext *LC = &*I;
701 ++I;
702 delete LC;
703 }
704 Contexts.clear();
705}
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3273
NodeId Parent
Definition: ASTDiff.cpp:191
StringRef P
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)
BumpVector< const VarDecl * > DeclVec
llvm::DenseMap< const void *, std::unique_ptr< ManagedAnalysis > > ManagedAnalysisMap
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
#define SM(sm)
Definition: Cuda.cpp:82
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
llvm::DenseSet< const void * > Visited
Definition: HTMLLogger.cpp:146
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the LambdaCapture class.
bool ShowColors
Definition: Logger.cpp:29
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
__device__ __2f16 float __ockl_bool s
__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:182
SourceManager & getSourceManager()
Definition: ASTContext.h:705
const LangOptions & getLangOpts() const
Definition: ASTContext.h:775
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, 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 BlockInvocationContext * getBlockInvocationContext(const LocationContext *ParentLC, const BlockDecl *BD, const void *Data)
Obtain a context of the block invocation using its parent context.
const CFGBlock * getBlockForRegisteredExpression(const Stmt *stmt)
const Decl * getDecl() const
static bool isInStdNamespace(const Decl *D)
CFGReverseBlockReachabilityAnalysis * getCFGReachablityAnalysis()
const ImplicitParamDecl * getSelfDecl() const
const StackFrameContext * getStackFrame(LocationContext const *ParentLC, const Stmt *S, const CFGBlock *Blk, unsigned BlockCount, unsigned Index)
Obtain a context of the call stack using its parent context.
ASTContext & getASTContext() const
llvm::iterator_range< referenced_decls_iterator > getReferencedBlockVars(const BlockDecl *BD)
AnalysisDeclContext(AnalysisDeclContextManager *Mgr, const Decl *D)
CFG::BuildOptions & getCFGBuildOptions()
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4474
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:4553
ArrayRef< Capture > captures() const
Definition: Decl.h:4601
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6173
const BlockDecl * getBlockDecl() const
Definition: Expr.h:6185
It represents a block invocation (based on BlockCall).
void Profile(llvm::FoldingSetNodeID &ID) override
Stmt * getBody(const FunctionDecl *D)
Factory method for creating bodies for ordinary functions.
Definition: BodyFarm.cpp:700
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:604
static CFGStmtMap * Build(CFG *C, ParentMap *PM)
Returns a new CFGMap for the given CFG.
Definition: CFGStmtMap.cpp:78
bool PruneTriviallyFalseEdges
Definition: CFG.h:1230
bool AddStaticInitBranches
Definition: CFG.h:1238
ForcedBlkExprs ** forcedBlkExprs
Definition: CFG.h:1228
CFGCallback * Observer
Definition: CFG.h:1229
bool AddRichCXXConstructors
Definition: CFG.h:1242
bool AddVirtualBaseBranches
Definition: CFG.h:1244
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
Definition: CFG.h:1226
bool MarkElidedCXXConstructors
Definition: CFG.h:1243
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition: CFG.h:1214
llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator
Definition: CFG.h:1362
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:5236
synthetic_stmt_iterator synthetic_stmt_end() const
Definition: CFG.h:1375
void dump(const LangOptions &LO, bool ShowColors) const
dump - A simple pretty printer of a CFG that outputs to stderr.
Definition: CFG.cpp:6103
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
Definition: CFG.h:1370
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:1021
capture_const_range captures() const
Definition: DeclCXX.h:1100
CodeInjector is an interface which is responsible for injecting AST of function definitions that may ...
Definition: CodeInjector.h:35
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1445
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2075
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
Definition: DeclBase.cpp:1943
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1260
ValueDecl * getDecl()
Definition: Expr.h:1328
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:85
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:501
SourceLocation getLocation() const
Definition: DeclBase.h:444
DeclContext * getDeclContext()
Definition: DeclBase.h:453
This represents one expression.
Definition: Expr.h:110
Represents a function declaration or definition.
Definition: Decl.h:1971
const StackFrameContext * getStackFrame(AnalysisDeclContext *ADC, const LocationContext *ParentLC, const Stmt *S, const CFGBlock *Block, unsigned BlockCount, unsigned Index)
Obtain a context of the call stack using its parent context.
void clear()
Discard all previously created LocationContext objects.
const BlockInvocationContext * getBlockInvocationContext(AnalysisDeclContext *ADC, const LocationContext *ParentLC, const BlockDecl *BD, const void *Data)
Obtain a context of the block invocation using its parent context.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
bool isParentOf(const LocationContext *LC) const
const Decl * getDecl() const
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.
LLVM_DUMP_METHOD void dumpStack(raw_ostream &Out) const
Prints out the call stack.
LLVM_DUMP_METHOD void dump() const
const StackFrameContext * getStackFrame() 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:276
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.
Definition: ParentMap.cpp:129
Stmt * getParent(Stmt *) const
Definition: ParentMap.cpp:136
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
bool isValid() const
unsigned getLine() const
Return the presumed line number of this location.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6305
semantics_iterator semantics_end()
Definition: Expr.h:6377
semantics_iterator semantics_begin()
Definition: Expr.h:6371
Expr *const * semantics_iterator
Definition: Expr.h:6369
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).
void Profile(llvm::FoldingSetNodeID &ID) override
bool inTopFrame() const override
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:185
Stmt - This represents one statement.
Definition: Stmt.h:84
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:338
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:706
Represents a variable declaration or definition.
Definition: Decl.h:918
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
The JSON file list parser is used to communicate input to InstallAPI.
void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc, const SourceManager &SM, bool AddBraces=true)
Definition: JsonSupport.h:82
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned TerseOutput
Provide a 'terse' output.