Skip to content

Commit

Permalink
DWARF Simplified Template Names: Narrow down the handling for operato…
Browse files Browse the repository at this point in the history
…r overloads

Actually we can, for now, remove the explicit "operator" handling
entirely - since clang currently won't try to flag any of these as
rebuildable. That seems like a reasonable state for now, but it could be
narrowed down to only apply to conversion operators, most likely - but
would need more nuance for op> and op>> since they would be incorrectly
flagged as already having their template arguments (due to the trailing
'>').
  • Loading branch information
dwblaikie committed Nov 5, 2021
1 parent d24a0e8 commit f57d0e2
Show file tree
Hide file tree
Showing 3 changed files with 12,080 additions and 14 deletions.
@@ -1,5 +1,6 @@
// RUN: %clang %target_itanium_abi_host_triple %s -c -o - -g -Xclang -gsimple-template-names=mangled -Xclang -debug-forward-template-params \
// RUN: %clang %target_itanium_abi_host_triple %s -c -o - -g -Xclang -gsimple-template-names=mangled -Xclang -debug-forward-template-params -std=c++20 \
// RUN: | llvm-dwarfdump --verify -
#include <cstdint>
template<typename ...Ts>
struct t1 {
};
Expand Down Expand Up @@ -67,7 +68,70 @@ struct t6 {
operator t1<float>*() {
return nullptr;
}
template<typename T>
void operator-(int) {
}
template<typename T>
void operator*(int) {
}
template<typename T>
void operator/(int) {
}
template<typename T>
void operator%(int) {
}
template<typename T>
void operator^(int) {
}
template<typename T>
void operator&(int) {
}
template<typename T>
void operator|(int) {
}
template<typename T>
void operator~() {
}
template<typename T>
void operator!() {
}
template<typename T>
void operator=(int) {
}
template<typename T>
void operator>(int) {
}
template<typename T>
void operator,(int) {
}
template<typename T>
void operator()() {
}
template<typename T>
void operator[](int) {
}
template<typename T>
void operator<=>(int) {
}
template<typename T>
void* operator new(std::size_t, T) {
__builtin_unreachable();
}
template<typename T>
void operator delete(void*, T) {
}
template<typename T>
void* operator new[](std::size_t, T) {
__builtin_unreachable();
}
template<typename T>
void operator delete[](void*, T) {
}
template<typename T>
int operator co_await() { __builtin_unreachable(); }

};
void operator"" _suff(unsigned long long) {}
template<template<typename...> class T> void f7() { }
template<template<typename...> class T, typename T2> void f8() { }
template<typename T>
Expand All @@ -94,6 +158,11 @@ struct t10 {
template<typename T = void>
t10() { }
};

template<typename T>
void operator_not_really() {
}

int main() {
struct { } A;
auto L = []{};
Expand Down Expand Up @@ -127,7 +196,7 @@ int main() {
f3<decltype(ns::AnonEnum1), ns::AnonEnum3, (decltype(ns::AnonEnum1))2>();
f3<int*, &i>();
f3<int*, nullptr>();
// t4<3> v2;
t4<3> v2;
f3<unsigned long, 1>();
f3<unsigned long long, 1>();
f3<long, 1>();
Expand Down Expand Up @@ -169,6 +238,27 @@ int main() {
v6.operator< <int>(1);
v6.operator<= <int>(1);
v6.operator t1<float>*();
v6.operator- <int>(3);
v6.operator* <int>(3);
v6.operator/ <int>(3);
v6.operator% <int>(3);
v6.operator^ <int>(3);
v6.operator& <int>(3);
v6.operator| <int>(3);
v6.operator~ <int>();
v6.operator! <int>();
v6.operator= <int>(3);
v6.operator> <int>(3);
v6.operator, <int>(3);
v6.operator() <int>();
v6.operator[] <int>(3);
v6.operator<=> <int>(3);
t6::operator new(0, 0);
t6::operator new[](0, 0);
t6::operator delete(nullptr, 0);
t6::operator delete[](nullptr, 0);
v6.operator co_await<int>();
42_suff;
struct t7 { };
f1<t7>();
f1<int(&)[3]>();
Expand Down Expand Up @@ -207,6 +297,7 @@ int main() {
struct t8 { decltype(A) m; };
f1<void(t8, decltype(A))>();
f1<void(t8)>();
operator_not_really<int>();
}
void t8::mem() {
struct t7 { };
Expand Down
25 changes: 13 additions & 12 deletions llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
Expand Up @@ -305,18 +305,19 @@ struct DWARFTypePrinter {
} else
EndedWithTemplate = Name.endswith(">");
OS << Name;
// FIXME: This needs to be a bit more narrow, it would fail to
// reconstitute a non-operator overload that is a template, like
// "operator_thing<int>"
if (!Name.endswith(">") && !Name.startswith("operator")) {
if (appendTemplateParameters(D)) {
if (EndedWithTemplate)
OS << ' ';
OS << '>';
EndedWithTemplate = true;
Word = true;
}
}
// This check would be insufficient for operator overloads like
// "operator>>" - but for now Clang doesn't try to simplify them, so this
// is OK. Add more nuanced operator overload handling here if/when needed.
if (Name.endswith(">"))
break;
if (!appendTemplateParameters(D))
break;

if (EndedWithTemplate)
OS << ' ';
OS << '>';
EndedWithTemplate = true;
Word = true;
break;
}
}
Expand Down

0 comments on commit f57d0e2

Please sign in to comment.