Check in a rudimentary FullExpr class that isn't used anywhere yet. Rename Action::FullExpr to Action::MakeFullExpr to avoid name clashes.

llvm-svn: 91494
diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index 0f0b22d..5aecf87 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -16,6 +16,7 @@
   Expr.cpp
   ExprCXX.cpp
   ExprConstant.cpp
+  FullExpr.cpp
   InheritViz.cpp
   NestedNameSpecifier.cpp
   ParentMap.cpp
diff --git a/clang/lib/AST/FullExpr.cpp b/clang/lib/AST/FullExpr.cpp
new file mode 100644
index 0000000..39c3bad
--- /dev/null
+++ b/clang/lib/AST/FullExpr.cpp
@@ -0,0 +1,42 @@
+//===--- FullExpr.cpp - C++ full expression class ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the FullExpr interface, to be used for type safe handling
+//  of full expressions.
+//
+//  Full expressions are described in C++ [intro.execution]p12.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/FullExpr.h"
+#include "llvm/Support/AlignOf.h"
+using namespace clang;
+
+FullExpr FullExpr::Create(ASTContext &Context, Expr *SubExpr, 
+                          CXXTemporary **Temporaries, unsigned NumTemporaries) {
+    FullExpr E;
+    
+    if (!NumTemporaries) {
+        E.SubExpr = SubExpr;
+        return E;
+    }
+    
+    unsigned Size = sizeof(FullExpr) 
+        + sizeof(CXXTemporary *) * NumTemporaries;
+    
+    unsigned Align = llvm::AlignOf<ExprAndTemporaries>::Alignment;
+    ExprAndTemporaries *ET = 
+        static_cast<ExprAndTemporaries *>(Context.Allocate(Size, Align));
+    
+    ET->SubExpr = SubExpr;
+    std::copy(Temporaries, Temporaries + NumTemporaries, ET->begin());
+    
+    return E;
+}
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index 2c53847..9904a2c 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -1589,7 +1589,7 @@
   
   // Otherwise, eat the semicolon.
   ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
-  return Actions.ActOnExprStmt(Actions.FullExpr(Res));
+  return Actions.ActOnExprStmt(Actions.MakeFullExpr(Res));
 }
 
 Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index a2ac646..4fc443c 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -131,7 +131,7 @@
     }
     // Otherwise, eat the semicolon.
     ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
-    return Actions.ActOnExprStmt(Actions.FullExpr(Expr));
+    return Actions.ActOnExprStmt(Actions.MakeFullExpr(Expr));
   }
 
   case tok::kw_case:                // C99 6.8.1: labeled-statement
@@ -494,7 +494,7 @@
         // Eat the semicolon at the end of stmt and convert the expr into a
         // statement.
         ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
-        R = Actions.ActOnExprStmt(Actions.FullExpr(Res));
+        R = Actions.ActOnExprStmt(Actions.MakeFullExpr(Res));
       }
     }
 
@@ -593,7 +593,7 @@
   if (ParseParenExprOrCondition(CondExp, CondVar))
     return StmtError();
 
-  FullExprArg FullCondExp(Actions.FullExpr(CondExp));
+  FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp));
 
   // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause.  We only do this
@@ -720,7 +720,7 @@
   if (ParseParenExprOrCondition(Cond, CondVar))
     return StmtError();
 
-  FullExprArg FullCond(Actions.FullExpr(Cond));
+  FullExprArg FullCond(Actions.MakeFullExpr(Cond));
   
   OwningStmtResult Switch = Actions.ActOnStartOfSwitchStmt(FullCond, CondVar);
 
@@ -801,7 +801,7 @@
   if (ParseParenExprOrCondition(Cond, CondVar))
     return StmtError();
 
-  FullExprArg FullCond(Actions.FullExpr(Cond));
+  FullExprArg FullCond(Actions.MakeFullExpr(Cond));
 
   // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause.  We only do this
@@ -993,7 +993,7 @@
 
     // Turn the expression into a stmt.
     if (!Value.isInvalid())
-      FirstPart = Actions.ActOnExprStmt(Actions.FullExpr(Value));
+      FirstPart = Actions.ActOnExprStmt(Actions.MakeFullExpr(Value));
 
     if (Tok.is(tok::semi)) {
       ConsumeToken();
@@ -1060,8 +1060,8 @@
 
   if (!ForEach)
     return Actions.ActOnForStmt(ForLoc, LParenLoc, move(FirstPart),
-                                Actions.FullExpr(SecondPart), SecondVar,
-                                Actions.FullExpr(ThirdPart), RParenLoc, 
+                                Actions.MakeFullExpr(SecondPart), SecondVar,
+                                Actions.MakeFullExpr(ThirdPart), RParenLoc, 
                                 move(Body));
 
   return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index 0472d50e..88f290a 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -24,6 +24,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/FullExpr.h"
 #include "clang/Parse/Action.h"
 #include "clang/Sema/SemaDiagnostic.h"
 #include "llvm/ADT/SmallVector.h"
@@ -2005,6 +2006,8 @@
   /// Otherwise, just returs the passed in expression.
   Expr *MaybeCreateCXXExprWithTemporaries(Expr *SubExpr);
 
+  FullExpr CreateFullExpr(Expr *SubExpr);
+  
   virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr);
 
   bool RequireCompleteDeclContext(const CXXScopeSpec &SS);
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 80b6430..4bcb058 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -2102,6 +2102,22 @@
   return E;
 }
 
+FullExpr Sema::CreateFullExpr(Expr *SubExpr) {
+  unsigned FirstTemporary = ExprEvalContexts.back().NumTemporaries;
+  assert(ExprTemporaries.size() >= FirstTemporary);
+  
+  unsigned NumTemporaries = ExprTemporaries.size() - FirstTemporary;
+  CXXTemporary **Temporaries = 
+    NumTemporaries == 0 ? 0 : &ExprTemporaries[FirstTemporary];
+  
+  FullExpr E = FullExpr::Create(Context, SubExpr, Temporaries, NumTemporaries);
+
+  ExprTemporaries.erase(ExprTemporaries.begin() + FirstTemporary,
+                        ExprTemporaries.end());
+
+  return E;
+}
+
 Sema::OwningExprResult
 Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
                                    tok::TokenKind OpKind, TypeTy *&ObjectType) {
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index cc57222..03169bf 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -1655,7 +1655,7 @@
       if (E.isInvalid())
         return getSema().StmtError();
 
-      return getSema().ActOnExprStmt(getSema().FullExpr(E));
+      return getSema().ActOnExprStmt(getSema().MakeFullExpr(E));
     }
   }
 
@@ -3067,7 +3067,7 @@
       return SemaRef.StmtError();
   }
   
-  Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
 
   // Transform the "then" branch.
   OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
@@ -3110,7 +3110,7 @@
       return SemaRef.StmtError();
   }
 
-  Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
   
   // Rebuild the switch statement.
   OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(FullCond,
@@ -3147,7 +3147,7 @@
       return SemaRef.StmtError();
   }
 
-  Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
 
   // Transform the body
   OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
@@ -3229,9 +3229,9 @@
     return SemaRef.Owned(S->Retain());
 
   return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
-                                     move(Init), getSema().FullExpr(Cond),
+                                     move(Init), getSema().MakeFullExpr(Cond),
                                      ConditionVar,
-                                     getSema().FullExpr(Inc),
+                                     getSema().MakeFullExpr(Inc),
                                      S->getRParenLoc(), move(Body));
 }