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+
1627namespace 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