Index: packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/TestCompletionCrashInLambda.py =================================================================== --- packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/TestCompletionCrashInLambda.py +++ /dev/null @@ -1,4 +0,0 @@ -from lldbsuite.test import lldbinline -from lldbsuite.test import decorators - -lldbinline.MakeInlineTest(__file__, globals(), [decorators.skipIf(bugnumber="rdar://53755023")]) Index: packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/main.cpp =================================================================== --- packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/main.cpp +++ /dev/null @@ -1,6 +0,0 @@ -int main() { - []() - { //%self.dbg.GetCommandInterpreter().HandleCompletion("e ", len("e "), 0, -1, lldb.SBStringList()) - } - (); -} Index: packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/TestCompletionInLambdaAndUnnamedClass.py =================================================================== --- /dev/null +++ packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/TestCompletionInLambdaAndUnnamedClass.py @@ -0,0 +1,4 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(),) Index: packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/main.cpp =================================================================== --- /dev/null +++ packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/main.cpp @@ -0,0 +1,11 @@ +int main() { + []() + { //%self.dbg.GetCommandInterpreter().HandleCompletion("e ", len("e "), 0, -1, lldb.SBStringList()) + } + (); + struct { + void f() + { //%self.dbg.GetCommandInterpreter().HandleCompletion("e ", len("e "), 0, -1, lldb.SBStringList()) + } + } A; +} Index: source/Symbol/ClangASTContext.cpp =================================================================== --- source/Symbol/ClangASTContext.cpp +++ source/Symbol/ClangASTContext.cpp @@ -1502,14 +1502,44 @@ // something is struct or a class, so we default to always use the more // complete definition just in case. - bool is_anonymous = (!name) || (!name[0]); + bool has_name = (!name) || (!name[0]); CXXRecordDecl *decl = CXXRecordDecl::Create( *ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), - SourceLocation(), is_anonymous ? nullptr : &ast->Idents.get(name)); + SourceLocation(), has_name ? nullptr : &ast->Idents.get(name)); - if (is_anonymous) - decl->setAnonymousStructOrUnion(true); + if (has_name) { + // In C++ a lambda is also represented as an unnamed class. This is + // different from an *anonymous class* that the user wrote: + // + // struct A { + // // anonymous class + // struct { + // int x; + // }; + // // unnamed class within a class + // struct { + // int y; + // } B; + // }; + // + // void f() { + // // unammed class outside of a class + // struct { + // int z; + // } C; + // } + // + // Anonymous classes is a GNU/MSVC extension that clang supports. It + // requires the anonymous class be embedded within a class. So the new + // heuristic verifies this condition. + // + // FIXME: An unnamed class within a class is also wrongly recognized as an + // anonymous struct. + if (CXXRecordDecl *record = dyn_cast(decl_ctx)) { + decl->setAnonymousStructOrUnion(true); + } + } if (decl) { if (metadata)