@@ -13,6 +13,17 @@ |
| | | |
---|
| #include "llvm/ADT/StringRef.h" | | #include "llvm/ADT/StringRef.h" |
---|
| | | |
---|
| | | +// Versions of GCC prior to GCC 9 don't declare __PRETTY_FUNCTION__ as constexpr |
---|
| | | +#if defined(__clang__) || defined(_MSC_VER) || \ |
---|
| | | + (defined(__GNUC__) && __GNUC__ >= 9) |
---|
| | | +#define LLVM_GET_TYPE_NAME_CONSTEXPR constexpr |
---|
| | | +#define LLVM_GET_TYPE_NAME_STATIC_ASSERT 1 |
---|
| | | +#else |
---|
| | | +#define LLVM_GET_TYPE_NAME_CONSTEXPR |
---|
| | | +#define LLVM_GET_TYPE_NAME_STATIC_ASSERT 0 |
---|
| | | +#include <cassert> |
---|
| | | +#endif |
---|
| | | + |
---|
| namespace llvm { | | namespace llvm { |
---|
| | | |
---|
| /// We provide a function which tries to compute the (demangled) name of a type | | /// We provide a function which tries to compute the (demangled) name of a type |
---|
@@ -25,50 +36,65 @@ namespace llvm { |
| /// The returned StringRef will point into a static storage duration string. | | /// The returned StringRef will point into a static storage duration string. |
---|
| /// However, it may not be null terminated and may be some strangely aligned | | /// However, it may not be null terminated and may be some strangely aligned |
---|
| /// inner substring of a larger string. | | /// inner substring of a larger string. |
---|
| -template <typename DesiredTypeName> inline constexpr StringRef getTypeName() { | | +template <typename DesiredTypeName> |
---|
| | | +inline LLVM_GET_TYPE_NAME_CONSTEXPR StringRef getTypeName() { |
---|
| #if defined(__clang__) || defined(__GNUC__) | | #if defined(__clang__) || defined(__GNUC__) |
---|
| - constexpr std::string_view Name = __PRETTY_FUNCTION__; | | + LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Name = __PRETTY_FUNCTION__; |
---|
| | | |
---|
| - constexpr std::string_view Key = "DesiredTypeName = "; | | + LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Key = "DesiredTypeName = "; |
---|
| - constexpr std::string_view TemplateParamsStart = Name.substr(Name.find(Key)); | | + LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view TemplateParamsStart = |
---|
| | | + Name.substr(Name.find(Key)); |
---|
| | | +#if LLVM_GET_TYPE_NAME_STATIC_ASSERT |
---|
| static_assert(!TemplateParamsStart.empty(), | | static_assert(!TemplateParamsStart.empty(), |
---|
| "Unable to find the template parameter!"); | | "Unable to find the template parameter!"); |
---|
| - constexpr std::string_view SubstitutionKey = | | +#else |
---|
| | | + assert(!TemplateParamsStart.empty() && |
---|
| | | + "Unable to find the template parameter!"); |
---|
| | | +#endif |
---|
| | | + |
---|
| | | + LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view SubstitutionKey = |
---|
| TemplateParamsStart.substr(Key.size()); | | TemplateParamsStart.substr(Key.size()); |
---|
| | | |
---|
| | | +#if LLVM_GET_TYPE_NAME_STATIC_ASSERT |
---|
| // ends_with() is only available in c++20 | | // ends_with() is only available in c++20 |
---|
| static_assert(!SubstitutionKey.empty() && SubstitutionKey.back() == ']', | | static_assert(!SubstitutionKey.empty() && SubstitutionKey.back() == ']', |
---|
| "Name doesn't end in the substitution key!"); | | "Name doesn't end in the substitution key!"); |
---|
| | | +#else |
---|
| | | + assert(!SubstitutionKey.empty() && SubstitutionKey.back() == ']' && |
---|
| | | + "Name doesn't end in the substitution key!"); |
---|
| | | +#endif |
---|
| | | + |
---|
| return SubstitutionKey.substr(0, SubstitutionKey.size() - 1); | | return SubstitutionKey.substr(0, SubstitutionKey.size() - 1); |
---|
| #elif defined(_MSC_VER) | | #elif defined(_MSC_VER) |
---|
| - constexpr std::string_view Name = __FUNCSIG__; | | + LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Name = __FUNCSIG__; |
---|
| | | |
---|
| - constexpr std::string_view Key = "getTypeName<"; | | + LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Key = "getTypeName<"; |
---|
| - constexpr std::string_view GetTypeNameStart = Name.substr(Name.find(Key)); | | + LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view GetTypeNameStart = |
---|
| | | + Name.substr(Name.find(Key)); |
---|
| static_assert(!GetTypeNameStart.empty(), | | static_assert(!GetTypeNameStart.empty(), |
---|
| "Unable to find the template parameter!"); | | "Unable to find the template parameter!"); |
---|
| - constexpr std::string_view SubstitutionKey = | | + LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view SubstitutionKey = |
---|
| GetTypeNameStart.substr(Key.size()); | | GetTypeNameStart.substr(Key.size()); |
---|
| | | |
---|
| // starts_with() only available in c++20 | | // starts_with() only available in c++20 |
---|
| - constexpr std::string_view RmPrefixClass = | | + LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixClass = |
---|
| SubstitutionKey.find("class ") == 0 | | SubstitutionKey.find("class ") == 0 |
---|
| ? SubstitutionKey.substr(sizeof("class ") - 1) | | ? SubstitutionKey.substr(sizeof("class ") - 1) |
---|
| : SubstitutionKey; | | : SubstitutionKey; |
---|
| - constexpr std::string_view RmPrefixStruct = | | + LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixStruct = |
---|
| RmPrefixClass.find("struct ") == 0 | | RmPrefixClass.find("struct ") == 0 |
---|
| ? RmPrefixClass.substr(sizeof("struct ") - 1) | | ? RmPrefixClass.substr(sizeof("struct ") - 1) |
---|
| : RmPrefixClass; | | : RmPrefixClass; |
---|
| - constexpr std::string_view RmPrefixUnion = | | + LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixUnion = |
---|
| RmPrefixStruct.find("union ") == 0 | | RmPrefixStruct.find("union ") == 0 |
---|
| ? RmPrefixStruct.substr(sizeof("union ") - 1) | | ? RmPrefixStruct.substr(sizeof("union ") - 1) |
---|
| : RmPrefixStruct; | | : RmPrefixStruct; |
---|
| - constexpr std::string_view RmPrefixEnum = | | + LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixEnum = |
---|
| RmPrefixUnion.find("enum ") == 0 | | RmPrefixUnion.find("enum ") == 0 |
---|
| ? RmPrefixUnion.substr(sizeof("enum ") - 1) | | ? RmPrefixUnion.substr(sizeof("enum ") - 1) |
---|
| : RmPrefixUnion; | | : RmPrefixUnion; |
---|
| | | |
---|
| - constexpr auto AnglePos = RmPrefixEnum.rfind('>'); | | + LLVM_GET_TYPE_NAME_CONSTEXPR auto AnglePos = RmPrefixEnum.rfind('>'); |
---|
| static_assert(AnglePos != std::string_view::npos, | | static_assert(AnglePos != std::string_view::npos, |
---|
| "Unable to find the closing '>'!"); | | "Unable to find the closing '>'!"); |
---|
| return RmPrefixEnum.substr(0, AnglePos); | | return RmPrefixEnum.substr(0, AnglePos); |
---|
@@ -81,4 +107,8 @@ template <typename DesiredTypeName> inline constexpr StringRef getTypeName() { |
| | | |
---|
| } // namespace llvm | | } // namespace llvm |
---|
| | | |
---|
| | | +// Don't leak out of this header file |
---|
| | | +#undef LLVM_GET_TYPE_NAME_CONSTEXPR |
---|
| | | +#undef LLVM_GET_TYPE_NAME_STATIC_ASSERT |
---|
| | | + |
---|
| #endif | | #endif |
---|