Parsing, representation, and preliminary semantic analysis of destructors.

Implicit declaration of destructors (when necessary).

Extended Declarator to store information about parsed constructors
and destructors; this will be extended to deal with declarators that
name overloaded operators (e.g., "operator +") and user-defined
conversion operators (e.g., "operator int").



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58767 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 57fa193..f90469a 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -128,6 +128,37 @@
   return Actions.ActOnLinkageSpec(Loc, LBrace, RBrace, LangBufPtr, StrSize, D);
 }
 
+/// ParseClassName - Parse a C++ class-name, which names a class. Note
+/// that we only check that the result names a type; semantic analysis
+/// will need to verify that the type names a class. The result is
+/// either a type or NULL, dependending on whether a type name was
+/// found.
+///
+///       class-name: [C++ 9.1]
+///         identifier
+///         template-id   [TODO]
+/// 
+Parser::TypeTy *Parser::ParseClassName() {
+  // Parse the class-name.
+  // FIXME: Alternatively, parse a simple-template-id.
+  if (Tok.isNot(tok::identifier)) {
+    Diag(Tok.getLocation(), diag::err_expected_class_name);
+    return 0;
+  }
+
+  // We have an identifier; check whether it is actually a type.
+  TypeTy *Type = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope);
+  if (!Type) {
+    Diag(Tok.getLocation(), diag::err_expected_class_name);
+    return 0;
+  }
+
+  // Consume the identifier.
+  ConsumeToken();
+
+  return Type;
+}
+
 /// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or
 /// elaborated-type-specifier [C++ dcl.type.elab]; we can't tell which
 /// until we reach the start of a definition or see a token that
@@ -325,29 +356,17 @@
 
   // FIXME: Parse optional '::' and optional nested-name-specifier.
 
-  // Parse the class-name.
-  // FIXME: Alternatively, parse a simple-template-id.
-  if (Tok.isNot(tok::identifier)) {
-    Diag(Tok.getLocation(), diag::err_expected_class_name);
-    return true;
-  }
-
-  // We have an identifier; check whether it is actually a type.
-  TypeTy *BaseType = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope);
-  if (!BaseType) {
-    Diag(Tok.getLocation(), diag::err_expected_class_name);
-    return true;
-  }
-
   // The location of the base class itself.
   SourceLocation BaseLoc = Tok.getLocation();
+
+  // Parse the class-name.
+  TypeTy *BaseType = ParseClassName();
+  if (!BaseType)
+    return true;
   
   // Find the complete source range for the base-specifier.  
   SourceRange Range(StartLoc, BaseLoc);
   
-  // Consume the identifier token (finally!).
-  ConsumeToken();
-  
   // Notify semantic analysis that we have parsed a complete
   // base-specifier.
   return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access, BaseType,