SVals.h revision dc3936b0557ce7377905b387d3c69bc8fa484b9c
1a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//== RValues.h - Abstract RValues for Path-Sens. Value Tracking -*- C++ -*--==// 2a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 3a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// The LLVM Compiler Infrastructure 4a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 5a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// This file is distributed under the University of Illinois Open Source 6a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// License. See LICENSE.TXT for details. 7a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 8a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 9a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 10aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek// This files defines RVal, LVal, and NonLVal, classes that represent 11a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// abstract r-values for use with path-sensitive value tracking. 12a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek// 13a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//===----------------------------------------------------------------------===// 14a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 15a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#ifndef LLVM_CLANG_ANALYSIS_RVALUE_H 16a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#define LLVM_CLANG_ANALYSIS_RVALUE_H 17a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 18d70d0b05e5143be9e952eceb5aad7914b2ecab97Ted Kremenek#include "clang/Analysis/PathSensitive/ValueManager.h" 19a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#include "llvm/Support/Casting.h" 20d131c4ff6133c691f91d8a82e7197d97b187425fTed Kremenek 210f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremenek//==------------------------------------------------------------------------==// 22aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek// Base RVal types. 23a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==// 24a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 250f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremeneknamespace clang { 260f10d50fe23c08f5133db0ad7269e7995ad9b172Ted Kremenek 27aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass RVal { 28a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 29aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek enum BaseKind { UninitializedKind, UnknownKind, LValKind, NonLValKind }; 30aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek enum { BaseBits = 2, BaseMask = 0x3 }; 31a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 3290e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenekprotected: 33a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek void* Data; 34a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek unsigned Kind; 35a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 36a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected: 37aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek RVal(const void* d, bool isLVal, unsigned ValKind) 38a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek : Data(const_cast<void*>(d)), 39aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek Kind((isLVal ? LValKind : NonLValKind) | (ValKind << BaseBits)) {} 40a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 41aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek explicit RVal(BaseKind k) 42a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek : Data(0), Kind(k) {} 43a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 44a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 45aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek ~RVal() {}; 46a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 47aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek /// BufferTy - A temporary buffer to hold a set of RVals. 48aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek typedef llvm::SmallVector<RVal,5> BufferTy; 49a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 50aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline unsigned getRawKind() const { return Kind; } 51aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); } 52aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; } 53a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 54aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline void Profile(llvm::FoldingSetNodeID& ID) const { 55a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek ID.AddInteger((unsigned) getRawKind()); 56a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek ID.AddPointer(reinterpret_cast<void*>(Data)); 57a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 58a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 59aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool operator==(const RVal& R) const { 60aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getRawKind() == R.getRawKind() && Data == R.Data; 61a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 62a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 63dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek 64dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek inline bool operator!=(const RVal& R) const { 65dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek return !(*this == R); 66dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek } 67dc3936b0557ce7377905b387d3c69bc8fa484b9cTed Kremenek 68aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static RVal GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl *D); 69a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 70aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool isUnknown() const { 71aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getRawKind() == UnknownKind; 72aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 73aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 74aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool isUninit() const { 75aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getRawKind() == UninitializedKind; 76aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 77aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 78aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool isUnknownOrUninit() const { 79aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getRawKind() <= UnknownKind; 80aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 81cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 82aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool isValid() const { 83aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getRawKind() > UnknownKind; 84aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 85a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 86a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek void print(std::ostream& OS) const; 87d8e9f0dc737133d4e8342f39389064620f5a7f8fTed Kremenek void printStdErr() const; 88a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 8990e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek typedef const SymbolID* symbol_iterator; 9090e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek symbol_iterator symbol_begin() const; 9190e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek symbol_iterator symbol_end() const; 9290e1481ef15ec75e3503e0c6e5effad5bd639f01Ted Kremenek 93a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek // Implement isa<T> support. 94aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const RVal*) { return true; } 95a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 96a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 97aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass UnknownVal : public RVal { 98a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 99aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek UnknownVal() : RVal(UnknownKind) {} 100a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 101aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const RVal* V) { 1022203118815997a0efcf19217e057bd20e33303e7Ted Kremenek return V->getBaseKind() == UnknownKind; 103a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 104a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 105a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 106aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass UninitializedVal : public RVal { 107a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 108aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek UninitializedVal() : RVal(UninitializedKind) {} 109a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 110aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const RVal* V) { 111a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek return V->getBaseKind() == UninitializedKind; 112a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 113a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 114a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 115aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass NonLVal : public RVal { 116a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected: 117aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek NonLVal(unsigned SubKind, const void* d) : RVal(d, false, SubKind) {} 118a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 119a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekpublic: 120a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek void print(std::ostream& Out) const; 121a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 122aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Utility methods to create NonLVals. 123aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static NonLVal MakeVal(ValueManager& ValMgr, uint64_t X, QualType T, 124aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek SourceLocation Loc = SourceLocation()); 125a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 126aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static NonLVal MakeVal(ValueManager& ValMgr, IntegerLiteral* I); 127a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 128aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static NonLVal MakeIntTruthVal(ValueManager& ValMgr, bool b); 129cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 130a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek // Implement isa<T> support. 131aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const RVal* V) { 132aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getBaseKind() == NonLValKind; 133a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 134a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 135a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 136aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass LVal : public RVal { 137a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenekprotected: 138aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek LVal(unsigned SubKind, const void* D) 139aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek : RVal(const_cast<void*>(D), true, SubKind) {} 140aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 141a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek // Equality operators. 142aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek NonLVal EQ(ValueManager& ValMgr, const LVal& R) const; 143aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek NonLVal NE(ValueManager& ValMgr, const LVal& R) const; 144a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 145cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenekpublic: 146d131c4ff6133c691f91d8a82e7197d97b187425fTed Kremenek void print(std::ostream& Out) const; 147d59cccc0b6cd4485897526699fe98514805c1883Ted Kremenek 148aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static LVal MakeVal(AddrLabelExpr* E); 1492a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek 150a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek // Implement isa<T> support. 151aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const RVal* V) { 152aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getBaseKind() == LValKind; 153a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek } 154a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek}; 155a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 156a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==// 157aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek// Subclasses of NonLVal. 158a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek//==------------------------------------------------------------------------==// 159a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 160329f854f217d72594a3ec5572eba6320f81a5efaTed Kremeneknamespace nonlval { 161329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek 162aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekenum Kind { ConcreteIntKind, SymbolValKind, SymIntConstraintValKind }; 163329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek 164aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass SymbolVal : public NonLVal { 165aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 166aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek SymbolVal(unsigned SymID) 167aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek : NonLVal(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {} 168aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 169aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek SymbolID getSymbol() const { 170aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return (SymbolID) reinterpret_cast<uintptr_t>(Data); 171aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 172aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 173aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const RVal* V) { 174aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getBaseKind() == NonLValKind && 175aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == SymbolValKind; 176aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 177aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 178aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const NonLVal* V) { 179aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == SymbolValKind; 180aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 181aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 1829466aa8cf38aa8e87fe3e2cd8005fc245d04f9b7Ted Kremenek 183aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass SymIntConstraintVal : public NonLVal { 184aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 185aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek SymIntConstraintVal(const SymIntConstraint& C) 186aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek : NonLVal(SymIntConstraintValKind, reinterpret_cast<const void*>(&C)) {} 187329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek 188aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const SymIntConstraint& getConstraint() const { 189aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return *reinterpret_cast<SymIntConstraint*>(Data); 190aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 191aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 192aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const RVal* V) { 193aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getBaseKind() == NonLValKind && 194aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == SymIntConstraintValKind; 195aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 196aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 197aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const NonLVal* V) { 198aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == SymIntConstraintValKind; 199aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 200aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 201aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 202aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass ConcreteInt : public NonLVal { 203aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 204aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek ConcreteInt(const llvm::APSInt& V) : NonLVal(ConcreteIntKind, &V) {} 205aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 206aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const llvm::APSInt& getValue() const { 207aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return *static_cast<llvm::APSInt*>(Data); 208aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 209aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 210aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Transfer functions for binary/unary operations on ConcreteInts. 211aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek ConcreteInt EvalBinOp(ValueManager& ValMgr, BinaryOperator::Opcode Op, 212aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const ConcreteInt& R) const; 213aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 214aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek ConcreteInt EvalComplement(ValueManager& ValMgr) const; 215aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 216aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek ConcreteInt EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const; 217aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 218aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 219aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const RVal* V) { 220aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getBaseKind() == NonLValKind && 221aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == ConcreteIntKind; 222aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 223aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 224aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const NonLVal* V) { 225aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == ConcreteIntKind; 226aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 227aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 228a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 229329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek} // end namespace clang::nonlval 230516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek 231516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==// 232aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek// Subclasses of LVal. 233516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek//==------------------------------------------------------------------------==// 234516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek 235329f854f217d72594a3ec5572eba6320f81a5efaTed Kremeneknamespace lval { 236516f91b0917f2aafdce1a989482d21a7224b40ecTed Kremenek 237aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekenum Kind { SymbolValKind, GotoLabelKind, DeclValKind, FuncValKind, 238aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek ConcreteIntKind }; 239aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 240aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass SymbolVal : public LVal { 241aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 242aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek SymbolVal(unsigned SymID) 243aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek : LVal(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {} 2442a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek 245aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek SymbolID getSymbol() const { 246aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return (SymbolID) reinterpret_cast<uintptr_t>(Data); 247aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 248aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 249aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const RVal* V) { 250aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getBaseKind() == LValKind && 251aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == SymbolValKind; 252aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 253aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 254aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const LVal* V) { 255aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == SymbolValKind; 256aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 257aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 258329f854f217d72594a3ec5572eba6320f81a5efaTed Kremenek 259aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass GotoLabel : public LVal { 260aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 261aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek GotoLabel(LabelStmt* Label) : LVal(GotoLabelKind, Label) {} 262aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 263aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek LabelStmt* getLabel() const { 264aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return static_cast<LabelStmt*>(Data); 265aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 266aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 267aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const RVal* V) { 268aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getBaseKind() == LValKind && 269aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == GotoLabelKind; 270aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 271aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 272aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const LVal* V) { 273aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == GotoLabelKind; 274aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 275aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 276aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 277cf78b6a771bb4537d5ee8fa44e718e842c2f70c7Ted Kremenek 278aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass DeclVal : public LVal { 279aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 280aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek DeclVal(const VarDecl* vd) : LVal(DeclValKind, vd) {} 281aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 282aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek VarDecl* getDecl() const { 283aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return static_cast<VarDecl*>(Data); 284aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 285aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 286aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool operator==(const DeclVal& R) const { 287aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getDecl() == R.getDecl(); 288aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 289aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 290aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool operator!=(const DeclVal& R) const { 291aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getDecl() != R.getDecl(); 292aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 293aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 294aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 295aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const RVal* V) { 296aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getBaseKind() == LValKind && 297aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == DeclValKind; 298aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 299aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 300aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const LVal* V) { 301aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == DeclValKind; 302aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 303aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 304aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 305aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass FuncVal : public LVal { 306aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 307aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek FuncVal(const FunctionDecl* fd) : LVal(FuncValKind, fd) {} 308aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 309aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek FunctionDecl* getDecl() const { 310aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return static_cast<FunctionDecl*>(Data); 311aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 312aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 313aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool operator==(const FuncVal& R) const { 314aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getDecl() == R.getDecl(); 315aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 316aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 317aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek inline bool operator!=(const FuncVal& R) const { 318aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return getDecl() != R.getDecl(); 319aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 320aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 321aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 322aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const RVal* V) { 323aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getBaseKind() == LValKind && 324aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == FuncValKind; 325aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 326aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 327aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const LVal* V) { 328aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == FuncValKind; 329aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 330aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 331aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 332aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekclass ConcreteInt : public LVal { 333aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenekpublic: 334aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek ConcreteInt(const llvm::APSInt& V) : LVal(ConcreteIntKind, &V) {} 335aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 336aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const llvm::APSInt& getValue() const { 337aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return *static_cast<llvm::APSInt*>(Data); 338aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 3392a502578a785d5e7ed9e08e2895dbdcfa5333c11Ted Kremenek 340aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Transfer functions for binary/unary operations on ConcreteInts. 341aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek ConcreteInt EvalBinOp(ValueManager& ValMgr, 342aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek BinaryOperator::Opcode Op, 343aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek const ConcreteInt& R) const; 344aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 345aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek // Implement isa<T> support. 346aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const RVal* V) { 347aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getBaseKind() == LValKind && 348aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek V->getSubKind() == ConcreteIntKind; 349aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 350aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 351aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek static inline bool classof(const LVal* V) { 352aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek return V->getSubKind() == ConcreteIntKind; 353aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek } 354aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek}; 355aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek 356aa1c4e5a6b87b62d991c55a0d4522bcd778068d7Ted Kremenek} // end clang::lval namespace 357a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek} // end clang namespace 358a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek 359a90ccfe03ce62f4c33cbb96982947cf474b4fae4Ted Kremenek#endif 360