<div dir="ltr">What about this?<div><br></div><div><div>diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h</div><div>index d8e0732..5b8503a 100644</div><div>--- a/include/llvm/ADT/StringRef.h</div><div>+++ b/include/llvm/ADT/StringRef.h</div><div>@@ -84,10 +84,10 @@ namespace llvm {</div><div><br></div><div>     /// Construct a string ref from a pointer and length.</div><div>     LLVM_ATTRIBUTE_ALWAYS_INLINE</div><div>-    /*implicit*/ StringRef(const char *data, size_t length)</div><div>+    /*implicit*/ constexpr StringRef(const char *data, size_t length)</div><div>       : Data(data), Length(length) {</div><div>-        assert((data || length == 0) &&</div><div>-        "StringRef cannot be built from a NULL argument with non-null length");</div><div>+        //assert((data || length == 0) &&</div><div>+        //"StringRef cannot be built from a NULL argument with non-null length");</div><div>       }</div><div><br></div><div>     /// Construct a string ref from an std::string.</div><div>@@ -839,6 +839,24 @@ namespace llvm {</div><div>     /// @}</div><div>   };</div><div><br></div><div>+  class StringLiteral {</div><div>+  public:</div><div>+    template<size_t N></div><div>+    constexpr StringLiteral(const char(&Str)[N])</div><div>+      : Str(Str), Length(N) {</div><div>+</div><div>+    }</div><div>+</div><div>+    constexpr operator StringRef() const {</div><div>+      return StringRef(Str, Length);</div><div>+    }</div><div>+</div><div>+  private:</div><div>+    const char *Str;</div><div>+    unsigned Length;</div><div>+  };</div><div>+</div><div>+</div><div>   /// @name StringRef Comparison Operators</div><div>   /// @{</div><div><br></div><div>diff --git a/unittests/ADT/StringRefTest.cpp b/unittests/ADT/StringRefTest.cpp</div><div>index c1cc558..0876f2e 100644</div><div>--- a/unittests/ADT/StringRefTest.cpp</div><div>+++ b/unittests/ADT/StringRefTest.cpp</div><div>@@ -17,6 +17,11 @@</div><div> #include "gtest/gtest.h"</div><div> using namespace llvm;</div><div><br></div><div>+</div><div>+constexpr StringLiteral Strings[] = {</div><div>+  "Test"</div><div>+};</div><div>+</div><div> namespace llvm {</div></div><div><br></div><div><br></div><div>The basic idea here is that you introduce a StringLiteral class and anywhere you want to use a global constructor, you make sure to declare a constexpr array instead of a normal array, and you make it of type StringLiteral.</div><div><br></div><div>This avoids the issue of having to make the StringRef constructor explicit since it doesn't touch StringRef, and it also avoids the ambiguity between constructing a StringRef with a literal versus a char array, because even though it is still possible to construct a StringLiteral with a char array, it is not possible to do so in a constexpr context.</div><div><br></div><div>If your StringRef is nested in part of another class, and you want an array of that class, it still works.  For example:</div><div><br></div><div>struct Foo {</div><div>  StringLiteral X;</div><div>  StringLiteral Y;</div><div>  int Z;</div><div>};</div><div><br></div><div>constexpr Foo[] Foos = { {"A", "B", 1}, {"C", "D", 2} };</div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Nov 28, 2016 at 11:38 AM Zachary Turner <<a href="mailto:zturner@google.com">zturner@google.com</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" class="gmail_msg">The fact that the templatized constructor falls down because of the possibility of initializing StringRef with a stack-allocated char array kills that idea in my mind.<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I feel like the only two reasonable solutions are </div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">1) allow UDL for this case, document that this is an exception and that UDLs are still not permitted anywhere else, and require (by policy, since I don't know of a way to have the compiler force it) that this UDL be used only in global constructors.  One idea to help "enforce" this policy would be to give the UDL a ridiculously convoluted name, like `string_ref_literal`, so that one would have to write "foo"_string_ref_literal, and then provide a macro like `#define LITERAL(x) x_string_ref_literal`, so that the user writes `StringRef s[] = { LITERAL("a"), LITERAL("b") };  I'm not sure if that's better or worse than `StringRef s[] = { "a"_sr, "b"_sr };`, but at least it's greppable this way.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">2) Don't allow global tables of StringRefs.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div></div><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Mon, Nov 28, 2016 at 11:30 AM Mehdi Amini via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Nov 28, 2016, at 11:27 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com" class="gmail_msg" target="_blank">dblaikie@gmail.com</a>> wrote:</div><br class="m_-2440867081013230252m_1253767149041102452Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg"><br class="gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Mon, Nov 28, 2016 at 11:01 AM Mehdi Amini <<a href="mailto:mehdi.amini@apple.com" class="gmail_msg" target="_blank">mehdi.amini@apple.com</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Nov 28, 2016, at 9:47 AM, David Blaikie via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:</div><br class="m_-2440867081013230252m_1253767149041102452m_-2045717065759680870Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg">OK - good to know. (not sure we're talking about pessimizing it - just not adding a new/possible optimization, to be clear)<br class="gmail_msg"></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">This does not seem that clear to me. The motivation seems to be able to create global table of StringRef, which we don’t do because the lack fo constexpr of static initializers right now.</div><div class="gmail_msg">Moving forward it would mean making clang a lot slower when built with MSVC if we were going this route.</div></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Ah, fair - perhaps I misunderstood/misrepresented, apologies. Figured this was just an attempt to reduce global initializers in arrays we already have. Any pointers on where the motivation is described/discussed?<br class="gmail_msg"></div></div></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">This thread started with: "There is a desire to be able to create constexpr StringRefs to avoid static initializers for global tables of/containing StringRefs.”</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I don’t have more information, but maybe Malcolm can elaborate?</div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">— </div><div class="gmail_msg">Mehdi</div><div class="gmail_msg"><br class="gmail_msg"></div><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg"><div class="gmail_quote gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg"><br class="gmail_msg">Just out of curiosity - are there particular reasons you prefer or need to ship an MSVC built version, rather than a bootstrapped Clang?</div><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Mon, Nov 28, 2016 at 9:24 AM Robinson, Paul <<a href="mailto:paul.robinson@sony.com" class="gmail_msg" target="_blank">paul.robinson@sony.com</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple" class="gmail_msg"><div class="gmail_msg m_-2440867081013230252m_1253767149041102452m_-2045717065759680870m_5859138549290728135WordSection1"><p class="MsoNormal gmail_msg" style="margin-left:.5in">So I wouldn't personally worry too much about performance degredation when built with MSVC - if, when building a stage 2 on Windows (building Clang with MSVC build Clang) you do end up with a compiler with the desired
 performance characteristics - then that's probably sufficient.<span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d" class="gmail_msg"><u class="gmail_msg"></u><u class="gmail_msg"></u></span></p><p class="MsoNormal gmail_msg"><a name="m_-2440867081013230252_m_1253767149041102452_m_-2045717065759680870_m_5859138549290728135__MailEndCompose" class="gmail_msg"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d" class="gmail_msg"><u class="gmail_msg"></u> <u class="gmail_msg"></u></span></a></p>
</div></div><div lang="EN-US" link="blue" vlink="purple" class="gmail_msg"><div class="gmail_msg m_-2440867081013230252m_1253767149041102452m_-2045717065759680870m_5859138549290728135WordSection1"><p class="MsoNormal gmail_msg"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d" class="gmail_msg">Hold on there—we deliver an MSVC-built Clang to our licensees, and I would really rather not pessimize it.<u class="gmail_msg"></u><u class="gmail_msg"></u></span></p><p class="MsoNormal gmail_msg"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d" class="gmail_msg">--paulr<u class="gmail_msg"></u><u class="gmail_msg"></u></span></p><p class="MsoNormal gmail_msg"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d" class="gmail_msg"><u class="gmail_msg"></u> <u class="gmail_msg"></u></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt" class="gmail_msg">
<div class="gmail_msg">
<div style="border:none;border-top:solid #b5c4df 1.0pt;padding:3.0pt 0in 0in 0in" class="gmail_msg"><p class="MsoNormal gmail_msg"><b class="gmail_msg"><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"" class="gmail_msg">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"" class="gmail_msg"> llvm-dev [mailto:<a href="mailto:llvm-dev-bounces@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev-bounces@lists.llvm.org</a>]
<b class="gmail_msg">On Behalf Of </b>David Blaikie via llvm-dev<br class="gmail_msg">
<b class="gmail_msg">Sent:</b> Friday, November 25, 2016 8:52 AM<br class="gmail_msg">
<b class="gmail_msg">To:</b> Mueller-Roemer, Johannes Sebastian; Malcolm Parsons; Hal Finkel; <a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a></span></p></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" class="gmail_msg"><div class="gmail_msg m_-2440867081013230252m_1253767149041102452m_-2045717065759680870m_5859138549290728135WordSection1"><div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt" class="gmail_msg"><div class="gmail_msg"><div style="border:none;border-top:solid #b5c4df 1.0pt;padding:3.0pt 0in 0in 0in" class="gmail_msg"><p class="MsoNormal gmail_msg"><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"" class="gmail_msg"><br class="gmail_msg">
<b class="gmail_msg">Subject:</b> Re: [llvm-dev] RFC: Constructing StringRefs at compile time<u class="gmail_msg"></u><u class="gmail_msg"></u></span></p></div></div></div></div></div><div lang="EN-US" link="blue" vlink="purple" class="gmail_msg"><div class="gmail_msg m_-2440867081013230252m_1253767149041102452m_-2045717065759680870m_5859138549290728135WordSection1"><div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt" class="gmail_msg"><p class="MsoNormal gmail_msg"><u class="gmail_msg"></u> <u class="gmail_msg"></u></p>
<div class="gmail_msg"><p class="MsoNormal gmail_msg" style="margin-bottom:12.0pt"><u class="gmail_msg"></u> <u class="gmail_msg"></u></p>
<div class="gmail_msg">
<div class="gmail_msg"><p class="MsoNormal gmail_msg">On Fri, Nov 25, 2016 at 6:10 AM Mueller-Roemer, Johannes Sebastian via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<u class="gmail_msg"></u><u class="gmail_msg"></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in" class="gmail_msg"><p class="MsoNormal gmail_msg">What about going for<br class="gmail_msg">
<br class="gmail_msg">
template<unsigned N><br class="gmail_msg">
constexpr StringRef(const char (&Str)[N])<br class="gmail_msg">
<br class="gmail_msg">
and avoiding strlen entirely for string literals?<u class="gmail_msg"></u><u class="gmail_msg"></u></p>
</blockquote>
<div class="gmail_msg"><p class="MsoNormal gmail_msg"><u class="gmail_msg"></u> <u class="gmail_msg"></u></p>
</div>
<div class="gmail_msg"><p class="MsoNormal gmail_msg">You'd at least want an assert in there (that N - 1 == strlen(Str)) in case a StringRef is ever constructed from a non-const char buffer that's only partially filled.<br class="gmail_msg">
<br class="gmail_msg">
But if we can write this in such a way that it performs well on good implementations - that seems sufficient. If getting good performance out of the compiler means bootstrapping - that's pretty much the status quo already, as I understand it.<br class="gmail_msg">
<br class="gmail_msg">
So I wouldn't personally worry too much about performance degredation when built with MSVC - if, when building a stage 2 on Windows (building Clang with MSVC build Clang) you do end up with a compiler with the desired performance characteristics - then that's
 probably sufficient.<u class="gmail_msg"></u><u class="gmail_msg"></u></p>
</div>
<div class="gmail_msg"><p class="MsoNormal gmail_msg"> <u class="gmail_msg"></u><u class="gmail_msg"></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in" class="gmail_msg"><p class="MsoNormal gmail_msg"><br class="gmail_msg">
-----Original Message-----<br class="gmail_msg">
From: llvm-dev [mailto:<a href="mailto:llvm-dev-bounces@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev-bounces@lists.llvm.org</a>] On Behalf Of Malcolm Parsons via llvm-dev<br class="gmail_msg">
Sent: Friday, November 25, 2016 13:34<br class="gmail_msg">
To: Hal Finkel <<a href="mailto:hfinkel@anl.gov" class="gmail_msg" target="_blank">hfinkel@anl.gov</a>><br class="gmail_msg">
Cc: <a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a><br class="gmail_msg">
Subject: Re: [llvm-dev] RFC: Constructing StringRefs at compile time<br class="gmail_msg">
<br class="gmail_msg">
On 24 November 2016 at 15:04, Hal Finkel <<a href="mailto:hfinkel@anl.gov" class="gmail_msg" target="_blank">hfinkel@anl.gov</a>> wrote:<br class="gmail_msg">
>> Creating constexpr StringRefs isn't trivial as strlen isn't portably<br class="gmail_msg">
>> constexpr and std::char_traits<char>::length is only constexpr in<br class="gmail_msg">
>> C++17.<br class="gmail_msg">
><br class="gmail_msg">
> Why don't we just create our own traits class that has a constexpr length, and then we can switch over to the standard one when we switch to C++17?<br class="gmail_msg">
<br class="gmail_msg">
GCC and Clang treat __builtin_strlen as constexpr.<br class="gmail_msg">
MSVC 2015 doesn't support C++14 extended constexpr. I don't know how well it optimises a recursive strlen.<br class="gmail_msg">
<br class="gmail_msg">
This works as an optimisation for GCC and Clang, and doesn't make things worse for MSVC:<br class="gmail_msg">
<br class="gmail_msg">
     /// Construct a string ref from a cstring.<br class="gmail_msg">
     LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="gmail_msg">
+#if __has_builtin(__builtin_strlen)<br class="gmail_msg">
+    /*implicit*/ constexpr StringRef(const char *Str)<br class="gmail_msg">
+        : Data(Str), Length(Str ? __builtin_strlen(Str) : 0) {} #else<br class="gmail_msg">
     /*implicit*/ StringRef(const char *Str)<br class="gmail_msg">
         : Data(Str), Length(Str ? ::strlen(Str) : 0) {}<br class="gmail_msg">
+#endif<br class="gmail_msg">
<br class="gmail_msg">
--<br class="gmail_msg">
Malcolm Parsons<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
LLVM Developers mailing list<br class="gmail_msg">
<a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a><br class="gmail_msg">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" class="gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
LLVM Developers mailing list<br class="gmail_msg">
<a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a><br class="gmail_msg">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" class="gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><u class="gmail_msg"></u><u class="gmail_msg"></u></p>
</blockquote>
</div>
</div>
</div></div></div></blockquote></div>
_______________________________________________<br class="gmail_msg">LLVM Developers mailing list<br class="gmail_msg"><a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a><br class="gmail_msg"><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" class="gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br class="gmail_msg"></div></blockquote></div></div></blockquote></div></div>
</div></blockquote></div></div>_______________________________________________<br class="gmail_msg">
LLVM Developers mailing list<br class="gmail_msg">
<a href="mailto:llvm-dev@lists.llvm.org" class="gmail_msg" target="_blank">llvm-dev@lists.llvm.org</a><br class="gmail_msg">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" class="gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br class="gmail_msg">
</blockquote></div></blockquote></div>