clang API Documentation
00001 //=== BasicValueFactory.h - Basic values for Path Sens analysis --*- C++ -*---// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines BasicValueFactory, a class that manages the lifetime 00011 // of APSInt objects and symbolic constraints used by ExprEngine 00012 // and related classes. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #ifndef LLVM_CLANG_GR_BASICVALUEFACTORY_H 00017 #define LLVM_CLANG_GR_BASICVALUEFACTORY_H 00018 00019 #include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h" 00020 #include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h" 00021 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 00022 00023 namespace clang { 00024 namespace ento { 00025 00026 class CompoundValData : public llvm::FoldingSetNode { 00027 QualType T; 00028 llvm::ImmutableList<SVal> L; 00029 00030 public: 00031 CompoundValData(QualType t, llvm::ImmutableList<SVal> l) 00032 : T(t), L(l) {} 00033 00034 typedef llvm::ImmutableList<SVal>::iterator iterator; 00035 iterator begin() const { return L.begin(); } 00036 iterator end() const { return L.end(); } 00037 00038 static void Profile(llvm::FoldingSetNodeID& ID, QualType T, 00039 llvm::ImmutableList<SVal> L); 00040 00041 void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, T, L); } 00042 }; 00043 00044 class LazyCompoundValData : public llvm::FoldingSetNode { 00045 StoreRef store; 00046 const TypedValueRegion *region; 00047 public: 00048 LazyCompoundValData(const StoreRef &st, const TypedValueRegion *r) 00049 : store(st), region(r) {} 00050 00051 const void *getStore() const { return store.getStore(); } 00052 const TypedValueRegion *getRegion() const { return region; } 00053 00054 static void Profile(llvm::FoldingSetNodeID& ID, 00055 const StoreRef &store, 00056 const TypedValueRegion *region); 00057 00058 void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); } 00059 }; 00060 00061 class BasicValueFactory { 00062 typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> > 00063 APSIntSetTy; 00064 00065 ASTContext &Ctx; 00066 llvm::BumpPtrAllocator& BPAlloc; 00067 00068 APSIntSetTy APSIntSet; 00069 void * PersistentSVals; 00070 void * PersistentSValPairs; 00071 00072 llvm::ImmutableList<SVal>::Factory SValListFactory; 00073 llvm::FoldingSet<CompoundValData> CompoundValDataSet; 00074 llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet; 00075 00076 public: 00077 BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator& Alloc) 00078 : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0), 00079 SValListFactory(Alloc) {} 00080 00081 ~BasicValueFactory(); 00082 00083 ASTContext &getContext() const { return Ctx; } 00084 00085 const llvm::APSInt& getValue(const llvm::APSInt& X); 00086 const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned); 00087 const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned); 00088 const llvm::APSInt& getValue(uint64_t X, QualType T); 00089 00090 /// Returns the type of the APSInt used to store values of the given QualType. 00091 APSIntType getAPSIntType(QualType T) const { 00092 assert(T->isIntegerType() || Loc::isLocType(T)); 00093 return APSIntType(Ctx.getTypeSize(T), 00094 !T->isSignedIntegerOrEnumerationType()); 00095 } 00096 00097 /// Convert - Create a new persistent APSInt with the same value as 'From' 00098 /// but with the bitwidth and signedness of 'To'. 00099 const llvm::APSInt &Convert(const llvm::APSInt& To, 00100 const llvm::APSInt& From) { 00101 APSIntType TargetType(To); 00102 if (TargetType == APSIntType(From)) 00103 return From; 00104 00105 return getValue(TargetType.convert(From)); 00106 } 00107 00108 const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) { 00109 APSIntType TargetType = getAPSIntType(T); 00110 if (TargetType == APSIntType(From)) 00111 return From; 00112 00113 return getValue(TargetType.convert(From)); 00114 } 00115 00116 const llvm::APSInt& getIntValue(uint64_t X, bool isUnsigned) { 00117 QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy; 00118 return getValue(X, T); 00119 } 00120 00121 inline const llvm::APSInt& getMaxValue(const llvm::APSInt &v) { 00122 return getValue(APSIntType(v).getMaxValue()); 00123 } 00124 00125 inline const llvm::APSInt& getMinValue(const llvm::APSInt &v) { 00126 return getValue(APSIntType(v).getMinValue()); 00127 } 00128 00129 inline const llvm::APSInt& getMaxValue(QualType T) { 00130 return getValue(getAPSIntType(T).getMaxValue()); 00131 } 00132 00133 inline const llvm::APSInt& getMinValue(QualType T) { 00134 return getValue(getAPSIntType(T).getMinValue()); 00135 } 00136 00137 inline const llvm::APSInt& Add1(const llvm::APSInt& V) { 00138 llvm::APSInt X = V; 00139 ++X; 00140 return getValue(X); 00141 } 00142 00143 inline const llvm::APSInt& Sub1(const llvm::APSInt& V) { 00144 llvm::APSInt X = V; 00145 --X; 00146 return getValue(X); 00147 } 00148 00149 inline const llvm::APSInt& getZeroWithPtrWidth(bool isUnsigned = true) { 00150 return getValue(0, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned); 00151 } 00152 00153 inline const llvm::APSInt &getIntWithPtrWidth(uint64_t X, bool isUnsigned) { 00154 return getValue(X, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned); 00155 } 00156 00157 inline const llvm::APSInt& getTruthValue(bool b, QualType T) { 00158 return getValue(b ? 1 : 0, Ctx.getTypeSize(T), false); 00159 } 00160 00161 inline const llvm::APSInt& getTruthValue(bool b) { 00162 return getTruthValue(b, Ctx.getLogicalOperationType()); 00163 } 00164 00165 const CompoundValData *getCompoundValData(QualType T, 00166 llvm::ImmutableList<SVal> Vals); 00167 00168 const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store, 00169 const TypedValueRegion *region); 00170 00171 llvm::ImmutableList<SVal> getEmptySValList() { 00172 return SValListFactory.getEmptyList(); 00173 } 00174 00175 llvm::ImmutableList<SVal> consVals(SVal X, llvm::ImmutableList<SVal> L) { 00176 return SValListFactory.add(X, L); 00177 } 00178 00179 const llvm::APSInt* evalAPSInt(BinaryOperator::Opcode Op, 00180 const llvm::APSInt& V1, 00181 const llvm::APSInt& V2); 00182 00183 const std::pair<SVal, uintptr_t>& 00184 getPersistentSValWithData(const SVal& V, uintptr_t Data); 00185 00186 const std::pair<SVal, SVal>& 00187 getPersistentSValPair(const SVal& V1, const SVal& V2); 00188 00189 const SVal* getPersistentSVal(SVal X); 00190 }; 00191 00192 } // end GR namespace 00193 00194 } // end clang namespace 00195 00196 #endif