diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-09-01 16:29:03 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-09-01 16:29:03 +0000 |
commit | afac01d7e76f28d5e5a5c377369cc400919387ee (patch) | |
tree | b42d2d01232aae9e98bfd6953e0441e88b52176b | |
parent | 6a081405e3c8cd41ac68db9e961fe7016900ccd8 (diff) |
Transfer calling-convention attributes down to member function pointers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112715 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/ASTContext.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 12 | ||||
-rw-r--r-- | test/SemaCXX/MicrosoftExtensions.cpp | 13 |
3 files changed, 32 insertions, 2 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 574ada3980..4591a0f3c5 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1124,6 +1124,15 @@ static QualType getExtFunctionType(ASTContext& Context, QualType T, return T; ResultType = Context.getBlockPointerType(ResultType); + } else if (const MemberPointerType *MemberPointer + = T->getAs<MemberPointerType>()) { + QualType Pointee = MemberPointer->getPointeeType(); + ResultType = getExtFunctionType(Context, Pointee, Info); + if (ResultType == Pointee) + return T; + + ResultType = Context.getMemberPointerType(ResultType, + MemberPointer->getClass()); } else if (const FunctionType *F = T->getAs<FunctionType>()) { if (F->getExtInfo() == Info) return T; diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 8988de8355..bb2fb99033 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1846,7 +1846,8 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) { // Delay if this is not a function or pointer to block. if (!Type->isFunctionPointerType() && !Type->isBlockPointerType() - && !Type->isFunctionType()) + && !Type->isFunctionType() + && !Type->isMemberFunctionPointerType()) return true; if (!GetResultType(Type)->isVoidType()) { @@ -1868,7 +1869,8 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) { // Delay if this is not a function or pointer to block. if (!Type->isFunctionPointerType() && !Type->isBlockPointerType() - && !Type->isFunctionType()) + && !Type->isFunctionType() + && !Type->isMemberFunctionPointerType()) return true; // Otherwise we can process right away. @@ -1894,6 +1896,12 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) { QualType T = Type; if (const PointerType *PT = Type->getAs<PointerType>()) T = PT->getPointeeType(); + else if (const BlockPointerType *BPT = Type->getAs<BlockPointerType>()) + T = BPT->getPointeeType(); + else if (const MemberPointerType *MPT = Type->getAs<MemberPointerType>()) + T = MPT->getPointeeType(); + else if (const ReferenceType *RT = Type->getAs<ReferenceType>()) + T = RT->getPointeeType(); const FunctionType *Fn = T->getAs<FunctionType>(); // Delay if the type didn't work out to a function. diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp index 48d4194197..fb3107f44e 100644 --- a/test/SemaCXX/MicrosoftExtensions.cpp +++ b/test/SemaCXX/MicrosoftExtensions.cpp @@ -29,3 +29,16 @@ struct Derived : Base { virtual void f2() throw(...); virtual void f3(); }; + +// __stdcall handling +struct M { + int __stdcall addP(); + float __stdcall subtractP(); +}; + +template<typename T> void h1(T (__stdcall M::* const )()) { } + +void m1() { + h1<int>(&M::addP); + h1(&M::subtractP); +} |