blob: 1c2814a3afeb6157c3326f0428085761829030c2 [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"
Ted Kremenek562731e2008-12-05 02:45:20 +000016#include "llvm/Support/raw_ostream.h"
Ted Kremenekd70d0b02008-02-16 01:12:31 +000017
18using namespace clang;
19
Ted Kremenek562731e2008-12-05 02:45:20 +000020void SymbolRef::print(llvm::raw_ostream& os) const {
21 os << getNumber();
22}
23
Ted Kremenek2dabd432008-12-05 02:27:51 +000024SymbolRef SymbolManager::getSymbol(VarDecl* D) {
Ted Kremenekd763eb92008-02-26 02:15:56 +000025
Ted Kremenek72c59d02008-08-13 03:28:04 +000026 assert (isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) ||
27 D->hasGlobalStorage());
Ted Kremenekd763eb92008-02-26 02:15:56 +000028
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000029 llvm::FoldingSetNodeID profile;
Ted Kremenekd70d0b02008-02-16 01:12:31 +000030
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000031 ParmVarDecl* PD = dyn_cast<ParmVarDecl>(D);
32
33 if (PD)
34 SymbolDataParmVar::Profile(profile, PD);
35 else
36 SymbolDataGlobalVar::Profile(profile, D);
37
38 void* InsertPos;
39
40 SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
41
42 if (SD)
43 return SD->getSymbol();
44
45 if (PD) {
46 SD = (SymbolData*) BPAlloc.Allocate<SymbolDataParmVar>();
47 new (SD) SymbolDataParmVar(SymbolCounter, PD);
48 }
49 else {
50 SD = (SymbolData*) BPAlloc.Allocate<SymbolDataGlobalVar>();
51 new (SD) SymbolDataGlobalVar(SymbolCounter, D);
Ted Kremenekd70d0b02008-02-16 01:12:31 +000052 }
53
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000054 DataSet.InsertNode(SD, InsertPos);
55
56 DataMap[SymbolCounter] = SD;
57 return SymbolCounter++;
Ted Kremenekd763eb92008-02-26 02:15:56 +000058}
Zhongxing Xueabf7762008-11-19 11:03:17 +000059
Ted Kremenek2dabd432008-12-05 02:27:51 +000060SymbolRef SymbolManager::getElementSymbol(const MemRegion* R,
Zhongxing Xueabf7762008-11-19 11:03:17 +000061 const llvm::APSInt* Idx){
62 llvm::FoldingSetNodeID ID;
63 SymbolDataElement::Profile(ID, R, Idx);
64 void* InsertPos;
65 SymbolData* SD = DataSet.FindNodeOrInsertPos(ID, InsertPos);
66
67 if (SD)
68 return SD->getSymbol();
69
70 SD = (SymbolData*) BPAlloc.Allocate<SymbolDataElement>();
71 new (SD) SymbolDataElement(SymbolCounter, R, Idx);
72
73 DataSet.InsertNode(SD, InsertPos);
74 DataMap[SymbolCounter] = SD;
75 return SymbolCounter++;
76}
77
Ted Kremenek2dabd432008-12-05 02:27:51 +000078SymbolRef SymbolManager::getFieldSymbol(const MemRegion* R, const FieldDecl* D) {
Zhongxing Xueabf7762008-11-19 11:03:17 +000079 llvm::FoldingSetNodeID ID;
80 SymbolDataField::Profile(ID, R, D);
81 void* InsertPos;
82 SymbolData* SD = DataSet.FindNodeOrInsertPos(ID, InsertPos);
83
84 if (SD)
85 return SD->getSymbol();
86
87 SD = (SymbolData*) BPAlloc.Allocate<SymbolDataField>();
88 new (SD) SymbolDataField(SymbolCounter, R, D);
89
90 DataSet.InsertNode(SD, InsertPos);
91 DataMap[SymbolCounter] = SD;
92 return SymbolCounter++;
93}
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000094
Ted Kremenek2dabd432008-12-05 02:27:51 +000095SymbolRef SymbolManager::getConjuredSymbol(Stmt* E, QualType T, unsigned Count) {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000096
97 llvm::FoldingSetNodeID profile;
Ted Kremenek60a6e0c2008-10-01 00:21:14 +000098 SymbolConjured::Profile(profile, E, T, Count);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000099 void* InsertPos;
100
101 SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
102
103 if (SD)
104 return SD->getSymbol();
105
Ted Kremenek361fa8e2008-03-12 21:45:47 +0000106 SD = (SymbolData*) BPAlloc.Allocate<SymbolConjured>();
Ted Kremenek60a6e0c2008-10-01 00:21:14 +0000107 new (SD) SymbolConjured(SymbolCounter, E, T, Count);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000108
109 DataSet.InsertNode(SD, InsertPos);
110 DataMap[SymbolCounter] = SD;
111
112 return SymbolCounter++;
113}
114
Ted Kremenek2dabd432008-12-05 02:27:51 +0000115const SymbolData& SymbolManager::getSymbolData(SymbolRef Sym) const {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000116 DataMapTy::const_iterator I = DataMap.find(Sym);
117 assert (I != DataMap.end());
118 return *I->second;
119}
120
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000121
Ted Kremeneka888c982008-02-19 20:51:40 +0000122QualType SymbolData::getType(const SymbolManager& SymMgr) const {
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000123 switch (getKind()) {
124 default:
125 assert (false && "getType() not implemented for this symbol.");
126
127 case ParmKind:
128 return cast<SymbolDataParmVar>(this)->getDecl()->getType();
Ted Kremenekd763eb92008-02-26 02:15:56 +0000129
130 case GlobalKind:
131 return cast<SymbolDataGlobalVar>(this)->getDecl()->getType();
Ted Kremenekf3d41622008-12-05 01:31:31 +0000132
Ted Kremenek361fa8e2008-03-12 21:45:47 +0000133 case ConjuredKind:
Ted Kremenek60a6e0c2008-10-01 00:21:14 +0000134 return cast<SymbolConjured>(this)->getType();
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000135 }
136}
137
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000138SymbolManager::~SymbolManager() {}