From: David Majnemer Date: Tue, 18 Feb 2014 12:58:35 +0000 (+0000) Subject: MS ABI: Add support for mangling __restrict X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8bd69ae74382c85c528a072312d36854b58d2b6f;p=clang MS ABI: Add support for mangling __restrict Pointer types in the MSVC ABI are a bit awkward, the width of the pointer is considered a kind of CVR qualifier. Restrict is handled similarly to const and volatile but is mangled after the pointer width qualifier. This fixes PR18880. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@201569 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index a8a09a7e60..90df22347e 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -145,7 +145,7 @@ private: void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc); void mangleCXXDtorType(CXXDtorType T); void mangleQualifiers(Qualifiers Quals, bool IsMember); - void manglePointerQualifiers(Qualifiers Quals); + void manglePointerQualifiers(Qualifiers Quals, const Type *PointeeType); void mangleUnscopedTemplateName(const TemplateDecl *ND); void mangleTemplateInstantiationName(const TemplateDecl *TD, @@ -1213,13 +1213,16 @@ void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals, // FIXME: For now, just drop all extension qualifiers on the floor. } -void MicrosoftCXXNameMangler::manglePointerQualifiers(Qualifiers Quals) { +void MicrosoftCXXNameMangler::manglePointerQualifiers(Qualifiers Quals, + const Type *PointeeType) { // ::= P # no qualifiers // ::= Q # const // ::= R # volatile // ::= S # const volatile bool HasConst = Quals.hasConst(), - HasVolatile = Quals.hasVolatile(); + HasVolatile = Quals.hasVolatile(), + HasRestrict = Quals.hasRestrict(); + if (HasConst && HasVolatile) { Out << 'S'; } else if (HasVolatile) { @@ -1229,6 +1232,12 @@ void MicrosoftCXXNameMangler::manglePointerQualifiers(Qualifiers Quals) { } else { Out << 'P'; } + + if (PointersAre64Bit && PointeeType && !PointeeType->isFunctionType()) + Out << 'E'; + + if (HasRestrict) + Out << 'I'; } void MicrosoftCXXNameMangler::mangleArgumentType(QualType T, @@ -1320,7 +1329,7 @@ void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range, // We have to mangle these now, while we still have enough information. if (IsPointer) - manglePointerQualifiers(Quals); + manglePointerQualifiers(Quals, T->getPointeeType().getTypePtr()); const Type *ty = T.getTypePtr(); switch (ty->getTypeClass()) { @@ -1656,7 +1665,7 @@ void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) { void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T) { // This isn't a recursive mangling, so now we have to do it all in this // one call. - manglePointerQualifiers(T->getElementType().getQualifiers()); + manglePointerQualifiers(T->getElementType().getQualifiers(), 0); mangleType(T->getElementType(), SourceRange()); } void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T, @@ -1728,8 +1737,6 @@ void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T, mangleName(T->getClass()->castAs()->getDecl()); mangleFunctionType(FPT, 0, true); } else { - if (PointersAre64Bit && !T->getPointeeType()->isFunctionType()) - Out << 'E'; mangleQualifiers(PointeeType.getQualifiers(), true); mangleName(T->getClass()->castAs()->getDecl()); mangleType(PointeeType, Range, QMM_Drop); @@ -1761,8 +1768,6 @@ void MicrosoftCXXNameMangler::mangleType( void MicrosoftCXXNameMangler::mangleType(const PointerType *T, SourceRange Range) { QualType PointeeTy = T->getPointeeType(); - if (PointersAre64Bit && !T->getPointeeType()->isFunctionType()) - Out << 'E'; mangleType(PointeeTy, Range); } void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T, diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 26534d7b43..cebdbad4fc 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -422,6 +422,10 @@ QualType Type::getPointeeType() const { return BPT->getPointeeType(); if (const ReferenceType *RT = getAs()) return RT->getPointeeType(); + if (const MemberPointerType *MPT = getAs()) + return MPT->getPointeeType(); + if (const DecayedType *DT = getAs()) + return DT->getPointeeType(); return QualType(); } diff --git a/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp index 58f24d5f14..fae2e1ab2d 100644 --- a/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp +++ b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp @@ -37,6 +37,22 @@ void foo_sad(char * const volatile x) {} // CHECK: "\01?foo_sad@@YAXSAD@Z" // X64: "\01?foo_sad@@YAXSEAD@Z" +void foo_piad(char * __restrict x) {} +// CHECK: "\01?foo_piad@@YAXPIAD@Z" +// X64: "\01?foo_piad@@YAXPEIAD@Z" + +void foo_qiad(char * const __restrict x) {} +// CHECK: "\01?foo_qiad@@YAXQIAD@Z" +// X64: "\01?foo_qiad@@YAXQEIAD@Z" + +void foo_riad(char * volatile __restrict x) {} +// CHECK: "\01?foo_riad@@YAXRIAD@Z" +// X64: "\01?foo_riad@@YAXREIAD@Z" + +void foo_siad(char * const volatile __restrict x) {} +// CHECK: "\01?foo_siad@@YAXSIAD@Z" +// X64: "\01?foo_siad@@YAXSEIAD@Z" + void foo_papad(char ** x) {} // CHECK: "\01?foo_papad@@YAXPAPAD@Z" // X64: "\01?foo_papad@@YAXPEAPEAD@Z" @@ -238,3 +254,7 @@ void mangle_yes_backref2(fun_type *const[], ptr_to_fun_type const[]) {} void mangle_yes_backref3(ptr_to_fun_type *const, void (**const)(void)) {} // CHECK: "\01?mangle_yes_backref3@@YAXQAP6AXXZ0@Z" // X64: "\01?mangle_yes_backref3@@YAXQEAP6AXXZ0@Z" + +void mangle_yes_backref4(int *const __restrict, int *const __restrict) {} +// CHECK: "\01?mangle_yes_backref4@@YAXQIAH0@Z" +// X64: "\01?mangle_yes_backref4@@YAXQEIAH0@Z" diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp index 2b0457f0d0..7207ad9a52 100644 --- a/test/CodeGenCXX/mangle-ms.cpp +++ b/test/CodeGenCXX/mangle-ms.cpp @@ -99,6 +99,11 @@ extern const int * const h2 = &a; int i[10][20]; // CHECK-DAG: @"\01?i@@3PAY0BE@HA" +typedef int (*FunT)(int, int); +FunT FunArr[10][20]; +// CHECK-DAG: @"\01?FunArr@@3PAY0BE@P6AHHH@ZA" +// X64-DAG: @"\01?FunArr@@3PAY0BE@P6AHHH@ZA" + int (__stdcall *j)(signed char, unsigned char); // CHECK-DAG: @"\01?j@@3P6GHCE@ZA"