From d02e83a548359df978f40cc1a52ffd78b7ef371b Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 4 Dec 2009 02:03:51 +0000 Subject: [PATCH] Allow BlockInvocationContext to wrap either a BlockDecl* or a BlockDataRegion*, giving us choice in our degree of context-sensitivity. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90516 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Analysis/PathSensitive/AnalysisContext.h | 27 +++++++++++++++---- .../clang/Analysis/PathSensitive/MemRegion.h | 2 ++ lib/Analysis/AnalysisContext.cpp | 19 ++++++++++--- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/PathSensitive/AnalysisContext.h index 9d3221d1f1..08b7f094a9 100644 --- a/include/clang/Analysis/PathSensitive/AnalysisContext.h +++ b/include/clang/Analysis/PathSensitive/AnalysisContext.h @@ -15,9 +15,10 @@ #ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H #define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H -#include "clang/AST/Stmt.h" +#include "clang/AST/Decl.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Allocator.h" @@ -30,6 +31,7 @@ class LiveVariables; class ParentMap; class ImplicitParamDecl; class LocationContextManager; +class BlockDataRegion; /// AnalysisContext contains the context data for the function or method under /// analysis. @@ -177,20 +179,35 @@ public: }; class BlockInvocationContext : public LocationContext { - const BlockDecl *BD; + llvm::PointerUnion Data; friend class LocationContextManager; + + BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent, + const BlockDataRegion *br) + : LocationContext(Block, ctx, parent), Data(br) {} + BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent, const BlockDecl *bd) - : LocationContext(Block, ctx, parent), BD(bd) {} + : LocationContext(Block, ctx, parent), Data(bd) {} public: ~BlockInvocationContext() {} - const BlockDecl *getBlockDecl() const { return BD; } + const BlockDataRegion *getBlockRegion() const { + return Data.is() ? + Data.get() : 0; + } + + const BlockDecl *getBlockDecl() const; void Profile(llvm::FoldingSetNodeID &ID); + static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, + const LocationContext *parent, const BlockDataRegion *br){ + ProfileCommon(ID, Block, ctx, parent, br); + } + static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx, const LocationContext *parent, const BlockDecl *bd) { ProfileCommon(ID, Block, ctx, parent, bd); @@ -216,7 +233,7 @@ public: const BlockInvocationContext * getBlockInvocation(AnalysisContext *ctx, const LocationContext *parent, - const BlockDecl *BD); + const BlockDataRegion *BR); /// Discard all previously created LocationContext objects. void clear(); diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h index 8b13b9069e..05aacd1e0c 100644 --- a/include/clang/Analysis/PathSensitive/MemRegion.h +++ b/include/clang/Analysis/PathSensitive/MemRegion.h @@ -340,6 +340,8 @@ public: const BlockTextRegion *getCodeRegion() const { return BC; } + const BlockDecl *getDecl() const { return BC->getDecl(); } + class referenced_vars_iterator { const MemRegion * const *R; public: diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp index e28b74dff5..e903c80597 100644 --- a/lib/Analysis/AnalysisContext.cpp +++ b/lib/Analysis/AnalysisContext.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/PathSensitive/AnalysisContext.h" +#include "clang/Analysis/PathSensitive/MemRegion.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/Analysis/CFG.h" #include "clang/AST/Decl.h" @@ -80,6 +81,12 @@ AnalysisContext *AnalysisContextManager::getContext(const Decl *D) { return AC; } +const BlockDecl *BlockInvocationContext::getBlockDecl() const { + return Data.is() ? + Data.get()->getDecl() + : Data.get(); +} + //===----------------------------------------------------------------------===// // FoldingSet profiling. //===----------------------------------------------------------------------===// @@ -104,7 +111,11 @@ void ScopeContext::Profile(llvm::FoldingSetNodeID &ID) { } void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getAnalysisContext(), getParent(), BD); + if (const BlockDataRegion *BR = getBlockRegion()) + Profile(ID, getAnalysisContext(), getParent(), BR); + else + Profile(ID, getAnalysisContext(), getParent(), + Data.get()); } //===----------------------------------------------------------------------===// @@ -146,8 +157,10 @@ LocationContextManager::getScope(AnalysisContext *ctx, const BlockInvocationContext * LocationContextManager::getBlockInvocation(AnalysisContext *ctx, const LocationContext *parent, - const BlockDecl *BD) { - return getLocationContext(ctx, parent, BD); + const BlockDataRegion *BR) { + return getLocationContext(ctx, + parent, + BR); } //===----------------------------------------------------------------------===//