[PATCH] D27226: [MS ABI] Implement more of the Itanium mangling rules

2016-12-06 Thread David Majnemer via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL288826: [MS ABI] Implement more of the Itanium mangling 
rules (authored by majnemer).

Changed prior to commit:
  https://reviews.llvm.org/D27226?vs=80096=80437#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D27226

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

Index: cfe/trunk/lib/AST/MicrosoftMangle.cpp
===
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp
@@ -66,6 +66,16 @@
   }
 };
 
+static const DeclContext *
+getLambdaDefaultArgumentDeclContext(const Decl *D) {
+  if (const auto *RD = dyn_cast(D))
+if (RD->isLambda())
+  if (const auto *Parm =
+  dyn_cast_or_null(RD->getLambdaContextDecl()))
+return Parm->getDeclContext();
+  return nullptr;
+}
+
 /// \brief Retrieve the declaration context that should be used when mangling
 /// the given declaration.
 static const DeclContext *getEffectiveDeclContext(const Decl *D) {
@@ -75,12 +85,8 @@
   // not the case: the lambda closure type ends up living in the context
   // where the function itself resides, because the function declaration itself
   // had not yet been created. Fix the context here.
-  if (const CXXRecordDecl *RD = dyn_cast(D)) {
-if (RD->isLambda())
-  if (ParmVarDecl *ContextParam =
-  dyn_cast_or_null(RD->getLambdaContextDecl()))
-return ContextParam->getDeclContext();
-  }
+  if (const auto *LDADC = getLambdaDefaultArgumentDeclContext(D))
+return LDADC;
 
   // Perform the same check for block literals.
   if (const BlockDecl *BD = dyn_cast(D)) {
@@ -112,14 +118,6 @@
   return FD;
 }
 
-static bool isLambda(const NamedDecl *ND) {
-  const CXXRecordDecl *Record = dyn_cast(ND);
-  if (!Record)
-return false;
-
-  return Record->isLambda();
-}
-
 /// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
 /// Microsoft Visual C++ ABI.
 class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
@@ -200,9 +198,11 @@
 
 // Lambda closure types are already numbered, give out a phony number so
 // that they demangle nicely.
-if (isLambda(ND)) {
-  disc = 1;
-  return true;
+if (const auto *RD = dyn_cast(ND)) {
+  if (RD->isLambda()) {
+disc = 1;
+return true;
+  }
 }
 
 // Use the canonical number for externally visible decls.
@@ -824,16 +824,41 @@
   if (const CXXRecordDecl *Record = dyn_cast(TD)) {
 if (Record->isLambda()) {
   llvm::SmallString<10> Name("getLambdaContextDecl();
+  unsigned LambdaManglingNumber = Record->getLambdaManglingNumber();
   unsigned LambdaId;
-  if (Record->getLambdaManglingNumber())
-LambdaId = Record->getLambdaManglingNumber();
+  const ParmVarDecl *Parm =
+  dyn_cast_or_null(LambdaContextDecl);
+  const FunctionDecl *Func =
+  Parm ? dyn_cast(Parm->getDeclContext()) : nullptr;
+
+  if (Func) {
+unsigned DefaultArgNo =
+Func->getNumParams() - Parm->getFunctionScopeIndex();
+Name += llvm::utostr(DefaultArgNo);
+Name += "_";
+  }
+
+  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 && LambdaContextDecl) {
+if ((isa(LambdaContextDecl) ||
+ isa(LambdaContextDecl)) &&
+LambdaContextDecl->getDeclContext()->isRecord()) {
+  mangleUnqualifiedName(cast(LambdaContextDecl));
+}
+  }
   break;
 }
   }
@@ -937,16 +962,22 @@
   // for how this should be done.
   Out << "__block_invoke" << Context.getBlockId(BD, false);
   Out << '@';
-  continue;
 } else if (const ObjCMethodDecl *Method = dyn_cast(DC)) {
   mangleObjCMethodName(Method);
 } else if (isa(DC)) {
   ND = cast(DC);
   if (const FunctionDecl *FD = dyn_cast(ND)) {
 mangle(FD, "?");
 break;
-  } else
+  } else {
 mangleUnqualifiedName(ND);
+// Lambdas in default arguments conceptually belong to the function the
+// parameter corresponds to.
+if (const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {
+  DC = LDADC;
+  continue;
+}
+  }
 }
 DC = DC->getParent();
   }
Index: cfe/trunk/test/CodeGenCXX/mangle-ms-cxx11.cpp

[PATCH] D27226: [MS ABI] Implement more of the Itanium mangling rules

2016-12-06 Thread Reid Kleckner via Phabricator via cfe-commits
rnk accepted this revision.
rnk added a comment.
This revision is now accepted and ready to land.

lgtm Thanks, apologies for the scope creep.


https://reviews.llvm.org/D27226



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27226: [MS ABI] Implement more of the Itanium mangling rules

2016-12-02 Thread David Majnemer via Phabricator via cfe-commits
majnemer updated this revision to Diff 80096.
majnemer added a comment.

- Simplify the mangling a little bit


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,28 @@
 
 // CHECK-DAG: @"\01?unaligned_foo8@unaligned_foo8_S@@QFCEXXZ"
 
+namespace PR31197 {
+struct A {
+  // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* @"\01??R@x@A@PR31197@@QBE@XZ"(
+  int *x = []() {
+static int white;
+// CHECK-DAG: @"\01?white@?1???R@x@A@PR31197@@QBE@XZ@4HA"
+return 
+  }();
+  // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* @"\01??R@y@A@PR31197@@QBE@XZ"(
+  int *y = []() {
+static int black;
+// CHECK-DAG: @"\01?black@?1???R@y@A@PR31197@@QBE@XZ@4HA"
+return 
+  }();
+  using FPtrTy = void(void);
+  static void default_args(FPtrTy x = [] {}, FPtrTy y = [] {}, int z = [] { return 1; }() + [] { return 2; }()) {}
+  // CHECK-DAG: @"\01??R@?0??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+  // CHECK-DAG: @"\01??R@?0??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+  // CHECK-DAG: @"\01??R@?0??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+  // CHECK-DAG: @"\01??R@?0??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+};
+A a;
+
+int call_it = (A::default_args(), 1);
+}
Index: lib/AST/MicrosoftMangle.cpp
===
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -66,6 +66,16 @@
   }
 };
 
+static const DeclContext *
+getLambdaDefaultArgumentDeclContext(const Decl *D) {
+  if (const auto *RD = dyn_cast(D))
+if (RD->isLambda())
+  if (const auto *Parm =
+  dyn_cast_or_null(RD->getLambdaContextDecl()))
+return Parm->getDeclContext();
+  return nullptr;
+}
+
 /// \brief Retrieve the declaration context that should be used when mangling
 /// the given declaration.
 static const DeclContext *getEffectiveDeclContext(const Decl *D) {
@@ -75,12 +85,8 @@
   // not the case: the lambda closure type ends up living in the context
   // where the function itself resides, because the function declaration itself
   // had not yet been created. Fix the context here.
-  if (const CXXRecordDecl *RD = dyn_cast(D)) {
-if (RD->isLambda())
-  if (ParmVarDecl *ContextParam =
-  dyn_cast_or_null(RD->getLambdaContextDecl()))
-return ContextParam->getDeclContext();
-  }
+  if (const auto *LDADC = getLambdaDefaultArgumentDeclContext(D))
+return LDADC;
 
   // Perform the same check for block literals.
   if (const BlockDecl *BD = dyn_cast(D)) {
@@ -112,14 +118,6 @@
   return FD;
 }
 
-static bool isLambda(const NamedDecl *ND) {
-  const CXXRecordDecl *Record = dyn_cast(ND);
-  if (!Record)
-return false;
-
-  return Record->isLambda();
-}
-
 /// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
 /// Microsoft Visual C++ ABI.
 class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
@@ -200,9 +198,11 @@
 
 // Lambda closure types are already numbered, give out a phony number so
 // that they demangle nicely.
-if (isLambda(ND)) {
-  disc = 1;
-  return true;
+if (const auto *RD = dyn_cast(ND)) {
+  if (RD->isLambda()) {
+disc = 1;
+return true;
+  }
 }
 
 // Use the canonical number for externally visible decls.
@@ -824,16 +824,41 @@
   if (const CXXRecordDecl *Record = dyn_cast(TD)) {
 if (Record->isLambda()) {
   llvm::SmallString<10> Name("getLambdaContextDecl();
+  unsigned LambdaManglingNumber = Record->getLambdaManglingNumber();
   unsigned LambdaId;
-  if (Record->getLambdaManglingNumber())
-LambdaId = Record->getLambdaManglingNumber();
+  const ParmVarDecl *Parm =
+  dyn_cast_or_null(LambdaContextDecl);
+  const FunctionDecl *Func =
+  Parm ? dyn_cast(Parm->getDeclContext()) : nullptr;
+
+  if (Func) {
+unsigned DefaultArgNo =
+Func->getNumParams() - Parm->getFunctionScopeIndex();
+Name += llvm::utostr(DefaultArgNo);
+Name += "_";
+  }
+
+  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 && LambdaContextDecl) {
+if ((isa(LambdaContextDecl) ||
+ isa(LambdaContextDecl)) &&
+

[PATCH] D27226: [MS ABI] Implement more of the Itanium mangling rules

2016-11-30 Thread David Majnemer via Phabricator via cfe-commits
majnemer updated this revision to Diff 79848.
majnemer marked an inline comment as done.
majnemer added a comment.

- Address review comments


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,28 @@
 
 // CHECK-DAG: @"\01?unaligned_foo8@unaligned_foo8_S@@QFCEXXZ"
 
+namespace PR31197 {
+struct A {
+  // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* @"\01??R@x@A@PR31197@@QBE@XZ"(
+  int *x = []() {
+static int white;
+// CHECK-DAG: @"\01?white@?1???R@x@A@PR31197@@QBE@XZ@4HA"
+return 
+  }();
+  // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* @"\01??R@y@A@PR31197@@QBE@XZ"(
+  int *y = []() {
+static int black;
+// CHECK-DAG: @"\01?black@?1???R@y@A@PR31197@@QBE@XZ@4HA"
+return 
+  }();
+  using FPtrTy = void(void);
+  static void default_args(FPtrTy x = [] {}, FPtrTy y = [] {}, int z = [] { return 1; }() + [] { return 2; }()) {}
+  // CHECK-DAG: @"\01??R@?A@??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+  // CHECK-DAG: @"\01??R@?A@??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+  // CHECK-DAG: @"\01??R@?A@??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+  // CHECK-DAG: @"\01??R@?A@??default_args@A@PR31197@@SAXP6AXXZ0H@Z@QBE@XZ"(
+};
+A a;
+
+int call_it = (A::default_args(), 1);
+}
Index: lib/AST/MicrosoftMangle.cpp
===
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -66,6 +66,16 @@
   }
 };
 
+static const DeclContext *
+getLambdaDefaultArgumentDeclContext(const Decl *D) {
+  if (const auto *RD = dyn_cast(D))
+if (RD->isLambda())
+  if (const auto *Parm =
+  dyn_cast_or_null(RD->getLambdaContextDecl()))
+return Parm->getDeclContext();
+  return nullptr;
+}
+
 /// \brief Retrieve the declaration context that should be used when mangling
 /// the given declaration.
 static const DeclContext *getEffectiveDeclContext(const Decl *D) {
@@ -75,12 +85,8 @@
   // not the case: the lambda closure type ends up living in the context
   // where the function itself resides, because the function declaration itself
   // had not yet been created. Fix the context here.
-  if (const CXXRecordDecl *RD = dyn_cast(D)) {
-if (RD->isLambda())
-  if (ParmVarDecl *ContextParam =
-  dyn_cast_or_null(RD->getLambdaContextDecl()))
-return ContextParam->getDeclContext();
-  }
+  if (const auto *LDADC = getLambdaDefaultArgumentDeclContext(D))
+return LDADC;
 
   // Perform the same check for block literals.
   if (const BlockDecl *BD = dyn_cast(D)) {
@@ -112,14 +118,6 @@
   return FD;
 }
 
-static bool isLambda(const NamedDecl *ND) {
-  const CXXRecordDecl *Record = dyn_cast(ND);
-  if (!Record)
-return false;
-
-  return Record->isLambda();
-}
-
 /// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
 /// Microsoft Visual C++ ABI.
 class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
@@ -200,9 +198,12 @@
 
 // Lambda closure types are already numbered, give out a phony number so
 // that they demangle nicely.
-if (isLambda(ND)) {
-  disc = 1;
-  return true;
+// Use scope zero for lambdas in default arguments, one for all other lambdas.
+if (const auto *RD = dyn_cast(ND)) {
+  if (RD->isLambda()) {
+disc = getLambdaDefaultArgumentDeclContext(RD) ? 0 : 1;
+return true;
+  }
 }
 
 // Use the canonical number for externally visible decls.
@@ -824,16 +825,41 @@
   if (const CXXRecordDecl *Record = dyn_cast(TD)) {
 if (Record->isLambda()) {
   llvm::SmallString<10> Name("getLambdaContextDecl();
+  unsigned LambdaManglingNumber = Record->getLambdaManglingNumber();
   unsigned LambdaId;
-  if (Record->getLambdaManglingNumber())
-LambdaId = Record->getLambdaManglingNumber();
+  const ParmVarDecl *Parm =
+  dyn_cast_or_null(LambdaContextDecl);
+  const FunctionDecl *Func =
+  Parm ? dyn_cast(Parm->getDeclContext()) : nullptr;
+
+  if (Func) {
+unsigned DefaultArgNo =
+Func->getNumParams() - Parm->getFunctionScopeIndex();
+Name += llvm::utostr(DefaultArgNo);
+Name += "_";
+  }
+
+  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.

[PATCH] D27226: [MS ABI] Implement more of the Itanium mangling rules

2016-11-30 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added inline comments.



Comment at: lib/AST/MicrosoftMangle.cpp:838
+  if (Func)
+LambdaId = Func->getNumParams() - Parm->getFunctionScopeIndex();
+  else if (LambdaManglingNumber)

Isn't this no good if I have two lambdas in one default arg?
  inline int f(int x = [] { return 1; }() + [] { return 2; }()) { return x; }
  int main() { return f(); }
We probably need . =/


https://reviews.llvm.org/D27226



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27226: [MS ABI] Implement more of the Itanium mangling rules

2016-11-30 Thread David Majnemer via Phabricator via cfe-commits
majnemer updated this revision to Diff 79837.
majnemer added a comment.

- Address review comments


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,26 @@
 
 // CHECK-DAG: @"\01?unaligned_foo8@unaligned_foo8_S@@QFCEXXZ"
 
+namespace PR31197 {
+struct A {
+  // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* @"\01??R@x@A@PR31197@@QBE@XZ"(
+  int *x = []() {
+static int white;
+// CHECK-DAG: @"\01?white@?1???R@x@A@PR31197@@QBE@XZ@4HA"
+return 
+  }();
+  // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* @"\01??R@y@A@PR31197@@QBE@XZ"(
+  int *y = []() {
+static int black;
+// CHECK-DAG: @"\01?black@?1???R@y@A@PR31197@@QBE@XZ@4HA"
+return 
+  }();
+  using FPtrTy = void(void);
+  static void default_args(FPtrTy x = [] {}, FPtrTy y = [] {}) {}
+  // CHECK-DAG: @"\01??R@?A@??default_args@A@PR31197@@SAXP6AXXZ0@Z@QBE@XZ"(
+  // CHECK-DAG: @"\01??R@?A@??default_args@A@PR31197@@SAXP6AXXZ0@Z@QBE@XZ"(
+};
+A a;
+
+int call_it = (A::default_args(), 1);
+}
Index: lib/AST/MicrosoftMangle.cpp
===
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -66,6 +66,16 @@
   }
 };
 
+static const DeclContext *
+getLambdaDefaultArgumentDeclContext(const Decl *D) {
+  if (const auto *RD = dyn_cast(D))
+if (RD->isLambda())
+  if (const auto *Parm =
+  dyn_cast_or_null(RD->getLambdaContextDecl()))
+return Parm->getDeclContext();
+  return nullptr;
+}
+
 /// \brief Retrieve the declaration context that should be used when mangling
 /// the given declaration.
 static const DeclContext *getEffectiveDeclContext(const Decl *D) {
@@ -75,12 +85,8 @@
   // not the case: the lambda closure type ends up living in the context
   // where the function itself resides, because the function declaration itself
   // had not yet been created. Fix the context here.
-  if (const CXXRecordDecl *RD = dyn_cast(D)) {
-if (RD->isLambda())
-  if (ParmVarDecl *ContextParam =
-  dyn_cast_or_null(RD->getLambdaContextDecl()))
-return ContextParam->getDeclContext();
-  }
+  if (const auto *LDADC = getLambdaDefaultArgumentDeclContext(D))
+return LDADC;
 
   // Perform the same check for block literals.
   if (const BlockDecl *BD = dyn_cast(D)) {
@@ -112,14 +118,6 @@
   return FD;
 }
 
-static bool isLambda(const NamedDecl *ND) {
-  const CXXRecordDecl *Record = dyn_cast(ND);
-  if (!Record)
-return false;
-
-  return Record->isLambda();
-}
-
 /// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
 /// Microsoft Visual C++ ABI.
 class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
@@ -200,9 +198,12 @@
 
 // Lambda closure types are already numbered, give out a phony number so
 // that they demangle nicely.
-if (isLambda(ND)) {
-  disc = 1;
-  return true;
+// Use scope zero for lambdas in default arguments, one for all other lambdas.
+if (const auto *RD = dyn_cast(ND)) {
+  if (RD->isLambda()) {
+disc = getLambdaDefaultArgumentDeclContext(RD) ? 0 : 1;
+return true;
+  }
 }
 
 // Use the canonical number for externally visible decls.
@@ -824,16 +825,36 @@
   if (const CXXRecordDecl *Record = dyn_cast(TD)) {
 if (Record->isLambda()) {
   llvm::SmallString<10> Name("getLambdaContextDecl();
+  unsigned LambdaManglingNumber = Record->getLambdaManglingNumber();
   unsigned LambdaId;
-  if (Record->getLambdaManglingNumber())
-LambdaId = Record->getLambdaManglingNumber();
+  const ParmVarDecl *Parm =
+  dyn_cast_or_null(LambdaContextDecl);
+  const FunctionDecl *Func =
+  Parm ? dyn_cast(Parm->getDeclContext()) : nullptr;
+
+  if (Func)
+LambdaId = Func->getNumParams() - Parm->getFunctionScopeIndex();
+  else 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 && LambdaContextDecl) {
+if ((isa(LambdaContextDecl) ||
+ isa(LambdaContextDecl)) &&
+LambdaContextDecl->getDeclContext()->isRecord()) {
+  mangleUnqualifiedName(cast(LambdaContextDecl));
+}
+  }
   break;
 }
   }
@@ -937,16 +958,22 @@

[PATCH] D27226: [MS ABI] Implement more of the Itanium mangling rules

2016-11-29 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added inline comments.



Comment at: test/CodeGenCXX/mangle-ms-cxx11.cpp:337
+A a;
+}

This machinery is also supposed to kick in for lambdas in default arguments, 
right? Can you add that test case?


https://reviews.llvm.org/D27226



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27226: [MS ABI] Implement more of the Itanium mangling rules

2016-11-29 Thread David Majnemer via Phabricator via cfe-commits
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@x@A@PR31197@@QBE@XZ"(
+  int *x = []() {
+static int white;
+// CHECK-DAG: @"\01?white@?1???R@x@A@PR31197@@QBE@XZ@4HA"
+return 
+  }();
+  // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* 
@"\01??R@y@A@PR31197@@QBE@XZ"(
+  int *y = []() {
+static int black;
+// CHECK-DAG: @"\01?black@?1???R@y@A@PR31197@@QBE@XZ@4HA"
+return 
+  }();
+};
+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(TD)) {
 if (Record->isLambda()) {
   llvm::SmallString<10> Name("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(Context) || isa(Context)) &&
+  Context->getDeclContext()->isRecord()) {
+mangleUnqualifiedName(cast(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@x@A@PR31197@@QBE@XZ"(
+  int *x = []() {
+static int white;
+// CHECK-DAG: @"\01?white@?1???R@x@A@PR31197@@QBE@XZ@4HA"
+return 
+  }();
+  // CHECK-DAG: define linkonce_odr x86_thiscallcc i32* @"\01??R@y@A@PR31197@@QBE@XZ"(
+  int *y = []() {
+static int black;
+// CHECK-DAG: @"\01?black@?1???R@y@A@PR31197@@QBE@XZ@4HA"
+return 
+  }();
+};
+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(TD)) {
 if (Record->isLambda()) {
   llvm::SmallString<10> Name("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(Context) || isa(Context)) &&
+  Context->getDeclContext()->isRecord()) {
+mangleUnqualifiedName(cast(Context));
+  }
+}
+  }
   break;
 }
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits