[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