BasicValueFactory.h revision 226633
141502Swpaul//=== BasicValueFactory.h - Basic values for Path Sens analysis --*- C++ -*---// 241502Swpaul// 341502Swpaul// The LLVM Compiler Infrastructure 441502Swpaul// 541502Swpaul// This file is distributed under the University of Illinois Open Source 641502Swpaul// License. See LICENSE.TXT for details. 741502Swpaul// 841502Swpaul//===----------------------------------------------------------------------===// 941502Swpaul// 1041502Swpaul// This file defines BasicValueFactory, a class that manages the lifetime 1141502Swpaul// of APSInt objects and symbolic constraints used by ExprEngine 1241502Swpaul// and related classes. 1341502Swpaul// 1441502Swpaul//===----------------------------------------------------------------------===// 1541502Swpaul 1641502Swpaul#ifndef LLVM_CLANG_GR_BASICVALUEFACTORY_H 1741502Swpaul#define LLVM_CLANG_GR_BASICVALUEFACTORY_H 1841502Swpaul 1941502Swpaul#include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h" 2041502Swpaul#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 2141502Swpaul#include "clang/AST/ASTContext.h" 2241502Swpaul#include "llvm/ADT/FoldingSet.h" 2341502Swpaul#include "llvm/ADT/APSInt.h" 2441502Swpaul#include "llvm/ADT/ImmutableList.h" 2541502Swpaul 2641502Swpaulnamespace clang { 2741502Swpaul 2841502Swpaulnamespace ento { 2941502Swpaul 3041502Swpaulclass ProgramState; 3141502Swpaul 3241502Swpaulclass CompoundValData : public llvm::FoldingSetNode { 3341502Swpaul QualType T; 3441502Swpaul llvm::ImmutableList<SVal> L; 3541502Swpaul 3641502Swpaulpublic: 3741502Swpaul CompoundValData(QualType t, llvm::ImmutableList<SVal> l) 3841502Swpaul : T(t), L(l) {} 3941502Swpaul 4041502Swpaul typedef llvm::ImmutableList<SVal>::iterator iterator; 4141502Swpaul iterator begin() const { return L.begin(); } 4241502Swpaul iterator end() const { return L.end(); } 4341502Swpaul 4441502Swpaul static void Profile(llvm::FoldingSetNodeID& ID, QualType T, 4541502Swpaul llvm::ImmutableList<SVal> L); 4641502Swpaul 4741502Swpaul void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, T, L); } 4841502Swpaul}; 4941502Swpaul 5041502Swpaulclass LazyCompoundValData : public llvm::FoldingSetNode { 5141502Swpaul StoreRef store; 5241502Swpaul const TypedValueRegion *region; 5341502Swpaulpublic: 5441502Swpaul LazyCompoundValData(const StoreRef &st, const TypedValueRegion *r) 5541502Swpaul : store(st), region(r) {} 5641502Swpaul 5741502Swpaul const void *getStore() const { return store.getStore(); } 5841502Swpaul const TypedValueRegion *getRegion() const { return region; } 5941502Swpaul 6041502Swpaul static void Profile(llvm::FoldingSetNodeID& ID, 6141502Swpaul const StoreRef &store, 6241502Swpaul const TypedValueRegion *region); 6341502Swpaul 6441502Swpaul void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, store, region); } 6541502Swpaul}; 6641502Swpaul 6741502Swpaulclass BasicValueFactory { 6841502Swpaul typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<llvm::APSInt> > 6941502Swpaul APSIntSetTy; 7041502Swpaul 7141502Swpaul ASTContext &Ctx; 7241502Swpaul llvm::BumpPtrAllocator& BPAlloc; 7341502Swpaul 7441502Swpaul APSIntSetTy APSIntSet; 7541502Swpaul void * PersistentSVals; 7641502Swpaul void * PersistentSValPairs; 7741502Swpaul 7841502Swpaul llvm::ImmutableList<SVal>::Factory SValListFactory; 7941502Swpaul llvm::FoldingSet<CompoundValData> CompoundValDataSet; 8041502Swpaul llvm::FoldingSet<LazyCompoundValData> LazyCompoundValDataSet; 8141502Swpaul 8241502Swpaulpublic: 8341502Swpaul BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator& Alloc) 84113038Sobrien : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0), 85113038Sobrien SValListFactory(Alloc) {} 86113038Sobrien 8748745Swpaul ~BasicValueFactory(); 8841502Swpaul 8941502Swpaul ASTContext &getContext() const { return Ctx; } 9041502Swpaul 9141502Swpaul const llvm::APSInt& getValue(const llvm::APSInt& X); 9241502Swpaul const llvm::APSInt& getValue(const llvm::APInt& X, bool isUnsigned); 9341502Swpaul const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned); 9441502Swpaul const llvm::APSInt& getValue(uint64_t X, QualType T); 9541502Swpaul 9650675Swpaul /// Convert - Create a new persistent APSInt with the same value as 'From' 9741502Swpaul /// but with the bitwidth and signedness of 'To'. 9841502Swpaul const llvm::APSInt &Convert(const llvm::APSInt& To, 9941502Swpaul const llvm::APSInt& From) { 10041502Swpaul 10141502Swpaul if (To.isUnsigned() == From.isUnsigned() && 10241502Swpaul To.getBitWidth() == From.getBitWidth()) 10341502Swpaul return From; 10441502Swpaul 10541502Swpaul return getValue(From.getSExtValue(), To.getBitWidth(), To.isUnsigned()); 10641502Swpaul } 10741502Swpaul 10841502Swpaul const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) { 10941502Swpaul assert(T->isIntegerType() || Loc::isLocType(T)); 11041502Swpaul unsigned bitwidth = Ctx.getTypeSize(T); 11149611Swpaul bool isUnsigned 11249611Swpaul = T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T); 11349611Swpaul 11441502Swpaul if (isUnsigned == From.isUnsigned() && bitwidth == From.getBitWidth()) 11541502Swpaul return From; 11641502Swpaul 11741502Swpaul return getValue(From.getSExtValue(), bitwidth, isUnsigned); 11850675Swpaul } 11950675Swpaul 12050675Swpaul const llvm::APSInt& getIntValue(uint64_t X, bool isUnsigned) { 12151089Speter QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy; 12250675Swpaul return getValue(X, T); 12350675Swpaul } 12441502Swpaul 12541502Swpaul inline const llvm::APSInt& getMaxValue(const llvm::APSInt &v) { 12641502Swpaul return getValue(llvm::APSInt::getMaxValue(v.getBitWidth(), v.isUnsigned())); 12741502Swpaul } 128113506Smdodd 129113506Smdodd inline const llvm::APSInt& getMinValue(const llvm::APSInt &v) { 13059758Speter return getValue(llvm::APSInt::getMinValue(v.getBitWidth(), v.isUnsigned())); 13159758Speter } 13241502Swpaul 13341502Swpaul inline const llvm::APSInt& getMaxValue(QualType T) { 13441502Swpaul assert(T->isIntegerType() || Loc::isLocType(T)); 13541502Swpaul bool isUnsigned 13641502Swpaul = T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T); 13741502Swpaul return getValue(llvm::APSInt::getMaxValue(Ctx.getTypeSize(T), isUnsigned)); 13841502Swpaul } 13941502Swpaul 14041502Swpaul inline const llvm::APSInt& getMinValue(QualType T) { 14141502Swpaul assert(T->isIntegerType() || Loc::isLocType(T)); 14241502Swpaul bool isUnsigned 14392739Salfred = T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T); 14492739Salfred return getValue(llvm::APSInt::getMinValue(Ctx.getTypeSize(T), isUnsigned)); 14592739Salfred } 14641502Swpaul 14798995Salfred inline const llvm::APSInt& Add1(const llvm::APSInt& V) { 14892739Salfred llvm::APSInt X = V; 14948745Swpaul ++X; 15092739Salfred return getValue(X); 15192739Salfred } 15292739Salfred 15341502Swpaul inline const llvm::APSInt& Sub1(const llvm::APSInt& V) { 15492739Salfred llvm::APSInt X = V; 15592739Salfred --X; 15692739Salfred return getValue(X); 15792739Salfred } 15892739Salfred 15992739Salfred inline const llvm::APSInt& getZeroWithPtrWidth(bool isUnsigned = true) { 16092739Salfred return getValue(0, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned); 16192739Salfred } 16292739Salfred 16392739Salfred inline const llvm::APSInt &getIntWithPtrWidth(uint64_t X, bool isUnsigned) { 16492739Salfred return getValue(X, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned); 16592739Salfred } 16692739Salfred 16792739Salfred inline const llvm::APSInt& getTruthValue(bool b, QualType T) { 16841502Swpaul return getValue(b ? 1 : 0, Ctx.getTypeSize(T), false); 16992739Salfred } 17092739Salfred 17192739Salfred inline const llvm::APSInt& getTruthValue(bool b) { 17292739Salfred return getTruthValue(b, Ctx.getLogicalOperationType()); 17392739Salfred } 17492739Salfred 17592739Salfred const CompoundValData *getCompoundValData(QualType T, 17641502Swpaul llvm::ImmutableList<SVal> Vals); 17792739Salfred 17892739Salfred const LazyCompoundValData *getLazyCompoundValData(const StoreRef &store, 17992739Salfred const TypedValueRegion *region); 18092739Salfred 18192739Salfred llvm::ImmutableList<SVal> getEmptySValList() { 18292739Salfred return SValListFactory.getEmptyList(); 18392739Salfred } 18441502Swpaul 18592739Salfred llvm::ImmutableList<SVal> consVals(SVal X, llvm::ImmutableList<SVal> L) { 18692739Salfred return SValListFactory.add(X, L); 18792739Salfred } 18850675Swpaul 18949611Swpaul const llvm::APSInt* evalAPSInt(BinaryOperator::Opcode Op, 19049611Swpaul const llvm::APSInt& V1, 19149611Swpaul const llvm::APSInt& V2); 19249611Swpaul 19349611Swpaul const std::pair<SVal, uintptr_t>& 19449611Swpaul getPersistentSValWithData(const SVal& V, uintptr_t Data); 19549611Swpaul 19649611Swpaul const std::pair<SVal, SVal>& 19749611Swpaul getPersistentSValPair(const SVal& V1, const SVal& V2); 19849611Swpaul 19949611Swpaul const SVal* getPersistentSVal(SVal X); 20049611Swpaul}; 20149611Swpaul 20249611Swpaul} // end GR namespace 20350675Swpaul 20450675Swpaul} // end clang namespace 20550675Swpaul 20650675Swpaul#endif 20750675Swpaul