diff options
Diffstat (limited to 'clang/lib/Analysis/SymbolManager.cpp')
-rw-r--r-- | clang/lib/Analysis/SymbolManager.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/clang/lib/Analysis/SymbolManager.cpp b/clang/lib/Analysis/SymbolManager.cpp new file mode 100644 index 00000000000..f243fa667b3 --- /dev/null +++ b/clang/lib/Analysis/SymbolManager.cpp @@ -0,0 +1,124 @@ +//== 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<ParmVarDecl>(D) || D->hasGlobalStorage()); + + llvm::FoldingSetNodeID profile; + + ParmVarDecl* PD = dyn_cast<ParmVarDecl>(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<SymbolDataParmVar>(); + new (SD) SymbolDataParmVar(SymbolCounter, PD); + } + else { + SD = (SymbolData*) BPAlloc.Allocate<SymbolDataGlobalVar>(); + 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<SymbolDataContentsOf>(); + new (SD) SymbolDataContentsOf(SymbolCounter, sym); + + + DataSet.InsertNode(SD, InsertPos); + DataMap[SymbolCounter] = SD; + + return SymbolCounter++; +} + +SymbolID SymbolManager::getConjuredSymbol(Expr* E, unsigned Count) { + + llvm::FoldingSetNodeID profile; + SymbolConjured::Profile(profile, E, Count); + void* InsertPos; + + SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos); + + if (SD) + return SD->getSymbol(); + + SD = (SymbolData*) BPAlloc.Allocate<SymbolConjured>(); + new (SD) SymbolConjured(SymbolCounter, E, 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<SymbolDataParmVar>(this)->getDecl()->getType(); + + case GlobalKind: + return cast<SymbolDataGlobalVar>(this)->getDecl()->getType(); + + case ContentsOfKind: { + SymbolID x = cast<SymbolDataContentsOf>(this)->getContainerSymbol(); + QualType T = SymMgr.getSymbolData(x).getType(SymMgr); + return T->getAsPointerType()->getPointeeType(); + } + + case ConjuredKind: + return cast<SymbolConjured>(this)->getExpr()->getType(); + } +} + +SymbolManager::~SymbolManager() {} |