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/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 817204c..d5b6312 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -257,6 +257,17 @@
   }
 }
 
+/// isCurrentClassName - Determine whether the identifier II is the
+/// name of the class type currently being defined. In the case of
+/// nested classes, this will only return true if II is the name of
+/// the innermost class.
+bool Sema::isCurrentClassName(const IdentifierInfo &II, Scope *) {
+  if (CXXRecordDecl *CurDecl = dyn_cast_or_null<CXXRecordDecl>(CurContext))
+    return &II == CurDecl->getIdentifier();
+  else
+    return false;
+}
+
 /// ActOnBaseSpecifier - Parsed a base specifier. A base specifier is
 /// one entry in the base class list of a class specifier, for
 /// example: 
@@ -361,9 +372,21 @@
 /// ActOnStartCXXClassDef - This is called at the start of a class/struct/union
 /// definition, when on C++.
 void Sema::ActOnStartCXXClassDef(Scope *S, DeclTy *D, SourceLocation LBrace) {
-  Decl *Dcl = static_cast<Decl *>(D);
-  PushDeclContext(cast<CXXRecordDecl>(Dcl));
+  CXXRecordDecl *Dcl = cast<CXXRecordDecl>(static_cast<Decl *>(D));
+  PushDeclContext(Dcl);
   FieldCollector->StartClass();
+
+  if (Dcl->getIdentifier()) {
+    // C++ [class]p2: 
+    //   [...] The class-name is also inserted into the scope of the
+    //   class itself; this is known as the injected-class-name. For
+    //   purposes of access checking, the injected-class-name is treated
+    //   as if it were a public member name.
+    TypedefDecl *InjectedClassName 
+      = TypedefDecl::Create(Context, Dcl, LBrace, Dcl->getIdentifier(),
+                            Context.getTypeDeclType(Dcl), /*PrevDecl=*/0);
+    PushOnScopeChains(InjectedClassName, S);
+  }
 }
 
 /// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
@@ -539,6 +562,22 @@
   Consumer.HandleTagDeclDefinition(Rec);
 }
 
+/// ActOnConstructorDeclarator - Called by ActOnDeclarator to complete
+/// the declaration of the given C++ constructor ConDecl that was
+/// built from declarator D. This routine is responsible for checking
+/// that the newly-created constructor declaration is well-formed and
+/// for recording it in the C++ class. Example:
+///
+/// @code 
+/// class X {
+///   X(); // X::X() will be the ConDecl.
+/// };
+/// @endcode
+Sema::DeclTy *Sema::ActOnConstructorDeclarator(CXXConstructorDecl *ConDecl) {
+  assert(ConDecl && "Expected to receive a constructor declaration");
+  return (DeclTy *)ConDecl;
+}
+
 //===----------------------------------------------------------------------===//
 // Namespace Handling
 //===----------------------------------------------------------------------===//