LLVM 24.0.0git
TypeName.h
Go to the documentation of this file.
1//===- TypeName.h -----------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_SUPPORT_TYPENAME_H
10#define LLVM_SUPPORT_TYPENAME_H
11
12#include <cassert>
13#include <string_view>
14
15#include "llvm/ADT/StringRef.h"
16
17// Versions of GCC prior to GCC 9 don't declare __PRETTY_FUNCTION__ as
18// constexpr, and versions of MSVC prior to VS2017 15.3 (_MSC_VER 1910) don't
19// declare __FUNCSIG__ as constexpr.
20#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 9) || \
21 (defined(_MSC_VER) && _MSC_VER >= 1910)
22#define LLVM_GET_TYPE_NAME_CONSTEXPR constexpr
23#define LLVM_GET_TYPE_NAME_STATIC_ASSERT 1
24#else
25#define LLVM_GET_TYPE_NAME_CONSTEXPR
26#define LLVM_GET_TYPE_NAME_STATIC_ASSERT 0
27#endif
28
29namespace llvm {
30
31/// We provide a function which tries to compute the (demangled) name of a type
32/// statically.
33///
34/// This routine may fail on some platforms or for particularly unusual types.
35/// Do not use it for anything other than logging and debugging aids. It isn't
36/// portable or dependendable in any real sense.
37///
38/// The returned StringRef will point into a static storage duration string.
39/// However, it may not be null terminated and may be some strangely aligned
40/// inner substring of a larger string.
41template <typename DesiredTypeName>
43#if defined(__clang__) || defined(__GNUC__)
44 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Name = __PRETTY_FUNCTION__;
45
46 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Key = "DesiredTypeName = ";
47 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view::size_type KeyPos =
48 Name.find(Key);
49#if LLVM_GET_TYPE_NAME_STATIC_ASSERT
50 static_assert(KeyPos != std::string_view::npos,
51 "Unable to find the template parameter!");
52#else
53 assert(KeyPos != std::string_view::npos &&
54 "Unable to find the template parameter!");
55#endif
56
57 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view TemplateParamsStart =
58 Name.substr(KeyPos);
59
60 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view SubstitutionKey =
61 TemplateParamsStart.substr(Key.size());
62
63#if LLVM_GET_TYPE_NAME_STATIC_ASSERT
64 // ends_with() is only available in c++20
65 static_assert(!SubstitutionKey.empty() && SubstitutionKey.back() == ']',
66 "Name doesn't end in the substitution key!");
67#else
68 assert(!SubstitutionKey.empty() && SubstitutionKey.back() == ']' &&
69 "Name doesn't end in the substitution key!");
70#endif
71
72 return SubstitutionKey.substr(0, SubstitutionKey.size() - 1);
73#elif defined(_MSC_VER)
74 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Name = __FUNCSIG__;
75
76 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view Key = "getTypeName<";
77 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view::size_type KeyPos =
78 Name.find(Key);
79#if LLVM_GET_TYPE_NAME_STATIC_ASSERT
80 static_assert(KeyPos != std::string_view::npos,
81 "Unable to find the template parameter!");
82#else
83 assert(KeyPos != std::string_view::npos &&
84 "Unable to find the template parameter!");
85#endif
86
87 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view GetTypeNameStart =
88 Name.substr(KeyPos);
89
90 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view SubstitutionKey =
91 GetTypeNameStart.substr(Key.size());
92
93 // starts_with() only available in c++20
94 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixClass =
95 SubstitutionKey.find("class ") == 0
96 ? SubstitutionKey.substr(sizeof("class ") - 1)
97 : SubstitutionKey;
98 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixStruct =
99 RmPrefixClass.find("struct ") == 0
100 ? RmPrefixClass.substr(sizeof("struct ") - 1)
101 : RmPrefixClass;
102 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixUnion =
103 RmPrefixStruct.find("union ") == 0
104 ? RmPrefixStruct.substr(sizeof("union ") - 1)
105 : RmPrefixStruct;
106 LLVM_GET_TYPE_NAME_CONSTEXPR std::string_view RmPrefixEnum =
107 RmPrefixUnion.find("enum ") == 0
108 ? RmPrefixUnion.substr(sizeof("enum ") - 1)
109 : RmPrefixUnion;
110
111 LLVM_GET_TYPE_NAME_CONSTEXPR auto AnglePos = RmPrefixEnum.rfind('>');
112#if LLVM_GET_TYPE_NAME_STATIC_ASSERT
113 static_assert(AnglePos != std::string_view::npos,
114 "Unable to find the closing '>'!");
115#else
116 assert(AnglePos != std::string_view::npos &&
117 "Unable to find the closing '>'!");
118#endif
119
120 return RmPrefixEnum.substr(0, AnglePos);
121#else
122 // No known technique for statically extracting a type name on this compiler.
123 // We return a string that is unlikely to look like any type in LLVM.
124 return "UNKNOWN_TYPE";
125#endif
126}
127
128} // namespace llvm
129
130// Don't leak out of this header file
131#undef LLVM_GET_TYPE_NAME_CONSTEXPR
132#undef LLVM_GET_TYPE_NAME_STATIC_ASSERT
133
134#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_GET_TYPE_NAME_CONSTEXPR
Definition TypeName.h:25
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
This is an optimization pass for GlobalISel generic memory operations.
LLVM_GET_TYPE_NAME_CONSTEXPR StringRef getTypeName()
We provide a function which tries to compute the (demangled) name of a type statically.
Definition TypeName.h:42
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key