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/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 71afe68..8d00c09 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1606,45 +1606,48 @@
 /// GetNameForDeclarator - Determine the full declaration name for the
 /// given Declarator.
 DeclarationName Sema::GetNameForDeclarator(Declarator &D) {
-  switch (D.getKind()) {
-  case Declarator::DK_Abstract:
-    assert(D.getIdentifier() == 0 && "abstract declarators have no name");
-    return DeclarationName();
+  UnqualifiedId &Name = D.getName();
+  switch (Name.getKind()) {
+  case UnqualifiedId::IK_Identifier:
+    return DeclarationName(Name.Identifier);
 
-  case Declarator::DK_Normal:
-    assert (D.getIdentifier() != 0 && "normal declarators have an identifier");
-    return DeclarationName(D.getIdentifier());
+  case UnqualifiedId::IK_OperatorFunctionId:
+    return Context.DeclarationNames.getCXXOperatorName(
+                                              Name.OperatorFunctionId.Operator);
 
-  case Declarator::DK_Constructor: {
-    QualType Ty = GetTypeFromParser(D.getDeclaratorIdType());
+  case UnqualifiedId::IK_ConversionFunctionId: {
+    QualType Ty = GetTypeFromParser(Name.ConversionFunctionId);
+    if (Ty.isNull())
+      return DeclarationName();
+    
+    return Context.DeclarationNames.getCXXConversionFunctionName(
+                                                  Context.getCanonicalType(Ty));
+  }
+      
+  case UnqualifiedId::IK_ConstructorName: {
+    QualType Ty = GetTypeFromParser(Name.ConstructorName);
+    if (Ty.isNull())
+      return DeclarationName();
+    
     return Context.DeclarationNames.getCXXConstructorName(
                                                 Context.getCanonicalType(Ty));
   }
-
-  case Declarator::DK_Destructor: {
-    QualType Ty = GetTypeFromParser(D.getDeclaratorIdType());
+      
+  case UnqualifiedId::IK_DestructorName: {
+    QualType Ty = GetTypeFromParser(Name.DestructorName);
+    if (Ty.isNull())
+      return DeclarationName();
+    
     return Context.DeclarationNames.getCXXDestructorName(
                                                 Context.getCanonicalType(Ty));
   }
-
-  case Declarator::DK_Conversion: {
-    // FIXME: We'd like to keep the non-canonical type for diagnostics!
-    QualType Ty = GetTypeFromParser(D.getDeclaratorIdType());
-    return Context.DeclarationNames.getCXXConversionFunctionName(
-                                                Context.getCanonicalType(Ty));
-  }
-
-  case Declarator::DK_Operator:
-    assert(D.getIdentifier() == 0 && "operator names have no identifier");
-    return Context.DeclarationNames.getCXXOperatorName(
-                                                D.getOverloadedOperator());
       
-  case Declarator::DK_TemplateId: {
-    TemplateName Name
-      = TemplateName::getFromVoidPointer(D.getTemplateId()->Template);    
-    if (TemplateDecl *Template = Name.getAsTemplateDecl())
+  case UnqualifiedId::IK_TemplateId: {
+    TemplateName TName
+      = TemplateName::getFromVoidPointer(Name.TemplateId->Template);    
+    if (TemplateDecl *Template = TName.getAsTemplateDecl())
       return Template->getDeclName();
-    if (OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl())
+    if (OverloadedFunctionDecl *Ovl = TName.getAsOverloadedFunctionDecl())
       return Ovl->getDeclName();
     
     return DeclarationName();
@@ -2517,7 +2520,7 @@
     isInline |= IsFunctionDefinition;
   }
 
-  if (D.getKind() == Declarator::DK_Constructor) {
+  if (Name.getNameKind() == DeclarationName::CXXConstructorName) {
     // This is a C++ constructor declaration.
     assert(DC->isRecord() &&
            "Constructors can only be declared in a member context");
@@ -2530,7 +2533,7 @@
                                        D.getIdentifierLoc(), Name, R, DInfo,
                                        isExplicit, isInline,
                                        /*isImplicitlyDeclared=*/false);
-  } else if (D.getKind() == Declarator::DK_Destructor) {
+  } else if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
     // This is a C++ destructor declaration.
     if (DC->isRecord()) {
       R = CheckDestructorDeclarator(D, SC);
@@ -2552,7 +2555,7 @@
                                    /*hasPrototype=*/true);
       D.setInvalidType();
     }
-  } else if (D.getKind() == Declarator::DK_Conversion) {
+  } else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) {
     if (!DC->isRecord()) {
       Diag(D.getIdentifierLoc(),
            diag::err_conv_function_not_member);
@@ -2798,8 +2801,8 @@
   bool HasExplicitTemplateArgs = false;
   llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
   SourceLocation LAngleLoc, RAngleLoc;
-  if (D.getKind() == Declarator::DK_TemplateId) {
-    TemplateIdAnnotation *TemplateId = D.getTemplateId();
+  if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
+    TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
     ASTTemplateArgsPtr TemplateArgsPtr(*this,
                                        TemplateId->getTemplateArgs(),
                                        TemplateId->getTemplateArgIsType(),
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 90aef21..bc25513 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2295,7 +2295,7 @@
   //   (7.1.3); however, a typedef-name that names a class shall not
   //   be used as the identifier in the declarator for a destructor
   //   declaration.
-  QualType DeclaratorType = GetTypeFromParser(D.getDeclaratorIdType());
+  QualType DeclaratorType = GetTypeFromParser(D.getName().DestructorName);
   if (isa<TypedefType>(DeclaratorType)) {
     Diag(D.getIdentifierLoc(), diag::err_destructor_typedef_name)
       << DeclaratorType;
@@ -2421,7 +2421,7 @@
   // C++ [class.conv.fct]p4:
   //   The conversion-type-id shall not represent a function type nor
   //   an array type.
-  QualType ConvType = GetTypeFromParser(D.getDeclaratorIdType());
+  QualType ConvType = GetTypeFromParser(D.getName().ConversionFunctionId);
   if (ConvType->isArrayType()) {
     Diag(D.getIdentifierLoc(), diag::err_conv_function_to_array);
     ConvType = Context.getPointerType(ConvType);
@@ -4515,12 +4515,12 @@
 
   if (DC->isFileContext()) {
     // This implies that it has to be an operator or function.
-    if (D.getKind() == Declarator::DK_Constructor ||
-        D.getKind() == Declarator::DK_Destructor ||
-        D.getKind() == Declarator::DK_Conversion) {
+    if (D.getName().getKind() == UnqualifiedId::IK_ConstructorName ||
+        D.getName().getKind() == UnqualifiedId::IK_DestructorName ||
+        D.getName().getKind() == UnqualifiedId::IK_ConversionFunctionId) {
       Diag(Loc, diag::err_introducing_special_friend) <<
-        (D.getKind() == Declarator::DK_Constructor ? 0 :
-         D.getKind() == Declarator::DK_Destructor ? 1 : 2);
+        (D.getName().getKind() == UnqualifiedId::IK_ConstructorName ? 0 :
+         D.getName().getKind() == UnqualifiedId::IK_DestructorName ? 1 : 2);
       return DeclPtrTy();
     }
   }
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index f7a22d2..7182992 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -4043,8 +4043,8 @@
   // argument list into our AST format.
   bool HasExplicitTemplateArgs = false;
   llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
-  if (D.getKind() == Declarator::DK_TemplateId) {
-    TemplateIdAnnotation *TemplateId = D.getTemplateId();
+  if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
+    TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
     ASTTemplateArgsPtr TemplateArgsPtr(*this,
                                        TemplateId->getTemplateArgs(),
                                        TemplateId->getTemplateArgIsType(),
@@ -4147,7 +4147,7 @@
   //
   // C++98 has the same restriction, just worded differently.
   FunctionTemplateDecl *FunTmpl = Specialization->getPrimaryTemplate();
-  if (D.getKind() != Declarator::DK_TemplateId && !FunTmpl &&
+  if (D.getName().getKind() != UnqualifiedId::IK_TemplateId && !FunTmpl &&
       D.getCXXScopeSpec().isSet() && 
       !ScopeSpecifierHasTemplateId(D.getCXXScopeSpec()))
     Diag(D.getIdentifierLoc(), 
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index d2652c9..94b74fb 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -870,6 +870,11 @@
 
 QualType Sema::GetTypeFromParser(TypeTy *Ty, DeclaratorInfo **DInfo) {
   QualType QT = QualType::getFromOpaquePtr(Ty);
+  if (QT.isNull()) {
+    if (DInfo) *DInfo = 0;
+    return QualType();
+  }
+
   DeclaratorInfo *DI = 0;
   if (LocInfoType *LIT = dyn_cast<LocInfoType>(QT)) {
     QT = LIT->getType();
@@ -893,20 +898,19 @@
   // have a type.
   QualType T;
 
-  switch (D.getKind()) {
-  case Declarator::DK_Abstract:
-  case Declarator::DK_Normal:
-  case Declarator::DK_Operator:
-  case Declarator::DK_TemplateId:
+  switch (D.getName().getKind()) {
+  case UnqualifiedId::IK_Identifier:
+  case UnqualifiedId::IK_OperatorFunctionId:
+  case UnqualifiedId::IK_TemplateId:
     T = ConvertDeclSpecToType(D, *this);
     
     if (!D.isInvalidType() && OwnedDecl && D.getDeclSpec().isTypeSpecOwned())
       *OwnedDecl = cast<TagDecl>((Decl *)D.getDeclSpec().getTypeRep());
     break;
 
-  case Declarator::DK_Constructor:
-  case Declarator::DK_Destructor:
-  case Declarator::DK_Conversion:
+  case UnqualifiedId::IK_ConstructorName:
+  case UnqualifiedId::IK_DestructorName:
+  case UnqualifiedId::IK_ConversionFunctionId:
     // Constructors and destructors don't have return types. Use
     // "void" instead. Conversion operators will check their return
     // types separately.