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