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.