Skip to content

Commit 45ca39d

Browse files
authored
[Support] Fix for non-constexpr __PRETTY_FUNCTION__ on older gcc (#128212)
Prior to gcc version 9, the `__PRETTY_FUNCTION__` macro was not declared constexpr. In that case, don't declare this as constexpr, and switch the static asserts to runtime asserts. Verified this should work on all supported compilers: https://godbolt.org/z/T77rvPW5z Followup to #127893 / 8a39214
1 parent 741f923 commit 45ca39d

File tree

1 file changed

+44
-14
lines changed

1 file changed

+44
-14
lines changed

llvm/include/llvm/Support/TypeName.h

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@
1313

1414
#include "llvm/ADT/StringRef.h"
1515

16+
// Versions of GCC prior to GCC 9 don't declare __PRETTY_FUNCTION__ as constexpr
17+
#if defined(__clang__) || defined(_MSC_VER) || \
18+
(defined(__GNUC__) && __GNUC__ >= 9)
19+
#define LLVM_GET_TYPE_NAME_CONSTEXPR constexpr
20+
#define LLVM_GET_TYPE_NAME_STATIC_ASSERT 1
21+
#else
22+
#define LLVM_GET_TYPE_NAME_CONSTEXPR
23+
#define LLVM_GET_TYPE_NAME_STATIC_ASSERT 0
24+
#include <cassert>
25+
#endif
26+
1627
namespace llvm {
1728

1829
/// We provide a function which tries to compute the (demangled) name of a type
@@ -25,50 +36,65 @@ namespace llvm {
2536
/// The returned StringRef will point into a static storage duration string.
2637
/// However, it may not be null terminated and may be some strangely aligned
2738
/// inner substring of a larger string.
28-
template <typename DesiredTypeName> inline constexpr StringRef getTypeName() {
39+
template <typename DesiredTypeName>
40+
inline LLVM_GET_TYPE_NAME_CONSTEXPR StringRef getTypeName() {
2941
#if defined(__clang__) || defined(__GNUC__)
30-
constexpr std::string_view Name = __PRETTY_FUNCTION__;
42+
LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Name = __PRETTY_FUNCTION__;
3143

32-
constexpr std::string_view Key = "DesiredTypeName = ";
33-
constexpr std::string_view TemplateParamsStart = Name.substr(Name.find(Key));
44+
LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Key = "DesiredTypeName = ";
45+
LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view TemplateParamsStart =
46+
Name.substr(Name.find(Key));
47+
#if LLVM_GET_TYPE_NAME_STATIC_ASSERT
3448
static_assert(!TemplateParamsStart.empty(),
3549
"Unable to find the template parameter!");
36-
constexpr std::string_view SubstitutionKey =
50+
#else
51+
assert(!TemplateParamsStart.empty() &&
52+
"Unable to find the template parameter!");
53+
#endif
54+
55+
LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view SubstitutionKey =
3756
TemplateParamsStart.substr(Key.size());
3857

58+
#if LLVM_GET_TYPE_NAME_STATIC_ASSERT
3959
// ends_with() is only available in c++20
4060
static_assert(!SubstitutionKey.empty() && SubstitutionKey.back() == ']',
4161
"Name doesn't end in the substitution key!");
62+
#else
63+
assert(!SubstitutionKey.empty() && SubstitutionKey.back() == ']' &&
64+
"Name doesn't end in the substitution key!");
65+
#endif
66+
4267
return SubstitutionKey.substr(0, SubstitutionKey.size() - 1);
4368
#elif defined(_MSC_VER)
44-
constexpr std::string_view Name = __FUNCSIG__;
69+
LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Name = __FUNCSIG__;
4570

46-
constexpr std::string_view Key = "getTypeName<";
47-
constexpr std::string_view GetTypeNameStart = Name.substr(Name.find(Key));
71+
LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Key = "getTypeName<";
72+
LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view GetTypeNameStart =
73+
Name.substr(Name.find(Key));
4874
static_assert(!GetTypeNameStart.empty(),
4975
"Unable to find the template parameter!");
50-
constexpr std::string_view SubstitutionKey =
76+
LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view SubstitutionKey =
5177
GetTypeNameStart.substr(Key.size());
5278

5379
// starts_with() only available in c++20
54-
constexpr std::string_view RmPrefixClass =
80+
LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixClass =
5581
SubstitutionKey.find("class ") == 0
5682
? SubstitutionKey.substr(sizeof("class ") - 1)
5783
: SubstitutionKey;
58-
constexpr std::string_view RmPrefixStruct =
84+
LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixStruct =
5985
RmPrefixClass.find("struct ") == 0
6086
? RmPrefixClass.substr(sizeof("struct ") - 1)
6187
: RmPrefixClass;
62-
constexpr std::string_view RmPrefixUnion =
88+
LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixUnion =
6389
RmPrefixStruct.find("union ") == 0
6490
? RmPrefixStruct.substr(sizeof("union ") - 1)
6591
: RmPrefixStruct;
66-
constexpr std::string_view RmPrefixEnum =
92+
LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixEnum =
6793
RmPrefixUnion.find("enum ") == 0
6894
? RmPrefixUnion.substr(sizeof("enum ") - 1)
6995
: RmPrefixUnion;
7096

71-
constexpr auto AnglePos = RmPrefixEnum.rfind('>');
97+
LLVM_GET_TYPE_NAME_CONSTEXPR auto AnglePos = RmPrefixEnum.rfind('>');
7298
static_assert(AnglePos != std::string_view::npos,
7399
"Unable to find the closing '>'!");
74100
return RmPrefixEnum.substr(0, AnglePos);
@@ -81,4 +107,8 @@ template <typename DesiredTypeName> inline constexpr StringRef getTypeName() {
81107

82108
} // namespace llvm
83109

110+
// Don't leak out of this header file
111+
#undef LLVM_GET_TYPE_NAME_CONSTEXPR
112+
#undef LLVM_GET_TYPE_NAME_STATIC_ASSERT
113+
84114
#endif

0 commit comments

Comments
 (0)