BasicValueFactory.h revision 226633
1218887Sdim//=== BasicValueFactory.h - Basic values for Path Sens analysis --*- C++ -*---// 2218887Sdim// 3218887Sdim// The LLVM Compiler Infrastructure 4218887Sdim// 5218887Sdim// This file is distributed under the University of Illinois Open Source 6218887Sdim// License. See LICENSE.TXT for details. 7218887Sdim// 8218887Sdim//===----------------------------------------------------------------------===// 9218887Sdim// 10218887Sdim// This file defines BasicValueFactory, a class that manages the lifetime 11218887Sdim// of APSInt objects and symbolic constraints used by ExprEngine 12218887Sdim// and related classes. 13218887Sdim// 14218887Sdim//===----------------------------------------------------------------------===// 15218887Sdim 16218887Sdim#ifndef LLVM_CLANG_GR_BASICVALUEFACTORY_H 17218887Sdim#define LLVM_CLANG_GR_BASICVALUEFACTORY_H 18218887Sdim 19221345Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h" 20218887Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 21218887Sdim#include "clang/AST/ASTContext.h" 22218887Sdim#include "llvm/ADT/FoldingSet.h" 23218887Sdim#include "llvm/ADT/APSInt.h" 24218887Sdim#include "llvm/ADT/ImmutableList.h" 25218887Sdim 26218887Sdimnamespace clang { 27218887Sdim 28218887Sdimnamespace ento { 29218887Sdim 30226633Sdimclass ProgramState; 31218887Sdim 32218887Sdimclass CompoundValData : public llvm::FoldingSetNode { 33218887Sdim QualType T; 34218887Sdim llvm::ImmutableList<SVal> L; 35218887Sdim 36218887Sdimpublic: 37218887Sdim CompoundValData(QualType t, llvm::ImmutableList<SVal> l) 38218887Sdim : T(t), L(l) {} 39218887Sdim 40218887Sdim typedef llvm::ImmutableList<SVal>::iterator iterator; 41218887Sdim iterator begin() const { return L.begin(); } 42218887Sdim iterator end() const { return L.end(); } 43218887Sdim 44218887Sdim static void Profile(llvm::FoldingSetNodeID& ID, QualType T, 45218887Sdim llvm::ImmutableList<SVal> L); 46218887Sdim 47218887Sdim void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, T, L); } 48218887Sdim}; 49218887Sdim 50218887Sdimclass LazyCompoundValData : public llvm::FoldingSetNode { 51221345Sdim StoreRef store; 52226633Sdim const TypedValueRegion *region; 53218887Sdimpublic: 54226633Sdim LazyCompoundValData(const StoreRef &st, const TypedValueRegion *r) 55218887Sdim : store(st), region(r) {} 56218887Sdim 57221345Sdim const void *getStore() const { return store.getStore(); } 58226633Sdim const TypedValueRegion *getRegion() const { return region; } 59218887Sdim 60221345Sdim static void Profile(llvm::FoldingSetNodeID& ID, 61221345Sdim const StoreRef &store, 62226633Sdim const TypedValueRegion *region); 63218887Sdim 64218887Sdim void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); } 65218887Sdim}; 66218887Sdim 67218887Sdimclass BasicValueFactory { 68218887Sdim typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> > 69218887Sdim APSIntSetTy; 70218887Sdim 71226633Sdim ASTContext &Ctx; 72218887Sdim llvm::BumpPtrAllocator& BPAlloc; 73218887Sdim 74218887Sdim APSIntSetTy APSIntSet; 75226633Sdim void * PersistentSVals; 76226633Sdim void * PersistentSValPairs; 77218887Sdim 78218887Sdim llvm::ImmutableList<SVal>::Factory SValListFactory; 79218887Sdim llvm::FoldingSet<CompoundValData> CompoundValDataSet; 80218887Sdim llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet; 81218887Sdim 82218887Sdimpublic: 83226633Sdim BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator& Alloc) 84218887Sdim : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0), 85218887Sdim SValListFactory(Alloc) {} 86218887Sdim 87218887Sdim ~BasicValueFactory(); 88218887Sdim 89226633Sdim ASTContext &getContext() const { return Ctx; } 90218887Sdim 91218887Sdim const llvm::APSInt& getValue(const llvm::APSInt& X); 92218887Sdim const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned); 93218887Sdim const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned); 94218887Sdim const llvm::APSInt& getValue(uint64_t X, QualType T); 95218887Sdim 96218887Sdim /// Convert - Create a new persistent APSInt with the same value as 'From' 97218887Sdim /// but with the bitwidth and signedness of 'To'. 98218887Sdim const llvm::APSInt &Convert(const llvm::APSInt& To, 99218887Sdim const llvm::APSInt& From) { 100218887Sdim 101218887Sdim if (To.isUnsigned() == From.isUnsigned() && 102218887Sdim To.getBitWidth() == From.getBitWidth()) 103218887Sdim return From; 104218887Sdim 105218887Sdim return getValue(From.getSExtValue(), To.getBitWidth(), To.isUnsigned()); 106218887Sdim } 107218887Sdim 108218887Sdim const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) { 109218887Sdim assert(T->isIntegerType() || Loc::isLocType(T)); 110218887Sdim unsigned bitwidth = Ctx.getTypeSize(T); 111223017Sdim bool isUnsigned 112223017Sdim = T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T); 113218887Sdim 114218887Sdim if (isUnsigned == From.isUnsigned() && bitwidth == From.getBitWidth()) 115218887Sdim return From; 116218887Sdim 117218887Sdim return getValue(From.getSExtValue(), bitwidth, isUnsigned); 118218887Sdim } 119218887Sdim 120218887Sdim const llvm::APSInt& getIntValue(uint64_t X, bool isUnsigned) { 121218887Sdim QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy; 122218887Sdim return getValue(X, T); 123218887Sdim } 124218887Sdim 125218887Sdim inline const llvm::APSInt& getMaxValue(const llvm::APSInt &v) { 126218887Sdim return getValue(llvm::APSInt::getMaxValue(v.getBitWidth(), v.isUnsigned())); 127218887Sdim } 128218887Sdim 129218887Sdim inline const llvm::APSInt& getMinValue(const llvm::APSInt &v) { 130218887Sdim return getValue(llvm::APSInt::getMinValue(v.getBitWidth(), v.isUnsigned())); 131218887Sdim } 132218887Sdim 133218887Sdim inline const llvm::APSInt& getMaxValue(QualType T) { 134218887Sdim assert(T->isIntegerType() || Loc::isLocType(T)); 135223017Sdim bool isUnsigned 136223017Sdim = T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T); 137218887Sdim return getValue(llvm::APSInt::getMaxValue(Ctx.getTypeSize(T), isUnsigned)); 138218887Sdim } 139218887Sdim 140218887Sdim inline const llvm::APSInt& getMinValue(QualType T) { 141218887Sdim assert(T->isIntegerType() || Loc::isLocType(T)); 142223017Sdim bool isUnsigned 143223017Sdim = T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T); 144218887Sdim return getValue(llvm::APSInt::getMinValue(Ctx.getTypeSize(T), isUnsigned)); 145218887Sdim } 146218887Sdim 147218887Sdim inline const llvm::APSInt& Add1(const llvm::APSInt& V) { 148218887Sdim llvm::APSInt X = V; 149218887Sdim ++X; 150218887Sdim return getValue(X); 151218887Sdim } 152218887Sdim 153218887Sdim inline const llvm::APSInt& Sub1(const llvm::APSInt& V) { 154218887Sdim llvm::APSInt X = V; 155218887Sdim --X; 156218887Sdim return getValue(X); 157218887Sdim } 158218887Sdim 159218887Sdim inline const llvm::APSInt& getZeroWithPtrWidth(bool isUnsigned = true) { 160218887Sdim return getValue(0, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned); 161218887Sdim } 162218887Sdim 163218887Sdim inline const llvm::APSInt &getIntWithPtrWidth(uint64_t X, bool isUnsigned) { 164218887Sdim return getValue(X, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned); 165218887Sdim } 166218887Sdim 167218887Sdim inline const llvm::APSInt& getTruthValue(bool b, QualType T) { 168218887Sdim return getValue(b ? 1 : 0, Ctx.getTypeSize(T), false); 169218887Sdim } 170218887Sdim 171218887Sdim inline const llvm::APSInt& getTruthValue(bool b) { 172218887Sdim return getTruthValue(b, Ctx.getLogicalOperationType()); 173218887Sdim } 174218887Sdim 175218887Sdim const CompoundValData *getCompoundValData(QualType T, 176218887Sdim llvm::ImmutableList<SVal> Vals); 177218887Sdim 178221345Sdim const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store, 179226633Sdim const TypedValueRegion *region); 180218887Sdim 181218887Sdim llvm::ImmutableList<SVal> getEmptySValList() { 182218887Sdim return SValListFactory.getEmptyList(); 183218887Sdim } 184218887Sdim 185218887Sdim llvm::ImmutableList<SVal> consVals(SVal X, llvm::ImmutableList<SVal> L) { 186218887Sdim return SValListFactory.add(X, L); 187218887Sdim } 188218887Sdim 189218887Sdim const llvm::APSInt* evalAPSInt(BinaryOperator::Opcode Op, 190218887Sdim const llvm::APSInt& V1, 191218887Sdim const llvm::APSInt& V2); 192218887Sdim 193218887Sdim const std::pair<SVal, uintptr_t>& 194218887Sdim getPersistentSValWithData(const SVal& V, uintptr_t Data); 195218887Sdim 196218887Sdim const std::pair<SVal, SVal>& 197218887Sdim getPersistentSValPair(const SVal& V1, const SVal& V2); 198218887Sdim 199218887Sdim const SVal* getPersistentSVal(SVal X); 200218887Sdim}; 201218887Sdim 202218887Sdim} // end GR namespace 203218887Sdim 204218887Sdim} // end clang namespace 205218887Sdim 206218887Sdim#endif 207