r185450 - More fixes for block mangling.
Eli Friedman
eli.friedman at gmail.com
Tue Jul 2 10:52:29 PDT 2013
Author: efriedma
Date: Tue Jul 2 12:52:28 2013
New Revision: 185450
URL: http://llvm.org/viewvc/llvm-project?rev=185450&view=rev
Log:
More fixes for block mangling.
Make sure we properly treat names defined inside a block as local
names. There are basically three fixes here. One, correctly
treat blocks as a context where we need to use local-name mangling using
the new isLocalContainerContext helper. Two, make
CXXNameMangler::manglePrefix handle local names in a consistent way.
Three, extend CXXNameMangler::mangleLocalName so it can mangle a block
correctly.
Modified:
cfe/trunk/lib/AST/ItaniumMangle.cpp
cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm
cfe/trunk/test/CodeGenCXX/captured-statements.cpp
cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp
cfe/trunk/test/CodeGenObjCXX/mangle-blocks.mm
Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=185450&r1=185449&r2=185450&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Tue Jul 2 12:52:28 2013
@@ -57,17 +57,25 @@ static const DeclContext *getEffectiveDe
return ContextParam->getDeclContext();
}
- return D->getDeclContext();
+ const DeclContext *DC = D->getDeclContext();
+ if (const CapturedDecl *CD = dyn_cast<CapturedDecl>(DC))
+ return getEffectiveDeclContext(CD);
+
+ return DC;
}
static const DeclContext *getEffectiveParentContext(const DeclContext *DC) {
return getEffectiveDeclContext(cast<Decl>(DC));
}
-
+
+static bool isLocalContainerContext(const DeclContext *DC) {
+ return isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC) || isa<BlockDecl>(DC);
+}
+
static const CXXRecordDecl *GetLocalClassDecl(const Decl *D) {
const DeclContext *DC = getEffectiveDeclContext(D);
while (!DC->isNamespace() && !DC->isTranslationUnit()) {
- if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC) || isa<BlockDecl>(DC))
+ if (isLocalContainerContext(DC))
return dyn_cast<CXXRecordDecl>(D);
D = cast<Decl>(DC);
DC = getEffectiveDeclContext(D);
@@ -306,7 +314,9 @@ private:
void mangleUnscopedTemplateName(const TemplateDecl *ND);
void mangleUnscopedTemplateName(TemplateName);
void mangleSourceName(const IdentifierInfo *II);
- void mangleLocalName(const NamedDecl *ND);
+ void mangleLocalName(const Decl *D);
+ void mangleBlockForPrefix(const BlockDecl *Block);
+ void mangleUnqualifiedBlock(const BlockDecl *Block);
void mangleLambda(const CXXRecordDecl *Lambda);
void mangleNestedName(const NamedDecl *ND, const DeclContext *DC,
bool NoFunction=false);
@@ -551,8 +561,7 @@ void CXXNameMangler::mangleName(const Na
// is that of the containing namespace, or the translation unit.
// FIXME: This is a hack; extern variables declared locally should have
// a proper semantic declaration context!
- if ((isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) &&
- ND->hasLinkage() && !isLambda(ND))
+ if (isLocalContainerContext(DC) && ND->hasLinkage() && !isLambda(ND))
while (!DC->isNamespace() && !DC->isTranslationUnit())
DC = getEffectiveParentContext(DC);
else if (GetLocalClassDecl(ND)) {
@@ -575,7 +584,7 @@ void CXXNameMangler::mangleName(const Na
return;
}
- if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) {
+ if (isLocalContainerContext(DC)) {
mangleLocalName(ND);
return;
}
@@ -1264,21 +1273,22 @@ void CXXNameMangler::mangleNestedName(co
Out << 'E';
}
-void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
+void CXXNameMangler::mangleLocalName(const Decl *D) {
// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
// := Z <function encoding> E s [<discriminator>]
// <local-name> := Z <function encoding> E d [ <parameter number> ]
// _ <entity name>
// <discriminator> := _ <non-negative number>
- const CXXRecordDecl *RD = GetLocalClassDecl(ND);
- const DeclContext *DC = getEffectiveDeclContext(RD ? RD : ND);
+ assert(isa<NamedDecl>(D) || isa<BlockDecl>(D));
+ const CXXRecordDecl *RD = GetLocalClassDecl(D);
+ const DeclContext *DC = getEffectiveDeclContext(RD ? RD : D);
Out << 'Z';
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC))
mangleObjCMethodName(MD);
else if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC))
- manglePrefix(BD); // FIXME: This isn't right.
+ mangleBlockForPrefix(BD);
else
mangleFunctionEncoding(cast<FunctionDecl>(DC));
@@ -1307,10 +1317,16 @@ void CXXNameMangler::mangleLocalName(con
}
// Mangle the name relative to the closest enclosing function.
- if (ND == RD) // equality ok because RD derived from ND above
- mangleUnqualifiedName(ND);
- else
+ // equality ok because RD derived from ND above
+ if (D == RD) {
+ mangleUnqualifiedName(RD);
+ } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
+ manglePrefix(getEffectiveDeclContext(BD), true /*NoFunction*/);
+ mangleUnqualifiedBlock(BD);
+ } else {
+ const NamedDecl *ND = cast<NamedDecl>(D);
mangleNestedName(ND, getEffectiveDeclContext(ND), true /*NoFunction*/);
+ }
if (!SkipDiscriminator) {
unsigned disc;
@@ -1325,7 +1341,48 @@ void CXXNameMangler::mangleLocalName(con
return;
}
- mangleUnqualifiedName(ND);
+ if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
+ mangleUnqualifiedBlock(BD);
+ else
+ mangleUnqualifiedName(cast<NamedDecl>(D));
+}
+
+void CXXNameMangler::mangleBlockForPrefix(const BlockDecl *Block) {
+ if (GetLocalClassDecl(Block)) {
+ mangleLocalName(Block);
+ return;
+ }
+ const DeclContext *DC = getEffectiveDeclContext(Block);
+ if (isLocalContainerContext(DC)) {
+ mangleLocalName(Block);
+ return;
+ }
+ manglePrefix(getEffectiveDeclContext(Block));
+ mangleUnqualifiedBlock(Block);
+}
+
+void CXXNameMangler::mangleUnqualifiedBlock(const BlockDecl *Block) {
+ if (Decl *Context = Block->getBlockManglingContextDecl()) {
+ if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) &&
+ Context->getDeclContext()->isRecord()) {
+ if (const IdentifierInfo *Name
+ = cast<NamedDecl>(Context)->getIdentifier()) {
+ mangleSourceName(Name);
+ Out << 'M';
+ }
+ }
+ }
+
+ // 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)
+ Out << Number - 2;
+ Out << '_';
}
void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {
@@ -1411,30 +1468,11 @@ void CXXNameMangler::manglePrefix(const
if (DC->isTranslationUnit())
return;
- if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
- // 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)
- Out << Number - 2;
- Out << '_';
- return;
- } else if (isa<CapturedDecl>(DC)) {
- // Skip CapturedDecl context.
- manglePrefix(getEffectiveParentContext(DC), NoFunction);
+ if (NoFunction && isLocalContainerContext(DC))
return;
- }
-
+
+ assert(!isLocalContainerContext(DC));
+
const NamedDecl *ND = cast<NamedDecl>(DC);
if (mangleSubstitution(ND))
return;
@@ -1444,12 +1482,7 @@ void CXXNameMangler::manglePrefix(const
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
mangleTemplatePrefix(TD);
mangleTemplateArgs(*TemplateArgs);
- }
- else if(NoFunction && (isa<FunctionDecl>(ND) || isa<ObjCMethodDecl>(ND)))
- return;
- else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
- mangleObjCMethodName(Method);
- else {
+ } else {
manglePrefix(getEffectiveDeclContext(ND), NoFunction);
mangleUnqualifiedName(ND);
}
Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm?rev=185450&r1=185449&r2=185450&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm Tue Jul 2 12:52:28 2013
@@ -14,7 +14,7 @@ namespace PR12746 {
}
// CHECK: define internal zeroext i1 @___ZN7PR127462f1EPi_block_invoke
- // CHECK: call zeroext i1 @"_ZZ7PR127462f1Ub_ENK3$_0clEv"
+ // CHECK: call zeroext i1 @"_ZZZN7PR127462f1EPiEUb_ENK3$_0clEv"
bool f2(int *x) {
auto outer = [&]() -> bool {
Modified: cfe/trunk/test/CodeGenCXX/captured-statements.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/captured-statements.cpp?rev=185450&r1=185449&r2=185450&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/captured-statements.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/captured-statements.cpp Tue Jul 2 12:52:28 2013
@@ -165,7 +165,7 @@ void template_capture_lambda() {
}
void test_capture_lambda() {
- // CHECK-6: define {{.*}} void @_ZZ23template_capture_lambdaIiEvvENKS_IiEUlvE_clEv
+ // CHECK-6: define {{.*}} void @_ZZ23template_capture_lambdaIiEvvENKUlvE_clEv
// CHECK-6-NOT: }
// CHECK-6: store i32*
// CHECK-6: store i32*
@@ -175,7 +175,7 @@ void test_capture_lambda() {
}
inline int test_captured_linkage() {
- // CHECK-7: @_ZN21test_captured_linkage1iE = linkonce_odr global i32 0
+ // CHECK-7: @_ZZ21test_captured_linkagevE1i = linkonce_odr global i32 0
int j;
#pragma clang __debug captured
{
Modified: cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp?rev=185450&r1=185449&r2=185450&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-lambdas.cpp Tue Jul 2 12:52:28 2013
@@ -160,7 +160,7 @@ void func_template(T = []{ return T(); }
// CHECK: define void @_Z17use_func_templatev()
void use_func_template() {
- // CHECK: call i32 @"_ZZ13func_templateIiEvT_ENKS_IiE3$_3clEv"
+ // CHECK: call i32 @"_ZZ13func_templateIiEvT_ENK3$_3clEv"
func_template<int>();
}
@@ -205,8 +205,8 @@ namespace PR12808 {
void f() {
b<int>(1);
}
- // CHECK: define linkonce_odr void @_ZZN7PR128081bIiEEviENKS0_IiEUlvE_clEv
- // CHECK: define linkonce_odr i32 @_ZZZN7PR128081bIiEEviENKS0_IiEUlvE_clEvENKUlvE_clEv
+ // CHECK: define linkonce_odr void @_ZZN7PR128081bIiEEviENKUlvE_clEv
+ // CHECK: define linkonce_odr i32 @_ZZZN7PR128081bIiEEviENKUlvE_clEvENKUlvE_clEv
}
// CHECK: define linkonce_odr void @_Z1fIZZNK23TestNestedInstantiationclEvENKUlvE_clEvEUlvE_EvT_
Modified: cfe/trunk/test/CodeGenObjCXX/mangle-blocks.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/mangle-blocks.mm?rev=185450&r1=185449&r2=185450&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjCXX/mangle-blocks.mm (original)
+++ cfe/trunk/test/CodeGenObjCXX/mangle-blocks.mm Tue Jul 2 12:52:28 2013
@@ -1,14 +1,14 @@
// RUN: %clang_cc1 -emit-llvm -fblocks -o - -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck %s
-// CHECK: @_ZGVN3fooUb_5valueE = internal global i64 0
-// CHECK: @_ZN26externally_visible_statics1SUb_1jE = linkonce_odr global i32 0
-// CHECK: @_ZN26externally_visible_statics10inlinefuncUb_1iE = linkonce_odr global i32 0
+// CHECK: @_ZGVZZ3foovEUb_E5value = internal global i64 0
+// CHECK: @_ZZ26externally_visible_statics1S1xMUb_E1j = linkonce_odr global i32 0
+// CHECK: @_ZZZN26externally_visible_statics10inlinefuncEvEUb_E1i = linkonce_odr global i32 0
int f();
void foo() {
// CHECK: define internal i32 @___Z3foov_block_invoke
- // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVN3fooUb_5valueE
+ // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZZ3foovEUb_E5value
(void)^(int x) {
static int value = f();
return x + value;
@@ -26,7 +26,7 @@ int i = ^(int x) { return x;}(i);
- (void)method {
// CHECK: define internal signext i8 @"__11-[A method]_block_invoke"
(void)^(int x) {
- // CHECK: @"_ZN11-[A method]Ub0_4nameE"
+ // CHECK: @"_ZZZ11-[A method]EUb0_E4name"
static const char *name = "hello";
return name[x];
};
@@ -44,7 +44,7 @@ namespace N {
// CHECK: define internal signext i8 @___Z3fooi_block_invoke
void bar() {
(void)^(int x) {
- // CHECK: @_ZN1N3barUb2_4nameE
+ // CHECK: @_ZZZN1N3barEvEUb2_E4name
static const char *name = "hello";
return name[x];
};
@@ -56,7 +56,7 @@ class C {
};
C::C() {
(void)^(int x) {
- // CHECK: @_ZN1CC1Ub3_5namebE
+ // CHECK: @_ZZZN1CC1EvEUb3_E5nameb
static const char *nameb = "hello";
return nameb[x];
};
More information about the cfe-commits
mailing list