<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Nov 18, 2014 at 1:38 PM, Duncan P. N. Exon Smith <span dir="ltr"><<a href="mailto:dexonsmith@apple.com" target="_blank">dexonsmith@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class=""><div class="h5"><br>
> On 2014 Nov 18, at 12:59, David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>> wrote:<br>
><br>
><br>
><br>
> On Tue, Nov 18, 2014 at 12:54 PM, Duncan P. N. Exon Smith <<a href="mailto:dexonsmith@apple.com">dexonsmith@apple.com</a>> wrote:<br>
><br>
> > On 2014 Nov 18, at 11:52, David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>> wrote:<br>
> ><br>
> ><br>
> ><br>
> > On Tue, Nov 18, 2014 at 11:19 AM, Duncan P. N. Exon Smith <<a href="mailto:dexonsmith@apple.com">dexonsmith@apple.com</a>> wrote:<br>
> ><br>
> > > On 2014 Nov 18, at 10:06, David Blaikie <<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>> wrote:<br>
> > ><br>
> > > Unexposed, but not magic - it can be implemented in LLVM as it is in libc++. A few of these utilities are a bit of a pain to write, but they're generic enough not to need to be written very often.<br>
> ><br>
> >> This is spiraling into a major project :).  I just want to pass in<br>
> >> a context by reference to prevent reference/pointer disagreement<br>
> >> in `MDString::get()` vs. `MDString::MDString()`, so I want some<br>
> >> API that is clear and correct.<br>
> ><br>
> > I'm not sure it's so clear when this can invoke explicit ctors in a context where one would only really expect implicit conversions. Maybe for this use case it's not problematic, but for others this could be a pretty confusing stumbling block/bug.<br>
> ><br>
> >> How about I file a PR for this?  Your argument that `emplace()`<br>
> >> would be a good abstraction here is convincing, but encapsulating<br>
> >> `StringMap` is pretty orthogonal to my current work.<br>
> ><br>
> > If you don't have time to address this now,<br>
><br>
> I don't, really.  If I fix every strange API I come across, I'll<br>
> never complete the metadata-value-split (or the custom debug info<br>
> IR that motivated it).<br>
><br>
> Not quite sure I agree - but we all make different tradeoffs along this spectrum, certainly.<br>
><br>
> > I'll find some & just do it - I don't really want this implicit invocation of explicit ctors sticking around.<br>
><br>
> But me being pragmatic shouldn't create work for you... that's the<br>
> wrong outcome.<br>
><br>
> If I'm the one who cares about it enough to desire change & other people don't (not like anyone else is speaking up here), perhaps it is.<br>
><br>
> >> In the meantime, I think the perfect-forwarding I added in the<br>
> >> 3-arg version of `StringMapEntry::Create()` is an incremental<br>
> >> improvement.<br>
> >><br>
> > I don't think this is an incremental improvement since it can lead to explicit ctors being called essentially implicitly.<br>
><br>
> I'd be happy to back out my API changes and allow the `MDString`<br>
> pointer/reference disagreement, but I don't think that will<br>
> satisfy you (although let me know if I'm wrong).<br>
><br>
> At least that would keep the weirdness out of a more common API.<br>
><br>
> Explicit constructors could *already* be called implicitly, I just<br>
> changed it so that the argument (whether implicit or explicit)<br>
> could be passed by reference.  If this API is flawed (and I think<br>
> you're right: it is), it's been flawed for a long time.<br>
><br>
> Fair point - don't know how long<br>
<br>
</div></div>Frankly, I don't know how long either; I didn't check the log.<br></blockquote><div><br>Pretty sure I remember introducing it, so I've only myself to blame - and probably somewhere in the last year or so. But I could be completely off on both counts.<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<span class=""><br>
> , or if anyone relies on it (I'll try adding some SFINAE & see if anyone else is relying on it - in that case, adding your use would be more problematic even if the API has been able to do this for a while & we just haven't grown such uses)<br>
<br>
</span>Okay, let me know what you figure out.<br></blockquote><div><br>Adding this:<br><br><pre style="color:rgb(0,0,0)">diff --git include/llvm/ADT/StringMap.h include/llvm/ADT/StringMap.h
index 2feb2ab..99efcdd 100644
--- include/llvm/ADT/StringMap.h
+++ include/llvm/ADT/StringMap.h
@@ -140,8 +140,9 @@ public:
   /// Create - Create a StringMapEntry for the specified key and default
   /// construct the value.
   template <typename AllocatorTy, typename InitType>
-  static StringMapEntry *Create(StringRef Key, AllocatorTy &Allocator,
-                                InitType &&InitVal) {
+  static typename std::enable_if<std::is_convertible<InitType, ValueTy>::value,
+                                 StringMapEntry *>::type
+  Create(StringRef Key, AllocatorTy &Allocator, InitType &&InitVal) {
     unsigned KeyLength = Key.size();
 
     // Allocate a new item with space for the string at the end and a null
@@ -169,8 +170,10 @@ public:
   }
 
   /// Create - Create a StringMapEntry with normal malloc/free.
-  template<typename InitType>
-  static StringMapEntry *Create(StringRef Key, InitType &&InitVal) {
+  template <typename InitType>
+  static typename std::enable_if<std::is_convertible<InitType, ValueTy>::value,
+                                 StringMapEntry *>::type
+  Create(StringRef Key, InitType &&InitVal) {
     MallocAllocator A;
     return Create(Key, A, std::forward<InitType>(InitVal));
   }

Only fails to compile on your new usage, not any other existing usage. (& now I'll have to try switching back to ValueTy directly to see what breaks there & why the InitType was added in there at all)</pre> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<span class=""><br>
> Not that we shouldn't fix it; I just don't see why fixing it<br>
> should be urgent.  IMO, the only urgency is filing a PR (or adding<br>
> a FIXME) so that it's tracked somehow.<br>
><br>
> Lots of things go that way to be disregarded essentially indefinitely, it's not something I have high hope will actually be addressed, going on past experience. For narrowly provided weirdness that's one thing, for common API that may grow new uses, etc, I'm more concerned about doing that.<br>
<br>
</span>FWIW, the original API change to StringMapEntry was pretty narrow,<br>
since anyone creating from that directly is already messing with<br>
implementation details.</blockquote><div><br>Pretty public implementation details - though I do wonder if we could make them more private...  <br><br>One other simple possibility is to make the type Movable (could be privately movable - keeping that friending of StringMapEntry around - as much as dislike that too (limits StringMap's ability to be refactored without breaking this code - depends on exactly where the ctor is called from, etc)) and just pass in a Metadata(Context) - it looks like a fair few other StringMap uses do that or similar (many of them insert a default value then update the value to point back to the key data, in fact - I guess they could all be updated to use the technique you've got here, computing the entry address from that of the value).</div></div><br></div></div>