[cfe-commits] r48272 - in /cfe/trunk: Analysis/CFRefCount.cpp Analysis/GRSimpleVals.cpp Analysis/GRSimpleVals.h Analysis/SymbolManager.cpp include/clang/Analysis/PathSensitive/GRCoreEngine.h include/clang/Analysis/PathSensitive/GRExprEngine.h include/clang/Analysis/PathSensitive/GRTransferFuncs.h include/clang/Analysis/PathSensitive/SymbolManager.h include/clang/Analysis/PathSensitive/ValueState.h

Ted Kremenek kremenek at apple.com
Tue Mar 11 18:21:45 PDT 2008


Author: kremenek
Date: Tue Mar 11 20:21:45 2008
New Revision: 48272

URL: http://llvm.org/viewvc/llvm-project?rev=48272&view=rev
Log:
Prototype (pre-alpha) implementation of CFRef checker.

Modified:
    cfe/trunk/Analysis/CFRefCount.cpp
    cfe/trunk/Analysis/GRSimpleVals.cpp
    cfe/trunk/Analysis/GRSimpleVals.h
    cfe/trunk/Analysis/SymbolManager.cpp
    cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
    cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h
    cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h

Modified: cfe/trunk/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/CFRefCount.cpp?rev=48272&r1=48271&r2=48272&view=diff

==============================================================================
--- cfe/trunk/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/Analysis/CFRefCount.cpp Tue Mar 11 20:21:45 2008
@@ -86,6 +86,10 @@
     return (*Args)[idx];
   }
   
+  RetEffect getRet() const {
+    return Ret;
+  }
+  
   typedef ArgEffects::const_iterator arg_iterator;
   
   arg_iterator begin_args() const { return Args->begin(); }
@@ -113,12 +117,24 @@
   llvm::BumpPtrAllocator BPAlloc;
   
   ArgEffects             ScratchArgs;
+  
+  
+  ArgEffects*   getArgEffects();
 
+  CFRefSummary* getCannedCFSummary(FunctionTypeProto* FT, bool isRetain);
+
+  CFRefSummary* getCFSummary(FunctionDecl* FD, const char* FName);
+  
+  CFRefSummary* getCFSummaryCreateRule(FunctionTypeProto* FT);
+  CFRefSummary* getCFSummaryGetRule(FunctionTypeProto* FT);  
+  
+  CFRefSummary* getPersistentSummary(ArgEffects* AE, RetEffect RE);
+  
 public:
   CFRefSummaryManager() {}
   ~CFRefSummaryManager();
   
-  CFRefSummary* getSummary(FunctionDecl* FD);
+  CFRefSummary* getSummary(FunctionDecl* FD, ASTContext& Ctx);
 };
   
 } // end anonymous namespace
@@ -137,7 +153,59 @@
     I->getValue().~ArgEffects();
 }
 
-CFRefSummary* CFRefSummaryManager::getSummary(FunctionDecl* FD) {
+ArgEffects* CFRefSummaryManager::getArgEffects() {
+
+  assert (!ScratchArgs.empty());
+  
+  llvm::FoldingSetNodeID profile;
+  profile.Add(ScratchArgs);
+  void* InsertPos;
+  
+  llvm::FoldingSetNodeWrapper<ArgEffects>* E =
+    AESet.FindNodeOrInsertPos(profile, InsertPos);
+  
+  if (E) {    
+    ScratchArgs.clear();
+    return &E->getValue();
+  }
+  
+  E = (llvm::FoldingSetNodeWrapper<ArgEffects>*)
+      BPAlloc.Allocate<llvm::FoldingSetNodeWrapper<ArgEffects> >();
+                       
+  new (E) llvm::FoldingSetNodeWrapper<ArgEffects>(ScratchArgs);
+  AESet.InsertNode(E, InsertPos);
+
+  ScratchArgs.clear();
+  return &E->getValue();
+}
+
+CFRefSummary* CFRefSummaryManager::getPersistentSummary(ArgEffects* AE,
+                                                        RetEffect RE) {
+  
+  llvm::FoldingSetNodeID profile;
+  CFRefSummary::Profile(profile, AE, RE);
+  void* InsertPos;
+  
+  CFRefSummary* Summ = SummarySet.FindNodeOrInsertPos(profile, InsertPos);
+  
+  if (Summ)
+    return Summ;
+  
+  Summ = (CFRefSummary*) BPAlloc.Allocate<CFRefSummary>();
+  new (Summ) CFRefSummary(AE, RE);
+  SummarySet.InsertNode(Summ, InsertPos);
+  
+  return Summ;
+}
+
+
+CFRefSummary* CFRefSummaryManager::getSummary(FunctionDecl* FD,
+                                              ASTContext& Ctx) {
+
+  SourceLocation Loc = FD->getLocation();
+  
+  if (!Loc.isFileID())
+    return NULL;
   
   { // Look into our cache of summaries to see if we have already computed
     // a summary for this FunctionDecl.
@@ -148,12 +216,169 @@
       return I->second;
   }
   
-  //
-  
+#if 0
+  SourceManager& SrcMgr = Ctx.getSourceManager();
+  unsigned fid = Loc.getFileID();
+  const FileEntry* FE = SrcMgr.getFileEntryForID(fid);
+  
+  if (!FE)
+    return NULL;
+  
+  const char* DirName = FE->getDir()->getName();  
+  assert (DirName);
+  assert (strlen(DirName) > 0);
+  
+  if (!strstr(DirName, "CoreFoundation")) {
+    SummaryMap[FD] = NULL;
+    return NULL;
+  }
+#endif
+  
+  const char* FName = FD->getIdentifier()->getName();
+    
+  if (FName[0] == 'C' && FName[1] == 'F') {
+    CFRefSummary* S = getCFSummary(FD, FName);
+    SummaryMap[FD] = S;
+    return S;
+  }
   
   return NULL;  
 }
 
+CFRefSummary* CFRefSummaryManager::getCFSummary(FunctionDecl* FD,
+                                                const char* FName) {
+  
+  // For now, only generate summaries for functions that have a prototype.
+  
+  FunctionTypeProto* FT =
+    dyn_cast<FunctionTypeProto>(FD->getType().getTypePtr());
+  
+  if (!FT)
+    return NULL;
+  
+  FName += 2;
+
+  if (strcmp(FName, "Retain") == 0)
+    return getCannedCFSummary(FT, true);
+  
+  if (strcmp(FName, "Release") == 0)
+    return getCannedCFSummary(FT, false);
+  
+  assert (ScratchArgs.empty());
+  bool usesCreateRule = false;
+  
+  if (strstr(FName, "Create"))
+    usesCreateRule = true;
+  
+  if (!usesCreateRule && strstr(FName, "Copy"))
+    usesCreateRule = true;
+  
+  if (usesCreateRule)
+    return getCFSummaryCreateRule(FT);
+
+  if (strstr(FName, "Get"))
+    return getCFSummaryGetRule(FT);
+  
+  return NULL;
+}
+
+CFRefSummary* CFRefSummaryManager::getCannedCFSummary(FunctionTypeProto* FT,
+                                                      bool isRetain) {
+  
+  if (FT->getNumArgs() != 1)
+    return NULL;
+  
+  TypedefType* ArgT = dyn_cast<TypedefType>(FT->getArgType(0).getTypePtr());
+  
+  if (!ArgT)
+    return NULL;
+  
+  // For CFRetain/CFRelease, the first (and only) argument is of type 
+  // "CFTypeRef".
+  
+  const char* TDName = ArgT->getDecl()->getIdentifier()->getName();
+  assert (TDName);
+  
+  if (strcmp("CFTypeRef", TDName) == 0)
+    return NULL;
+  
+  if (!ArgT->isPointerType())
+    return NULL;
+  
+  // Check the return type.  It should also be "CFTypeRef".
+  
+  QualType RetTy = FT->getResultType();
+  
+  if (RetTy.getTypePtr() != ArgT)
+    return NULL;
+  
+  // The function's interface checks out.  Generate a canned summary.
+  
+  assert (ScratchArgs.empty());
+  ScratchArgs.push_back(isRetain ? IncRef : DecRef);
+  
+  return getPersistentSummary(getArgEffects(), RetEffect::MakeAlias(0));
+}
+
+static bool isCFRefType(QualType T) {
+  
+  if (!T->isPointerType())
+    return false;
+  
+  // Check the typedef for the name "CF" and the substring "Ref".
+  
+  TypedefType* TD = dyn_cast<TypedefType>(T.getTypePtr());
+  
+  if (!TD)
+    return false;
+  
+  const char* TDName = TD->getDecl()->getIdentifier()->getName();
+  assert (TDName);
+  
+  if (TDName[0] != 'C' || TDName[1] != 'F')
+    return false;
+  
+  if (strstr(TDName, "Ref") == 0)
+    return false;
+  
+  return true;
+}
+  
+
+CFRefSummary*
+CFRefSummaryManager::getCFSummaryCreateRule(FunctionTypeProto* FT) {
+ 
+  if (!isCFRefType(FT->getResultType()))
+    return NULL;
+
+  assert (ScratchArgs.empty());
+  
+  // FIXME: Add special-cases for functions that retain/release.  For now
+  //  just handle the default case.
+  
+  for (unsigned i = 0, n = FT->getNumArgs(); i != n; ++i)
+    ScratchArgs.push_back(DoNothing);
+  
+  return getPersistentSummary(getArgEffects(), RetEffect::MakeOwned());
+}
+
+CFRefSummary*
+CFRefSummaryManager::getCFSummaryGetRule(FunctionTypeProto* FT) {
+  
+  if (!isCFRefType(FT->getResultType()))
+    return NULL;
+  
+  assert (ScratchArgs.empty());
+  
+  // FIXME: Add special-cases for functions that retain/release.  For now
+  //  just handle the default case.
+  
+  for (unsigned i = 0, n = FT->getNumArgs(); i != n; ++i)
+    ScratchArgs.push_back(DoNothing);
+  
+  return getPersistentSummary(getArgEffects(), RetEffect::MakeNotOwned());
+}
+
 //===----------------------------------------------------------------------===//
 // Transfer functions.
 //===----------------------------------------------------------------------===//
@@ -246,8 +471,8 @@
   // Instance variables.
   
   CFRefSummaryManager Summaries;
-  RefBFactoryTy  RefBFactory;
-  
+  RefBFactoryTy       RefBFactory;
+     
   UseAfterReleasesTy UseAfterReleases;
   ReleasesNotOwnedTy ReleasesNotOwned;
   
@@ -282,9 +507,8 @@
   // Calls.
   
   virtual void EvalCall(ExplodedNodeSet<ValueState>& Dst,
-                        ValueStateManager& StateMgr,
+                        GRExprEngine& Engine,
                         GRStmtNodeBuilder<ValueState>& Builder,
-                        BasicValueFactory& BasicVals,
                         CallExpr* CE, LVal L,
                         ExplodedNode<ValueState>* Pred);  
 };
@@ -307,11 +531,12 @@
 }
 
 void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
-                            ValueStateManager& StateMgr,
-                            GRStmtNodeBuilder<ValueState>& Builder,
-                            BasicValueFactory& BasicVals,
-                            CallExpr* CE, LVal L,
-                            ExplodedNode<ValueState>* Pred) {
+                          GRExprEngine& Engine,
+                          GRStmtNodeBuilder<ValueState>& Builder,
+                          CallExpr* CE, LVal L,
+                          ExplodedNode<ValueState>* Pred) {
+  
+  ValueStateManager& StateMgr = Engine.getStateManager();
   
   // FIXME: Support calls to things other than lval::FuncVal.  At the very
   //  least we should stop tracking ref-state for ref-counted objects passed
@@ -323,7 +548,7 @@
 
   lval::FuncVal FV = cast<lval::FuncVal>(L);
   FunctionDecl* FD = FV.getDecl();
-  CFRefSummary* Summ = Summaries.getSummary(FD);
+  CFRefSummary* Summ = Summaries.getSummary(FD, Engine.getContext());
 
   // Get the state.
   
@@ -355,35 +580,36 @@
             
       if (isa<LVal>(V))
         StateMgr.Unbind(StVals, cast<LVal>(V));
-    }    
-  }
-  else {
+    }
     
-    // This function has a summary.  Evaluate the effect of the arguments.
+    St = StateMgr.getPersistentState(StVals);
+    Builder.Nodify(Dst, CE, Pred, St);
+    return;
+  }
+  
+  // This function has a summary.  Evaluate the effect of the arguments.
+  
+  unsigned idx = 0;
+  
+  for (CallExpr::arg_iterator I=CE->arg_begin(), E=CE->arg_end();
+        I!=E; ++I, ++idx) {
     
-    unsigned idx = 0;
+    RVal V = StateMgr.GetRVal(St, *I);
     
-    for (CallExpr::arg_iterator I=CE->arg_begin(), E=CE->arg_end();
-          I!=E; ++I, ++idx) {
-      
-      RVal V = StateMgr.GetRVal(St, *I);
-      
-      if (isa<lval::SymbolVal>(V)) {
-        SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
-        RefBindings B = GetRefBindings(StVals);
+    if (isa<lval::SymbolVal>(V)) {
+      SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
+      RefBindings B = GetRefBindings(StVals);
 
-        if (RefBindings::TreeTy* T = B.SlimFind(Sym)) {
-          B = Update(B, Sym, T->getValue().second, Summ->getArg(idx), hasError);
-          SetRefBindings(StVals, B);
-          if (hasError) break;
-        }
+      if (RefBindings::TreeTy* T = B.SlimFind(Sym)) {
+        B = Update(B, Sym, T->getValue().second, Summ->getArg(idx), hasError);
+        SetRefBindings(StVals, B);
+        if (hasError) break;
       }
-    }    
-  }
-  
-  St = StateMgr.getPersistentState(StVals);
-  
+    }
+  }    
+    
   if (hasError) {
+    St = StateMgr.getPersistentState(StVals);
     GRExprEngine::NodeTy* N = Builder.generateNode(CE, St, Pred);
 
     if (N) {
@@ -399,10 +625,61 @@
           ReleasesNotOwned.insert(N);
           break;
       }
-    }    
+    }
+    
+    return;
   }
-  else
-    Builder.Nodify(Dst, CE, Pred, St);
+
+  // Finally, consult the summary for the return value.
+  
+  RetEffect RE = Summ->getRet();
+  St = StateMgr.getPersistentState(StVals);
+
+  
+  switch (RE.getKind()) {
+    default:
+      assert (false && "Unhandled RetEffect."); break;
+    
+    case RetEffect::Alias: {
+      unsigned idx = RE.getValue();
+      assert (idx < CE->getNumArgs());
+      RVal V = StateMgr.GetRVal(St, CE->getArg(idx));
+      St = StateMgr.SetRVal(St, CE, V, Engine.getCFG().isBlkExpr(CE), false);
+      break;
+    }
+      
+    case RetEffect::OwnedSymbol: {
+      unsigned Count = Builder.getCurrentBlockCount();
+      SymbolID Sym = Engine.getSymbolManager().getCallRetValSymbol(CE, Count);
+
+      ValueState StImpl = *St;
+      RefBindings B = GetRefBindings(StImpl);
+      SetRefBindings(StImpl, RefBFactory.Add(B, Sym, RefVal::makeOwned(1)));
+      
+      St = StateMgr.SetRVal(StateMgr.getPersistentState(StImpl),
+                            CE, lval::SymbolVal(Sym),
+                            Engine.getCFG().isBlkExpr(CE), false);
+      
+      break;
+    }
+      
+    case RetEffect::NotOwnedSymbol: {
+      unsigned Count = Builder.getCurrentBlockCount();
+      SymbolID Sym = Engine.getSymbolManager().getCallRetValSymbol(CE, Count);
+      
+      ValueState StImpl = *St;
+      RefBindings B = GetRefBindings(StImpl);
+      SetRefBindings(StImpl, RefBFactory.Add(B, Sym, RefVal::makeNotOwned()));
+      
+      St = StateMgr.SetRVal(StateMgr.getPersistentState(StImpl),
+                            CE, lval::SymbolVal(Sym),
+                            Engine.getCFG().isBlkExpr(CE), false);
+      
+      break;
+    }
+  }
+      
+  Builder.Nodify(Dst, CE, Pred, St);
 }
 
 
@@ -418,6 +695,12 @@
       assert (false && "Unhandled CFRef transition.");
       
     case DoNothing:
+      if (V.getKind() == RefVal::Released) {
+        V = RefVal::makeUseAfterRelease();        
+        hasError = V.getKind();
+        break;
+      }
+      
       return B;
       
     case IncRef:      

Modified: cfe/trunk/Analysis/GRSimpleVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRSimpleVals.cpp?rev=48272&r1=48271&r2=48272&view=diff

==============================================================================
--- cfe/trunk/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/Analysis/GRSimpleVals.cpp Tue Mar 11 20:21:45 2008
@@ -95,13 +95,13 @@
   if (Diag.hasErrorOccurred())
     return 0;
   
-  GRCoreEngine<GRExprEngine> Engine(cfg, FD, Ctx);
-  GRExprEngine* CheckerState = &Engine.getCheckerState();
+  GRCoreEngine<GRExprEngine> Eng(cfg, FD, Ctx);
+  GRExprEngine* CheckerState = &Eng.getCheckerState();
   GRSimpleVals GRSV;
   CheckerState->setTransferFunctions(GRSV);
   
   // Execute the worklist algorithm.
-  Engine.ExecuteWorkList(50000);
+  Eng.ExecuteWorkList(50000);
   
   SourceManager& SrcMgr = Ctx.getSourceManager();  
 
@@ -144,7 +144,7 @@
   if (Visualize) CheckerState->ViewGraph(TrimGraph);
 #endif
   
-  return Engine.getGraph().size();
+  return Eng.getGraph().size();
 }
   
 } // end clang namespace
@@ -153,14 +153,16 @@
 // Transfer function for Casts.
 //===----------------------------------------------------------------------===//
 
-RVal GRSimpleVals::EvalCast(BasicValueFactory& BasicVals, NonLVal X, QualType T) {
+RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLVal X, QualType T) {
   
   if (!isa<nonlval::ConcreteInt>(X))
     return UnknownVal();
+
+  BasicValueFactory& BasicVals = Eng.getBasicVals();
   
   llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
   V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
-  V.extOrTrunc(BasicVals.getContext().getTypeSize(T));
+  V.extOrTrunc(Eng.getContext().getTypeSize(T));
   
   if (T->isPointerType())
     return lval::ConcreteInt(BasicVals.getValue(V));
@@ -170,7 +172,7 @@
 
 // Casts.
 
-RVal GRSimpleVals::EvalCast(BasicValueFactory& BasicVals, LVal X, QualType T) {
+RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, LVal X, QualType T) {
   
   if (T->isPointerType() || T->isReferenceType())
     return X;
@@ -180,33 +182,35 @@
   if (!isa<lval::ConcreteInt>(X))
     return UnknownVal();
   
+  BasicValueFactory& BasicVals = Eng.getBasicVals();
+  
   llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
   V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
-  V.extOrTrunc(BasicVals.getContext().getTypeSize(T));
+  V.extOrTrunc(Eng.getContext().getTypeSize(T));
 
   return nonlval::ConcreteInt(BasicVals.getValue(V));
 }
 
 // Unary operators.
 
-RVal GRSimpleVals::EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U, NonLVal X){
+RVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLVal X){
   
   switch (X.getSubKind()) {
       
     case nonlval::ConcreteIntKind:
-      return cast<nonlval::ConcreteInt>(X).EvalMinus(BasicVals, U);
+      return cast<nonlval::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U);
       
     default:
       return UnknownVal();
   }
 }
 
-RVal GRSimpleVals::EvalComplement(BasicValueFactory& BasicVals, NonLVal X) {
+RVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLVal X) {
 
   switch (X.getSubKind()) {
       
     case nonlval::ConcreteIntKind:
-      return cast<nonlval::ConcreteInt>(X).EvalComplement(BasicVals);
+      return cast<nonlval::ConcreteInt>(X).EvalComplement(Eng.getBasicVals());
       
     default:
       return UnknownVal();
@@ -215,8 +219,11 @@
 
 // Binary operators.
 
-RVal GRSimpleVals::EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
-                             NonLVal L, NonLVal R)  {  
+RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
+                             NonLVal L, NonLVal R)  {
+  
+  BasicValueFactory& BasicVals = Eng.getBasicVals();
+  
   while (1) {
     
     switch (L.getSubKind()) {
@@ -242,7 +249,7 @@
         if (isa<nonlval::ConcreteInt>(R)) {
           const SymIntConstraint& C =
             BasicVals.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
-                                 cast<nonlval::ConcreteInt>(R).getValue());
+                                    cast<nonlval::ConcreteInt>(R).getValue());
           
           return nonlval::SymIntConstraintVal(C);
         }
@@ -256,7 +263,7 @@
 
 // Binary Operators (except assignments and comma).
 
-RVal GRSimpleVals::EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
+RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                              LVal L, LVal R) {
   
   switch (Op) {
@@ -265,23 +272,25 @@
       return UnknownVal();
       
     case BinaryOperator::EQ:
-      return EvalEQ(BasicVals, L, R);
+      return EvalEQ(Eng, L, R);
       
     case BinaryOperator::NE:
-      return EvalNE(BasicVals, L, R);      
+      return EvalNE(Eng, L, R);      
   }
 }
 
 // Pointer arithmetic.
 
-RVal GRSimpleVals::EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
+RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                              LVal L, NonLVal R) {  
   return UnknownVal();
 }
 
 // Equality operators for LVals.
 
-RVal GRSimpleVals::EvalEQ(BasicValueFactory& BasicVals, LVal L, LVal R) {
+RVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, LVal L, LVal R) {
+  
+  BasicValueFactory& BasicVals = Eng.getBasicVals();
   
   switch (L.getSubKind()) {
 
@@ -337,8 +346,10 @@
   return NonLVal::MakeIntTruthVal(BasicVals, false);
 }
 
-RVal GRSimpleVals::EvalNE(BasicValueFactory& BasicVals, LVal L, LVal R) {
+RVal GRSimpleVals::EvalNE(GRExprEngine& Eng, LVal L, LVal R) {
   
+  BasicValueFactory& BasicVals = Eng.getBasicVals();
+
   switch (L.getSubKind()) {
 
     default:
@@ -356,8 +367,8 @@
       else if (isa<lval::SymbolVal>(R)) {        
         const SymIntConstraint& C =
           BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
-                               BinaryOperator::NE,
-                               cast<lval::ConcreteInt>(L).getValue());
+                                  BinaryOperator::NE,
+                                  cast<lval::ConcreteInt>(L).getValue());
         
         return nonlval::SymIntConstraintVal(C);
       }
@@ -368,8 +379,8 @@
       if (isa<lval::ConcreteInt>(R)) {          
         const SymIntConstraint& C =
           BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
-                               BinaryOperator::NE,
-                               cast<lval::ConcreteInt>(R).getValue());
+                                  BinaryOperator::NE,
+                                  cast<lval::ConcreteInt>(R).getValue());
         
         return nonlval::SymIntConstraintVal(C);
       }
@@ -398,9 +409,8 @@
 //===----------------------------------------------------------------------===//
 
 void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
-                            ValueStateManager& StateMgr,
+                            GRExprEngine& Eng,
                             GRStmtNodeBuilder<ValueState>& Builder,
-                            BasicValueFactory& BasicVals,
                             CallExpr* CE, LVal L,
                             ExplodedNode<ValueState>* Pred) {
   
@@ -411,10 +421,10 @@
   for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
         I != E; ++I) {
 
-    RVal V = StateMgr.GetRVal(St, *I);
+    RVal V = Eng.getStateManager().GetRVal(St, *I);
     
     if (isa<LVal>(V))
-      St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
+      St = Eng.getStateManager().SetRVal(St, cast<LVal>(V), UnknownVal());
   }
     
   Builder.Nodify(Dst, CE, Pred, St);

Modified: cfe/trunk/Analysis/GRSimpleVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRSimpleVals.h?rev=48272&r1=48271&r2=48272&view=diff

==============================================================================
--- cfe/trunk/Analysis/GRSimpleVals.h (original)
+++ cfe/trunk/Analysis/GRSimpleVals.h Tue Mar 11 20:21:45 2008
@@ -28,34 +28,33 @@
   
   // Casts.
   
-  virtual RVal EvalCast(BasicValueFactory& BasicVals, NonLVal V, QualType CastT);
-  virtual RVal EvalCast(BasicValueFactory& BasicVals, LVal V, QualType CastT);
+  virtual RVal EvalCast(GRExprEngine& Engine, NonLVal V, QualType CastT);
+  virtual RVal EvalCast(GRExprEngine& Engine, LVal V, QualType CastT);
   
   // Unary Operators.
   
-  virtual RVal EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U, NonLVal X);
+  virtual RVal EvalMinus(GRExprEngine& Engine, UnaryOperator* U, NonLVal X);
 
-  virtual RVal EvalComplement(BasicValueFactory& BasicVals, NonLVal X);
+  virtual RVal EvalComplement(GRExprEngine& Engine, NonLVal X);
   
   // Binary Operators.
   
-  virtual RVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
+  virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
                          NonLVal L, NonLVal R);
   
-  virtual RVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
+  virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
                          LVal L, LVal R);
   
   // Pointer arithmetic.
   
-  virtual RVal EvalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
+  virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
                          LVal L, NonLVal R);  
   
   // Calls.
   
   virtual void EvalCall(ExplodedNodeSet<ValueState>& Dst,
-                        ValueStateManager& StateMgr,
+                        GRExprEngine& Engine,
                         GRStmtNodeBuilder<ValueState>& Builder,
-                        BasicValueFactory& BasicVals,
                         CallExpr* CE, LVal L,
                         ExplodedNode<ValueState>* Pred);
   
@@ -63,8 +62,8 @@
   
   // Equality operators for LVals.
   
-  RVal EvalEQ(BasicValueFactory& BasicVals, LVal L, LVal R);
-  RVal EvalNE(BasicValueFactory& BasicVals, LVal L, LVal R);
+  RVal EvalEQ(GRExprEngine& Engine, LVal L, LVal R);
+  RVal EvalNE(GRExprEngine& Engine, LVal L, LVal R);
 };
   
 } // end clang namespace

Modified: cfe/trunk/Analysis/SymbolManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/SymbolManager.cpp?rev=48272&r1=48271&r2=48272&view=diff

==============================================================================
--- cfe/trunk/Analysis/SymbolManager.cpp (original)
+++ cfe/trunk/Analysis/SymbolManager.cpp Tue Mar 11 20:21:45 2008
@@ -20,30 +20,84 @@
 
   assert (isa<ParmVarDecl>(D) || D->hasGlobalStorage());
   
-  SymbolID& X = DataToSymbol[getKey(D)];
+  llvm::FoldingSetNodeID profile;
   
-  if (!X.isInitialized()) {
-    X = SymbolToData.size();
-    
-    if (ParmVarDecl* VD = dyn_cast<ParmVarDecl>(D))
-      SymbolToData.push_back(SymbolDataParmVar(VD));
-    else
-      SymbolToData.push_back(SymbolDataGlobalVar(D));
+  ParmVarDecl* PD = dyn_cast<ParmVarDecl>(D);
+  
+  if (PD)
+    SymbolDataParmVar::Profile(profile, PD);
+  else
+    SymbolDataGlobalVar::Profile(profile, D);
+  
+  void* InsertPos;
+  
+  SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
+
+  if (SD)
+    return SD->getSymbol();
+  
+  if (PD) {
+    SD = (SymbolData*) BPAlloc.Allocate<SymbolDataParmVar>();
+    new (SD) SymbolDataParmVar(SymbolCounter, PD);
+  }
+  else {
+    SD = (SymbolData*) BPAlloc.Allocate<SymbolDataGlobalVar>();
+    new (SD) SymbolDataGlobalVar(SymbolCounter, D);
   }
   
-  return X;
+  DataSet.InsertNode(SD, InsertPos);
+  
+  DataMap[SymbolCounter] = SD;
+  return SymbolCounter++;
 }  
  
 SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) {
-  SymbolID& X = DataToSymbol[getKey(sym)];
   
-  if (!X.isInitialized()) {
-    X = SymbolToData.size();
-    SymbolToData.push_back(SymbolDataContentsOf(sym));
-  }
+  llvm::FoldingSetNodeID profile;
+  SymbolDataContentsOf::Profile(profile, sym);
+  void* InsertPos;
+  
+  SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
+  
+  if (SD)
+    return SD->getSymbol();
+
+  SD = (SymbolData*) BPAlloc.Allocate<SymbolDataContentsOf>();
+  new (SD) SymbolDataContentsOf(SymbolCounter, sym);
+
+
+  DataSet.InsertNode(SD, InsertPos);  
+  DataMap[SymbolCounter] = SD;
   
-  return X;  
+  return SymbolCounter++;
 }
+  
+SymbolID SymbolManager::getCallRetValSymbol(CallExpr* CE, unsigned Count) {
+  
+  llvm::FoldingSetNodeID profile;
+  SymbolDataCallRetVal::Profile(profile, CE, Count);
+  void* InsertPos;
+  
+  SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
+  
+  if (SD)
+    return SD->getSymbol();
+  
+  SD = (SymbolData*) BPAlloc.Allocate<SymbolDataCallRetVal>();
+  new (SD) SymbolDataCallRetVal(SymbolCounter, CE, Count);
+  
+  DataSet.InsertNode(SD, InsertPos);  
+  DataMap[SymbolCounter] = SD;
+  
+  return SymbolCounter++;
+}
+
+const SymbolData& SymbolManager::getSymbolData(SymbolID Sym) const {  
+  DataMapTy::const_iterator I = DataMap.find(Sym);
+  assert (I != DataMap.end());  
+  return *I->second;
+}
+
 
 QualType SymbolData::getType(const SymbolManager& SymMgr) const {
   switch (getKind()) {
@@ -57,12 +111,14 @@
       return cast<SymbolDataGlobalVar>(this)->getDecl()->getType();
       
     case ContentsOfKind: {
-      SymbolID x = cast<SymbolDataContentsOf>(this)->getSymbol();
+      SymbolID x = cast<SymbolDataContentsOf>(this)->getContainerSymbol();
       QualType T = SymMgr.getSymbolData(x).getType(SymMgr);
       return T->getAsPointerType()->getPointeeType();
     }
+      
+    case CallRetValKind:
+      return cast<SymbolDataCallRetVal>(this)->getCallExpr()->getType();
   }
 }
 
-SymbolManager::SymbolManager() {}
 SymbolManager::~SymbolManager() {}

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h?rev=48272&r1=48271&r2=48272&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h Tue Mar 11 20:21:45 2008
@@ -143,6 +143,12 @@
     return LastNode ? (LastNode->isSink() ? NULL : LastNode) : NULL;
   }
   
+  GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
+  
+  unsigned getCurrentBlockCount() const {
+    return getBlockCounter().getNumVisited(B.getBlockID());
+  }  
+  
   ExplodedNodeImpl* generateNodeImpl(Stmt* S, void* State,
                                      ExplodedNodeImpl* Pred);
 
@@ -182,6 +188,14 @@
     return static_cast<NodeTy*>(NB.generateNodeImpl(S, St));    
   }
   
+  GRBlockCounter getBlockCounter() const {
+    return NB.getBlockCounter();
+  }  
+  
+  unsigned getCurrentBlockCount() const {
+    return NB.getCurrentBlockCount();
+  }
+  
   StateTy* GetState(NodeTy* Pred) const {
     if ((ExplodedNodeImpl*) Pred == NB.getBasePredecessor())
       return CleanedState;

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=48272&r1=48271&r2=48272&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Tue Mar 11 20:21:45 2008
@@ -263,6 +263,16 @@
   ///  nodes by processing the 'effects' of a switch statement.
   void ProcessSwitch(SwitchNodeBuilder& builder);
   
+  
+  ValueStateManager& getStateManager() { return StateMgr; }
+  const ValueStateManager& getStateManger() const { return StateMgr; }
+  
+  BasicValueFactory& getBasicVals() { return BasicVals; }
+  const BasicValueFactory& getBasicVals() const { return BasicVals; }
+  
+  SymbolManager& getSymbolManager() { return SymMgr; }
+  const SymbolManager& getSymbolManager() const { return SymMgr; }
+  
 protected:
   
   ValueState* GetState(NodeTy* N) {
@@ -394,25 +404,25 @@
       return X;
     
     if (isa<LVal>(X))
-      return TF->EvalCast(BasicVals, cast<LVal>(X), CastT);
+      return TF->EvalCast(*this, cast<LVal>(X), CastT);
     else
-      return TF->EvalCast(BasicVals, cast<NonLVal>(X), CastT);
+      return TF->EvalCast(*this, cast<NonLVal>(X), CastT);
   }
   
   RVal EvalMinus(UnaryOperator* U, RVal X) {
-    return X.isValid() ? TF->EvalMinus(BasicVals, U, cast<NonLVal>(X)) : X;
+    return X.isValid() ? TF->EvalMinus(*this, U, cast<NonLVal>(X)) : X;
   }
   
   RVal EvalComplement(RVal X) {
-    return X.isValid() ? TF->EvalComplement(BasicVals, cast<NonLVal>(X)) : X;
+    return X.isValid() ? TF->EvalComplement(*this, cast<NonLVal>(X)) : X;
   }
 
   RVal EvalBinOp(BinaryOperator::Opcode Op, NonLVal L, RVal R) {
-    return R.isValid() ? TF->EvalBinOp(BasicVals, Op, L, cast<NonLVal>(R)) : R;
+    return R.isValid() ? TF->EvalBinOp(*this, Op, L, cast<NonLVal>(R)) : R;
   }
   
   RVal EvalBinOp(BinaryOperator::Opcode Op, NonLVal L, NonLVal R) {
-    return R.isValid() ? TF->EvalBinOp(BasicVals, Op, L, R) : R;
+    return R.isValid() ? TF->EvalBinOp(*this, Op, L, R) : R;
   }
   
   RVal EvalBinOp(BinaryOperator::Opcode Op, RVal L, RVal R) {
@@ -425,9 +435,9 @@
         
     if (isa<LVal>(L)) {
       if (isa<LVal>(R))
-        return TF->EvalBinOp(BasicVals, Op, cast<LVal>(L), cast<LVal>(R));
+        return TF->EvalBinOp(*this, Op, cast<LVal>(L), cast<LVal>(R));
       else
-        return TF->EvalBinOp(BasicVals, Op, cast<LVal>(L), cast<NonLVal>(R));
+        return TF->EvalBinOp(*this, Op, cast<LVal>(L), cast<NonLVal>(R));
     }
     
     if (isa<LVal>(R)) {
@@ -437,15 +447,15 @@
       assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub);
 
       // Commute the operands.      
-      return TF->EvalBinOp(BasicVals, Op, cast<LVal>(R), cast<NonLVal>(L));
+      return TF->EvalBinOp(*this, Op, cast<LVal>(R), cast<NonLVal>(L));
     }
     else
-      return TF->EvalBinOp(BasicVals, Op, cast<NonLVal>(L), cast<NonLVal>(R));
+      return TF->EvalBinOp(*this, Op, cast<NonLVal>(L), cast<NonLVal>(R));
   }
   
   void EvalCall(NodeSet& Dst, CallExpr* CE, LVal L, NodeTy* Pred) {
     assert (Builder && "GRStmtNodeBuilder must be defined.");    
-    return TF->EvalCall(Dst, StateMgr, *Builder, BasicVals, CE, L, Pred);
+    return TF->EvalCall(Dst, *this, *Builder, CE, L, Pred);
   }
   
   ValueState* MarkBranch(ValueState* St, Stmt* Terminator, bool branchTaken);

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h?rev=48272&r1=48271&r2=48272&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRTransferFuncs.h Tue Mar 11 20:21:45 2008
@@ -21,6 +21,8 @@
 
 namespace clang {
   
+  class GRExprEngine;
+  
 class GRTransferFuncs {
 public:
   GRTransferFuncs() {}
@@ -32,38 +34,34 @@
   
   // Casts.
   
-  virtual RVal EvalCast(BasicValueFactory& BasicVals, NonLVal V,
-                        QualType CastT) =0;
-  
-  virtual RVal EvalCast(BasicValueFactory& BasicVals, LVal V,
-                        QualType CastT) = 0;
+  virtual RVal EvalCast(GRExprEngine& Engine, NonLVal V, QualType CastT) =0;  
+  virtual RVal EvalCast(GRExprEngine& Engine, LVal V, QualType CastT) = 0;
 
   // Unary Operators.
   
-  virtual RVal EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U,
-                         NonLVal X) = 0;
+  virtual RVal EvalMinus(GRExprEngine& Engine, UnaryOperator* U, NonLVal X) = 0;
 
-  virtual RVal EvalComplement(BasicValueFactory& BasicVals, NonLVal X) = 0;
+  virtual RVal EvalComplement(GRExprEngine& Engine, NonLVal X) = 0;
 
   // Binary Operators.
   
-  virtual RVal EvalBinOp(BasicValueFactory& BasicVals,
-                         BinaryOperator::Opcode Op, NonLVal L, NonLVal R) = 0;
+  virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
+                         NonLVal L, NonLVal R) = 0;
   
-  virtual RVal EvalBinOp(BasicValueFactory& BasicVals,
-                         BinaryOperator::Opcode Op, LVal L, LVal R) = 0;
+  virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
+                         LVal L, LVal R) = 0;
   
   // Pointer arithmetic.
   
-  virtual RVal EvalBinOp(BasicValueFactory& BasicVals,
-                         BinaryOperator::Opcode Op, LVal L, NonLVal R) = 0;
+  virtual RVal EvalBinOp(GRExprEngine& Engine, BinaryOperator::Opcode Op,
+                         LVal L, NonLVal R) = 0;
   
   // Calls.
   
   virtual void EvalCall(ExplodedNodeSet<ValueState>& Dst,
-                        ValueStateManager& StateMgr,
+                        GRExprEngine& Engine,
                         GRStmtNodeBuilder<ValueState>& Builder,
-                        BasicValueFactory& BasicVals, CallExpr* CE, LVal L,
+                        CallExpr* CE, LVal L,
                         ExplodedNode<ValueState>* Pred) = 0;
 };
   

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h?rev=48272&r1=48271&r2=48272&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h Tue Mar 11 20:21:45 2008
@@ -20,7 +20,7 @@
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/Support/DataTypes.h"
-#include <vector>
+#include "llvm/Support/Allocator.h"
 
 namespace clang {
   
@@ -28,15 +28,14 @@
   
 class SymbolID {
   unsigned Data;
+  
 public:
-  SymbolID() : Data(~0) {}
   SymbolID(unsigned x) : Data(x) {}
   
-  bool isInitialized() const { return Data != (unsigned) ~0; }
-  operator unsigned() const { assert (isInitialized()); return Data; }
+  operator unsigned() const { return Data; }
+  unsigned getNumber() const { return Data; }
   
   void Profile(llvm::FoldingSetNodeID& ID) const { 
-    assert (isInitialized());
     ID.AddInteger(Data);
   }
   
@@ -44,51 +43,74 @@
     X.Profile(ID);
   }
 };
+  
+} // end clang namespace
+
+namespace llvm {
+  template <> struct DenseMapInfo<clang::SymbolID> {
+    static inline clang::SymbolID getEmptyKey() {
+      return clang::SymbolID(~0U);
+    }
+    static inline clang::SymbolID getTombstoneKey() {
+      return clang::SymbolID(~0U - 1);
+    }
+    static unsigned getHashValue(clang::SymbolID X) {
+      return X.getNumber();
+    }
+    static bool isEqual(clang::SymbolID X, clang::SymbolID Y) {
+      return X.getNumber() == Y.getNumber();
+    }
+    static bool isPod() { return true; }
+  };
+}
 
 // SymbolData: Used to record meta data about symbols.
 
-class SymbolData {
+namespace clang {
+  
+class SymbolData : public llvm::FoldingSetNode {
 public:
-  enum Kind { UndefKind, ParmKind, GlobalKind, ContentsOfKind };
+  enum Kind { UndefKind, ParmKind, GlobalKind, ContentsOfKind, CallRetValKind };
   
 private:
-  uintptr_t Data;
   Kind K;
+  SymbolID Sym;
   
 protected:
-  SymbolData(uintptr_t D, Kind k) : Data(D), K(k) {}
-  SymbolData(void* D, Kind k) : Data(reinterpret_cast<uintptr_t>(D)), K(k) {}
-  
-  void* getPtr() const { 
-    assert (K != UndefKind);
-    return reinterpret_cast<void*>(Data);
-  }
-  
-  uintptr_t getInt() const {
-    assert (K != UndefKind);
-    return Data;
-  }
-  
+  SymbolData(Kind k, SymbolID sym) : K(k), Sym(sym) {}  
+
 public:
-  SymbolData() : Data(0), K(UndefKind) {}
+  virtual ~SymbolData() {}
   
-  Kind  getKind() const { return K; }  
-  
-  inline bool operator==(const SymbolData& R) const { 
-    return K == R.K && Data == R.Data;
-  }
+  Kind getKind() const { return K; }  
   
+  SymbolID getSymbol() const { return Sym; }
+    
   QualType getType(const SymbolManager& SymMgr) const;
   
+  virtual void Profile(llvm::FoldingSetNodeID& profile) = 0;
+  
   // Implement isa<T> support.
   static inline bool classof(const SymbolData*) { return true; }
 };
 
 class SymbolDataParmVar : public SymbolData {
-public:
-  SymbolDataParmVar(ParmVarDecl* VD) : SymbolData(VD, ParmKind) {}
+  ParmVarDecl *VD;
+
+public:  
+  SymbolDataParmVar(SymbolID MySym, ParmVarDecl* vd)
+    : SymbolData(ParmKind, MySym), VD(vd) {}
+  
+  ParmVarDecl* getDecl() const { return VD; }  
   
-  ParmVarDecl* getDecl() const { return (ParmVarDecl*) getPtr(); }
+  static void Profile(llvm::FoldingSetNodeID& profile, ParmVarDecl* VD) {
+    profile.AddInteger((unsigned) ParmKind);
+    profile.AddPointer(VD);
+  }
+  
+  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+    Profile(profile, VD);
+  }
   
   // Implement isa<T> support.
   static inline bool classof(const SymbolData* D) {
@@ -97,10 +119,22 @@
 };
   
 class SymbolDataGlobalVar : public SymbolData {
+  VarDecl *VD;
+
 public:
-  SymbolDataGlobalVar(VarDecl* VD) : SymbolData(VD, GlobalKind) {}
+  SymbolDataGlobalVar(SymbolID MySym, VarDecl* vd) :
+    SymbolData(GlobalKind, MySym), VD(vd) {}
+  
+  VarDecl* getDecl() const { return VD; }
   
-  VarDecl* getDecl() const { return (VarDecl*) getPtr(); }
+  static void Profile(llvm::FoldingSetNodeID& profile, VarDecl* VD) {
+    profile.AddInteger((unsigned) GlobalKind);
+    profile.AddPointer(VD);
+  }
+  
+  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+    Profile(profile, VD);
+  }
   
   // Implement isa<T> support.
   static inline bool classof(const SymbolData* D) {
@@ -109,16 +143,57 @@
 };
 
 class SymbolDataContentsOf : public SymbolData {
+  SymbolID Sym;
+      
 public:
-  SymbolDataContentsOf(SymbolID ID) : SymbolData(ID, ContentsOfKind) {}
+  SymbolDataContentsOf(SymbolID MySym, SymbolID sym) : 
+    SymbolData(ContentsOfKind, MySym), Sym(sym) {}
+  
+  SymbolID getContainerSymbol() const { return Sym; }
   
-  SymbolID getSymbol() const { return (SymbolID) getInt(); }
+  static void Profile(llvm::FoldingSetNodeID& profile, SymbolID Sym) {
+    profile.AddInteger((unsigned) ContentsOfKind);
+    profile.AddInteger(Sym);
+  }
+  
+  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+    Profile(profile, Sym);
+  }
   
   // Implement isa<T> support.
   static inline bool classof(const SymbolData* D) {
     return D->getKind() == ContentsOfKind;
   }  
 };
+  
+class SymbolDataCallRetVal : public SymbolData {
+  CallExpr* CE;
+  unsigned Count;
+
+public:
+  SymbolDataCallRetVal(SymbolID Sym, CallExpr* ce, unsigned count)
+    : SymbolData(CallRetValKind, Sym), CE(ce), Count(count) {}
+  
+  CallExpr* getCallExpr() const { return CE; }
+  unsigned getCount() const { return Count; }  
+  
+  static void Profile(llvm::FoldingSetNodeID& profile,
+                      CallExpr* CE, unsigned Count) {
+    
+    profile.AddInteger((unsigned) CallRetValKind);
+    profile.AddPointer(CE);
+    profile.AddInteger(Count);
+  }
+  
+  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+    Profile(profile, CE, Count);
+  }
+  
+  // Implement isa<T> support.
+  static inline bool classof(const SymbolData* D) {
+    return D->getKind() == CallRetValKind;
+  }  
+};
 
 // Constraints on symbols.  Usually wrapped by RValues.
 
@@ -133,7 +208,7 @@
   Op(op), Val(V) {}
   
   BinaryOperator::Opcode getOpcode() const { return Op; }
-  const SymbolID& getSymbol() const { return Symbol; }
+  SymbolID getSymbol() const { return Symbol; }
   const llvm::APSInt& getInt() const { return Val; }
   
   static inline void Profile(llvm::FoldingSetNodeID& ID,
@@ -152,32 +227,28 @@
 
 
 class SymbolManager {
-  std::vector<SymbolData> SymbolToData;
-  
-  typedef llvm::DenseMap<void*,SymbolID> MapTy;
-  MapTy DataToSymbol;
+  typedef llvm::FoldingSet<SymbolData> DataSetTy;
+  typedef llvm::DenseMap<SymbolID, SymbolData*> DataMapTy;
   
-  void* getKey(void* P) const {
-    return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(P) | 0x1);
-  }
+  DataSetTy DataSet;
+  DataMapTy DataMap;
   
-  void* getKey(SymbolID sym) const {
-    return reinterpret_cast<void*>((uintptr_t) (sym << 1));
-  }
+  unsigned SymbolCounter;
+  llvm::BumpPtrAllocator& BPAlloc;
   
 public:
-  SymbolManager();
+  SymbolManager(llvm::BumpPtrAllocator& bpalloc)
+    : SymbolCounter(0), BPAlloc(bpalloc) {}
+  
   ~SymbolManager();
   
   SymbolID getSymbol(VarDecl* D);
   SymbolID getContentsOfSymbol(SymbolID sym);
+  SymbolID getCallRetValSymbol(CallExpr* CE, unsigned VisitCount);
   
-  inline const SymbolData& getSymbolData(SymbolID ID) const {
-    assert (ID < SymbolToData.size());
-    return SymbolToData[ID];
-  }
+  const SymbolData& getSymbolData(SymbolID ID) const;
   
-  inline QualType getType(SymbolID ID) const {
+  QualType getType(SymbolID ID) const {
     return getSymbolData(ID).getType(*this);
   }
 };

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h?rev=48272&r1=48271&r2=48272&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h Tue Mar 11 20:21:45 2008
@@ -214,6 +214,7 @@
       CNEFactory(alloc),
       CEFactory(alloc),
       BasicVals(Ctx, alloc),
+      SymMgr(alloc),
       Alloc(alloc) {}
   
   ValueState* getInitialState();





More information about the cfe-commits mailing list