[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