<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On Jun 12, 2013, at 4:42 PM, Eli Friedman <<a href="mailto:eli.friedman@gmail.com">eli.friedman@gmail.com</a>> wrote:</div><blockquote type="cite"><div dir="ltr">Take a C++ function like the following:<div><br></div><div><font face="courier new, monospace">inline void f() {</font></div><div><font face="courier new, monospace">  ^{</font></div><div style="margin: 0px; "><font face="courier new, monospace">    static int i = 0;</font></div><div style="margin: 0px; "><font face="courier new, monospace">    printf("%d\n", ++i);</font></div><div style="margin: 0px; "><font face="courier new, monospace">  }();</font></div><div><font face="courier new, monospace">}</font></div><div><br></div><div>Looks pretty simple, right?  Unfortunately, trunk clang doesn't handle this correctly.  The primary issue here is we haven't defined the correct way to mangle the name of "i", and clang's current scheme is unusable because it depends on the details of IRGen.  (There's also the matter that we don't compute the linkage correctly, but that's a simple IRGen bug.)</div>
<div><br></div><div>I'm attaching a patch which expands the scheme we use for mangling lambda expressions in this sort of context to also work for block literals.  The patch is still a bit of a mess: there's a bunch of copy-paste code I still need to clean up, I haven't included tests, and it would probably be nice to include the parameter types of the block in the mangling.  That said, it essentially implements everything necessary.</div></div></blockquote><div><br></div>Unlike lambdas, we never actually need to mangle a block declaration;  we just encounter it as a context for local statics and types.  And much like we do with lambdas, we should just ignore the block as a context and mangle the static/type as a local declaration within the actual enclosing declaration.  So I'm not sure what this is about:<br><div><br></div><div>   if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {</div><div>-    manglePrefix(getEffectiveParentContext(DC), NoFunction);    </div><div>-    SmallString<64> Name;</div><div>-    llvm::raw_svector_ostream NameStream(Name);</div><div>-    Context.mangleBlock(Block, NameStream);</div><div>-    NameStream.flush();</div><div>-    Out << Name.size() << Name;</div><div>+    manglePrefix(getEffectiveParentContext(DC), NoFunction);</div><div>+    if (unsigned Number = Block->getBlockManglingNumber()) {</div><div>+      Out << "14__block_prefix";</div><div>+      if (Number > 1)</div><div>+        mangleNumber(Number - 2);</div><div>+      Out << '_';</div><div>+      return;</div><div>+    }</div><div>+    Out << "23__block_prefix_internal";</div><div>+    Out << Context.getPrefixBlockId(Block);</div><div>+    Out << '_';</div><div><br></div></div><div><blockquote type="cite"><div dir="ltr">
<div>Note that this doesn't touch the mangling scheme for the actual function definitions for blocks; they don't need to be externally visible, so we don't need to change the current mangling. </div>
<div><br></div><div>I'd like some feedback to make sure my patch is actually implementing something sane.</div></div></blockquote><div><br></div>Other than the mangling scheme, this seems reasonable.</div><div><br></div><blockquote type="cite"><div dir="ltr">Any suggestions for a better name than LambdaBlockMangleContext are also welcome.</div></blockquote><div><br></div><div>How about ClosureOwningContext?</div><div><br></div><div>John.</div></body></html>