1 //=== BasicValueFactory.h - Basic values for Path Sens analysis --*- 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 BasicValueFactory, a class that manages the lifetime
11 // of APSInt objects and symbolic constraints used by GRExprEngine
12 // and related classes.
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
17 #define LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
19 #include "clang/GR/PathSensitive/SVals.h"
20 #include "clang/AST/ASTContext.h"
21 #include "llvm/ADT/FoldingSet.h"
22 #include "llvm/ADT/APSInt.h"
23 #include "llvm/ADT/ImmutableList.h"
29 class CompoundValData
: public llvm::FoldingSetNode
{
31 llvm::ImmutableList
<SVal
> L
;
34 CompoundValData(QualType t
, llvm::ImmutableList
<SVal
> l
)
37 typedef llvm::ImmutableList
<SVal
>::iterator iterator
;
38 iterator
begin() const { return L
.begin(); }
39 iterator
end() const { return L
.end(); }
41 static void Profile(llvm::FoldingSetNodeID
& ID
, QualType T
,
42 llvm::ImmutableList
<SVal
> L
);
44 void Profile(llvm::FoldingSetNodeID
& ID
) { Profile(ID
, T
, L
); }
47 class LazyCompoundValData
: public llvm::FoldingSetNode
{
49 const TypedRegion
*region
;
51 LazyCompoundValData(const void *st
, const TypedRegion
*r
)
52 : store(st
), region(r
) {}
54 const void *getStore() const { return store
; }
55 const TypedRegion
*getRegion() const { return region
; }
57 static void Profile(llvm::FoldingSetNodeID
& ID
, const void *store
,
58 const TypedRegion
*region
);
60 void Profile(llvm::FoldingSetNodeID
& ID
) { Profile(ID
, store
, region
); }
63 class BasicValueFactory
{
64 typedef llvm::FoldingSet
<llvm::FoldingSetNodeWrapper
<llvm::APSInt
> >
68 llvm::BumpPtrAllocator
& BPAlloc
;
70 APSIntSetTy APSIntSet
;
71 void* PersistentSVals
;
72 void* PersistentSValPairs
;
74 llvm::ImmutableList
<SVal
>::Factory SValListFactory
;
75 llvm::FoldingSet
<CompoundValData
> CompoundValDataSet
;
76 llvm::FoldingSet
<LazyCompoundValData
> LazyCompoundValDataSet
;
79 BasicValueFactory(ASTContext
& ctx
, llvm::BumpPtrAllocator
& Alloc
)
80 : Ctx(ctx
), BPAlloc(Alloc
), PersistentSVals(0), PersistentSValPairs(0),
81 SValListFactory(Alloc
) {}
85 ASTContext
& getContext() const { return Ctx
; }
87 const llvm::APSInt
& getValue(const llvm::APSInt
& X
);
88 const llvm::APSInt
& getValue(const llvm::APInt
& X
, bool isUnsigned
);
89 const llvm::APSInt
& getValue(uint64_t X
, unsigned BitWidth
, bool isUnsigned
);
90 const llvm::APSInt
& getValue(uint64_t X
, QualType T
);
92 /// Convert - Create a new persistent APSInt with the same value as 'From'
93 /// but with the bitwidth and signedness of 'To'.
94 const llvm::APSInt
&Convert(const llvm::APSInt
& To
,
95 const llvm::APSInt
& From
) {
97 if (To
.isUnsigned() == From
.isUnsigned() &&
98 To
.getBitWidth() == From
.getBitWidth())
101 return getValue(From
.getSExtValue(), To
.getBitWidth(), To
.isUnsigned());
104 const llvm::APSInt
&Convert(QualType T
, const llvm::APSInt
&From
) {
105 assert(T
->isIntegerType() || Loc::IsLocType(T
));
106 unsigned bitwidth
= Ctx
.getTypeSize(T
);
107 bool isUnsigned
= T
->isUnsignedIntegerType() || Loc::IsLocType(T
);
109 if (isUnsigned
== From
.isUnsigned() && bitwidth
== From
.getBitWidth())
112 return getValue(From
.getSExtValue(), bitwidth
, isUnsigned
);
115 const llvm::APSInt
& getIntValue(uint64_t X
, bool isUnsigned
) {
116 QualType T
= isUnsigned
? Ctx
.UnsignedIntTy
: Ctx
.IntTy
;
117 return getValue(X
, T
);
120 inline const llvm::APSInt
& getMaxValue(const llvm::APSInt
&v
) {
121 return getValue(llvm::APSInt::getMaxValue(v
.getBitWidth(), v
.isUnsigned()));
124 inline const llvm::APSInt
& getMinValue(const llvm::APSInt
&v
) {
125 return getValue(llvm::APSInt::getMinValue(v
.getBitWidth(), v
.isUnsigned()));
128 inline const llvm::APSInt
& getMaxValue(QualType T
) {
129 assert(T
->isIntegerType() || Loc::IsLocType(T
));
130 bool isUnsigned
= T
->isUnsignedIntegerType() || Loc::IsLocType(T
);
131 return getValue(llvm::APSInt::getMaxValue(Ctx
.getTypeSize(T
), isUnsigned
));
134 inline const llvm::APSInt
& getMinValue(QualType T
) {
135 assert(T
->isIntegerType() || Loc::IsLocType(T
));
136 bool isUnsigned
= T
->isUnsignedIntegerType() || Loc::IsLocType(T
);
137 return getValue(llvm::APSInt::getMinValue(Ctx
.getTypeSize(T
), isUnsigned
));
140 inline const llvm::APSInt
& Add1(const llvm::APSInt
& V
) {
146 inline const llvm::APSInt
& Sub1(const llvm::APSInt
& V
) {
152 inline const llvm::APSInt
& getZeroWithPtrWidth(bool isUnsigned
= true) {
153 return getValue(0, Ctx
.getTypeSize(Ctx
.VoidPtrTy
), isUnsigned
);
156 inline const llvm::APSInt
&getIntWithPtrWidth(uint64_t X
, bool isUnsigned
) {
157 return getValue(X
, Ctx
.getTypeSize(Ctx
.VoidPtrTy
), isUnsigned
);
160 inline const llvm::APSInt
& getTruthValue(bool b
, QualType T
) {
161 return getValue(b
? 1 : 0, Ctx
.getTypeSize(T
), false);
164 inline const llvm::APSInt
& getTruthValue(bool b
) {
165 return getTruthValue(b
, Ctx
.IntTy
);
168 const CompoundValData
*getCompoundValData(QualType T
,
169 llvm::ImmutableList
<SVal
> Vals
);
171 const LazyCompoundValData
*getLazyCompoundValData(const void *store
,
172 const TypedRegion
*region
);
174 llvm::ImmutableList
<SVal
> getEmptySValList() {
175 return SValListFactory
.getEmptyList();
178 llvm::ImmutableList
<SVal
> consVals(SVal X
, llvm::ImmutableList
<SVal
> L
) {
179 return SValListFactory
.add(X
, L
);
182 const llvm::APSInt
* evalAPSInt(BinaryOperator::Opcode Op
,
183 const llvm::APSInt
& V1
,
184 const llvm::APSInt
& V2
);
186 const std::pair
<SVal
, uintptr_t>&
187 getPersistentSValWithData(const SVal
& V
, uintptr_t Data
);
189 const std::pair
<SVal
, SVal
>&
190 getPersistentSValPair(const SVal
& V1
, const SVal
& V2
);
192 const SVal
* getPersistentSVal(SVal X
);
195 } // end clang namespace