Fix mangling for block literals.
Blocks, like lambdas, can be written in contexts which are required to be
treated as the same under ODR. Unlike lambdas, it isn't possible to actually
take the address of a block, so the mangling of the block itself doesn't
matter. However, objects like static variables inside a block do need to
be mangled in a consistent way.
There are basically three components here. One, block literals need a
consistent numbering. Two, objects/types inside a block literal need
to be mangled using it. Three, objects/types inside a block literal need
to have their linkage computed correctly.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185372 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index cf1e512..bbdf0f9 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -1416,15 +1416,22 @@
return;
if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
- // The symbol we're adding a prefix for isn't externally
- // visible; make up something sane.
- // FIXME: This isn't always true!
- SmallString<16> BlockPrefix;
- BlockPrefix += "__block_prefix_internal";
- unsigned Number = Context.getBlockId(Block, false);
+ // Reflect the lambda mangling rules, except that we don't have an
+ // actual function declaration.
+ if (NoFunction)
+ return;
+
+ manglePrefix(getEffectiveParentContext(DC), NoFunction);
+ // If we have a block mangling number, use it.
+ unsigned Number = Block->getBlockManglingNumber();
+ // Otherwise, just make up a number. It doesn't matter what it is because
+ // the symbol in question isn't externally visible.
+ if (!Number)
+ Number = Context.getBlockId(Block, false);
+ Out << "Ub";
if (Number > 1)
- BlockPrefix += llvm::utostr_32(Number - 2);
- Out << BlockPrefix.size() << BlockPrefix;
+ Out << Number - 2;
+ Out << '_';
return;
} else if (isa<CapturedDecl>(DC)) {
// Skip CapturedDecl context.