]> granicus.if.org Git - clang/commitdiff
Make IRGen for initializing a member reference work correctly.
authorEli Friedman <eli.friedman@gmail.com>
Sat, 29 Aug 2009 20:58:20 +0000 (20:58 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Sat, 29 Aug 2009 20:58:20 +0000 (20:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80439 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXX.cpp
test/CodeGenCXX/constructor-init-reference.cpp [new file with mode: 0644]

index 43eea15a69d8c7da9a256c99354111e2ce7d770a..4ca0473312d9a39900306f69ddb25b189458edd5 100644 (file)
@@ -1643,7 +1643,16 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
         FieldType = getContext().getBaseElementType(FieldType);
       
       LoadOfThis = LoadCXXThis();
-      LValue LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
+      LValue LHS;
+      if (FieldType->isReferenceType()) {
+        // FIXME: This is really ugly; should be refactored somehow
+        unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
+        llvm::Value *V = Builder.CreateStructGEP(LoadOfThis, idx, "tmp");
+        LHS = LValue::MakeAddr(V, FieldType.getCVRQualifiers(),
+                               QualType::GCNone, FieldType.getAddressSpace());
+      } else {
+        LHS = EmitLValueForField(LoadOfThis, Field, false, 0);
+      }
       if (FieldType->getAs<RecordType>()) {
         if (!Field->isAnonymousStructOrUnion()) {
           assert(Member->getConstructor() && 
@@ -1673,8 +1682,13 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
       
       assert(Member->getNumArgs() == 1 && "Initializer count must be 1 only");
       Expr *RhsExpr = *Member->arg_begin();
-      llvm::Value *RHS = EmitScalarExpr(RhsExpr, true);
-      EmitStoreThroughLValue(RValue::get(RHS), LHS, FieldType);
+      RValue RHS;
+      if (FieldType->isReferenceType())
+        RHS = EmitReferenceBindingToExpr(RhsExpr, FieldType,
+                                        /*IsInitializer=*/true);
+      else
+        RHS = RValue::get(EmitScalarExpr(RhsExpr, true));
+      EmitStoreThroughLValue(RHS, LHS, FieldType);
     }
   }
 
diff --git a/test/CodeGenCXX/constructor-init-reference.cpp b/test/CodeGenCXX/constructor-init-reference.cpp
new file mode 100644 (file)
index 0000000..040441f
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: clang-cc -emit-llvm -o - %s | grep "store i32\* @x, i32\*\*"
+
+int x;
+class A {
+  int& y;
+  A() : y(x) {}
+};
+A z;
+