1303231Sdim//===- TypeName.h -----------------------------------------------*- C++ -*-===// 2303231Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6303231Sdim// 7303231Sdim//===----------------------------------------------------------------------===// 8303231Sdim 9303231Sdim#ifndef LLVM_SUPPORT_TYPENAME_H 10303231Sdim#define LLVM_SUPPORT_TYPENAME_H 11303231Sdim 12303231Sdim#include "llvm/ADT/StringRef.h" 13303231Sdim 14303231Sdimnamespace llvm { 15303231Sdim 16303231Sdim/// We provide a function which tries to compute the (demangled) name of a type 17303231Sdim/// statically. 18303231Sdim/// 19303231Sdim/// This routine may fail on some platforms or for particularly unusual types. 20303231Sdim/// Do not use it for anything other than logging and debugging aids. It isn't 21303231Sdim/// portable or dependendable in any real sense. 22303231Sdim/// 23303231Sdim/// The returned StringRef will point into a static storage duration string. 24303231Sdim/// However, it may not be null terminated and may be some strangely aligned 25303231Sdim/// inner substring of a larger string. 26303231Sdimtemplate <typename DesiredTypeName> 27303231Sdiminline StringRef getTypeName() { 28303231Sdim#if defined(__clang__) || defined(__GNUC__) 29303231Sdim StringRef Name = __PRETTY_FUNCTION__; 30303231Sdim 31303231Sdim StringRef Key = "DesiredTypeName = "; 32303231Sdim Name = Name.substr(Name.find(Key)); 33303231Sdim assert(!Name.empty() && "Unable to find the template parameter!"); 34303231Sdim Name = Name.drop_front(Key.size()); 35303231Sdim 36303231Sdim assert(Name.endswith("]") && "Name doesn't end in the substitution key!"); 37303231Sdim return Name.drop_back(1); 38303231Sdim#elif defined(_MSC_VER) 39303231Sdim StringRef Name = __FUNCSIG__; 40303231Sdim 41303231Sdim StringRef Key = "getTypeName<"; 42303231Sdim Name = Name.substr(Name.find(Key)); 43303231Sdim assert(!Name.empty() && "Unable to find the function name!"); 44303231Sdim Name = Name.drop_front(Key.size()); 45303231Sdim 46303231Sdim for (StringRef Prefix : {"class ", "struct ", "union ", "enum "}) 47303231Sdim if (Name.startswith(Prefix)) { 48303231Sdim Name = Name.drop_front(Prefix.size()); 49303231Sdim break; 50303231Sdim } 51303231Sdim 52303231Sdim auto AnglePos = Name.rfind('>'); 53303231Sdim assert(AnglePos != StringRef::npos && "Unable to find the closing '>'!"); 54303231Sdim return Name.substr(0, AnglePos); 55303231Sdim#else 56303231Sdim // No known technique for statically extracting a type name on this compiler. 57303231Sdim // We return a string that is unlikely to look like any type in LLVM. 58303231Sdim return "UNKNOWN_TYPE"; 59303231Sdim#endif 60303231Sdim} 61303231Sdim 62303231Sdim} 63303231Sdim 64303231Sdim#endif 65