Skip to content

Commit 83286a1

Browse files
committed
[MS ABI] Add mangled type for auto template parameter whose argument kind is Integeral
1 parent 76e3a27 commit 83286a1

File tree

3 files changed

+86
-23
lines changed

3 files changed

+86
-23
lines changed

clang/include/clang/Basic/LangOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class LangOptions : public LangOptionsBase {
119119
MSVC2017 = 1910,
120120
MSVC2017_5 = 1912,
121121
MSVC2017_7 = 1914,
122+
MSVC2019 = 1920,
122123
};
123124

124125
/// Clang versions with different platform ABI conformance.

clang/lib/AST/MicrosoftMangle.cpp

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -378,8 +378,10 @@ class MicrosoftCXXNameMangler {
378378
void mangleFunctionClass(const FunctionDecl *FD);
379379
void mangleCallingConvention(CallingConv CC);
380380
void mangleCallingConvention(const FunctionType *T);
381-
void mangleIntegerLiteral(const llvm::APSInt &Number, bool IsBoolean);
382-
void mangleExpression(const Expr *E);
381+
void mangleIntegerLiteral(const llvm::APSInt &Number,
382+
const NonTypeTemplateParmDecl *PD = nullptr,
383+
QualType TemplateArgType = QualType());
384+
void mangleExpression(const Expr *E, const NonTypeTemplateParmDecl *PD);
383385
void mangleThrowSpecification(const FunctionProtoType *T);
384386

385387
void mangleTemplateArgs(const TemplateDecl *TD,
@@ -1357,24 +1359,36 @@ MicrosoftCXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *TD) {
13571359
mangleUnqualifiedName(TD);
13581360
}
13591361

1360-
void MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value,
1361-
bool IsBoolean) {
1362+
void MicrosoftCXXNameMangler::mangleIntegerLiteral(
1363+
const llvm::APSInt &Value, const NonTypeTemplateParmDecl *PD,
1364+
QualType TemplateArgType) {
13621365
// <integer-literal> ::= $0 <number>
1363-
Out << "$0";
1364-
// Make sure booleans are encoded as 0/1.
1365-
if (IsBoolean && Value.getBoolValue())
1366-
mangleNumber(1);
1367-
else if (Value.isSigned())
1366+
Out << "$";
1367+
1368+
// Since MSVC 2019, add 'M[<type>]' after '$' for auto template parameter when
1369+
// argument is integer.
1370+
if (getASTContext().getLangOpts().isCompatibleWithMSVC(
1371+
LangOptions::MSVC2019) &&
1372+
PD && PD->getType()->getTypeClass() == Type::Auto &&
1373+
!TemplateArgType.isNull()) {
1374+
Out << "M";
1375+
mangleType(TemplateArgType, SourceRange(), QMM_Drop);
1376+
}
1377+
1378+
Out << "0";
1379+
1380+
if (Value.isSigned())
13681381
mangleNumber(Value.getSExtValue());
13691382
else
13701383
mangleNumber(Value.getZExtValue());
13711384
}
13721385

1373-
void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {
1386+
void MicrosoftCXXNameMangler::mangleExpression(
1387+
const Expr *E, const NonTypeTemplateParmDecl *PD) {
13741388
// See if this is a constant expression.
13751389
if (Optional<llvm::APSInt> Value =
13761390
E->getIntegerConstantExpr(Context.getASTContext())) {
1377-
mangleIntegerLiteral(*Value, E->getType()->isBooleanType());
1391+
mangleIntegerLiteral(*Value, PD, E->getType());
13781392
return;
13791393
}
13801394

@@ -1448,10 +1462,12 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
14481462
}
14491463
break;
14501464
}
1451-
case TemplateArgument::Integral:
1465+
case TemplateArgument::Integral: {
1466+
QualType T = TA.getIntegralType();
14521467
mangleIntegerLiteral(TA.getAsIntegral(),
1453-
TA.getIntegralType()->isBooleanType());
1468+
cast<NonTypeTemplateParmDecl>(Parm), T);
14541469
break;
1470+
}
14551471
case TemplateArgument::NullPtr: {
14561472
QualType T = TA.getNullPtrType();
14571473
if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
@@ -1473,16 +1489,18 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
14731489
// However, we are free to use 0 *if* we would use multiple fields for
14741490
// non-nullptr member pointers.
14751491
if (!RD->nullFieldOffsetIsZero()) {
1476-
mangleIntegerLiteral(llvm::APSInt::get(-1), /*IsBoolean=*/false);
1492+
mangleIntegerLiteral(llvm::APSInt::get(-1),
1493+
cast<NonTypeTemplateParmDecl>(Parm), T);
14771494
return;
14781495
}
14791496
}
14801497
}
1481-
mangleIntegerLiteral(llvm::APSInt::getUnsigned(0), /*IsBoolean=*/false);
1498+
mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),
1499+
cast<NonTypeTemplateParmDecl>(Parm), T);
14821500
break;
14831501
}
14841502
case TemplateArgument::Expression:
1485-
mangleExpression(TA.getAsExpr());
1503+
mangleExpression(TA.getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));
14861504
break;
14871505
case TemplateArgument::Pack: {
14881506
ArrayRef<TemplateArgument> TemplateArgs = TA.getPackAsArray();
@@ -1814,8 +1832,7 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
18141832
if (Context.getASTContext().addressSpaceMapManglingFor(AS)) {
18151833
unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS);
18161834
Extra.mangleSourceName("_AS");
1817-
Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS),
1818-
/*IsBoolean*/ false);
1835+
Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));
18191836
} else {
18201837
switch (AS) {
18211838
default:
@@ -2707,8 +2724,7 @@ void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals,
27072724
Stream << "?$";
27082725
Extra.mangleSourceName("__vector");
27092726
Extra.mangleType(QualType(ET, 0), Range, QMM_Escape);
2710-
Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()),
2711-
/*IsBoolean=*/false);
2727+
Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()));
27122728

27132729
mangleArtificialTagType(TTK_Union, TemplateMangling, {"__clang"});
27142730
}
@@ -2947,7 +2963,7 @@ void MicrosoftCXXNameMangler::mangleType(const PipeType *T, Qualifiers,
29472963
Stream << "?$";
29482964
Extra.mangleSourceName("ocl_pipe");
29492965
Extra.mangleType(ElementType, Range, QMM_Escape);
2950-
Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly()), true);
2966+
Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly()));
29512967

29522968
mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"});
29532969
}
@@ -2987,8 +3003,7 @@ void MicrosoftCXXNameMangler::mangleType(const ExtIntType *T, Qualifiers,
29873003
Extra.mangleSourceName("_UExtInt");
29883004
else
29893005
Extra.mangleSourceName("_ExtInt");
2990-
Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()),
2991-
/*IsBoolean=*/false);
3006+
Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()));
29923007

29933008
mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"});
29943009
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// 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 --check-prefix=AFTER %s
2+
// RUN: %clang_cc1 -std=c++17 -fms-compatibility-version=19.14 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-windows-msvc | FileCheck --check-prefix=BEFORE %s
3+
4+
template <auto a>
5+
class AutoParmTemplate {
6+
public:
7+
AutoParmTemplate() {}
8+
};
9+
10+
template <auto...>
11+
class AutoParmsTemplate {
12+
public:
13+
AutoParmsTemplate() {}
14+
};
15+
16+
template <auto a>
17+
auto AutoFunc() {
18+
return a;
19+
}
20+
21+
void template_mangling() {
22+
AutoFunc<1>();
23+
// AFTER: call {{.*}} @"??$AutoFunc@$MH00@@YA?A?<auto>@@XZ"
24+
// BEFORE: call {{.*}} @"??$AutoFunc@$00@@YA?A?<auto>@@XZ"
25+
AutoParmTemplate<0> auto_int;
26+
// AFTER: call {{.*}} @"??0?$AutoParmTemplate@$MH0A@@@QEAA@XZ"
27+
// BEFORE: call {{.*}} @"??0?$AutoParmTemplate@$0A@@@QEAA@XZ"
28+
AutoParmTemplate<'a'> auto_char;
29+
// AFTER: call {{.*}} @"??0?$AutoParmTemplate@$MD0GB@@@QEAA@XZ"
30+
// BEFORE: call {{.*}} @"??0?$AutoParmTemplate@$0GB@@@QEAA@XZ"
31+
AutoParmTemplate<9223372036854775807LL> int64_max;
32+
// AFTER: call {{.*}} @"??0?$AutoParmTemplate@$M_J0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
33+
// BEFORE: call {{.*}} @"??0?$AutoParmTemplate@$0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
34+
AutoParmTemplate<-9223372036854775807LL - 1LL> int64_min;
35+
// AFTER: call {{.*}} @"??0?$AutoParmTemplate@$M_J0?IAAAAAAAAAAAAAAA@@@QEAA@XZ"
36+
// BEFORE: call {{.*}} @"??0?$AutoParmTemplate@$0?IAAAAAAAAAAAAAAA@@@QEAA@XZ"
37+
AutoParmTemplate<(unsigned long long)-1> uint64_neg_1;
38+
// AFTER: call {{.*}} @"??0?$AutoParmTemplate@$M_K0?0@@QEAA@XZ"
39+
// BEFORE: call {{.*}} @"??0?$AutoParmTemplate@$0?0@@QEAA@XZ"
40+
41+
AutoParmsTemplate<0, false, 'a'> c1;
42+
// AFTER: call {{.*}} @"??0?$AutoParmsTemplate@$MH0A@$M_N0A@$MD0GB@@@QEAA@XZ"
43+
// BEFORE: call {{.*}} @"??0?$AutoParmsTemplate@$0A@$0A@$0GB@@@QEAA@XZ"
44+
AutoParmsTemplate<(unsigned long)1, 9223372036854775807LL> c2;
45+
// AFTER: call {{.*}} @"??0?$AutoParmsTemplate@$MK00$M_J0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
46+
// BEFORE: call {{.*}} @"??0?$AutoParmsTemplate@$00$0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
47+
}

0 commit comments

Comments
 (0)