blob: ef9f89ae8c1d53dfd7e959646d789388f85de5e3 [file] [log] [blame]
Ted Kremeneka90ccfe2008-01-31 19:34:24 +00001//== ValueState.h - Path-Sens. "State" for tracking valuues -----*- C++ -*--==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This files defines SymbolID, ValueKey, and ValueState.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_ANALYSIS_VALUESTATE_H
15#define LLVM_CLANG_ANALYSIS_VALUESTATE_H
16
17// FIXME: Reduce the number of includes.
18
19#include "RValues.h"
20
21#include "clang/Analysis/PathSensitive/GREngine.h"
22#include "clang/AST/Expr.h"
23#include "clang/AST/Decl.h"
24#include "clang/AST/ASTContext.h"
25#include "clang/Analysis/Analyses/LiveVariables.h"
26
27#include "llvm/Support/Casting.h"
28#include "llvm/Support/DataTypes.h"
29#include "llvm/ADT/APSInt.h"
30#include "llvm/ADT/FoldingSet.h"
31#include "llvm/ADT/ImmutableMap.h"
32#include "llvm/ADT/SmallVector.h"
33#include "llvm/ADT/SmallPtrSet.h"
34#include "llvm/Support/Allocator.h"
35#include "llvm/Support/Compiler.h"
36#include "llvm/Support/Streams.h"
37
38#include <functional>
39
40namespace clang {
41
42/// ValueKey - A variant smart pointer that wraps either a ValueDecl* or a
43/// Stmt*. Use cast<> or dyn_cast<> to get actual pointer type
44class ValueKey {
45 uintptr_t Raw;
46 void operator=(const ValueKey& RHS); // Do not implement.
47
48public:
49 enum Kind { IsSubExpr=0x0, IsBlkExpr=0x1, IsDecl=0x2, // L-Value Bindings.
50 IsSymbol=0x3, // Symbol Bindings.
51 Mask=0x3 };
52
53 inline Kind getKind() const {
54 return (Kind) (Raw & Mask);
55 }
56
57 inline void* getPtr() const {
58 assert (getKind() != IsSymbol);
59 return reinterpret_cast<void*>(Raw & ~Mask);
60 }
61
62 inline SymbolID getSymbolID() const {
63 assert (getKind() == IsSymbol);
64 return Raw >> 2;
65 }
66
67 ValueKey(const ValueDecl* VD)
68 : Raw(reinterpret_cast<uintptr_t>(VD) | IsDecl) {
69 assert(VD && "ValueDecl cannot be NULL.");
70 }
71
72 ValueKey(Stmt* S, bool isBlkExpr = false)
73 : Raw(reinterpret_cast<uintptr_t>(S) | (isBlkExpr ? IsBlkExpr : IsSubExpr)){
74 assert(S && "Tracked statement cannot be NULL.");
75 }
76
77 ValueKey(SymbolID V)
78 : Raw((V << 2) | IsSymbol) {}
79
80 bool isSymbol() const { return getKind() == IsSymbol; }
81 bool isSubExpr() const { return getKind() == IsSubExpr; }
82 bool isBlkExpr() const { return getKind() == IsBlkExpr; }
83 bool isDecl() const { return getKind() == IsDecl; }
84 bool isStmt() const { return getKind() <= IsBlkExpr; }
85
86 inline void Profile(llvm::FoldingSetNodeID& ID) const {
87 ID.AddInteger(isSymbol() ? 1 : 0);
88
89 if (isSymbol())
90 ID.AddInteger(getSymbolID());
91 else
92 ID.AddPointer(getPtr());
93 }
94
95 inline bool operator==(const ValueKey& X) const {
96 return isSymbol() ? getSymbolID() == X.getSymbolID()
97 : getPtr() == X.getPtr();
98 }
99
100 inline bool operator!=(const ValueKey& X) const {
101 return !operator==(X);
102 }
103
104 inline bool operator<(const ValueKey& X) const {
105 if (isSymbol())
106 return X.isSymbol() ? getSymbolID() < X.getSymbolID() : false;
107
108 return getPtr() < X.getPtr();
109 }
110};
111
112//===----------------------------------------------------------------------===//
113// ValueState - An ImmutableMap type Stmt*/Decl*/Symbols to RValues.
114//===----------------------------------------------------------------------===//
115
116typedef llvm::ImmutableMap<ValueKey,RValue> ValueState;
117
118template<>
119struct GRTrait<ValueState> {
120 static inline void* toPtr(ValueState M) {
121 return reinterpret_cast<void*>(M.getRoot());
122 }
123 static inline ValueState toState(void* P) {
124 return ValueState(static_cast<ValueState::TreeTy*>(P));
125 }
126};
127
128} // end clang namespace
129
130//==------------------------------------------------------------------------==//
131// Casting machinery to get cast<> and dyn_cast<> working with ValueKey.
132//==------------------------------------------------------------------------==//
133
134namespace llvm {
135
136 template<> inline bool
137 isa<clang::ValueDecl,clang::ValueKey>(const clang::ValueKey& V) {
138 return V.getKind() == clang::ValueKey::IsDecl;
139 }
140
141 template<> inline bool
142 isa<clang::Stmt,clang::ValueKey>(const clang::ValueKey& V) {
143 return ((unsigned) V.getKind()) < clang::ValueKey::IsDecl;
144 }
145
146 template<> struct cast_retty_impl<clang::ValueDecl,clang::ValueKey> {
147 typedef const clang::ValueDecl* ret_type;
148 };
149
150 template<> struct cast_retty_impl<clang::Stmt,clang::ValueKey> {
151 typedef const clang::Stmt* ret_type;
152 };
153
154 template<> struct simplify_type<clang::ValueKey> {
155 typedef void* SimpleType;
156 static inline SimpleType getSimplifiedValue(const clang::ValueKey &V) {
157 return V.getPtr();
158 }
159 };
160} // end llvm namespace
161
162#endif