]> granicus.if.org Git - clang/commitdiff
MS ABI: Handle indirect field decls in template args
authorDavid Majnemer <david.majnemer@gmail.com>
Thu, 6 Feb 2014 12:46:52 +0000 (12:46 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Thu, 6 Feb 2014 12:46:52 +0000 (12:46 +0000)
Properly support fields that come from anonymous unions and structs
when used as template arguments for pointer to data member params.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@200921 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/MicrosoftMangle.cpp
test/CodeGenCXX/mangle-ms-templates-memptrs.cpp

index f02dfc72ee90661ba0055868c0e620c99433c71c..4ecbab437bc40ac73d8578156f85d89f366b07a5 100644 (file)
@@ -122,7 +122,7 @@ public:
   void mangleDeclaration(const NamedDecl *ND);
   void mangleFunctionEncoding(const FunctionDecl *FD);
   void mangleVariableEncoding(const VarDecl *VD);
-  void mangleMemberDataPointer(const CXXRecordDecl *RD, const FieldDecl *FD);
+  void mangleMemberDataPointer(const CXXRecordDecl *RD, const ValueDecl *VD);
   void mangleMemberFunctionPointer(const CXXRecordDecl *RD,
                                    const CXXMethodDecl *MD);
   void mangleVirtualMemPtrThunk(
@@ -378,7 +378,7 @@ void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
 }
 
 void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD,
-                                                      const FieldDecl *FD) {
+                                                      const ValueDecl *VD) {
   // <member-data-pointer> ::= <integer-literal>
   //                       ::= $F <number> <number>
   //                       ::= $G <number> <number> <number>
@@ -386,8 +386,8 @@ void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD,
   int64_t FieldOffset;
   int64_t VBTableOffset;
   MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel();
-  if (FD) {
-    FieldOffset = getASTContext().getFieldOffset(FD);
+  if (VD) {
+    FieldOffset = getASTContext().getFieldOffset(VD);
     assert(FieldOffset % getASTContext().getCharWidth() == 0 &&
            "cannot take address of bitfield");
     FieldOffset /= getASTContext().getCharWidth();
@@ -1083,8 +1083,9 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
   }
   case TemplateArgument::Declaration: {
     const NamedDecl *ND = cast<NamedDecl>(TA.getAsDecl());
-    if (const FieldDecl *FD = dyn_cast<FieldDecl>(ND)) {
-      mangleMemberDataPointer(cast<CXXRecordDecl>(FD->getParent()), FD);
+    if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
+      mangleMemberDataPointer(cast<CXXRecordDecl>(ND->getDeclContext()),
+                              cast<ValueDecl>(ND));
     } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
       const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
       if (MD && MD->isInstance())
index 32fcbd3d6bf0d398e116a0b6c7bc174fe7453570..21b92952d639a3c88ea8d65f931d60d89a221775 100644 (file)
@@ -10,6 +10,7 @@ struct S             { int a, b; void f(); virtual void g(); };
 struct M : A, B      { int a, b; void f(); virtual void g(); };
 struct V : virtual A { int a, b; void f(); virtual void g(); };
 struct U             { int a, b; void f(); virtual void g(); };
+struct I             { union { struct { int a, b; }; }; void f(); virtual void g(); };
 
 struct C        { virtual void f(); };
 struct D        { virtual void g(); };
@@ -27,10 +28,12 @@ void ReadFields() {
   M m;
   V v;
   U u;
+  ReadField<I, &S::a>(s);
   ReadField<S, &S::a>(s);
   ReadField<M, &M::a>(m);
   ReadField<V, &V::a>(v);
   ReadField<U, &U::a>(u);
+  ReadField<I, &S::b>(s);
   ReadField<S, &S::b>(s);
   ReadField<M, &M::b>(m);
   ReadField<V, &V::b>(v);
@@ -46,10 +49,12 @@ void ReadFields() {
 }
 
 // CHECK-LABEL: define {{.*}}ReadFields
+// CHECK: call {{.*}} @"\01??$ReadField@UI@@$03@@YAHAAUS@@@Z"
 // CHECK: call {{.*}} @"\01??$ReadField@US@@$03@@YAHAAUS@@@Z"
 // CHECK: call {{.*}} @"\01??$ReadField@UM@@$0M@@@YAHAAUM@@@Z"
 // CHECK: call {{.*}} @"\01??$ReadField@UV@@$F7A@@@YAHAAUV@@@Z"
 // CHECK: call {{.*}} @"\01??$ReadField@UU@@$G3A@A@@@YAHAAUU@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UI@@$07@@YAHAAUS@@@Z"
 // CHECK: call {{.*}} @"\01??$ReadField@US@@$07@@YAHAAUS@@@Z"
 // CHECK: call {{.*}} @"\01??$ReadField@UM@@$0BA@@@YAHAAUM@@@Z"
 // CHECK: call {{.*}} @"\01??$ReadField@UV@@$FM@A@@@YAHAAUV@@@Z"