blob: 589178fecb123fa38af786e83909064dc3314777 [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 Kremeneka880b662009-03-04 22:53:46 +000055SymbolRef SymbolManager::getConjuredSymbol(Stmt* E, QualType T, unsigned Count,
56 const void* SymbolTag) {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000057
58 llvm::FoldingSetNodeID profile;
Ted Kremeneka880b662009-03-04 22:53:46 +000059 SymbolConjured::Profile(profile, E, T, Count, SymbolTag);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000060 void* InsertPos;
61
62 SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
63
64 if (SD)
65 return SD->getSymbol();
66
Ted Kremenek361fa8e2008-03-12 21:45:47 +000067 SD = (SymbolData*) BPAlloc.Allocate<SymbolConjured>();
Ted Kremeneka880b662009-03-04 22:53:46 +000068 new (SD) SymbolConjured(SymbolCounter, E, T, Count, SymbolTag);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000069
70 DataSet.InsertNode(SD, InsertPos);
71 DataMap[SymbolCounter] = SD;
72
73 return SymbolCounter++;
74}
75
Ted Kremenek2dabd432008-12-05 02:27:51 +000076const SymbolData& SymbolManager::getSymbolData(SymbolRef Sym) const {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000077 DataMapTy::const_iterator I = DataMap.find(Sym);
78 assert (I != DataMap.end());
79 return *I->second;
80}
81
Ted Kremenekd70d0b02008-02-16 01:12:31 +000082
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +000083QualType SymbolConjured::getType(ASTContext&) const {
84 return T;
85}
Ted Kremenekd763eb92008-02-26 02:15:56 +000086
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +000087QualType SymbolRegionRValue::getType(ASTContext& C) const {
88 if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
89 return TR->getRValueType(C);
90
91 return QualType();
Ted Kremenekd70d0b02008-02-16 01:12:31 +000092}
93
Ted Kremenekd70d0b02008-02-16 01:12:31 +000094SymbolManager::~SymbolManager() {}
Ted Kremenek241677a2009-01-21 22:26:05 +000095
96void SymbolReaper::markLive(SymbolRef sym) {
97 TheLiving = F.Add(TheLiving, sym);
98 TheDead = F.Remove(TheDead, sym);
99}
100
101bool SymbolReaper::maybeDead(SymbolRef sym) {
102 if (isLive(sym))
103 return false;
104
105 TheDead = F.Add(TheDead, sym);
106 return true;
107}
108
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000109bool SymbolReaper::isLive(SymbolRef sym) {
Ted Kremenekdcb6a262009-01-22 18:51:33 +0000110 if (TheLiving.contains(sym))
111 return true;
112
113 // Interogate the symbol. It may derive from an input value to
114 // the analyzed function/method.
115 return isa<SymbolRegionRValue>(SymMgr.getSymbolData(sym));
Ted Kremenek241677a2009-01-21 22:26:05 +0000116}
Ted Kremenek5216ad72009-02-14 03:16:10 +0000117
118SymbolVisitor::~SymbolVisitor() {}