From: Zhongxing Xu Date: Wed, 19 Nov 2008 11:03:17 +0000 (+0000) Subject: Add SymbolData for array elements and struct fields. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=eabf776661662a8e652eb692084d20fddffd5cca;p=clang Add SymbolData for array elements and struct fields. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59618 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Analysis/PathSensitive/SVals.h index 7a1a87e34b..417a89adc8 100644 --- a/include/clang/Analysis/PathSensitive/SVals.h +++ b/include/clang/Analysis/PathSensitive/SVals.h @@ -73,6 +73,10 @@ public: } static SVal GetSymbolValue(SymbolManager& SymMgr, VarDecl *D); + static SVal getSymbolValue(SymbolManager& SymMgr, const MemRegion* R, + const llvm::APSInt* Idx, QualType T); + static SVal getSymbolValue(SymbolManager& SymMgr, const MemRegion* R, + const FieldDecl* FD, QualType T); inline bool isUnknown() const { return getRawKind() == UnknownKind; diff --git a/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Analysis/PathSensitive/SymbolManager.h index 66f214e436..53a6eecf44 100644 --- a/include/clang/Analysis/PathSensitive/SymbolManager.h +++ b/include/clang/Analysis/PathSensitive/SymbolManager.h @@ -24,7 +24,7 @@ namespace clang { - +class MemRegion; class SymbolManager; class SymbolID { @@ -69,7 +69,8 @@ namespace clang { class SymbolData : public llvm::FoldingSetNode { public: - enum Kind { UndefKind, ParmKind, GlobalKind, ContentsOfKind, ConjuredKind }; + enum Kind { UndefKind, ParmKind, GlobalKind, ElementKind, FieldKind, + ContentsOfKind, ConjuredKind }; private: Kind K; @@ -141,6 +142,52 @@ public: } }; +class SymbolDataElement : public SymbolData { + const MemRegion* R; + const llvm::APSInt* Idx; + +public: + SymbolDataElement(SymbolID MySym, const MemRegion* r, const llvm::APSInt* idx) + : SymbolData(ElementKind, MySym), R(r), Idx(idx) {} + + static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion* R, + const llvm::APSInt* Idx) { + profile.AddPointer(R); + profile.AddPointer(Idx); + } + + void Profile(llvm::FoldingSetNodeID& profile) { + Profile(profile, R, Idx); + } + + static bool classof(const SymbolData* D) { + return D->getKind() == ElementKind; + } +}; + +class SymbolDataField : public SymbolData { + const MemRegion* R; + const FieldDecl* D; + +public: + SymbolDataField(SymbolID MySym, const MemRegion* r, const FieldDecl* d) + : SymbolData(FieldKind, MySym), R(r), D(d) {} + + static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion* R, + const FieldDecl* D) { + profile.AddPointer(R); + profile.AddPointer(D); + } + + void Profile(llvm::FoldingSetNodeID& profile) { + Profile(profile, R, D); + } + + static bool classof(const SymbolData* D) { + return D->getKind() == FieldKind; + } +}; + class SymbolDataContentsOf : public SymbolData { SymbolID Sym; @@ -245,6 +292,8 @@ public: ~SymbolManager(); SymbolID getSymbol(VarDecl* D); + SymbolID getElementSymbol(const MemRegion* R, const llvm::APSInt* Idx); + SymbolID getFieldSymbol(const MemRegion* R, const FieldDecl* D); SymbolID getContentsOfSymbol(SymbolID sym); SymbolID getConjuredSymbol(Stmt* E, QualType T, unsigned VisitCount); SymbolID getConjuredSymbol(Expr* E, unsigned VisitCount) { diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp index 6b29ae7d42..644f60d25a 100644 --- a/lib/Analysis/SVals.cpp +++ b/lib/Analysis/SVals.cpp @@ -272,6 +272,22 @@ SVal SVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) { return nonloc::SymbolVal(SymMgr.getSymbol(D)); } +SVal SVal::getSymbolValue(SymbolManager& SymMgr, const MemRegion* R, + const llvm::APSInt* Idx, QualType T) { + if (Loc::IsLocType(T)) + return loc::SymbolVal(SymMgr.getElementSymbol(R, Idx)); + else + return nonloc::SymbolVal(SymMgr.getElementSymbol(R, Idx)); +} + +SVal SVal::getSymbolValue(SymbolManager& SymMgr, const MemRegion* R, + const FieldDecl* FD, QualType T) { + if (Loc::IsLocType(T)) + return loc::SymbolVal(SymMgr.getFieldSymbol(R, FD)); + else + return nonloc::SymbolVal(SymMgr.getFieldSymbol(R, FD)); +} + nonloc::LocAsInteger nonloc::LocAsInteger::Make(BasicValueFactory& Vals, Loc V, unsigned Bits) { return LocAsInteger(Vals.getPersistentSValWithData(V, Bits)); diff --git a/lib/Analysis/SymbolManager.cpp b/lib/Analysis/SymbolManager.cpp index 7829e3ace3..aee74a4a14 100644 --- a/lib/Analysis/SymbolManager.cpp +++ b/lib/Analysis/SymbolManager.cpp @@ -51,6 +51,41 @@ SymbolID SymbolManager::getSymbol(VarDecl* D) { DataMap[SymbolCounter] = SD; return SymbolCounter++; } + +SymbolID SymbolManager::getElementSymbol(const MemRegion* R, + const llvm::APSInt* Idx){ + llvm::FoldingSetNodeID ID; + SymbolDataElement::Profile(ID, R, Idx); + void* InsertPos; + SymbolData* SD = DataSet.FindNodeOrInsertPos(ID, InsertPos); + + if (SD) + return SD->getSymbol(); + + SD = (SymbolData*) BPAlloc.Allocate(); + new (SD) SymbolDataElement(SymbolCounter, R, Idx); + + DataSet.InsertNode(SD, InsertPos); + DataMap[SymbolCounter] = SD; + return SymbolCounter++; +} + +SymbolID SymbolManager::getFieldSymbol(const MemRegion* R, const FieldDecl* D) { + llvm::FoldingSetNodeID ID; + SymbolDataField::Profile(ID, R, D); + void* InsertPos; + SymbolData* SD = DataSet.FindNodeOrInsertPos(ID, InsertPos); + + if (SD) + return SD->getSymbol(); + + SD = (SymbolData*) BPAlloc.Allocate(); + new (SD) SymbolDataField(SymbolCounter, R, D); + + DataSet.InsertNode(SD, InsertPos); + DataMap[SymbolCounter] = SD; + return SymbolCounter++; +} SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) {