mirror of https://github.com/microsoft/clang.git
Mangle __unaligned in Itanium ABI
__unaligned is not currently mangled in any way in the Itanium ABI. This causes failures when using -fms-extensions and C++ in targets using Itanium ABI. As suggested by @rsmith the simplest thing to do here is actually mangle the qualifier as a vendor extension. This patch also removes the change done in D31976 and updates its test to the new reality. This fixes https://bugs.llvm.org/show_bug.cgi?id=33080 https://bugs.llvm.org/show_bug.cgi?id=33178 Differential Revision: https://reviews.llvm.org/D33398 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@304523 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fae6a43ca3
commit
4c7454ba51
|
@ -1459,8 +1459,6 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
|
|||
// We do not consider restrict a distinguishing attribute for overloading
|
||||
// purposes so we must not mangle it.
|
||||
MethodQuals.removeRestrict();
|
||||
// __unaligned is not currently mangled in any way, so remove it.
|
||||
MethodQuals.removeUnaligned();
|
||||
mangleQualifiers(MethodQuals);
|
||||
mangleRefQualifier(Method->getRefQualifier());
|
||||
}
|
||||
|
@ -2140,7 +2138,8 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
|
|||
}
|
||||
|
||||
void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
|
||||
// Vendor qualifiers come first.
|
||||
// Vendor qualifiers come first and if they are order-insensitive they must
|
||||
// be emitted in reversed alphabetical order, see Itanium ABI 5.1.5.
|
||||
|
||||
// Address space qualifiers start with an ordinary letter.
|
||||
if (Quals.hasAddressSpace()) {
|
||||
|
@ -2176,17 +2175,28 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
|
|||
}
|
||||
|
||||
// The ARC ownership qualifiers start with underscores.
|
||||
switch (Quals.getObjCLifetime()) {
|
||||
// Objective-C ARC Extension:
|
||||
//
|
||||
// <type> ::= U "__strong"
|
||||
// <type> ::= U "__weak"
|
||||
// <type> ::= U "__autoreleasing"
|
||||
//
|
||||
// Note: we emit __weak first to preserve the order as
|
||||
// required by the Itanium ABI.
|
||||
if (Quals.getObjCLifetime() == Qualifiers::OCL_Weak)
|
||||
mangleVendorQualifier("__weak");
|
||||
|
||||
// __unaligned (from -fms-extensions)
|
||||
if (Quals.hasUnaligned())
|
||||
mangleVendorQualifier("__unaligned");
|
||||
|
||||
// Remaining ARC ownership qualifiers.
|
||||
switch (Quals.getObjCLifetime()) {
|
||||
case Qualifiers::OCL_None:
|
||||
break;
|
||||
|
||||
case Qualifiers::OCL_Weak:
|
||||
mangleVendorQualifier("__weak");
|
||||
// Do nothing as we already handled this case above.
|
||||
break;
|
||||
|
||||
case Qualifiers::OCL_Strong:
|
||||
|
@ -4327,7 +4337,7 @@ bool CXXNameMangler::mangleSubstitution(const NamedDecl *ND) {
|
|||
/// substitutions.
|
||||
static bool hasMangledSubstitutionQualifiers(QualType T) {
|
||||
Qualifiers Qs = T.getQualifiers();
|
||||
return Qs.getCVRQualifiers() || Qs.hasAddressSpace();
|
||||
return Qs.getCVRQualifiers() || Qs.hasAddressSpace() || Qs.hasUnaligned();
|
||||
}
|
||||
|
||||
bool CXXNameMangler::mangleSubstitution(QualType T) {
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// RUN: %clang_cc1 -triple %itanium_abi_triple -fms-extensions -emit-llvm -o- %s | FileCheck %s
|
||||
|
||||
void fa(__unaligned struct A *) {}
|
||||
// CHECK: define void @_Z2faPU11__unaligned1A(
|
||||
|
||||
void ga(struct A *, struct A *) {}
|
||||
// CHECK: define void @_Z2gaP1AS0_(
|
||||
|
||||
void gb(__unaligned struct A *, struct A *) {}
|
||||
// CHECK: define void @_Z2gbPU11__unaligned1APS_(
|
||||
|
||||
void gc(struct A *, __unaligned struct A *) {}
|
||||
// CHECK: define void @_Z2gcP1APU11__unalignedS_(
|
||||
|
||||
void gd(__unaligned struct A *, __unaligned struct A *) {}
|
||||
// CHECK: define void @_Z2gdPU11__unaligned1AS1_(
|
||||
|
||||
void hb(__unaligned struct A *, __unaligned const struct A *) {}
|
||||
// CHECK: define void @_Z2hbPU11__unaligned1APU11__unalignedKS_(
|
||||
|
||||
void ja(__unaligned struct A *, __unaligned struct A *__unaligned *, __unaligned struct A *__unaligned *__unaligned *) {}
|
||||
// CHECK: define void @_Z2jaPU11__unaligned1APU11__unalignedS1_PU11__unalignedS3_(
|
||||
|
||||
void jb(__unaligned struct A *, __unaligned struct A **, __unaligned struct A *__unaligned *__unaligned *) {}
|
||||
// CHECK: @_Z2jbPU11__unaligned1APS1_PU11__unalignedPU11__unalignedS1_(
|
||||
|
||||
template <typename T, typename Q>
|
||||
void ta(T &, Q *) {}
|
||||
|
||||
void ia(__unaligned struct A &a) {
|
||||
ta(a, &a);
|
||||
}
|
||||
// CHECK: @_Z2taIU11__unaligned1AS1_EvRT_PT0_(
|
|
@ -0,0 +1,20 @@
|
|||
// RUN: %clang_cc1 -triple %itanium_abi_triple -fms-extensions -emit-llvm %s -o- | FileCheck %s
|
||||
|
||||
struct A {
|
||||
void foo() __unaligned;
|
||||
void foo() const __unaligned;
|
||||
void foo() volatile __unaligned;
|
||||
void foo() const volatile __unaligned;
|
||||
};
|
||||
|
||||
void A::foo() __unaligned {}
|
||||
// CHECK: define void @_ZNU11__unaligned1A3fooEv(
|
||||
|
||||
void A::foo() const __unaligned {}
|
||||
// CHECK: define void @_ZNU11__unalignedK1A3fooEv(
|
||||
|
||||
void A::foo() volatile __unaligned {}
|
||||
// CHECK: define void @_ZNU11__unalignedV1A3fooEv(
|
||||
|
||||
void A::foo() const volatile __unaligned {}
|
||||
// CHECK: define void @_ZNU11__unalignedVK1A3fooEv(
|
|
@ -1,4 +1,5 @@
|
|||
// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -triple %itanium_abi_triple -emit-llvm -fblocks -o - %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -DTEST_UNALIGNED -fms-extensions -fobjc-arc -fobjc-runtime-has-weak -triple %itanium_abi_triple -emit-llvm -fblocks -o - %s | FileCheck %s --check-prefix=UNALIGNED
|
||||
|
||||
// CHECK-LABEL: define {{.*}}void @_Z1fPU8__strongP11objc_object(i8**)
|
||||
void f(__strong id *) {}
|
||||
|
@ -32,3 +33,12 @@ template<unsigned N> struct unsigned_c { };
|
|||
// CHECK-LABEL: define weak_odr {{.*}}void @_Z1gIKvEvP10unsigned_cIXplszv1U8__bridgecvPT_v1U8__bridgecvP11objc_objectcvS3_Li0ELi1EEE
|
||||
template<typename T>void g(unsigned_c<sizeof((__bridge T*)(__bridge id)(T*)0) + 1>*) {}
|
||||
template void g<const void>(unsigned_c<sizeof(id) + 1> *);
|
||||
|
||||
#if TEST_UNALIGNED
|
||||
// UNALIGNED-LABEL: define {{.*}}void @_Z1gPU6__weakU11__unalignedP11objc_object(i8**)
|
||||
void g(__weak __unaligned id *) {}
|
||||
// UNALIGNED-LABEL: define {{.*}}void @_Z1gPU11__unalignedU8__strongP11objc_object(i8**)
|
||||
void g(__strong __unaligned id *) {}
|
||||
// UNALIGNED-LABEL: define {{.*}}void @_Z1gPU11__unalignedU15__autoreleasingP11objc_object(i8**)
|
||||
void g(__autoreleasing __unaligned id *) {}
|
||||
#endif // TEST_UNALIGNED
|
||||
|
|
Loading…
Reference in New Issue