diff --git a/clang/include/clang/AST/StmtCXX.h b/clang/include/clang/AST/StmtCXX.h index 6026707b1698..4e87c2701c26 100644 --- a/clang/include/clang/AST/StmtCXX.h +++ b/clang/include/clang/AST/StmtCXX.h @@ -59,35 +59,42 @@ public: /// class CXXTryStmt : public Stmt { SourceLocation TryLoc; - - // First place is the guarded CompoundStatement. Subsequent are the handlers. - Stmt **Stmts; unsigned NumHandlers; -protected: - virtual void DoDestroy(ASTContext &Ctx); + CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers, + unsigned numHandlers); public: - CXXTryStmt(ASTContext &C, SourceLocation tryLoc, Stmt *tryBlock, - Stmt **handlers, unsigned numHandlers); + static CXXTryStmt *Create(ASTContext &C, SourceLocation tryLoc, + Stmt *tryBlock, Stmt **handlers, + unsigned numHandlers); virtual SourceRange getSourceRange() const { return SourceRange(getTryLoc(), getEndLoc()); } SourceLocation getTryLoc() const { return TryLoc; } - SourceLocation getEndLoc() const { return Stmts[NumHandlers]->getLocEnd(); } + SourceLocation getEndLoc() const { + Stmt const * const*Stmts = reinterpret_cast(this + 1); + return Stmts[NumHandlers]->getLocEnd(); + } - CompoundStmt *getTryBlock() { return llvm::cast(Stmts[0]); } + CompoundStmt *getTryBlock() { + Stmt **Stmts = reinterpret_cast(this + 1); + return llvm::cast(Stmts[0]); + } const CompoundStmt *getTryBlock() const { + Stmt const * const*Stmts = reinterpret_cast(this + 1); return llvm::cast(Stmts[0]); } unsigned getNumHandlers() const { return NumHandlers; } CXXCatchStmt *getHandler(unsigned i) { + Stmt **Stmts = reinterpret_cast(this + 1); return llvm::cast(Stmts[i + 1]); } const CXXCatchStmt *getHandler(unsigned i) const { + Stmt const * const*Stmts = reinterpret_cast(this + 1); return llvm::cast(Stmts[i + 1]); } diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index e90eceec1b34..8347249a466b 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -407,10 +407,20 @@ ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc, 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()); + return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers); +} + +CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, Stmt **handlers, unsigned numHandlers) : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) { - Stmts = new (C) Stmt*[NumHandlers + 1]; + Stmt **Stmts = reinterpret_cast(this + 1); Stmts[0] = tryBlock; std::copy(handlers, handlers + NumHandlers, Stmts + 1); } @@ -493,14 +503,6 @@ void AsmStmt::DoDestroy(ASTContext &C) { 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 //===----------------------------------------------------------------------===// @@ -664,5 +666,10 @@ Stmt::child_iterator CXXCatchStmt::child_end() { } // CXXTryStmt -Stmt::child_iterator CXXTryStmt::child_begin() { return &Stmts[0]; } -Stmt::child_iterator CXXTryStmt::child_end() { return &Stmts[0]+NumHandlers+1; } +Stmt::child_iterator CXXTryStmt::child_begin() { + return reinterpret_cast(this + 1); +} + +Stmt::child_iterator CXXTryStmt::child_end() { + return reinterpret_cast(this + 1) + NumHandlers + 1; +} diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 0fecb8ba8687..a1aefee78bd9 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -1551,7 +1551,7 @@ Sema::ActOnCXXTryBlock(SourceLocation TryLoc, StmtArg TryBlock, CurFunctionNeedsScopeChecking = true; RawHandlers.release(); - return Owned(new (Context) CXXTryStmt(Context, TryLoc, - static_cast(TryBlock.release()), - Handlers, NumHandlers)); + return Owned(CXXTryStmt::Create(Context, TryLoc, + static_cast(TryBlock.release()), + Handlers, NumHandlers)); }