Ted Kremenek | d70d0b0 | 2008-02-16 01:12:31 +0000 | [diff] [blame] | 1 | //== 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 Greif | 843e934 | 2008-03-06 10:40:09 +0000 | [diff] [blame] | 10 | // This file defines SymbolManager, a class that manages symbolic values |
Ted Kremenek | d70d0b0 | 2008-02-16 01:12:31 +0000 | [diff] [blame] | 11 | // created for use by GRExprEngine and related classes. |
| 12 | // |
| 13 | //===----------------------------------------------------------------------===// |
| 14 | |
| 15 | #include "clang/Analysis/PathSensitive/SymbolManager.h" |
Zhongxing Xu | 4193eca | 2008-12-20 06:32:12 +0000 | [diff] [blame] | 16 | #include "clang/Analysis/PathSensitive/MemRegion.h" |
Ted Kremenek | 562731e | 2008-12-05 02:45:20 +0000 | [diff] [blame] | 17 | #include "llvm/Support/raw_ostream.h" |
Ted Kremenek | d70d0b0 | 2008-02-16 01:12:31 +0000 | [diff] [blame] | 18 | |
| 19 | using namespace clang; |
| 20 | |
Ted Kremenek | 562731e | 2008-12-05 02:45:20 +0000 | [diff] [blame] | 21 | void SymbolRef::print(llvm::raw_ostream& os) const { |
| 22 | os << getNumber(); |
| 23 | } |
| 24 | |
Zhongxing Xu | 4193eca | 2008-12-20 06:32:12 +0000 | [diff] [blame] | 25 | SymbolRef SymbolManager::getSymbol(const MemRegion* R) { |
| 26 | switch (R->getKind()) { |
Daniel Dunbar | f185319 | 2009-01-15 18:32:35 +0000 | [diff] [blame] | 27 | default: |
| 28 | assert(0 && "unprocessed region"); |
Zhongxing Xu | 4193eca | 2008-12-20 06:32:12 +0000 | [diff] [blame] | 29 | 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 Xu | 4193eca | 2008-12-20 06:32:12 +0000 | [diff] [blame] | 43 | } |
| 44 | } |
| 45 | |
| 46 | SymbolRef SymbolManager::getSymbol(const VarDecl* D) { |
Ted Kremenek | d763eb9 | 2008-02-26 02:15:56 +0000 | [diff] [blame] | 47 | |
Ted Kremenek | 72c59d0 | 2008-08-13 03:28:04 +0000 | [diff] [blame] | 48 | assert (isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) || |
| 49 | D->hasGlobalStorage()); |
Ted Kremenek | d763eb9 | 2008-02-26 02:15:56 +0000 | [diff] [blame] | 50 | |
Ted Kremenek | 00a3a5f | 2008-03-12 01:21:45 +0000 | [diff] [blame] | 51 | llvm::FoldingSetNodeID profile; |
Ted Kremenek | d70d0b0 | 2008-02-16 01:12:31 +0000 | [diff] [blame] | 52 | |
Zhongxing Xu | 4193eca | 2008-12-20 06:32:12 +0000 | [diff] [blame] | 53 | const ParmVarDecl* PD = dyn_cast<ParmVarDecl>(D); |
Ted Kremenek | 00a3a5f | 2008-03-12 01:21:45 +0000 | [diff] [blame] | 54 | |
| 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 Kremenek | d70d0b0 | 2008-02-16 01:12:31 +0000 | [diff] [blame] | 74 | } |
| 75 | |
Ted Kremenek | 00a3a5f | 2008-03-12 01:21:45 +0000 | [diff] [blame] | 76 | DataSet.InsertNode(SD, InsertPos); |
| 77 | |
| 78 | DataMap[SymbolCounter] = SD; |
| 79 | return SymbolCounter++; |
Ted Kremenek | d763eb9 | 2008-02-26 02:15:56 +0000 | [diff] [blame] | 80 | } |
Zhongxing Xu | eabf776 | 2008-11-19 11:03:17 +0000 | [diff] [blame] | 81 | |
Ted Kremenek | 2dabd43 | 2008-12-05 02:27:51 +0000 | [diff] [blame] | 82 | SymbolRef SymbolManager::getElementSymbol(const MemRegion* R, |
Zhongxing Xu | eabf776 | 2008-11-19 11:03:17 +0000 | [diff] [blame] | 83 | 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 Kremenek | 2dabd43 | 2008-12-05 02:27:51 +0000 | [diff] [blame] | 100 | SymbolRef SymbolManager::getFieldSymbol(const MemRegion* R, const FieldDecl* D) { |
Zhongxing Xu | eabf776 | 2008-11-19 11:03:17 +0000 | [diff] [blame] | 101 | 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 Kremenek | 00a3a5f | 2008-03-12 01:21:45 +0000 | [diff] [blame] | 116 | |
Ted Kremenek | 2dabd43 | 2008-12-05 02:27:51 +0000 | [diff] [blame] | 117 | SymbolRef SymbolManager::getConjuredSymbol(Stmt* E, QualType T, unsigned Count) { |
Ted Kremenek | 00a3a5f | 2008-03-12 01:21:45 +0000 | [diff] [blame] | 118 | |
| 119 | llvm::FoldingSetNodeID profile; |
Ted Kremenek | 60a6e0c | 2008-10-01 00:21:14 +0000 | [diff] [blame] | 120 | SymbolConjured::Profile(profile, E, T, Count); |
Ted Kremenek | 00a3a5f | 2008-03-12 01:21:45 +0000 | [diff] [blame] | 121 | void* InsertPos; |
| 122 | |
| 123 | SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos); |
| 124 | |
| 125 | if (SD) |
| 126 | return SD->getSymbol(); |
| 127 | |
Ted Kremenek | 361fa8e | 2008-03-12 21:45:47 +0000 | [diff] [blame] | 128 | SD = (SymbolData*) BPAlloc.Allocate<SymbolConjured>(); |
Ted Kremenek | 60a6e0c | 2008-10-01 00:21:14 +0000 | [diff] [blame] | 129 | new (SD) SymbolConjured(SymbolCounter, E, T, Count); |
Ted Kremenek | 00a3a5f | 2008-03-12 01:21:45 +0000 | [diff] [blame] | 130 | |
| 131 | DataSet.InsertNode(SD, InsertPos); |
| 132 | DataMap[SymbolCounter] = SD; |
| 133 | |
| 134 | return SymbolCounter++; |
| 135 | } |
| 136 | |
Ted Kremenek | 2dabd43 | 2008-12-05 02:27:51 +0000 | [diff] [blame] | 137 | const SymbolData& SymbolManager::getSymbolData(SymbolRef Sym) const { |
Ted Kremenek | 00a3a5f | 2008-03-12 01:21:45 +0000 | [diff] [blame] | 138 | DataMapTy::const_iterator I = DataMap.find(Sym); |
| 139 | assert (I != DataMap.end()); |
| 140 | return *I->second; |
| 141 | } |
| 142 | |
Ted Kremenek | d70d0b0 | 2008-02-16 01:12:31 +0000 | [diff] [blame] | 143 | |
Ted Kremenek | a888c98 | 2008-02-19 20:51:40 +0000 | [diff] [blame] | 144 | QualType SymbolData::getType(const SymbolManager& SymMgr) const { |
Ted Kremenek | d70d0b0 | 2008-02-16 01:12:31 +0000 | [diff] [blame] | 145 | 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 Kremenek | d763eb9 | 2008-02-26 02:15:56 +0000 | [diff] [blame] | 151 | |
| 152 | case GlobalKind: |
| 153 | return cast<SymbolDataGlobalVar>(this)->getDecl()->getType(); |
Ted Kremenek | f3d4162 | 2008-12-05 01:31:31 +0000 | [diff] [blame] | 154 | |
Ted Kremenek | 361fa8e | 2008-03-12 21:45:47 +0000 | [diff] [blame] | 155 | case ConjuredKind: |
Ted Kremenek | 60a6e0c | 2008-10-01 00:21:14 +0000 | [diff] [blame] | 156 | return cast<SymbolConjured>(this)->getType(); |
Ted Kremenek | d70d0b0 | 2008-02-16 01:12:31 +0000 | [diff] [blame] | 157 | } |
| 158 | } |
| 159 | |
Ted Kremenek | d70d0b0 | 2008-02-16 01:12:31 +0000 | [diff] [blame] | 160 | SymbolManager::~SymbolManager() {} |
Ted Kremenek | 241677a | 2009-01-21 22:26:05 +0000 | [diff] [blame] | 161 | |
| 162 | void SymbolReaper::markLive(SymbolRef sym) { |
| 163 | TheLiving = F.Add(TheLiving, sym); |
| 164 | TheDead = F.Remove(TheDead, sym); |
| 165 | } |
| 166 | |
| 167 | bool SymbolReaper::maybeDead(SymbolRef sym) { |
| 168 | if (isLive(sym)) |
| 169 | return false; |
| 170 | |
| 171 | TheDead = F.Add(TheDead, sym); |
| 172 | return true; |
| 173 | } |
| 174 | |
| 175 | bool SymbolReaper::isLive(SymbolRef sym) { |
| 176 | return TheLiving.contains(sym); |
| 177 | } |
| 178 | |