[PATCH] D27226: [MS ABI] Implement more of the Itanium mangling rules
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
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
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
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
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
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
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
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