zequanwu updated this revision to Diff 266339.
zequanwu added a comment.

Add `19.20` version. Only add mangled type for version 19. 20 or later to be 
abi-compatible with https://godbolt.org/z/Bhc__A


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80409/new/

https://reviews.llvm.org/D80409

Files:
  clang/include/clang/Basic/LangOptions.h
  clang/lib/AST/MicrosoftMangle.cpp
  clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp

Index: clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -std=c++17 -fms-compatibility-version=19.20 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-windows-msvc | FileCheck %s
+
+template <auto a>
+class AutoParmTemplate {
+public:
+  AutoParmTemplate() {}
+};
+
+template <auto...>
+class AutoParmsTemplate {
+public:
+  AutoParmsTemplate() {}
+};
+
+void template_mangling() {
+  AutoParmTemplate<0> auto_int;
+  // CHECK: call {{.*}} @"??0?$AutoParmTemplate@$MH0A@@@QEAA@XZ"
+  AutoParmTemplate<false> auto_bool;
+  // CHECK: call {{.*}} @"??0?$AutoParmTemplate@$M_N0A@@@QEAA@XZ"
+  AutoParmTemplate<'a'> auto_char;
+  // CHECK: call {{.*}} @"??0?$AutoParmTemplate@$MD0GB@@@QEAA@XZ"
+  AutoParmTemplate<9223372036854775807LL> int64_max;
+  // CHECK: call {{.*}} @"??0?$AutoParmTemplate@$M_J0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
+  AutoParmTemplate<-9223372036854775807LL - 1LL> int64_min;
+  // CHECK: call {{.*}} @"??0?$AutoParmTemplate@$M_J0?IAAAAAAAAAAAAAAA@@@QEAA@XZ"
+  AutoParmTemplate<(unsigned long long)-1> uint64_neg_1;
+  // CHECK: call {{.*}} @"??0?$AutoParmTemplate@$M_K0?0@@QEAA@XZ"
+
+  AutoParmsTemplate<0, false, 'a'> c1;
+  // CHECK: call {{.*}} @"??0?$AutoParmsTemplate@$MH0A@$M_N0A@$MD0GB@@@QEAA@XZ"
+  AutoParmsTemplate<(unsigned long)1, 9223372036854775807LL> c2;
+  // CHECK: call {{.*}} @"??0?$AutoParmsTemplate@$MK00$M_J0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
+}
Index: clang/lib/AST/MicrosoftMangle.cpp
===================================================================
--- clang/lib/AST/MicrosoftMangle.cpp
+++ clang/lib/AST/MicrosoftMangle.cpp
@@ -378,8 +378,10 @@
   void mangleFunctionClass(const FunctionDecl *FD);
   void mangleCallingConvention(CallingConv CC);
   void mangleCallingConvention(const FunctionType *T);
-  void mangleIntegerLiteral(const llvm::APSInt &Number, bool IsBoolean);
-  void mangleExpression(const Expr *E);
+  void mangleIntegerLiteral(const llvm::APSInt &Number,
+                            const NonTypeTemplateParmDecl *PD = nullptr,
+                            QualType *TemplateArgType = nullptr);
+  void mangleExpression(const Expr *E, const NonTypeTemplateParmDecl *PD);
   void mangleThrowSpecification(const FunctionProtoType *T);
 
   void mangleTemplateArgs(const TemplateDecl *TD,
@@ -1357,24 +1359,35 @@
   mangleUnqualifiedName(TD);
 }
 
-void MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value,
-                                                   bool IsBoolean) {
-  // <integer-literal> ::= $0 <number>
-  Out << "$0";
-  // Make sure booleans are encoded as 0/1.
-  if (IsBoolean && Value.getBoolValue())
-    mangleNumber(1);
-  else if (Value.isSigned())
+void MicrosoftCXXNameMangler::mangleIntegerLiteral(
+    const llvm::APSInt &Value, const NonTypeTemplateParmDecl *PD,
+    QualType *TemplateArgType) {
+  // <integer-literal> ::= $ [<type>] 0 <number>
+  Out << "$";
+
+  // mangle argument type if parmeter is auto
+  if (getASTContext().getLangOpts().isCompatibleWithMSVC(
+          LangOptions::MSVC2019) &&
+      PD && PD->getType()->getTypeClass() == Type::Auto && TemplateArgType) {
+    Out << "M";
+    mangleType(*TemplateArgType, SourceRange(), QMM_Drop);
+  }
+
+  Out << "0";
+
+  if (Value.isSigned())
     mangleNumber(Value.getSExtValue());
   else
     mangleNumber(Value.getZExtValue());
 }
 
-void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {
+void MicrosoftCXXNameMangler::mangleExpression(
+    const Expr *E, const NonTypeTemplateParmDecl *PD) {
   // See if this is a constant expression.
   llvm::APSInt Value;
   if (E->isIntegerConstantExpr(Value, Context.getASTContext())) {
-    mangleIntegerLiteral(Value, E->getType()->isBooleanType());
+    QualType T = E->getType();
+    mangleIntegerLiteral(Value, PD, &T);
     return;
   }
 
@@ -1448,10 +1461,12 @@
     }
     break;
   }
-  case TemplateArgument::Integral:
+  case TemplateArgument::Integral: {
+    QualType T = TA.getIntegralType();
     mangleIntegerLiteral(TA.getAsIntegral(),
-                         TA.getIntegralType()->isBooleanType());
+                         cast<NonTypeTemplateParmDecl>(Parm), &T);
     break;
+  }
   case TemplateArgument::NullPtr: {
     QualType T = TA.getNullPtrType();
     if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
@@ -1473,16 +1488,18 @@
         // However, we are free to use 0 *if* we would use multiple fields for
         // non-nullptr member pointers.
         if (!RD->nullFieldOffsetIsZero()) {
-          mangleIntegerLiteral(llvm::APSInt::get(-1), /*IsBoolean=*/false);
+          mangleIntegerLiteral(llvm::APSInt::get(-1),
+                               cast<NonTypeTemplateParmDecl>(Parm), &T);
           return;
         }
       }
     }
-    mangleIntegerLiteral(llvm::APSInt::getUnsigned(0), /*IsBoolean=*/false);
+    mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
+                         cast<NonTypeTemplateParmDecl>(Parm), &T);
     break;
   }
   case TemplateArgument::Expression:
-    mangleExpression(TA.getAsExpr());
+    mangleExpression(TA.getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
     break;
   case TemplateArgument::Pack: {
     ArrayRef<TemplateArgument> TemplateArgs = TA.getPackAsArray();
@@ -1814,8 +1831,7 @@
   if (Context.getASTContext().addressSpaceMapManglingFor(AS)) {
     unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS);
     Extra.mangleSourceName("_AS");
-    Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS),
-                               /*IsBoolean*/ false);
+    Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
   } else {
     switch (AS) {
     default:
@@ -2700,8 +2716,7 @@
     Stream << "?$";
     Extra.mangleSourceName("__vector");
     Extra.mangleType(QualType(ET, 0), Range, QMM_Escape);
-    Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()),
-                               /*IsBoolean=*/false);
+    Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()));
 
     mangleArtificialTagType(TTK_Union, TemplateMangling, {"__clang"});
   }
@@ -2940,7 +2955,7 @@
   Stream << "?$";
   Extra.mangleSourceName("ocl_pipe");
   Extra.mangleType(ElementType, Range, QMM_Escape);
-  Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly()), true);
+  Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly()));
 
   mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"});
 }
@@ -2980,8 +2995,7 @@
     Extra.mangleSourceName("_UExtInt");
   else
     Extra.mangleSourceName("_ExtInt");
-  Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()),
-                             /*IsBoolean=*/false);
+  Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()));
 
   mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"});
 }
Index: clang/include/clang/Basic/LangOptions.h
===================================================================
--- clang/include/clang/Basic/LangOptions.h
+++ clang/include/clang/Basic/LangOptions.h
@@ -119,6 +119,7 @@
     MSVC2017 = 1910,
     MSVC2017_5 = 1912,
     MSVC2017_7 = 1914,
+    MSVC2019 = 1920,
   };
 
   /// Clang versions with different platform ABI conformance.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to