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"
58 : ADCMgr(ADCMgr),
D(
D), cfgBuildOptions(Options) {
64 : ADCMgr(ADCMgr),
D(
D) {
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,
75 : Injector(injector), FunctionBodyFarm(ASTCtx, injector),
76 SynthesizeBodies(synthesizeBodies) {
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();
101 if (SynthesizedBody) {
102 Body = SynthesizedBody;
103 IsAutosynthesized =
true;
108 else if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
109 Stmt *Body = MD->getBody();
112 if (SynthesizedBody) {
113 Body = SynthesizedBody;
114 IsAutosynthesized =
true;
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();
123 llvm_unreachable(
"unknown code decl");
145 return isa_and_nonnull<ImplicitParamDecl>(VD) && VD->
getName() ==
"self";
149 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D))
150 return MD->getSelfDecl();
151 if (
const auto *BD = dyn_cast<BlockDecl>(D)) {
153 for (
const auto &I : BD->captures()) {
154 const VarDecl *VD = I.getVariable();
156 return dyn_cast<ImplicitParamDecl>(VD);
160 auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
168 for (
const auto &LC : parent->
captures()) {
169 if (!LC.capturesVariable())
174 return dyn_cast<ImplicitParamDecl>(VD);
184 if (
const auto *e = dyn_cast<Expr>(
stmt))
185 stmt = e->IgnoreParens();
186 (void) (*forcedBlkExprs)[
stmt];
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());
233 if (!builtCompleteCFG) {
239 builtCompleteCFG =
true;
247 return completeCFG.get();
252 return cfgStmtMap.get();
256 return cfgStmtMap.get();
281 if (
const auto *
C = dyn_cast<CXXConstructorDecl>(
getDecl())) {
282 for (
const auto *I :
C->inits()) {
283 PM->addStmt(I->getInit());
288 if (builtCompleteCFG)
295 if (
const auto *FD = dyn_cast<FunctionDecl>(
D)) {
302 std::unique_ptr<AnalysisDeclContext> &AC = Contexts[
D];
304 AC = std::make_unique<AnalysisDeclContext>(
this,
D, cfgBuildOptions);
313 unsigned BlockCount,
unsigned Index) {
314 return getLocationContextManager().
getStackFrame(
this, ParentLC, S, Blk,
326 const auto *ND = dyn_cast<NamespaceDecl>(DC);
331 if (!isa<NamespaceDecl>(
Parent))
333 ND = cast<NamespaceDecl>(
Parent);
336 return ND->isStdNamespace();
341 llvm::raw_string_ostream OS(Str);
345 OS << FD->getQualifiedNameAsString();
351 for (
const auto &
P : FD->parameters()) {
352 if (
P != *FD->param_begin())
359 }
else if (isa<BlockDecl>(
D)) {
363 OS <<
"block (line: " <<
Loc.getLine() <<
", col: " <<
Loc.getColumn()
370 OS << (OMD->isInstanceMethod() ?
'-' :
'+') <<
'[';
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();
380 OS << OC->getIdentifier()->getNameStart() <<
'('
381 << OC->getIdentifier()->getNameStart() <<
')';
383 }
else if (
const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
384 OS << OCD->getClassInterface()->getName() <<
'(' << OCD->getName() <<
')';
386 OS <<
' ' << OMD->getSelector().getAsString() <<
']';
395 "Cannot create LocationContexts without an AnalysisDeclContextManager!");
396 return ADCMgr->getLocationContextManager();
410 ID.AddPointer(parent);
429 const CFGBlock *blk,
unsigned blockCount,
unsigned idx) {
430 llvm::FoldingSetNodeID ID;
434 cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
437 Contexts.InsertNode(L, InsertPos);
445 llvm::FoldingSetNodeID ID;
449 cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
453 Contexts.InsertNode(L, InsertPos);
465 if (
const auto *SFC = dyn_cast<StackFrameContext>(LC))
491 Out <<
SM.getExpansionLineNumber(
Loc);
506 switch (LCtx->getKind()) {
508 Out <<
"\t#" << Frame <<
' ';
510 if (
const auto *
D = dyn_cast<NamedDecl>(LCtx->getDecl()))
513 Out <<
"Calling anonymous code";
514 if (
const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
520 Out <<
"Invoking block";
521 if (
const Decl *
D = cast<BlockInvocationContext>(LCtx)->
getDecl()) {
522 Out <<
" defined at line ";
532 unsigned int Space,
bool IsDot,
534 printMoreInfoPerContext)
const {
544 Indent(Out, Space, IsDot)
545 <<
"{ \"lctx_id\": " << LCtx->getID() <<
", \"location_context\": \"";
546 switch (LCtx->getKind()) {
548 Out <<
'#' << Frame <<
" Call\", \"calling\": \"";
550 if (
const auto *
D = dyn_cast<NamedDecl>(LCtx->getDecl()))
551 Out <<
D->getQualifiedNameAsString();
553 Out <<
"anonymous code";
555 Out <<
"\", \"location\": ";
556 if (
const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
562 Out <<
", \"items\": ";
565 Out <<
"Invoking block\" ";
566 if (
const Decl *
D = cast<BlockInvocationContext>(LCtx)->
getDecl()) {
567 Out <<
", \"location\": ";
574 printMoreInfoPerContext(LCtx);
577 if (LCtx->getParent())
591class FindBlockDeclRefExprsVals :
public StmtVisitor<FindBlockDeclRefExprsVals>{
600 : BEVals(bevals), BC(bc) {}
602 void VisitStmt(
Stmt *S) {
603 for (
auto *Child : S->children())
610 if (
const auto *VD = dyn_cast<VarDecl>(DR->
getDecl())) {
611 if (!VD->hasLocalStorage()) {
627 Expr *Semantic = *it;
628 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
629 Semantic = OVE->getSourceExpr();
641 llvm::BumpPtrAllocator &A) {
650 for (
const auto &CI : BD->
captures()) {
655 FindBlockDeclRefExprsVals F(*BV, BC);
662llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
664 if (!ReferencedBlockVars)
665 ReferencedBlockVars =
new llvm::DenseMap<const BlockDecl*,void*>();
669 return llvm::make_range(
V->begin(),
V->end());
672std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(
const void *tag) {
673 if (!ManagedAnalyses)
686 delete forcedBlkExprs;
687 delete ReferencedBlockVars;
698 for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
699 E = Contexts.end(); I !=
E; ) {
Defines the clang::ASTContext interface.
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...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
llvm::DenseSet< const void * > Visited
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the LambdaCapture class.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.