WIP Patch: Introduce a proper mangling scheme for block literals

John McCall rjmccall at apple.com
Tue Jun 18 18:41:36 PDT 2013


On Jun 12, 2013, at 4:42 PM, Eli Friedman <eli.friedman at gmail.com> wrote:
> Take a C++ function like the following:
> 
> inline void f() {
>   ^{
>     static int i = 0;
>     printf("%d\n", ++i);
>   }();
> }
> 
> 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.)
> 
> 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.

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:

   if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
-    manglePrefix(getEffectiveParentContext(DC), NoFunction);    
-    SmallString<64> Name;
-    llvm::raw_svector_ostream NameStream(Name);
-    Context.mangleBlock(Block, NameStream);
-    NameStream.flush();
-    Out << Name.size() << Name;
+    manglePrefix(getEffectiveParentContext(DC), NoFunction);
+    if (unsigned Number = Block->getBlockManglingNumber()) {
+      Out << "14__block_prefix";
+      if (Number > 1)
+        mangleNumber(Number - 2);
+      Out << '_';
+      return;
+    }
+    Out << "23__block_prefix_internal";
+    Out << Context.getPrefixBlockId(Block);
+    Out << '_';

> 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. 
> 
> I'd like some feedback to make sure my patch is actually implementing something sane.

Other than the mangling scheme, this seems reasonable.

> Any suggestions for a better name than LambdaBlockMangleContext are also welcome.

How about ClosureOwningContext?

John.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130618/baf6a6e0/attachment.html>


More information about the cfe-commits mailing list