diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index c3e018132484..568a9f2a4595 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -21,6 +21,7 @@ namespace clang { class CXXConstructorDecl; + class CXXTempVarDecl; //===--------------------------------------------------------------------===// // C++ Expressions. @@ -946,6 +947,32 @@ public: virtual child_iterator child_end(); }; +class CXXExprWithCleanup : public Expr { + Stmt *SubExpr; + + CXXTempVarDecl **Decls; + unsigned NumDecls; + +public: + CXXExprWithCleanup(Expr *subexpr, CXXTempVarDecl **decls, unsigned numdecls); + ~CXXExprWithCleanup(); + + const Expr *getSubExpr() const { return cast(SubExpr); } + Expr *getSubExpr() { return cast(SubExpr); } + + virtual SourceRange getSourceRange() const { return SourceRange(); } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXExprWithCleanupClass; + } + static bool classof(const CXXExprWithCleanup *) { return true; } + + // Iterators + virtual child_iterator child_begin(); + virtual child_iterator child_end(); +}; + } // end namespace clang #endif diff --git a/clang/include/clang/AST/StmtNodes.def b/clang/include/clang/AST/StmtNodes.def index b9c6aa28dd42..5dbb6286ca3e 100644 --- a/clang/include/clang/AST/StmtNodes.def +++ b/clang/include/clang/AST/StmtNodes.def @@ -121,6 +121,7 @@ STMT(QualifiedDeclRefExpr , DeclRefExpr) STMT(UnresolvedDeclRefExpr , Expr) STMT(CXXDestroyExpr , Expr) STMT(CXXConstructExpr , Expr) +STMT(CXXExprWithCleanup , Expr) // Obj-C Expressions. STMT(ObjCStringLiteral , Expr) diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 5b4d4d330e3a..bab58a2f3fc9 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -274,6 +274,22 @@ CXXDestroyExpr *CXXDestroyExpr::Create(ASTContext &C, VarDecl *vd) { return new (C) CXXDestroyExpr(vd, C.VoidTy); } +CXXExprWithCleanup::CXXExprWithCleanup(Expr *subexpr, CXXTempVarDecl **decls, + unsigned numdecls) +: Expr(CXXExprWithCleanupClass, subexpr->getType(), + subexpr->isTypeDependent(), subexpr->isValueDependent()), + SubExpr(subexpr), Decls(0), NumDecls(numdecls) { + if (NumDecls > 0) { + Decls = new CXXTempVarDecl*[NumDecls]; + for (unsigned i = 0; i < NumDecls; ++i) + Decls[i] = decls[i]; + } +} + +CXXExprWithCleanup::~CXXExprWithCleanup() { + delete[] Decls; +} + // CXXConstructExpr Stmt::child_iterator CXXConstructExpr::child_begin() { return &Args[0]; @@ -289,3 +305,8 @@ Stmt::child_iterator CXXDestroyExpr::child_begin() { Stmt::child_iterator CXXDestroyExpr::child_end() { return child_iterator(); } + +// CXXExprWithCleanup +Stmt::child_iterator CXXExprWithCleanup::child_begin() { return &SubExpr; } +Stmt::child_iterator CXXExprWithCleanup::child_end() { return &SubExpr + 1; } + diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 5e75a2eb615c..1a74937be94e 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1105,6 +1105,11 @@ void StmtPrinter::VisitCXXDestroyExpr(CXXDestroyExpr *E) { // Nothing to print. } +void StmtPrinter::VisitCXXExprWithCleanup(CXXExprWithCleanup *E) { + // Just forward to the sub expression. + PrintExpr(E->getSubExpr()); +} + static const char *getTypeTraitName(UnaryTypeTrait UTT) { switch (UTT) { default: assert(false && "Unknown type trait");