Skip to content

Commit d722361

Browse files
Adds support to clang"s windows mangler to handle template argument values that are pointers one-past-the-end of a non-array symbol. Also improves error messages in other template argument scenarios where clang bails.
1 parent 2f55e55 commit d722361

File tree

2 files changed

+68
-15
lines changed

2 files changed

+68
-15
lines changed

clang/lib/AST/MicrosoftMangle.cpp

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1922,11 +1922,19 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
19221922
if (WithScalarType)
19231923
mangleType(T, SourceRange(), QMM_Escape);
19241924

1925-
// We don't know how to mangle past-the-end pointers yet.
1926-
if (V.isLValueOnePastTheEnd())
1927-
break;
1928-
19291925
APValue::LValueBase Base = V.getLValueBase();
1926+
1927+
// this might not cover every case but did cover issue 97756
1928+
// see test CodeGen/ms_mangler_templatearg_opte
1929+
if (V.isLValueOnePastTheEnd()) {
1930+
Out << "5E";
1931+
auto *VD = Base.dyn_cast<const ValueDecl *>();
1932+
if (VD)
1933+
mangle(VD);
1934+
Out << "@";
1935+
return;
1936+
}
1937+
19301938
if (!V.hasLValuePath() || V.getLValuePath().empty()) {
19311939
// Taking the address of a complete object has a special-case mangling.
19321940
if (Base.isNull()) {
@@ -1938,12 +1946,23 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
19381946
mangleNumber(V.getLValueOffset().getQuantity());
19391947
} else if (!V.hasLValuePath()) {
19401948
// FIXME: This can only happen as an extension. Invent a mangling.
1941-
break;
1949+
DiagnosticsEngine &Diags = Context.getDiags();
1950+
unsigned DiagID =
1951+
Diags.getCustomDiagID(DiagnosticsEngine::Error,
1952+
"cannot mangle this template argument yet "
1953+
"(extension not comaptible with ms mangler)");
1954+
Diags.Report(DiagID);
1955+
return;
19421956
} else if (auto *VD = Base.dyn_cast<const ValueDecl*>()) {
19431957
Out << "E";
19441958
mangle(VD);
19451959
} else {
1946-
break;
1960+
DiagnosticsEngine &Diags = Context.getDiags();
1961+
unsigned DiagID = Diags.getCustomDiagID(
1962+
DiagnosticsEngine::Error,
1963+
"cannot mangle this template argument yet (undeclared base)");
1964+
Diags.Report(DiagID);
1965+
return;
19471966
}
19481967
} else {
19491968
if (TAK == TplArgKind::ClassNTTP && T->isPointerType())
@@ -1988,8 +2007,14 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
19882007
Out << *I;
19892008

19902009
auto *VD = Base.dyn_cast<const ValueDecl*>();
1991-
if (!VD)
1992-
break;
2010+
if (!VD) {
2011+
DiagnosticsEngine &Diags = Context.getDiags();
2012+
unsigned DiagID = Diags.getCustomDiagID(
2013+
DiagnosticsEngine::Error,
2014+
"cannot mangle this template argument yet (null value decl)");
2015+
Diags.Report(DiagID);
2016+
return;
2017+
}
19932018
Out << (TAK == TplArgKind::ClassNTTP ? 'E' : '1');
19942019
mangle(VD);
19952020

@@ -2104,15 +2129,24 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
21042129
return;
21052130
}
21062131

2107-
case APValue::AddrLabelDiff:
2108-
case APValue::FixedPoint:
2109-
break;
2132+
case APValue::AddrLabelDiff: {
2133+
DiagnosticsEngine &Diags = Context.getDiags();
2134+
unsigned DiagID = Diags.getCustomDiagID(
2135+
DiagnosticsEngine::Error, "cannot mangle this template argument yet "
2136+
"(value type: address label diff)");
2137+
Diags.Report(DiagID);
2138+
return;
21102139
}
21112140

2112-
DiagnosticsEngine &Diags = Context.getDiags();
2113-
unsigned DiagID = Diags.getCustomDiagID(
2114-
DiagnosticsEngine::Error, "cannot mangle this template argument yet");
2115-
Diags.Report(DiagID);
2141+
case APValue::FixedPoint: {
2142+
DiagnosticsEngine &Diags = Context.getDiags();
2143+
unsigned DiagID = Diags.getCustomDiagID(
2144+
DiagnosticsEngine::Error,
2145+
"cannot mangle this template argument yet (value type: fixed point)");
2146+
Diags.Report(DiagID);
2147+
return;
2148+
}
2149+
}
21162150
}
21172151

21182152
void MicrosoftCXXNameMangler::mangleObjCProtocol(const ObjCProtocolDecl *PD) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -emit-llvm -std=c++20 -x c++ < %s | FileCheck -check-prefix=WIN64 %s
2+
3+
struct A {
4+
const int* ptr;
5+
};
6+
7+
template<A> void tfn() {};
8+
9+
// WIN64: ??$tfn@$2UA@@PEBH5CE?ints@@3QBHB06@@@@@YAXXZ
10+
constexpr int ints[] = { 1, 2, 7, 8, 9, -17, -10 }; //Note: this does NOT break the unpatched mangler
11+
12+
// WIN64: ??$tfn@$2UA@@PEBH5E?one_int@@3HB@@@@YAXXZ
13+
constexpr int one_int = 7;
14+
15+
void template_instance() {
16+
tfn<A{ints + sizeof(ints)/sizeof(int)}>();
17+
tfn<A{&one_int + 1}>();
18+
}
19+

0 commit comments

Comments
 (0)