Implement Doug's suggestion. Eliminate the Stmts pointer from CXXTryStmt and instead allocate the statements after the object.

llvm-svn: 95199
This commit is contained in:
Sam Weinig 2010-02-03 03:56:39 +00:00
parent 27a41d5473
commit a16b0dd1ae
3 changed files with 38 additions and 24 deletions

View File

@ -59,35 +59,42 @@ public:
/// ///
class CXXTryStmt : public Stmt { class CXXTryStmt : public Stmt {
SourceLocation TryLoc; SourceLocation TryLoc;
// First place is the guarded CompoundStatement. Subsequent are the handlers.
Stmt **Stmts;
unsigned NumHandlers; unsigned NumHandlers;
protected: CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers,
virtual void DoDestroy(ASTContext &Ctx); unsigned numHandlers);
public: public:
CXXTryStmt(ASTContext &C, SourceLocation tryLoc, Stmt *tryBlock, static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc,
Stmt **handlers, unsigned numHandlers); Stmt *tryBlock, Stmt **handlers,
unsigned numHandlers);
virtual SourceRange getSourceRange() const { virtual SourceRange getSourceRange() const {
return SourceRange(getTryLoc(), getEndLoc()); return SourceRange(getTryLoc(), getEndLoc());
} }
SourceLocation getTryLoc() const { return TryLoc; } SourceLocation getTryLoc() const { return TryLoc; }
SourceLocation getEndLoc() const { return Stmts[NumHandlers]->getLocEnd(); } SourceLocation getEndLoc() const {
Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
return Stmts[NumHandlers]->getLocEnd();
}
CompoundStmt *getTryBlock() { return llvm::cast<CompoundStmt>(Stmts[0]); } CompoundStmt *getTryBlock() {
Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
return llvm::cast<CompoundStmt>(Stmts[0]);
}
const CompoundStmt *getTryBlock() const { const CompoundStmt *getTryBlock() const {
Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
return llvm::cast<CompoundStmt>(Stmts[0]); return llvm::cast<CompoundStmt>(Stmts[0]);
} }
unsigned getNumHandlers() const { return NumHandlers; } unsigned getNumHandlers() const { return NumHandlers; }
CXXCatchStmt *getHandler(unsigned i) { CXXCatchStmt *getHandler(unsigned i) {
Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
return llvm::cast<CXXCatchStmt>(Stmts[i + 1]); return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
} }
const CXXCatchStmt *getHandler(unsigned i) const { const CXXCatchStmt *getHandler(unsigned i) const {
Stmt const * const*Stmts = reinterpret_cast<Stmt const * const*>(this + 1);
return llvm::cast<CXXCatchStmt>(Stmts[i + 1]); return llvm::cast<CXXCatchStmt>(Stmts[i + 1]);
} }

View File

@ -407,10 +407,20 @@ ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc,
RParenLoc = rparenloc; RParenLoc = rparenloc;
} }
CXXTryStmt::CXXTryStmt(ASTContext &C, SourceLocation tryLoc, Stmt *tryBlock, CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc,
Stmt *tryBlock, Stmt **handlers,
unsigned numHandlers) {
std::size_t Size = sizeof(CXXTryStmt);
Size += ((numHandlers + 1) * sizeof(Stmt));
void *Mem = C.Allocate(Size, llvm::alignof<CXXTryStmt>());
return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers);
}
CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
Stmt **handlers, unsigned numHandlers) Stmt **handlers, unsigned numHandlers)
: Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) { : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) {
Stmts = new (C) Stmt*[NumHandlers + 1]; Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
Stmts[0] = tryBlock; Stmts[0] = tryBlock;
std::copy(handlers, handlers + NumHandlers, Stmts + 1); std::copy(handlers, handlers + NumHandlers, Stmts + 1);
} }
@ -493,14 +503,6 @@ void AsmStmt::DoDestroy(ASTContext &C) {
C.Deallocate((void *)this); C.Deallocate((void *)this);
} }
void CXXTryStmt::DoDestroy(ASTContext& C) {
DestroyChildren(C);
C.Deallocate(Stmts);
this->~CXXTryStmt();
C.Deallocate((void *)this);
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Child Iterators for iterating over subexpressions/substatements // Child Iterators for iterating over subexpressions/substatements
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -664,5 +666,10 @@ Stmt::child_iterator CXXCatchStmt::child_end() {
} }
// CXXTryStmt // CXXTryStmt
Stmt::child_iterator CXXTryStmt::child_begin() { return &Stmts[0]; } Stmt::child_iterator CXXTryStmt::child_begin() {
Stmt::child_iterator CXXTryStmt::child_end() { return &Stmts[0]+NumHandlers+1; } return reinterpret_cast<Stmt **>(this + 1);
}
Stmt::child_iterator CXXTryStmt::child_end() {
return reinterpret_cast<Stmt **>(this + 1) + NumHandlers + 1;
}

View File

@ -1551,7 +1551,7 @@ Sema::ActOnCXXTryBlock(SourceLocation TryLoc, StmtArg TryBlock,
CurFunctionNeedsScopeChecking = true; CurFunctionNeedsScopeChecking = true;
RawHandlers.release(); RawHandlers.release();
return Owned(new (Context) CXXTryStmt(Context, TryLoc, return Owned(CXXTryStmt::Create(Context, TryLoc,
static_cast<Stmt*>(TryBlock.release()), static_cast<Stmt*>(TryBlock.release()),
Handlers, NumHandlers)); Handlers, NumHandlers));
} }