[cfe-commits] r123996 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaStmt.cpp

Douglas Gregor dgregor at apple.com
Fri Jan 21 13:08:57 PST 2011


Author: dgregor
Date: Fri Jan 21 15:08:57 2011
New Revision: 123996

URL: http://llvm.org/viewvc/llvm-project?rev=123996&view=rev
Log:
Generalize the NRVO move-construction-based initialization routine. No functionality change

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaStmt.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=123996&r1=123995&r2=123996&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Jan 21 15:08:57 2011
@@ -1025,6 +1025,11 @@
   bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
 
 
+  ExprResult PerformMoveOrCopyInitialization(const InitializedEntity &Entity,
+                                             const VarDecl *NRVOCandidate,
+                                             QualType ResultType,
+                                             Expr *Value);
+  
   ExprResult PerformCopyInitialization(const InitializedEntity &Entity,
                                        SourceLocation EqualLoc,
                                        ExprResult Init);

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=123996&r1=123995&r2=123996&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Fri Jan 21 15:08:57 2011
@@ -1137,37 +1137,34 @@
   return 0;
 }
 
-/// \brief Perform the initialization of a return value.
+/// \brief Perform the initialization of a potentially-movable value, which
+/// is the result of return value.
 ///
 /// This routine implements C++0x [class.copy]p33, which attempts to treat
 /// returned lvalues as rvalues in certain cases (to prefer move construction),
 /// then falls back to treating them as lvalues if that failed.
-static ExprResult initializeReturnValue(Sema &S,
-                                        const VarDecl *NRVOCandidate,
-                                        SourceLocation ReturnLoc,
-                                        QualType ResultType,
-                                        Expr *RetValExp) {
+ExprResult 
+Sema::PerformMoveOrCopyInitialization(const InitializedEntity &Entity,
+                                      const VarDecl *NRVOCandidate,
+                                      QualType ResultType,
+                                      Expr *Value) {
   // C++0x [class.copy]p33:
   //   When the criteria for elision of a copy operation are met or would 
   //   be met save for the fact that the source object is a function 
   //   parameter, and the object to be copied is designated by an lvalue, 
   //   overload resolution to select the constructor for the copy is first
   //   performed as if the object were designated by an rvalue.
-  InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc, 
-                                                                 ResultType,
-                                                           NRVOCandidate != 0);
-  
   ExprResult Res = ExprError();
-  if (NRVOCandidate || S.getCopyElisionCandidate(ResultType, RetValExp, true)) {
+  if (NRVOCandidate || getCopyElisionCandidate(ResultType, Value, true)) {
     ImplicitCastExpr AsRvalue(ImplicitCastExpr::OnStack, 
-                              RetValExp->getType(), CK_LValueToRValue,
-                              RetValExp, VK_XValue);
+                              Value->getType(), CK_LValueToRValue,
+                              Value, VK_XValue);
     
     Expr *InitExpr = &AsRvalue;
     InitializationKind Kind 
-    = InitializationKind::CreateCopy(RetValExp->getLocStart(),
-                                     RetValExp->getLocStart());
-    InitializationSequence Seq(S, Entity, Kind, &InitExpr, 1);
+      = InitializationKind::CreateCopy(Value->getLocStart(),
+                                       Value->getLocStart());
+    InitializationSequence Seq(*this, Entity, Kind, &InitExpr, 1);
     
     //   [...] If overload resolution fails, or if the type of the first 
     //   parameter of the selected constructor is not an rvalue reference
@@ -1185,25 +1182,24 @@
         = cast<CXXConstructorDecl>(Step->Function.Function);
         
         const RValueReferenceType *RRefType
-        = Constructor->getParamDecl(0)->getType()
-        ->getAs<RValueReferenceType>();
+          = Constructor->getParamDecl(0)->getType()
+                                                 ->getAs<RValueReferenceType>();
         
         // If we don't meet the criteria, break out now.
         if (!RRefType || 
-            !S.Context.hasSameUnqualifiedType(RRefType->getPointeeType(),
-                                              ResultType))
+            !Context.hasSameUnqualifiedType(RRefType->getPointeeType(),
+                            Context.getTypeDeclType(Constructor->getParent())))
           break;
         
         // Promote "AsRvalue" to the heap, since we now need this
         // expression node to persist.
-        RetValExp = ImplicitCastExpr::Create(S.Context,
-                                             RetValExp->getType(),
-                                             CK_LValueToRValue,
-                                             RetValExp, 0, VK_XValue);
+        Value = ImplicitCastExpr::Create(Context, Value->getType(),
+                                         CK_LValueToRValue, Value, 0, 
+                                         VK_XValue);
         
         // Complete type-checking the initialization of the return type
         // using the constructor we found.
-        Res = Seq.Perform(S, Entity, Kind, MultiExprArg(&RetValExp, 1));
+        Res = Seq.Perform(*this, Entity, Kind, MultiExprArg(&Value, 1));
       }
     }
   }
@@ -1212,7 +1208,7 @@
   // above, or overload resolution failed. Either way, we need to try 
   // (again) now with the return value expression as written.
   if (Res.isInvalid())
-    Res = S.PerformCopyInitialization(Entity, SourceLocation(), RetValExp);
+    Res = PerformCopyInitialization(Entity, SourceLocation(), Value);
   
   return Res;
 }
@@ -1273,8 +1269,11 @@
       // In C++ the return statement is handled via a copy initialization.
       // the C version of which boils down to CheckSingleAssignmentConstraints.
       NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
-      ExprResult Res = initializeReturnValue(*this, NRVOCandidate, ReturnLoc,
-                                             FnRetType, RetValExp);
+      InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc, 
+                                                                     FnRetType,
+                                                           NRVOCandidate != 0);
+      ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate, 
+                                                       FnRetType, RetValExp);
       if (Res.isInvalid()) {
         // FIXME: Cleanup temporaries here, anyway?
         return StmtError();
@@ -1367,8 +1366,11 @@
       // In C++ the return statement is handled via a copy initialization.
       // the C version of which boils down to CheckSingleAssignmentConstraints.
       NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
-      ExprResult Res = initializeReturnValue(*this, NRVOCandidate, ReturnLoc,
-                                             FnRetType, RetValExp);
+      InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc, 
+                                                                     FnRetType,
+                                                                     NRVOCandidate != 0);
+      ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate, 
+                                                       FnRetType, RetValExp);
       if (Res.isInvalid()) {
         // FIXME: Cleanup temporaries here, anyway?
         return StmtError();





More information about the cfe-commits mailing list