Introduce a new class, UnqualifiedId, that provides a parsed
representation of a C++ unqualified-id, along with a single parsing
function (Parser::ParseUnqualifiedId) that will parse all of the
various forms of unqualified-id in C++.

Replace the representation of the declarator name in Declarator with
the new UnqualifiedId class, simplifying declarator-id parsing
considerably and providing more source-location information to
Sema. In the future, I hope to migrate all of the other
unqualified-id-parsing code over to this single representation, then
begin to merge actions that are currently only different because we
didn't have a unqualified notion of the name in the parser.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85851 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index b56c331..55970c0 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2270,97 +2270,46 @@
 void Parser::ParseDirectDeclarator(Declarator &D) {
   DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
 
-  if (getLang().CPlusPlus) {
-    if (D.mayHaveIdentifier()) {
-      // ParseDeclaratorInternal might already have parsed the scope.
-      bool afterCXXScope = D.getCXXScopeSpec().isSet() ||
-        ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), /*ObjectType=*/0,
-                                       true);
-      if (afterCXXScope) {
-        // Change the declaration context for name lookup, until this function
-        // is exited (and the declarator has been parsed).
-        DeclScopeObj.EnterDeclaratorScope();
-      }
-
-      if (Tok.is(tok::identifier)) {
-        assert(Tok.getIdentifierInfo() && "Not an identifier?");
-
-        // If this identifier is the name of the current class, it's a
-        // constructor name.
-        if (!D.getDeclSpec().hasTypeSpecifier() &&
-            Actions.isCurrentClassName(*Tok.getIdentifierInfo(),CurScope)) {
-          CXXScopeSpec *SS = afterCXXScope? &D.getCXXScopeSpec() : 0;
-          D.setConstructor(Actions.getTypeName(*Tok.getIdentifierInfo(),
-                                               Tok.getLocation(), CurScope, SS),
-                           Tok.getLocation());
-        // This is a normal identifier.
-        } else
-          D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
-        ConsumeToken();
-        goto PastIdentifier;
-      } else if (Tok.is(tok::annot_template_id)) {
-        TemplateIdAnnotation *TemplateId
-          = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
-
-        D.setTemplateId(TemplateId);
-        ConsumeToken();
-        goto PastIdentifier;
-      } else if (Tok.is(tok::kw_operator)) {
-        SourceLocation OperatorLoc = Tok.getLocation();
-        SourceLocation EndLoc;
-
-        // First try the name of an overloaded operator
-        if (OverloadedOperatorKind Op = TryParseOperatorFunctionId(&EndLoc)) {
-          D.setOverloadedOperator(Op, OperatorLoc, EndLoc);
-        } else {
-          // This must be a conversion function (C++ [class.conv.fct]).
-          if (TypeTy *ConvType = ParseConversionFunctionId(&EndLoc))
-            D.setConversionFunction(ConvType, OperatorLoc, EndLoc);
-          else {
-            D.SetIdentifier(0, Tok.getLocation());
-          }
-        }
-        goto PastIdentifier;
-      } else if (Tok.is(tok::tilde)) {
-        // This should be a C++ destructor.
-        SourceLocation TildeLoc = ConsumeToken();
-        if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
-          // FIXME: Inaccurate.
-          SourceLocation NameLoc = Tok.getLocation();
-          SourceLocation EndLoc;
-          CXXScopeSpec *SS = afterCXXScope? &D.getCXXScopeSpec() : 0;
-          TypeResult Type = ParseClassName(EndLoc, SS, true);
-          if (Type.isInvalid())
-            D.SetIdentifier(0, TildeLoc);
-          else
-            D.setDestructor(Type.get(), TildeLoc, NameLoc);
-        } else {
-          Diag(Tok, diag::err_destructor_class_name);
-          D.SetIdentifier(0, TildeLoc);
-        }
-        goto PastIdentifier;
-      }
-
-      // If we reached this point, token is not identifier and not '~'.
-
-      if (afterCXXScope) {
-        Diag(Tok, diag::err_expected_unqualified_id);
+  if (getLang().CPlusPlus && D.mayHaveIdentifier()) {
+    // ParseDeclaratorInternal might already have parsed the scope.
+    bool afterCXXScope = D.getCXXScopeSpec().isSet() ||
+      ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), /*ObjectType=*/0,
+                                     true);
+    if (afterCXXScope) {
+      // Change the declaration context for name lookup, until this function
+      // is exited (and the declarator has been parsed).
+      DeclScopeObj.EnterDeclaratorScope();
+    } 
+    
+    if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) ||
+        Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
+      // We found something that indicates the start of an unqualified-id.
+      // Parse that unqualified-id.
+      if (ParseUnqualifiedId(D.getCXXScopeSpec(), 
+                             /*EnteringContext=*/true, 
+                             /*AllowDestructorName=*/true, 
+                   /*AllowConstructorName=*/!D.getDeclSpec().hasTypeSpecifier(), 
+                             D.getName())) {
         D.SetIdentifier(0, Tok.getLocation());
         D.setInvalidType(true);
-        goto PastIdentifier;
+      } else {
+        // Parsed the unqualified-id; update range information and move along.
+        if (D.getSourceRange().getBegin().isInvalid())
+          D.SetRangeBegin(D.getName().getSourceRange().getBegin());
+        D.SetRangeEnd(D.getName().getSourceRange().getEnd());
       }
+      goto PastIdentifier;
     }
-  }
-
-  // If we reached this point, we are either in C/ObjC or the token didn't
-  // satisfy any of the C++-specific checks.
-  if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
+  } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
     assert(!getLang().CPlusPlus &&
            "There's a C++-specific check for tok::identifier above");
     assert(Tok.getIdentifierInfo() && "Not an identifier?");
     D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
     ConsumeToken();
-  } else if (Tok.is(tok::l_paren)) {
+    goto PastIdentifier;
+  }
+    
+  if (Tok.is(tok::l_paren)) {
     // direct-declarator: '(' declarator ')'
     // direct-declarator: '(' attributes declarator ')'
     // Example: 'char (*X)'   or 'int (*XX)(void)'