]> granicus.if.org Git - clang/commitdiff
Implement Sema::ActOnFinishFullExpr and create a CXXExprWithTemporaries node if neces...
authorAnders Carlsson <andersca@mac.com>
Sun, 17 May 2009 18:41:29 +0000 (18:41 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 17 May 2009 18:41:29 +0000 (18:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71983 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaExprCXX.cpp

index c4890499a6d519b3bbadf0c3b91838a68859882b..eb723bb080e43fbcee0a17f52449fc82248a2506 100644 (file)
@@ -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<SwitchStmt*, 8> FunctionSwitchStack;
-  
+
+  /// ExprTemporaries - This is the stack of temporaries that are created by 
+  /// the current full expression.
+  llvm::SmallVector<CXXTempVarDecl*, 8> 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);
index f6ee0927da85f308f285b565da0f33333f4e75f8..142f7132543d41a4194eba85118ac0e28c0192aa 100644 (file)
@@ -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<CXXRecordDecl>(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<Expr>();
+  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);
+}