r181825 - [ms-cxxabi] Mangle in an implicit 'E' for certain types on win64

Reid Kleckner reid at kleckner.net
Tue May 14 13:30:42 PDT 2013


Author: rnk
Date: Tue May 14 15:30:42 2013
New Revision: 181825

URL: http://llvm.org/viewvc/llvm-project?rev=181825&view=rev
Log:
[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!

Modified:
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms.cpp

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=181825&r1=181824&r2=181825&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Tue May 14 15:30:42 2013
@@ -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::mangleFunc
 }
 
 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::mangleFunc
         else
           Out << 'Q';
     }
+    if (PointersAre64Bit && !MD->isStatic())
+      Out << 'E';
   } else
     Out << 'Y';
 }
@@ -1380,9 +1395,9 @@ void MicrosoftCXXNameMangler::mangleType
 // <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::mangleDeca
     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
 }
 
 // <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);
 }
 

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=181825&r1=181824&r2=181825&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Tue May 14 15:30:42 2013
@@ -211,7 +211,7 @@ void EmptySubobjectMap::AddSubobjectAtOf
   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())

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp?rev=181825&r1=181824&r2=181825&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp Tue May 14 15:30:42 2013
@@ -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 at Z"
+// X64: "\01?foo@@YAXI at Z"
 
 void foo(const double) {}
 // CHECK: "\01?foo@@YAXN at Z"
+// X64: "\01?foo@@YAXN at Z"
 
 void bar(const volatile double) {}
 // CHECK: "\01?bar@@YAXN at Z"
+// X64: "\01?bar@@YAXN at Z"
 
 void foo_pad(char * x) {}
 // CHECK: "\01?foo_pad@@YAXPAD at Z"
+// X64: "\01?foo_pad@@YAXPEAD at Z"
 
 void foo_pbd(const char * x) {}
 // CHECK: "\01?foo_pbd@@YAXPBD at Z"
+// X64: "\01?foo_pbd@@YAXPEBD at Z"
 
 void foo_pcd(volatile char * x) {}
 // CHECK: "\01?foo_pcd@@YAXPCD at Z"
+// X64: "\01?foo_pcd@@YAXPECD at Z"
 
 void foo_qad(char * const x) {}
 // CHECK: "\01?foo_qad@@YAXQAD at Z"
+// X64: "\01?foo_qad@@YAXQEAD at Z"
 
 void foo_rad(char * volatile x) {}
 // CHECK: "\01?foo_rad@@YAXRAD at Z"
+// X64: "\01?foo_rad@@YAXREAD at Z"
 
 void foo_sad(char * const volatile x) {}
 // CHECK: "\01?foo_sad@@YAXSAD at Z"
+// X64: "\01?foo_sad@@YAXSEAD at Z"
 
 void foo_papad(char ** x) {}
 // CHECK: "\01?foo_papad@@YAXPAPAD at Z"
+// X64: "\01?foo_papad@@YAXPEAPEAD at Z"
 
 void foo_papbd(char const ** x) {}
 // CHECK: "\01?foo_papbd@@YAXPAPBD at Z"
+// X64: "\01?foo_papbd@@YAXPEAPEBD at Z"
 
 void foo_papcd(char volatile ** x) {}
 // CHECK: "\01?foo_papcd@@YAXPAPCD at Z"
+// X64: "\01?foo_papcd@@YAXPEAPECD at Z"
 
 void foo_pbqad(char * const* x) {}
 // CHECK: "\01?foo_pbqad@@YAXPBQAD at Z"
+// X64: "\01?foo_pbqad@@YAXPEBQEAD at Z"
 
 void foo_pcrad(char * volatile* x) {}
 // CHECK: "\01?foo_pcrad@@YAXPCRAD at Z"
+// X64: "\01?foo_pcrad@@YAXPECREAD at Z"
 
 void foo_qapad(char ** const x) {}
 // CHECK: "\01?foo_qapad@@YAXQAPAD at Z"
+// X64: "\01?foo_qapad@@YAXQEAPEAD at Z"
 
 void foo_rapad(char ** volatile x) {}
 // CHECK: "\01?foo_rapad@@YAXRAPAD at Z"
+// X64: "\01?foo_rapad@@YAXREAPEAD at Z"
 
 void foo_pbqbd(const char * const* x) {}
 // CHECK: "\01?foo_pbqbd@@YAXPBQBD at Z"
+// X64: "\01?foo_pbqbd@@YAXPEBQEBD at Z"
 
 void foo_pbqcd(volatile char * const* x) {}
 // CHECK: "\01?foo_pbqcd@@YAXPBQCD at Z"
+// X64: "\01?foo_pbqcd@@YAXPEBQECD at Z"
 
 void foo_pcrbd(const char * volatile* x) {}
 // CHECK: "\01?foo_pcrbd@@YAXPCRBD at Z"
+// X64: "\01?foo_pcrbd@@YAXPECREBD at Z"
 
 void foo_pcrcd(volatile char * volatile* x) {}
 // CHECK: "\01?foo_pcrcd@@YAXPCRCD at Z"
+// X64: "\01?foo_pcrcd@@YAXPECRECD at Z"
 
 void foo_aad(char &x) {}
 // CHECK: "\01?foo_aad@@YAXAAD at Z"
+// X64: "\01?foo_aad@@YAXAEAD at Z"
 
 void foo_abd(const char &x) {}
 // CHECK: "\01?foo_abd@@YAXABD at Z"
+// X64: "\01?foo_abd@@YAXAEBD at Z"
 
 void foo_aapad(char *&x) {}
 // CHECK: "\01?foo_aapad@@YAXAAPAD at Z"
+// X64: "\01?foo_aapad@@YAXAEAPEAD at Z"
 
 void foo_aapbd(const char *&x) {}
 // CHECK: "\01?foo_aapbd@@YAXAAPBD at Z"
+// X64: "\01?foo_aapbd@@YAXAEAPEBD at Z"
 
 void foo_abqad(char * const &x) {}
 // CHECK: "\01?foo_abqad@@YAXABQAD at Z"
+// X64: "\01?foo_abqad@@YAXAEBQEAD at Z"
 
 void foo_abqbd(const char * const &x) {}
 // CHECK: "\01?foo_abqbd@@YAXABQBD at Z"
+// X64: "\01?foo_abqbd@@YAXAEBQEBD at Z"
 
 void foo_aay144h(int (&x)[5][5]) {}
 // CHECK: "\01?foo_aay144h@@YAXAAY144H at Z"
+// X64: "\01?foo_aay144h@@YAXAEAY144H at Z"
 
 void foo_aay144cbh(const int (&x)[5][5]) {}
 // CHECK: "\01?foo_aay144cbh@@YAXAAY144$$CBH at Z"
+// X64: "\01?foo_aay144cbh@@YAXAEAY144$$CBH at Z"
 
 void foo_qay144h(int (&&x)[5][5]) {}
 // CHECK: "\01?foo_qay144h@@YAX$$QAY144H at Z"
+// X64: "\01?foo_qay144h@@YAX$$QEAY144H at Z"
 
 void foo_qay144cbh(const int (&&x)[5][5]) {}
 // CHECK: "\01?foo_qay144cbh@@YAX$$QAY144$$CBH at Z"
+// X64: "\01?foo_qay144cbh@@YAX$$QEAY144$$CBH at Z"
 
 void foo_p6ahxz(int x()) {}
 // CHECK: "\01?foo_p6ahxz@@YAXP6AHXZ at Z"
+// X64: "\01?foo_p6ahxz@@YAXP6AHXZ at Z"
 
 void foo_a6ahxz(int (&x)()) {}
 // CHECK: "\01?foo_a6ahxz@@YAXA6AHXZ at Z"
+// X64: "\01?foo_a6ahxz@@YAXA6AHXZ at Z"
 
 void foo_q6ahxz(int (&&x)()) {}
 // CHECK: "\01?foo_q6ahxz@@YAX$$Q6AHXZ at Z"
+// X64: "\01?foo_q6ahxz@@YAX$$Q6AHXZ at Z"
 
 void foo_qay04h(int x[5][5]) {}
 // CHECK: "\01?foo_qay04h@@YAXQAY04H at Z"
+// X64: "\01?foo_qay04h@@YAXQEAY04H at Z"
 
 void foo_qay04cbh(const int x[5][5]) {}
 // CHECK: "\01?foo_qay04cbh@@YAXQAY04$$CBH at Z"
+// X64: "\01?foo_qay04cbh@@YAXQEAY04$$CBH at Z"
 
 typedef double Vector[3];
 
 void foo(Vector*) {}
 // CHECK: "\01?foo@@YAXPAY02N at Z"
+// X64: "\01?foo@@YAXPEAY02N at Z"
 
 void foo(Vector) {}
 // CHECK: "\01?foo@@YAXQAN at Z"
+// X64: "\01?foo@@YAXQEAN at Z"
 
 void foo_const(const Vector) {}
 // CHECK: "\01?foo_const@@YAXQBN at Z"
+// X64: "\01?foo_const@@YAXQEBN at Z"
 
 void foo_volatile(volatile Vector) {}
 // CHECK: "\01?foo_volatile@@YAXQCN at Z"
+// X64: "\01?foo_volatile@@YAXQECN at Z"
 
 void foo(Vector*, const Vector, const double) {}
 // CHECK: "\01?foo@@YAXPAY02NQBNN at Z"
+// X64: "\01?foo@@YAXPEAY02NQEBNN at Z"

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp?rev=181825&r1=181824&r2=181825&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp Tue May 14 15:30:42 2013
@@ -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 at VTypename@@@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$Class at VTypename@@@@QEAA at XZ"
 
   Class<const Typename> c1_const;
 // CHECK: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QEAA at XZ"
   Class<volatile Typename> c1_volatile;
 // CHECK: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QEAA at XZ"
   Class<const volatile Typename> c1_cv;
 // CHECK: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QEAA at XZ"
 
   Class<Nested<Typename> > c2;
 // CHECK: call {{.*}} @"\01??0?$Class at V?$Nested at VTypename@@@@@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$Class at V?$Nested at VTypename@@@@@@QEAA at XZ"
 
   Class<int * const> c_intpc;
 // CHECK: call {{.*}} @"\01??0?$Class at QAH@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$Class at QEAH@@QEAA at XZ"
   Class<int()> c_ft;
 // CHECK: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QEAA at XZ"
   Class<int[]> c_inti;
 // CHECK: call {{.*}} @"\01??0?$Class@$$BY0A at H@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$Class@$$BY0A at H@@QEAA at XZ"
   Class<int[5]> c_int5;
 // CHECK: call {{.*}} @"\01??0?$Class@$$BY04H@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$Class@$$BY04H@@QEAA at XZ"
   Class<const int[5]> c_intc5;
 // CHECK: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QEAA at XZ"
   Class<int * const[5]> c_intpc5;
 // CHECK: call {{.*}} @"\01??0?$Class@$$BY04QAH@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$Class@$$BY04QEAH@@QEAA at XZ"
 
   BoolTemplate<false> _false;
 // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QEAA at XZ"
 
   BoolTemplate<true> _true;
   // PR13158
   _true.Foo(1);
 // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$00@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$BoolTemplate@$00@@QEAA at XZ"
 // CHECK: call {{.*}} @"\01??$Foo at H@?$BoolTemplate@$00@@QAEXH at Z"
+// X64: call {{.*}} @"\01??$Foo at H@?$BoolTemplate@$00@@QEAAXH at Z"
 
   IntTemplate<0> zero;
 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0A@@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$IntTemplate@$0A@@@QEAA at XZ"
 
   IntTemplate<5> five;
 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$04@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$IntTemplate@$04@@QEAA at XZ"
 
   IntTemplate<11> eleven;
 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0L@@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$IntTemplate@$0L@@@QEAA at XZ"
 
   IntTemplate<256> _256;
 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0BAA@@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$IntTemplate@$0BAA@@@QEAA at XZ"
 
   IntTemplate<513> _513;
 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0CAB@@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$IntTemplate@$0CAB@@@QEAA at XZ"
 
   IntTemplate<1026> _1026;
 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0EAC@@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$IntTemplate@$0EAC@@@QEAA at XZ"
 
   IntTemplate<65535> ffff;
 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QAE at XZ"
+// X64: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QEAA at XZ"
 }
 
 namespace space {
   template<class T> const T& foo(const T& l) { return l; }
 }
 // CHECK: "\01??$foo at H@space@@YAABHABH at Z"
+// X64: "\01??$foo at H@space@@YAAEBHAEBH at 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"
 }

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms.cpp?rev=181825&r1=181824&r2=181825&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms.cpp Tue May 14 15:30:42 2013
@@ -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 at 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 at XZ"
+//X64: @"\01??0foo@@QEAA at XZ"
 
   ~foo(){}
 //CHECK: @"\01??1foo@@QAE at XZ"
+//X64: @"\01??1foo@@QEAA at XZ
 
   foo(int i){}
 //CHECK: @"\01??0foo@@QAE at H@Z"
+//X64: @"\01??0foo@@QEAA at H@Z"
 
   foo(char *q){}
 //CHECK: @"\01??0foo@@QAE at PAD@Z"
+//X64: @"\01??0foo@@QEAA at 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 at Z"
+//X64: @"\01??Hfoo@@QEAAHH at Z"
 
   foo::static_method();
 //CHECK: @"\01?static_method at foo@@SAPAV1 at XZ"
+//X64: @"\01?static_method at foo@@SAPEAV1 at 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 at Z"
+// X64: @"\01?beta@@YA_N_J_W at Z"
   alpha(0.f, 0.0);
   return false;
 }
@@ -119,17 +128,21 @@ bool __fastcall beta(long long a, wchar_
 // 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 at Z"
+// X64: @"\01?delta@@YAXQEAHAEBJ at Z"
 
 // Array mangling.
 void epsilon(int a[][10][20]) {}
 // CHECK: @"\01?epsilon@@YAXQAY19BE at H@Z"
+// X64: @"\01?epsilon@@YAXQEAY19BE at H@Z"
 
 void zeta(int (*)(int, int)) {}
 // CHECK: @"\01?zeta@@YAXP6AHHH at Z@Z"
+// X64: @"\01?zeta@@YAXP6AHHH at 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 {





More information about the cfe-commits mailing list