From: Ted Kremenek Date: Tue, 7 Oct 2008 23:09:49 +0000 (+0000) Subject: Migrate DeclStmt over to using a DeclGroup instead of a pointer to a ScopedDecl*. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8ffb159441e923322bef6b5dee1aaf24c738d75e;p=clang Migrate DeclStmt over to using a DeclGroup instead of a pointer to a ScopedDecl*. This also removes the ugly hack needed in CFG.cpp for subclassing DeclStmt to create a DeclStmt with one Decl*. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57275 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 1111bd31e1..f6216eeeef 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -18,6 +18,7 @@ #include "llvm/Support/raw_ostream.h" #include "clang/Basic/SourceLocation.h" #include "clang/AST/StmtIterator.h" +#include "clang/AST/DeclGroup.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/iterator.h" #include "llvm/Bitcode/SerializationFwd.h" @@ -141,33 +142,37 @@ public: /// class DeclStmt : public Stmt { protected: - ScopedDecl *TheDecl; + DeclGroupOwningRef DG; SourceLocation StartLoc, EndLoc; public: - DeclStmt(ScopedDecl *D, SourceLocation startLoc, SourceLocation endLoc) - : Stmt(DeclStmtClass), TheDecl(D), StartLoc(startLoc), EndLoc(endLoc) {} + DeclStmt(DeclGroupOwningRef& dg, SourceLocation startLoc, + SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg), + StartLoc(startLoc), EndLoc(endLoc) {} virtual void Destroy(ASTContext& Ctx); // hasSolitaryDecl - This method returns true if this DeclStmt refers // to a single Decl. - bool hasSolitaryDecl() const; + bool hasSolitaryDecl() const { + return DG.hasSolitaryDecl(); + } const ScopedDecl* getSolitaryDecl() const { assert (hasSolitaryDecl() && "Caller assumes this DeclStmt points to one Decl*"); - return TheDecl; + return llvm::cast(*DG.begin()); } ScopedDecl* getSolitaryDecl() { assert (hasSolitaryDecl() && "Caller assumes this DeclStmt points to one Decl*"); - return TheDecl; + return llvm::cast(*DG.begin()); } SourceLocation getStartLoc() const { return StartLoc; } SourceLocation getEndLoc() const { return EndLoc; } - virtual SourceRange getSourceRange() const { + + SourceRange getSourceRange() const { return SourceRange(StartLoc, EndLoc); } @@ -180,42 +185,42 @@ public: virtual child_iterator child_begin(); virtual child_iterator child_end(); - // Iterators over the decls. class decl_iterator { - ScopedDecl* D; + DeclGroupRef::iterator I; public: - decl_iterator(ScopedDecl *d) : D(d) {} - bool operator==(const decl_iterator& I) const { return D == I.D; } - bool operator!=(const decl_iterator& I) const { return D != I.D; } - ScopedDecl* operator*() const { return D; } - decl_iterator& operator++(); + decl_iterator(DeclGroupRef::iterator i) : I(i) {} + decl_iterator& operator++() { ++I; return *this; } + bool operator==(const decl_iterator& R) const { + return R.I == I; + } + bool operator!=(const decl_iterator& R) const { + return R.I != I; + } + ScopedDecl* operator*() const { + return llvm::cast(*I); + } }; - - virtual decl_iterator decl_begin() { return TheDecl; } - virtual decl_iterator decl_end() { return 0; } - + class const_decl_iterator { - decl_iterator Impl; + DeclGroupRef::const_iterator I; public: - const_decl_iterator(const ScopedDecl *d) - : Impl(const_cast(d)) {} - - bool operator==(const const_decl_iterator& I) const { - return Impl == I.Impl; - } - bool operator!=(const const_decl_iterator& I) const { - return Impl != I.Impl; + const_decl_iterator(DeclGroupRef::const_iterator i) : I(i) {} + const_decl_iterator& operator++() { ++I; return *this; } + bool operator==(const const_decl_iterator& R) const { + return R.I == I; } - const ScopedDecl* operator*() const { - return *Impl; + bool operator!=(const const_decl_iterator& R) const { + return R.I != I; } - const_decl_iterator& operator++() { - ++Impl; return *this; + ScopedDecl* operator*() const { + return llvm::cast(*I); } }; - const_decl_iterator decl_begin() const { return TheDecl; } - const_decl_iterator decl_end() const { return 0; } + decl_iterator decl_begin() { return DG.begin(); } + decl_iterator decl_end() { return DG.end(); } + const_decl_iterator decl_begin() const { return DG.begin(); } + const_decl_iterator decl_end() const { return DG.end(); } // Serialization. virtual void EmitImpl(llvm::Serializer& S) const; diff --git a/lib/AST/CFG.cpp b/lib/AST/CFG.cpp index 2eea6492cd..2a79355a63 100644 --- a/lib/AST/CFG.cpp +++ b/lib/AST/CFG.cpp @@ -50,32 +50,6 @@ static SourceLocation GetEndLoc(ScopedDecl* D) { return D->getLocation(); } -class VISIBILITY_HIDDEN UnaryDeclStmt : public DeclStmt { - Stmt* Ex; -public: - UnaryDeclStmt(ScopedDecl* D) - : DeclStmt(D, D->getLocation(), GetEndLoc(D)), Ex(0) { - if (VarDecl* VD = dyn_cast(D)) - Ex = VD->getInit(); - } - - virtual ~UnaryDeclStmt() {} - virtual void Destroy(ASTContext& Ctx) { assert(false && "Do not call"); } - - virtual child_iterator child_begin() { - return Ex ? &Ex : 0; - } - virtual child_iterator child_end() { - return Ex ? &Ex + 1 : 0; - } - virtual decl_iterator decl_begin() { - return TheDecl; - } - virtual decl_iterator decl_end() { - return TheDecl ? TheDecl->getNextDeclarator() : 0; - } -}; - /// CFGBuilder - This class implements CFG construction from an AST. /// The builder is stateful: an instance of the builder should be used to only /// construct a single CFG. @@ -395,16 +369,25 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* Terminator, bool AlwaysAddStmt = false) { Buf.push_back(*DI); for (BufTy::reverse_iterator I=Buf.rbegin(), E=Buf.rend(); I!=E; ++I) { - // Get the alignment of UnaryDeclStmt, padding out to >=8 bytes. - unsigned A = llvm::AlignOf::Alignment < 8 - ? 8 : llvm::AlignOf::Alignment; + // Get the alignment of the new DeclStmt, padding out to >=8 bytes. + unsigned A = llvm::AlignOf::Alignment < 8 + ? 8 : llvm::AlignOf::Alignment; + + // Allocate the DeclStmt using the BumpPtrAllocator. It will + // get automatically freed with the CFG. Note that even though + // we are using a DeclGroupOwningRef that wraps a singe Decl*, + // that Decl* will not get deallocated because the destroy method + // of DG is never called. + DeclGroupOwningRef DG(*I); + ScopedDecl* D = *I; + void* Mem = cfg->getAllocator().Allocate(sizeof(DeclStmt), A); + + DeclStmt* DS = new (Mem) DeclStmt(DG, D->getLocation(), + GetEndLoc(D)); - // Allocate the UnaryDeclStmt using the BumpPtrAllocator. It will - // get automatically freed with the CFG. - void* Mem = cfg->getAllocator().Allocate(sizeof(UnaryDeclStmt), A); // Append the fake DeclStmt to block. - Block->appendStmt(new (Mem) UnaryDeclStmt(*I)); - B = WalkAST_VisitDeclSubExpr(*I); + Block->appendStmt(DS); + B = WalkAST_VisitDeclSubExpr(D); } return B; } diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index fbb369f387..f30e105b17 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -55,7 +55,7 @@ void Stmt::Destroy(ASTContext& C) { } void DeclStmt::Destroy(ASTContext& C) { - TheDecl->Destroy(C); + DG.Destroy(C); delete this; } @@ -188,16 +188,12 @@ ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc, //===----------------------------------------------------------------------===// // DeclStmt -Stmt::child_iterator DeclStmt::child_begin() { return TheDecl; } -Stmt::child_iterator DeclStmt::child_end() { return child_iterator(); } - -DeclStmt::decl_iterator& DeclStmt::decl_iterator::operator++() { - D = D->getNextDeclarator(); - return *this; +Stmt::child_iterator DeclStmt::child_begin() { + return StmtIterator(DG.begin(), DG.end()); } -bool DeclStmt::hasSolitaryDecl() const { - return TheDecl->getNextDeclarator() == 0; +Stmt::child_iterator DeclStmt::child_end() { + return StmtIterator(DG.end(), DG.end()); } // NullStmt diff --git a/lib/AST/StmtSerialization.cpp b/lib/AST/StmtSerialization.cpp index b226bdf8f9..f72800d8ad 100644 --- a/lib/AST/StmtSerialization.cpp +++ b/lib/AST/StmtSerialization.cpp @@ -478,14 +478,14 @@ ContinueStmt* ContinueStmt::CreateImpl(Deserializer& D, ASTContext& C) { void DeclStmt::EmitImpl(Serializer& S) const { S.Emit(StartLoc); S.Emit(EndLoc); - S.EmitOwnedPtr(TheDecl); + S.Emit(DG); } DeclStmt* DeclStmt::CreateImpl(Deserializer& D, ASTContext& C) { SourceLocation StartLoc = SourceLocation::ReadVal(D); - SourceLocation EndLoc = SourceLocation::ReadVal(D); - ScopedDecl* decl = cast(D.ReadOwnedPtr(C)); - return new DeclStmt(decl, StartLoc, EndLoc); + SourceLocation EndLoc = SourceLocation::ReadVal(D); + DeclGroupOwningRef DG; + return new DeclStmt(DG.Read(D, C), StartLoc, EndLoc); } void DeclRefExpr::EmitImpl(Serializer& S) const { diff --git a/lib/AST/StmtViz.cpp b/lib/AST/StmtViz.cpp index 6790efbd56..1316d3551d 100644 --- a/lib/AST/StmtViz.cpp +++ b/lib/AST/StmtViz.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "clang/AST/StmtGraphTraits.h" +#include "clang/AST/Decl.h" #include "llvm/Support/GraphWriter.h" #include diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 68b36ba818..f75758ebb0 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -42,7 +42,28 @@ Sema::StmtResult Sema::ActOnDeclStmt(DeclTy *decl, SourceLocation StartLoc, return true; ScopedDecl *SD = cast(static_cast(decl)); - return new DeclStmt(SD, StartLoc, EndLoc); + + + // This is a temporary hack until we are always passing around + // DeclGroupRefs. + llvm::SmallVector decls; + while (SD) { + ScopedDecl* d = SD; + SD = SD->getNextDeclarator(); + d->setNextDeclarator(0); + decls.push_back(d); + } + + assert (!decls.empty()); + + if (decls.size() == 1) { + DeclGroupOwningRef DG(*decls.begin()); + return new DeclStmt(DG, StartLoc, EndLoc); + } + else { + DeclGroupOwningRef DG(DeclGroup::Create(Context, decls.size(), &decls[0])); + return new DeclStmt(DG, StartLoc, EndLoc); + } } Action::StmtResult