Further cleanup. Moved definitions for SymbolManager and ValueManager into

their own [.cpp;.h] files.

llvm-svn: 47201
This commit is contained in:
Ted Kremenek 2008-02-16 01:12:31 +00:00
parent f861fbaae8
commit 074965c5cb
7 changed files with 443 additions and 432 deletions

View File

@ -13,116 +13,13 @@
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathSensitive/RValues.h"
#include "llvm/Support/Streams.h"
using namespace clang;
using llvm::dyn_cast;
using llvm::cast;
using llvm::APSInt;
//===----------------------------------------------------------------------===//
// SymbolManager.
//===----------------------------------------------------------------------===//
SymbolID SymbolManager::getSymbol(ParmVarDecl* D) {
SymbolID& X = DataToSymbol[getKey(D)];
if (!X.isInitialized()) {
X = SymbolToData.size();
SymbolToData.push_back(SymbolDataParmVar(D));
}
return X;
}
SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) {
SymbolID& X = DataToSymbol[getKey(sym)];
if (!X.isInitialized()) {
X = SymbolToData.size();
SymbolToData.push_back(SymbolDataContentsOf(sym));
}
return X;
}
QualType SymbolData::getType() const {
switch (getKind()) {
default:
assert (false && "getType() not implemented for this symbol.");
case ParmKind:
return cast<SymbolDataParmVar>(this)->getDecl()->getType();
}
}
SymbolManager::SymbolManager() {}
SymbolManager::~SymbolManager() {}
//===----------------------------------------------------------------------===//
// Values and ValueManager.
//===----------------------------------------------------------------------===//
ValueManager::~ValueManager() {
// Note that the dstor for the contents of APSIntSet will never be called,
// so we iterate over the set and invoke the dstor for each APSInt. This
// frees an aux. memory allocated to represent very large constants.
for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
I->getValue().~APSInt();
}
const APSInt& ValueManager::getValue(const APSInt& X) {
llvm::FoldingSetNodeID ID;
void* InsertPos;
typedef llvm::FoldingSetNodeWrapper<APSInt> FoldNodeTy;
X.Profile(ID);
FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
if (!P) {
P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
new (P) FoldNodeTy(X);
APSIntSet.InsertNode(P, InsertPos);
}
return *P;
}
const APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth,
bool isUnsigned) {
APSInt V(BitWidth, isUnsigned);
V = X;
return getValue(V);
}
const APSInt& ValueManager::getValue(uint64_t X, QualType T,
SourceLocation Loc) {
unsigned bits = Ctx.getTypeSize(T, Loc);
APSInt V(bits, T->isUnsignedIntegerType());
V = X;
return getValue(V);
}
const SymIntConstraint&
ValueManager::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
const llvm::APSInt& V) {
llvm::FoldingSetNodeID ID;
SymIntConstraint::Profile(ID, sym, Op, V);
void* InsertPos;
SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos);
if (!C) {
C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>();
new (C) SymIntConstraint(sym, Op, V);
SymIntCSet.InsertNode(C, InsertPos);
}
return *C;
}
//===----------------------------------------------------------------------===//
// Symbol Iteration.
//===----------------------------------------------------------------------===//
@ -154,69 +51,12 @@ RValue::symbol_iterator RValue::symbol_end() const {
// Transfer function dispatch for Non-LValues.
//===----------------------------------------------------------------------===//
static const
llvm::APSInt& EvaluateAPSInt(ValueManager& ValMgr, BinaryOperator::Opcode Op,
const llvm::APSInt& V1, const llvm::APSInt& V2) {
switch (Op) {
default:
assert (false && "Invalid Opcode.");
case BinaryOperator::Mul:
return ValMgr.getValue( V1 * V2 );
case BinaryOperator::Div:
return ValMgr.getValue( V1 / V2 );
case BinaryOperator::Rem:
return ValMgr.getValue( V1 % V2 );
case BinaryOperator::Add:
return ValMgr.getValue( V1 + V2 );
case BinaryOperator::Sub:
return ValMgr.getValue( V1 - V2 );
case BinaryOperator::Shl:
return ValMgr.getValue( V1.operator<<( (unsigned) V2.getZExtValue() ));
case BinaryOperator::Shr:
return ValMgr.getValue( V1.operator>>( (unsigned) V2.getZExtValue() ));
case BinaryOperator::LT:
return ValMgr.getTruthValue( V1 < V2 );
case BinaryOperator::GT:
return ValMgr.getTruthValue( V1 > V2 );
case BinaryOperator::LE:
return ValMgr.getTruthValue( V1 <= V2 );
case BinaryOperator::GE:
return ValMgr.getTruthValue( V1 >= V2 );
case BinaryOperator::EQ:
return ValMgr.getTruthValue( V1 == V2 );
case BinaryOperator::NE:
return ValMgr.getTruthValue( V1 != V2 );
// Note: LAnd, LOr, Comma are handled specially by higher-level logic.
case BinaryOperator::And:
return ValMgr.getValue( V1 & V2 );
case BinaryOperator::Or:
return ValMgr.getValue( V1 | V2 );
}
}
nonlval::ConcreteInt
nonlval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
BinaryOperator::Opcode Op,
const nonlval::ConcreteInt& RHS) const {
return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue());
return ValMgr.EvaluateAPSInt(Op, getValue(), RHS.getValue());
}
@ -249,7 +89,7 @@ lval::ConcreteInt::EvalBinaryOp(ValueManager& ValMgr,
assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
(Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));
return EvaluateAPSInt(ValMgr, Op, getValue(), RHS.getValue());
return ValMgr.EvaluateAPSInt(Op, getValue(), RHS.getValue());
}
NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const {

View File

@ -0,0 +1,53 @@
//== SymbolManager.h - Management of Symbolic Values ------------*- C++ -*--==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This files defines SymbolManager, a class that manages symbolic values
// created for use by GRExprEngine and related classes.
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathSensitive/SymbolManager.h"
using namespace clang;
SymbolID SymbolManager::getSymbol(ParmVarDecl* D) {
SymbolID& X = DataToSymbol[getKey(D)];
if (!X.isInitialized()) {
X = SymbolToData.size();
SymbolToData.push_back(SymbolDataParmVar(D));
}
return X;
}
SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) {
SymbolID& X = DataToSymbol[getKey(sym)];
if (!X.isInitialized()) {
X = SymbolToData.size();
SymbolToData.push_back(SymbolDataContentsOf(sym));
}
return X;
}
QualType SymbolData::getType() const {
switch (getKind()) {
default:
assert (false && "getType() not implemented for this symbol.");
case ParmKind:
return cast<SymbolDataParmVar>(this)->getDecl()->getType();
}
}
SymbolManager::SymbolManager() {}
SymbolManager::~SymbolManager() {}

View File

@ -0,0 +1,134 @@
// ValueManager.h - Low-level value management for Value Tracking -*- C++ -*--==
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This files defines ValueManager, a class that manages the lifetime of APSInt
// objects and symbolic constraints used by GRExprEngine and related classes.
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathSensitive/ValueManager.h"
using namespace clang;
ValueManager::~ValueManager() {
// Note that the dstor for the contents of APSIntSet will never be called,
// so we iterate over the set and invoke the dstor for each APSInt. This
// frees an aux. memory allocated to represent very large constants.
for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
I->getValue().~APSInt();
}
const llvm::APSInt& ValueManager::getValue(const llvm::APSInt& X) {
llvm::FoldingSetNodeID ID;
void* InsertPos;
typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy;
X.Profile(ID);
FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
if (!P) {
P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
new (P) FoldNodeTy(X);
APSIntSet.InsertNode(P, InsertPos);
}
return *P;
}
const llvm::APSInt& ValueManager::getValue(uint64_t X, unsigned BitWidth,
bool isUnsigned) {
llvm::APSInt V(BitWidth, isUnsigned);
V = X;
return getValue(V);
}
const llvm::APSInt& ValueManager::getValue(uint64_t X, QualType T,
SourceLocation Loc) {
unsigned bits = Ctx.getTypeSize(T, Loc);
llvm::APSInt V(bits, T->isUnsignedIntegerType());
V = X;
return getValue(V);
}
const SymIntConstraint&
ValueManager::getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
const llvm::APSInt& V) {
llvm::FoldingSetNodeID ID;
SymIntConstraint::Profile(ID, sym, Op, V);
void* InsertPos;
SymIntConstraint* C = SymIntCSet.FindNodeOrInsertPos(ID, InsertPos);
if (!C) {
C = (SymIntConstraint*) BPAlloc.Allocate<SymIntConstraint>();
new (C) SymIntConstraint(sym, Op, V);
SymIntCSet.InsertNode(C, InsertPos);
}
return *C;
}
const llvm::APSInt&
ValueManager::EvaluateAPSInt(BinaryOperator::Opcode Op,
const llvm::APSInt& V1, const llvm::APSInt& V2) {
switch (Op) {
default:
assert (false && "Invalid Opcode.");
case BinaryOperator::Mul:
return getValue( V1 * V2 );
case BinaryOperator::Div:
return getValue( V1 / V2 );
case BinaryOperator::Rem:
return getValue( V1 % V2 );
case BinaryOperator::Add:
return getValue( V1 + V2 );
case BinaryOperator::Sub:
return getValue( V1 - V2 );
case BinaryOperator::Shl:
return getValue( V1.operator<<( (unsigned) V2.getZExtValue() ));
case BinaryOperator::Shr:
return getValue( V1.operator>>( (unsigned) V2.getZExtValue() ));
case BinaryOperator::LT:
return getTruthValue( V1 < V2 );
case BinaryOperator::GT:
return getTruthValue( V1 > V2 );
case BinaryOperator::LE:
return getTruthValue( V1 <= V2 );
case BinaryOperator::GE:
return getTruthValue( V1 >= V2 );
case BinaryOperator::EQ:
return getTruthValue( V1 == V2 );
case BinaryOperator::NE:
return getTruthValue( V1 != V2 );
// Note: LAnd, LOr, Comma are handled specially by higher-level logic.
case BinaryOperator::And:
return getValue( V1 & V2 );
case BinaryOperator::Or:
return getValue( V1 | V2 );
}
}

View File

@ -15,224 +15,9 @@
#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H
#define LLVM_CLANG_ANALYSIS_RVALUE_H
// FIXME: reduce the number of includes.
#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/ASTContext.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/PathSensitive/ValueManager.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Streams.h"
#include <functional>
//==------------------------------------------------------------------------==//
// Values and ValueManager.
//==------------------------------------------------------------------------==//
namespace clang {
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; }
void Profile(llvm::FoldingSetNodeID& ID) const {
assert (isInitialized());
ID.AddInteger(Data);
}
static inline void Profile(llvm::FoldingSetNodeID& ID, SymbolID X) {
X.Profile(ID);
}
};
// SymbolData: Used to record meta data about symbols.
class SymbolData {
public:
enum Kind { UninitKind, ParmKind, ContentsOfKind };
private:
uintptr_t Data;
Kind K;
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 != UninitKind);
return reinterpret_cast<void*>(Data);
}
uintptr_t getInt() const {
assert (K != UninitKind);
return Data;
}
public:
SymbolData() : Data(0), K(UninitKind) {}
Kind getKind() const { return K; }
inline bool operator==(const SymbolData& R) const {
return K == R.K && Data == R.Data;
}
QualType getType() const;
// Implement isa<T> support.
static inline bool classof(const SymbolData*) { return true; }
};
class SymbolDataParmVar : public SymbolData {
public:
SymbolDataParmVar(ParmVarDecl* VD) : SymbolData(VD, ParmKind) {}
ParmVarDecl* getDecl() const { return (ParmVarDecl*) getPtr(); }
// Implement isa<T> support.
static inline bool classof(const SymbolData* D) {
return D->getKind() == ParmKind;
}
};
class SymbolDataContentsOf : public SymbolData {
public:
SymbolDataContentsOf(SymbolID ID) : SymbolData(ID, ContentsOfKind) {}
SymbolID getSymbol() const { return (SymbolID) getInt(); }
// Implement isa<T> support.
static inline bool classof(const SymbolData* D) {
return D->getKind() == ContentsOfKind;
}
};
// Constraints on symbols. Usually wrapped by RValues.
class SymIntConstraint : public llvm::FoldingSetNode {
SymbolID Symbol;
BinaryOperator::Opcode Op;
const llvm::APSInt& Val;
public:
SymIntConstraint(SymbolID sym, BinaryOperator::Opcode op,
const llvm::APSInt& V)
: Symbol(sym),
Op(op), Val(V) {}
BinaryOperator::Opcode getOpcode() const { return Op; }
const SymbolID& getSymbol() const { return Symbol; }
const llvm::APSInt& getInt() const { return Val; }
static inline void Profile(llvm::FoldingSetNodeID& ID,
const SymbolID& Symbol,
BinaryOperator::Opcode Op,
const llvm::APSInt& Val) {
Symbol.Profile(ID);
ID.AddInteger(Op);
ID.AddPointer(&Val);
}
void Profile(llvm::FoldingSetNodeID& ID) {
Profile(ID, Symbol, Op, Val);
}
};
class SymbolManager {
std::vector<SymbolData> SymbolToData;
typedef llvm::DenseMap<void*,SymbolID> MapTy;
MapTy DataToSymbol;
void* getKey(void* P) const {
return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(P) | 0x1);
}
void* getKey(SymbolID sym) const {
return reinterpret_cast<void*>((uintptr_t) (sym << 1));
}
public:
SymbolManager();
~SymbolManager();
SymbolID getSymbol(ParmVarDecl* D);
SymbolID getContentsOfSymbol(SymbolID sym);
inline const SymbolData& getSymbolData(SymbolID ID) const {
assert (ID < SymbolToData.size());
return SymbolToData[ID];
}
inline QualType getType(SymbolID ID) const {
return getSymbolData(ID).getType();
}
};
class ValueManager {
typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
APSIntSetTy;
typedef llvm::FoldingSet<SymIntConstraint>
SymIntCSetTy;
ASTContext& Ctx;
llvm::BumpPtrAllocator& BPAlloc;
APSIntSetTy APSIntSet;
SymIntCSetTy SymIntCSet;
public:
ValueManager(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
: Ctx(ctx), BPAlloc(Alloc) {}
~ValueManager();
ASTContext& getContext() const { return Ctx; }
const llvm::APSInt& getValue(const llvm::APSInt& X);
const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
const llvm::APSInt& getValue(uint64_t X, QualType T,
SourceLocation Loc = SourceLocation());
inline const llvm::APSInt& getZeroWithPtrWidth() {
return getValue( 0,
Ctx.getTypeSize(Ctx.VoidPtrTy, SourceLocation()),
true );
}
inline const llvm::APSInt& getTruthValue(bool b) {
return getValue( b ? 1 : 0,
Ctx.getTypeSize(Ctx.IntTy, SourceLocation()),
false );
}
const SymIntConstraint& getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
const llvm::APSInt& V);
};
} // end clang namespace
//==------------------------------------------------------------------------==//
// Base RValue types.
//==------------------------------------------------------------------------==//

View File

@ -1,53 +0,0 @@
//==- StateVariant.h - Variant to wrap generated analysis states --*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the template class StateVariant, which serves to wrap
// states that are generated by transfer functions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_PS_STATEVARIANT
#define LLVM_CLANG_ANALYSIS_PS_STATEVARIANT
namespace clang {
template<typename StateTy>
class StateVariant {
enum VariantFlag { Infeasible, ImpotentStmt, HasState };
StateTy* State;
VariantFlag Flag;
explicit StateVariant(StateTy* state, VariantFlag f) : State(state), Flag(f){}
public:
StateVariant(StateTy* state) : State(state), Flag(HasState) {}
bool isInfeasible() const { return Flag == Infeasible; }
bool isStmtImpotent() const { return Flag == ImpotentStmt; }
StateTy* getState() const {
assert (!isInfeasible());
return State;
}
// Factory methods to create states indicating infeasible paths or that
// a statement can never modify the program state (from the perspective of
// the analysis).
static inline StateVariant DenoteInfeasiblePath(StateTy* state = NULL) {
return StateVariant(state,Infeasible);
}
static inline StateVariant DenoteImpotentStmt(StateTy* state) {
return StateVariant(state,ImpotentStmt);
}
};
} // end clang namespace
#endif

View File

@ -0,0 +1,173 @@
//== SymbolManager.h - Management of Symbolic Values ------------*- C++ -*--==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This files defines SymbolManager, a class that manages symbolic values
// created for use by GRExprEngine and related classes.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_SYMMGR_H
#define LLVM_CLANG_ANALYSIS_SYMMGR_H
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/DataTypes.h"
#include <vector>
namespace clang {
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; }
void Profile(llvm::FoldingSetNodeID& ID) const {
assert (isInitialized());
ID.AddInteger(Data);
}
static inline void Profile(llvm::FoldingSetNodeID& ID, SymbolID X) {
X.Profile(ID);
}
};
// SymbolData: Used to record meta data about symbols.
class SymbolData {
public:
enum Kind { UninitKind, ParmKind, ContentsOfKind };
private:
uintptr_t Data;
Kind K;
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 != UninitKind);
return reinterpret_cast<void*>(Data);
}
uintptr_t getInt() const {
assert (K != UninitKind);
return Data;
}
public:
SymbolData() : Data(0), K(UninitKind) {}
Kind getKind() const { return K; }
inline bool operator==(const SymbolData& R) const {
return K == R.K && Data == R.Data;
}
QualType getType() const;
// Implement isa<T> support.
static inline bool classof(const SymbolData*) { return true; }
};
class SymbolDataParmVar : public SymbolData {
public:
SymbolDataParmVar(ParmVarDecl* VD) : SymbolData(VD, ParmKind) {}
ParmVarDecl* getDecl() const { return (ParmVarDecl*) getPtr(); }
// Implement isa<T> support.
static inline bool classof(const SymbolData* D) {
return D->getKind() == ParmKind;
}
};
class SymbolDataContentsOf : public SymbolData {
public:
SymbolDataContentsOf(SymbolID ID) : SymbolData(ID, ContentsOfKind) {}
SymbolID getSymbol() const { return (SymbolID) getInt(); }
// Implement isa<T> support.
static inline bool classof(const SymbolData* D) {
return D->getKind() == ContentsOfKind;
}
};
// Constraints on symbols. Usually wrapped by RValues.
class SymIntConstraint : public llvm::FoldingSetNode {
SymbolID Symbol;
BinaryOperator::Opcode Op;
const llvm::APSInt& Val;
public:
SymIntConstraint(SymbolID sym, BinaryOperator::Opcode op,
const llvm::APSInt& V)
: Symbol(sym),
Op(op), Val(V) {}
BinaryOperator::Opcode getOpcode() const { return Op; }
const SymbolID& getSymbol() const { return Symbol; }
const llvm::APSInt& getInt() const { return Val; }
static inline void Profile(llvm::FoldingSetNodeID& ID,
const SymbolID& Symbol,
BinaryOperator::Opcode Op,
const llvm::APSInt& Val) {
Symbol.Profile(ID);
ID.AddInteger(Op);
ID.AddPointer(&Val);
}
void Profile(llvm::FoldingSetNodeID& ID) {
Profile(ID, Symbol, Op, Val);
}
};
class SymbolManager {
std::vector<SymbolData> SymbolToData;
typedef llvm::DenseMap<void*,SymbolID> MapTy;
MapTy DataToSymbol;
void* getKey(void* P) const {
return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(P) | 0x1);
}
void* getKey(SymbolID sym) const {
return reinterpret_cast<void*>((uintptr_t) (sym << 1));
}
public:
SymbolManager();
~SymbolManager();
SymbolID getSymbol(ParmVarDecl* D);
SymbolID getContentsOfSymbol(SymbolID sym);
inline const SymbolData& getSymbolData(SymbolID ID) const {
assert (ID < SymbolToData.size());
return SymbolToData[ID];
}
inline QualType getType(SymbolID ID) const {
return getSymbolData(ID).getType();
}
};
} // end clang namespace
#endif

View File

@ -0,0 +1,79 @@
// ValueManager.h - Low-level value management for Value Tracking -*- C++ -*--==
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This files defines ValueManager, a class that manages the lifetime of APSInt
// objects and symbolic constraints used by GRExprEngine and related classes.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_VALUEMANAGER_H
#define LLVM_CLANG_ANALYSIS_VALUEMANAGER_H
#include "clang/Analysis/PathSensitive/SymbolManager.h"
#include "clang/AST/ASTContext.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/APSInt.h"
namespace llvm {
class BumpPtrAllocator;
}
namespace clang {
class ASTContext;
class ValueManager {
typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> >
APSIntSetTy;
typedef llvm::FoldingSet<SymIntConstraint>
SymIntCSetTy;
ASTContext& Ctx;
llvm::BumpPtrAllocator& BPAlloc;
APSIntSetTy APSIntSet;
SymIntCSetTy SymIntCSet;
public:
ValueManager(ASTContext& ctx, llvm::BumpPtrAllocator& Alloc)
: Ctx(ctx), BPAlloc(Alloc) {}
~ValueManager();
ASTContext& getContext() const { return Ctx; }
const llvm::APSInt& getValue(const llvm::APSInt& X);
const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
const llvm::APSInt& getValue(uint64_t X, QualType T,
SourceLocation Loc = SourceLocation());
inline const llvm::APSInt& getZeroWithPtrWidth() {
return getValue( 0,
Ctx.getTypeSize(Ctx.VoidPtrTy, SourceLocation()),
true );
}
inline const llvm::APSInt& getTruthValue(bool b) {
return getValue( b ? 1 : 0,
Ctx.getTypeSize(Ctx.IntTy, SourceLocation()),
false );
}
const SymIntConstraint& getConstraint(SymbolID sym, BinaryOperator::Opcode Op,
const llvm::APSInt& V);
const llvm::APSInt& EvaluateAPSInt(BinaryOperator::Opcode Op,
const llvm::APSInt& V1,
const llvm::APSInt& V2);
};
} // end clang namespace
#endif