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