Author: compnerd Date: Thu Feb 8 19:23:54 2018 New Revision: 324701 URL: http://llvm.org/viewvc/llvm-project?rev=324701&view=rev Log: AST: support ObjC lifetime qualifiers in MS ABI
Adjust the ObjC protocol conformance workaround to be more extensible. Use a synthetic type for the protocol (`struct Protocol`). Embed this within a reserved namespace to permit extending the extended pointer type qualifiers similarly for ObjC lifetime qualifiers. Introduce additional special handling for `__autoreleasing`, `__strong`, and `__weak` Objective C lifetime qualifiers. We decorate these by creating an artificial template type `Autoreleasing`, `Strong`, or `Weak` in the `__ObjC` namespace. These are only considered in the template type specialization and not the function parameter. Added: cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm Removed: cfe/trunk/test/CodeGenObjCXX/msabi-protocol-conformance.mm Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=324701&r1=324700&r2=324701&view=diff ============================================================================== --- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original) +++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Thu Feb 8 19:23:54 2018 @@ -362,6 +362,10 @@ private: const TemplateArgumentList &TemplateArgs); void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA, const NamedDecl *Parm); + + void mangleObjCProtocol(const ObjCProtocolDecl *PD); + void mangleObjCLifetime(const QualType T, Qualifiers Quals, + SourceRange Range); }; } @@ -1456,6 +1460,47 @@ void MicrosoftCXXNameMangler::mangleTemp } } +void MicrosoftCXXNameMangler::mangleObjCProtocol(const ObjCProtocolDecl *PD) { + llvm::SmallString<64> TemplateMangling; + llvm::raw_svector_ostream Stream(TemplateMangling); + MicrosoftCXXNameMangler Extra(Context, Stream); + + Stream << "?$"; + Extra.mangleSourceName("Protocol"); + Extra.mangleArtificalTagType(TTK_Struct, PD->getName()); + + mangleArtificalTagType(TTK_Struct, TemplateMangling, {"__ObjC"}); +} + +void MicrosoftCXXNameMangler::mangleObjCLifetime(const QualType Type, + Qualifiers Quals, + SourceRange Range) { + llvm::SmallString<64> TemplateMangling; + llvm::raw_svector_ostream Stream(TemplateMangling); + MicrosoftCXXNameMangler Extra(Context, Stream); + + Stream << "?$"; + switch (Quals.getObjCLifetime()) { + case Qualifiers::OCL_None: + case Qualifiers::OCL_ExplicitNone: + break; + case Qualifiers::OCL_Autoreleasing: + Extra.mangleSourceName("Autoreleasing"); + break; + case Qualifiers::OCL_Strong: + Extra.mangleSourceName("Strong"); + break; + case Qualifiers::OCL_Weak: + Extra.mangleSourceName("Weak"); + break; + } + Extra.manglePointerCVQualifiers(Quals); + Extra.manglePointerExtQualifiers(Quals, Type); + Extra.mangleType(Type, Range); + + mangleArtificalTagType(TTK_Struct, TemplateMangling, {"__ObjC"}); +} + void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals, bool IsMember) { // <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers> @@ -1683,6 +1728,8 @@ void MicrosoftCXXNameMangler::mangleType switch (QMM) { case QMM_Drop: + if (Quals.hasObjCLifetime()) + Quals = Quals.withoutObjCLifetime(); break; case QMM_Mangle: if (const FunctionType *FT = dyn_cast<FunctionType>(T)) { @@ -1701,6 +1748,8 @@ void MicrosoftCXXNameMangler::mangleType case QMM_Result: // Presence of __unaligned qualifier shouldn't affect mangling here. Quals.removeUnaligned(); + if (Quals.hasObjCLifetime()) + Quals = Quals.withoutObjCLifetime(); if ((!IsPointer && Quals) || isa<TagType>(T)) { Out << '?'; mangleQualifiers(Quals, false); @@ -2334,6 +2383,15 @@ void MicrosoftCXXNameMangler::mangleType void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T, Qualifiers Quals, SourceRange Range) { QualType PointeeType = T->getPointeeType(); + switch (Quals.getObjCLifetime()) { + case Qualifiers::OCL_None: + case Qualifiers::OCL_ExplicitNone: + break; + case Qualifiers::OCL_Autoreleasing: + case Qualifiers::OCL_Strong: + case Qualifiers::OCL_Weak: + return mangleObjCLifetime(PointeeType, Quals, Range); + } manglePointerCVQualifiers(Quals); manglePointerExtQualifiers(Quals, PointeeType); mangleType(PointeeType, Range); @@ -2469,11 +2527,8 @@ void MicrosoftCXXNameMangler::mangleType else mangleSourceName(T->getInterface()->getName()); - for (const auto &Q : T->quals()) { - Out << 'Y'; // cointerface - mangleSourceName(Q->getName()); - Out << '@'; - } + for (const auto &Q : T->quals()) + mangleObjCProtocol(Q); Out << '@'; Out << '@'; Added: cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm?rev=324701&view=auto ============================================================================== --- cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm (added) +++ cfe/trunk/test/CodeGenObjCXX/msabi-objc-extensions.mm Thu Feb 8 19:23:54 2018 @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 -triple thumbv7-windows-msvc -fobjc-runtime=ios-6.0 -fobjc-arc -o - -emit-llvm %s | FileCheck %s + +@protocol P; +@protocol Q; + +@class I; + +void f(id<P>, id, id<P>, id) {} +// CHECK-LABEL: "\01?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@PAUobjc_object@@01@Z" + +void f(id, id<P>, id<P>, id) {} +// CHECK-LABEL: "\01?f@@YAXPAUobjc_object@@PAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@10@Z" + +void f(id<P>, id<P>) {} +// CHECK-LABEL: "\01?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@0@Z" + +void f(id<P>) {} +// CHECK-LABEL: "\01?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@@@@Z" + +void f(id<P, Q>) {} +// CHECK-LABEL: "\01?f@@YAXPAU?$objc_object@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" + +void f(Class<P>) {} +// CHECK-LABEL: "\01?f@@YAXPAU?$objc_class@U?$Protocol@UP@@@__ObjC@@@@@Z" + +void f(Class<P, Q>) {} +// CHECK-LABEL: "\01?f@@YAXPAU?$objc_class@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" + +void f(I<P> *) {} +// CHECK-LABEL: "\01?f@@YAXPAU?$I@U?$Protocol@UP@@@__ObjC@@@@@Z" + +void f(I<P, Q> *) {} +// CHECK-LABEL: "\01?f@@YAXPAU?$I@U?$Protocol@UP@@@__ObjC@@U?$Protocol@UQ@@@2@@@@Z" + +template <typename> +struct S {}; + +void f(S<__unsafe_unretained id>) {} +// CHECK-LABEL: "\01?f@@YAXU?$S@PAUobjc_object@@@@@Z" + +void f(S<__autoreleasing id>) {} +// CHECK-LABEL: "\01?f@@YAXU?$S@U?$Autoreleasing@PAUobjc_object@@@__ObjC@@@@@Z" + +void f(S<__strong id>) {} +// CHECK-LABEL: "\01?f@@YAXU?$S@U?$Strong@PAUobjc_object@@@__ObjC@@@@@Z" + +void f(S<__weak id>) {} +// CHECK-LABEL: "\01?f@@YAXU?$S@U?$Weak@PAUobjc_object@@@__ObjC@@@@@Z" + +void w(__weak id) {} +// CHECK-LABEL: "\01?w@@YAXPAUobjc_object@@@Z" + +void s(__strong id) {} +// CHECK-LABEL: "\01?s@@YAXPAUobjc_object@@@Z" + +void a(__autoreleasing id) {} +// CHECK-LABEL: "\01?a@@YAXPAUobjc_object@@@Z" + +void u(__unsafe_unretained id) {} +// CHECK-LABEL: "\01?u@@YAXPAUobjc_object@@@Z" + +S<__autoreleasing id> g() { return S<__autoreleasing id>(); } +// CHECK-LABEL: "\01?g@@YA?AU?$S@U?$Autoreleasing@PAUobjc_object@@@__ObjC@@@@XZ" + +__autoreleasing id h() { return nullptr; } +// CHECK-LABEL: "\01?h@@YAPAUobjc_object@@XZ" Removed: cfe/trunk/test/CodeGenObjCXX/msabi-protocol-conformance.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/msabi-protocol-conformance.mm?rev=324700&view=auto ============================================================================== --- cfe/trunk/test/CodeGenObjCXX/msabi-protocol-conformance.mm (original) +++ cfe/trunk/test/CodeGenObjCXX/msabi-protocol-conformance.mm (removed) @@ -1,34 +0,0 @@ -// RUN: %clang_cc1 -triple thumbv7-windows-msvc -fobjc-runtime=ios-6.0 -o - -emit-llvm %s | FileCheck %s - -@protocol P; -@protocol Q; - -@class I; - -void f(id<P>, id, id<P>, id) {} -// CHECK-LABEL: "\01?f@@YAXPAU?$objc_object@YP@@@@PAUobjc_object@@01@Z" - -void f(id, id<P>, id<P>, id) {} -// CHECK-LABEL: "\01?f@@YAXPAUobjc_object@@PAU?$objc_object@YP@@@@10@Z" - -void f(id<P>, id<P>) {} -// CHECK-LABEL: "\01?f@@YAXPAU?$objc_object@YP@@@@0@Z" - -void f(id<P>) {} -// CHECK-LABEL: "\01?f@@YAXPAU?$objc_object@YP@@@@@Z" - -void f(id<P, Q>) {} -// CHECK-LABEL: "\01?f@@YAXPAU?$objc_object@YP@@YQ@@@@@Z" - -void f(Class<P>) {} -// CHECK-LABEL: "\01?f@@YAXPAU?$objc_class@YP@@@@@Z" - -void f(Class<P, Q>) {} -// CHECK-LABEL: "\01?f@@YAXPAU?$objc_class@YP@@YQ@@@@@Z" - -void f(I<P> *) {} -// CHECK-LABEL: "\01?f@@YAXPAU?$I@YP@@@@@Z" - -void f(I<P, Q> *) {} -// CHECK-LABEL: "\01?f@@YAXPAU?$I@YP@@YQ@@@@@Z" - _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits