diff options
author | Anders Carlsson <andersca@mac.com> | 2009-05-30 20:03:25 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-05-30 20:03:25 +0000 |
commit | fceb0a8adba9d25db99a4d73e9655c2831a96ecd (patch) | |
tree | e8a72292f3196229430e122f73383a03734b0f9d | |
parent | c1ce477119fed070299668aab24084b17ff5f14b (diff) |
Add a CXXBindTemporaryExpr.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72627 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/ExprCXX.h | 31 | ||||
-rw-r--r-- | include/clang/AST/StmtNodes.def | 1 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 18 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateExpr.cpp | 10 |
5 files changed, 64 insertions, 0 deletions
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 13df65047f..ed713c843b 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -423,7 +423,38 @@ class CXXTemporary { public: static CXXTemporary *Create(ASTContext &C, CXXDestructorDecl *Destructor); }; + +/// CXXBindTemporaryExpr - Represents binding an expression to a temporary, +/// so its destructor can be called later. +class CXXBindTemporaryExpr : public Expr { + CXXTemporary *Temp; + + Stmt *SubExpr; + + CXXBindTemporaryExpr(CXXTemporary *temp, Expr* subexpr) + : Expr(CXXBindTemporaryExprClass, + subexpr->getType()), Temp(temp), SubExpr(subexpr) { } + +public: + static CXXBindTemporaryExpr *Create(ASTContext &C, CXXTemporary *Temp, + Expr* SubExpr); + const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } + Expr *getSubExpr() { return cast<Expr>(SubExpr); } + + virtual SourceRange getSourceRange() const { return SourceRange(); } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXBindTemporaryExprClass; + } + static bool classof(const CXXBindTemporaryExpr *) { return true; } + + // Iterators + virtual child_iterator child_begin(); + virtual child_iterator child_end(); +}; + /// CXXConstructExpr - Represents a call to a C++ constructor. class CXXConstructExpr : public Expr { VarDecl *VD; diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def index 060a586ee9..ab6524663d 100644 --- a/include/clang/AST/StmtNodes.def +++ b/include/clang/AST/StmtNodes.def @@ -124,6 +124,7 @@ EXPR(UnaryTypeTraitExpr , Expr) EXPR(QualifiedDeclRefExpr , DeclRefExpr) EXPR(UnresolvedDeclRefExpr , Expr) EXPR(CXXConstructExpr , Expr) +EXPR(CXXBindTemporaryExpr , Expr) EXPR(CXXExprWithTemporaries , Expr) EXPR(CXXTemporaryObjectExpr , CXXConstructExpr) EXPR(CXXUnresolvedConstructExpr, Expr) diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 16b9c4b67b..d0032fb5e5 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -242,6 +242,15 @@ CXXTemporary *CXXTemporary::Create(ASTContext &C, return new CXXTemporary(Destructor); } +CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(ASTContext &C, + CXXTemporary *Temp, + Expr* SubExpr) { + assert(SubExpr->getType()->isRecordType() && + "Expression bound to a temporary must have record type!"); + + return new CXXBindTemporaryExpr(Temp, SubExpr); +} + CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C, VarDecl *vd, CXXConstructorDecl *Cons, QualType writtenTy, @@ -303,6 +312,15 @@ CXXExprWithTemporaries::~CXXExprWithTemporaries() { delete[] Decls; } +// CXXBindTemporaryExpr +Stmt::child_iterator CXXBindTemporaryExpr::child_begin() { + return &SubExpr; +} + +Stmt::child_iterator CXXBindTemporaryExpr::child_end() { + return &SubExpr + 1; +} + // CXXConstructExpr Stmt::child_iterator CXXConstructExpr::child_begin() { return &Args[0]; diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 594b98f863..710da63861 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -988,6 +988,10 @@ void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { OS << ")"; } +void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { + PrintExpr(Node->getSubExpr()); +} + void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { OS << Node->getType().getAsString(); OS << "("; diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp index c312bb8542..3b28813a72 100644 --- a/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp @@ -976,6 +976,16 @@ TemplateExprInstantiator::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { } Sema::OwningExprResult +TemplateExprInstantiator::VisitCXXBindTemporaryExpr( + CXXBindTemporaryExpr *E) { + OwningExprResult SubExpr = Visit(E->getSubExpr()); + if (SubExpr.isInvalid()) + return SemaRef.ExprError(); + + return move(SubExpr); +} + +Sema::OwningExprResult TemplateExprInstantiator::VisitCXXConstructExpr(CXXConstructExpr *E) { assert(!cast<CXXRecordDecl>(E->getConstructor()->getDeclContext()) ->isDependentType() && "Dependent constructor shouldn't be here"); |