blob: 45e1aae23bc59614dc8b665ca849879f820b23e9 [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 Kremenek9ab6b9c2009-01-22 18:23:34 +000055SymbolRef SymbolManager::getConjuredSymbol(Stmt* E, QualType T, unsigned Count){
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000056
57 llvm::FoldingSetNodeID profile;
Ted Kremenek60a6e0c2008-10-01 00:21:14 +000058 SymbolConjured::Profile(profile, E, T, Count);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000059 void* InsertPos;
60
61 SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos);
62
63 if (SD)
64 return SD->getSymbol();
65
Ted Kremenek361fa8e2008-03-12 21:45:47 +000066 SD = (SymbolData*) BPAlloc.Allocate<SymbolConjured>();
Ted Kremenek60a6e0c2008-10-01 00:21:14 +000067 new (SD) SymbolConjured(SymbolCounter, E, T, Count);
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000068
69 DataSet.InsertNode(SD, InsertPos);
70 DataMap[SymbolCounter] = SD;
71
72 return SymbolCounter++;
73}
74
Ted Kremenek2dabd432008-12-05 02:27:51 +000075const SymbolData& SymbolManager::getSymbolData(SymbolRef Sym) const {
Ted Kremenek00a3a5f2008-03-12 01:21:45 +000076 DataMapTy::const_iterator I = DataMap.find(Sym);
77 assert (I != DataMap.end());
78 return *I->second;
79}
80
Ted Kremenekd70d0b02008-02-16 01:12:31 +000081
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +000082QualType SymbolConjured::getType(ASTContext&) const {
83 return T;
84}
Ted Kremenekd763eb92008-02-26 02:15:56 +000085
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +000086QualType SymbolRegionRValue::getType(ASTContext& C) const {
87 if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
88 return TR->getRValueType(C);
89
90 return QualType();
Ted Kremenekd70d0b02008-02-16 01:12:31 +000091}
92
Ted Kremenekd70d0b02008-02-16 01:12:31 +000093SymbolManager::~SymbolManager() {}
Ted Kremenek241677a2009-01-21 22:26:05 +000094
95void SymbolReaper::markLive(SymbolRef sym) {
96 TheLiving = F.Add(TheLiving, sym);
97 TheDead = F.Remove(TheDead, sym);
98}
99
100bool SymbolReaper::maybeDead(SymbolRef sym) {
101 if (isLive(sym))
102 return false;
103
104 TheDead = F.Add(TheDead, sym);
105 return true;
106}
107
Ted Kremenek9ab6b9c2009-01-22 18:23:34 +0000108bool SymbolReaper::isLive(SymbolRef sym) {
Ted Kremenekdcb6a262009-01-22 18:51:33 +0000109 if (TheLiving.contains(sym))
110 return true;
111
112 // Interogate the symbol. It may derive from an input value to
113 // the analyzed function/method.
114 return isa<SymbolRegionRValue>(SymMgr.getSymbolData(sym));
Ted Kremenek241677a2009-01-21 22:26:05 +0000115}
Ted Kremenek5216ad72009-02-14 03:16:10 +0000116
117SymbolVisitor::~SymbolVisitor() {}