blob: 7829e3ace3a113f8edb6f4ff5c146a3d5f591c58 [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"
16
17using namespace clang;
18
Ted Kremenekd763eb92008-02-26 02:15:56 +000019SymbolID SymbolManager::getSymbol(VarDecl* D) {
20
Ted Kremenek72c59d02008-08-13 03:28:04 +000021 assert (isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) ||
22 D->hasGlobalStorage());
Ted Kremenekd763eb92008-02-26 02:15:56 +000023
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000024 llvm::FoldingSetNodeID profile;
Ted Kremenekd70d0b02008-02-16 01:12:31 +000025
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000026 ParmVarDecl* PD = dyn_cast<ParmVarDecl>(D);
27
28 if (PD)
29 SymbolDataParmVar::Profile(profile, PD);
30 else
31 SymbolDataGlobalVar::Profile(profile, D);
32
33 void* InsertPos;
34
35 SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
36
37 if (SD)
38 return SD->getSymbol();
39
40 if (PD) {
41 SD = (SymbolData*) BPAlloc.Allocate<SymbolDataParmVar>();
42 new (SD) SymbolDataParmVar(SymbolCounter, PD);
43 }
44 else {
45 SD = (SymbolData*) BPAlloc.Allocate<SymbolDataGlobalVar>();
46 new (SD) SymbolDataGlobalVar(SymbolCounter, D);
Ted Kremenekd70d0b02008-02-16 01:12:31 +000047 }
48
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000049 DataSet.InsertNode(SD, InsertPos);
50
51 DataMap[SymbolCounter] = SD;
52 return SymbolCounter++;
Ted Kremenekd763eb92008-02-26 02:15:56 +000053}
54
Ted Kremenekd70d0b02008-02-16 01:12:31 +000055SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) {
Ted Kremenekd70d0b02008-02-16 01:12:31 +000056
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000057 llvm::FoldingSetNodeID profile;
58 SymbolDataContentsOf::Profile(profile, sym);
59 void* InsertPos;
Ted Kremenekd70d0b02008-02-16 01:12:31 +000060
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000061 SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
62
63 if (SD)
64 return SD->getSymbol();
65
66 SD = (SymbolData*) BPAlloc.Allocate<SymbolDataContentsOf>();
67 new (SD) SymbolDataContentsOf(SymbolCounter, sym);
68
69
70 DataSet.InsertNode(SD, InsertPos);
71 DataMap[SymbolCounter] = SD;
72
73 return SymbolCounter++;
Ted Kremenekd70d0b02008-02-16 01:12:31 +000074}
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000075
Ted Kremenekb5abb422008-11-12 19:22:47 +000076SymbolID SymbolManager::getConjuredSymbol(Stmt* E, QualType T, unsigned Count) {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000077
78 llvm::FoldingSetNodeID profile;
Ted Kremenek60a6e0c2008-10-01 00:21:14 +000079 SymbolConjured::Profile(profile, E, T, Count);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000080 void* InsertPos;
81
82 SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
83
84 if (SD)
85 return SD->getSymbol();
86
Ted Kremenek361fa8e2008-03-12 21:45:47 +000087 SD = (SymbolData*) BPAlloc.Allocate<SymbolConjured>();
Ted Kremenek60a6e0c2008-10-01 00:21:14 +000088 new (SD) SymbolConjured(SymbolCounter, E, T, Count);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000089
90 DataSet.InsertNode(SD, InsertPos);
91 DataMap[SymbolCounter] = SD;
92
93 return SymbolCounter++;
94}
95
96const SymbolData& SymbolManager::getSymbolData(SymbolID Sym) const {
97 DataMapTy::const_iterator I = DataMap.find(Sym);
98 assert (I != DataMap.end());
99 return *I->second;
100}
101
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000102
Ted Kremeneka888c982008-02-19 20:51:40 +0000103QualType SymbolData::getType(const SymbolManager& SymMgr) const {
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000104 switch (getKind()) {
105 default:
106 assert (false && "getType() not implemented for this symbol.");
107
108 case ParmKind:
109 return cast<SymbolDataParmVar>(this)->getDecl()->getType();
Ted Kremenekd763eb92008-02-26 02:15:56 +0000110
111 case GlobalKind:
112 return cast<SymbolDataGlobalVar>(this)->getDecl()->getType();
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000113
Ted Kremeneka888c982008-02-19 20:51:40 +0000114 case ContentsOfKind: {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000115 SymbolID x = cast<SymbolDataContentsOf>(this)->getContainerSymbol();
Ted Kremeneka888c982008-02-19 20:51:40 +0000116 QualType T = SymMgr.getSymbolData(x).getType(SymMgr);
117 return T->getAsPointerType()->getPointeeType();
118 }
Ted Kremenek00a3a5f2008-03-12 01:21:45 +0000119
Ted Kremenek361fa8e2008-03-12 21:45:47 +0000120 case ConjuredKind:
Ted Kremenek60a6e0c2008-10-01 00:21:14 +0000121 return cast<SymbolConjured>(this)->getType();
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000122 }
123}
124
Ted Kremenekd70d0b02008-02-16 01:12:31 +0000125SymbolManager::~SymbolManager() {}