[cfe-commits] r83429 - in /cfe/trunk: lib/Sema/SemaOverload.cpp test/SemaCXX/builtin-ptrtomember-overload.cpp

Fariborz Jahanian fjahanian at apple.com
Tue Oct 6 16:08:14 PDT 2009


Author: fjahanian
Date: Tue Oct  6 18:08:05 2009
New Revision: 83429

URL: http://llvm.org/viewvc/llvm-project?rev=83429&view=rev
Log:
Patch to implement C++ [over.built]p11 of overload resolution.
Doug, please review. There is a FIXME in the test case with a question
which is unrelated to this patch (that is, error is issued
before set of builtins are added to the candidate list).


Added:
    cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload.cpp
Modified:
    cfe/trunk/lib/Sema/SemaOverload.cpp

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=83429&r1=83428&r2=83429&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Oct  6 18:08:05 2009
@@ -3678,7 +3678,45 @@
     break;
 
   case OO_ArrowStar:
-    // FIXME: No support for pointer-to-members yet.
+    // C++ [over.built]p11:
+    //    For every quintuple (C1, C2, T, CV1, CV2), where C2 is a class type, 
+    //    C1 is the same type as C2 or is a derived class of C2, T is an object 
+    //    type or a function type, and CV1 and CV2 are cv-qualifier-seqs, 
+    //    there exist candidate operator functions of the form 
+    //    CV12 T& operator->*(CV1 C1*, CV2 T C2::*); 
+    //    where CV12 is the union of CV1 and CV2.
+    {
+      for (BuiltinCandidateTypeSet::iterator Ptr = 
+             CandidateTypes.pointer_begin();
+           Ptr != CandidateTypes.pointer_end(); ++Ptr) {
+        QualType C1Ty = (*Ptr);
+        QualType C1;
+        if (const PointerType *PointerTy = C1Ty->getAs<PointerType>()) {
+          C1 = PointerTy->getPointeeType();
+          C1 = Context.getCanonicalType(C1).getUnqualifiedType();
+          if (!isa<RecordType>(C1))
+            continue;
+        }
+        for (BuiltinCandidateTypeSet::iterator
+             MemPtr = CandidateTypes.member_pointer_begin(),
+             MemPtrEnd = CandidateTypes.member_pointer_end();
+             MemPtr != MemPtrEnd; ++MemPtr) {
+          const MemberPointerType *mptr = cast<MemberPointerType>(*MemPtr);
+          QualType C2 = QualType(mptr->getClass(), 0);
+          C2 = Context.getCanonicalType(C2).getUnqualifiedType();
+          if (C1 != C2 && !IsDerivedFrom(C1, C2))
+            break;
+          QualType ParamTypes[2] = { *Ptr, *MemPtr };
+          // build CV12 T&
+          QualType T = mptr->getPointeeType();
+          unsigned CV1 = (*Ptr).getCVRQualifiers();
+          unsigned CV2 = T.getCVRQualifiers();
+          T = Context.getCVRQualifiedType(T, (CV1 | CV2));
+          QualType ResultTy = Context.getLValueReferenceType(T);
+          AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet);
+        }
+      }
+    }
     break;
 
   case OO_Conditional:

Added: cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload.cpp?rev=83429&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload.cpp (added)
+++ cfe/trunk/test/SemaCXX/builtin-ptrtomember-overload.cpp Tue Oct  6 18:08:05 2009
@@ -0,0 +1,19 @@
+// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x
+
+struct A {};
+
+struct B {
+	operator A*();
+};
+
+struct C : B {
+
+};
+
+
+void foo(C c, B b, int A::* pmf) {
+        // FIXME. Bug or correct? gcc accepts it. It requires derived-to-base followed by user defined conversion to work.
+	int j = c->*pmf; // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct C'}}
+	int i = b->*pmf;
+}
+





More information about the cfe-commits mailing list