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