]> granicus.if.org Git - clang/commitdiff
Transfer calling-convention attributes down to member function pointers.
authorDouglas Gregor <dgregor@apple.com>
Wed, 1 Sep 2010 16:29:03 +0000 (16:29 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 1 Sep 2010 16:29:03 +0000 (16:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112715 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ASTContext.cpp
lib/Sema/SemaType.cpp
test/SemaCXX/MicrosoftExtensions.cpp

index 574ada39807bd72f838185d553c90e9f5002f06c..4591a0f3c55c6837632537a83f082ad2f656f1d9 100644 (file)
@@ -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;
index 8988de835556306368b6e3d801ea54c9b5ca7146..bb2fb99033040a9cc2a4e343a5792aa4cdbb20e7 100644 (file)
@@ -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.
index 48d41941970e4cccc5a70d07eb17063d7754e986..fb3107f44e979ea40b85c24a2a9de9fae68a33ed 100644 (file)
@@ -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);
+}