1 // SValBuilder.h - Construction of SVals from evaluating expressions -*- C++ -*-
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines SValBuilder, a class that defines the interface for
11 // "symbolical evaluators" which construct an SVal from an expression.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_ANALYSIS_SVALBUILDER
16 #define LLVM_CLANG_ANALYSIS_SVALBUILDER
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/GR/PathSensitive/SVals.h"
21 #include "clang/GR/PathSensitive/BasicValueFactory.h"
22 #include "clang/GR/PathSensitive/MemRegion.h"
32 /// Manager of APSInt values.
33 BasicValueFactory BasicVals
;
35 /// Manages the creation of symbols.
38 /// Manages the creation of memory regions.
39 MemRegionManager MemMgr
;
41 GRStateManager
&StateMgr
;
43 /// The scalar type to use for array indices.
44 const QualType ArrayIndexTy
;
46 /// The width of the scalar type used for array indices.
47 const unsigned ArrayIndexWidth
;
50 // FIXME: Make these protected again one RegionStoreManager correctly
51 // handles loads from differening bound value types.
52 virtual SVal
evalCastNL(NonLoc val
, QualType castTy
) = 0;
53 virtual SVal
evalCastL(Loc val
, QualType castTy
) = 0;
56 SValBuilder(llvm::BumpPtrAllocator
&alloc
, ASTContext
&context
,
57 GRStateManager
&stateMgr
)
58 : Context(context
), BasicVals(context
, alloc
),
59 SymMgr(context
, BasicVals
, alloc
),
60 MemMgr(context
, alloc
),
62 ArrayIndexTy(context
.IntTy
),
63 ArrayIndexWidth(context
.getTypeSize(ArrayIndexTy
)) {}
65 virtual ~SValBuilder() {}
67 SVal
evalCast(SVal V
, QualType castTy
, QualType originalType
);
69 virtual SVal
evalMinus(NonLoc val
) = 0;
71 virtual SVal
evalComplement(NonLoc val
) = 0;
73 virtual SVal
evalBinOpNN(const GRState
*state
, BinaryOperator::Opcode Op
,
74 NonLoc lhs
, NonLoc rhs
, QualType resultTy
) = 0;
76 virtual SVal
evalBinOpLL(const GRState
*state
, BinaryOperator::Opcode Op
,
77 Loc lhs
, Loc rhs
, QualType resultTy
) = 0;
79 virtual SVal
evalBinOpLN(const GRState
*state
, BinaryOperator::Opcode Op
,
80 Loc lhs
, NonLoc rhs
, QualType resultTy
) = 0;
82 /// getKnownValue - evaluates a given SVal. If the SVal has only one possible
83 /// (integer) value, that value is returned. Otherwise, returns NULL.
84 virtual const llvm::APSInt
*getKnownValue(const GRState
*state
, SVal V
) = 0;
86 SVal
evalBinOp(const GRState
*ST
, BinaryOperator::Opcode Op
,
87 SVal L
, SVal R
, QualType T
);
89 DefinedOrUnknownSVal
evalEQ(const GRState
*ST
, DefinedOrUnknownSVal L
,
90 DefinedOrUnknownSVal R
);
92 ASTContext
&getContext() { return Context
; }
93 const ASTContext
&getContext() const { return Context
; }
95 GRStateManager
&getStateManager() { return StateMgr
; }
97 BasicValueFactory
&getBasicValueFactory() { return BasicVals
; }
98 const BasicValueFactory
&getBasicValueFactory() const { return BasicVals
; }
100 SymbolManager
&getSymbolManager() { return SymMgr
; }
101 const SymbolManager
&getSymbolManager() const { return SymMgr
; }
103 MemRegionManager
&getRegionManager() { return MemMgr
; }
104 const MemRegionManager
&getRegionManager() const { return MemMgr
; }
106 // Forwarding methods to SymbolManager.
108 const SymbolConjured
* getConjuredSymbol(const Stmt
* E
, QualType T
,
110 const void* SymbolTag
= 0) {
111 return SymMgr
.getConjuredSymbol(E
, T
, VisitCount
, SymbolTag
);
114 const SymbolConjured
* getConjuredSymbol(const Expr
* E
, unsigned VisitCount
,
115 const void* SymbolTag
= 0) {
116 return SymMgr
.getConjuredSymbol(E
, VisitCount
, SymbolTag
);
119 /// makeZeroVal - Construct an SVal representing '0' for the specified type.
120 DefinedOrUnknownSVal
makeZeroVal(QualType T
);
122 /// getRegionValueSymbolVal - make a unique symbol for value of R.
123 DefinedOrUnknownSVal
getRegionValueSymbolVal(const TypedRegion
*R
);
125 DefinedOrUnknownSVal
getConjuredSymbolVal(const void *SymbolTag
,
126 const Expr
*E
, unsigned Count
);
127 DefinedOrUnknownSVal
getConjuredSymbolVal(const void *SymbolTag
,
128 const Expr
*E
, QualType T
,
131 DefinedOrUnknownSVal
getDerivedRegionValueSymbolVal(SymbolRef parentSymbol
,
132 const TypedRegion
*R
);
134 DefinedSVal
getMetadataSymbolVal(const void *SymbolTag
, const MemRegion
*MR
,
135 const Expr
*E
, QualType T
, unsigned Count
);
137 DefinedSVal
getFunctionPointer(const FunctionDecl
*FD
);
139 DefinedSVal
getBlockPointer(const BlockDecl
*BD
, CanQualType locTy
,
140 const LocationContext
*LC
);
142 NonLoc
makeCompoundVal(QualType T
, llvm::ImmutableList
<SVal
> Vals
) {
143 return nonloc::CompoundVal(BasicVals
.getCompoundValData(T
, Vals
));
146 NonLoc
makeLazyCompoundVal(const void *store
, const TypedRegion
*R
) {
147 return nonloc::LazyCompoundVal(BasicVals
.getLazyCompoundValData(store
, R
));
150 NonLoc
makeZeroArrayIndex() {
151 return nonloc::ConcreteInt(BasicVals
.getValue(0, ArrayIndexTy
));
154 NonLoc
makeArrayIndex(uint64_t idx
) {
155 return nonloc::ConcreteInt(BasicVals
.getValue(idx
, ArrayIndexTy
));
158 SVal
convertToArrayIndex(SVal V
);
160 nonloc::ConcreteInt
makeIntVal(const IntegerLiteral
* I
) {
161 return nonloc::ConcreteInt(BasicVals
.getValue(I
->getValue(),
162 I
->getType()->isUnsignedIntegerType()));
165 nonloc::ConcreteInt
makeIntVal(const CXXBoolLiteralExpr
*E
) {
166 return E
->getValue() ? nonloc::ConcreteInt(BasicVals
.getValue(1, 1, true))
167 : nonloc::ConcreteInt(BasicVals
.getValue(0, 1, true));
170 nonloc::ConcreteInt
makeIntVal(const llvm::APSInt
& V
) {
171 return nonloc::ConcreteInt(BasicVals
.getValue(V
));
174 loc::ConcreteInt
makeIntLocVal(const llvm::APSInt
&v
) {
175 return loc::ConcreteInt(BasicVals
.getValue(v
));
178 NonLoc
makeIntVal(const llvm::APInt
& V
, bool isUnsigned
) {
179 return nonloc::ConcreteInt(BasicVals
.getValue(V
, isUnsigned
));
182 DefinedSVal
makeIntVal(uint64_t X
, QualType T
) {
183 if (Loc::IsLocType(T
))
184 return loc::ConcreteInt(BasicVals
.getValue(X
, T
));
186 return nonloc::ConcreteInt(BasicVals
.getValue(X
, T
));
189 NonLoc
makeIntVal(uint64_t X
, bool isUnsigned
) {
190 return nonloc::ConcreteInt(BasicVals
.getIntValue(X
, isUnsigned
));
193 NonLoc
makeIntValWithPtrWidth(uint64_t X
, bool isUnsigned
) {
194 return nonloc::ConcreteInt(BasicVals
.getIntWithPtrWidth(X
, isUnsigned
));
197 NonLoc
makeIntVal(uint64_t X
, unsigned BitWidth
, bool isUnsigned
) {
198 return nonloc::ConcreteInt(BasicVals
.getValue(X
, BitWidth
, isUnsigned
));
201 NonLoc
makeLocAsInteger(Loc V
, unsigned Bits
) {
202 return nonloc::LocAsInteger(BasicVals
.getPersistentSValWithData(V
, Bits
));
205 NonLoc
makeNonLoc(const SymExpr
*lhs
, BinaryOperator::Opcode op
,
206 const llvm::APSInt
& rhs
, QualType T
);
208 NonLoc
makeNonLoc(const SymExpr
*lhs
, BinaryOperator::Opcode op
,
209 const SymExpr
*rhs
, QualType T
);
211 NonLoc
makeTruthVal(bool b
, QualType T
) {
212 return nonloc::ConcreteInt(BasicVals
.getTruthValue(b
, T
));
215 NonLoc
makeTruthVal(bool b
) {
216 return nonloc::ConcreteInt(BasicVals
.getTruthValue(b
));
220 return loc::ConcreteInt(BasicVals
.getZeroWithPtrWidth());
223 Loc
makeLoc(SymbolRef Sym
) {
224 return loc::MemRegionVal(MemMgr
.getSymbolicRegion(Sym
));
227 Loc
makeLoc(const MemRegion
* R
) {
228 return loc::MemRegionVal(R
);
231 Loc
makeLoc(const AddrLabelExpr
* E
) {
232 return loc::GotoLabel(E
->getLabel());
235 Loc
makeLoc(const llvm::APSInt
& V
) {
236 return loc::ConcreteInt(BasicVals
.getValue(V
));
241 SValBuilder
* createSimpleSValBuilder(llvm::BumpPtrAllocator
&alloc
,
243 GRStateManager
&stateMgr
);
245 } // end clang namespace