xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Support/TypeName.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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  
14  namespace 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.
26  template <typename DesiredTypeName>
27  inline 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.ends_with("]") && "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.starts_with(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  } // namespace llvm
63  
64  #endif
65