diff options
author | Reid Kleckner <reid@kleckner.net> | 2013-05-14 20:30:42 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2013-05-14 20:30:42 +0000 |
commit | 369f316ef884679bc1b5c95206a56495036cbf29 (patch) | |
tree | bbe99cbe14c52c72f4a5679a4464a6889ce9e11a | |
parent | dcc7d48d55b76c99e454121ccce4819f6c0a71e0 (diff) | |
download | bcm5719-llvm-369f316ef884679bc1b5c95206a56495036cbf29.tar.gz bcm5719-llvm-369f316ef884679bc1b5c95206a56495036cbf29.zip |
[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!
llvm-svn: 181825
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 90 | ||||
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 2 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp | 41 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/mangle-ms-templates.cpp | 26 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/mangle-ms.cpp | 20 |
5 files changed, 143 insertions, 36 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index d242cd9335b..dbd37f02019 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/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 <map> 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) { - // <function-class> ::= 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 + // <function-class> ::= <member-function> E? # E designates a 64-bit 'this' + // # pointer. in 64-bit mode *all* + // # 'this' pointers are 64-bit. + // ::= <global-function> + // <member-function> ::= 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 + // <global-function> ::= Y # global near + // ::= Z # global far if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(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) { // <type> ::= <array-type> // <array-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers> // [Y <dimension-count> <dimension>+] -// <element-type> # as global -// ::= Q <cvr-qualifiers> [Y <dimension-count> <dimension>+] -// <element-type> # as param +// <element-type> # as global, E is never required +// ::= Q E? <cvr-qualifiers> [Y <dimension-count> <dimension>+] +// <element-type> # 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( } // <type> ::= <pointer-type> -// <pointer-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers> <type> +// <pointer-type> ::= E? <pointer-cvr-qualifiers> <cvr-qualifiers> <type> +// # 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, } // <type> ::= <reference-type> -// <reference-type> ::= A <cvr-qualifiers> <type> +// <reference-type> ::= A E? <cvr-qualifiers> <type> +// # 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); } // <type> ::= <r-value-reference-type> -// <r-value-reference-type> ::= $$Q <cvr-qualifiers> <type> +// <r-value-reference-type> ::= $$Q E? <cvr-qualifiers> <type> +// # 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/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index f27b502c9ce..eb39d084244 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/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/clang/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp b/clang/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp index d03ba526497..ed7027d975d 100644 --- a/clang/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp +++ b/clang/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/clang/test/CodeGenCXX/mangle-ms-templates.cpp b/clang/test/CodeGenCXX/mangle-ms-templates.cpp index 10e68248dc1..c52b6b4b7a2 100644 --- a/clang/test/CodeGenCXX/mangle-ms-templates.cpp +++ b/clang/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<typename T> class Class { @@ -33,65 +34,87 @@ class BoolTemplate<true> { void template_mangling() { Class<Typename> c1; // CHECK: call {{.*}} @"\01??0?$Class@VTypename@@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@VTypename@@@@QEAA@XZ" Class<const Typename> c1_const; // CHECK: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QEAA@XZ" Class<volatile Typename> c1_volatile; // CHECK: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QEAA@XZ" Class<const volatile Typename> c1_cv; // CHECK: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QEAA@XZ" Class<Nested<Typename> > c2; // CHECK: call {{.*}} @"\01??0?$Class@V?$Nested@VTypename@@@@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@V?$Nested@VTypename@@@@@@QEAA@XZ" Class<int * const> c_intpc; // CHECK: call {{.*}} @"\01??0?$Class@QAH@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@QEAH@@QEAA@XZ" Class<int()> c_ft; // CHECK: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QEAA@XZ" Class<int[]> c_inti; // CHECK: call {{.*}} @"\01??0?$Class@$$BY0A@H@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$BY0A@H@@QEAA@XZ" Class<int[5]> c_int5; // CHECK: call {{.*}} @"\01??0?$Class@$$BY04H@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$BY04H@@QEAA@XZ" Class<const int[5]> c_intc5; // CHECK: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QEAA@XZ" Class<int * const[5]> c_intpc5; // CHECK: call {{.*}} @"\01??0?$Class@$$BY04QAH@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$Class@$$BY04QEAH@@QEAA@XZ" BoolTemplate<false> _false; // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QAE@XZ" +// X64: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QEAA@XZ" BoolTemplate<true> _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<class T> 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<spam>(); // CHECK: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ" +// X64: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ" } diff --git a/clang/test/CodeGenCXX/mangle-ms.cpp b/clang/test/CodeGenCXX/mangle-ms.cpp index 1b98a84823f..3f80e54f433 100644 --- a/clang/test/CodeGenCXX/mangle-ms.cpp +++ b/clang/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 { |