diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-03-10 17:45:58 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-03-10 17:45:58 +0000 |
commit | 27c39af73c0d7d0b97e57b3a905040d4cefc9708 (patch) | |
tree | 56c1dd85a159948815817b5a90bedb39cf9ad105 /lib/Sema/SemaCXXCast.cpp | |
parent | d2e6cf1d1c6468396ec057119c32aa58b1ee5ac9 (diff) | |
download | FreeBSD-src-27c39af73c0d7d0b97e57b3a905040d4cefc9708.zip FreeBSD-src-27c39af73c0d7d0b97e57b3a905040d4cefc9708.tar.gz |
Update clang to r98164.
Diffstat (limited to 'lib/Sema/SemaCXXCast.cpp')
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index 0097cd3..e04abd2 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -84,7 +84,8 @@ static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, QualType OrigSrcType, QualType OrigDestType, unsigned &msg, CastExpr::CastKind &Kind); -static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, +static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, + QualType SrcType, QualType DestType,bool CStyle, const SourceRange &OpRange, unsigned &msg, @@ -554,7 +555,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr, // Reverse member pointer conversion. C++ 4.11 specifies member pointer // conversion. C++ 5.2.9p9 has additional information. // DR54's access restrictions apply here also. - tcr = TryStaticMemberPointerUpcast(Self, SrcType, DestType, CStyle, + tcr = TryStaticMemberPointerUpcast(Self, SrcExpr, SrcType, DestType, CStyle, OpRange, msg, Kind); if (tcr != TC_NotApplicable) return tcr; @@ -798,12 +799,23 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, /// where B is a base class of D [...]. /// TryCastResult -TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, QualType DestType, - bool CStyle, const SourceRange &OpRange, +TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType, + QualType DestType, bool CStyle, + const SourceRange &OpRange, unsigned &msg, CastExpr::CastKind &Kind) { const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>(); if (!DestMemPtr) return TC_NotApplicable; + + bool WasOverloadedFunction = false; + if (FunctionDecl *Fn + = Self.ResolveAddressOfOverloadedFunction(SrcExpr, DestType, false)) { + CXXMethodDecl *M = cast<CXXMethodDecl>(Fn); + SrcType = Self.Context.getMemberPointerType(Fn->getType(), + Self.Context.getTypeDeclType(M->getParent()).getTypePtr()); + WasOverloadedFunction = true; + } + const MemberPointerType *SrcMemPtr = SrcType->getAs<MemberPointerType>(); if (!SrcMemPtr) { msg = diag::err_bad_static_cast_member_pointer_nonmp; @@ -853,6 +865,24 @@ TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, QualType DestType, return TC_Failed; } + if (WasOverloadedFunction) { + // Resolve the address of the overloaded function again, this time + // allowing complaints if something goes wrong. + FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr, + DestType, + true); + if (!Fn) { + msg = 0; + return TC_Failed; + } + + SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr, Fn); + if (!SrcExpr) { + msg = 0; + return TC_Failed; + } + } + Kind = CastExpr::CK_DerivedToBaseMemberPointer; return TC_Success; } |