зеркало из https://github.com/microsoft/clang-1.git
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). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83429 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
edee783ed3
Коммит
4657a99274
|
@ -3678,7 +3678,45 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
|
|||
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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче