Clean up trivial default constructors now.

hasTrivialDefaultConstructor() really really means it now.

Also implement a fun standards bug regarding aggregates. Doug, if you'd
like, I can un-implement that bug if you think it is truly a defect.

The bug is that non-special-member constructors are never considered
user-provided, so the following is an aggregate:

struct foo {
  foo(int);
};

It's kind of bad, but the solution isn't obvious - should

struct foo {
  foo (int) = delete;
};

be an aggregate or not?

Lastly, add a missing initialization to FunctionDecl.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131101 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index ab097e4..a18aeff 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -38,10 +38,10 @@
     HasTrivialMoveConstructor(true), HasTrivialCopyAssignment(true),
     HasTrivialMoveAssignment(true), HasTrivialDestructor(true),
     HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false),
-    DeclaredDefaultConstructor(false), DeclaredCopyConstructor(false), 
-    DeclaredCopyAssignment(false), DeclaredDestructor(false),
-    NumBases(0), NumVBases(0), Bases(), VBases(),
-  Definition(D), FirstFriend(0) {
+    NeedsImplicitDefaultConstructor(false), DeclaredDefaultConstructor(false),
+    DeclaredCopyConstructor(false), DeclaredCopyAssignment(false),
+    DeclaredDestructor(false), NumBases(0), NumVBases(0), Bases(), VBases(),
+    Definition(D), FirstFriend(0) {
 }
 
 CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
@@ -458,8 +458,10 @@
     if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
       // If this is the implicit default constructor, note that we have now
       // declared it.
-      if (Constructor->isDefaultConstructor())
+      if (Constructor->isDefaultConstructor()) {
         data().DeclaredDefaultConstructor = true;
+        data().NeedsImplicitDefaultConstructor = true;
+      }
       // If this is the implicit copy constructor, note that we have now
       // declared it.
       else if (Constructor->isCopyConstructor())
@@ -490,21 +492,21 @@
     data().UserDeclaredConstructor = true;
 
     // Note that we have no need of an implicitly-declared default constructor.
-    data().DeclaredDefaultConstructor = true;
+    data().NeedsImplicitDefaultConstructor = true;
     
-    // C++ [dcl.init.aggr]p1:
-    //   An aggregate is an array or a class (clause 9) with no
-    //   user-declared constructors (12.1) [...].
-    data().Aggregate = false;
-
-    // C++ [class]p4:
-    //   A POD-struct is an aggregate class [...]
-    data().PlainOldData = false;
+    // FIXME: Under C++0x, /only/ special member functions may be user-provided.
+    //        This is probably a defect.
+    bool UserProvided = false;
 
     // C++0x [class.ctor]p5:
     //   A default constructor is trivial if it is not user-provided [...]
-    if (Constructor->isUserProvided())
-      data().HasTrivialDefaultConstructor = false;
+    if (Constructor->isDefaultConstructor()) {
+      data().DeclaredDefaultConstructor = true;
+      if (Constructor->isUserProvided()) {
+        data().HasTrivialDefaultConstructor = false;
+        UserProvided = true;
+      }
+    }
 
     // Note when we have a user-declared copy or move constructor, which will
     // suppress the implicit declaration of those constructors.
@@ -516,14 +518,18 @@
         // C++0x [class.copy]p13:
         //   A copy/move constructor for class X is trivial if it is not
         //   user-provided [...]
-        if (Constructor->isUserProvided())
+        if (Constructor->isUserProvided()) {
           data().HasTrivialCopyConstructor = false;
+          UserProvided = true;
+        }
       } else if (Constructor->isMoveConstructor()) {
         // C++0x [class.copy]p13:
         //   A copy/move constructor for class X is trivial if it is not
         //   user-provided [...]
-        if (Constructor->isUserProvided())
+        if (Constructor->isUserProvided()) {
           data().HasTrivialMoveConstructor = false;
+          UserProvided = true;
+        }
       }
     }
     if (Constructor->isConstExpr() &&
@@ -533,6 +539,21 @@
       data().HasConstExprNonCopyMoveConstructor = true;
     }
 
+    // C++ [dcl.init.aggr]p1:
+    //   An aggregate is an array or a class with no user-declared
+    //   constructors [...].
+    // C++0x [dcl.init.aggr]p1:
+    //   An aggregate is an array or a class with no user-provided
+    //   constructors [...].
+    if (!getASTContext().getLangOptions().CPlusPlus0x || UserProvided)
+      data().Aggregate = false;
+
+    // C++ [class]p4:
+    //   A POD-struct is an aggregate class [...]
+    // Since the POD bit is meant to be C++03 POD-ness, clear it even if the
+    // type is technically an aggregate in C++0x since it wouldn't be in 03.
+    data().PlainOldData = false;
+
     return;
   }