blob: ee18f2c9e48f98c19a84b39028dd01f290d4f4f5 [file] [log] [blame]
Ted Kremenekd70d0b02008-02-16 01:12:31 +00001//== SymbolManager.h - Management of Symbolic Values ------------*- 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//
Gabor Greif843e9342008-03-06 10:40:09 +000010// This file defines SymbolManager, a class that manages symbolic values
Ted Kremenekd70d0b02008-02-16 01:12:31 +000011// created for use by GRExprEngine and related classes.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Analysis/PathSensitive/SymbolManager.h"
Zhongxing Xu4193eca2008-12-20 06:32:12 +000016#include "clang/Analysis/PathSensitive/MemRegion.h"
Ted Kremenek562731e2008-12-05 02:45:20 +000017#include "llvm/Support/raw_ostream.h"
Ted Kremenekd70d0b02008-02-16 01:12:31 +000018
19using namespace clang;
20
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +000021static void print(llvm::raw_ostream& os, const SymExpr *SE);
22
23static void print(llvm::raw_ostream& os, BinaryOperator::Opcode Op) {
24 switch (Op) {
25 default:
26 assert(false && "operator printing not implemented");
27 break;
28 case BinaryOperator::Mul: os << '*' ; break;
29 case BinaryOperator::Div: os << '/' ; break;
30 case BinaryOperator::Rem: os << '%' ; break;
31 case BinaryOperator::Add: os << '+' ; break;
32 case BinaryOperator::Sub: os << '-' ; break;
33 case BinaryOperator::Shl: os << "<<" ; break;
34 case BinaryOperator::Shr: os << ">>" ; break;
35 case BinaryOperator::LT: os << "<" ; break;
36 case BinaryOperator::GT: os << '>' ; break;
37 case BinaryOperator::LE: os << "<=" ; break;
38 case BinaryOperator::GE: os << ">=" ; break;
39 case BinaryOperator::EQ: os << "==" ; break;
40 case BinaryOperator::NE: os << "!=" ; break;
41 case BinaryOperator::And: os << '&' ; break;
42 case BinaryOperator::Xor: os << '^' ; break;
43 case BinaryOperator::Or: os << '|' ; break;
44 }
45}
46
47static void print(llvm::raw_ostream& os, const SymIntExpr *SE) {
48 os << '(';
49 print(os, SE->getLHS());
50 os << ") ";
51 print(os, SE->getOpcode());
52 os << ' ' << SE->getRHS().getZExtValue();
53 if (SE->getRHS().isUnsigned()) os << 'U';
54}
Ted Kremenek94c96982009-03-03 22:06:47 +000055
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +000056static void print(llvm::raw_ostream& os, const SymSymExpr *SE) {
57 os << '(';
58 print(os, SE->getLHS());
59 os << ") ";
60 os << '(';
61 print(os, SE->getRHS());
62 os << ')';
63}
64
65static void print(llvm::raw_ostream& os, const SymExpr *SE) {
66 switch (SE->getKind()) {
67 case SymExpr::BEGIN_SYMBOLS:
68 case SymExpr::RegionRValue:
69 case SymExpr::ConjuredKind:
70 case SymExpr::END_SYMBOLS:
71 os << '$' << cast<SymbolData>(SE)->getSymbolID();
72 return;
73 case SymExpr::SymIntKind:
74 print(os, cast<SymIntExpr>(SE));
75 return;
76 case SymExpr::SymSymKind:
77 print(os, cast<SymSymExpr>(SE));
78 return;
79 }
80}
81
82
83llvm::raw_ostream& llvm::operator<<(llvm::raw_ostream& os, const SymExpr *SE) {
84 print(os, SE);
Ted Kremenek94c96982009-03-03 22:06:47 +000085 return os;
86}
87
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +000088std::ostream& std::operator<<(std::ostream& os, const SymExpr *SE) {
89 llvm::raw_os_ostream O(os);
90 print(O, SE);
Ted Kremenek94c96982009-03-03 22:06:47 +000091 return os;
Ted Kremenek562731e2008-12-05 02:45:20 +000092}
93
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +000094const SymbolRegionRValue*
95SymbolManager::getRegionRValueSymbol(const MemRegion* R) {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000096 llvm::FoldingSetNodeID profile;
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +000097 SymbolRegionRValue::Profile(profile, R);
98 void* InsertPos;
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +000099 SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
100 if (!SD) {
101 SD = (SymExpr*) BPAlloc.Allocate<SymbolRegionRValue>();
102 new (SD) SymbolRegionRValue(SymbolCounter, R);
103 DataSet.InsertNode(SD, InsertPos);
104 ++SymbolCounter;
105 }
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000106
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000107 return cast<SymbolRegionRValue>(SD);
Zhongxing Xueabf7762008-11-19 11:03:17 +0000108}
109
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000110const SymbolConjured*
111SymbolManager::getConjuredSymbol(const Stmt* E, QualType T, unsigned Count,
112 const void* SymbolTag) {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000113
114 llvm::FoldingSetNodeID profile;
Ted Kremeneka880b662009-03-04 22:53:46 +0000115 SymbolConjured::Profile(profile, E, T, Count, SymbolTag);
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000116 void* InsertPos;
117 SymExpr *SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
118 if (!SD) {
119 SD = (SymExpr*) BPAlloc.Allocate<SymbolConjured>();
120 new (SD) SymbolConjured(SymbolCounter, E, T, Count, SymbolTag);
121 DataSet.InsertNode(SD, InsertPos);
122 ++SymbolCounter;
123 }
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000124
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000125 return cast<SymbolConjured>(SD);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000126}
127
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000128const SymIntExpr *SymbolManager::getSymIntExpr(const SymExpr *lhs,
129 BinaryOperator::Opcode op,
130 const llvm::APSInt& v,
131 QualType t) {
Zhongxing Xua129eb92009-03-25 05:58:37 +0000132 llvm::FoldingSetNodeID ID;
133 SymIntExpr::Profile(ID, lhs, op, v, t);
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000134 void *InsertPos;
135 SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
Zhongxing Xua129eb92009-03-25 05:58:37 +0000136
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000137 if (!data) {
138 data = (SymIntExpr*) BPAlloc.Allocate<SymIntExpr>();
139 new (data) SymIntExpr(lhs, op, v, t);
140 DataSet.InsertNode(data, InsertPos);
141 }
142
143 return cast<SymIntExpr>(data);
Zhongxing Xua129eb92009-03-25 05:58:37 +0000144}
145
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000146const SymSymExpr *SymbolManager::getSymSymExpr(const SymExpr *lhs,
147 BinaryOperator::Opcode op,
148 const SymExpr *rhs,
149 QualType t) {
Zhongxing Xua129eb92009-03-25 05:58:37 +0000150 llvm::FoldingSetNodeID ID;
151 SymSymExpr::Profile(ID, lhs, op, rhs, t);
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000152 void *InsertPos;
153 SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
Zhongxing Xua129eb92009-03-25 05:58:37 +0000154
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000155 if (!data) {
156 data = (SymSymExpr*) BPAlloc.Allocate<SymSymExpr>();
157 new (data) SymSymExpr(lhs, op, rhs, t);
158 DataSet.InsertNode(data, InsertPos);
159 }
160
161 return cast<SymSymExpr>(data);
Zhongxing Xua129eb92009-03-25 05:58:37 +0000162}
163
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000164QualType SymbolConjured::getType(ASTContext&) const {
165 return T;
166}
Ted Kremenekd763eb92008-02-26 02:15:56 +0000167
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000168QualType SymbolRegionRValue::getType(ASTContext& C) const {
169 if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
Zhongxing Xuff697822009-05-09 00:50:33 +0000170 return TR->getObjectType(C);
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000171
172 return QualType();
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000173}
174
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000175SymbolManager::~SymbolManager() {}
Ted Kremenek241677a2009-01-21 22:26:05 +0000176
Ted Kremenek693de5d2009-03-23 15:42:58 +0000177bool SymbolManager::canSymbolicate(QualType T) {
178 return Loc::IsLocType(T) || T->isIntegerType();
179}
180
Ted Kremenek241677a2009-01-21 22:26:05 +0000181void SymbolReaper::markLive(SymbolRef sym) {
182 TheLiving = F.Add(TheLiving, sym);
183 TheDead = F.Remove(TheDead, sym);
184}
185
186bool SymbolReaper::maybeDead(SymbolRef sym) {
187 if (isLive(sym))
188 return false;
189
190 TheDead = F.Add(TheDead, sym);
191 return true;
192}
193
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000194bool SymbolReaper::isLive(SymbolRef sym) {
Ted Kremenekdcb6a262009-01-22 18:51:33 +0000195 if (TheLiving.contains(sym))
196 return true;
197
198 // Interogate the symbol. It may derive from an input value to
199 // the analyzed function/method.
Ted Kremeneke0e4ebf2009-03-26 03:35:11 +0000200 return isa<SymbolRegionRValue>(sym);
Ted Kremenek241677a2009-01-21 22:26:05 +0000201}
Ted Kremenek5216ad72009-02-14 03:16:10 +0000202
203SymbolVisitor::~SymbolVisitor() {}