Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Support] Fix for non-constexpr __PRETTY_FUNCTION__ on older gcc #128212

Merged
merged 1 commit into from
Feb 21, 2025

Conversation

rupprecht
Copy link
Collaborator

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

…rsions

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
@llvmbot
Copy link
Member

llvmbot commented Feb 21, 2025

@llvm/pr-subscribers-llvm-support

Author: Jordan Rupprecht (rupprecht)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/128212.diff

1 Files Affected:

  • (modified) llvm/include/llvm/Support/TypeName.h (+44-14)
diff --git a/llvm/include/llvm/Support/TypeName.h b/llvm/include/llvm/Support/TypeName.h
index c50d67dc38635..85612650ce897 100644
--- a/llvm/include/llvm/Support/TypeName.h
+++ b/llvm/include/llvm/Support/TypeName.h
@@ -13,6 +13,17 @@
 
 #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 {
 
 /// 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.
 /// However, it may not be null terminated and may be some strangely aligned
 /// 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__)
-  constexpr std::string_view Name = __PRETTY_FUNCTION__;
+  LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Name = __PRETTY_FUNCTION__;
 
-  constexpr std::string_view Key = "DesiredTypeName = ";
-  constexpr std::string_view TemplateParamsStart = Name.substr(Name.find(Key));
+  LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Key = "DesiredTypeName = ";
+  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(),
                 "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());
 
+#if LLVM_GET_TYPE_NAME_STATIC_ASSERT
   // ends_with() is only available in c++20
   static_assert(!SubstitutionKey.empty() && SubstitutionKey.back() == ']',
                 "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);
 #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<";
-  constexpr std::string_view GetTypeNameStart = Name.substr(Name.find(Key));
+  LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Key = "getTypeName<";
+  LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view GetTypeNameStart =
+      Name.substr(Name.find(Key));
   static_assert(!GetTypeNameStart.empty(),
                 "Unable to find the template parameter!");
-  constexpr std::string_view SubstitutionKey =
+  LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view SubstitutionKey =
       GetTypeNameStart.substr(Key.size());
 
   // 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.substr(sizeof("class ") - 1)
           : SubstitutionKey;
-  constexpr std::string_view RmPrefixStruct =
+  LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixStruct =
       RmPrefixClass.find("struct ") == 0
           ? RmPrefixClass.substr(sizeof("struct ") - 1)
           : RmPrefixClass;
-  constexpr std::string_view RmPrefixUnion =
+  LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixUnion =
       RmPrefixStruct.find("union ") == 0
           ? RmPrefixStruct.substr(sizeof("union ") - 1)
           : RmPrefixStruct;
-  constexpr std::string_view RmPrefixEnum =
+  LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixEnum =
       RmPrefixUnion.find("enum ") == 0
           ? RmPrefixUnion.substr(sizeof("enum ") - 1)
           : RmPrefixUnion;
 
-  constexpr auto AnglePos = RmPrefixEnum.rfind('>');
+  LLVM_GET_TYPE_NAME_CONSTEXPR auto AnglePos = RmPrefixEnum.rfind('>');
   static_assert(AnglePos != std::string_view::npos,
                 "Unable to find the closing '>'!");
   return RmPrefixEnum.substr(0, AnglePos);
@@ -81,4 +107,8 @@ template <typename DesiredTypeName> inline constexpr StringRef getTypeName() {
 
 } // namespace llvm
 
+// Don't leak out of this header file
+#undef LLVM_GET_TYPE_NAME_CONSTEXPR
+#undef LLVM_GET_TYPE_NAME_STATIC_ASSERT
+
 #endif

Copy link
Contributor

@jplehr jplehr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@rupprecht rupprecht merged commit 45ca39d into llvm:main Feb 21, 2025
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants