r200920 - MS ABI: Tweak pointer-to-member mangling/inheritance model selection

David Majnemer david.majnemer at gmail.com
Thu Feb 6 02:59:20 PST 2014


Author: majnemer
Date: Thu Feb  6 04:59:19 2014
New Revision: 200920

URL: http://llvm.org/viewvc/llvm-project?rev=200920&view=rev
Log:
MS ABI: Tweak pointer-to-member mangling/inheritance model selection

Properly determine the inheritance model when dealing with nullptr:
- If a nullptr template argument is being checked against
  pointer-to-member parameter, nail down an inheritance model.
  N.B. We will chose an inheritance model even if we won't ultimately
  choose the template to instantiate!  Cooky, right?
- Null pointer-to-datamembers have a virtual base table offset of -1,
  not zero. Previously, we chose an offset of 0.

Modified:
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/lib/Sema/SemaCast.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=200920&r1=200919&r2=200920&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Thu Feb  6 04:59:19 2014
@@ -383,43 +383,38 @@ void MicrosoftCXXNameMangler::mangleMemb
   //                       ::= $F <number> <number>
   //                       ::= $G <number> <number> <number>
 
-  int64_t FO = 0;
+  int64_t FieldOffset;
+  int64_t VBTableOffset;
   MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel();
   if (FD) {
-    FO = getASTContext().getFieldOffset(FD);
-    assert(FO % getASTContext().getCharWidth() == 0 &&
+    FieldOffset = getASTContext().getFieldOffset(FD);
+    assert(FieldOffset % getASTContext().getCharWidth() == 0 &&
            "cannot take address of bitfield");
-    FO /= getASTContext().getCharWidth();
-  } else if (!RD->nullFieldOffsetIsZero()) {
-    FO = -1;
+    FieldOffset /= getASTContext().getCharWidth();
+
+    VBTableOffset = 0;
+  } else {
+    FieldOffset = RD->nullFieldOffsetIsZero() ? 0 : -1;
+
+    VBTableOffset = -1;
   }
 
+  char Code = '\0';
   switch (IM) {
-  case MSInheritanceAttr::Keyword_single_inheritance:
-  case MSInheritanceAttr::Keyword_multiple_inheritance: {
-    // If we only have a single field, it's just an integer literal.
-    llvm::APSInt Val(64, /*isUnsigned=*/false);
-    Val = FO;
-    mangleIntegerLiteral(Val, /*IsBoolean=*/false);
-    break;
+  case MSInheritanceAttr::Keyword_single_inheritance:      Code = '0'; break;
+  case MSInheritanceAttr::Keyword_multiple_inheritance:    Code = '0'; break;
+  case MSInheritanceAttr::Keyword_virtual_inheritance:     Code = 'F'; break;
+  case MSInheritanceAttr::Keyword_unspecified_inheritance: Code = 'G'; break;
   }
 
-  // Otherwise, we have an aggregate, but all adjusting fields should be zero,
-  // because we don't allow casts (even implicit) in the context of a template
-  // argument.
-  case MSInheritanceAttr::Keyword_virtual_inheritance:
-    Out << "$F";
-    mangleNumber(FO);
-    mangleNumber(0);
-    break;
+  Out << '$' << Code;
 
-  case MSInheritanceAttr::Keyword_unspecified_inheritance:
-    Out << "$G";
-    mangleNumber(FO);
-    mangleNumber(0);
+  mangleNumber(FieldOffset);
+
+  if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
     mangleNumber(0);
-    break;
-  }
+  if (MSInheritanceAttr::hasVBTableOffsetField(IM))
+    mangleNumber(VBTableOffset);
 }
 
 void
@@ -455,9 +450,7 @@ MicrosoftCXXNameMangler::mangleMemberFun
   // thunk.
   uint64_t NVOffset = 0;
   uint64_t VBTableOffset = 0;
-  if (!MD) {
-    mangleNumber(0);
-  } else if (MD->isVirtual()) {
+  if (MD->isVirtual()) {
     MicrosoftVTableContext *VTContext =
         cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
     const MicrosoftVTableContext::MethodVFTableLocation &ML =
@@ -1110,7 +1103,7 @@ void MicrosoftCXXNameMangler::mangleTemp
   case TemplateArgument::NullPtr: {
     QualType T = TA.getNullPtrType();
     if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
-      const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+      const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
       if (MPT->isMemberFunctionPointerType())
         mangleMemberFunctionPointer(RD, 0);
       else

Modified: cfe/trunk/lib/Sema/SemaCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCast.cpp?rev=200920&r1=200919&r2=200920&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCast.cpp Thu Feb  6 04:59:19 2014
@@ -1433,6 +1433,10 @@ TryStaticImplicitCast(Sema &Self, ExprRe
       msg = 0;
       return TC_Failed;
     }
+  } else if (DestType->isMemberPointerType()) {
+    if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+      Self.RequireCompleteType(OpRange.getBegin(), DestType, 0);
+    }
   }
 
   InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=200920&r1=200919&r2=200920&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Feb  6 04:59:19 2014
@@ -20,6 +20,7 @@
 #include "clang/AST/TypeVisitor.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/TargetInfo.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/ParsedTemplate.h"
@@ -4529,6 +4530,8 @@ static bool CheckTemplateArgumentPointer
   case NPV_NullPointer:
     S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null);
     Converted = TemplateArgument(ParamType, /*isNullPtr*/true);
+    if (S.Context.getTargetInfo().getCXXABI().isMicrosoft())
+      S.RequireCompleteType(Arg->getExprLoc(), ParamType, 0);
     return false;
   case NPV_NotNullPointer:
     break;

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp?rev=200920&r1=200919&r2=200920&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp Thu Feb  6 04:59:19 2014
@@ -59,8 +59,8 @@ void ReadFields() {
 // them right in class templates.
 // CHECK: call {{.*}} @"\01??$ReadField at US@@$0A@@@YAHAAUS@@@Z"
 // CHECK: call {{.*}} @"\01??$ReadField at UM@@$0A@@@YAHAAUM@@@Z"
-// CHECK: call {{.*}} @"\01??$ReadField at UV@@$FA at A@@@YAHAAUV@@@Z"
-// CHECK: call {{.*}} @"\01??$ReadField at UU@@$GA at A@A@@@YAHAAUU@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField at UV@@$FA@?0@@YAHAAUV@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField at UU@@$GA at A@?0@@YAHAAUU@@@Z"
 
 // Non-polymorphic null data memptr vs first field memptr.  MSVC mangles these
 // the same.





More information about the cfe-commits mailing list