[cfe-commits] r84162 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp test/CodeGenCXX/references.cpp

Anders Carlsson andersca at mac.com
Wed Oct 14 17:51:47 PDT 2009


Author: andersca
Date: Wed Oct 14 19:51:46 2009
New Revision: 84162

URL: http://llvm.org/viewvc/llvm-project?rev=84162&view=rev
Log:
Handle

struct A { };
struct B : A { };

void f() {
  const A& a = B();
}

correctly. (This now does the offset conversion if necessary and calls the destructor when a goes out of scope).

Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/test/CodeGenCXX/references.cpp

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=84162&r1=84161&r2=84162&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Oct 14 19:51:46 2009
@@ -78,6 +78,26 @@
 RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,
                                                    QualType DestType,
                                                    bool IsInitializer) {
+  if (const CXXExprWithTemporaries *TE = dyn_cast<CXXExprWithTemporaries>(E)) {
+    // If we shouldn't destroy the temporaries, just emit the
+    // child expression.
+    if (!TE->shouldDestroyTemporaries())
+      return EmitReferenceBindingToExpr(TE->getSubExpr(), DestType,
+                                        IsInitializer);
+    
+    // Keep track of the current cleanup stack depth.
+    unsigned OldNumLiveTemporaries = LiveTemporaries.size();
+    
+    RValue RV = EmitReferenceBindingToExpr(TE->getSubExpr(), DestType,
+                                           IsInitializer);
+    
+    // Pop temporaries.
+    while (LiveTemporaries.size() > OldNumLiveTemporaries)
+      PopCXXTemporary();
+    
+    return RV;
+  }
+  
   RValue Val;
   if (E->isLvalue(getContext()) == Expr::LV_Valid) {
     // Emit the expr as an lvalue.
@@ -86,9 +106,21 @@
       return RValue::get(LV.getAddress());
     Val = EmitLoadOfLValue(LV, E->getType());
   } else {
-    // FIXME: Initializers don't work with casts yet. For example
-    // const A& a = B();
-    // if B inherits from A.
+    const CXXRecordDecl *BaseClassDecl = 0;
+    const CXXRecordDecl *DerivedClassDecl = 0;
+    
+    if (const CastExpr *CE = 
+          dyn_cast<CastExpr>(E->IgnoreParenNoopCasts(getContext()))) {
+      if (CE->getCastKind() == CastExpr::CK_DerivedToBase) {
+        E = CE->getSubExpr();
+        
+        BaseClassDecl = 
+          cast<CXXRecordDecl>(CE->getType()->getAs<RecordType>()->getDecl());
+        DerivedClassDecl = 
+          cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
+      }
+    }
+      
     Val = EmitAnyExprToTemp(E, /*IsAggLocVolatile=*/false,
                             IsInitializer);
 
@@ -106,6 +138,16 @@
         }
       }
     }
+    
+    // Check if need to perform the derived-to-base cast.
+    if (BaseClassDecl) {
+      llvm::Value *Derived = Val.getAggregateAddr();
+      
+      llvm::Value *Base = 
+        GetAddressCXXOfBaseClass(Derived, DerivedClassDecl, BaseClassDecl, 
+                                 /*NullCheckValue=*/false);
+      return RValue::get(Base);
+    }
   }
 
   if (Val.isAggregate()) {

Modified: cfe/trunk/test/CodeGenCXX/references.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/references.cpp?rev=84162&r1=84161&r2=84162&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/references.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/references.cpp Wed Oct 14 19:51:46 2009
@@ -1,4 +1,4 @@
-// RUN: clang-cc -verify -emit-llvm -o %t %s
+// RUN: clang-cc -verify -emit-llvm -o - %s | FileCheck %s
 
 void t1() {
   extern int& a;
@@ -100,3 +100,10 @@
 void *foo = 0;
 void * const & kFoo = foo;
 
+struct D : C { D(); ~D(); };
+
+void h() {
+  // CHECK: call void @_ZN1DD1Ev
+  const C& c = D();
+}
+





More information about the cfe-commits mailing list