]> granicus.if.org Git - clang/commitdiff
Implement C++ [over.match.funcs]p4 as it concerns partial ordering of
authorDouglas Gregor <dgregor@apple.com>
Fri, 12 Nov 2010 23:44:13 +0000 (23:44 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 12 Nov 2010 23:44:13 +0000 (23:44 +0000)
function templates. Fixes PR8130.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118944 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateDeduction.cpp
test/CXX/over/over.match/over.match.funcs/p4.cpp [new file with mode: 0644]

index e564298fee2c0a1ca1cafcf5e0189c515f5e5b48..221b122b741c9c97243aceae3ecfdb19faf5be87 100644 (file)
@@ -2125,7 +2125,31 @@ MarkUsedTemplateParameters(Sema &SemaRef, QualType T,
                            bool OnlyDeduced,
                            unsigned Level,
                            llvm::SmallVectorImpl<bool> &Deduced);
-  
+/// \brief If this is a non-static member function, 
+static void MaybeAddImplicitObjectParameterType(ASTContext &Context,
+                                                CXXMethodDecl *Method,
+                                 llvm::SmallVectorImpl<QualType> &ArgTypes) {
+  if (Method->isStatic())
+    return;
+
+  // C++ [over.match.funcs]p4:
+  //
+  //   For non-static member functions, the type of the implicit
+  //   object parameter is
+  //     — "lvalue reference to cv X" for functions declared without a
+  //       ref-qualifier or with the & ref-qualifier
+  //     - "rvalue reference to cv X" for functions declared with the
+  //       && ref-qualifier
+  //
+  // FIXME: We don't have ref-qualifiers yet, so we don't do that part.
+  QualType ArgTy = Context.getTypeDeclType(Method->getParent());
+  ArgTy = Context.getQualifiedType(ArgTy,
+                        Qualifiers::fromCVRMask(Method->getTypeQualifiers()));
+  ArgTy = Context.getLValueReferenceType(ArgTy);
+  ArgTypes.push_back(ArgTy);
+}
+
 /// \brief Determine whether the function template \p FT1 is at least as
 /// specialized as \p FT2.
 static bool isAtLeastAsSpecializedAs(Sema &S,
@@ -2152,12 +2176,24 @@ static bool isAtLeastAsSpecializedAs(Sema &S,
   case TPOC_Call: {
     //   - In the context of a function call, the function parameter types are
     //     used.
-    unsigned NumParams = std::min(Proto1->getNumArgs(), Proto2->getNumArgs());
+    llvm::SmallVector<QualType, 4> Args1;
+    if (CXXMethodDecl *Method1 = dyn_cast<CXXMethodDecl>(FD1))
+      MaybeAddImplicitObjectParameterType(S.Context, Method1, Args1);
+    Args1.insert(Args1.end(), 
+                 Proto1->arg_type_begin(), Proto1->arg_type_end());
+
+    llvm::SmallVector<QualType, 4> Args2;
+    if (CXXMethodDecl *Method2 = dyn_cast<CXXMethodDecl>(FD2))
+      MaybeAddImplicitObjectParameterType(S.Context, Method2, Args2);
+    Args2.insert(Args2.end(), 
+                 Proto2->arg_type_begin(), Proto2->arg_type_end());
+
+    unsigned NumParams = std::min(Args1.size(), Args2.size());
     for (unsigned I = 0; I != NumParams; ++I)
       if (DeduceTemplateArgumentsDuringPartialOrdering(S,
                                                        TemplateParams,
-                                                       Proto2->getArgType(I),
-                                                       Proto1->getArgType(I),
+                                                       Args2[I],
+                                                       Args1[I],
                                                        Info,
                                                        Deduced,
                                                        QualifierComparisons))
diff --git a/test/CXX/over/over.match/over.match.funcs/p4.cpp b/test/CXX/over/over.match/over.match.funcs/p4.cpp
new file mode 100644 (file)
index 0000000..e06b863
--- /dev/null
@@ -0,0 +1,16 @@
+// 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
+  }
+}