From d6a08d16a0c8d98e2491f3ee012dbb46b64038f2 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 14 May 2013 20:30:42 +0000 Subject: [PATCH] [ms-cxxabi] Mangle in an implicit 'E' for certain types on win64 Most of the complexity of this patch is figuring out which types get the qualifier and which don't. If we implement __ptr32/64, then we should check the qualifier instead of assuming all pointers are 64-bit. This fixes PR13792. Patch by Warren Hunt! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181825 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/MicrosoftMangle.cpp | 90 +++++++++++++------- lib/AST/RecordLayoutBuilder.cpp | 2 +- test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp | 41 +++++++++ test/CodeGenCXX/mangle-ms-templates.cpp | 26 +++++- test/CodeGenCXX/mangle-ms.cpp | 20 ++++- 5 files changed, 143 insertions(+), 36 deletions(-) diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index d242cd9335..dbd37f0201 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -22,6 +22,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/Basic/ABI.h" #include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/TargetInfo.h" #include using namespace clang; @@ -58,18 +59,26 @@ class MicrosoftCXXNameMangler { ASTContext &getASTContext() const { return Context.getASTContext(); } + // FIXME: If we add support for __ptr32/64 qualifiers, then we should push + // this check into mangleQualifiers(). + const bool PointersAre64Bit; + public: enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result }; MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_) : Context(C), Out(Out_), Structor(0), StructorType(-1), + PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) == + 64), UseNameBackReferences(true) { } MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_, const CXXDestructorDecl *D, CXXDtorType Type) : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type), + PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) == + 64), UseNameBackReferences(true) { } raw_ostream &getStream() const { return Out; } @@ -1228,32 +1237,36 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, } void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) { - // ::= A # private: near - // ::= B # private: far - // ::= C # private: static near - // ::= D # private: static far - // ::= E # private: virtual near - // ::= F # private: virtual far - // ::= G # private: thunk near - // ::= H # private: thunk far - // ::= I # protected: near - // ::= J # protected: far - // ::= K # protected: static near - // ::= L # protected: static far - // ::= M # protected: virtual near - // ::= N # protected: virtual far - // ::= O # protected: thunk near - // ::= P # protected: thunk far - // ::= Q # public: near - // ::= R # public: far - // ::= S # public: static near - // ::= T # public: static far - // ::= U # public: virtual near - // ::= V # public: virtual far - // ::= W # public: thunk near - // ::= X # public: thunk far - // ::= Y # global near - // ::= Z # global far + // ::= E? # E designates a 64-bit 'this' + // # pointer. in 64-bit mode *all* + // # 'this' pointers are 64-bit. + // ::= + // ::= A # private: near + // ::= B # private: far + // ::= C # private: static near + // ::= D # private: static far + // ::= E # private: virtual near + // ::= F # private: virtual far + // ::= G # private: thunk near + // ::= H # private: thunk far + // ::= I # protected: near + // ::= J # protected: far + // ::= K # protected: static near + // ::= L # protected: static far + // ::= M # protected: virtual near + // ::= N # protected: virtual far + // ::= O # protected: thunk near + // ::= P # protected: thunk far + // ::= Q # public: near + // ::= R # public: far + // ::= S # public: static near + // ::= T # public: static far + // ::= U # public: virtual near + // ::= V # public: virtual far + // ::= W # public: thunk near + // ::= X # public: thunk far + // ::= Y # global near + // ::= Z # global far if (const CXXMethodDecl *MD = dyn_cast(FD)) { switch (MD->getAccess()) { default: @@ -1281,6 +1294,8 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) { else Out << 'Q'; } + if (PointersAre64Bit && !MD->isStatic()) + Out << 'E'; } else Out << 'Y'; } @@ -1380,9 +1395,9 @@ void MicrosoftCXXNameMangler::mangleType(const TagType *T) { // ::= // ::= // [Y +] -// # as global -// ::= Q [Y +] -// # as param +// # as global, E is never required +// ::= Q E? [Y +] +// # as param, E is required for 64-bit // It's supposed to be the other way around, but for some strange reason, it // isn't. Today this behavior is retained for the sole purpose of backwards // compatibility. @@ -1394,6 +1409,8 @@ void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T, manglePointerQualifiers(T->getElementType().getQualifiers()); } else { Out << 'Q'; + if (PointersAre64Bit) + Out << 'E'; } mangleType(T->getElementType(), SourceRange()); } @@ -1494,10 +1511,13 @@ void MicrosoftCXXNameMangler::mangleType( } // ::= -// ::= +// ::= E? +// # the E is required for 64-bit non static pointers 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, @@ -1508,18 +1528,24 @@ void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T, } // ::= -// ::= A +// ::= A E? +// # the E is required for 64-bit non static lvalue references void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T, SourceRange Range) { Out << 'A'; + if (PointersAre64Bit && !T->getPointeeType()->isFunctionType()) + Out << 'E'; mangleType(T->getPointeeType(), Range); } // ::= -// ::= $$Q +// ::= $$Q E? +// # the E is required for 64-bit non static rvalue references void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T, SourceRange Range) { Out << "$$Q"; + if (PointersAre64Bit && !T->getPointeeType()->isFunctionType()) + Out << 'E'; mangleType(T->getPointeeType(), Range); } diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index f27b502c9c..eb39d08424 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -211,7 +211,7 @@ void EmptySubobjectMap::AddSubobjectAtOffset(const CXXRecordDecl *RD, if (!RD->isEmpty()) return; - // If we have empty structures inside an union, we can assign both + // If we have empty structures inside a union, we can assign both // the same offset. Just avoid pushing them twice in the list. ClassVectorTy& Classes = EmptyClassOffsets[Offset]; if (std::find(Classes.begin(), Classes.end(), RD) != Classes.end()) diff --git a/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp index d03ba52649..ed7027d975 100644 --- a/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp +++ b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp @@ -1,123 +1,164 @@ // RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s +// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 | FileCheck -check-prefix=X64 %s void foo(const unsigned int) {} // CHECK: "\01?foo@@YAXI@Z" +// X64: "\01?foo@@YAXI@Z" void foo(const double) {} // CHECK: "\01?foo@@YAXN@Z" +// X64: "\01?foo@@YAXN@Z" void bar(const volatile double) {} // CHECK: "\01?bar@@YAXN@Z" +// X64: "\01?bar@@YAXN@Z" void foo_pad(char * x) {} // CHECK: "\01?foo_pad@@YAXPAD@Z" +// X64: "\01?foo_pad@@YAXPEAD@Z" void foo_pbd(const char * x) {} // CHECK: "\01?foo_pbd@@YAXPBD@Z" +// X64: "\01?foo_pbd@@YAXPEBD@Z" void foo_pcd(volatile char * x) {} // CHECK: "\01?foo_pcd@@YAXPCD@Z" +// X64: "\01?foo_pcd@@YAXPECD@Z" void foo_qad(char * const x) {} // CHECK: "\01?foo_qad@@YAXQAD@Z" +// X64: "\01?foo_qad@@YAXQEAD@Z" void foo_rad(char * volatile x) {} // CHECK: "\01?foo_rad@@YAXRAD@Z" +// X64: "\01?foo_rad@@YAXREAD@Z" void foo_sad(char * const volatile x) {} // CHECK: "\01?foo_sad@@YAXSAD@Z" +// X64: "\01?foo_sad@@YAXSEAD@Z" void foo_papad(char ** x) {} // CHECK: "\01?foo_papad@@YAXPAPAD@Z" +// X64: "\01?foo_papad@@YAXPEAPEAD@Z" void foo_papbd(char const ** x) {} // CHECK: "\01?foo_papbd@@YAXPAPBD@Z" +// X64: "\01?foo_papbd@@YAXPEAPEBD@Z" void foo_papcd(char volatile ** x) {} // CHECK: "\01?foo_papcd@@YAXPAPCD@Z" +// X64: "\01?foo_papcd@@YAXPEAPECD@Z" void foo_pbqad(char * const* x) {} // CHECK: "\01?foo_pbqad@@YAXPBQAD@Z" +// X64: "\01?foo_pbqad@@YAXPEBQEAD@Z" void foo_pcrad(char * volatile* x) {} // CHECK: "\01?foo_pcrad@@YAXPCRAD@Z" +// X64: "\01?foo_pcrad@@YAXPECREAD@Z" void foo_qapad(char ** const x) {} // CHECK: "\01?foo_qapad@@YAXQAPAD@Z" +// X64: "\01?foo_qapad@@YAXQEAPEAD@Z" void foo_rapad(char ** volatile x) {} // CHECK: "\01?foo_rapad@@YAXRAPAD@Z" +// X64: "\01?foo_rapad@@YAXREAPEAD@Z" void foo_pbqbd(const char * const* x) {} // CHECK: "\01?foo_pbqbd@@YAXPBQBD@Z" +// X64: "\01?foo_pbqbd@@YAXPEBQEBD@Z" void foo_pbqcd(volatile char * const* x) {} // CHECK: "\01?foo_pbqcd@@YAXPBQCD@Z" +// X64: "\01?foo_pbqcd@@YAXPEBQECD@Z" void foo_pcrbd(const char * volatile* x) {} // CHECK: "\01?foo_pcrbd@@YAXPCRBD@Z" +// X64: "\01?foo_pcrbd@@YAXPECREBD@Z" void foo_pcrcd(volatile char * volatile* x) {} // CHECK: "\01?foo_pcrcd@@YAXPCRCD@Z" +// X64: "\01?foo_pcrcd@@YAXPECRECD@Z" void foo_aad(char &x) {} // CHECK: "\01?foo_aad@@YAXAAD@Z" +// X64: "\01?foo_aad@@YAXAEAD@Z" void foo_abd(const char &x) {} // CHECK: "\01?foo_abd@@YAXABD@Z" +// X64: "\01?foo_abd@@YAXAEBD@Z" void foo_aapad(char *&x) {} // CHECK: "\01?foo_aapad@@YAXAAPAD@Z" +// X64: "\01?foo_aapad@@YAXAEAPEAD@Z" void foo_aapbd(const char *&x) {} // CHECK: "\01?foo_aapbd@@YAXAAPBD@Z" +// X64: "\01?foo_aapbd@@YAXAEAPEBD@Z" void foo_abqad(char * const &x) {} // CHECK: "\01?foo_abqad@@YAXABQAD@Z" +// X64: "\01?foo_abqad@@YAXAEBQEAD@Z" void foo_abqbd(const char * const &x) {} // CHECK: "\01?foo_abqbd@@YAXABQBD@Z" +// X64: "\01?foo_abqbd@@YAXAEBQEBD@Z" void foo_aay144h(int (&x)[5][5]) {} // CHECK: "\01?foo_aay144h@@YAXAAY144H@Z" +// X64: "\01?foo_aay144h@@YAXAEAY144H@Z" void foo_aay144cbh(const int (&x)[5][5]) {} // CHECK: "\01?foo_aay144cbh@@YAXAAY144$$CBH@Z" +// X64: "\01?foo_aay144cbh@@YAXAEAY144$$CBH@Z" void foo_qay144h(int (&&x)[5][5]) {} // CHECK: "\01?foo_qay144h@@YAX$$QAY144H@Z" +// X64: "\01?foo_qay144h@@YAX$$QEAY144H@Z" void foo_qay144cbh(const int (&&x)[5][5]) {} // CHECK: "\01?foo_qay144cbh@@YAX$$QAY144$$CBH@Z" +// X64: "\01?foo_qay144cbh@@YAX$$QEAY144$$CBH@Z" void foo_p6ahxz(int x()) {} // CHECK: "\01?foo_p6ahxz@@YAXP6AHXZ@Z" +// X64: "\01?foo_p6ahxz@@YAXP6AHXZ@Z" void foo_a6ahxz(int (&x)()) {} // CHECK: "\01?foo_a6ahxz@@YAXA6AHXZ@Z" +// X64: "\01?foo_a6ahxz@@YAXA6AHXZ@Z" void foo_q6ahxz(int (&&x)()) {} // CHECK: "\01?foo_q6ahxz@@YAX$$Q6AHXZ@Z" +// X64: "\01?foo_q6ahxz@@YAX$$Q6AHXZ@Z" void foo_qay04h(int x[5][5]) {} // CHECK: "\01?foo_qay04h@@YAXQAY04H@Z" +// X64: "\01?foo_qay04h@@YAXQEAY04H@Z" void foo_qay04cbh(const int x[5][5]) {} // CHECK: "\01?foo_qay04cbh@@YAXQAY04$$CBH@Z" +// X64: "\01?foo_qay04cbh@@YAXQEAY04$$CBH@Z" typedef double Vector[3]; void foo(Vector*) {} // CHECK: "\01?foo@@YAXPAY02N@Z" +// X64: "\01?foo@@YAXPEAY02N@Z" void foo(Vector) {} // CHECK: "\01?foo@@YAXQAN@Z" +// X64: "\01?foo@@YAXQEAN@Z" void foo_const(const Vector) {} // CHECK: "\01?foo_const@@YAXQBN@Z" +// X64: "\01?foo_const@@YAXQEBN@Z" void foo_volatile(volatile Vector) {} // CHECK: "\01?foo_volatile@@YAXQCN@Z" +// X64: "\01?foo_volatile@@YAXQECN@Z" void foo(Vector*, const Vector, const double) {} // CHECK: "\01?foo@@YAXPAY02NQBNN@Z" +// X64: "\01?foo@@YAXPEAY02NQEBNN@Z" diff --git a/test/CodeGenCXX/mangle-ms-templates.cpp b/test/CodeGenCXX/mangle-ms-templates.cpp index 10e68248dc..c52b6b4b7a 100644 --- a/test/CodeGenCXX/mangle-ms-templates.cpp +++ b/test/CodeGenCXX/mangle-ms-templates.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fms-extensions -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s +// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s +// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s template class Class { @@ -33,65 +34,87 @@ class BoolTemplate { void template_mangling() { Class c1; // CHECK: call {{.*}} @"\01??0?$Class@VTypename@@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@VTypename@@@@QEAA@XZ" Class c1_const; // CHECK: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QEAA@XZ" Class c1_volatile; // CHECK: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QEAA@XZ" Class c1_cv; // CHECK: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QEAA@XZ" Class > c2; // CHECK: call {{.*}} @"\01??0?$Class@V?$Nested@VTypename@@@@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@V?$Nested@VTypename@@@@@@QEAA@XZ" Class c_intpc; // CHECK: call {{.*}} @"\01??0?$Class@QAH@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@QEAH@@QEAA@XZ" Class c_ft; // CHECK: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QEAA@XZ" Class c_inti; // CHECK: call {{.*}} @"\01??0?$Class@$$BY0A@H@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$BY0A@H@@QEAA@XZ" Class c_int5; // CHECK: call {{.*}} @"\01??0?$Class@$$BY04H@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$BY04H@@QEAA@XZ" Class c_intc5; // CHECK: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QEAA@XZ" Class c_intpc5; // CHECK: call {{.*}} @"\01??0?$Class@$$BY04QAH@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$BY04QEAH@@QEAA@XZ" BoolTemplate _false; // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QEAA@XZ" BoolTemplate _true; // PR13158 _true.Foo(1); // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$00@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$BoolTemplate@$00@@QEAA@XZ" // CHECK: call {{.*}} @"\01??$Foo@H@?$BoolTemplate@$00@@QAEXH@Z" +// X64: call {{.*}} @"\01??$Foo@H@?$BoolTemplate@$00@@QEAAXH@Z" IntTemplate<0> zero; // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0A@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$IntTemplate@$0A@@@QEAA@XZ" IntTemplate<5> five; // CHECK: call {{.*}} @"\01??0?$IntTemplate@$04@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$IntTemplate@$04@@QEAA@XZ" IntTemplate<11> eleven; // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0L@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$IntTemplate@$0L@@@QEAA@XZ" IntTemplate<256> _256; // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0BAA@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$IntTemplate@$0BAA@@@QEAA@XZ" IntTemplate<513> _513; // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0CAB@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$IntTemplate@$0CAB@@@QEAA@XZ" IntTemplate<1026> _1026; // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0EAC@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$IntTemplate@$0EAC@@@QEAA@XZ" IntTemplate<65535> ffff; // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QEAA@XZ" } namespace space { template const T& foo(const T& l) { return l; } } // CHECK: "\01??$foo@H@space@@YAABHABH@Z" +// X64: "\01??$foo@H@space@@YAAEBHAEBH@Z" void use() { space::foo(42); @@ -108,4 +131,5 @@ void FunctionPointerTemplate() { void spam() { FunctionPointerTemplate(); // CHECK: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ" +// X64: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ" } diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp index 1b98a84823..3f80e54f43 100644 --- a/test/CodeGenCXX/mangle-ms.cpp +++ b/test/CodeGenCXX/mangle-ms.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s -// RUN: %clang_cc1 -fms-compatibility -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s +// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s +// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s // CHECK: @"\01?a@@3HA" // CHECK: @"\01?b@N@@3HA" @@ -33,6 +33,7 @@ namespace N { static int c; int _c(void) {return N::anonymous + c;} // CHECK: @"\01?_c@@YAHXZ" +// X64: @"\01?_c@@YAHXZ" class foo { static const short d; @@ -43,15 +44,19 @@ public: int operator+(int a); foo(){} //CHECK: @"\01??0foo@@QAE@XZ" +//X64: @"\01??0foo@@QEAA@XZ" ~foo(){} //CHECK: @"\01??1foo@@QAE@XZ" +//X64: @"\01??1foo@@QEAA@XZ foo(int i){} //CHECK: @"\01??0foo@@QAE@H@Z" +//X64: @"\01??0foo@@QEAA@H@Z" foo(char *q){} //CHECK: @"\01??0foo@@QAE@PAD@Z" +//X64: @"\01??0foo@@QEAA@PEAD@Z" static foo* static_method() { return 0; } @@ -77,12 +82,15 @@ enum quux { foo bar() { return foo(); } //CHECK: @"\01?bar@@YA?AVfoo@@XZ" +//X64: @"\01?bar@@YA?AVfoo@@XZ" int foo::operator+(int a) { //CHECK: @"\01??Hfoo@@QAEHH@Z" +//X64: @"\01??Hfoo@@QEAAHH@Z" foo::static_method(); //CHECK: @"\01?static_method@foo@@SAPAV1@XZ" +//X64: @"\01?static_method@foo@@SAPEAV1@XZ" bar(); return a; } @@ -109,6 +117,7 @@ int (foo2::*l)(int); static void __stdcall alpha(float a, double b) throw() {} bool __fastcall beta(long long a, wchar_t b) throw(signed char, unsigned char) { // CHECK: @"\01?beta@@YI_N_J_W@Z" +// X64: @"\01?beta@@YA_N_J_W@Z" alpha(0.f, 0.0); return false; } @@ -119,17 +128,21 @@ bool __fastcall beta(long long a, wchar_t b) throw(signed char, unsigned char) { // Make sure tag-type mangling works. void gamma(class foo, struct bar, union baz, enum quux) {} // CHECK: @"\01?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z" +// X64: @"\01?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z" // Make sure pointer/reference-type mangling works. void delta(int * const a, const long &) {} // CHECK: @"\01?delta@@YAXQAHABJ@Z" +// X64: @"\01?delta@@YAXQEAHAEBJ@Z" // Array mangling. void epsilon(int a[][10][20]) {} // CHECK: @"\01?epsilon@@YAXQAY19BE@H@Z" +// X64: @"\01?epsilon@@YAXQEAY19BE@H@Z" void zeta(int (*)(int, int)) {} // CHECK: @"\01?zeta@@YAXP6AHHH@Z@Z" +// X64: @"\01?zeta@@YAXP6AHHH@Z@Z" // Blocks mangling (Clang extension). A block should be mangled slightly // differently from a similar function pointer. @@ -158,6 +171,7 @@ void operator_new_delete() { void (redundant_parens)(); void redundant_parens_use() { redundant_parens(); } // CHECK: @"\01?redundant_parens@@YAXXZ" +// X64: @"\01?redundant_parens@@YAXXZ" // PR13047 typedef double RGB[3]; @@ -169,10 +183,12 @@ extern RGB const ((color4)[5]) = {}; // PR12603 enum E {}; // CHECK: "\01?fooE@@YA?AW4E@@XZ" +// X64: "\01?fooE@@YA?AW4E@@XZ" E fooE() { return E(); } class X {}; // CHECK: "\01?fooX@@YA?AVX@@XZ" +// X64: "\01?fooX@@YA?AVX@@XZ" X fooX() { return X(); } namespace PR13182 { -- 2.40.0