[cfe-commits] r80624 - in /cfe/trunk: include/clang/Parse/Action.h lib/Parse/ParseExpr.cpp lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp test/SemaTemplate/member-function-template.cpp
Douglas Gregor
dgregor at apple.com
Mon Aug 31 14:16:33 PDT 2009
Author: dgregor
Date: Mon Aug 31 16:16:32 2009
New Revision: 80624
URL: http://llvm.org/viewvc/llvm-project?rev=80624&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/SemaTemplate/member-function-template.cpp
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=80624&r1=80623&r2=80624&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Mon Aug 31 16:16:32 2009
@@ -1321,6 +1321,53 @@
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) {
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=80624&r1=80623&r2=80624&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Mon Aug 31 16:16:32 2009
@@ -941,7 +941,7 @@
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 @@
&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 @@
// 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);
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=80624&r1=80623&r2=80624&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Aug 31 16:16:32 2009
@@ -1598,6 +1598,7 @@
DeclarationName MemberName,
DeclPtrTy ImplDecl,
const CXXScopeSpec *SS = 0);
+
virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
@@ -1972,6 +1973,19 @@
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.
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=80624&r1=80623&r2=80624&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Aug 31 16:16:32 2009
@@ -2005,7 +2005,7 @@
ImpCastExprToType(BaseExpr, BaseType);
}
} else if (BaseType->isObjCClassType() &&
- BaseType != Context.ObjCClassRedefinitionType) {
+ BaseType != Context.ObjCClassRedefinitionType) {
BaseType = Context.ObjCClassRedefinitionType;
ImpCastExprToType(BaseExpr, BaseType);
}
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=80624&r1=80623&r2=80624&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Aug 31 16:16:32 2009
@@ -1831,6 +1831,21 @@
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)
Modified: cfe/trunk/test/SemaTemplate/member-function-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/member-function-template.cpp?rev=80624&r1=80623&r2=80624&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/member-function-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/member-function-template.cpp Mon Aug 31 16:16:32 2009
@@ -40,5 +40,11 @@
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; };
More information about the cfe-commits
mailing list