]> granicus.if.org Git - clang/commitdiff
Start creating CXXBindReferenceExpr nodes when binding complex types to references.
authorAnders Carlsson <andersca@mac.com>
Sun, 31 Jan 2010 18:34:51 +0000 (18:34 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 31 Jan 2010 18:34:51 +0000 (18:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94964 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCall.cpp
lib/CodeGen/CGDecl.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CodeGenFunction.h
lib/Sema/SemaInit.cpp

index d3a41d62a7749934f28670c6657f6522006cda94..e1fe0d29a2dbb1170db4070e37fc2ba8166dea73 100644 (file)
@@ -802,6 +802,9 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
 }
 
 RValue CodeGenFunction::EmitCallArg(const Expr *E, QualType ArgType) {
+  if (const CXXBindReferenceExpr *BE = dyn_cast<CXXBindReferenceExpr>(E))
+    return RValue::get(EmitCXXBindReferenceExpr(BE));
+  
   if (ArgType->isReferenceType())
     return EmitReferenceBindingToExpr(E, ArgType);
 
index 51e194da342769f356b89a516c05d6f50c400e39..6ba537e528c27e4c6590c914486a80f7e77772e5 100644 (file)
@@ -507,6 +507,10 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
         
         Builder.CreateCall4(CGM.getMemCpyFn(), Loc, SrcPtr, SizeVal, AlignVal);
       }
+    } else if (const CXXBindReferenceExpr *BE = 
+                dyn_cast<CXXBindReferenceExpr>(Init)) {
+      llvm::Value *V = EmitCXXBindReferenceExpr(BE);
+      EmitStoreOfScalar(V, Loc, /*Volatile=*/false, Ty);
     } else if (Ty->isReferenceType()) {
       RValue RV = EmitReferenceBindingToExpr(Init, Ty, /*IsInitializer=*/true);
       EmitStoreOfScalar(RV.getScalarVal(), Loc, false, Ty);
index 605f77975f9587dc0c480c0aafcba2c3d684ef50..c0dd68bc70b6620b234b2cb176352b6a2af5d6ed 100644 (file)
@@ -92,9 +92,31 @@ RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E,
                      IsInitializer);
 }
 
+llvm::Value * 
+CodeGenFunction::EmitCXXBindReferenceExpr(const CXXBindReferenceExpr *E) {
+  QualType T = E->getType();
+  assert(T->isAnyComplexType() && "FIXME: Unhandled bind expression!");
+  
+  const Expr *SubExpr = E->getSubExpr();
+
+  if (!E->requiresTemporaryCopy())
+    return EmitLValue(SubExpr).getAddress();
+
+  llvm::Value *Value = CreateTempAlloca(ConvertTypeForMem(T), "reftmp");
+    
+  if (T->isAnyComplexType()) 
+    EmitComplexExprIntoAddr(SubExpr, Value, /*DestIsVolatile=*/false);
+  else
+    assert(false && "Unhandled bind expression");
+    
+  return Value;
+}
+
 RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,
                                                    QualType DestType,
                                                    bool IsInitializer) {
+  assert(!E->getType()->isAnyComplexType() && 
+         "Should not use this function for complex types!");
   bool ShouldDestroyTemporaries = false;
   unsigned OldNumLiveTemporaries = 0;
 
index 7a8da0c95ba879682ca9c7acdade458fbbb5cee1..69b2fa222c18639d12ae527415070741425142b4 100644 (file)
@@ -1116,6 +1116,8 @@ public:
   RValue EmitReferenceBindingToExpr(const Expr* E, QualType DestType,
                                     bool IsInitializer = false);
 
+  llvm::Value *EmitCXXBindReferenceExpr(const CXXBindReferenceExpr *E);
+
   //===--------------------------------------------------------------------===//
   //                           Expression Emission
   //===--------------------------------------------------------------------===//
index a9adb70050b78a8a17c7b796e82f70812600f571..db888a62a4fa90bb5e4ca3d4349e985871ce17d6 100644 (file)
@@ -3297,15 +3297,31 @@ InitializationSequence::Perform(Sema &S,
       // Check exception specifications
       if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
         return S.ExprError();
+      
+      // FIXME: We should do this for all types.
+      if (DestType->isAnyComplexType()) {
+        CurInit = 
+          S.Owned(CXXBindReferenceExpr::Create(S.Context, 
+                                               CurInit.takeAs<Expr>(), 
+                                               /*ExtendsLifetime=*/false,
+                                               /*RequiresTemporaryCopy=*/false));
+      }
+
       break;
-        
+
     case SK_BindReferenceToTemporary:
       // Check exception specifications
       if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
         return S.ExprError();
 
-      // FIXME: At present, we have no AST to describe when we need to make a
-      // temporary to bind a reference to. We should.
+      // FIXME: We should do this for all types.
+      if (DestType->isAnyComplexType()) {
+        CurInit = 
+          S.Owned(CXXBindReferenceExpr::Create(S.Context, 
+                                               CurInit.takeAs<Expr>(), 
+                                               /*ExtendsLifetime=*/false,
+                                               /*RequiresTemporaryCopy=*/true));
+      }
       break;
         
     case SK_UserConversion: {