Home | History | Annotate | Download | only in Support
      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 
     15 namespace 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.
     27 template <typename DesiredTypeName>
     28 inline 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