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@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"

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@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"
 }

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@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_
 // 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 {


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to