void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T, Qualifiers,
SourceRange Range) {
- // We don't allow overloading by different protocol qualification,
- // so mangling them isn't necessary.
- mangleType(T->getBaseType(), Range, QMM_Drop);
+ if (T->qual_empty())
+ return mangleType(T->getBaseType(), Range, QMM_Drop);
+
+ ArgBackRefMap OuterArgsContext;
+ BackRefVec OuterTemplateContext;
+
+ TypeBackReferences.swap(OuterArgsContext);
+ NameBackReferences.swap(OuterTemplateContext);
+
+ mangleTagTypeKind(TTK_Struct);
+
+ Out << "?$";
+ if (T->isObjCId())
+ mangleSourceName("objc_object");
+ else if (T->isObjCClass())
+ mangleSourceName("objc_class");
+ else
+ mangleSourceName(T->getInterface()->getName());
+
+ for (const auto &Q : T->quals()) {
+ Out << 'Y'; // cointerface
+ mangleSourceName(Q->getName());
+ Out << '@';
+ }
+ Out << '@';
+
+ Out << '@';
+
+ TypeBackReferences.swap(OuterArgsContext);
+ NameBackReferences.swap(OuterTemplateContext);
}
void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T,
--- /dev/null
+// 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"
+