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 "llvm/ADT/StringRef.h"
13
14namespace llvm {
15
16/// We provide a function which tries to compute the (demangled) name of a type
17/// statically.
18///
19/// This routine may fail on some platforms or for particularly unusual types.
20/// Do not use it for anything other than logging and debugging aids. It isn't
21/// portable or dependendable in any real sense.
22///
23/// The returned StringRef will point into a static storage duration string.
24/// However, it may not be null terminated and may be some strangely aligned
25/// inner substring of a larger string.
26template <typename DesiredTypeName>
27inline StringRef getTypeName() {
28#if defined(__clang__) || defined(__GNUC__)
29 StringRef Name = __PRETTY_FUNCTION__;
30
31 StringRef Key = "DesiredTypeName = ";
32 Name = Name.substr(Name.find(Key));
33 assert(!Name.empty() && "Unable to find the template parameter!");
34 Name = Name.drop_front(Key.size());
35
36 assert(Name.endswith("]") && "Name doesn't end in the substitution key!");
37 return Name.drop_back(1);
38#elif defined(_MSC_VER)
39 StringRef Name = __FUNCSIG__;
40
41 StringRef Key = "getTypeName<";
42 Name = Name.substr(Name.find(Key));
43 assert(!Name.empty() && "Unable to find the function name!");
44 Name = Name.drop_front(Key.size());
45
46 for (StringRef Prefix : {"class ", "struct ", "union ", "enum "})
47 if (Name.startswith(Prefix)) {
48 Name = Name.drop_front(Prefix.size());
49 break;
50 }
51
52 auto AnglePos = Name.rfind('>');
53 assert(AnglePos != StringRef::npos && "Unable to find the closing '>'!");
54 return Name.substr(0, AnglePos);
55#else
56 // No known technique for statically extracting a type name on this compiler.
57 // We return a string that is unlikely to look like any type in LLVM.
58 return "UNKNOWN_TYPE";
59#endif
60}
61
62}
63
64#endif
65