From 4d254836f4a6a03fb3c77d0636c3cb5475540eb0 Mon Sep 17 00:00:00 2001 From: Charles Davis Date: Sat, 3 Jul 2010 16:56:59 +0000 Subject: [PATCH] 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 --- lib/CodeGen/MicrosoftCXXABI.cpp | 35 +++++++++++++++++++++------------ test/CodeGenCXX/mangle-ms.cpp | 10 +++++++--- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index b459ae2110..da0fdb616d 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -599,6 +599,7 @@ void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals, // ::= _B # based function (far?) (pointers only) // ::= _C # based method (pointers only) // ::= _D # based method (far?) (pointers only) + // ::= _E # block (Clang) // ::= 0 # __based(void) // ::= 1 # __based(segment)? // ::= 2 # __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. - // ::= P # pointer - // ::= Q # const pointer - // ::= R # volatile pointer - // ::= S # const volatile pointer - if (T->isAnyPointerType() || T->isMemberPointerType()) { - if (!Quals.hasVolatile()) { + // ::= 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()); } // ::= @@ -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) { diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp index b011168bbb..61f8a595fc 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 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" + -- 2.40.0