[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