blob: 33d6a5722e25ba5f0ed0ab45a63dea1b28cb68ab [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 Kremenek94c96982009-03-03 22:06:47 +000021llvm::raw_ostream& llvm::operator<<(llvm::raw_ostream& os,
22 clang::SymbolRef sym) {
23 if (sym.isValid())
24 os << sym.getNumber();
25 else
26 os << "(Invalid)";
27
28 return os;
29}
30
31std::ostream& std::operator<<(std::ostream& os, clang::SymbolRef sym) {
32 if (sym.isValid())
33 os << sym.getNumber();
34 else
35 os << "(Invalid)";
36
37 return os;
Ted Kremenek562731e2008-12-05 02:45:20 +000038}
39
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +000040SymbolRef SymbolManager::getRegionRValueSymbol(const MemRegion* R) {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000041 llvm::FoldingSetNodeID profile;
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000042
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +000043 SymbolRegionRValue::Profile(profile, R);
44 void* InsertPos;
45 SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
46 if (SD) return SD->getSymbol();
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000047
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +000048 SD = (SymbolData*) BPAlloc.Allocate<SymbolRegionRValue>();
49 new (SD) SymbolRegionRValue(SymbolCounter, R);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000050 DataSet.InsertNode(SD, InsertPos);
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +000051 DataMap[SymbolCounter] = SD;
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000052 return SymbolCounter++;
Zhongxing Xueabf7762008-11-19 11:03:17 +000053}
54
Ted Kremenekbb9b2712009-03-20 20:10:45 +000055SymbolRef SymbolManager::getConjuredSymbol(const Stmt* E, QualType T,
56 unsigned Count,
Ted Kremeneka880b662009-03-04 22:53:46 +000057 const void* SymbolTag) {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000058
59 llvm::FoldingSetNodeID profile;
Ted Kremeneka880b662009-03-04 22:53:46 +000060 SymbolConjured::Profile(profile, E, T, Count, SymbolTag);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000061 void* InsertPos;
62
63 SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
64
65 if (SD)
66 return SD->getSymbol();
67
Ted Kremenek361fa8e2008-03-12 21:45:47 +000068 SD = (SymbolData*) BPAlloc.Allocate<SymbolConjured>();
Ted Kremeneka880b662009-03-04 22:53:46 +000069 new (SD) SymbolConjured(SymbolCounter, E, T, Count, SymbolTag);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000070
71 DataSet.InsertNode(SD, InsertPos);
72 DataMap[SymbolCounter] = SD;
73
74 return SymbolCounter++;
75}
76
Zhongxing Xua129eb92009-03-25 05:58:37 +000077SymbolRef SymbolManager::getSymIntExpr(SymbolRef lhs,BinaryOperator::Opcode op,
78 const llvm::APSInt& v, QualType t) {
79 llvm::FoldingSetNodeID ID;
80 SymIntExpr::Profile(ID, lhs, op, v, t);
81 void* InsertPos;
82
83 SymbolData* data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
84
85 if (data)
86 return data->getSymbol();
87
88 data = (SymIntExpr*) BPAlloc.Allocate<SymIntExpr>();
89 new (data) SymIntExpr(SymbolCounter, lhs, op, v, t);
90
91 DataSet.InsertNode(data, InsertPos);
92 DataMap[SymbolCounter] = data;
93
94 return SymbolCounter++;
95}
96
97SymbolRef SymbolManager::getSymSymExpr(SymbolRef lhs, BinaryOperator::Opcode op,
98 SymbolRef rhs, QualType t) {
99 llvm::FoldingSetNodeID ID;
100 SymSymExpr::Profile(ID, lhs, op, rhs, t);
101 void* InsertPos;
102
103 SymbolData* data = DataSet.FindNodeOrInsertPos(ID, InsertPos);
104
105 if (data)
106 return data->getSymbol();
107
108 data = (SymSymExpr*) BPAlloc.Allocate<SymSymExpr>();
109 new (data) SymSymExpr(SymbolCounter, lhs, op, rhs, t);
110
111 DataSet.InsertNode(data, InsertPos);
112 DataMap[SymbolCounter] = data;
113
114 return SymbolCounter++;
115}
116
117
Ted Kremenek2dabd432008-12-05 02:27:51 +0000118const SymbolData& SymbolManager::getSymbolData(SymbolRef Sym) const {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000119 DataMapTy::const_iterator I = DataMap.find(Sym);
120 assert (I != DataMap.end());
121 return *I->second;
122}
123
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000124
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000125QualType SymbolConjured::getType(ASTContext&) const {
126 return T;
127}
Ted Kremenekd763eb92008-02-26 02:15:56 +0000128
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000129QualType SymbolRegionRValue::getType(ASTContext& C) const {
130 if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
131 return TR->getRValueType(C);
132
133 return QualType();
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000134}
135
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000136SymbolManager::~SymbolManager() {}
Ted Kremenek241677a2009-01-21 22:26:05 +0000137
Ted Kremenek693de5d2009-03-23 15:42:58 +0000138bool SymbolManager::canSymbolicate(QualType T) {
139 return Loc::IsLocType(T) || T->isIntegerType();
140}
141
Ted Kremenek241677a2009-01-21 22:26:05 +0000142void SymbolReaper::markLive(SymbolRef sym) {
143 TheLiving = F.Add(TheLiving, sym);
144 TheDead = F.Remove(TheDead, sym);
145}
146
147bool SymbolReaper::maybeDead(SymbolRef sym) {
148 if (isLive(sym))
149 return false;
150
151 TheDead = F.Add(TheDead, sym);
152 return true;
153}
154
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000155bool SymbolReaper::isLive(SymbolRef sym) {
Ted Kremenekdcb6a262009-01-22 18:51:33 +0000156 if (TheLiving.contains(sym))
157 return true;
158
159 // Interogate the symbol. It may derive from an input value to
160 // the analyzed function/method.
161 return isa<SymbolRegionRValue>(SymMgr.getSymbolData(sym));
Ted Kremenek241677a2009-01-21 22:26:05 +0000162}
Ted Kremenek5216ad72009-02-14 03:16:10 +0000163
164SymbolVisitor::~SymbolVisitor() {}