clang 22.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
121 llvm_unreachable("unknown code decl");
122}
123
125 bool Tmp;
126 return getBody(Tmp);
127}
128
130 bool Tmp;
131 getBody(Tmp);
132 return Tmp;
133}
134
136 bool Tmp;
137 Stmt *Body = getBody(Tmp);
138 return Tmp && Body->getBeginLoc().isValid();
139}
140
141/// Returns true if \param VD is an Objective-C implicit 'self' parameter.
142static bool isSelfDecl(const VarDecl *VD) {
143 return isa_and_nonnull<ImplicitParamDecl>(VD) && VD->getName() == "self";
144}
145
147 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
148 return MD->getSelfDecl();
149 if (const auto *BD = dyn_cast<BlockDecl>(D)) {
150 // See if 'self' was captured by the block.
151 for (const auto &I : BD->captures()) {
152 const VarDecl *VD = I.getVariable();
153 if (isSelfDecl(VD))
154 return dyn_cast<ImplicitParamDecl>(VD);
155 }
156 }
157
158 auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
159 if (!CXXMethod)
160 return nullptr;
161
162 const CXXRecordDecl *parent = CXXMethod->getParent();
163 if (!parent->isLambda())
164 return nullptr;
165
166 for (const auto &LC : parent->captures()) {
167 if (!LC.capturesVariable())
168 continue;
169
170 ValueDecl *VD = LC.getCapturedVar();
171 if (isSelfDecl(dyn_cast<VarDecl>(VD)))
172 return dyn_cast<ImplicitParamDecl>(VD);
173 }
174
175 return nullptr;
176}
177
179 if (!forcedBlkExprs)
180 forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
181 // Default construct an entry for 'stmt'.
182 if (const auto *e = dyn_cast<Expr>(stmt))
183 stmt = e->IgnoreParens();
184 (void) (*forcedBlkExprs)[stmt];
185}
186
187const CFGBlock *
189 assert(forcedBlkExprs);
190 if (const auto *e = dyn_cast<Expr>(stmt))
191 stmt = e->IgnoreParens();
192 CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
193 forcedBlkExprs->find(stmt);
194 assert(itr != forcedBlkExprs->end());
195 return itr->second;
196}
197
198/// Add each synthetic statement in the CFG to the parent map, using the
199/// source statement's parent.
200static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
201 if (!TheCFG)
202 return;
203
205 E = TheCFG->synthetic_stmt_end();
206 I != E; ++I) {
207 PM.setParent(I->first, PM.getParent(I->second));
208 }
209}
210
212 if (!cfgBuildOptions.PruneTriviallyFalseEdges)
213 return getUnoptimizedCFG();
214
215 if (!builtCFG) {
216 cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
217 // Even when the cfg is not successfully built, we don't
218 // want to try building it again.
219 builtCFG = true;
220
221 if (PM)
222 addParentsForSyntheticStmts(cfg.get(), *PM);
223
224 // The Observer should only observe one build of the CFG.
225 getCFGBuildOptions().Observer = nullptr;
226 }
227 return cfg.get();
228}
229
231 if (!builtCompleteCFG) {
232 SaveAndRestore NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges, false);
233 completeCFG =
234 CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
235 // Even when the cfg is not successfully built, we don't
236 // want to try building it again.
237 builtCompleteCFG = true;
238
239 if (PM)
240 addParentsForSyntheticStmts(completeCFG.get(), *PM);
241
242 // The Observer should only observe one build of the CFG.
243 getCFGBuildOptions().Observer = nullptr;
244 }
245 return completeCFG.get();
246}
247
249 if (cfgStmtMap)
250 return cfgStmtMap.get();
251
252 if (CFG *c = getCFG()) {
253 cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
254 return cfgStmtMap.get();
255 }
256
257 return nullptr;
258}
259
261 if (CFA)
262 return CFA.get();
263
264 if (CFG *c = getCFG()) {
265 CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
266 return CFA.get();
267 }
268
269 return nullptr;
270}
271
273 getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
274}
275
277 if (!PM) {
278 PM.reset(new ParentMap(getBody()));
279 if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
280 for (const auto *I : C->inits()) {
281 PM->addStmt(I->getInit());
282 }
283 }
284 if (builtCFG)
286 if (builtCompleteCFG)
288 }
289 return *PM;
290}
291
293 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
294 // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
295 // that has the body.
296 FD->hasBody(FD);
297 D = FD;
298 }
299
300 std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
301 if (!AC)
302 AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
303 return AC.get();
304}
305
307
308const StackFrameContext *
310 const Stmt *S, const CFGBlock *Blk,
311 unsigned BlockCount, unsigned Index) {
312 return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,
313 BlockCount, Index);
314}
315
317 const LocationContext *ParentLC, const BlockDecl *BD, const void *Data) {
318 return getLocationContextManager().getBlockInvocationContext(this, ParentLC,
319 BD, Data);
320}
321
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)) {
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
390LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
391 assert(
392 ADCMgr &&
393 "Cannot create LocationContexts without an AnalysisDeclContextManager!");
394 return ADCMgr->getLocationContextManager();
395}
396
397//===----------------------------------------------------------------------===//
398// FoldingSet profiling.
399//===----------------------------------------------------------------------===//
400
401void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
402 ContextKind ck,
404 const LocationContext *parent,
405 const void *data) {
406 ID.AddInteger(ck);
407 ID.AddPointer(ctx);
408 ID.AddPointer(parent);
409 ID.AddPointer(data);
410}
411
412void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
413 Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,
414 BlockCount, Index);
415}
416
417void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
418 Profile(ID, getAnalysisDeclContext(), getParent(), BD, Data);
419}
420
421//===----------------------------------------------------------------------===//
422// LocationContext creation.
423//===----------------------------------------------------------------------===//
424
426 AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,
427 const CFGBlock *blk, unsigned blockCount, unsigned idx) {
428 llvm::FoldingSetNodeID ID;
429 StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);
430 void *InsertPos;
431 auto *L =
432 cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
433 if (!L) {
434 L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);
435 Contexts.InsertNode(L, InsertPos);
436 }
437 return L;
438}
439
441 AnalysisDeclContext *ADC, const LocationContext *ParentLC,
442 const BlockDecl *BD, const void *Data) {
443 llvm::FoldingSetNodeID ID;
444 BlockInvocationContext::Profile(ID, ADC, ParentLC, BD, Data);
445 void *InsertPos;
446 auto *L =
447 cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
448 InsertPos));
449 if (!L) {
450 L = new BlockInvocationContext(ADC, ParentLC, BD, Data, ++NewID);
451 Contexts.InsertNode(L, InsertPos);
452 }
453 return L;
454}
455
456//===----------------------------------------------------------------------===//
457// LocationContext methods.
458//===----------------------------------------------------------------------===//
459
461 const LocationContext *LC = this;
462 while (LC) {
463 if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
464 return SFC;
465 LC = LC->getParent();
466 }
467 return nullptr;
468}
469
471 return getStackFrame()->inTopFrame();
472}
473
475 do {
476 const LocationContext *Parent = LC->getParent();
477 if (Parent == this)
478 return true;
479 else
480 LC = Parent;
481 } while (LC);
482
483 return false;
484}
485
486static void printLocation(raw_ostream &Out, const SourceManager &SM,
488 if (Loc.isFileID() && SM.isInMainFile(Loc))
489 Out << SM.getExpansionLineNumber(Loc);
490 else
491 Loc.print(Out, SM);
492}
493
494void LocationContext::dumpStack(raw_ostream &Out) const {
496 PrintingPolicy PP(Ctx.getLangOpts());
497 PP.TerseOutput = 1;
498
499 const SourceManager &SM =
501
502 unsigned Frame = 0;
503 for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
504 switch (LCtx->getKind()) {
505 case StackFrame:
506 Out << "\t#" << Frame << ' ';
507 ++Frame;
508 if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
509 Out << "Calling " << AnalysisDeclContext::getFunctionName(D);
510 else
511 Out << "Calling anonymous code";
512 if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
513 Out << " at line ";
514 printLocation(Out, SM, S->getBeginLoc());
515 }
516 break;
517 case Block:
518 Out << "Invoking block";
519 if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
520 Out << " defined at line ";
521 printLocation(Out, SM, D->getBeginLoc());
522 }
523 break;
524 }
525 Out << '\n';
526 }
527}
528
529void LocationContext::printJson(raw_ostream &Out, const char *NL,
530 unsigned int Space, bool IsDot,
531 std::function<void(const LocationContext *)>
532 printMoreInfoPerContext) const {
534 PrintingPolicy PP(Ctx.getLangOpts());
535 PP.TerseOutput = 1;
536
537 const SourceManager &SM =
539
540 unsigned Frame = 0;
541 for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
542 Indent(Out, Space, IsDot)
543 << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
544 switch (LCtx->getKind()) {
545 case StackFrame:
546 Out << '#' << Frame << " Call\", \"calling\": \"";
547 ++Frame;
548 if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
549 Out << D->getQualifiedNameAsString();
550 else
551 Out << "anonymous code";
552
553 Out << "\", \"location\": ";
554 if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
555 printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
556 } else {
557 Out << "null";
558 }
559
560 Out << ", \"items\": ";
561 break;
562 case Block:
563 Out << "Invoking block\" ";
564 if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
565 Out << ", \"location\": ";
567 Out << ' ';
568 }
569 break;
570 }
571
572 printMoreInfoPerContext(LCtx);
573
574 Out << '}';
575 if (LCtx->getParent())
576 Out << ',';
577 Out << NL;
578 }
579}
580
581LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); }
582
583//===----------------------------------------------------------------------===//
584// Lazily generated map to query the external variables referenced by a Block.
585//===----------------------------------------------------------------------===//
586
587namespace {
588
589class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
594
595public:
596 FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
598 : BEVals(bevals), BC(bc) {}
599
600 void VisitStmt(Stmt *S) {
601 for (auto *Child : S->children())
602 if (Child)
603 Visit(Child);
604 }
605
606 void VisitDeclRefExpr(DeclRefExpr *DR) {
607 // Non-local variables are also directly modified.
608 if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
609 if (!VD->hasLocalStorage()) {
610 if (Visited.insert(VD).second)
611 BEVals.push_back(VD, BC);
612 }
613 }
614 }
615
616 void VisitBlockExpr(BlockExpr *BR) {
617 // Blocks containing blocks can transitively capture more variables.
618 IgnoredContexts.insert(BR->getBlockDecl());
619 Visit(BR->getBlockDecl()->getBody());
620 }
621
622 void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
624 et = PE->semantics_end(); it != et; ++it) {
625 Expr *Semantic = *it;
626 if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
627 Semantic = OVE->getSourceExpr();
628 Visit(Semantic);
629 }
630 }
631};
632
633} // namespace
634
636
638 void *&Vec,
639 llvm::BumpPtrAllocator &A) {
640 if (Vec)
641 return (DeclVec*) Vec;
642
643 BumpVectorContext BC(A);
644 DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
645 new (BV) DeclVec(BC, 10);
646
647 // Go through the capture list.
648 for (const auto &CI : BD->captures()) {
649 BV->push_back(CI.getVariable(), BC);
650 }
651
652 // Find the referenced global/static variables.
653 FindBlockDeclRefExprsVals F(*BV, BC);
654 F.Visit(BD->getBody());
655
656 Vec = BV;
657 return BV;
658}
659
660llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
662 if (!ReferencedBlockVars)
663 ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
664
665 const DeclVec *V =
666 LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
667 return llvm::make_range(V->begin(), V->end());
668}
669
670std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
671 if (!ManagedAnalyses)
672 ManagedAnalyses = new ManagedAnalysisMap();
673 ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
674 return (*M)[tag];
675}
676
677//===----------------------------------------------------------------------===//
678// Cleanup.
679//===----------------------------------------------------------------------===//
680
682
684 delete forcedBlkExprs;
685 delete ReferencedBlockVars;
686 delete (ManagedAnalysisMap*) ManagedAnalyses;
687}
688
690
692 clear();
693}
694
696 for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
697 E = Contexts.end(); I != E; ) {
698 LocationContext *LC = &*I;
699 ++I;
700 delete LC;
701 }
702 Contexts.clear();
703}
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3597
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...
const Decl * D
Expr * E
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:145
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the LambdaCapture class.
bool ShowColors
Definition: Logger.cpp:29
#define SM(sm)
Definition: OffloadArch.cpp:16
SourceLocation Loc
Definition: SemaObjC.cpp:754
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:188
SourceManager & getSourceManager()
Definition: ASTContext.h:801
const LangOptions & getLangOpts() const
Definition: ASTContext.h:894
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 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:4630
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:4709
ArrayRef< Capture > captures() const
Definition: Decl.h:4757
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6560
const BlockDecl * getBlockDecl() const
Definition: Expr.h:6572
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:605
static CFGStmtMap * Build(CFG *C, ParentMap *PM)
Returns a new CFGMap for the given CFG.
Definition: CFGStmtMap.cpp:78
bool PruneTriviallyFalseEdges
Definition: CFG.h:1238
bool AddStaticInitBranches
Definition: CFG.h:1246
ForcedBlkExprs ** forcedBlkExprs
Definition: CFG.h:1236
CFGCallback * Observer
Definition: CFG.h:1237
bool AddRichCXXConstructors
Definition: CFG.h:1250
bool AddVirtualBaseBranches
Definition: CFG.h:1252
llvm::DenseMap< const Stmt *, const CFGBlock * > ForcedBlkExprs
Definition: CFG.h:1234
bool MarkElidedCXXConstructors
Definition: CFG.h:1251
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition: CFG.h:1222
llvm::DenseMap< const DeclStmt *, const DeclStmt * >::const_iterator synthetic_stmt_iterator
Definition: CFG.h:1370
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:5345
synthetic_stmt_iterator synthetic_stmt_end() const
Definition: CFG.h:1383
void dump(const LangOptions &LO, bool ShowColors) const
dump - A simple pretty printer of a CFG that outputs to stderr.
Definition: CFG.cpp:6218
synthetic_stmt_iterator synthetic_stmt_begin() const
Iterates over synthetic DeclStmts in the CFG.
Definition: CFG.h:1378
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:1449
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2109
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
Definition: DeclBase.cpp:2040
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1272
ValueDecl * getDecl()
Definition: Expr.h:1340
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:524
SourceLocation getLocation() const
Definition: DeclBase.h:439
DeclContext * getDeclContext()
Definition: DeclBase.h:448
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:431
This represents one expression.
Definition: Expr.h:112
Represents a function declaration or definition.
Definition: Decl.h:1999
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:300
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:135
Stmt * getParent(Stmt *) const
Definition: ParentMap.cpp:142
Represents an unpacked "presumed" location which can be presented to the user.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6692
semantics_iterator semantics_end()
Definition: Expr.h:6757
semantics_iterator semantics_begin()
Definition: Expr.h:6753
Expr *const * semantics_iterator
Definition: Expr.h:6751
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:186
Stmt - This represents one statement.
Definition: Stmt.h:85
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:346
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:711
Represents a variable declaration or definition.
Definition: Decl.h:925
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
int const char * function
Definition: c++config.h:31
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned TerseOutput
Provide a 'terse' output.