зеркало из https://github.com/microsoft/clang-1.git
CompoundVal now uses an ImmutableList<SVal> to store its set of SVals. This change was motivated by the need to allow state-splitting in GRExprEngine::VisitInitListExpr. As a side-benefit, we no longer need to perform any copies of SVals when creating a CompoundSVal, and the profiling of CompoundSVal is now constant time.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58437 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
56f6e3f3d2
Коммит
632e8b8497
|
@ -17,33 +17,26 @@
|
||||||
#define LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
|
#define LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
|
||||||
|
|
||||||
#include "clang/Analysis/PathSensitive/SymbolManager.h"
|
#include "clang/Analysis/PathSensitive/SymbolManager.h"
|
||||||
|
#include "clang/Analysis/PathSensitive/SVals.h"
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
#include "llvm/ADT/FoldingSet.h"
|
#include "llvm/ADT/FoldingSet.h"
|
||||||
#include "llvm/ADT/APSInt.h"
|
#include "llvm/ADT/APSInt.h"
|
||||||
|
#include "llvm/ADT/ImmutableList.h"
|
||||||
namespace llvm {
|
|
||||||
class BumpPtrAllocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
|
|
||||||
class SVal;
|
|
||||||
|
|
||||||
class CompoundValData : public llvm::FoldingSetNode {
|
class CompoundValData : public llvm::FoldingSetNode {
|
||||||
QualType T;
|
QualType T;
|
||||||
unsigned NumVals;
|
llvm::ImmutableList<SVal> L;
|
||||||
SVal* Vals;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CompoundValData(QualType t, const SVal* vals, unsigned n,
|
CompoundValData(QualType t, llvm::ImmutableList<SVal> l)
|
||||||
llvm::BumpPtrAllocator& A);
|
: T(t), L(l) {}
|
||||||
|
|
||||||
static void Profile(llvm::FoldingSetNodeID& ID, QualType T, unsigned N,
|
static void Profile(llvm::FoldingSetNodeID& ID, QualType T,
|
||||||
const SVal* Vals);
|
llvm::ImmutableList<SVal> L);
|
||||||
|
|
||||||
void Profile(llvm::FoldingSetNodeID& ID) {
|
void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, T, L); }
|
||||||
Profile(ID, T, NumVals, Vals);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BasicValueFactory {
|
class BasicValueFactory {
|
||||||
|
@ -62,11 +55,13 @@ class BasicValueFactory {
|
||||||
void* PersistentSVals;
|
void* PersistentSVals;
|
||||||
void* PersistentSValPairs;
|
void* PersistentSValPairs;
|
||||||
|
|
||||||
llvm::FoldingSet<CompoundValData> CompoundValDataSet;
|
llvm::ImmutableList<SVal>::Factory SValListFactory;
|
||||||
|
llvm::FoldingSet<CompoundValData> CompoundValDataSet;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
|
BasicValueFactory(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
|
||||||
: Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0) {}
|
: Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0),
|
||||||
|
SValListFactory(Alloc) {}
|
||||||
|
|
||||||
~BasicValueFactory();
|
~BasicValueFactory();
|
||||||
|
|
||||||
|
@ -87,8 +82,16 @@ public:
|
||||||
const SymIntConstraint& getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
|
const SymIntConstraint& getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
|
||||||
const llvm::APSInt& V);
|
const llvm::APSInt& V);
|
||||||
|
|
||||||
const CompoundValData* getCompoundValData(QualType T, const SVal* Vals,
|
const CompoundValData* getCompoundValData(QualType T,
|
||||||
unsigned NumVals);
|
llvm::ImmutableList<SVal> Vals);
|
||||||
|
|
||||||
|
llvm::ImmutableList<SVal> getEmptySValList() {
|
||||||
|
return SValListFactory.GetEmptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::ImmutableList<SVal> consVals(SVal X, llvm::ImmutableList<SVal> L) {
|
||||||
|
return SValListFactory.Add(X, L);
|
||||||
|
}
|
||||||
|
|
||||||
const llvm::APSInt* EvaluateAPSInt(BinaryOperator::Opcode Op,
|
const llvm::APSInt* EvaluateAPSInt(BinaryOperator::Opcode Op,
|
||||||
const llvm::APSInt& V1,
|
const llvm::APSInt& V1,
|
||||||
|
|
|
@ -15,15 +15,18 @@
|
||||||
#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H
|
#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H
|
||||||
#define LLVM_CLANG_ANALYSIS_RVALUE_H
|
#define LLVM_CLANG_ANALYSIS_RVALUE_H
|
||||||
|
|
||||||
#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
|
#include "clang/Analysis/PathSensitive/SymbolManager.h"
|
||||||
#include "llvm/Support/Casting.h"
|
#include "llvm/Support/Casting.h"
|
||||||
|
#include "llvm/ADT/ImmutableList.h"
|
||||||
|
|
||||||
//==------------------------------------------------------------------------==//
|
//==------------------------------------------------------------------------==//
|
||||||
// Base SVal types.
|
// Base SVal types.
|
||||||
//==------------------------------------------------------------------------==//
|
//==------------------------------------------------------------------------==//
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
|
|
||||||
|
class CompoundValData;
|
||||||
|
class BasicValueFactory;
|
||||||
class MemRegion;
|
class MemRegion;
|
||||||
class GRStateManager;
|
class GRStateManager;
|
||||||
|
|
||||||
|
@ -170,7 +173,7 @@ public:
|
||||||
|
|
||||||
static NonLoc MakeIntTruthVal(BasicValueFactory& BasicVals, bool b);
|
static NonLoc MakeIntTruthVal(BasicValueFactory& BasicVals, bool b);
|
||||||
|
|
||||||
static NonLoc MakeCompoundVal(QualType T, SVal* Vals, unsigned NumSVals,
|
static NonLoc MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals,
|
||||||
BasicValueFactory& BasicVals);
|
BasicValueFactory& BasicVals);
|
||||||
|
|
||||||
// Implement isa<T> support.
|
// Implement isa<T> support.
|
||||||
|
@ -312,10 +315,7 @@ public:
|
||||||
return V->getSubKind() == LocAsIntegerKind;
|
return V->getSubKind() == LocAsIntegerKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline LocAsInteger Make(BasicValueFactory& Vals, Loc V,
|
static LocAsInteger Make(BasicValueFactory& Vals, Loc V, unsigned Bits);
|
||||||
unsigned Bits) {
|
|
||||||
return LocAsInteger(Vals.getPersistentSValWithData(V, Bits));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CompoundVal : public NonLoc {
|
class CompoundVal : public NonLoc {
|
||||||
|
|
|
@ -14,34 +14,18 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
|
#include "clang/Analysis/PathSensitive/BasicValueFactory.h"
|
||||||
#include "clang/Analysis/PathSensitive/SVals.h"
|
|
||||||
|
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
|
||||||
CompoundValData::CompoundValData(QualType t, const SVal* vals, unsigned n,
|
|
||||||
llvm::BumpPtrAllocator& A)
|
|
||||||
: T(t), NumVals(n) {
|
|
||||||
|
|
||||||
Vals = (SVal*) A.Allocate<SVal>(n);
|
|
||||||
|
|
||||||
new (Vals) SVal[n];
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < n; ++i)
|
|
||||||
Vals[i] = vals[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
void CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
|
void CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
|
||||||
unsigned N, const SVal* Vals) {
|
llvm::ImmutableList<SVal> L) {
|
||||||
T.Profile(ID);
|
T.Profile(ID);
|
||||||
ID.AddInteger(N);
|
ID.AddPointer(L.getInternalPointer());
|
||||||
for (unsigned i = 0; i < N; ++i)
|
|
||||||
Vals[i].Profile(ID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::pair<SVal, uintptr_t> SValData;
|
typedef std::pair<SVal, uintptr_t> SValData;
|
||||||
typedef std::pair<SVal, SVal> SValPair;
|
typedef std::pair<SVal, SVal> SValPair;
|
||||||
|
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
template<> struct FoldingSetTrait<SValData> {
|
template<> struct FoldingSetTrait<SValData> {
|
||||||
static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
|
static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
|
||||||
|
@ -127,17 +111,18 @@ BasicValueFactory::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
|
||||||
}
|
}
|
||||||
|
|
||||||
const CompoundValData*
|
const CompoundValData*
|
||||||
BasicValueFactory::getCompoundValData(QualType T, const SVal* Vals,
|
BasicValueFactory::getCompoundValData(QualType T,
|
||||||
unsigned NumVals) {
|
llvm::ImmutableList<SVal> Vals) {
|
||||||
|
|
||||||
llvm::FoldingSetNodeID ID;
|
llvm::FoldingSetNodeID ID;
|
||||||
CompoundValData::Profile(ID, T, NumVals, Vals);
|
CompoundValData::Profile(ID, T, Vals);
|
||||||
void* InsertPos;
|
void* InsertPos;
|
||||||
|
|
||||||
CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
|
CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
|
||||||
|
|
||||||
if (!D) {
|
if (!D) {
|
||||||
D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
|
D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
|
||||||
new (D) CompoundValData(T, Vals, NumVals, BPAlloc);
|
new (D) CompoundValData(T, Vals);
|
||||||
CompoundValDataSet.InsertNode(D, InsertPos);
|
CompoundValDataSet.InsertNode(D, InsertPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,9 +245,9 @@ NonLoc NonLoc::MakeIntTruthVal(BasicValueFactory& BasicVals, bool b) {
|
||||||
return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
|
return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
NonLoc NonLoc::MakeCompoundVal(QualType T, SVal* Vals, unsigned NumSVals,
|
NonLoc NonLoc::MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals,
|
||||||
BasicValueFactory& BasicVals) {
|
BasicValueFactory& BasicVals) {
|
||||||
return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals, NumSVals));
|
return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
|
||||||
}
|
}
|
||||||
|
|
||||||
SVal SVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
|
SVal SVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
|
||||||
|
@ -260,6 +260,11 @@ SVal SVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
|
||||||
return nonloc::SymbolVal(SymMgr.getSymbol(D));
|
return nonloc::SymbolVal(SymMgr.getSymbol(D));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nonloc::LocAsInteger nonloc::LocAsInteger::Make(BasicValueFactory& Vals, Loc V,
|
||||||
|
unsigned Bits) {
|
||||||
|
return LocAsInteger(Vals.getPersistentSValWithData(V, Bits));
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Utility methods for constructing Locs.
|
// Utility methods for constructing Locs.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -353,7 +358,7 @@ void NonLoc::print(std::ostream& Out) const {
|
||||||
Out << " [as " << C.getNumBits() << " bit integer]";
|
Out << " [as " << C.getNumBits() << " bit integer]";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert (false && "Pretty-printed not implemented for this NonLoc.");
|
assert (false && "Pretty-printed not implemented for this NonLoc.");
|
||||||
break;
|
break;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче