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> getTypeName()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