From 165a0a07c0a91f8d61ee3737b62e7f376bb7e1c7 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sun, 17 May 2009 18:41:29 +0000 Subject: [PATCH] Implement Sema::ActOnFinishFullExpr and create a CXXExprWithTemporaries node if necessary. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71983 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/Sema.h | 8 +++++++- lib/Sema/SemaExprCXX.cpp | 25 +++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index c4890499a6..eb723bb080 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -162,7 +162,11 @@ public: /// in the top level function. Clients should always use getSwitchStack() to /// handle the case when they are in a block. llvm::SmallVector FunctionSwitchStack; - + + /// ExprTemporaries - This is the stack of temporaries that are created by + /// the current full expression. + llvm::SmallVector ExprTemporaries; + /// CurFunctionNeedsScopeChecking - This is set to true when a function or /// ObjC method body contains a VLA or an ObjC try block, which introduce /// scopes that need to be checked for goto conditions. If a function does @@ -1583,6 +1587,8 @@ public: TypeTy *Ty, SourceLocation RParen); + virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr); + bool RequireCompleteDeclContext(const CXXScopeSpec &SS); DeclContext *computeDeclContext(const CXXScopeSpec &SS); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index f6ee0927da..142f713254 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -164,8 +164,11 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep, CallExpr::hasAnyTypeDependentArguments(Exprs, NumExprs)) { exprs.release(); - // FIXME: Is this correct? + // FIXME: Is this correct (I don't think so). Instead, we should have an + // CXXUnresolvedTemporaryObjectExpr node for this. CXXTempVarDecl *Temp = CXXTempVarDecl::Create(Context, CurContext, Ty); + ExprTemporaries.push_back(Temp); + return Owned(new (Context) CXXTemporaryObjectExpr(Context, Temp, 0, Ty, TyBeginLoc, Exprs, NumExprs, @@ -190,6 +193,8 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep, if (const RecordType *RT = Ty->getAsRecordType()) { CXXRecordDecl *Record = cast(RT->getDecl()); + // FIXME: We should always create a CXXTemporaryObjectExpr here unless + // both the ctor and dtor are trivial. if (NumExprs > 1 || Record->hasUserDeclaredConstructor()) { CXXConstructorDecl *Constructor = PerformInitializationByConstructor(Ty, Exprs, NumExprs, @@ -203,7 +208,8 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep, return ExprError(); CXXTempVarDecl *Temp = CXXTempVarDecl::Create(Context, CurContext, Ty); - + ExprTemporaries.push_back(Temp); + exprs.release(); return Owned(new (Context) CXXTemporaryObjectExpr(Context, Temp, Constructor, Ty, @@ -1494,3 +1500,18 @@ QualType Sema::FindCompositePointerType(Expr *&E1, Expr *&E2) { } return QualType(); } + +Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) { + Expr *FullExpr = Arg.takeAs(); + assert(FullExpr && "Null full expr!"); + + if (!ExprTemporaries.empty()) { + // Create a cleanup expr. + FullExpr = + new (Context) CXXExprWithTemporaries(FullExpr, &ExprTemporaries[0], + ExprTemporaries.size()); + ExprTemporaries.clear(); + } + + return Owned(FullExpr); +} -- 2.40.0