Clean up designated initialization of unions, so that CodeGen doesn't
have to try to guess which member is being initialized.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63315 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 075a12c..b487bac 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -443,7 +443,38 @@
   unsigned NumInitElements = E->getNumInits();
   RecordDecl *SD = E->getType()->getAsRecordType()->getDecl();
   unsigned CurInitVal = 0;
-  bool isUnion = E->getType()->isUnionType();
+
+  if (E->getType()->isUnionType()) {
+    // Only initialize one field of a union. The field itself is
+    // specified by the initializer list.
+    if (!E->getInitializedFieldInUnion()) {
+      // Empty union; we have nothing to do.
+      
+#ifndef NDEBUG
+      // Make sure that it's really an empty and not a failure of
+      // semantic analysis.
+      for (RecordDecl::field_iterator Field = SD->field_begin(),
+                                   FieldEnd = SD->field_end();
+           Field != FieldEnd; ++Field)
+        assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
+#endif
+      return;
+    }
+
+    // FIXME: volatility
+    FieldDecl *Field = E->getInitializedFieldInUnion();
+    LValue FieldLoc = CGF.EmitLValueForField(DestPtr, Field, true, 0);
+
+    if (NumInitElements) {
+      // Store the initializer into the field
+      EmitInitializationToLValue(E->getInit(0), FieldLoc);
+    } else {
+      // Default-initialize to null
+      EmitNullInitializationToLValue(FieldLoc, Field->getType());
+    }
+
+    return;
+  }
   
   // Here we iterate over the fields; this makes it simpler to both
   // default-initialize fields and skip over unnamed fields.
@@ -457,29 +488,15 @@
     if (Field->isUnnamedBitfield())
       continue;
 
-    // When we're coping with C99 designated initializers into a
-    // union, find the field that has the same type as the expression
-    // we're initializing the union with.
-    if (isUnion && CurInitVal < NumInitElements && 
-        (CGF.getContext().getCanonicalType(Field->getType()) != 
-           CGF.getContext().getCanonicalType(E->getInit(CurInitVal)->getType())))
-      continue;
-
     // FIXME: volatility
-    LValue FieldLoc = CGF.EmitLValueForField(DestPtr, *Field, isUnion,0);
+    LValue FieldLoc = CGF.EmitLValueForField(DestPtr, *Field, false, 0);
     if (CurInitVal < NumInitElements) {
       // Store the initializer into the field
-      // This will probably have to get a bit smarter when we support
-      // designators in initializers
       EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc);
     } else {
       // We're out of initalizers; default-initialize to null
       EmitNullInitializationToLValue(FieldLoc, Field->getType());
     }
-
-    // Unions only initialize one field.
-    if (isUnion)
-      break;
   }
 }