forked from OSchip/llvm-project
Add parsing for references to member function templates with explicit
template argument lists, e.g., x.f<int>(). Semantic analysis will be a separate commit. llvm-svn: 80624
This commit is contained in:
parent
cc2f1eb7fe
commit
fbc1823451
|
@ -1321,6 +1321,53 @@ public:
|
|||
return ExprEmpty();
|
||||
}
|
||||
|
||||
/// \brief Parsed a reference to a member template-id.
|
||||
///
|
||||
/// This callback will occur instead of ActOnMemberReferenceExpr() when the
|
||||
/// member in question is a template for which the code provides an
|
||||
/// explicitly-specified template argument list, e.g.,
|
||||
///
|
||||
/// \code
|
||||
/// x.f<int>()
|
||||
/// \endcode
|
||||
///
|
||||
/// \param S the scope in which the member reference expression occurs
|
||||
///
|
||||
/// \param Base the expression to the left of the "." or "->".
|
||||
///
|
||||
/// \param OpLoc the location of the "." or "->".
|
||||
///
|
||||
/// \param OpKind the kind of operator, which will be "." or "->".
|
||||
///
|
||||
/// \param SS the scope specifier that precedes the template-id in, e.g.,
|
||||
/// \c x.Base::f<int>().
|
||||
///
|
||||
/// \param Template the declaration of the template that is being referenced.
|
||||
///
|
||||
/// \param TemplateNameLoc the location of the template name referred to by
|
||||
/// \p Template.
|
||||
///
|
||||
/// \param LAngleLoc the location of the left angle bracket ('<')
|
||||
///
|
||||
/// \param TemplateArgs the (possibly-empty) template argument list provided
|
||||
/// as part of the member reference.
|
||||
///
|
||||
/// \param RAngleLoc the location of the right angle bracket ('>')
|
||||
virtual OwningExprResult
|
||||
ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
|
||||
SourceLocation OpLoc,
|
||||
tok::TokenKind OpKind,
|
||||
const CXXScopeSpec &SS,
|
||||
// FIXME: "template" keyword?
|
||||
TemplateTy Template,
|
||||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgs,
|
||||
SourceLocation *TemplateArgLocs,
|
||||
SourceLocation RAngleLoc) {
|
||||
return ExprEmpty();
|
||||
}
|
||||
|
||||
/// ActOnFinishFullExpr - Called whenever a full expression has been parsed.
|
||||
/// (C++ [intro.execution]p12).
|
||||
virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr) {
|
||||
|
|
|
@ -941,7 +941,7 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
|
|||
ObjCImpDecl, &SS);
|
||||
ConsumeToken();
|
||||
} else if (getLang().CPlusPlus && Tok.is(tok::tilde)) {
|
||||
// We have a C++ pseudo-destructor.
|
||||
// We have a C++ pseudo-destructor or a destructor call, e.g., t.~T()
|
||||
|
||||
// Consume the tilde.
|
||||
ConsumeToken();
|
||||
|
@ -961,6 +961,8 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
|
|||
&SS);
|
||||
ConsumeToken();
|
||||
} else if (getLang().CPlusPlus && Tok.is(tok::kw_operator)) {
|
||||
// We have a reference to a member operator, e.g., t.operator int or
|
||||
// t.operator+.
|
||||
if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) {
|
||||
if (!LHS.isInvalid())
|
||||
LHS = Actions.ActOnOverloadedOperatorReferenceExpr(CurScope,
|
||||
|
@ -983,6 +985,27 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
|
|||
// Don't emit a diagnostic; ParseConversionFunctionId does it for us
|
||||
return ExprError();
|
||||
}
|
||||
} else if (getLang().CPlusPlus && Tok.is(tok::annot_template_id)) {
|
||||
// We have a reference to a member template along with explicitly-
|
||||
// specified template arguments, e.g., t.f<int>.
|
||||
TemplateIdAnnotation *TemplateId
|
||||
= static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
|
||||
if (!LHS.isInvalid()) {
|
||||
ASTTemplateArgsPtr TemplateArgsPtr(Actions,
|
||||
TemplateId->getTemplateArgs(),
|
||||
TemplateId->getTemplateArgIsType(),
|
||||
TemplateId->NumArgs);
|
||||
|
||||
LHS = Actions.ActOnMemberTemplateIdReferenceExpr(CurScope, move(LHS),
|
||||
OpLoc, OpKind, SS,
|
||||
TemplateTy::make(TemplateId->Template),
|
||||
TemplateId->TemplateNameLoc,
|
||||
TemplateId->LAngleLoc,
|
||||
TemplateArgsPtr,
|
||||
TemplateId->getTemplateArgLocations(),
|
||||
TemplateId->RAngleLoc);
|
||||
}
|
||||
ConsumeToken();
|
||||
} else {
|
||||
if (getLang().CPlusPlus)
|
||||
Actions.ActOnCXXExitMemberScope(CurScope, MemberSS);
|
||||
|
|
|
@ -1598,6 +1598,7 @@ public:
|
|||
DeclarationName MemberName,
|
||||
DeclPtrTy ImplDecl,
|
||||
const CXXScopeSpec *SS = 0);
|
||||
|
||||
virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base,
|
||||
SourceLocation OpLoc,
|
||||
tok::TokenKind OpKind,
|
||||
|
@ -1972,6 +1973,19 @@ public:
|
|||
TypeTy *Ty,
|
||||
const CXXScopeSpec *SS = 0);
|
||||
|
||||
virtual OwningExprResult
|
||||
ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
|
||||
SourceLocation OpLoc,
|
||||
tok::TokenKind OpKind,
|
||||
const CXXScopeSpec &SS,
|
||||
// FIXME: "template" keyword?
|
||||
TemplateTy Template,
|
||||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgs,
|
||||
SourceLocation *TemplateArgLocs,
|
||||
SourceLocation RAngleLoc);
|
||||
|
||||
/// MaybeCreateCXXExprWithTemporaries - If the list of temporaries is
|
||||
/// non-empty, will create a new CXXExprWithTemporaries expression.
|
||||
/// Otherwise, just returs the passed in expression.
|
||||
|
|
|
@ -2005,7 +2005,7 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
|
|||
ImpCastExprToType(BaseExpr, BaseType);
|
||||
}
|
||||
} else if (BaseType->isObjCClassType() &&
|
||||
BaseType != Context.ObjCClassRedefinitionType) {
|
||||
BaseType != Context.ObjCClassRedefinitionType) {
|
||||
BaseType = Context.ObjCClassRedefinitionType;
|
||||
ImpCastExprToType(BaseExpr, BaseType);
|
||||
}
|
||||
|
|
|
@ -1831,6 +1831,21 @@ Sema::ActOnConversionOperatorReferenceExpr(Scope *S, ExprArg Base,
|
|||
ConvName, DeclPtrTy(), SS);
|
||||
}
|
||||
|
||||
Sema::OwningExprResult
|
||||
Sema::ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
|
||||
SourceLocation OpLoc,
|
||||
tok::TokenKind OpKind,
|
||||
const CXXScopeSpec &SS,
|
||||
TemplateTy Template,
|
||||
SourceLocation TemplateNameLoc,
|
||||
SourceLocation LAngleLoc,
|
||||
ASTTemplateArgsPtr TemplateArgs,
|
||||
SourceLocation *TemplateArgLocs,
|
||||
SourceLocation RAngleLoc) {
|
||||
// FIXME: Implement!
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) {
|
||||
Expr *FullExpr = Arg.takeAs<Expr>();
|
||||
if (FullExpr)
|
||||
|
|
|
@ -40,5 +40,11 @@ void test_X_f1_address() {
|
|||
int& (X::*pm3)(float, int) = &X::f1;
|
||||
}
|
||||
|
||||
void test_X_f0_explicit(X x, int i, long l) {
|
||||
int &ir1 = x.f0<int>(i);
|
||||
int &ir2 = x.f0<>(i);
|
||||
int &ir3 = x.f0<long>(i);
|
||||
}
|
||||
|
||||
// PR4608
|
||||
class A { template <class x> x a(x z) { return z+y; } int y; };
|
||||
|
|
Loading…
Reference in New Issue