Add support for parsing and representing C++ constructor declarations.

Notes:
  - Constructors are never found by name lookup, so they'll never get
    pushed into any scope. Instead, they are stored as an 
    OverloadedFunctionDecl in CXXRecordDecl for easy overloading.
  - There's a new action isCurrentClassName that determines whether an
    identifier is the name of the innermost class currently being defined;
    we use this to identify the declarator-id grammar rule that refers to 
    a type-name. 
  - MinimalAction does *not* support parsing constructors.
  - We now handle virtual and explicit function specifiers.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58499 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 2306151..16053ce 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -737,8 +737,88 @@
     }
 
     bool isInline = D.getDeclSpec().isInlineSpecified();
+    bool isVirtual = D.getDeclSpec().isVirtualSpecified();
+    bool isExplicit = D.getDeclSpec().isExplicitSpecified();
+
     FunctionDecl *NewFD;
-    if (D.getContext() == Declarator::MemberContext) {
+    if (isCurrentClassName(*II, S)) {
+      // This is a C++ constructor declaration.
+      assert(D.getContext() == Declarator::MemberContext &&
+             "Constructors can only be declared in a member context");
+
+      // C++ [class.ctor]p3:
+      //   A constructor shall not be virtual (10.3) or static (9.4). A
+      //   constructor can be invoked for a const, volatile or const
+      //   volatile object. A constructor shall not be declared const,
+      //   volatile, or const volatile (9.3.2).
+      if (isVirtual) {
+        Diag(D.getIdentifierLoc(),
+             diag::err_constructor_cannot_be,
+             "virtual",
+             SourceRange(D.getDeclSpec().getVirtualSpecLoc()),
+             SourceRange(D.getIdentifierLoc()));
+        isVirtual = false;
+      }
+      if (SC == FunctionDecl::Static) {
+        Diag(D.getIdentifierLoc(),
+             diag::err_constructor_cannot_be,
+             "static",
+             SourceRange(D.getDeclSpec().getStorageClassSpecLoc()),
+             SourceRange(D.getIdentifierLoc()));
+        isVirtual = false;
+      }
+      if (D.getDeclSpec().hasTypeSpecifier()) {
+        // Constructors don't have return types, but the parser will
+        // happily parse something like:
+        //
+        //   class X {
+        //     float X(float);
+        //   };
+        //
+        // The return type will be eliminated later.
+        Diag(D.getIdentifierLoc(),
+             diag::err_constructor_return_type,
+             SourceRange(D.getDeclSpec().getTypeSpecTypeLoc()),
+             SourceRange(D.getIdentifierLoc()));
+      } 
+      if (R->getAsFunctionTypeProto()->getTypeQuals() != 0) {
+        DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
+        if (FTI.TypeQuals & QualType::Const)
+          Diag(D.getIdentifierLoc(),
+               diag::err_invalid_qualified_constructor,
+               "const",
+               SourceRange(D.getIdentifierLoc()));
+        if (FTI.TypeQuals & QualType::Volatile)
+          Diag(D.getIdentifierLoc(),
+               diag::err_invalid_qualified_constructor,
+               "volatile",
+               SourceRange(D.getIdentifierLoc()));
+        if (FTI.TypeQuals & QualType::Restrict)
+          Diag(D.getIdentifierLoc(),
+               diag::err_invalid_qualified_constructor,
+               "restrict",
+               SourceRange(D.getIdentifierLoc()));
+      }
+      
+      // Rebuild the function type "R" without any type qualifiers (in
+      // case any of the errors above fired) and with "void" as the
+      // return type, since constructors don't have return types. We
+      // *always* have to do this, because GetTypeForDeclarator will
+      // put in a result type of "int" when none was specified.
+      const FunctionTypeProto *Proto = R->getAsFunctionTypeProto();
+      R = Context.getFunctionType(Context.VoidTy, Proto->arg_type_begin(),
+                                  Proto->getNumArgs(),
+                                  Proto->isVariadic(),
+                                  0);
+
+      // Create the new declaration
+      NewFD = CXXConstructorDecl::Create(Context, 
+                                         cast<CXXRecordDecl>(CurContext),
+                                         D.getIdentifierLoc(), II, R,
+                                         isExplicit, isInline,
+                                         /*isImplicitlyDeclared=*/false);
+
+    } else if (D.getContext() == Declarator::MemberContext) {
       // This is a C++ method declaration.
       NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(CurContext),
                                     D.getIdentifierLoc(), II, R,
@@ -826,6 +906,13 @@
       }
     }
 
+    // C++ constructors are handled by a separate routine, since they
+    // don't require any declaration merging (C++ [class.mfct]p2) and
+    // they aren't ever pushed into scope, because they can't be found
+    // by name lookup anyway (C++ [class.ctor]p2).
+    if (CXXConstructorDecl *ConDecl = dyn_cast<CXXConstructorDecl>(NewFD))
+      return ActOnConstructorDeclarator(ConDecl);
+
     // Merge the decl with the existing one if appropriate. Since C functions
     // are in a flat namespace, make sure we consider decls in outer scopes.
     if (PrevDecl &&