Index: include/clang/AST/StmtCXX.h =================================================================== --- include/clang/AST/StmtCXX.h +++ include/clang/AST/StmtCXX.h @@ -62,21 +62,21 @@ /// CXXTryStmt - A C++ try block, including all handlers. /// -class CXXTryStmt : public Stmt { +class CXXTryStmt final : public Stmt, + private llvm::TrailingObjects { + + friend TrailingObjects; + SourceLocation TryLoc; unsigned NumHandlers; + size_t numTrailingObjects(OverloadToken) const { return NumHandlers; } CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef handlers); - CXXTryStmt(EmptyShell Empty, unsigned numHandlers) : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { } - Stmt const * const *getStmts() const { - return reinterpret_cast(this + 1); - } - Stmt **getStmts() { - return reinterpret_cast(this + 1); - } + Stmt * const *getStmts() const { return getTrailingObjects(); } + Stmt **getStmts() { return getTrailingObjects(); } public: static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc, @@ -90,22 +90,22 @@ SourceLocation getTryLoc() const { return TryLoc; } SourceLocation getEndLoc() const { - return getStmts()[NumHandlers]->getLocEnd(); + return getTrailingObjects()[NumHandlers]->getLocEnd(); } CompoundStmt *getTryBlock() { - return cast(getStmts()[0]); + return cast(getTrailingObjects()[0]); } const CompoundStmt *getTryBlock() const { - return cast(getStmts()[0]); + return cast(getTrailingObjects()[0]); } unsigned getNumHandlers() const { return NumHandlers; } CXXCatchStmt *getHandler(unsigned i) { - return cast(getStmts()[i + 1]); + return cast(getTrailingObjects()[i + 1]); } const CXXCatchStmt *getHandler(unsigned i) const { - return cast(getStmts()[i + 1]); + return cast(getTrailingObjects()[i + 1]); } static bool classof(const Stmt *T) { @@ -113,7 +113,8 @@ } child_range children() { - return child_range(getStmts(), getStmts() + getNumHandlers() + 1); + return child_range(getTrailingObjects(), + getTrailingObjects() + getNumHandlers() + 1); } friend class ASTStmtReader; Index: lib/AST/StmtCXX.cpp =================================================================== --- lib/AST/StmtCXX.cpp +++ lib/AST/StmtCXX.cpp @@ -25,18 +25,14 @@ CXXTryStmt *CXXTryStmt::Create(const ASTContext &C, SourceLocation tryLoc, Stmt *tryBlock, ArrayRef handlers) { - std::size_t Size = sizeof(CXXTryStmt); - Size += ((handlers.size() + 1) * sizeof(Stmt *)); - + const size_t Size = totalSizeToAlloc(handlers.size() + 1); void *Mem = C.Allocate(Size, alignof(CXXTryStmt)); return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers); } CXXTryStmt *CXXTryStmt::Create(const ASTContext &C, EmptyShell Empty, unsigned numHandlers) { - std::size_t Size = sizeof(CXXTryStmt); - Size += ((numHandlers + 1) * sizeof(Stmt *)); - + const size_t Size = totalSizeToAlloc(numHandlers + 1); void *Mem = C.Allocate(Size, alignof(CXXTryStmt)); return new (Mem) CXXTryStmt(Empty, numHandlers); } @@ -44,7 +40,7 @@ CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef handlers) : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(handlers.size()) { - Stmt **Stmts = reinterpret_cast(this + 1); + Stmt **Stmts = getTrailingObjects(); Stmts[0] = tryBlock; std::copy(handlers.begin(), handlers.end(), Stmts + 1); }