Implement and test aggregate initialization in C++. Major changes:

  - Support initialization of reference members; complain if any
  reference members are left uninitialized.
  - Use C++ copy-initialization for initializing each element (falls
  back to constraint checking in C)
  - Make sure we diagnose when one tries to provide an initializer
  list for a non-aggregate.
  - Don't complain about empty initializers in C++ (they are permitted)
  - Unrelated but necessary: don't bother trying to convert the
  decl-specifier-seq to a type when we're dealing with a C++
  constructor, destructor, or conversion operator; it results in
  spurious warnings.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63431 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 43f8baa..9d78d0a 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -18,8 +18,11 @@
 #include "clang/Parse/DeclSpec.h"
 using namespace clang;
 
-/// ConvertDeclSpecToType - Convert the specified declspec to the appropriate
-/// type object.  This returns null on error.
+/// \brief Convert the specified declspec to the appropriate type
+/// object.
+/// \param DS  the declaration specifiers
+/// \returns The type described by the declaration specifiers, or NULL
+/// if there was an error.
 QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
   // FIXME: Should move the logic from DeclSpec::Finish to here for validity
   // checking.
@@ -81,6 +84,7 @@
       // "At least one type specifier shall be given in the declaration
       // specifiers in each declaration, and in the specifier-qualifier list in
       // each struct declaration and type name."
+      // FIXME: this should be a hard error in C++
       if (!DS.hasTypeSpecifier())
         Diag(DS.getSourceRange().getBegin(), diag::ext_missing_type_specifier);
     }
@@ -254,8 +258,26 @@
   if (!getLangOptions().C99 && !getLangOptions().CPlusPlus0x &&
       D.getDeclSpec().getTypeSpecWidth() == DeclSpec::TSW_longlong)
     Diag(D.getDeclSpec().getTypeSpecWidthLoc(), diag::ext_longlong);
-  
-  QualType T = ConvertDeclSpecToType(D.getDeclSpec());
+
+  // Determine the type of the declarator. Not all forms of declarator
+  // have a type.
+  QualType T;
+  switch (D.getKind()) {
+  case Declarator::DK_Abstract:
+  case Declarator::DK_Normal:
+  case Declarator::DK_Operator:
+    T = ConvertDeclSpecToType(D.getDeclSpec());
+    break;
+
+  case Declarator::DK_Constructor:
+  case Declarator::DK_Destructor:
+  case Declarator::DK_Conversion:
+    // Constructors and destructors don't have return types. Use
+    // "void" instead. Conversion operators will check their return
+    // types separately.
+    T = Context.VoidTy;
+    break;
+  }
 
   // Walk the DeclTypeInfo, building the recursive type as we go.  DeclTypeInfos
   // are ordered from the identifier out, which is opposite of what we want :).