//== SymbolManager.h - Management of Symbolic Values ------------*- C++ -*--==// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines SymbolManager, a class that manages symbolic values // created for use by GRExprEngine and related classes. // //===----------------------------------------------------------------------===// #include "clang/Analysis/PathSensitive/SymbolManager.h" using namespace clang; SymbolID SymbolManager::getSymbol(VarDecl* D) { assert (isa(D) || isa(D) || D->hasGlobalStorage()); llvm::FoldingSetNodeID profile; ParmVarDecl* PD = dyn_cast(D); if (PD) SymbolDataParmVar::Profile(profile, PD); else SymbolDataGlobalVar::Profile(profile, D); void* InsertPos; SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos); if (SD) return SD->getSymbol(); if (PD) { SD = (SymbolData*) BPAlloc.Allocate(); new (SD) SymbolDataParmVar(SymbolCounter, PD); } else { SD = (SymbolData*) BPAlloc.Allocate(); new (SD) SymbolDataGlobalVar(SymbolCounter, D); } DataSet.InsertNode(SD, InsertPos); DataMap[SymbolCounter] = SD; return SymbolCounter++; } SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) { llvm::FoldingSetNodeID profile; SymbolDataContentsOf::Profile(profile, sym); void* InsertPos; SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos); if (SD) return SD->getSymbol(); SD = (SymbolData*) BPAlloc.Allocate(); new (SD) SymbolDataContentsOf(SymbolCounter, sym); DataSet.InsertNode(SD, InsertPos); DataMap[SymbolCounter] = SD; return SymbolCounter++; } SymbolID SymbolManager::getConjuredSymbol(Stmt* E, QualType T, unsigned Count) { llvm::FoldingSetNodeID profile; SymbolConjured::Profile(profile, E, T, Count); void* InsertPos; SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos); if (SD) return SD->getSymbol(); SD = (SymbolData*) BPAlloc.Allocate(); new (SD) SymbolConjured(SymbolCounter, E, T, Count); DataSet.InsertNode(SD, InsertPos); DataMap[SymbolCounter] = SD; return SymbolCounter++; } const SymbolData& SymbolManager::getSymbolData(SymbolID Sym) const { DataMapTy::const_iterator I = DataMap.find(Sym); assert (I != DataMap.end()); return *I->second; } QualType SymbolData::getType(const SymbolManager& SymMgr) const { switch (getKind()) { default: assert (false && "getType() not implemented for this symbol."); case ParmKind: return cast(this)->getDecl()->getType(); case GlobalKind: return cast(this)->getDecl()->getType(); case ContentsOfKind: { SymbolID x = cast(this)->getContainerSymbol(); QualType T = SymMgr.getSymbolData(x).getType(SymMgr); return T->getAsPointerType()->getPointeeType(); } case ConjuredKind: return cast(this)->getType(); } } SymbolManager::~SymbolManager() {}