<div dir="ltr">Ah, if ICC defines __GNUC__ then we're golden. I'll make that change, thanks!</div><br><div class="gmail_quote"><div dir="ltr">On Wed, Feb 24, 2016 at 8:32 PM David Majnemer via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I think the handling for __INTEL_COMPILER is not quite right.<div><br></div><div>Intel's compiler for Windows, icl, also defines __INTEL_COMPILER.</div><div>While icl defines __PRETTY_FUNCTION__, it provides behavior compatible with __FUNCSIG__.</div><div>Given that icc defines __GNUC__ and icl defines _MSC_VER, I'd suggest removing the defined(__INTEL_COMPILER).  I think the other checks will do the right thing.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 24, 2016 at 7:58 PM, Chandler Carruth via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: chandlerc<br>
Date: Wed Feb 24 21:58:21 2016<br>
New Revision: 261819<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=261819&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=261819&view=rev</a><br>
Log:<br>
[Support] Add a fancy helper function to get a static name for a type.<br>
<br>
This extracts the type name from __PRETTY_FUNCTION__ for compilers that<br>
support it (I've opted Clang, GCC, and ICC into this as I've tested that<br>
they work) and from __FUNCSIG__ which is very similar on MSVC. The<br>
routine falls back gracefully on a stub "UNKNOWN_TYPE" string with<br>
compilers or formats it doesn't understand.<br>
<br>
This should be enough for a lot of common cases in LLVM where the real<br>
goal is just to log or print a type name as a debugging aid, and save<br>
a ton of boilerplate in the process. Notably, I'm planning to use this<br>
to remove all the getName() boiler plate from the new pass manager.<br>
<br>
The design and implementation is based on a bunch of advice and<br>
discussion with Richard Smith and experimenting with most versions of<br>
Clang and GCC. David Majnemer also provided excellent advice on how best<br>
to do this with MSVC. Richard also checked that ICC does something<br>
reasonable and I'll watch the build bots for other compilers. It'd be<br>
great if someone could contribute logic for xlC and/or other toolchains.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D17565" rel="noreferrer" target="_blank">http://reviews.llvm.org/D17565</a><br>
<br>
Added:<br>
    llvm/trunk/include/llvm/Support/TypeName.h<br>
    llvm/trunk/unittests/Support/TypeNameTest.cpp<br>
Modified:<br>
    llvm/trunk/unittests/Support/CMakeLists.txt<br>
<br>
Added: llvm/trunk/include/llvm/Support/TypeName.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/TypeName.h?rev=261819&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/TypeName.h?rev=261819&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Support/TypeName.h (added)<br>
+++ llvm/trunk/include/llvm/Support/TypeName.h Wed Feb 24 21:58:21 2016<br>
@@ -0,0 +1,65 @@<br>
+//===- TypeName.h -----------------------------------------------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_SUPPORT_TYPENAME_H<br>
+#define LLVM_SUPPORT_TYPENAME_H<br>
+<br>
+#include "llvm/ADT/StringRef.h"<br>
+<br>
+namespace llvm {<br>
+<br>
+/// We provide a function which tries to compute the (demangled) name of a type<br>
+/// statically.<br>
+///<br>
+/// This routine may fail on some platforms or for particularly unusual types.<br>
+/// Do not use it for anything other than logging and debugging aids. It isn't<br>
+/// portable or dependendable in any real sense.<br>
+///<br>
+/// The returned StringRef will point into a static storage duration string.<br>
+/// However, it may not be null terminated and may be some strangely aligned<br>
+/// inner substring of a larger string.<br>
+template <typename DesiredTypeName><br>
+inline StringRef getTypeName() {<br>
+#if defined(__clang__) || defined(__GNUC__) || defined(__INTEL_COMPILER)<br>
+  StringRef Name = __PRETTY_FUNCTION__;<br>
+<br>
+  StringRef Key = "DesiredTypeName = ";<br>
+  Name = Name.substr(Name.find(Key));<br>
+  assert(!Name.empty() && "Unable to find the template parameter!");<br>
+  Name = Name.drop_front(Key.size());<br>
+<br>
+  assert(Name.endswith("]") && "Name doesn't end in the substitution key!");<br>
+  return Name.drop_back(1);<br>
+#elif defined(_MSC_VER)<br>
+  StringRef Name = __FUNCSIG__;<br>
+<br>
+  StringRef Key = "getTypeName<";<br>
+  Name = Name.substr(Name.find(Key));<br>
+  assert(!Name.empty() && "Unable to find the function name!");<br>
+  Name = Name.drop_front(Key.size());<br>
+<br>
+  for (StringRef Prefix : {"class ", "struct ", "union ", "enum "})<br>
+    if (Name.startswith(Prefix)) {<br>
+      Name = Name.drop_front(Prefix.size());<br>
+      break;<br>
+    }<br>
+<br>
+  auto AnglePos = Name.rfind('>');<br>
+  assert(AnglePos != StringRef::npos && "Unable to find the closing '>'!");<br>
+  return Name.substr(0, AnglePos);<br>
+#else<br>
+  // No known technique for statically extracting a type name on this compiler.<br>
+  // We return a string that is unlikely to look like any type in LLVM.<br>
+  return "UNKNOWN_TYPE";<br>
+#endif<br>
+}<br>
+<br>
+}<br>
+<br>
+#endif<br>
<br>
Modified: llvm/trunk/unittests/Support/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CMakeLists.txt?rev=261819&r1=261818&r2=261819&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CMakeLists.txt?rev=261819&r1=261818&r2=261819&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/Support/CMakeLists.txt (original)<br>
+++ llvm/trunk/unittests/Support/CMakeLists.txt Wed Feb 24 21:58:21 2016<br>
@@ -42,6 +42,7 @@ add_llvm_unittest(SupportTests<br>
   ThreadPool.cpp<br>
   TimerTest.cpp<br>
   TimeValueTest.cpp<br>
+  TypeNameTest.cpp<br>
   TrailingObjectsTest.cpp<br>
   UnicodeTest.cpp<br>
   YAMLIOTest.cpp<br>
<br>
Added: llvm/trunk/unittests/Support/TypeNameTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/TypeNameTest.cpp?rev=261819&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/TypeNameTest.cpp?rev=261819&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/Support/TypeNameTest.cpp (added)<br>
+++ llvm/trunk/unittests/Support/TypeNameTest.cpp Wed Feb 24 21:58:21 2016<br>
@@ -0,0 +1,49 @@<br>
+//===- TypeNameTest.cpp ---------------------------------------------------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/Support/TypeName.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+#include "gtest/gtest.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+namespace {<br>
+namespace N1 {<br>
+struct S1 {};<br>
+class C1 {};<br>
+union U1 {};<br>
+}<br>
+<br>
+TEST(TypeNameTest, Names) {<br>
+  struct S2 {};<br>
+<br>
+  StringRef S1Name = getTypeName<N1::S1>();<br>
+  StringRef C1Name = getTypeName<N1::C1>();<br>
+  StringRef U1Name = getTypeName<N1::U1>();<br>
+  StringRef S2Name = getTypeName<S2>();<br>
+<br>
+#if defined(__clang__) || defined(__GNUC__) || defined(__INTEL_COMPILER) ||    \<br>
+    defined(_MSC_VER)<br>
+  EXPECT_TRUE(S1Name.endswith("::N1::S1")) << S1Name.str();<br>
+  EXPECT_TRUE(C1Name.endswith("::N1::C1")) << C1Name.str();<br>
+  EXPECT_TRUE(U1Name.endswith("::N1::U1")) << U1Name.str();<br>
+#ifdef __clang__<br>
+  EXPECT_TRUE(S2Name.endswith("S2")) << S2Name.str();<br>
+#else<br>
+  EXPECT_TRUE(S2Name.endswith("::S2")) << S2Name.str();<br>
+#endif<br>
+#else<br>
+  EXPECT_EQ("UNKNOWN_TYPE", S1Name);<br>
+  EXPECT_EQ("UNKNOWN_TYPE", C1Name);<br>
+  EXPECT_EQ("UNKNOWN_TYPE", U1Name);<br>
+  EXPECT_EQ("UNKNOWN_TYPE", S2Name);<br>
+#endif<br>
+}<br>
+<br>
+} // end anonymous namespace<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>