blob: f8f855594929e5b6be9cde91772a6efc17c92404 [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 Kremenek562731e2008-12-05 02:45:20 +000021void SymbolRef::print(llvm::raw_ostream& os) const {
22 os << getNumber();
23}
24
Zhongxing Xu4193eca2008-12-20 06:32:12 +000025SymbolRef SymbolManager::getSymbol(const MemRegion* R) {
26 switch (R->getKind()) {
Daniel Dunbarf1853192009-01-15 18:32:35 +000027 default:
28 assert(0 && "unprocessed region");
Zhongxing Xu4193eca2008-12-20 06:32:12 +000029 case MemRegion::VarRegionKind:
30 return getSymbol(cast<VarRegion>(R)->getDecl());
31
32 case MemRegion::ElementRegionKind: {
33 const ElementRegion* ER = cast<ElementRegion>(R);
34 const llvm::APSInt& Idx =
35 cast<nonloc::ConcreteInt>(ER->getIndex()).getValue();
36 return getElementSymbol(ER->getSuperRegion(), &Idx);
37 }
38
39 case MemRegion::FieldRegionKind: {
40 const FieldRegion* FR = cast<FieldRegion>(R);
41 return getFieldSymbol(FR->getSuperRegion(), FR->getDecl());
42 }
Zhongxing Xu4193eca2008-12-20 06:32:12 +000043 }
44}
45
46SymbolRef SymbolManager::getSymbol(const VarDecl* D) {
Ted Kremenekd763eb92008-02-26 02:15:56 +000047
Ted Kremenek72c59d02008-08-13 03:28:04 +000048 assert (isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) ||
49 D->hasGlobalStorage());
Ted Kremenekd763eb92008-02-26 02:15:56 +000050
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000051 llvm::FoldingSetNodeID profile;
Ted Kremenekd70d0b02008-02-16 01:12:31 +000052
Zhongxing Xu4193eca2008-12-20 06:32:12 +000053 const ParmVarDecl* PD = dyn_cast<ParmVarDecl>(D);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000054
55 if (PD)
56 SymbolDataParmVar::Profile(profile, PD);
57 else
58 SymbolDataGlobalVar::Profile(profile, D);
59
60 void* InsertPos;
61
62 SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
63
64 if (SD)
65 return SD->getSymbol();
66
67 if (PD) {
68 SD = (SymbolData*) BPAlloc.Allocate<SymbolDataParmVar>();
69 new (SD) SymbolDataParmVar(SymbolCounter, PD);
70 }
71 else {
72 SD = (SymbolData*) BPAlloc.Allocate<SymbolDataGlobalVar>();
73 new (SD) SymbolDataGlobalVar(SymbolCounter, D);
Ted Kremenekd70d0b02008-02-16 01:12:31 +000074 }
75
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000076 DataSet.InsertNode(SD, InsertPos);
77
78 DataMap[SymbolCounter] = SD;
79 return SymbolCounter++;
Ted Kremenekd763eb92008-02-26 02:15:56 +000080}
Zhongxing Xueabf7762008-11-19 11:03:17 +000081
Ted Kremenek2dabd432008-12-05 02:27:51 +000082SymbolRef SymbolManager::getElementSymbol(const MemRegion* R,
Zhongxing Xueabf7762008-11-19 11:03:17 +000083 const llvm::APSInt* Idx){
84 llvm::FoldingSetNodeID ID;
85 SymbolDataElement::Profile(ID, R, Idx);
86 void* InsertPos;
87 SymbolData* SD = DataSet.FindNodeOrInsertPos(ID, InsertPos);
88
89 if (SD)
90 return SD->getSymbol();
91
92 SD = (SymbolData*) BPAlloc.Allocate<SymbolDataElement>();
93 new (SD) SymbolDataElement(SymbolCounter, R, Idx);
94
95 DataSet.InsertNode(SD, InsertPos);
96 DataMap[SymbolCounter] = SD;
97 return SymbolCounter++;
98}
99
Ted Kremenek2dabd432008-12-05 02:27:51 +0000100SymbolRef SymbolManager::getFieldSymbol(const MemRegion* R, const FieldDecl* D) {
Zhongxing Xueabf7762008-11-19 11:03:17 +0000101 llvm::FoldingSetNodeID ID;
102 SymbolDataField::Profile(ID, R, D);
103 void* InsertPos;
104 SymbolData* SD = DataSet.FindNodeOrInsertPos(ID, InsertPos);
105
106 if (SD)
107 return SD->getSymbol();
108
109 SD = (SymbolData*) BPAlloc.Allocate<SymbolDataField>();
110 new (SD) SymbolDataField(SymbolCounter, R, D);
111
112 DataSet.InsertNode(SD, InsertPos);
113 DataMap[SymbolCounter] = SD;
114 return SymbolCounter++;
115}
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000116
Ted Kremenek2dabd432008-12-05 02:27:51 +0000117SymbolRef SymbolManager::getConjuredSymbol(Stmt* E, QualType T, unsigned Count) {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000118
119 llvm::FoldingSetNodeID profile;
Ted Kremenek60a6e0c2008-10-01 00:21:14 +0000120 SymbolConjured::Profile(profile, E, T, Count);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000121 void* InsertPos;
122
123 SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
124
125 if (SD)
126 return SD->getSymbol();
127
Ted Kremenek361fa8e2008-03-12 21:45:47 +0000128 SD = (SymbolData*) BPAlloc.Allocate<SymbolConjured>();
Ted Kremenek60a6e0c2008-10-01 00:21:14 +0000129 new (SD) SymbolConjured(SymbolCounter, E, T, Count);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000130
131 DataSet.InsertNode(SD, InsertPos);
132 DataMap[SymbolCounter] = SD;
133
134 return SymbolCounter++;
135}
136
Ted Kremenek2dabd432008-12-05 02:27:51 +0000137const SymbolData& SymbolManager::getSymbolData(SymbolRef Sym) const {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000138 DataMapTy::const_iterator I = DataMap.find(Sym);
139 assert (I != DataMap.end());
140 return *I->second;
141}
142
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000143
Ted Kremeneka888c982008-02-19 20:51:40 +0000144QualType SymbolData::getType(const SymbolManager& SymMgr) const {
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000145 switch (getKind()) {
146 default:
147 assert (false && "getType() not implemented for this symbol.");
148
149 case ParmKind:
150 return cast<SymbolDataParmVar>(this)->getDecl()->getType();
Ted Kremenekd763eb92008-02-26 02:15:56 +0000151
152 case GlobalKind:
153 return cast<SymbolDataGlobalVar>(this)->getDecl()->getType();
Ted Kremenekf3d41622008-12-05 01:31:31 +0000154
Ted Kremenek361fa8e2008-03-12 21:45:47 +0000155 case ConjuredKind:
Ted Kremenek60a6e0c2008-10-01 00:21:14 +0000156 return cast<SymbolConjured>(this)->getType();
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000157 }
158}
159
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000160SymbolManager::~SymbolManager() {}