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
This commit is contained in:
Ted Kremenek 2008-10-07 23:09:49 +00:00
Родитель 2c3352b5d1
Коммит 8ffb159441
6 изменённых файлов: 88 добавлений и 82 удалений

Просмотреть файл

@ -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<ScopedDecl>(*DG.begin());
}
ScopedDecl* getSolitaryDecl() {
assert (hasSolitaryDecl() &&
"Caller assumes this DeclStmt points to one Decl*");
return TheDecl;
return llvm::cast<ScopedDecl>(*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<ScopedDecl>(*I);
}
};
virtual decl_iterator decl_begin() { return TheDecl; }
virtual decl_iterator decl_end() { return 0; }
class const_decl_iterator {
decl_iterator Impl;
public:
const_decl_iterator(const ScopedDecl *d)
: Impl(const_cast<ScopedDecl*>(d)) {}
bool operator==(const const_decl_iterator& I) const {
return Impl == I.Impl;
class const_decl_iterator {
DeclGroupRef::const_iterator I;
public:
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;
}
bool operator!=(const const_decl_iterator& I) const {
return Impl != I.Impl;
bool operator!=(const const_decl_iterator& R) const {
return R.I != I;
}
const ScopedDecl* operator*() const {
return *Impl;
}
const_decl_iterator& operator++() {
++Impl; return *this;
ScopedDecl* operator*() const {
return llvm::cast<ScopedDecl>(*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;

Просмотреть файл

@ -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<VarDecl>(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<UnaryDeclStmt>::Alignment < 8
? 8 : llvm::AlignOf<UnaryDeclStmt>::Alignment;
// Get the alignment of the new DeclStmt, padding out to >=8 bytes.
unsigned A = llvm::AlignOf<DeclStmt>::Alignment < 8
? 8 : llvm::AlignOf<DeclStmt>::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;
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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<ScopedDecl>(D.ReadOwnedPtr<Decl>(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 {

Просмотреть файл

@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/StmtGraphTraits.h"
#include "clang/AST/Decl.h"
#include "llvm/Support/GraphWriter.h"
#include <sstream>

Просмотреть файл

@ -42,7 +42,28 @@ Sema::StmtResult Sema::ActOnDeclStmt(DeclTy *decl, SourceLocation StartLoc,
return true;
ScopedDecl *SD = cast<ScopedDecl>(static_cast<Decl *>(decl));
return new DeclStmt(SD, StartLoc, EndLoc);
// This is a temporary hack until we are always passing around
// DeclGroupRefs.
llvm::SmallVector<Decl*, 10> 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