Home | History | Annotate | Line # | Download | only in Analysis
      1      1.1  joerg //===- AnalysisDeclContext.cpp - Analysis context for Path Sens analysis --===//
      2      1.1  joerg //
      3      1.1  joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4      1.1  joerg // See https://llvm.org/LICENSE.txt for license information.
      5      1.1  joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6      1.1  joerg //
      7      1.1  joerg //===----------------------------------------------------------------------===//
      8      1.1  joerg //
      9      1.1  joerg // This file defines AnalysisDeclContext, a class that manages the analysis
     10      1.1  joerg // context data for path sensitive analysis.
     11      1.1  joerg //
     12      1.1  joerg //===----------------------------------------------------------------------===//
     13      1.1  joerg 
     14      1.1  joerg #include "clang/Analysis/AnalysisDeclContext.h"
     15      1.1  joerg #include "clang/AST/ASTContext.h"
     16      1.1  joerg #include "clang/AST/Decl.h"
     17      1.1  joerg #include "clang/AST/DeclBase.h"
     18      1.1  joerg #include "clang/AST/DeclCXX.h"
     19      1.1  joerg #include "clang/AST/DeclObjC.h"
     20      1.1  joerg #include "clang/AST/DeclTemplate.h"
     21      1.1  joerg #include "clang/AST/Expr.h"
     22      1.1  joerg #include "clang/AST/LambdaCapture.h"
     23      1.1  joerg #include "clang/AST/ParentMap.h"
     24      1.1  joerg #include "clang/AST/PrettyPrinter.h"
     25      1.1  joerg #include "clang/AST/Stmt.h"
     26      1.1  joerg #include "clang/AST/StmtCXX.h"
     27      1.1  joerg #include "clang/AST/StmtVisitor.h"
     28      1.1  joerg #include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
     29      1.1  joerg #include "clang/Analysis/BodyFarm.h"
     30      1.1  joerg #include "clang/Analysis/CFG.h"
     31      1.1  joerg #include "clang/Analysis/CFGStmtMap.h"
     32      1.1  joerg #include "clang/Analysis/Support/BumpVector.h"
     33      1.1  joerg #include "clang/Basic/JsonSupport.h"
     34      1.1  joerg #include "clang/Basic/LLVM.h"
     35      1.1  joerg #include "clang/Basic/SourceLocation.h"
     36      1.1  joerg #include "clang/Basic/SourceManager.h"
     37      1.1  joerg #include "llvm/ADT/DenseMap.h"
     38      1.1  joerg #include "llvm/ADT/FoldingSet.h"
     39      1.1  joerg #include "llvm/ADT/STLExtras.h"
     40      1.1  joerg #include "llvm/ADT/SmallPtrSet.h"
     41      1.1  joerg #include "llvm/ADT/iterator_range.h"
     42      1.1  joerg #include "llvm/Support/Allocator.h"
     43      1.1  joerg #include "llvm/Support/Casting.h"
     44      1.1  joerg #include "llvm/Support/Compiler.h"
     45      1.1  joerg #include "llvm/Support/ErrorHandling.h"
     46      1.1  joerg #include "llvm/Support/SaveAndRestore.h"
     47      1.1  joerg #include "llvm/Support/raw_ostream.h"
     48      1.1  joerg #include <cassert>
     49      1.1  joerg #include <memory>
     50      1.1  joerg 
     51      1.1  joerg using namespace clang;
     52      1.1  joerg 
     53  1.1.1.2  joerg using ManagedAnalysisMap = llvm::DenseMap<const void *, std::unique_ptr<ManagedAnalysis>>;
     54      1.1  joerg 
     55  1.1.1.2  joerg AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
     56  1.1.1.2  joerg                                          const Decl *D,
     57  1.1.1.2  joerg                                          const CFG::BuildOptions &Options)
     58  1.1.1.2  joerg     : ADCMgr(ADCMgr), D(D), cfgBuildOptions(Options) {
     59      1.1  joerg   cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
     60      1.1  joerg }
     61      1.1  joerg 
     62  1.1.1.2  joerg AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *ADCMgr,
     63  1.1.1.2  joerg                                          const Decl *D)
     64  1.1.1.2  joerg     : ADCMgr(ADCMgr), D(D) {
     65      1.1  joerg   cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
     66      1.1  joerg }
     67      1.1  joerg 
     68      1.1  joerg AnalysisDeclContextManager::AnalysisDeclContextManager(
     69      1.1  joerg     ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors,
     70      1.1  joerg     bool addInitializers, bool addTemporaryDtors, bool addLifetime,
     71      1.1  joerg     bool addLoopExit, bool addScopes, bool synthesizeBodies,
     72      1.1  joerg     bool addStaticInitBranch, bool addCXXNewAllocator,
     73      1.1  joerg     bool addRichCXXConstructors, bool markElidedCXXConstructors,
     74      1.1  joerg     bool addVirtualBaseBranches, CodeInjector *injector)
     75      1.1  joerg     : Injector(injector), FunctionBodyFarm(ASTCtx, injector),
     76      1.1  joerg       SynthesizeBodies(synthesizeBodies) {
     77      1.1  joerg   cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
     78      1.1  joerg   cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
     79      1.1  joerg   cfgBuildOptions.AddInitializers = addInitializers;
     80      1.1  joerg   cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
     81      1.1  joerg   cfgBuildOptions.AddLifetime = addLifetime;
     82      1.1  joerg   cfgBuildOptions.AddLoopExit = addLoopExit;
     83      1.1  joerg   cfgBuildOptions.AddScopes = addScopes;
     84      1.1  joerg   cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
     85      1.1  joerg   cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
     86      1.1  joerg   cfgBuildOptions.AddRichCXXConstructors = addRichCXXConstructors;
     87      1.1  joerg   cfgBuildOptions.MarkElidedCXXConstructors = markElidedCXXConstructors;
     88      1.1  joerg   cfgBuildOptions.AddVirtualBaseBranches = addVirtualBaseBranches;
     89      1.1  joerg }
     90      1.1  joerg 
     91      1.1  joerg void AnalysisDeclContextManager::clear() { Contexts.clear(); }
     92      1.1  joerg 
     93      1.1  joerg Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
     94      1.1  joerg   IsAutosynthesized = false;
     95      1.1  joerg   if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
     96      1.1  joerg     Stmt *Body = FD->getBody();
     97      1.1  joerg     if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
     98      1.1  joerg       Body = CoroBody->getBody();
     99  1.1.1.2  joerg     if (ADCMgr && ADCMgr->synthesizeBodies()) {
    100  1.1.1.2  joerg       Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(FD);
    101      1.1  joerg       if (SynthesizedBody) {
    102      1.1  joerg         Body = SynthesizedBody;
    103      1.1  joerg         IsAutosynthesized = true;
    104      1.1  joerg       }
    105      1.1  joerg     }
    106      1.1  joerg     return Body;
    107      1.1  joerg   }
    108      1.1  joerg   else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
    109      1.1  joerg     Stmt *Body = MD->getBody();
    110  1.1.1.2  joerg     if (ADCMgr && ADCMgr->synthesizeBodies()) {
    111  1.1.1.2  joerg       Stmt *SynthesizedBody = ADCMgr->getBodyFarm().getBody(MD);
    112      1.1  joerg       if (SynthesizedBody) {
    113      1.1  joerg         Body = SynthesizedBody;
    114      1.1  joerg         IsAutosynthesized = true;
    115      1.1  joerg       }
    116      1.1  joerg     }
    117      1.1  joerg     return Body;
    118      1.1  joerg   } else if (const auto *BD = dyn_cast<BlockDecl>(D))
    119      1.1  joerg     return BD->getBody();
    120      1.1  joerg   else if (const auto *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(D))
    121      1.1  joerg     return FunTmpl->getTemplatedDecl()->getBody();
    122      1.1  joerg 
    123      1.1  joerg   llvm_unreachable("unknown code decl");
    124      1.1  joerg }
    125      1.1  joerg 
    126      1.1  joerg Stmt *AnalysisDeclContext::getBody() const {
    127      1.1  joerg   bool Tmp;
    128      1.1  joerg   return getBody(Tmp);
    129      1.1  joerg }
    130      1.1  joerg 
    131      1.1  joerg bool AnalysisDeclContext::isBodyAutosynthesized() const {
    132      1.1  joerg   bool Tmp;
    133      1.1  joerg   getBody(Tmp);
    134      1.1  joerg   return Tmp;
    135      1.1  joerg }
    136      1.1  joerg 
    137      1.1  joerg bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const {
    138      1.1  joerg   bool Tmp;
    139      1.1  joerg   Stmt *Body = getBody(Tmp);
    140      1.1  joerg   return Tmp && Body->getBeginLoc().isValid();
    141      1.1  joerg }
    142      1.1  joerg 
    143      1.1  joerg /// Returns true if \param VD is an Objective-C implicit 'self' parameter.
    144      1.1  joerg static bool isSelfDecl(const VarDecl *VD) {
    145      1.1  joerg   return isa<ImplicitParamDecl>(VD) && VD->getName() == "self";
    146      1.1  joerg }
    147      1.1  joerg 
    148      1.1  joerg const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const {
    149      1.1  joerg   if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
    150      1.1  joerg     return MD->getSelfDecl();
    151      1.1  joerg   if (const auto *BD = dyn_cast<BlockDecl>(D)) {
    152      1.1  joerg     // See if 'self' was captured by the block.
    153      1.1  joerg     for (const auto &I : BD->captures()) {
    154      1.1  joerg       const VarDecl *VD = I.getVariable();
    155      1.1  joerg       if (isSelfDecl(VD))
    156      1.1  joerg         return dyn_cast<ImplicitParamDecl>(VD);
    157      1.1  joerg     }
    158      1.1  joerg   }
    159      1.1  joerg 
    160      1.1  joerg   auto *CXXMethod = dyn_cast<CXXMethodDecl>(D);
    161      1.1  joerg   if (!CXXMethod)
    162      1.1  joerg     return nullptr;
    163      1.1  joerg 
    164      1.1  joerg   const CXXRecordDecl *parent = CXXMethod->getParent();
    165      1.1  joerg   if (!parent->isLambda())
    166      1.1  joerg     return nullptr;
    167      1.1  joerg 
    168      1.1  joerg   for (const auto &LC : parent->captures()) {
    169      1.1  joerg     if (!LC.capturesVariable())
    170      1.1  joerg       continue;
    171      1.1  joerg 
    172      1.1  joerg     VarDecl *VD = LC.getCapturedVar();
    173      1.1  joerg     if (isSelfDecl(VD))
    174      1.1  joerg       return dyn_cast<ImplicitParamDecl>(VD);
    175      1.1  joerg   }
    176      1.1  joerg 
    177      1.1  joerg   return nullptr;
    178      1.1  joerg }
    179      1.1  joerg 
    180      1.1  joerg void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
    181      1.1  joerg   if (!forcedBlkExprs)
    182      1.1  joerg     forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs();
    183      1.1  joerg   // Default construct an entry for 'stmt'.
    184      1.1  joerg   if (const auto *e = dyn_cast<Expr>(stmt))
    185      1.1  joerg     stmt = e->IgnoreParens();
    186      1.1  joerg   (void) (*forcedBlkExprs)[stmt];
    187      1.1  joerg }
    188      1.1  joerg 
    189      1.1  joerg const CFGBlock *
    190      1.1  joerg AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) {
    191      1.1  joerg   assert(forcedBlkExprs);
    192      1.1  joerg   if (const auto *e = dyn_cast<Expr>(stmt))
    193      1.1  joerg     stmt = e->IgnoreParens();
    194      1.1  joerg   CFG::BuildOptions::ForcedBlkExprs::const_iterator itr =
    195      1.1  joerg     forcedBlkExprs->find(stmt);
    196      1.1  joerg   assert(itr != forcedBlkExprs->end());
    197      1.1  joerg   return itr->second;
    198      1.1  joerg }
    199      1.1  joerg 
    200      1.1  joerg /// Add each synthetic statement in the CFG to the parent map, using the
    201      1.1  joerg /// source statement's parent.
    202      1.1  joerg static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) {
    203      1.1  joerg   if (!TheCFG)
    204      1.1  joerg     return;
    205      1.1  joerg 
    206      1.1  joerg   for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(),
    207      1.1  joerg                                     E = TheCFG->synthetic_stmt_end();
    208      1.1  joerg        I != E; ++I) {
    209      1.1  joerg     PM.setParent(I->first, PM.getParent(I->second));
    210      1.1  joerg   }
    211      1.1  joerg }
    212      1.1  joerg 
    213      1.1  joerg CFG *AnalysisDeclContext::getCFG() {
    214      1.1  joerg   if (!cfgBuildOptions.PruneTriviallyFalseEdges)
    215      1.1  joerg     return getUnoptimizedCFG();
    216      1.1  joerg 
    217      1.1  joerg   if (!builtCFG) {
    218      1.1  joerg     cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
    219      1.1  joerg     // Even when the cfg is not successfully built, we don't
    220      1.1  joerg     // want to try building it again.
    221      1.1  joerg     builtCFG = true;
    222      1.1  joerg 
    223      1.1  joerg     if (PM)
    224      1.1  joerg       addParentsForSyntheticStmts(cfg.get(), *PM);
    225      1.1  joerg 
    226      1.1  joerg     // The Observer should only observe one build of the CFG.
    227      1.1  joerg     getCFGBuildOptions().Observer = nullptr;
    228      1.1  joerg   }
    229      1.1  joerg   return cfg.get();
    230      1.1  joerg }
    231      1.1  joerg 
    232      1.1  joerg CFG *AnalysisDeclContext::getUnoptimizedCFG() {
    233      1.1  joerg   if (!builtCompleteCFG) {
    234      1.1  joerg     SaveAndRestore<bool> NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges,
    235      1.1  joerg                                   false);
    236      1.1  joerg     completeCFG =
    237      1.1  joerg         CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions);
    238      1.1  joerg     // Even when the cfg is not successfully built, we don't
    239      1.1  joerg     // want to try building it again.
    240      1.1  joerg     builtCompleteCFG = true;
    241      1.1  joerg 
    242      1.1  joerg     if (PM)
    243      1.1  joerg       addParentsForSyntheticStmts(completeCFG.get(), *PM);
    244      1.1  joerg 
    245      1.1  joerg     // The Observer should only observe one build of the CFG.
    246      1.1  joerg     getCFGBuildOptions().Observer = nullptr;
    247      1.1  joerg   }
    248      1.1  joerg   return completeCFG.get();
    249      1.1  joerg }
    250      1.1  joerg 
    251      1.1  joerg CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() {
    252      1.1  joerg   if (cfgStmtMap)
    253      1.1  joerg     return cfgStmtMap.get();
    254      1.1  joerg 
    255      1.1  joerg   if (CFG *c = getCFG()) {
    256      1.1  joerg     cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
    257      1.1  joerg     return cfgStmtMap.get();
    258      1.1  joerg   }
    259      1.1  joerg 
    260      1.1  joerg   return nullptr;
    261      1.1  joerg }
    262      1.1  joerg 
    263      1.1  joerg CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
    264      1.1  joerg   if (CFA)
    265      1.1  joerg     return CFA.get();
    266      1.1  joerg 
    267      1.1  joerg   if (CFG *c = getCFG()) {
    268      1.1  joerg     CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
    269      1.1  joerg     return CFA.get();
    270      1.1  joerg   }
    271      1.1  joerg 
    272      1.1  joerg   return nullptr;
    273      1.1  joerg }
    274      1.1  joerg 
    275      1.1  joerg void AnalysisDeclContext::dumpCFG(bool ShowColors) {
    276      1.1  joerg   getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
    277      1.1  joerg }
    278      1.1  joerg 
    279      1.1  joerg ParentMap &AnalysisDeclContext::getParentMap() {
    280      1.1  joerg   if (!PM) {
    281      1.1  joerg     PM.reset(new ParentMap(getBody()));
    282      1.1  joerg     if (const auto *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
    283      1.1  joerg       for (const auto *I : C->inits()) {
    284      1.1  joerg         PM->addStmt(I->getInit());
    285      1.1  joerg       }
    286      1.1  joerg     }
    287      1.1  joerg     if (builtCFG)
    288      1.1  joerg       addParentsForSyntheticStmts(getCFG(), *PM);
    289      1.1  joerg     if (builtCompleteCFG)
    290      1.1  joerg       addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM);
    291      1.1  joerg   }
    292      1.1  joerg   return *PM;
    293      1.1  joerg }
    294      1.1  joerg 
    295      1.1  joerg AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
    296      1.1  joerg   if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
    297      1.1  joerg     // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl
    298      1.1  joerg     // that has the body.
    299      1.1  joerg     FD->hasBody(FD);
    300      1.1  joerg     D = FD;
    301      1.1  joerg   }
    302      1.1  joerg 
    303      1.1  joerg   std::unique_ptr<AnalysisDeclContext> &AC = Contexts[D];
    304      1.1  joerg   if (!AC)
    305      1.1  joerg     AC = std::make_unique<AnalysisDeclContext>(this, D, cfgBuildOptions);
    306      1.1  joerg   return AC.get();
    307      1.1  joerg }
    308      1.1  joerg 
    309      1.1  joerg BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; }
    310      1.1  joerg 
    311      1.1  joerg const StackFrameContext *
    312  1.1.1.2  joerg AnalysisDeclContext::getStackFrame(const LocationContext *ParentLC,
    313  1.1.1.2  joerg                                    const Stmt *S, const CFGBlock *Blk,
    314  1.1.1.2  joerg                                    unsigned BlockCount, unsigned Index) {
    315  1.1.1.2  joerg   return getLocationContextManager().getStackFrame(this, ParentLC, S, Blk,
    316  1.1.1.2  joerg                                                    BlockCount, Index);
    317      1.1  joerg }
    318      1.1  joerg 
    319  1.1.1.2  joerg const BlockInvocationContext *AnalysisDeclContext::getBlockInvocationContext(
    320  1.1.1.2  joerg     const LocationContext *ParentLC, const BlockDecl *BD, const void *Data) {
    321  1.1.1.2  joerg   return getLocationContextManager().getBlockInvocationContext(this, ParentLC,
    322  1.1.1.2  joerg                                                                BD, Data);
    323      1.1  joerg }
    324      1.1  joerg 
    325      1.1  joerg bool AnalysisDeclContext::isInStdNamespace(const Decl *D) {
    326      1.1  joerg   const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
    327      1.1  joerg   const auto *ND = dyn_cast<NamespaceDecl>(DC);
    328      1.1  joerg   if (!ND)
    329      1.1  joerg     return false;
    330      1.1  joerg 
    331      1.1  joerg   while (const DeclContext *Parent = ND->getParent()) {
    332      1.1  joerg     if (!isa<NamespaceDecl>(Parent))
    333      1.1  joerg       break;
    334      1.1  joerg     ND = cast<NamespaceDecl>(Parent);
    335      1.1  joerg   }
    336      1.1  joerg 
    337      1.1  joerg   return ND->isStdNamespace();
    338      1.1  joerg }
    339      1.1  joerg 
    340      1.1  joerg LocationContextManager &AnalysisDeclContext::getLocationContextManager() {
    341  1.1.1.2  joerg   assert(
    342  1.1.1.2  joerg       ADCMgr &&
    343  1.1.1.2  joerg       "Cannot create LocationContexts without an AnalysisDeclContextManager!");
    344  1.1.1.2  joerg   return ADCMgr->getLocationContextManager();
    345      1.1  joerg }
    346      1.1  joerg 
    347      1.1  joerg //===----------------------------------------------------------------------===//
    348      1.1  joerg // FoldingSet profiling.
    349      1.1  joerg //===----------------------------------------------------------------------===//
    350      1.1  joerg 
    351      1.1  joerg void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
    352      1.1  joerg                                     ContextKind ck,
    353      1.1  joerg                                     AnalysisDeclContext *ctx,
    354      1.1  joerg                                     const LocationContext *parent,
    355      1.1  joerg                                     const void *data) {
    356      1.1  joerg   ID.AddInteger(ck);
    357      1.1  joerg   ID.AddPointer(ctx);
    358      1.1  joerg   ID.AddPointer(parent);
    359      1.1  joerg   ID.AddPointer(data);
    360      1.1  joerg }
    361      1.1  joerg 
    362      1.1  joerg void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
    363      1.1  joerg   Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block,
    364      1.1  joerg           BlockCount, Index);
    365      1.1  joerg }
    366      1.1  joerg 
    367      1.1  joerg void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
    368  1.1.1.2  joerg   Profile(ID, getAnalysisDeclContext(), getParent(), BD, Data);
    369      1.1  joerg }
    370      1.1  joerg 
    371      1.1  joerg //===----------------------------------------------------------------------===//
    372      1.1  joerg // LocationContext creation.
    373      1.1  joerg //===----------------------------------------------------------------------===//
    374      1.1  joerg 
    375      1.1  joerg const StackFrameContext *LocationContextManager::getStackFrame(
    376      1.1  joerg     AnalysisDeclContext *ctx, const LocationContext *parent, const Stmt *s,
    377      1.1  joerg     const CFGBlock *blk, unsigned blockCount, unsigned idx) {
    378      1.1  joerg   llvm::FoldingSetNodeID ID;
    379      1.1  joerg   StackFrameContext::Profile(ID, ctx, parent, s, blk, blockCount, idx);
    380      1.1  joerg   void *InsertPos;
    381      1.1  joerg   auto *L =
    382      1.1  joerg    cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
    383      1.1  joerg   if (!L) {
    384      1.1  joerg     L = new StackFrameContext(ctx, parent, s, blk, blockCount, idx, ++NewID);
    385      1.1  joerg     Contexts.InsertNode(L, InsertPos);
    386      1.1  joerg   }
    387      1.1  joerg   return L;
    388      1.1  joerg }
    389      1.1  joerg 
    390  1.1.1.2  joerg const BlockInvocationContext *LocationContextManager::getBlockInvocationContext(
    391  1.1.1.2  joerg     AnalysisDeclContext *ADC, const LocationContext *ParentLC,
    392  1.1.1.2  joerg     const BlockDecl *BD, const void *Data) {
    393      1.1  joerg   llvm::FoldingSetNodeID ID;
    394  1.1.1.2  joerg   BlockInvocationContext::Profile(ID, ADC, ParentLC, BD, Data);
    395      1.1  joerg   void *InsertPos;
    396      1.1  joerg   auto *L =
    397      1.1  joerg     cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID,
    398      1.1  joerg                                                                     InsertPos));
    399      1.1  joerg   if (!L) {
    400  1.1.1.2  joerg     L = new BlockInvocationContext(ADC, ParentLC, BD, Data, ++NewID);
    401      1.1  joerg     Contexts.InsertNode(L, InsertPos);
    402      1.1  joerg   }
    403      1.1  joerg   return L;
    404      1.1  joerg }
    405      1.1  joerg 
    406      1.1  joerg //===----------------------------------------------------------------------===//
    407      1.1  joerg // LocationContext methods.
    408      1.1  joerg //===----------------------------------------------------------------------===//
    409      1.1  joerg 
    410      1.1  joerg const StackFrameContext *LocationContext::getStackFrame() const {
    411      1.1  joerg   const LocationContext *LC = this;
    412      1.1  joerg   while (LC) {
    413      1.1  joerg     if (const auto *SFC = dyn_cast<StackFrameContext>(LC))
    414      1.1  joerg       return SFC;
    415      1.1  joerg     LC = LC->getParent();
    416      1.1  joerg   }
    417      1.1  joerg   return nullptr;
    418      1.1  joerg }
    419      1.1  joerg 
    420      1.1  joerg bool LocationContext::inTopFrame() const {
    421      1.1  joerg   return getStackFrame()->inTopFrame();
    422      1.1  joerg }
    423      1.1  joerg 
    424      1.1  joerg bool LocationContext::isParentOf(const LocationContext *LC) const {
    425      1.1  joerg   do {
    426      1.1  joerg     const LocationContext *Parent = LC->getParent();
    427      1.1  joerg     if (Parent == this)
    428      1.1  joerg       return true;
    429      1.1  joerg     else
    430      1.1  joerg       LC = Parent;
    431      1.1  joerg   } while (LC);
    432      1.1  joerg 
    433      1.1  joerg   return false;
    434      1.1  joerg }
    435      1.1  joerg 
    436      1.1  joerg static void printLocation(raw_ostream &Out, const SourceManager &SM,
    437      1.1  joerg                           SourceLocation Loc) {
    438      1.1  joerg   if (Loc.isFileID() && SM.isInMainFile(Loc))
    439      1.1  joerg     Out << SM.getExpansionLineNumber(Loc);
    440      1.1  joerg   else
    441      1.1  joerg     Loc.print(Out, SM);
    442      1.1  joerg }
    443      1.1  joerg 
    444  1.1.1.2  joerg void LocationContext::dumpStack(raw_ostream &Out) const {
    445      1.1  joerg   ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
    446      1.1  joerg   PrintingPolicy PP(Ctx.getLangOpts());
    447      1.1  joerg   PP.TerseOutput = 1;
    448      1.1  joerg 
    449      1.1  joerg   const SourceManager &SM =
    450      1.1  joerg       getAnalysisDeclContext()->getASTContext().getSourceManager();
    451      1.1  joerg 
    452      1.1  joerg   unsigned Frame = 0;
    453      1.1  joerg   for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
    454      1.1  joerg     switch (LCtx->getKind()) {
    455      1.1  joerg     case StackFrame:
    456      1.1  joerg       Out << "\t#" << Frame << ' ';
    457      1.1  joerg       ++Frame;
    458      1.1  joerg       if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
    459      1.1  joerg         Out << "Calling " << D->getQualifiedNameAsString();
    460      1.1  joerg       else
    461      1.1  joerg         Out << "Calling anonymous code";
    462      1.1  joerg       if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
    463      1.1  joerg         Out << " at line ";
    464      1.1  joerg         printLocation(Out, SM, S->getBeginLoc());
    465      1.1  joerg       }
    466      1.1  joerg       break;
    467      1.1  joerg     case Block:
    468      1.1  joerg       Out << "Invoking block";
    469      1.1  joerg       if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
    470      1.1  joerg         Out << " defined at line ";
    471      1.1  joerg         printLocation(Out, SM, D->getBeginLoc());
    472      1.1  joerg       }
    473      1.1  joerg       break;
    474      1.1  joerg     }
    475  1.1.1.2  joerg     Out << '\n';
    476      1.1  joerg   }
    477      1.1  joerg }
    478      1.1  joerg 
    479      1.1  joerg void LocationContext::printJson(raw_ostream &Out, const char *NL,
    480      1.1  joerg                                 unsigned int Space, bool IsDot,
    481      1.1  joerg                                 std::function<void(const LocationContext *)>
    482      1.1  joerg                                     printMoreInfoPerContext) const {
    483      1.1  joerg   ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
    484      1.1  joerg   PrintingPolicy PP(Ctx.getLangOpts());
    485      1.1  joerg   PP.TerseOutput = 1;
    486      1.1  joerg 
    487      1.1  joerg   const SourceManager &SM =
    488      1.1  joerg       getAnalysisDeclContext()->getASTContext().getSourceManager();
    489      1.1  joerg 
    490      1.1  joerg   unsigned Frame = 0;
    491      1.1  joerg   for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
    492      1.1  joerg     Indent(Out, Space, IsDot)
    493      1.1  joerg         << "{ \"lctx_id\": " << LCtx->getID() << ", \"location_context\": \"";
    494      1.1  joerg     switch (LCtx->getKind()) {
    495      1.1  joerg     case StackFrame:
    496      1.1  joerg       Out << '#' << Frame << " Call\", \"calling\": \"";
    497      1.1  joerg       ++Frame;
    498      1.1  joerg       if (const auto *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
    499      1.1  joerg         Out << D->getQualifiedNameAsString();
    500      1.1  joerg       else
    501      1.1  joerg         Out << "anonymous code";
    502      1.1  joerg 
    503      1.1  joerg       Out << "\", \"location\": ";
    504      1.1  joerg       if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
    505      1.1  joerg         printSourceLocationAsJson(Out, S->getBeginLoc(), SM);
    506      1.1  joerg       } else {
    507      1.1  joerg         Out << "null";
    508      1.1  joerg       }
    509      1.1  joerg 
    510      1.1  joerg       Out << ", \"items\": ";
    511      1.1  joerg       break;
    512      1.1  joerg     case Block:
    513      1.1  joerg       Out << "Invoking block\" ";
    514      1.1  joerg       if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
    515      1.1  joerg         Out << ", \"location\": ";
    516      1.1  joerg         printSourceLocationAsJson(Out, D->getBeginLoc(), SM);
    517      1.1  joerg         Out << ' ';
    518      1.1  joerg       }
    519      1.1  joerg       break;
    520      1.1  joerg     }
    521      1.1  joerg 
    522      1.1  joerg     printMoreInfoPerContext(LCtx);
    523      1.1  joerg 
    524      1.1  joerg     Out << '}';
    525      1.1  joerg     if (LCtx->getParent())
    526      1.1  joerg       Out << ',';
    527      1.1  joerg     Out << NL;
    528      1.1  joerg   }
    529      1.1  joerg }
    530      1.1  joerg 
    531      1.1  joerg LLVM_DUMP_METHOD void LocationContext::dump() const { printJson(llvm::errs()); }
    532      1.1  joerg 
    533      1.1  joerg //===----------------------------------------------------------------------===//
    534      1.1  joerg // Lazily generated map to query the external variables referenced by a Block.
    535      1.1  joerg //===----------------------------------------------------------------------===//
    536      1.1  joerg 
    537      1.1  joerg namespace {
    538      1.1  joerg 
    539      1.1  joerg class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
    540      1.1  joerg   BumpVector<const VarDecl *> &BEVals;
    541      1.1  joerg   BumpVectorContext &BC;
    542      1.1  joerg   llvm::SmallPtrSet<const VarDecl *, 4> Visited;
    543      1.1  joerg   llvm::SmallPtrSet<const DeclContext *, 4> IgnoredContexts;
    544      1.1  joerg 
    545      1.1  joerg public:
    546      1.1  joerg   FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
    547      1.1  joerg                             BumpVectorContext &bc)
    548      1.1  joerg       : BEVals(bevals), BC(bc) {}
    549      1.1  joerg 
    550      1.1  joerg   void VisitStmt(Stmt *S) {
    551      1.1  joerg     for (auto *Child : S->children())
    552      1.1  joerg       if (Child)
    553      1.1  joerg         Visit(Child);
    554      1.1  joerg   }
    555      1.1  joerg 
    556      1.1  joerg   void VisitDeclRefExpr(DeclRefExpr *DR) {
    557      1.1  joerg     // Non-local variables are also directly modified.
    558      1.1  joerg     if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
    559      1.1  joerg       if (!VD->hasLocalStorage()) {
    560      1.1  joerg         if (Visited.insert(VD).second)
    561      1.1  joerg           BEVals.push_back(VD, BC);
    562      1.1  joerg       }
    563      1.1  joerg     }
    564      1.1  joerg   }
    565      1.1  joerg 
    566      1.1  joerg   void VisitBlockExpr(BlockExpr *BR) {
    567      1.1  joerg     // Blocks containing blocks can transitively capture more variables.
    568      1.1  joerg     IgnoredContexts.insert(BR->getBlockDecl());
    569      1.1  joerg     Visit(BR->getBlockDecl()->getBody());
    570      1.1  joerg   }
    571      1.1  joerg 
    572      1.1  joerg   void VisitPseudoObjectExpr(PseudoObjectExpr *PE) {
    573      1.1  joerg     for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(),
    574      1.1  joerg          et = PE->semantics_end(); it != et; ++it) {
    575      1.1  joerg       Expr *Semantic = *it;
    576      1.1  joerg       if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantic))
    577      1.1  joerg         Semantic = OVE->getSourceExpr();
    578      1.1  joerg       Visit(Semantic);
    579      1.1  joerg     }
    580      1.1  joerg   }
    581      1.1  joerg };
    582      1.1  joerg 
    583      1.1  joerg } // namespace
    584      1.1  joerg 
    585      1.1  joerg using DeclVec = BumpVector<const VarDecl *>;
    586      1.1  joerg 
    587      1.1  joerg static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,
    588      1.1  joerg                                               void *&Vec,
    589      1.1  joerg                                               llvm::BumpPtrAllocator &A) {
    590      1.1  joerg   if (Vec)
    591      1.1  joerg     return (DeclVec*) Vec;
    592      1.1  joerg 
    593      1.1  joerg   BumpVectorContext BC(A);
    594      1.1  joerg   DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
    595      1.1  joerg   new (BV) DeclVec(BC, 10);
    596      1.1  joerg 
    597      1.1  joerg   // Go through the capture list.
    598      1.1  joerg   for (const auto &CI : BD->captures()) {
    599      1.1  joerg     BV->push_back(CI.getVariable(), BC);
    600      1.1  joerg   }
    601      1.1  joerg 
    602      1.1  joerg   // Find the referenced global/static variables.
    603      1.1  joerg   FindBlockDeclRefExprsVals F(*BV, BC);
    604      1.1  joerg   F.Visit(BD->getBody());
    605      1.1  joerg 
    606      1.1  joerg   Vec = BV;
    607      1.1  joerg   return BV;
    608      1.1  joerg }
    609      1.1  joerg 
    610      1.1  joerg llvm::iterator_range<AnalysisDeclContext::referenced_decls_iterator>
    611      1.1  joerg AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) {
    612      1.1  joerg   if (!ReferencedBlockVars)
    613      1.1  joerg     ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
    614      1.1  joerg 
    615      1.1  joerg   const DeclVec *V =
    616      1.1  joerg       LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
    617      1.1  joerg   return llvm::make_range(V->begin(), V->end());
    618      1.1  joerg }
    619      1.1  joerg 
    620  1.1.1.2  joerg std::unique_ptr<ManagedAnalysis> &AnalysisDeclContext::getAnalysisImpl(const void *tag) {
    621      1.1  joerg   if (!ManagedAnalyses)
    622      1.1  joerg     ManagedAnalyses = new ManagedAnalysisMap();
    623      1.1  joerg   ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
    624      1.1  joerg   return (*M)[tag];
    625      1.1  joerg }
    626      1.1  joerg 
    627      1.1  joerg //===----------------------------------------------------------------------===//
    628      1.1  joerg // Cleanup.
    629      1.1  joerg //===----------------------------------------------------------------------===//
    630      1.1  joerg 
    631      1.1  joerg ManagedAnalysis::~ManagedAnalysis() = default;
    632      1.1  joerg 
    633      1.1  joerg AnalysisDeclContext::~AnalysisDeclContext() {
    634      1.1  joerg   delete forcedBlkExprs;
    635      1.1  joerg   delete ReferencedBlockVars;
    636  1.1.1.2  joerg   delete (ManagedAnalysisMap*) ManagedAnalyses;
    637      1.1  joerg }
    638      1.1  joerg 
    639      1.1  joerg LocationContext::~LocationContext() = default;
    640      1.1  joerg 
    641      1.1  joerg LocationContextManager::~LocationContextManager() {
    642      1.1  joerg   clear();
    643      1.1  joerg }
    644      1.1  joerg 
    645      1.1  joerg void LocationContextManager::clear() {
    646      1.1  joerg   for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
    647      1.1  joerg        E = Contexts.end(); I != E; ) {
    648      1.1  joerg     LocationContext *LC = &*I;
    649      1.1  joerg     ++I;
    650      1.1  joerg     delete LC;
    651      1.1  joerg   }
    652      1.1  joerg   Contexts.clear();
    653      1.1  joerg }
    654