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