[cfe-commits] r58440 - /cfe/trunk/lib/Analysis/GRExprEngine.cpp
Ted Kremenek
kremenek at apple.com
Thu Oct 30 10:47:32 PDT 2008
Author: kremenek
Date: Thu Oct 30 12:47:32 2008
New Revision: 58440
URL: http://llvm.org/viewvc/llvm-project?rev=58440&view=rev
Log:
Use a worklist in GRExprEngine::VisitInitListExpr to process subexpressions.
Modified:
cfe/trunk/lib/Analysis/GRExprEngine.cpp
Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=58440&r1=58439&r2=58440&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Thu Oct 30 12:47:32 2008
@@ -1619,44 +1619,73 @@
}
}
+namespace {
+ // This class is used by VisitInitListExpr as an item in a worklist
+ // for processing the values contained in an InitListExpr.
+class VISIBILITY_HIDDEN InitListWLItem {
+public:
+ llvm::ImmutableList<SVal> Vals;
+ GRExprEngine::NodeTy* N;
+ InitListExpr::reverse_iterator Itr;
+
+ InitListWLItem(GRExprEngine::NodeTy* n, llvm::ImmutableList<SVal> vals,
+ InitListExpr::reverse_iterator itr)
+ : Vals(vals), N(n), Itr(itr) {}
+};
+}
+
+
void GRExprEngine::VisitInitListExpr(InitListExpr* E, NodeTy* Pred,
NodeSet& Dst) {
const GRState* state = GetState(Pred);
QualType T = E->getType();
- unsigned NumInitElements = E->getNumInits();
-
- llvm::SmallVector<SVal, 10> InitVals;
- InitVals.reserve(NumInitElements);
-
+ unsigned NumInitElements = E->getNumInits();
if (T->isArrayType() || T->isStructureType()) {
- for (unsigned i = 0; i < NumInitElements; ++i) {
- Expr* Init = E->getInit(i);
- NodeSet Tmp;
- Visit(Init, Pred, Tmp);
-
- // FIXME: Use worklist to allow state splitting.
- assert(Tmp.size() == 1);
- // Get the new intermediate node and its state.
- Pred = *Tmp.begin();
- state = GetState(Pred);
- SVal InitV = GetSVal(state, Init);
- InitVals.push_back(InitV);
- }
-
- // Now we have a vector holding all init values. Make CompoundSValData.
- SVal V = NonLoc::MakeCompoundVal(T, &InitVals[0], NumInitElements,
- StateMgr.getBasicVals());
+ llvm::SmallVector<InitListWLItem, 10> WorkList;
+ WorkList.reserve(NumInitElements);
+
+ WorkList.push_back(InitListWLItem(Pred, getBasicVals().getEmptySValList(),
+ E->rbegin()));
+
+ InitListExpr::reverse_iterator ItrEnd = E->rend();
+
+ while (!WorkList.empty()) {
+ InitListWLItem X = WorkList.back();
+ WorkList.pop_back();
+
+ NodeSet Tmp;
+ Visit(*X.Itr, X.N, Tmp);
+
+ InitListExpr::reverse_iterator NewItr = X.Itr + 1;
- // Make final state and node.
- state = BindExpr(state, E, V);
+ for (NodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) {
+ // Get the last initializer value.
+ state = GetState(*NI);
+ SVal InitV = GetSVal(state, cast<Expr>(*X.Itr));
+
+ // Construct the new list of values by prepending the new value to
+ // the already constructed list.
+ llvm::ImmutableList<SVal> NewVals =
+ getBasicVals().consVals(InitV, X.Vals);
+
+ if (NewItr == ItrEnd) {
+ // Now we have a list holding all init values. Make CompoundSValData.
+ SVal V = NonLoc::MakeCompoundVal(T, NewVals, getBasicVals());
- MakeNode(Dst, E, Pred, state);
- return;
+ // Make final state and node.
+ MakeNode(Dst, E, Pred, BindExpr(state, E, V));
+ }
+ else {
+ // Still some initializer values to go. Push them onto the worklist.
+ WorkList.push_back(InitListWLItem(*NI, NewVals, NewItr));
+ }
+ }
+ }
}
if (Loc::IsLocType(T) || T->isIntegerType()) {
More information about the cfe-commits
mailing list