smeenai created this revision. smeenai added reviewers: compnerd, DHowett-MSFT, rjmccall, rnk, theraven. Herald added a subscriber: erik.pilkington.
Obj-C classes are mangled as C++ structs with the same name (in both the Itanium and the Microsoft ABIs), but we want to be able to distinguish them for the purposes of exception handling, so we need to add a discriminator to the RTTI and the RTTI name. The chosen discriminator (`.objc`) is fairly arbitrary, and I'm open to other suggestions. It's also perhaps not ideal to have the discriminator as a prefix, since then the RTTI won't demangle (RTTI names never demangle anyway, so that's less of a concern). Having it infix would make for a cleaner mangling, but it would also require keeping some state around in the mangler to indicate when we're mangling for RTTI, which seems like a much uglier implementation and not worth it. Repository: rC Clang https://reviews.llvm.org/D52674 Files: lib/AST/MicrosoftMangle.cpp test/CodeGenObjCXX/arc-marker-funclet.mm test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm test/CodeGenObjCXX/msabi-objc-exceptions-gnustep.mm test/CodeGenObjCXX/msabi-objc-extensions.mm test/CodeGenObjCXX/msabi-objc-types.mm
Index: test/CodeGenObjCXX/msabi-objc-types.mm =================================================================== --- test/CodeGenObjCXX/msabi-objc-types.mm +++ test/CodeGenObjCXX/msabi-objc-types.mm @@ -3,166 +3,166 @@ @class I; id kid; -// CHECK: @"?kid@@3PAU.objc_object@@A" = dso_local global +// CHECK: @"?kid@@3PAUobjc_object@@A" = dso_local global Class klass; -// CHECK: @"?klass@@3PAU.objc_class@@A" = dso_local global +// CHECK: @"?klass@@3PAUobjc_class@@A" = dso_local global I *kI; -// CHECK: @"?kI@@3PAU.objc_cls_I@@A" = dso_local global +// CHECK: @"?kI@@3PAUI@@A" = dso_local global void f(I *) {} -// CHECK-LABEL: "?f@@YAXPAU.objc_cls_I@@@Z" +// CHECK-LABEL: "?f@@YAXPAUI@@@Z" void f(const I *) {} -// CHECK-LABEL: "?f@@YAXPBU.objc_cls_I@@@Z" +// CHECK-LABEL: "?f@@YAXPBUI@@@Z" void f(I &) {} -// CHECK-LABEL: "?f@@YAXAAU.objc_cls_I@@@Z" +// CHECK-LABEL: "?f@@YAXAAUI@@@Z" void f(const I &) {} -// CHECK-LABEL: "?f@@YAXABU.objc_cls_I@@@Z" +// CHECK-LABEL: "?f@@YAXABUI@@@Z" void f(const I &&) {} -// CHECK-LABEL: "?f@@YAX$$QBU.objc_cls_I@@@Z" +// CHECK-LABEL: "?f@@YAX$$QBUI@@@Z" void g(id) {} -// CHECK-LABEL: "?g@@YAXPAU.objc_object@@@Z" +// CHECK-LABEL: "?g@@YAXPAUobjc_object@@@Z" void g(id &) {} -// CHECK-LABEL: "?g@@YAXAAPAU.objc_object@@@Z" +// CHECK-LABEL: "?g@@YAXAAPAUobjc_object@@@Z" void g(const id &) {} -// CHECK-LABEL: "?g@@YAXABQAU.objc_object@@@Z" +// CHECK-LABEL: "?g@@YAXABQAUobjc_object@@@Z" void g(id &&) {} -// CHECK-LABEL: "?g@@YAX$$QAPAU.objc_object@@@Z" +// CHECK-LABEL: "?g@@YAX$$QAPAUobjc_object@@@Z" void h(Class) {} -// CHECK-LABEL: "?h@@YAXPAU.objc_class@@@Z" +// CHECK-LABEL: "?h@@YAXPAUobjc_class@@@Z" void h(Class &) {} -// CHECK-LABEL: "?h@@YAXAAPAU.objc_class@@@Z" +// CHECK-LABEL: "?h@@YAXAAPAUobjc_class@@@Z" void h(const Class &) {} -// CHECK-LABEL: "?h@@YAXABQAU.objc_class@@@Z" +// CHECK-LABEL: "?h@@YAXABQAUobjc_class@@@Z" void h(Class &&) {} -// CHECK-LABEL: "?h@@YAX$$QAPAU.objc_class@@@Z" +// CHECK-LABEL: "?h@@YAX$$QAPAUobjc_class@@@Z" I *i() { return nullptr; } -// CHECK-LABEL: "?i@@YAPAU.objc_cls_I@@XZ" +// CHECK-LABEL: "?i@@YAPAUI@@XZ" const I *j() { return nullptr; } -// CHECK-LABEL: "?j@@YAPBU.objc_cls_I@@XZ" +// CHECK-LABEL: "?j@@YAPBUI@@XZ" I &k() { return *kI; } -// CHECK-LABEL: "?k@@YAAAU.objc_cls_I@@XZ" +// CHECK-LABEL: "?k@@YAAAUI@@XZ" const I &l() { return *kI; } -// CHECK-LABEL: "?l@@YAABU.objc_cls_I@@XZ" +// CHECK-LABEL: "?l@@YAABUI@@XZ" void m(const id) {} -// CHECK-LABEL: "?m@@YAXQAU.objc_object@@@Z" +// CHECK-LABEL: "?m@@YAXQAUobjc_object@@@Z" void m(const I *) {} -// CHECK-LABEL: "?m@@YAXPBU.objc_cls_I@@@Z" +// CHECK-LABEL: "?m@@YAXPBUI@@@Z" void n(SEL) {} -// CHECK-LABEL: "?n@@YAXPAU.objc_selector@@@Z" +// CHECK-LABEL: "?n@@YAXPAUobjc_selector@@@Z" void n(SEL *) {} -// CHECK-LABEL: "?n@@YAXPAPAU.objc_selector@@@Z" +// CHECK-LABEL: "?n@@YAXPAPAUobjc_selector@@@Z" void n(const SEL *) {} -// CHECK-LABEL: "?n@@YAXPBQAU.objc_selector@@@Z" +// CHECK-LABEL: "?n@@YAXPBQAUobjc_selector@@@Z" void n(SEL &) {} -// CHECK-LABEL: "?n@@YAXAAPAU.objc_selector@@@Z" +// CHECK-LABEL: "?n@@YAXAAPAUobjc_selector@@@Z" void n(const SEL &) {} -// CHECK-LABEL: "?n@@YAXABQAU.objc_selector@@@Z" +// CHECK-LABEL: "?n@@YAXABQAUobjc_selector@@@Z" void n(SEL &&) {} -// CHECK-LABEL: "?n@@YAX$$QAPAU.objc_selector@@@Z" +// CHECK-LABEL: "?n@@YAX$$QAPAUobjc_selector@@@Z" struct __declspec(dllexport) s { struct s &operator=(const struct s &) = delete; void m(I *) {} - // CHECK-LABEL: "?m@s@@QAAXPAU.objc_cls_I@@@Z" + // CHECK-LABEL: "?m@s@@QAAXPAUI@@@Z" void m(const I *) {} - // CHECK-LABEL: "?m@s@@QAAXPBU.objc_cls_I@@@Z" + // CHECK-LABEL: "?m@s@@QAAXPBUI@@@Z" void m(I &) {} - // CHECK-LABEL: "?m@s@@QAAXAAU.objc_cls_I@@@Z" + // CHECK-LABEL: "?m@s@@QAAXAAUI@@@Z" void m(const I &) {} - // CHECK-LABEL: "?m@s@@QAAXABU.objc_cls_I@@@Z" + // CHECK-LABEL: "?m@s@@QAAXABUI@@@Z" void m(I &&) {} - // CHECK-LABEL: "?m@s@@QAAX$$QAU.objc_cls_I@@@Z" + // CHECK-LABEL: "?m@s@@QAAX$$QAUI@@@Z" void m(const I &&) {} - // CHECK-LABEL: "?m@s@@QAAX$$QBU.objc_cls_I@@@Z" + // CHECK-LABEL: "?m@s@@QAAX$$QBUI@@@Z" void m(id) {} - // CHECK-LABEL: "?m@s@@QAAXPAU.objc_object@@@Z" + // CHECK-LABEL: "?m@s@@QAAXPAUobjc_object@@@Z" void m(id &) {} - // CHECK-LABEL: "?m@s@@QAAXAAPAU.objc_object@@@Z" + // CHECK-LABEL: "?m@s@@QAAXAAPAUobjc_object@@@Z" void m(id &&) {} - // CHECK-LABEL: "?m@s@@QAAX$$QAPAU.objc_object@@@Z" + // CHECK-LABEL: "?m@s@@QAAX$$QAPAUobjc_object@@@Z" void m(const id &) {} - // CHECK-LABEL: "?m@s@@QAAXABQAU.objc_object@@@Z" + // CHECK-LABEL: "?m@s@@QAAXABQAUobjc_object@@@Z" void m(const id &&) {} - // CHECK-LABEL: "?m@s@@QAAX$$QBQAU.objc_object@@@Z" + // CHECK-LABEL: "?m@s@@QAAX$$QBQAUobjc_object@@@Z" void m(Class *) {} - // CHECK-LABEL: "?m@s@@QAAXPAPAU.objc_class@@@Z" + // CHECK-LABEL: "?m@s@@QAAXPAPAUobjc_class@@@Z" void m(const Class *) {} - // CHECK-LABEL: "?m@s@@QAAXPBQAU.objc_class@@@Z" + // CHECK-LABEL: "?m@s@@QAAXPBQAUobjc_class@@@Z" void m(Class) {} - // CHECK-LABEL: "?m@s@@QAAXPAU.objc_class@@@Z" + // CHECK-LABEL: "?m@s@@QAAXPAUobjc_class@@@Z" void m(Class &) {} - // CHECK-LABEL: "?m@s@@QAAXAAPAU.objc_class@@@Z" + // CHECK-LABEL: "?m@s@@QAAXAAPAUobjc_class@@@Z" void m(const Class &) {} - // CHECK-LABEL: "?m@s@@QAAXABQAU.objc_class@@@Z" + // CHECK-LABEL: "?m@s@@QAAXABQAUobjc_class@@@Z" void m(Class &&) {} - // CHECK-LABEL: "?m@s@@QAAX$$QAPAU.objc_class@@@Z" + // CHECK-LABEL: "?m@s@@QAAX$$QAPAUobjc_class@@@Z" void m(const Class &&) {} - // CHECK-LABEL: "?m@s@@QAAX$$QBQAU.objc_class@@@Z" + // CHECK-LABEL: "?m@s@@QAAX$$QBQAUobjc_class@@@Z" void m(SEL) {} - // CHECK-LABEL: "?m@s@@QAAXPAU.objc_selector@@@Z" + // CHECK-LABEL: "?m@s@@QAAXPAUobjc_selector@@@Z" void m(SEL *) {} - // CHECK-LABEL: "?m@s@@QAAXPAPAU.objc_selector@@@Z" + // CHECK-LABEL: "?m@s@@QAAXPAPAUobjc_selector@@@Z" void m(const SEL *) {} - // CHECK-LABEL: "?m@s@@QAAXPBQAU.objc_selector@@@Z" + // CHECK-LABEL: "?m@s@@QAAXPBQAUobjc_selector@@@Z" void m(SEL &) {} - // CHECK-LABEL: "?m@s@@QAAXAAPAU.objc_selector@@@Z" + // CHECK-LABEL: "?m@s@@QAAXAAPAUobjc_selector@@@Z" void m(const SEL &) {} - // CHECK-LABEL: "?m@s@@QAAXABQAU.objc_selector@@@Z" + // CHECK-LABEL: "?m@s@@QAAXABQAUobjc_selector@@@Z" void m(SEL &&) {} - // CHECK-LABEL: "?m@s@@QAAX$$QAPAU.objc_selector@@@Z" + // CHECK-LABEL: "?m@s@@QAAX$$QAPAUobjc_selector@@@Z" void m(const SEL &&) {} - // CHECK-LABEL: "?m@s@@QAAX$$QBQAU.objc_selector@@@Z" + // CHECK-LABEL: "?m@s@@QAAX$$QBQAUobjc_selector@@@Z" }; template <typename T> @@ -179,14 +179,14 @@ }; template struct t<id>; -// CHECK-LABEL: "??0?$t@PAU.objc_object@@@@QAA@XZ" +// CHECK-LABEL: "??0?$t@PAUobjc_object@@@@QAA@XZ" template struct t<remove_pointer<id>::type>; -// CHECK-LABEL: "??0?$t@U.objc_object@@@@QAA@XZ" +// CHECK-LABEL: "??0?$t@Uobjc_object@@@@QAA@XZ" template struct t<SEL>; -// CHECK-LABEL: "??0?$t@PAU.objc_selector@@@@QAA@XZ" +// CHECK-LABEL: "??0?$t@PAUobjc_selector@@@@QAA@XZ" template struct t<remove_pointer<SEL>::type>; -// CHECK-LABEL: "??0?$t@U.objc_selector@@@@QAA@XZ" +// CHECK-LABEL: "??0?$t@Uobjc_selector@@@@QAA@XZ" Index: test/CodeGenObjCXX/msabi-objc-extensions.mm =================================================================== --- test/CodeGenObjCXX/msabi-objc-extensions.mm +++ test/CodeGenObjCXX/msabi-objc-extensions.mm @@ -7,92 +7,91 @@ @class J<T>; void f(id<P>, id, id<P>, id) {} -// CHECK-LABEL: "?f@@YAXPAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@@@PAU.objc_object@@01@Z" +// CHECK-LABEL: "?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@PAUobjc_object@@01@Z" void f(id, id<P>, id<P>, id) {} -// CHECK-LABEL: "?f@@YAXPAU.objc_object@@PAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@@@10@Z" +// CHECK-LABEL: "?f@@YAXPAUobjc_object@@PAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@10@Z" void f(id<P>, id<P>) {} -// CHECK-LABEL: "?f@@YAXPAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@@@0@Z" +// CHECK-LABEL: "?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@0@Z" void f(id<P>) {} -// CHECK-LABEL: "?f@@YAXPAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@@@@Z" +// CHECK-LABEL: "?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@@Z" void f(id<P, Q>) {} -// CHECK-LABEL: "?f@@YAXPAU?$.objc_object@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" +// CHECK-LABEL: "?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" void f(Class<P>) {} -// CHECK-LABEL: "?f@@YAXPAU?$.objc_class@U?$Protocol@UP@@@__ObjC@@@@@Z" +// CHECK-LABEL: "?f@@YAXPAU?$objc_class@U?$Protocol@UP@@@__ObjC@@@@@Z" void f(Class<P, Q>) {} -// CHECK-LABEL: "?f@@YAXPAU?$.objc_class@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" +// CHECK-LABEL: "?f@@YAXPAU?$objc_class@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" void f(I<P> *) {} -// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_I@U?$Protocol@UP@@@__ObjC@@@@@Z" +// CHECK-LABEL: "?f@@YAXPAU?$I@U?$Protocol@UP@@@__ObjC@@@@@Z" void f(I<P, Q> *) {} -// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_I@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" +// CHECK-LABEL: "?f@@YAXPAU?$I@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" template <typename> struct S {}; void f(S<__unsafe_unretained id>) {} -// CHECK-LABEL: "?f@@YAXU?$S@PAU.objc_object@@@@@Z" +// CHECK-LABEL: "?f@@YAXU?$S@PAUobjc_object@@@@@Z" void f(S<__autoreleasing id>) {} -// CHECK-LABEL: "?f@@YAXU?$S@U?$Autoreleasing@PAU.objc_object@@@__ObjC@@@@@Z" +// CHECK-LABEL: "?f@@YAXU?$S@U?$Autoreleasing@PAUobjc_object@@@__ObjC@@@@@Z" void f(S<__strong id>) {} -// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU.objc_object@@@__ObjC@@@@@Z" +// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAUobjc_object@@@__ObjC@@@@@Z" void f(S<__weak id>) {} -// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAU.objc_object@@@__ObjC@@@@@Z" +// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAUobjc_object@@@__ObjC@@@@@Z" void w(__weak id) {} -// CHECK-LABEL: "?w@@YAXPAU.objc_object@@@Z" +// CHECK-LABEL: "?w@@YAXPAUobjc_object@@@Z" void s(__strong id) {} -// CHECK-LABEL: "?s@@YAXPAU.objc_object@@@Z" +// CHECK-LABEL: "?s@@YAXPAUobjc_object@@@Z" void a(__autoreleasing id) {} -// CHECK-LABEL: "?a@@YAXPAU.objc_object@@@Z" +// CHECK-LABEL: "?a@@YAXPAUobjc_object@@@Z" void u(__unsafe_unretained id) {} -// CHECK-LABEL: "?u@@YAXPAU.objc_object@@@Z" +// CHECK-LABEL: "?u@@YAXPAUobjc_object@@@Z" S<__autoreleasing id> g() { return S<__autoreleasing id>(); } -// CHECK-LABEL: "?g@@YA?AU?$S@U?$Autoreleasing@PAU.objc_object@@@__ObjC@@@@XZ" +// CHECK-LABEL: "?g@@YA?AU?$S@U?$Autoreleasing@PAUobjc_object@@@__ObjC@@@@XZ" __autoreleasing id h() { return nullptr; } -// CHECK-LABEL: "?h@@YAPAU.objc_object@@XZ" +// CHECK-LABEL: "?h@@YAPAUobjc_object@@XZ" void f(I *) {} -// CHECK-LABEL: "?f@@YAXPAU.objc_cls_I@@@Z" +// CHECK-LABEL: "?f@@YAXPAUI@@@Z" void f(__kindof I *) {} -// CHECK-LABEL: "?f@@YAXPAU?$KindOf@U.objc_cls_I@@@__ObjC@@@Z" +// CHECK-LABEL: "?f@@YAXPAU?$KindOf@UI@@@__ObjC@@@Z" void f(__kindof I<P> *) {} -// CHECK-LABEL: "?f@@YAXPAU?$KindOf@U?$.objc_cls_I@U?$Protocol@UP@@@__ObjC@@@@@__ObjC@@@Z" +// CHECK-LABEL: "?f@@YAXPAU?$KindOf@U?$I@U?$Protocol@UP@@@__ObjC@@@@@__ObjC@@@Z" void f(S<I *>) {} -// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU.objc_cls_I@@@__ObjC@@@@@Z" +// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAUI@@@__ObjC@@@@@Z" void f(S<__kindof I *>) {} -// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU?$KindOf@U.objc_cls_I@@@__ObjC@@@__ObjC@@@@@Z" +// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU?$KindOf@UI@@@__ObjC@@@__ObjC@@@@@Z" void f(S<__kindof I<P> *>) {} -// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU?$KindOf@U?$.objc_cls_I@U?$Protocol@UP@@@__ObjC@@@@@__ObjC@@@__ObjC@@@@@Z" +// CHECK-LABEL: "?f@@YAXU?$S@U?$Strong@PAU?$KindOf@U?$I@U?$Protocol@UP@@@__ObjC@@@@@__ObjC@@@__ObjC@@@@@Z" void f(S<__weak __kindof I *>) {} -// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAU?$KindOf@U.objc_cls_I@@@__ObjC@@@__ObjC@@@@@Z" +// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAU?$KindOf@UI@@@__ObjC@@@__ObjC@@@@@Z" void f(S<__weak __kindof I<P> *>) {} -// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAU?$KindOf@U?$.objc_cls_I@U?$Protocol@UP@@@__ObjC@@@@@__ObjC@@@__ObjC@@@@@Z" +// CHECK-LABEL: "?f@@YAXU?$S@U?$Weak@PAU?$KindOf@U?$I@U?$Protocol@UP@@@__ObjC@@@@@__ObjC@@@__ObjC@@@@@Z" void f(J<I *> *) {} -// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_J@PAU.objc_cls_I@@@@@Z" +// CHECK-LABEL: "?f@@YAXPAU?$J@PAUI@@@@@Z" void f(J<__kindof I *> *) {} -// CHECK-LABEL: "?f@@YAXPAU?$.objc_cls_J@PAU?$KindOf@U.objc_cls_I@@@__ObjC@@@@@Z" - +// CHECK-LABEL: "?f@@YAXPAU?$J@PAU?$KindOf@UI@@@__ObjC@@@@@Z" Index: test/CodeGenObjCXX/msabi-objc-exceptions-gnustep.mm =================================================================== --- /dev/null +++ test/CodeGenObjCXX/msabi-objc-exceptions-gnustep.mm @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple i686-windows-msvc -fobjc-runtime=gnustep-2.0 -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefix=X86 %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -fobjc-runtime=gnustep-2.0 -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck -check-prefix=X64 %s + +// Ensure we have the .objc discriminator in the RTTI and the RTTI name. +// X86-DAG: @"??_R0objc.PAUobjc_object@@@8" = linkonce_odr global %{{[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [23 x i8] c".objc.PAUobjc_object@@\00" }, comdat +// X64-DAG: @"??_R0objc.PEAUobjc_object@@@8" = linkonce_odr global %{{[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [24 x i8] c".objc.PEAUobjc_object@@\00" }, comdat + +@class I; +// X86-DAG: @"??_R0objc.PAUI@@@8" = linkonce_odr global %{{[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [13 x i8] c".objc.PAUI@@\00" }, comdat +// X64-DAG: @"??_R0objc.PEAUI@@@8" = linkonce_odr global %{{[^ ]+}} { i8** @"??_7type_info@@6B@", i8* null, [14 x i8] c".objc.PEAUI@@\00" }, comdat + +void f(); +void g() { + @try { + f(); + } @catch (I *) { + } @catch (id) { + } +} Index: test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm =================================================================== --- test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm +++ test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm @@ -9,7 +9,7 @@ // Verify that we destruct things from left to right in the MS C++ ABI: a, b, c, d. // -// CHECK-LABEL: define dso_local void @"?test_arc_order@@YAXUA@@PAU.objc_object@@01@Z" +// CHECK-LABEL: define dso_local void @"?test_arc_order@@YAXUA@@PAUobjc_object@@01@Z" // CHECK: (<{ %struct.A, i8*, %struct.A, i8* }>* inalloca) void test_arc_order(A a, id __attribute__((ns_consumed)) b , A c, id __attribute__((ns_consumed)) d) { // CHECK: call x86_thiscallcc void @"??1A@@QAE@XZ"(%struct.A* %{{.*}}) Index: test/CodeGenObjCXX/arc-marker-funclet.mm =================================================================== --- test/CodeGenObjCXX/arc-marker-funclet.mm +++ test/CodeGenObjCXX/arc-marker-funclet.mm @@ -10,7 +10,7 @@ } } -// CHECK: call i8* @"?f@@YAPAU.objc_object@@XZ"() [ "funclet"(token %1) ] +// CHECK: call i8* @"?f@@YAPAUobjc_object@@XZ"() [ "funclet"(token %1) ] // CHECK-NEXT: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ] // The corresponding f() call was invoked from the entry basic block. Index: lib/AST/MicrosoftMangle.cpp =================================================================== --- lib/AST/MicrosoftMangle.cpp +++ lib/AST/MicrosoftMangle.cpp @@ -482,7 +482,7 @@ mangleFunctionEncoding(FD, Context.shouldMangleDeclName(FD)); else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) mangleVariableEncoding(VD); - else if (!isa<ObjCInterfaceDecl>(D)) + else llvm_unreachable("Tried to mangle unexpected NamedDecl!"); } @@ -1951,13 +1951,13 @@ llvm_unreachable("placeholder types shouldn't get to name mangling"); case BuiltinType::ObjCId: - mangleArtificalTagType(TTK_Struct, ".objc_object"); + mangleArtificalTagType(TTK_Struct, "objc_object"); break; case BuiltinType::ObjCClass: - mangleArtificalTagType(TTK_Struct, ".objc_class"); + mangleArtificalTagType(TTK_Struct, "objc_class"); break; case BuiltinType::ObjCSel: - mangleArtificalTagType(TTK_Struct, ".objc_selector"); + mangleArtificalTagType(TTK_Struct, "objc_selector"); break; #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ @@ -2637,10 +2637,9 @@ void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers, SourceRange) { - // ObjC interfaces are mangled as if they were structs with a name that is - // not a valid C/C++ identifier + // ObjC interfaces have structs underlying them. mangleTagTypeKind(TTK_Struct); - mangle(T->getDecl(), ".objc_cls_"); + mangleName(T->getDecl()); } void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T, @@ -2661,11 +2660,11 @@ Out << "?$"; if (T->isObjCId()) - mangleSourceName(".objc_object"); + mangleSourceName("objc_object"); else if (T->isObjCClass()) - mangleSourceName(".objc_class"); + mangleSourceName("objc_class"); else - mangleSourceName((".objc_cls_" + T->getInterface()->getName()).str()); + mangleSourceName(T->getInterface()->getName()); for (const auto &Q : T->quals()) mangleObjCProtocol(Q); @@ -3002,14 +3001,22 @@ msvc_hashing_ostream MHO(Out); MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "??_R0"; + // Obj-C classes are mangled as C++ structs with the same name, but we want to + // be able to distinguish a C++ struct X from an Obj-C class X for the + // purposes of exception handling, so we add a discriminator. + if (T->isObjCObjectPointerType()) + Mangler.getStream() << "objc."; Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result); Mangler.getStream() << "@8"; } void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T, raw_ostream &Out) { MicrosoftCXXNameMangler Mangler(*this, Out); Mangler.getStream() << '.'; + // See the comment in MicrosoftMangleContextImpl::mangleCXXRTTI. + if (T->isObjCObjectPointerType()) + Mangler.getStream() << "objc."; Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits