Introduce a new expression node, ImplicitValueInitExpr, that
represents an implicit value-initialization of a subobject of a
particular type. This replaces the (ab)use of CXXZeroValueInitExpr
within initializer lists for the "holes" that occur due to the use of
C99 designated initializers.

The new test case is currently XFAIL'd, because CodeGen's
ConstExprEmitter (in lib/CodeGen/CGExprConstant.cpp) needs to be
taught to value-initialize when it sees ImplicitValueInitExprs.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63317 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 7572560..1559213 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2220,17 +2220,17 @@
   if (CompoundLiteralExpr *e = dyn_cast<CompoundLiteralExpr>(Init))
     return CheckForConstantInitializer(e->getInitializer(), DclT);
 
+  if (isa<ImplicitValueInitExpr>(Init)) {
+    // FIXME: In C++, check for non-POD types.
+    return false;
+  }
+
   if (InitListExpr *Exp = dyn_cast<InitListExpr>(Init)) {
     unsigned numInits = Exp->getNumInits();
     for (unsigned i = 0; i < numInits; i++) {
       // FIXME: Need to get the type of the declaration for C++,
       // because it could be a reference?
 
-      // Implicitly-generated value initializations are okay.
-      if (isa<CXXZeroInitValueExpr>(Exp->getInit(i)) &&
-          cast<CXXZeroInitValueExpr>(Exp->getInit(i))->isImplicit()) 
-        continue;
-
       if (CheckForConstantInitializer(Exp->getInit(i),
                                       Exp->getInit(i)->getType()))
         return true;
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 527f965..5d7f705 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -17,7 +17,6 @@
 #include "clang/Parse/Designator.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
 #include <map>
 using namespace clang;
 
@@ -137,10 +136,9 @@
       // FIXME: Check for fields with reference type in C++?
       if (!ILE->getInit(Init))
         ILE->setInit(Init, 
-                     new (Context) CXXZeroInitValueExpr(Field->getType(), 
-                                                        SourceLocation(),
-                                                        SourceLocation()));
-      else if (InitListExpr *InnerILE = dyn_cast<InitListExpr>(ILE->getInit(Init)))
+                     new (Context) ImplicitValueInitExpr(Field->getType()));
+      else if (InitListExpr *InnerILE 
+                 = dyn_cast<InitListExpr>(ILE->getInit(Init)))
         fillInValueInitializations(Context, InnerILE);
       ++Init;
     }
@@ -160,9 +158,7 @@
   for (unsigned Init = 0, NumInits = ILE->getNumInits(); Init != NumInits; 
        ++Init) {
     if (!ILE->getInit(Init))
-      ILE->setInit(Init, new (Context) CXXZeroInitValueExpr(ElementType, 
-                                                            SourceLocation(),
-                                                            SourceLocation()));
+      ILE->setInit(Init, new (Context) ImplicitValueInitExpr(ElementType));
     else if (InitListExpr *InnerILE =dyn_cast<InitListExpr>(ILE->getInit(Init)))
       fillInValueInitializations(Context, InnerILE);
   }
@@ -550,6 +546,22 @@
     hadError = true;
     return;
   }    
+
+  if (DeclType->isUnionType() && IList->getNumInits() == 0) {
+    // Value-initialize the first named member of the union.
+    RecordDecl *RD = DeclType->getAsRecordType()->getDecl();
+    for (RecordDecl::field_iterator FieldEnd = RD->field_end();
+         Field != FieldEnd; ++Field) {
+      if (Field->getDeclName()) {
+        StructuredList->setInitializedFieldInUnion(*Field);
+        break;
+      }
+    }
+    return;
+  }
+
+
+
   // If structDecl is a forward declaration, this loop won't do
   // anything except look at designated initializers; That's okay,
   // because an error should get printed out elsewhere. It might be