Mangle Objective-C pointers and block pointers in the Microsoft C++ Mangler.
ObjC pointers were easy enough (as far as the ABI is concerned, they're
just pointers to structs), but I had to invent a new mangling for block
pointers. This is particularly worrying with the Microsoft ABI, because
it is a vendor-specific ABI; extending it could come back to bite us
later when MS extends it on their own (and you know they will).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107572 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
index b459ae2..da0fdb6 100644
--- a/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -599,6 +599,7 @@
// ::= _B <basis> # based function (far?) (pointers only)
// ::= _C <basis> # based method (pointers only)
// ::= _D <basis> # based method (far?) (pointers only)
+ // ::= _E # block (Clang)
// <basis> ::= 0 # __based(void)
// ::= 1 # __based(segment)?
// ::= 2 <name> # __based(name)
@@ -641,14 +642,15 @@
Qualifiers Quals = T.getLocalQualifiers();
if (Quals) {
// We have to mangle these now, while we still have enough information.
- // <pointer-cvr-qualifiers> ::= P # pointer
- // ::= Q # const pointer
- // ::= R # volatile pointer
- // ::= S # const volatile pointer
- if (T->isAnyPointerType() || T->isMemberPointerType()) {
- if (!Quals.hasVolatile()) {
+ // <pointer-cvr-qualifiers> ::= P # pointer
+ // ::= Q # const pointer
+ // ::= R # volatile pointer
+ // ::= S # const volatile pointer
+ if (T->isAnyPointerType() || T->isMemberPointerType() ||
+ T->isBlockPointerType()) {
+ if (!Quals.hasVolatile())
Out << 'Q';
- } else {
+ else {
if (!Quals.hasConst())
Out << 'R';
else
@@ -660,8 +662,8 @@
// type has no qualifiers, the lack of qualifier gets mangled
// in there.
mangleQualifiers(Quals, false);
- }
- else if (T->isAnyPointerType() || T->isMemberPointerType()) {
+ } else if (T->isAnyPointerType() || T->isMemberPointerType() ||
+ T->isBlockPointerType()) {
Out << 'P';
}
switch (T->getTypeClass()) {
@@ -1040,7 +1042,9 @@
}
}
void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T) {
- assert(false && "Don't know how to mangle ObjCObjectPointerTypes yet!");
+ // Object pointers never have qualifiers.
+ Out << 'A';
+ mangleType(T->getPointeeType());
}
// <type> ::= <reference-type>
@@ -1073,15 +1077,20 @@
}
void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T) {
- assert(false && "Don't know how to mangle ObjCInterfaceTypes yet!");
+ // ObjC interfaces have structs underlying them.
+ Out << 'U';
+ mangleName(T->getDecl());
}
void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T) {
- assert(false && "Don't know how to mangle ObjCObjectTypes yet!");
+ // We don't allow overloading by different protocol qualification,
+ // so mangling them isn't necessary.
+ mangleType(T->getBaseType());
}
void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T) {
- assert(false && "Don't know how to mangle BlockPointerTypes yet!");
+ Out << "_E";
+ mangleType(T->getPointeeType());
}
void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *T) {
diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp
index b011168..61f8a59 100644
--- a/test/CodeGenCXX/mangle-ms.cpp
+++ b/test/CodeGenCXX/mangle-ms.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fms-extensions -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-apple-darwin10 | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-apple-darwin10 | FileCheck %s
// CHECK: @"\01?a@@3HA"
// CHECK: @"\01?b@N@@3HA"
@@ -86,7 +86,11 @@
void delta(int * const a, const long &) {}
// CHECK: @"\01?delta@@YAXQAHABJ@Z"
-// Array mangling. (It should be mangled as a const pointer, but that needs
-// to be fixed in Sema.)
+// Array mangling.
void epsilon(int a[][10][20]) {}
// CHECK: @"\01?epsilon@@YAXQAY19BE@H@Z"
+
+// Blocks mangling (Clang extension).
+void zeta(int (^)(int, int)) {}
+// CHECK: @"\01?zeta@@YAXP_EAHHH@Z@Z"
+