| //== 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() {} |