]> granicus.if.org Git - clang/commitdiff
Don't skip lambdas when mangling local vars.
authorEli Friedman <eli.friedman@gmail.com>
Tue, 2 Jul 2013 02:01:18 +0000 (02:01 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Tue, 2 Jul 2013 02:01:18 +0000 (02:01 +0000)
This commit rearranges the logic in CXXNameMangler::mangleLocalName and
GetLocalClassDecl so that it doesn't accidentally skip over lambdas.  It
also reduces code duplication a bit.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185402 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ItaniumMangle.cpp
test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm
test/CodeGenCXX/mangle-lambdas.cpp

index 394e70759a7976199fdcb62d7a4aa200e53d39ee..7948ef7de067e6105c780b7559482cea1f55f64d 100644 (file)
@@ -64,15 +64,13 @@ static const DeclContext *getEffectiveParentContext(const DeclContext *DC) {
   return getEffectiveDeclContext(cast<Decl>(DC));
 }
   
-static const CXXRecordDecl *GetLocalClassDecl(const NamedDecl *ND) {
-  const DeclContext *DC = dyn_cast<DeclContext>(ND);
-  if (!DC)
-    DC = getEffectiveDeclContext(ND);
+static const CXXRecordDecl *GetLocalClassDecl(const Decl *D) {
+  const DeclContext *DC = getEffectiveDeclContext(D);
   while (!DC->isNamespace() && !DC->isTranslationUnit()) {
-    const DeclContext *Parent = getEffectiveDeclContext(cast<Decl>(DC));
-    if (isa<FunctionDecl>(Parent))
-      return dyn_cast<CXXRecordDecl>(DC);
-    DC = Parent;
+    if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC) || isa<BlockDecl>(DC))
+      return dyn_cast<CXXRecordDecl>(D);
+    D = cast<Decl>(DC);
+    DC = getEffectiveDeclContext(D);
   }
   return 0;
 }
@@ -1272,16 +1270,21 @@ void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
   // <local-name> := Z <function encoding> E d [ <parameter number> ] 
   //                 _ <entity name>
   // <discriminator> := _ <non-negative number>
-  const DeclContext *DC = getEffectiveDeclContext(ND);
+  const CXXRecordDecl *RD = GetLocalClassDecl(ND);
+  const DeclContext *DC = getEffectiveDeclContext(RD ? RD : ND);
 
   Out << 'Z';
 
-  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) {
-   mangleObjCMethodName(MD);
-  } else if (const CXXRecordDecl *RD = GetLocalClassDecl(ND)) {
-    mangleFunctionEncoding(cast<FunctionDecl>(getEffectiveDeclContext(RD)));
-    Out << 'E';
+  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.
+  else
+    mangleFunctionEncoding(cast<FunctionDecl>(DC));
 
+  Out << 'E';
+
+  if (RD) {
     // The parameter number is omitted for the last parameter, 0 for the 
     // second-to-last parameter, 1 for the third-to-last parameter, etc. The 
     // <entity name> will of course contain a <closure-type-name>: Its 
@@ -1307,7 +1310,7 @@ void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
     if (ND == RD) // equality ok because RD derived from ND above
       mangleUnqualifiedName(ND);
     else
-      mangleNestedName(ND, DC, true /*NoFunction*/);
+      mangleNestedName(ND, getEffectiveDeclContext(ND), true /*NoFunction*/);
 
     if (!SkipDiscriminator) {
       unsigned disc;
@@ -1321,10 +1324,7 @@ void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
     
     return;
   }
-  else
-    mangleFunctionEncoding(cast<FunctionDecl>(DC));
 
-  Out << 'E';
   mangleUnqualifiedName(ND);
 }
 
index 39f59a3fecc310f2c64e24b8d093407f0b21ecaa..a86770d24f3b549307bba04197fd5f596b595f43 100644 (file)
@@ -14,7 +14,7 @@ namespace PR12746 {
   }
 
   // CHECK: define internal zeroext i1 @___ZN7PR127462f1EPi_block_invoke
-  // CHECK: call zeroext i1 @"_ZNK7PR127462f1Ub_3$_0clEv"
+  // CHECK: call zeroext i1 @"_ZZ7PR127462f1Ub_ENK3$_0clEv"
 
   bool f2(int *x) {
     auto outer = [&]() -> bool {
index a9c3ace8a63ad7cac9fd03628b516925907fe05d..76839e1c9d2c7c1b63fd3e0a6a8d67b7cf9258f4 100644 (file)
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s | FileCheck %s
 
 // CHECK: @_ZZNK7PR12917IJiiEE1nMUlvE_clEvE1n = linkonce_odr global i32 0
-// CHECK: @_ZZN7PR12917IJicdEEC1EicdEd_N1nE = linkonce_odr global i32 0
-// CHECK: @_ZZN7PR12917IJicdEEC1EicdEd0_N1nE = linkonce_odr global i32 0
-// CHECK: @_ZZN7PR12917IJicdEEC1EicdEd1_N1nE = linkonce_odr global i32 0
+// CHECK: @_ZZZN7PR12917IJicdEEC1EicdEd_NKUlvE_clEvE1n = linkonce_odr global i32 0
+// CHECK: @_ZZZN7PR12917IJicdEEC1EicdEd0_NKUlvE_clEvE1n = linkonce_odr global i32 0
+// CHECK: @_ZZZN7PR12917IJicdEEC1EicdEd1_NKUlvE_clEvE1n = linkonce_odr global i32 0
 
 // CHECK: define linkonce_odr void @_Z11inline_funci
 inline void inline_func(int n) {