forked from OSchip/llvm-project
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). llvm-svn: 107572
This commit is contained in:
parent
1180f8e90f
commit
3babfba597
|
@ -599,6 +599,7 @@ void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
|
|||
// ::= _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 @@ void MicrosoftCXXNameMangler::mangleType(QualType T) {
|
|||
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 @@ void MicrosoftCXXNameMangler::mangleType(QualType T) {
|
|||
// 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 PointerType *T) {
|
|||
}
|
||||
}
|
||||
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 DependentSizedExtVectorType *T) {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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 gamma(class foo, struct bar, union baz, enum quux) {}
|
|||
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"
|
||||
|
||||
|
|
Loading…
Reference in New Issue