forked from OSchip/llvm-project
Fix the mangling of function pointers in the MS ABI.
Patch by Timur Iskhodzhanov! llvm-svn: 162638
This commit is contained in:
parent
0a0aa84da3
commit
3351dc397b
|
@ -1059,6 +1059,8 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T,
|
|||
SourceRange) {
|
||||
// Structors only appear in decls, so at this point we know it's not a
|
||||
// structor type.
|
||||
// FIXME: This may not be lambda-friendly.
|
||||
Out << "$$A6";
|
||||
mangleType(T, NULL, false, false);
|
||||
}
|
||||
void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,
|
||||
|
@ -1214,7 +1216,7 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T,
|
|||
if (CC == CC_Default) {
|
||||
if (IsInstMethod) {
|
||||
const FunctionProtoType *FPT =
|
||||
T->getCanonicalTypeUnqualified().getAs<FunctionProtoType>();
|
||||
T->getCanonicalTypeUnqualified().castAs<FunctionProtoType>();
|
||||
bool isVariadic = FPT->isVariadic();
|
||||
CC = getASTContext().getDefaultCXXMethodCallConv(isVariadic);
|
||||
} else {
|
||||
|
@ -1497,7 +1499,9 @@ void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T,
|
|||
void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T,
|
||||
SourceRange Range) {
|
||||
Out << "_E";
|
||||
mangleType(T->getPointeeType(), Range);
|
||||
|
||||
QualType pointee = T->getPointeeType();
|
||||
mangleType(pointee->castAs<FunctionProtoType>(), NULL, false, false);
|
||||
}
|
||||
|
||||
void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *T,
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
|
||||
|
||||
template<typename Signature>
|
||||
class C;
|
||||
|
||||
template<typename Ret>
|
||||
class C<Ret(void)> {};
|
||||
typedef C<void(void)> C0;
|
||||
|
||||
template<typename Ret, typename Arg1>
|
||||
class C<Ret(Arg1)> {};
|
||||
|
||||
template<typename Ret, typename Arg1, typename Arg2>
|
||||
class C<Ret(Arg1, Arg2)> {};
|
||||
|
||||
C0 callback_void;
|
||||
// CHECK: "\01?callback_void@@3V?$C@$$A6AXXZ@@A"
|
||||
|
||||
volatile C0 callback_void_volatile;
|
||||
// CHECK: "\01?callback_void_volatile@@3V?$C@$$A6AXXZ@@C"
|
||||
|
||||
class Type {};
|
||||
|
||||
C<int(void)> callback_int;
|
||||
// CHECK: "\01?callback_int@@3V?$C@$$A6AHXZ@@A"
|
||||
C<Type(void)> callback_Type;
|
||||
// CHECK: "\01?callback_Type@@3V?$C@$$A6A?AVType@@XZ@@A"
|
||||
|
||||
C<void(int)> callback_void_int;
|
||||
// CHECK: "\01?callback_void_int@@3V?$C@$$A6AXH@Z@@A"
|
||||
C<int(int)> callback_int_int;
|
||||
// CHECK: "\01?callback_int_int@@3V?$C@$$A6AHH@Z@@A"
|
||||
C<void(Type)> callback_void_Type;
|
||||
// CHECK: "\01?callback_void_Type@@3V?$C@$$A6AXVType@@@Z@@A"
|
||||
|
||||
void foo(C0 c) {}
|
||||
// CHECK: "\01?foo@@YAXV?$C@$$A6AXXZ@@@Z"
|
||||
|
||||
// Here be dragons!
|
||||
// Let's face the magic of template partial specialization...
|
||||
|
||||
void function(C<void(void)>) {}
|
||||
// CHECK: "\01?function@@YAXV?$C@$$A6AXXZ@@@Z"
|
||||
|
||||
template<typename Ret> class C<Ret(*)(void)> {};
|
||||
void function_pointer(C<void(*)(void)>) {}
|
||||
// CHECK: "\01?function_pointer@@YAXV?$C@P6AXXZ@@@Z"
|
||||
|
||||
// Block equivalent to the previous definitions.
|
||||
template<typename Ret> class C<Ret(^)(void)> {};
|
||||
void block(C<void(^)(void)>) {}
|
||||
// CHECK: "\01?block@@YAXV?$C@P_EAXXZ@@@Z"
|
||||
// FYI blocks are not present in MSVS, so we're free to choose the spec.
|
||||
|
||||
template<typename T> class C<void (T::*)(void)> {};
|
||||
class Z {
|
||||
public:
|
||||
void method() {}
|
||||
};
|
||||
void member_pointer(C<void (Z::*)(void)>) {}
|
||||
// CHECK: "\01?member_pointer@@YAXV?$C@P8Z@@AEXXZ@@@Z"
|
||||
|
||||
template<typename T> void bar(T) {}
|
||||
|
||||
void call_bar() {
|
||||
bar<int (*)(int)>(0);
|
||||
// CHECK: "\01??$bar@P6AHH@Z@@YAXP6AHH@Z@Z"
|
||||
|
||||
bar<int (^)(int)>(0);
|
||||
// CHECK: "\01??$bar@P_EAHH@Z@@YAXP_EAHH@Z@Z"
|
||||
// FYI blocks are not present in MSVS, so we're free to choose the spec.
|
||||
}
|
|
@ -128,6 +128,10 @@ void zeta(int (*)(int, int)) {}
|
|||
void eta(int (^)(int, int)) {}
|
||||
// CHECK: @"\01?eta@@YAXP_EAHHH@Z@Z"
|
||||
|
||||
typedef int theta_arg(int,int);
|
||||
void theta(theta_arg^ block) {}
|
||||
// CHECK: @"\01?theta@@YAXP_EAHHH@Z@Z"
|
||||
|
||||
void operator_new_delete() {
|
||||
char *ptr = new char;
|
||||
// CHECK: @"\01??2@YAPAXI@Z"
|
||||
|
|
Loading…
Reference in New Issue