]> granicus.if.org Git - clang/commitdiff
Allow BlockInvocationContext to wrap either a BlockDecl* or a BlockDataRegion*, givin...
authorTed Kremenek <kremenek@apple.com>
Fri, 4 Dec 2009 02:03:51 +0000 (02:03 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 4 Dec 2009 02:03:51 +0000 (02:03 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90516 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/AnalysisContext.h
include/clang/Analysis/PathSensitive/MemRegion.h
lib/Analysis/AnalysisContext.cpp

index 9d3221d1f153be167a29c6ada17ad107cbac88f7..08b7f094a9a5e86170b70b3e00c9ad2c5fc70b9a 100644 (file)
 #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<const BlockDataRegion *, const BlockDecl *> 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<const BlockDataRegion*>() ? 
+      Data.get<const BlockDataRegion*>() : 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();
index 8b13b9069e7999298292c6209ab2cff27c06d0ab..05aacd1e0c7047ac3b421525d194d921e30c96bc 100644 (file)
@@ -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:
index e28b74dff57b30960b6baff7db796e57a00a6248..e903c805974e5456c1ae375ed8d69b586b726130 100644 (file)
@@ -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<const BlockDataRegion*>() ?
+    Data.get<const BlockDataRegion*>()->getDecl()
+  : Data.get<const BlockDecl*>();
+}
+
 //===----------------------------------------------------------------------===//
 // 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<const BlockDecl*>());    
 }
 
 //===----------------------------------------------------------------------===//
@@ -146,8 +157,10 @@ LocationContextManager::getScope(AnalysisContext *ctx,
 const BlockInvocationContext *
 LocationContextManager::getBlockInvocation(AnalysisContext *ctx,
                                  const LocationContext *parent,
-                                 const BlockDecl *BD) {
-  return getLocationContext<BlockInvocationContext, BlockDecl>(ctx, parent, BD);
+                                 const BlockDataRegion *BR) {
+  return getLocationContext<BlockInvocationContext, BlockDataRegion>(ctx,
+                                                                     parent,
+                                                                     BR);
 }
 
 //===----------------------------------------------------------------------===//