[cfe-commits] r119145 - in /cfe/trunk: lib/Sema/SemaTemplateDeduction.cpp test/CXX/over/over.match/over.match.funcs/p4.cpp test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp

Douglas Gregor dgregor at apple.com
Mon Nov 15 07:41:17 PST 2010


Author: dgregor
Date: Mon Nov 15 09:41:16 2010
New Revision: 119145

URL: http://llvm.org/viewvc/llvm-project?rev=119145&view=rev
Log:
Implement C++0x [temp.func.order]p3 (aka DR532) properly. In
particular, we only add the implement object parameter type if only
one of the function templates is a non-static member function
template.

Moreover, since this DR differs from existing practice in C++98/03,
this commit implements the existing practice (which ignores the
first parameter of the function template that is not the non-static
member function template) in C++98/03 mode.

Added:
    cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp   (with props)
    cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp   (with props)
Removed:
    cfe/trunk/test/CXX/over/over.match/over.match.funcs/p4.cpp
Modified:
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=119145&r1=119144&r2=119145&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Mon Nov 15 09:41:16 2010
@@ -2172,21 +2172,46 @@
   //   The types used to determine the ordering depend on the context in which
   //   the partial ordering is done:
   TemplateDeductionInfo Info(S.Context, Loc);
+  CXXMethodDecl *Method1 = 0;
+  CXXMethodDecl *Method2 = 0;
+  bool IsNonStatic2 = false;
+  bool IsNonStatic1 = false;
+  unsigned Skip2 = 0;
   switch (TPOC) {
   case TPOC_Call: {
     //   - In the context of a function call, the function parameter types are
     //     used.
+    Method1 = dyn_cast<CXXMethodDecl>(FD1);
+    Method2 = dyn_cast<CXXMethodDecl>(FD2);
+    IsNonStatic1 = Method1 && !Method1->isStatic();
+    IsNonStatic2 = Method2 && !Method2->isStatic();
+
+    // C++0x [temp.func.order]p3:
+    //   [...] If only one of the function templates is a non-static
+    //   member, that function template is considered to have a new
+    //   first parameter inserted in its function parameter list. The
+    //   new parameter is of type "reference to cv A," where cv are
+    //   the cv-qualifiers of the function template (if any) and A is
+    //   the class of which the function template is a member.
+    //
+    // C++98/03 doesn't have this provision, so instead we drop the
+    // first argument of the free function or static member, which
+    // seems to match existing practice.
     llvm::SmallVector<QualType, 4> Args1;
-    if (CXXMethodDecl *Method1 = dyn_cast<CXXMethodDecl>(FD1))
+    unsigned Skip1 = !S.getLangOptions().CPlusPlus0x && 
+      IsNonStatic2 && !IsNonStatic1;
+    if (S.getLangOptions().CPlusPlus0x && IsNonStatic1 && !IsNonStatic2)
       MaybeAddImplicitObjectParameterType(S.Context, Method1, Args1);
     Args1.insert(Args1.end(), 
-                 Proto1->arg_type_begin(), Proto1->arg_type_end());
+                 Proto1->arg_type_begin() + Skip1, Proto1->arg_type_end());
 
     llvm::SmallVector<QualType, 4> Args2;
-    if (CXXMethodDecl *Method2 = dyn_cast<CXXMethodDecl>(FD2))
+    Skip2 = !S.getLangOptions().CPlusPlus0x && 
+      IsNonStatic1 && !IsNonStatic2;
+    if (S.getLangOptions().CPlusPlus0x && IsNonStatic2 && !IsNonStatic1)
       MaybeAddImplicitObjectParameterType(S.Context, Method2, Args2);
     Args2.insert(Args2.end(), 
-                 Proto2->arg_type_begin(), Proto2->arg_type_end());
+                 Proto2->arg_type_begin() + Skip2, Proto2->arg_type_end());
 
     unsigned NumParams = std::min(Args1.size(), Args2.size());
     for (unsigned I = 0; I != NumParams; ++I)
@@ -2252,7 +2277,10 @@
   switch (TPOC) {
   case TPOC_Call: {
     unsigned NumParams = std::min(Proto1->getNumArgs(), Proto2->getNumArgs());
-    for (unsigned I = 0; I != NumParams; ++I)
+    if (S.getLangOptions().CPlusPlus0x && IsNonStatic2 && !IsNonStatic1)
+      ::MarkUsedTemplateParameters(S, Method2->getThisType(S.Context), false, 
+                                   TemplateParams->getDepth(), UsedParameters);
+    for (unsigned I = Skip2; I < NumParams; ++I)
       ::MarkUsedTemplateParameters(S, Proto2->getArgType(I), false, 
                                    TemplateParams->getDepth(),
                                    UsedParameters);

Removed: cfe/trunk/test/CXX/over/over.match/over.match.funcs/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/over/over.match/over.match.funcs/p4.cpp?rev=119144&view=auto
==============================================================================
--- cfe/trunk/test/CXX/over/over.match/over.match.funcs/p4.cpp (original)
+++ cfe/trunk/test/CXX/over/over.match/over.match.funcs/p4.cpp (removed)
@@ -1,16 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-namespace PR8130 {
-  struct A { };
-
-  template<class T> struct B {
-    template<class R> int &operator*(R&); // #1
-  };
-
-  template<class T, class R> float &operator*(T&, R&); // #2
-  void test() {
-    A a;
-    B<A> b;
-    int &ir = b * a; // calls #1a
-  }
-}

Added: cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp?rev=119145&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp Mon Nov 15 09:41:16 2010
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+// Core DR 532.
+namespace PR8130 {
+  struct A { };
+
+  template<class T> struct B {
+    template<class R> int &operator*(R&);
+  };
+
+  template<class T, class R> float &operator*(T&, R&);
+  void test() {
+    A a;
+    B<A> b;
+    int &ir = b * a;
+  }
+}

Propchange: cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp?rev=119145&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp Mon Nov 15 09:41:16 2010
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace DeduceVsMember {
+  template<typename T>
+  struct X {
+    template<typename U>
+    int &operator==(const U& other) const;
+  };
+
+  template<typename T, typename U>
+  float &operator==(const T&, const X<U>&);
+
+  void test(X<int> xi, X<float> xf) {
+    float& ir = (xi == xf);
+  }
+}

Propchange: cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list