Replace the code that parses member access expressions after "." or
"->" with a use of ParseUnqualifiedId. Collapse
ActOnMemberReferenceExpr, ActOnDestructorReferenceExpr (both of them),
ActOnOverloadedOperatorReferenceExpr,
ActOnConversionOperatorReferenceExpr, and
ActOnMemberTemplateIdReferenceExpr into a single, new action
ActOnMemberAccessExpr that does the same thing more cleanly (and can
keep more source-location information).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85930 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index b125035..265d13a 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -315,76 +315,13 @@
/*EnteringContext=*/false,
/*AllowDestructorName=*/false,
/*AllowConstructorName=*/false,
+ /*ObjectType=*/0,
Name))
return ExprError();
return Actions.ActOnIdExpression(CurScope, SS, Name, Tok.is(tok::l_paren),
isAddressOfOperand);
-#if 0
- // unqualified-id:
- // identifier
- // operator-function-id
- // conversion-function-id
- // '~' class-name [TODO]
- // template-id
- //
- switch (Tok.getKind()) {
- default:
- return ExprError(Diag(Tok, diag::err_expected_unqualified_id));
-
- case tok::identifier: {
- // Consume the identifier so that we can see if it is followed by a '('.
- IdentifierInfo &II = *Tok.getIdentifierInfo();
- SourceLocation L = ConsumeToken();
- return Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren),
- &SS, isAddressOfOperand);
- }
-
- case tok::kw_operator: {
- SourceLocation OperatorLoc = Tok.getLocation();
- if (OverloadedOperatorKind Op = TryParseOperatorFunctionId())
- return Actions.ActOnCXXOperatorFunctionIdExpr(
- CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS,
- isAddressOfOperand);
- if (TypeTy *Type = ParseConversionFunctionId())
- return Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, Type,
- Tok.is(tok::l_paren), SS,
- isAddressOfOperand);
-
- // We already complained about a bad conversion-function-id,
- // above.
- return ExprError();
- }
-
- case tok::annot_template_id: {
- TemplateIdAnnotation *TemplateId
- = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
- assert((TemplateId->Kind == TNK_Function_template ||
- TemplateId->Kind == TNK_Dependent_template_name) &&
- "A template type name is not an ID expression");
-
- ASTTemplateArgsPtr TemplateArgsPtr(Actions,
- TemplateId->getTemplateArgs(),
- TemplateId->getTemplateArgIsType(),
- TemplateId->NumArgs);
-
- OwningExprResult Result
- = Actions.ActOnTemplateIdExpr(SS,
- TemplateTy::make(TemplateId->Template),
- TemplateId->TemplateNameLoc,
- TemplateId->LAngleLoc,
- TemplateArgsPtr,
- TemplateId->getTemplateArgLocations(),
- TemplateId->RAngleLoc);
- ConsumeToken(); // Consume the template-id token
- return move(Result);
- }
-
- } // switch.
-
- assert(0 && "The switch was supposed to take care everything.");
-#endif
}
/// ParseCXXCasts - This handles the various ways to cast expressions to another
@@ -806,6 +743,7 @@
IdentifierInfo *Name,
SourceLocation NameLoc,
bool EnteringContext,
+ TypeTy *ObjectType,
UnqualifiedId &Id) {
assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id");
@@ -814,14 +752,13 @@
switch (Id.getKind()) {
case UnqualifiedId::IK_Identifier:
TNK = Actions.isTemplateName(CurScope, *Id.Identifier, Id.StartLocation,
- &SS, /*ObjectType=*/0, EnteringContext,
- Template);
+ &SS, ObjectType, EnteringContext, Template);
break;
case UnqualifiedId::IK_OperatorFunctionId: {
// FIXME: Temporary hack: warn that we are completely ignoring the
// template arguments for now.
- // Parse the enclosed template argument list.
+ // Parse the enclosed template argument list and throw it away.
SourceLocation LAngleLoc, RAngleLoc;
TemplateArgList TemplateArgs;
TemplateArgIsTypeList TemplateArgIsType;
@@ -840,15 +777,32 @@
}
case UnqualifiedId::IK_ConstructorName:
- TNK = Actions.isTemplateName(CurScope, *Name, NameLoc,
- &SS, /*ObjectType=*/0, EnteringContext,
- Template);
+ TNK = Actions.isTemplateName(CurScope, *Name, NameLoc, &SS, ObjectType,
+ EnteringContext, Template);
break;
case UnqualifiedId::IK_DestructorName:
- TNK = Actions.isTemplateName(CurScope, *Name, NameLoc,
- &SS, /*ObjectType=*/0, EnteringContext,
- Template);
+ if (ObjectType) {
+ Template = Actions.ActOnDependentTemplateName(SourceLocation(), *Name,
+ NameLoc, SS, ObjectType);
+ TNK = TNK_Dependent_template_name;
+ if (!Template.get())
+ return true;
+ } else {
+ TNK = Actions.isTemplateName(CurScope, *Name, NameLoc, &SS, ObjectType,
+ EnteringContext, Template);
+
+ if (TNK == TNK_Non_template && Id.DestructorName == 0) {
+ // The identifier following the destructor did not refer to a template
+ // or to a type. Complain.
+ if (ObjectType)
+ Diag(NameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
+ << Name;
+ else
+ Diag(NameLoc, diag::err_destructor_class_name);
+ return true;
+ }
+ }
break;
default:
@@ -974,6 +928,7 @@
bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
bool AllowDestructorName,
bool AllowConstructorName,
+ TypeTy *ObjectType,
UnqualifiedId &Result) {
// unqualified-id:
// identifier
@@ -997,7 +952,7 @@
// If the next token is a '<', we may have a template.
if (Tok.is(tok::less))
return ParseUnqualifiedIdTemplateId(SS, Id, IdLoc, EnteringContext,
- Result);
+ ObjectType, Result);
return false;
}
@@ -1110,7 +1065,8 @@
// If the next token is a '<', we may have a template.
if (Tok.is(tok::less))
return ParseUnqualifiedIdTemplateId(SS, 0, SourceLocation(),
- EnteringContext, Result);
+ EnteringContext, ObjectType,
+ Result);
return false;
}
@@ -1166,24 +1122,30 @@
IdentifierInfo *ClassName = Tok.getIdentifierInfo();
SourceLocation ClassNameLoc = ConsumeToken();
+ if (Tok.is(tok::less)) {
+ Result.setDestructorName(TildeLoc, 0, ClassNameLoc);
+ return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc,
+ EnteringContext, ObjectType, Result);
+ }
+
// Note that this is a destructor name.
Action::TypeTy *Ty = Actions.getTypeName(*ClassName, ClassNameLoc,
CurScope, &SS);
if (!Ty) {
- Diag(ClassNameLoc, diag::err_destructor_class_name);
+ if (ObjectType)
+ Diag(ClassNameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
+ << ClassName;
+ else
+ Diag(ClassNameLoc, diag::err_destructor_class_name);
return true;
}
Result.setDestructorName(TildeLoc, Ty, ClassNameLoc);
-
- if (Tok.is(tok::less))
- return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc,
- EnteringContext, Result);
-
return false;
}
- Diag(Tok, diag::err_expected_unqualified_id);
+ Diag(Tok, diag::err_expected_unqualified_id)
+ << getLang().CPlusPlus;
return true;
}