majnemer created this revision.
majnemer added a reviewer: rnk.
majnemer added a subscriber: cfe-commits.

We didn't implement one of the corner cases: a lambda which belongs to
an initializer for a field.  In this case, we need to mangle the field
name into the lambda.

This fixes PR31197.


https://reviews.llvm.org/D27226

Files:
  lib/AST/MicrosoftMangle.cpp
  test/CodeGenCXX/mangle-ms-cxx11.cpp


Index: test/CodeGenCXX/mangle-ms-cxx11.cpp
===================================================================
--- test/CodeGenCXX/mangle-ms-cxx11.cpp
+++ test/CodeGenCXX/mangle-ms-cxx11.cpp
@@ -318,3 +318,20 @@
 
 // CHECK-DAG: @"\01?unaligned_foo8@unaligned_foo8_S@@QFCEXXZ"
 
+namespace PR31197 {
+struct A {
+  // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* 
@"\01??R<lambda_1>@x@A@PR31197@@QBE@XZ"(
+  int *x = []() {
+    static int white;
+    // CHECK-DAG: @"\01?white@?1???R<lambda_1>@x@A@PR31197@@QBE@XZ@4HA"
+    return &white;
+  }();
+  // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* 
@"\01??R<lambda_1>@y@A@PR31197@@QBE@XZ"(
+  int *y = []() {
+    static int black;
+    // CHECK-DAG: @"\01?black@?1???R<lambda_1>@y@A@PR31197@@QBE@XZ@4HA"
+    return &black;
+  }();
+};
+A a;
+}
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -824,16 +824,28 @@
       if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
         if (Record->isLambda()) {
           llvm::SmallString<10> Name("<lambda_");
+          unsigned LambdaManglingNumber = Record->getLambdaManglingNumber();
           unsigned LambdaId;
-          if (Record->getLambdaManglingNumber())
-            LambdaId = Record->getLambdaManglingNumber();
+          if (LambdaManglingNumber)
+            LambdaId = LambdaManglingNumber;
           else
             LambdaId = Context.getLambdaId(Record);
 
           Name += llvm::utostr(LambdaId);
           Name += ">";
 
           mangleSourceName(Name);
+
+          // If the context of a closure type is an initializer for a class
+          // member (static or nonstatic), it is encoded in a qualified name.
+          if (LambdaManglingNumber) {
+            if (Decl *Context = Record->getLambdaContextDecl()) {
+              if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) &&
+                  Context->getDeclContext()->isRecord()) {
+                mangleUnqualifiedName(cast<NamedDecl>(Context));
+              }
+            }
+          }
           break;
         }
       }


Index: test/CodeGenCXX/mangle-ms-cxx11.cpp
===================================================================
--- test/CodeGenCXX/mangle-ms-cxx11.cpp
+++ test/CodeGenCXX/mangle-ms-cxx11.cpp
@@ -318,3 +318,20 @@
 
 // CHECK-DAG: @"\01?unaligned_foo8@unaligned_foo8_S@@QFCEXXZ"
 
+namespace PR31197 {
+struct A {
+  // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* @"\01??R<lambda_1>@x@A@PR31197@@QBE@XZ"(
+  int *x = []() {
+    static int white;
+    // CHECK-DAG: @"\01?white@?1???R<lambda_1>@x@A@PR31197@@QBE@XZ@4HA"
+    return &white;
+  }();
+  // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* @"\01??R<lambda_1>@y@A@PR31197@@QBE@XZ"(
+  int *y = []() {
+    static int black;
+    // CHECK-DAG: @"\01?black@?1???R<lambda_1>@y@A@PR31197@@QBE@XZ@4HA"
+    return &black;
+  }();
+};
+A a;
+}
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -824,16 +824,28 @@
       if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
         if (Record->isLambda()) {
           llvm::SmallString<10> Name("<lambda_");
+          unsigned LambdaManglingNumber = Record->getLambdaManglingNumber();
           unsigned LambdaId;
-          if (Record->getLambdaManglingNumber())
-            LambdaId = Record->getLambdaManglingNumber();
+          if (LambdaManglingNumber)
+            LambdaId = LambdaManglingNumber;
           else
             LambdaId = Context.getLambdaId(Record);
 
           Name += llvm::utostr(LambdaId);
           Name += ">";
 
           mangleSourceName(Name);
+
+          // If the context of a closure type is an initializer for a class
+          // member (static or nonstatic), it is encoded in a qualified name.
+          if (LambdaManglingNumber) {
+            if (Decl *Context = Record->getLambdaContextDecl()) {
+              if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) &&
+                  Context->getDeclContext()->isRecord()) {
+                mangleUnqualifiedName(cast<NamedDecl>(Context));
+              }
+            }
+          }
           break;
         }
       }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to