clang API Documentation
00001 //== AnalysisDeclContext.cpp - Analysis context for Path Sens analysis -*- C++ -*-// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines AnalysisDeclContext, a class that manages the analysis context 00011 // data for path sensitive analysis. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "clang/Analysis/AnalysisContext.h" 00016 #include "BodyFarm.h" 00017 #include "clang/AST/ASTContext.h" 00018 #include "clang/AST/Decl.h" 00019 #include "clang/AST/DeclObjC.h" 00020 #include "clang/AST/DeclTemplate.h" 00021 #include "clang/AST/ParentMap.h" 00022 #include "clang/AST/StmtVisitor.h" 00023 #include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h" 00024 #include "clang/Analysis/Analyses/LiveVariables.h" 00025 #include "clang/Analysis/Analyses/PseudoConstantAnalysis.h" 00026 #include "clang/Analysis/CFG.h" 00027 #include "clang/Analysis/CFGStmtMap.h" 00028 #include "clang/Analysis/Support/BumpVector.h" 00029 #include "llvm/ADT/SmallPtrSet.h" 00030 #include "llvm/Support/ErrorHandling.h" 00031 #include "llvm/Support/SaveAndRestore.h" 00032 #include "llvm/Support/raw_ostream.h" 00033 00034 using namespace clang; 00035 00036 typedef llvm::DenseMap<const void *, ManagedAnalysis *> ManagedAnalysisMap; 00037 00038 AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr, 00039 const Decl *d, 00040 const CFG::BuildOptions &buildOptions) 00041 : Manager(Mgr), 00042 D(d), 00043 cfgBuildOptions(buildOptions), 00044 forcedBlkExprs(nullptr), 00045 builtCFG(false), 00046 builtCompleteCFG(false), 00047 ReferencedBlockVars(nullptr), 00048 ManagedAnalyses(nullptr) 00049 { 00050 cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs; 00051 } 00052 00053 AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr, 00054 const Decl *d) 00055 : Manager(Mgr), 00056 D(d), 00057 forcedBlkExprs(nullptr), 00058 builtCFG(false), 00059 builtCompleteCFG(false), 00060 ReferencedBlockVars(nullptr), 00061 ManagedAnalyses(nullptr) 00062 { 00063 cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs; 00064 } 00065 00066 AnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG, 00067 bool addImplicitDtors, 00068 bool addInitializers, 00069 bool addTemporaryDtors, 00070 bool synthesizeBodies, 00071 bool addStaticInitBranch, 00072 bool addCXXNewAllocator, 00073 CodeInjector *injector) 00074 : Injector(injector), SynthesizeBodies(synthesizeBodies) 00075 { 00076 cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG; 00077 cfgBuildOptions.AddImplicitDtors = addImplicitDtors; 00078 cfgBuildOptions.AddInitializers = addInitializers; 00079 cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors; 00080 cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch; 00081 cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator; 00082 } 00083 00084 void AnalysisDeclContextManager::clear() { 00085 llvm::DeleteContainerSeconds(Contexts); 00086 } 00087 00088 static BodyFarm &getBodyFarm(ASTContext &C, CodeInjector *injector = nullptr) { 00089 static BodyFarm *BF = new BodyFarm(C, injector); 00090 return *BF; 00091 } 00092 00093 Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const { 00094 IsAutosynthesized = false; 00095 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 00096 Stmt *Body = FD->getBody(); 00097 if (!Body && Manager && Manager->synthesizeBodies()) { 00098 Body = getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(FD); 00099 if (Body) 00100 IsAutosynthesized = true; 00101 } 00102 return Body; 00103 } 00104 else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { 00105 Stmt *Body = MD->getBody(); 00106 if (!Body && Manager && Manager->synthesizeBodies()) { 00107 Body = getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(MD); 00108 if (Body) 00109 IsAutosynthesized = true; 00110 } 00111 return Body; 00112 } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) 00113 return BD->getBody(); 00114 else if (const FunctionTemplateDecl *FunTmpl 00115 = dyn_cast_or_null<FunctionTemplateDecl>(D)) 00116 return FunTmpl->getTemplatedDecl()->getBody(); 00117 00118 llvm_unreachable("unknown code decl"); 00119 } 00120 00121 Stmt *AnalysisDeclContext::getBody() const { 00122 bool Tmp; 00123 return getBody(Tmp); 00124 } 00125 00126 bool AnalysisDeclContext::isBodyAutosynthesized() const { 00127 bool Tmp; 00128 getBody(Tmp); 00129 return Tmp; 00130 } 00131 00132 bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const { 00133 bool Tmp; 00134 Stmt *Body = getBody(Tmp); 00135 return Tmp && Body->getLocStart().isValid(); 00136 } 00137 00138 00139 const ImplicitParamDecl *AnalysisDeclContext::getSelfDecl() const { 00140 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) 00141 return MD->getSelfDecl(); 00142 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) { 00143 // See if 'self' was captured by the block. 00144 for (const auto &I : BD->captures()) { 00145 const VarDecl *VD = I.getVariable(); 00146 if (VD->getName() == "self") 00147 return dyn_cast<ImplicitParamDecl>(VD); 00148 } 00149 } 00150 00151 return nullptr; 00152 } 00153 00154 void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) { 00155 if (!forcedBlkExprs) 00156 forcedBlkExprs = new CFG::BuildOptions::ForcedBlkExprs(); 00157 // Default construct an entry for 'stmt'. 00158 if (const Expr *e = dyn_cast<Expr>(stmt)) 00159 stmt = e->IgnoreParens(); 00160 (void) (*forcedBlkExprs)[stmt]; 00161 } 00162 00163 const CFGBlock * 00164 AnalysisDeclContext::getBlockForRegisteredExpression(const Stmt *stmt) { 00165 assert(forcedBlkExprs); 00166 if (const Expr *e = dyn_cast<Expr>(stmt)) 00167 stmt = e->IgnoreParens(); 00168 CFG::BuildOptions::ForcedBlkExprs::const_iterator itr = 00169 forcedBlkExprs->find(stmt); 00170 assert(itr != forcedBlkExprs->end()); 00171 return itr->second; 00172 } 00173 00174 /// Add each synthetic statement in the CFG to the parent map, using the 00175 /// source statement's parent. 00176 static void addParentsForSyntheticStmts(const CFG *TheCFG, ParentMap &PM) { 00177 if (!TheCFG) 00178 return; 00179 00180 for (CFG::synthetic_stmt_iterator I = TheCFG->synthetic_stmt_begin(), 00181 E = TheCFG->synthetic_stmt_end(); 00182 I != E; ++I) { 00183 PM.setParent(I->first, PM.getParent(I->second)); 00184 } 00185 } 00186 00187 CFG *AnalysisDeclContext::getCFG() { 00188 if (!cfgBuildOptions.PruneTriviallyFalseEdges) 00189 return getUnoptimizedCFG(); 00190 00191 if (!builtCFG) { 00192 cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions); 00193 // Even when the cfg is not successfully built, we don't 00194 // want to try building it again. 00195 builtCFG = true; 00196 00197 if (PM) 00198 addParentsForSyntheticStmts(cfg.get(), *PM); 00199 00200 // The Observer should only observe one build of the CFG. 00201 getCFGBuildOptions().Observer = nullptr; 00202 } 00203 return cfg.get(); 00204 } 00205 00206 CFG *AnalysisDeclContext::getUnoptimizedCFG() { 00207 if (!builtCompleteCFG) { 00208 SaveAndRestore<bool> NotPrune(cfgBuildOptions.PruneTriviallyFalseEdges, 00209 false); 00210 completeCFG = 00211 CFG::buildCFG(D, getBody(), &D->getASTContext(), cfgBuildOptions); 00212 // Even when the cfg is not successfully built, we don't 00213 // want to try building it again. 00214 builtCompleteCFG = true; 00215 00216 if (PM) 00217 addParentsForSyntheticStmts(completeCFG.get(), *PM); 00218 00219 // The Observer should only observe one build of the CFG. 00220 getCFGBuildOptions().Observer = nullptr; 00221 } 00222 return completeCFG.get(); 00223 } 00224 00225 CFGStmtMap *AnalysisDeclContext::getCFGStmtMap() { 00226 if (cfgStmtMap) 00227 return cfgStmtMap.get(); 00228 00229 if (CFG *c = getCFG()) { 00230 cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap())); 00231 return cfgStmtMap.get(); 00232 } 00233 00234 return nullptr; 00235 } 00236 00237 CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() { 00238 if (CFA) 00239 return CFA.get(); 00240 00241 if (CFG *c = getCFG()) { 00242 CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c)); 00243 return CFA.get(); 00244 } 00245 00246 return nullptr; 00247 } 00248 00249 void AnalysisDeclContext::dumpCFG(bool ShowColors) { 00250 getCFG()->dump(getASTContext().getLangOpts(), ShowColors); 00251 } 00252 00253 ParentMap &AnalysisDeclContext::getParentMap() { 00254 if (!PM) { 00255 PM.reset(new ParentMap(getBody())); 00256 if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(getDecl())) { 00257 for (const auto *I : C->inits()) { 00258 PM->addStmt(I->getInit()); 00259 } 00260 } 00261 if (builtCFG) 00262 addParentsForSyntheticStmts(getCFG(), *PM); 00263 if (builtCompleteCFG) 00264 addParentsForSyntheticStmts(getUnoptimizedCFG(), *PM); 00265 } 00266 return *PM; 00267 } 00268 00269 PseudoConstantAnalysis *AnalysisDeclContext::getPseudoConstantAnalysis() { 00270 if (!PCA) 00271 PCA.reset(new PseudoConstantAnalysis(getBody())); 00272 return PCA.get(); 00273 } 00274 00275 AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) { 00276 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 00277 // Calling 'hasBody' replaces 'FD' in place with the FunctionDecl 00278 // that has the body. 00279 FD->hasBody(FD); 00280 D = FD; 00281 } 00282 00283 AnalysisDeclContext *&AC = Contexts[D]; 00284 if (!AC) 00285 AC = new AnalysisDeclContext(this, D, cfgBuildOptions); 00286 return AC; 00287 } 00288 00289 const StackFrameContext * 00290 AnalysisDeclContext::getStackFrame(LocationContext const *Parent, const Stmt *S, 00291 const CFGBlock *Blk, unsigned Idx) { 00292 return getLocationContextManager().getStackFrame(this, Parent, S, Blk, Idx); 00293 } 00294 00295 const BlockInvocationContext * 00296 AnalysisDeclContext::getBlockInvocationContext(const LocationContext *parent, 00297 const clang::BlockDecl *BD, 00298 const void *ContextData) { 00299 return getLocationContextManager().getBlockInvocationContext(this, parent, 00300 BD, ContextData); 00301 } 00302 00303 LocationContextManager & AnalysisDeclContext::getLocationContextManager() { 00304 assert(Manager && 00305 "Cannot create LocationContexts without an AnalysisDeclContextManager!"); 00306 return Manager->getLocationContextManager(); 00307 } 00308 00309 //===----------------------------------------------------------------------===// 00310 // FoldingSet profiling. 00311 //===----------------------------------------------------------------------===// 00312 00313 void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID, 00314 ContextKind ck, 00315 AnalysisDeclContext *ctx, 00316 const LocationContext *parent, 00317 const void *data) { 00318 ID.AddInteger(ck); 00319 ID.AddPointer(ctx); 00320 ID.AddPointer(parent); 00321 ID.AddPointer(data); 00322 } 00323 00324 void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) { 00325 Profile(ID, getAnalysisDeclContext(), getParent(), CallSite, Block, Index); 00326 } 00327 00328 void ScopeContext::Profile(llvm::FoldingSetNodeID &ID) { 00329 Profile(ID, getAnalysisDeclContext(), getParent(), Enter); 00330 } 00331 00332 void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) { 00333 Profile(ID, getAnalysisDeclContext(), getParent(), BD, ContextData); 00334 } 00335 00336 //===----------------------------------------------------------------------===// 00337 // LocationContext creation. 00338 //===----------------------------------------------------------------------===// 00339 00340 template <typename LOC, typename DATA> 00341 const LOC* 00342 LocationContextManager::getLocationContext(AnalysisDeclContext *ctx, 00343 const LocationContext *parent, 00344 const DATA *d) { 00345 llvm::FoldingSetNodeID ID; 00346 LOC::Profile(ID, ctx, parent, d); 00347 void *InsertPos; 00348 00349 LOC *L = cast_or_null<LOC>(Contexts.FindNodeOrInsertPos(ID, InsertPos)); 00350 00351 if (!L) { 00352 L = new LOC(ctx, parent, d); 00353 Contexts.InsertNode(L, InsertPos); 00354 } 00355 return L; 00356 } 00357 00358 const StackFrameContext* 00359 LocationContextManager::getStackFrame(AnalysisDeclContext *ctx, 00360 const LocationContext *parent, 00361 const Stmt *s, 00362 const CFGBlock *blk, unsigned idx) { 00363 llvm::FoldingSetNodeID ID; 00364 StackFrameContext::Profile(ID, ctx, parent, s, blk, idx); 00365 void *InsertPos; 00366 StackFrameContext *L = 00367 cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos)); 00368 if (!L) { 00369 L = new StackFrameContext(ctx, parent, s, blk, idx); 00370 Contexts.InsertNode(L, InsertPos); 00371 } 00372 return L; 00373 } 00374 00375 const ScopeContext * 00376 LocationContextManager::getScope(AnalysisDeclContext *ctx, 00377 const LocationContext *parent, 00378 const Stmt *s) { 00379 return getLocationContext<ScopeContext, Stmt>(ctx, parent, s); 00380 } 00381 00382 const BlockInvocationContext * 00383 LocationContextManager::getBlockInvocationContext(AnalysisDeclContext *ctx, 00384 const LocationContext *parent, 00385 const BlockDecl *BD, 00386 const void *ContextData) { 00387 llvm::FoldingSetNodeID ID; 00388 BlockInvocationContext::Profile(ID, ctx, parent, BD, ContextData); 00389 void *InsertPos; 00390 BlockInvocationContext *L = 00391 cast_or_null<BlockInvocationContext>(Contexts.FindNodeOrInsertPos(ID, 00392 InsertPos)); 00393 if (!L) { 00394 L = new BlockInvocationContext(ctx, parent, BD, ContextData); 00395 Contexts.InsertNode(L, InsertPos); 00396 } 00397 return L; 00398 } 00399 00400 //===----------------------------------------------------------------------===// 00401 // LocationContext methods. 00402 //===----------------------------------------------------------------------===// 00403 00404 const StackFrameContext *LocationContext::getCurrentStackFrame() const { 00405 const LocationContext *LC = this; 00406 while (LC) { 00407 if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) 00408 return SFC; 00409 LC = LC->getParent(); 00410 } 00411 return nullptr; 00412 } 00413 00414 bool LocationContext::inTopFrame() const { 00415 return getCurrentStackFrame()->inTopFrame(); 00416 } 00417 00418 bool LocationContext::isParentOf(const LocationContext *LC) const { 00419 do { 00420 const LocationContext *Parent = LC->getParent(); 00421 if (Parent == this) 00422 return true; 00423 else 00424 LC = Parent; 00425 } while (LC); 00426 00427 return false; 00428 } 00429 00430 void LocationContext::dumpStack(raw_ostream &OS, StringRef Indent) const { 00431 ASTContext &Ctx = getAnalysisDeclContext()->getASTContext(); 00432 PrintingPolicy PP(Ctx.getLangOpts()); 00433 PP.TerseOutput = 1; 00434 00435 unsigned Frame = 0; 00436 for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) { 00437 switch (LCtx->getKind()) { 00438 case StackFrame: 00439 OS << Indent << '#' << Frame++ << ' '; 00440 cast<StackFrameContext>(LCtx)->getDecl()->print(OS, PP); 00441 OS << '\n'; 00442 break; 00443 case Scope: 00444 OS << Indent << " (scope)\n"; 00445 break; 00446 case Block: 00447 OS << Indent << " (block context: " 00448 << cast<BlockInvocationContext>(LCtx)->getContextData() 00449 << ")\n"; 00450 break; 00451 } 00452 } 00453 } 00454 00455 LLVM_DUMP_METHOD void LocationContext::dumpStack() const { 00456 dumpStack(llvm::errs()); 00457 } 00458 00459 //===----------------------------------------------------------------------===// 00460 // Lazily generated map to query the external variables referenced by a Block. 00461 //===----------------------------------------------------------------------===// 00462 00463 namespace { 00464 class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{ 00465 BumpVector<const VarDecl*> &BEVals; 00466 BumpVectorContext &BC; 00467 llvm::SmallPtrSet<const VarDecl*, 4> Visited; 00468 llvm::SmallPtrSet<const DeclContext*, 4> IgnoredContexts; 00469 public: 00470 FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals, 00471 BumpVectorContext &bc) 00472 : BEVals(bevals), BC(bc) {} 00473 00474 void VisitStmt(Stmt *S) { 00475 for (Stmt::child_range I = S->children(); I; ++I) 00476 if (Stmt *child = *I) 00477 Visit(child); 00478 } 00479 00480 void VisitDeclRefExpr(DeclRefExpr *DR) { 00481 // Non-local variables are also directly modified. 00482 if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) { 00483 if (!VD->hasLocalStorage()) { 00484 if (Visited.insert(VD)) 00485 BEVals.push_back(VD, BC); 00486 } 00487 } 00488 } 00489 00490 void VisitBlockExpr(BlockExpr *BR) { 00491 // Blocks containing blocks can transitively capture more variables. 00492 IgnoredContexts.insert(BR->getBlockDecl()); 00493 Visit(BR->getBlockDecl()->getBody()); 00494 } 00495 00496 void VisitPseudoObjectExpr(PseudoObjectExpr *PE) { 00497 for (PseudoObjectExpr::semantics_iterator it = PE->semantics_begin(), 00498 et = PE->semantics_end(); it != et; ++it) { 00499 Expr *Semantic = *it; 00500 if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Semantic)) 00501 Semantic = OVE->getSourceExpr(); 00502 Visit(Semantic); 00503 } 00504 } 00505 }; 00506 } // end anonymous namespace 00507 00508 typedef BumpVector<const VarDecl*> DeclVec; 00509 00510 static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD, 00511 void *&Vec, 00512 llvm::BumpPtrAllocator &A) { 00513 if (Vec) 00514 return (DeclVec*) Vec; 00515 00516 BumpVectorContext BC(A); 00517 DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>(); 00518 new (BV) DeclVec(BC, 10); 00519 00520 // Go through the capture list. 00521 for (const auto &CI : BD->captures()) { 00522 BV->push_back(CI.getVariable(), BC); 00523 } 00524 00525 // Find the referenced global/static variables. 00526 FindBlockDeclRefExprsVals F(*BV, BC); 00527 F.Visit(BD->getBody()); 00528 00529 Vec = BV; 00530 return BV; 00531 } 00532 00533 std::pair<AnalysisDeclContext::referenced_decls_iterator, 00534 AnalysisDeclContext::referenced_decls_iterator> 00535 AnalysisDeclContext::getReferencedBlockVars(const BlockDecl *BD) { 00536 if (!ReferencedBlockVars) 00537 ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>(); 00538 00539 DeclVec *V = LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A); 00540 return std::make_pair(V->begin(), V->end()); 00541 } 00542 00543 ManagedAnalysis *&AnalysisDeclContext::getAnalysisImpl(const void *tag) { 00544 if (!ManagedAnalyses) 00545 ManagedAnalyses = new ManagedAnalysisMap(); 00546 ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses; 00547 return (*M)[tag]; 00548 } 00549 00550 //===----------------------------------------------------------------------===// 00551 // Cleanup. 00552 //===----------------------------------------------------------------------===// 00553 00554 ManagedAnalysis::~ManagedAnalysis() {} 00555 00556 AnalysisDeclContext::~AnalysisDeclContext() { 00557 delete forcedBlkExprs; 00558 delete ReferencedBlockVars; 00559 // Release the managed analyses. 00560 if (ManagedAnalyses) { 00561 ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses; 00562 llvm::DeleteContainerSeconds(*M); 00563 delete M; 00564 } 00565 } 00566 00567 AnalysisDeclContextManager::~AnalysisDeclContextManager() { 00568 llvm::DeleteContainerSeconds(Contexts); 00569 } 00570 00571 LocationContext::~LocationContext() {} 00572 00573 LocationContextManager::~LocationContextManager() { 00574 clear(); 00575 } 00576 00577 void LocationContextManager::clear() { 00578 for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(), 00579 E = Contexts.end(); I != E; ) { 00580 LocationContext *LC = &*I; 00581 ++I; 00582 delete LC; 00583 } 00584 00585 Contexts.clear(); 00586 } 00587