123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353 |
- //== MemRegion.cpp - Abstract memory regions for static analysis --*- 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 MemRegion and its subclasses. MemRegion defines a
- // partially-typed abstraction of memory useful for path-sensitive dataflow
- // analyses.
- //
- //===----------------------------------------------------------------------===//
- #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
- #include "clang/AST/Attr.h"
- #include "clang/AST/CharUnits.h"
- #include "clang/AST/DeclObjC.h"
- #include "clang/AST/RecordLayout.h"
- #include "clang/Analysis/AnalysisContext.h"
- #include "clang/Analysis/Support/BumpVector.h"
- #include "clang/Basic/SourceManager.h"
- #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
- #include "llvm/Support/raw_ostream.h"
- using namespace clang;
- using namespace ento;
- //===----------------------------------------------------------------------===//
- // MemRegion Construction.
- //===----------------------------------------------------------------------===//
- template<typename RegionTy> struct MemRegionManagerTrait;
- template <typename RegionTy, typename A1>
- RegionTy* MemRegionManager::getRegion(const A1 a1) {
- const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
- MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
- llvm::FoldingSetNodeID ID;
- RegionTy::ProfileRegion(ID, a1, superRegion);
- void *InsertPos;
- RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
- InsertPos));
- if (!R) {
- R = (RegionTy*) A.Allocate<RegionTy>();
- new (R) RegionTy(a1, superRegion);
- Regions.InsertNode(R, InsertPos);
- }
- return R;
- }
- template <typename RegionTy, typename A1>
- RegionTy* MemRegionManager::getSubRegion(const A1 a1,
- const MemRegion *superRegion) {
- llvm::FoldingSetNodeID ID;
- RegionTy::ProfileRegion(ID, a1, superRegion);
- void *InsertPos;
- RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
- InsertPos));
- if (!R) {
- R = (RegionTy*) A.Allocate<RegionTy>();
- new (R) RegionTy(a1, superRegion);
- Regions.InsertNode(R, InsertPos);
- }
- return R;
- }
- template <typename RegionTy, typename A1, typename A2>
- RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
- const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
- MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
- llvm::FoldingSetNodeID ID;
- RegionTy::ProfileRegion(ID, a1, a2, superRegion);
- void *InsertPos;
- RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
- InsertPos));
- if (!R) {
- R = (RegionTy*) A.Allocate<RegionTy>();
- new (R) RegionTy(a1, a2, superRegion);
- Regions.InsertNode(R, InsertPos);
- }
- return R;
- }
- template <typename RegionTy, typename A1, typename A2>
- RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
- const MemRegion *superRegion) {
- llvm::FoldingSetNodeID ID;
- RegionTy::ProfileRegion(ID, a1, a2, superRegion);
- void *InsertPos;
- RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
- InsertPos));
- if (!R) {
- R = (RegionTy*) A.Allocate<RegionTy>();
- new (R) RegionTy(a1, a2, superRegion);
- Regions.InsertNode(R, InsertPos);
- }
- return R;
- }
- template <typename RegionTy, typename A1, typename A2, typename A3>
- RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
- const MemRegion *superRegion) {
- llvm::FoldingSetNodeID ID;
- RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
- void *InsertPos;
- RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
- InsertPos));
- if (!R) {
- R = (RegionTy*) A.Allocate<RegionTy>();
- new (R) RegionTy(a1, a2, a3, superRegion);
- Regions.InsertNode(R, InsertPos);
- }
- return R;
- }
- //===----------------------------------------------------------------------===//
- // Object destruction.
- //===----------------------------------------------------------------------===//
- MemRegion::~MemRegion() {}
- MemRegionManager::~MemRegionManager() {
- // All regions and their data are BumpPtrAllocated. No need to call
- // their destructors.
- }
- //===----------------------------------------------------------------------===//
- // Basic methods.
- //===----------------------------------------------------------------------===//
- bool SubRegion::isSubRegionOf(const MemRegion* R) const {
- const MemRegion* r = getSuperRegion();
- while (r != 0) {
- if (r == R)
- return true;
- if (const SubRegion* sr = dyn_cast<SubRegion>(r))
- r = sr->getSuperRegion();
- else
- break;
- }
- return false;
- }
- MemRegionManager* SubRegion::getMemRegionManager() const {
- const SubRegion* r = this;
- do {
- const MemRegion *superRegion = r->getSuperRegion();
- if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
- r = sr;
- continue;
- }
- return superRegion->getMemRegionManager();
- } while (1);
- }
- const StackFrameContext *VarRegion::getStackFrame() const {
- const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
- return SSR ? SSR->getStackFrame() : NULL;
- }
- //===----------------------------------------------------------------------===//
- // Region extents.
- //===----------------------------------------------------------------------===//
- DefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const {
- ASTContext &Ctx = svalBuilder.getContext();
- QualType T = getDesugaredValueType(Ctx);
- if (isa<VariableArrayType>(T))
- return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
- if (isa<IncompleteArrayType>(T))
- return UnknownVal();
- CharUnits size = Ctx.getTypeSizeInChars(T);
- QualType sizeTy = svalBuilder.getArrayIndexType();
- return svalBuilder.makeIntVal(size.getQuantity(), sizeTy);
- }
- DefinedOrUnknownSVal FieldRegion::getExtent(SValBuilder &svalBuilder) const {
- DefinedOrUnknownSVal Extent = DeclRegion::getExtent(svalBuilder);
- // A zero-length array at the end of a struct often stands for dynamically-
- // allocated extra memory.
- if (Extent.isZeroConstant()) {
- QualType T = getDesugaredValueType(svalBuilder.getContext());
- if (isa<ConstantArrayType>(T))
- return UnknownVal();
- }
- return Extent;
- }
- DefinedOrUnknownSVal AllocaRegion::getExtent(SValBuilder &svalBuilder) const {
- return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
- }
- DefinedOrUnknownSVal SymbolicRegion::getExtent(SValBuilder &svalBuilder) const {
- return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this));
- }
- DefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const {
- return svalBuilder.makeIntVal(getStringLiteral()->getByteLength()+1,
- svalBuilder.getArrayIndexType());
- }
- ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg)
- : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
- const ObjCIvarDecl *ObjCIvarRegion::getDecl() const {
- return cast<ObjCIvarDecl>(D);
- }
- QualType ObjCIvarRegion::getValueType() const {
- return getDecl()->getType();
- }
- QualType CXXBaseObjectRegion::getValueType() const {
- return QualType(getDecl()->getTypeForDecl(), 0);
- }
- //===----------------------------------------------------------------------===//
- // FoldingSet profiling.
- //===----------------------------------------------------------------------===//
- void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
- ID.AddInteger((unsigned)getKind());
- }
- void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddInteger((unsigned)getKind());
- ID.AddPointer(getStackFrame());
- }
- void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddInteger((unsigned)getKind());
- ID.AddPointer(getCodeRegion());
- }
- void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
- const StringLiteral* Str,
- const MemRegion* superRegion) {
- ID.AddInteger((unsigned) StringRegionKind);
- ID.AddPointer(Str);
- ID.AddPointer(superRegion);
- }
- void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
- const ObjCStringLiteral* Str,
- const MemRegion* superRegion) {
- ID.AddInteger((unsigned) ObjCStringRegionKind);
- ID.AddPointer(Str);
- ID.AddPointer(superRegion);
- }
- void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
- const Expr *Ex, unsigned cnt,
- const MemRegion *superRegion) {
- ID.AddInteger((unsigned) AllocaRegionKind);
- ID.AddPointer(Ex);
- ID.AddInteger(cnt);
- ID.AddPointer(superRegion);
- }
- void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
- ProfileRegion(ID, Ex, Cnt, superRegion);
- }
- void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
- CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
- }
- void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
- const CompoundLiteralExpr *CL,
- const MemRegion* superRegion) {
- ID.AddInteger((unsigned) CompoundLiteralRegionKind);
- ID.AddPointer(CL);
- ID.AddPointer(superRegion);
- }
- void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
- const PointerType *PT,
- const MemRegion *sRegion) {
- ID.AddInteger((unsigned) CXXThisRegionKind);
- ID.AddPointer(PT);
- ID.AddPointer(sRegion);
- }
- void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
- CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
- }
- void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
- const ObjCIvarDecl *ivd,
- const MemRegion* superRegion) {
- DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind);
- }
- void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
- const MemRegion* superRegion, Kind k) {
- ID.AddInteger((unsigned) k);
- ID.AddPointer(D);
- ID.AddPointer(superRegion);
- }
- void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
- DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
- }
- void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
- VarRegion::ProfileRegion(ID, getDecl(), superRegion);
- }
- void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
- const MemRegion *sreg) {
- ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
- ID.Add(sym);
- ID.AddPointer(sreg);
- }
- void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
- SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
- }
- void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
- QualType ElementType, SVal Idx,
- const MemRegion* superRegion) {
- ID.AddInteger(MemRegion::ElementRegionKind);
- ID.Add(ElementType);
- ID.AddPointer(superRegion);
- Idx.Profile(ID);
- }
- void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
- ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
- }
- void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
- const NamedDecl *FD,
- const MemRegion*) {
- ID.AddInteger(MemRegion::FunctionTextRegionKind);
- ID.AddPointer(FD);
- }
- void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
- FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
- }
- void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
- const BlockDecl *BD, CanQualType,
- const AnalysisDeclContext *AC,
- const MemRegion*) {
- ID.AddInteger(MemRegion::BlockTextRegionKind);
- ID.AddPointer(BD);
- }
- void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
- BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
- }
- void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
- const BlockTextRegion *BC,
- const LocationContext *LC,
- const MemRegion *sReg) {
- ID.AddInteger(MemRegion::BlockDataRegionKind);
- ID.AddPointer(BC);
- ID.AddPointer(LC);
- ID.AddPointer(sReg);
- }
- void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
- BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
- }
- void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
- Expr const *Ex,
- const MemRegion *sReg) {
- ID.AddPointer(Ex);
- ID.AddPointer(sReg);
- }
- void CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
- ProfileRegion(ID, Ex, getSuperRegion());
- }
- void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
- const CXXRecordDecl *RD,
- bool IsVirtual,
- const MemRegion *SReg) {
- ID.AddPointer(RD);
- ID.AddBoolean(IsVirtual);
- ID.AddPointer(SReg);
- }
- void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
- ProfileRegion(ID, getDecl(), isVirtual(), superRegion);
- }
- //===----------------------------------------------------------------------===//
- // Region anchors.
- //===----------------------------------------------------------------------===//
- void GlobalsSpaceRegion::anchor() { }
- void HeapSpaceRegion::anchor() { }
- void UnknownSpaceRegion::anchor() { }
- void StackLocalsSpaceRegion::anchor() { }
- void StackArgumentsSpaceRegion::anchor() { }
- void TypedRegion::anchor() { }
- void TypedValueRegion::anchor() { }
- void CodeTextRegion::anchor() { }
- void SubRegion::anchor() { }
- //===----------------------------------------------------------------------===//
- // Region pretty-printing.
- //===----------------------------------------------------------------------===//
- void MemRegion::dump() const {
- dumpToStream(llvm::errs());
- }
- std::string MemRegion::getString() const {
- std::string s;
- llvm::raw_string_ostream os(s);
- dumpToStream(os);
- return os.str();
- }
- void MemRegion::dumpToStream(raw_ostream &os) const {
- os << "<Unknown Region>";
- }
- void AllocaRegion::dumpToStream(raw_ostream &os) const {
- os << "alloca{" << (const void*) Ex << ',' << Cnt << '}';
- }
- void FunctionTextRegion::dumpToStream(raw_ostream &os) const {
- os << "code{" << getDecl()->getDeclName().getAsString() << '}';
- }
- void BlockTextRegion::dumpToStream(raw_ostream &os) const {
- os << "block_code{" << (const void*) this << '}';
- }
- void BlockDataRegion::dumpToStream(raw_ostream &os) const {
- os << "block_data{" << BC << '}';
- }
- void CompoundLiteralRegion::dumpToStream(raw_ostream &os) const {
- // FIXME: More elaborate pretty-printing.
- os << "{ " << (const void*) CL << " }";
- }
- void CXXTempObjectRegion::dumpToStream(raw_ostream &os) const {
- os << "temp_object{" << getValueType().getAsString() << ','
- << (const void*) Ex << '}';
- }
- void CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {
- os << "base{" << superRegion << ',' << getDecl()->getName() << '}';
- }
- void CXXThisRegion::dumpToStream(raw_ostream &os) const {
- os << "this";
- }
- void ElementRegion::dumpToStream(raw_ostream &os) const {
- os << "element{" << superRegion << ','
- << Index << ',' << getElementType().getAsString() << '}';
- }
- void FieldRegion::dumpToStream(raw_ostream &os) const {
- os << superRegion << "->" << *getDecl();
- }
- void ObjCIvarRegion::dumpToStream(raw_ostream &os) const {
- os << "ivar{" << superRegion << ',' << *getDecl() << '}';
- }
- void StringRegion::dumpToStream(raw_ostream &os) const {
- Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts()));
- }
- void ObjCStringRegion::dumpToStream(raw_ostream &os) const {
- Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts()));
- }
- void SymbolicRegion::dumpToStream(raw_ostream &os) const {
- os << "SymRegion{" << sym << '}';
- }
- void VarRegion::dumpToStream(raw_ostream &os) const {
- os << *cast<VarDecl>(D);
- }
- void RegionRawOffset::dump() const {
- dumpToStream(llvm::errs());
- }
- void RegionRawOffset::dumpToStream(raw_ostream &os) const {
- os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}';
- }
- void StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const {
- os << "StaticGlobalsMemSpace{" << CR << '}';
- }
- void GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const {
- os << "GlobalInternalSpaceRegion";
- }
- void GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const {
- os << "GlobalSystemSpaceRegion";
- }
- void GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const {
- os << "GlobalImmutableSpaceRegion";
- }
- void HeapSpaceRegion::dumpToStream(raw_ostream &os) const {
- os << "HeapSpaceRegion";
- }
- void UnknownSpaceRegion::dumpToStream(raw_ostream &os) const {
- os << "UnknownSpaceRegion";
- }
- void StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const {
- os << "StackArgumentsSpaceRegion";
- }
- void StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const {
- os << "StackLocalsSpaceRegion";
- }
- bool MemRegion::canPrintPretty() const {
- return false;
- }
- void MemRegion::printPretty(raw_ostream &os) const {
- return;
- }
- bool VarRegion::canPrintPretty() const {
- return true;
- }
- void VarRegion::printPretty(raw_ostream &os) const {
- os << getDecl()->getName();
- }
- bool ObjCIvarRegion::canPrintPretty() const {
- return true;
- }
- void ObjCIvarRegion::printPretty(raw_ostream &os) const {
- os << getDecl()->getName();
- }
- bool FieldRegion::canPrintPretty() const {
- return superRegion->canPrintPretty();
- }
- void FieldRegion::printPretty(raw_ostream &os) const {
- superRegion->printPretty(os);
- os << "." << getDecl()->getName();
- }
- //===----------------------------------------------------------------------===//
- // MemRegionManager methods.
- //===----------------------------------------------------------------------===//
- template <typename REG>
- const REG *MemRegionManager::LazyAllocate(REG*& region) {
- if (!region) {
- region = (REG*) A.Allocate<REG>();
- new (region) REG(this);
- }
- return region;
- }
- template <typename REG, typename ARG>
- const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
- if (!region) {
- region = (REG*) A.Allocate<REG>();
- new (region) REG(this, a);
- }
- return region;
- }
- const StackLocalsSpaceRegion*
- MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
- assert(STC);
- StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC];
- if (R)
- return R;
- R = A.Allocate<StackLocalsSpaceRegion>();
- new (R) StackLocalsSpaceRegion(this, STC);
- return R;
- }
- const StackArgumentsSpaceRegion *
- MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
- assert(STC);
- StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC];
- if (R)
- return R;
- R = A.Allocate<StackArgumentsSpaceRegion>();
- new (R) StackArgumentsSpaceRegion(this, STC);
- return R;
- }
- const GlobalsSpaceRegion
- *MemRegionManager::getGlobalsRegion(MemRegion::Kind K,
- const CodeTextRegion *CR) {
- if (!CR) {
- if (K == MemRegion::GlobalSystemSpaceRegionKind)
- return LazyAllocate(SystemGlobals);
- if (K == MemRegion::GlobalImmutableSpaceRegionKind)
- return LazyAllocate(ImmutableGlobals);
- assert(K == MemRegion::GlobalInternalSpaceRegionKind);
- return LazyAllocate(InternalGlobals);
- }
- assert(K == MemRegion::StaticGlobalSpaceRegionKind);
- StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR];
- if (R)
- return R;
- R = A.Allocate<StaticGlobalSpaceRegion>();
- new (R) StaticGlobalSpaceRegion(this, CR);
- return R;
- }
- const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
- return LazyAllocate(heap);
- }
- const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
- return LazyAllocate(unknown);
- }
- const MemSpaceRegion *MemRegionManager::getCodeRegion() {
- return LazyAllocate(code);
- }
- //===----------------------------------------------------------------------===//
- // Constructing regions.
- //===----------------------------------------------------------------------===//
- const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
- return getSubRegion<StringRegion>(Str, getGlobalsRegion());
- }
- const ObjCStringRegion *
- MemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){
- return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion());
- }
- /// Look through a chain of LocationContexts to either find the
- /// StackFrameContext that matches a DeclContext, or find a VarRegion
- /// for a variable captured by a block.
- static llvm::PointerUnion<const StackFrameContext *, const VarRegion *>
- getStackOrCaptureRegionForDeclContext(const LocationContext *LC,
- const DeclContext *DC,
- const VarDecl *VD) {
- while (LC) {
- if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) {
- if (cast<DeclContext>(SFC->getDecl()) == DC)
- return SFC;
- }
- if (const BlockInvocationContext *BC =
- dyn_cast<BlockInvocationContext>(LC)) {
- const BlockDataRegion *BR =
- static_cast<const BlockDataRegion*>(BC->getContextData());
- // FIXME: This can be made more efficient.
- for (BlockDataRegion::referenced_vars_iterator
- I = BR->referenced_vars_begin(),
- E = BR->referenced_vars_end(); I != E; ++I) {
- if (const VarRegion *VR = dyn_cast<VarRegion>(I.getOriginalRegion()))
- if (VR->getDecl() == VD)
- return cast<VarRegion>(I.getCapturedRegion());
- }
- }
-
- LC = LC->getParent();
- }
- return (const StackFrameContext*)0;
- }
- const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
- const LocationContext *LC) {
- const MemRegion *sReg = 0;
- if (D->hasGlobalStorage() && !D->isStaticLocal()) {
- // First handle the globals defined in system headers.
- if (C.getSourceManager().isInSystemHeader(D->getLocation())) {
- // Whitelist the system globals which often DO GET modified, assume the
- // rest are immutable.
- if (D->getName().find("errno") != StringRef::npos)
- sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind);
- else
- sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
- // Treat other globals as GlobalInternal unless they are constants.
- } else {
- QualType GQT = D->getType();
- const Type *GT = GQT.getTypePtrOrNull();
- // TODO: We could walk the complex types here and see if everything is
- // constified.
- if (GT && GQT.isConstQualified() && GT->isArithmeticType())
- sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
- else
- sReg = getGlobalsRegion();
- }
-
- // Finally handle static locals.
- } else {
- // FIXME: Once we implement scope handling, we will need to properly lookup
- // 'D' to the proper LocationContext.
- const DeclContext *DC = D->getDeclContext();
- llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V =
- getStackOrCaptureRegionForDeclContext(LC, DC, D);
-
- if (V.is<const VarRegion*>())
- return V.get<const VarRegion*>();
-
- const StackFrameContext *STC = V.get<const StackFrameContext*>();
- if (!STC)
- sReg = getUnknownRegion();
- else {
- if (D->hasLocalStorage()) {
- sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
- ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
- : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
- }
- else {
- assert(D->isStaticLocal());
- const Decl *STCD = STC->getDecl();
- if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD))
- sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
- getFunctionTextRegion(cast<NamedDecl>(STCD)));
- else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) {
- const BlockTextRegion *BTR =
- getBlockTextRegion(BD,
- C.getCanonicalType(BD->getSignatureAsWritten()->getType()),
- STC->getAnalysisDeclContext());
- sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind,
- BTR);
- }
- else {
- sReg = getGlobalsRegion();
- }
- }
- }
- }
- return getSubRegion<VarRegion>(D, sReg);
- }
- const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
- const MemRegion *superR) {
- return getSubRegion<VarRegion>(D, superR);
- }
- const BlockDataRegion *
- MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
- const LocationContext *LC) {
- const MemRegion *sReg = 0;
- const BlockDecl *BD = BC->getDecl();
- if (!BD->hasCaptures()) {
- // This handles 'static' blocks.
- sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
- }
- else {
- if (LC) {
- // FIXME: Once we implement scope handling, we want the parent region
- // to be the scope.
- const StackFrameContext *STC = LC->getCurrentStackFrame();
- assert(STC);
- sReg = getStackLocalsRegion(STC);
- }
- else {
- // We allow 'LC' to be NULL for cases where want BlockDataRegions
- // without context-sensitivity.
- sReg = getUnknownRegion();
- }
- }
- return getSubRegion<BlockDataRegion>(BC, LC, sReg);
- }
- const CompoundLiteralRegion*
- MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
- const LocationContext *LC) {
- const MemRegion *sReg = 0;
- if (CL->isFileScope())
- sReg = getGlobalsRegion();
- else {
- const StackFrameContext *STC = LC->getCurrentStackFrame();
- assert(STC);
- sReg = getStackLocalsRegion(STC);
- }
- return getSubRegion<CompoundLiteralRegion>(CL, sReg);
- }
- const ElementRegion*
- MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
- const MemRegion* superRegion,
- ASTContext &Ctx){
- QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
- llvm::FoldingSetNodeID ID;
- ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
- void *InsertPos;
- MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
- ElementRegion* R = cast_or_null<ElementRegion>(data);
- if (!R) {
- R = (ElementRegion*) A.Allocate<ElementRegion>();
- new (R) ElementRegion(T, Idx, superRegion);
- Regions.InsertNode(R, InsertPos);
- }
- return R;
- }
- const FunctionTextRegion *
- MemRegionManager::getFunctionTextRegion(const NamedDecl *FD) {
- return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
- }
- const BlockTextRegion *
- MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
- AnalysisDeclContext *AC) {
- return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
- }
- /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
- const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
- return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
- }
- const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) {
- return getSubRegion<SymbolicRegion>(Sym, getHeapRegion());
- }
- const FieldRegion*
- MemRegionManager::getFieldRegion(const FieldDecl *d,
- const MemRegion* superRegion){
- return getSubRegion<FieldRegion>(d, superRegion);
- }
- const ObjCIvarRegion*
- MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d,
- const MemRegion* superRegion) {
- return getSubRegion<ObjCIvarRegion>(d, superRegion);
- }
- const CXXTempObjectRegion*
- MemRegionManager::getCXXTempObjectRegion(Expr const *E,
- LocationContext const *LC) {
- const StackFrameContext *SFC = LC->getCurrentStackFrame();
- assert(SFC);
- return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC));
- }
- /// Checks whether \p BaseClass is a valid virtual or direct non-virtual base
- /// class of the type of \p Super.
- static bool isValidBaseClass(const CXXRecordDecl *BaseClass,
- const TypedValueRegion *Super,
- bool IsVirtual) {
- BaseClass = BaseClass->getCanonicalDecl();
- const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl();
- if (!Class)
- return true;
- if (IsVirtual)
- return Class->isVirtuallyDerivedFrom(BaseClass);
- for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
- E = Class->bases_end();
- I != E; ++I) {
- if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
- return true;
- }
- return false;
- }
- const CXXBaseObjectRegion *
- MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
- const MemRegion *Super,
- bool IsVirtual) {
- if (isa<TypedValueRegion>(Super)) {
- assert(isValidBaseClass(RD, dyn_cast<TypedValueRegion>(Super), IsVirtual));
- (void)isValidBaseClass;
- if (IsVirtual) {
- // Virtual base regions should not be layered, since the layout rules
- // are different.
- while (const CXXBaseObjectRegion *Base =
- dyn_cast<CXXBaseObjectRegion>(Super)) {
- Super = Base->getSuperRegion();
- }
- assert(Super && !isa<MemSpaceRegion>(Super));
- }
- }
- return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
- }
- const CXXThisRegion*
- MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
- const LocationContext *LC) {
- const StackFrameContext *STC = LC->getCurrentStackFrame();
- assert(STC);
- const PointerType *PT = thisPointerTy->getAs<PointerType>();
- assert(PT);
- return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
- }
- const AllocaRegion*
- MemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt,
- const LocationContext *LC) {
- const StackFrameContext *STC = LC->getCurrentStackFrame();
- assert(STC);
- return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
- }
- const MemSpaceRegion *MemRegion::getMemorySpace() const {
- const MemRegion *R = this;
- const SubRegion* SR = dyn_cast<SubRegion>(this);
- while (SR) {
- R = SR->getSuperRegion();
- SR = dyn_cast<SubRegion>(R);
- }
- return dyn_cast<MemSpaceRegion>(R);
- }
- bool MemRegion::hasStackStorage() const {
- return isa<StackSpaceRegion>(getMemorySpace());
- }
- bool MemRegion::hasStackNonParametersStorage() const {
- return isa<StackLocalsSpaceRegion>(getMemorySpace());
- }
- bool MemRegion::hasStackParametersStorage() const {
- return isa<StackArgumentsSpaceRegion>(getMemorySpace());
- }
- bool MemRegion::hasGlobalsOrParametersStorage() const {
- const MemSpaceRegion *MS = getMemorySpace();
- return isa<StackArgumentsSpaceRegion>(MS) ||
- isa<GlobalsSpaceRegion>(MS);
- }
- // getBaseRegion strips away all elements and fields, and get the base region
- // of them.
- const MemRegion *MemRegion::getBaseRegion() const {
- const MemRegion *R = this;
- while (true) {
- switch (R->getKind()) {
- case MemRegion::ElementRegionKind:
- case MemRegion::FieldRegionKind:
- case MemRegion::ObjCIvarRegionKind:
- case MemRegion::CXXBaseObjectRegionKind:
- R = cast<SubRegion>(R)->getSuperRegion();
- continue;
- default:
- break;
- }
- break;
- }
- return R;
- }
- bool MemRegion::isSubRegionOf(const MemRegion *R) const {
- return false;
- }
- //===----------------------------------------------------------------------===//
- // View handling.
- //===----------------------------------------------------------------------===//
- const MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const {
- const MemRegion *R = this;
- while (true) {
- switch (R->getKind()) {
- case ElementRegionKind: {
- const ElementRegion *ER = cast<ElementRegion>(R);
- if (!ER->getIndex().isZeroConstant())
- return R;
- R = ER->getSuperRegion();
- break;
- }
- case CXXBaseObjectRegionKind:
- if (!StripBaseCasts)
- return R;
- R = cast<CXXBaseObjectRegion>(R)->getSuperRegion();
- break;
- default:
- return R;
- }
- }
- }
- // FIXME: Merge with the implementation of the same method in Store.cpp
- static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
- if (const RecordType *RT = Ty->getAs<RecordType>()) {
- const RecordDecl *D = RT->getDecl();
- if (!D->getDefinition())
- return false;
- }
- return true;
- }
- RegionRawOffset ElementRegion::getAsArrayOffset() const {
- CharUnits offset = CharUnits::Zero();
- const ElementRegion *ER = this;
- const MemRegion *superR = NULL;
- ASTContext &C = getContext();
- // FIXME: Handle multi-dimensional arrays.
- while (ER) {
- superR = ER->getSuperRegion();
- // FIXME: generalize to symbolic offsets.
- SVal index = ER->getIndex();
- if (Optional<nonloc::ConcreteInt> CI = index.getAs<nonloc::ConcreteInt>()) {
- // Update the offset.
- int64_t i = CI->getValue().getSExtValue();
- if (i != 0) {
- QualType elemType = ER->getElementType();
- // If we are pointing to an incomplete type, go no further.
- if (!IsCompleteType(C, elemType)) {
- superR = ER;
- break;
- }
- CharUnits size = C.getTypeSizeInChars(elemType);
- offset += (i * size);
- }
- // Go to the next ElementRegion (if any).
- ER = dyn_cast<ElementRegion>(superR);
- continue;
- }
- return NULL;
- }
- assert(superR && "super region cannot be NULL");
- return RegionRawOffset(superR, offset);
- }
- RegionOffset MemRegion::getAsOffset() const {
- const MemRegion *R = this;
- const MemRegion *SymbolicOffsetBase = 0;
- int64_t Offset = 0;
- while (1) {
- switch (R->getKind()) {
- case GenericMemSpaceRegionKind:
- case StackLocalsSpaceRegionKind:
- case StackArgumentsSpaceRegionKind:
- case HeapSpaceRegionKind:
- case UnknownSpaceRegionKind:
- case StaticGlobalSpaceRegionKind:
- case GlobalInternalSpaceRegionKind:
- case GlobalSystemSpaceRegionKind:
- case GlobalImmutableSpaceRegionKind:
- // Stores can bind directly to a region space to set a default value.
- assert(Offset == 0 && !SymbolicOffsetBase);
- goto Finish;
- case FunctionTextRegionKind:
- case BlockTextRegionKind:
- case BlockDataRegionKind:
- // These will never have bindings, but may end up having values requested
- // if the user does some strange casting.
- if (Offset != 0)
- SymbolicOffsetBase = R;
- goto Finish;
- case SymbolicRegionKind:
- case AllocaRegionKind:
- case CompoundLiteralRegionKind:
- case CXXThisRegionKind:
- case StringRegionKind:
- case ObjCStringRegionKind:
- case VarRegionKind:
- case CXXTempObjectRegionKind:
- // Usual base regions.
- goto Finish;
- case ObjCIvarRegionKind:
- // This is a little strange, but it's a compromise between
- // ObjCIvarRegions having unknown compile-time offsets (when using the
- // non-fragile runtime) and yet still being distinct, non-overlapping
- // regions. Thus we treat them as "like" base regions for the purposes
- // of computing offsets.
- goto Finish;
- case CXXBaseObjectRegionKind: {
- const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R);
- R = BOR->getSuperRegion();
- QualType Ty;
- if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) {
- Ty = TVR->getDesugaredValueType(getContext());
- } else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
- // If our base region is symbolic, we don't know what type it really is.
- // Pretend the type of the symbol is the true dynamic type.
- // (This will at least be self-consistent for the life of the symbol.)
- Ty = SR->getSymbol()->getType()->getPointeeType();
- }
-
- const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl();
- if (!Child) {
- // We cannot compute the offset of the base class.
- SymbolicOffsetBase = R;
- }
- // Don't bother calculating precise offsets if we already have a
- // symbolic offset somewhere in the chain.
- if (SymbolicOffsetBase)
- continue;
- CharUnits BaseOffset;
- const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child);
- if (BOR->isVirtual())
- BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl());
- else
- BaseOffset = Layout.getBaseClassOffset(BOR->getDecl());
- // The base offset is in chars, not in bits.
- Offset += BaseOffset.getQuantity() * getContext().getCharWidth();
- break;
- }
- case ElementRegionKind: {
- const ElementRegion *ER = cast<ElementRegion>(R);
- R = ER->getSuperRegion();
- QualType EleTy = ER->getValueType();
- if (!IsCompleteType(getContext(), EleTy)) {
- // We cannot compute the offset of the base class.
- SymbolicOffsetBase = R;
- continue;
- }
- SVal Index = ER->getIndex();
- if (Optional<nonloc::ConcreteInt> CI =
- Index.getAs<nonloc::ConcreteInt>()) {
- // Don't bother calculating precise offsets if we already have a
- // symbolic offset somewhere in the chain.
- if (SymbolicOffsetBase)
- continue;
- int64_t i = CI->getValue().getSExtValue();
- // This type size is in bits.
- Offset += i * getContext().getTypeSize(EleTy);
- } else {
- // We cannot compute offset for non-concrete index.
- SymbolicOffsetBase = R;
- }
- break;
- }
- case FieldRegionKind: {
- const FieldRegion *FR = cast<FieldRegion>(R);
- R = FR->getSuperRegion();
- const RecordDecl *RD = FR->getDecl()->getParent();
- if (RD->isUnion() || !RD->isCompleteDefinition()) {
- // We cannot compute offset for incomplete type.
- // For unions, we could treat everything as offset 0, but we'd rather
- // treat each field as a symbolic offset so they aren't stored on top
- // of each other, since we depend on things in typed regions actually
- // matching their types.
- SymbolicOffsetBase = R;
- }
- // Don't bother calculating precise offsets if we already have a
- // symbolic offset somewhere in the chain.
- if (SymbolicOffsetBase)
- continue;
- // Get the field number.
- unsigned idx = 0;
- for (RecordDecl::field_iterator FI = RD->field_begin(),
- FE = RD->field_end(); FI != FE; ++FI, ++idx)
- if (FR->getDecl() == *FI)
- break;
- const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
- // This is offset in bits.
- Offset += Layout.getFieldOffset(idx);
- break;
- }
- }
- }
- Finish:
- if (SymbolicOffsetBase)
- return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic);
- return RegionOffset(R, Offset);
- }
- //===----------------------------------------------------------------------===//
- // BlockDataRegion
- //===----------------------------------------------------------------------===//
- std::pair<const VarRegion *, const VarRegion *>
- BlockDataRegion::getCaptureRegions(const VarDecl *VD) {
- MemRegionManager &MemMgr = *getMemRegionManager();
- const VarRegion *VR = 0;
- const VarRegion *OriginalVR = 0;
- if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage()) {
- VR = MemMgr.getVarRegion(VD, this);
- OriginalVR = MemMgr.getVarRegion(VD, LC);
- }
- else {
- if (LC) {
- VR = MemMgr.getVarRegion(VD, LC);
- OriginalVR = VR;
- }
- else {
- VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
- OriginalVR = MemMgr.getVarRegion(VD, LC);
- }
- }
- return std::make_pair(VR, OriginalVR);
- }
- void BlockDataRegion::LazyInitializeReferencedVars() {
- if (ReferencedVars)
- return;
- AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext();
- AnalysisDeclContext::referenced_decls_iterator I, E;
- llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
- if (I == E) {
- ReferencedVars = (void*) 0x1;
- return;
- }
- MemRegionManager &MemMgr = *getMemRegionManager();
- llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
- BumpVectorContext BC(A);
- typedef BumpVector<const MemRegion*> VarVec;
- VarVec *BV = (VarVec*) A.Allocate<VarVec>();
- new (BV) VarVec(BC, E - I);
- VarVec *BVOriginal = (VarVec*) A.Allocate<VarVec>();
- new (BVOriginal) VarVec(BC, E - I);
- for ( ; I != E; ++I) {
- const VarRegion *VR = 0;
- const VarRegion *OriginalVR = 0;
- llvm::tie(VR, OriginalVR) = getCaptureRegions(*I);
- assert(VR);
- assert(OriginalVR);
- BV->push_back(VR, BC);
- BVOriginal->push_back(OriginalVR, BC);
- }
- ReferencedVars = BV;
- OriginalVars = BVOriginal;
- }
- BlockDataRegion::referenced_vars_iterator
- BlockDataRegion::referenced_vars_begin() const {
- const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
- BumpVector<const MemRegion*> *Vec =
- static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
- if (Vec == (void*) 0x1)
- return BlockDataRegion::referenced_vars_iterator(0, 0);
-
- BumpVector<const MemRegion*> *VecOriginal =
- static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
-
- return BlockDataRegion::referenced_vars_iterator(Vec->begin(),
- VecOriginal->begin());
- }
- BlockDataRegion::referenced_vars_iterator
- BlockDataRegion::referenced_vars_end() const {
- const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
- BumpVector<const MemRegion*> *Vec =
- static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
- if (Vec == (void*) 0x1)
- return BlockDataRegion::referenced_vars_iterator(0, 0);
-
- BumpVector<const MemRegion*> *VecOriginal =
- static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
- return BlockDataRegion::referenced_vars_iterator(Vec->end(),
- VecOriginal->end());
- }
- const VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const {
- for (referenced_vars_iterator I = referenced_vars_begin(),
- E = referenced_vars_end();
- I != E; ++I) {
- if (I.getCapturedRegion() == R)
- return I.getOriginalRegion();
- }
- return 0;
- }
|