summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShafik Yaghmour <syaghmour@apple.com>2019-08-14 22:30:29 +0000
committerShafik Yaghmour <syaghmour@apple.com>2019-08-14 22:30:29 +0000
commit62abe494fb36cd4c523d36f05cb0e3839df50c04 (patch)
tree5b9306c76f60fded49007107ffea012a4defe083
parent6ba7992031cc803a01f0622f4899668b15a20a98 (diff)
downloadbcm5719-llvm-62abe494fb36cd4c523d36f05cb0e3839df50c04.tar.gz
bcm5719-llvm-62abe494fb36cd4c523d36f05cb0e3839df50c04.zip
Improve anonymous class heuristic in ClangASTContext::CreateRecordType
Summary: Currently the heuristic used in ClangASTContext::CreateRecordType to identify an anonymous class is that there is that name is a nullptr or simply a null terminator. This heuristic is not accurate since it will also sweep up unnamed classes and lambdas. The improved heuristic relies on the requirement that an anonymous class must be contained within a class. Differential Revision: https://reviews.llvm.org/D66175 llvm-svn: 368937
-rw-r--r--lldb/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/TestCompletionCrashInLambda.py4
-rw-r--r--lldb/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/main.cpp6
-rw-r--r--lldb/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/TestCompletionInLambdaAndUnnamedClass.py4
-rw-r--r--lldb/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/main.cpp11
-rw-r--r--lldb/source/Symbol/ClangASTContext.cpp38
5 files changed, 49 insertions, 14 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/TestCompletionCrashInLambda.py b/lldb/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/TestCompletionCrashInLambda.py
deleted file mode 100644
index a04ec919972..00000000000
--- a/lldb/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")])
diff --git a/lldb/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/main.cpp b/lldb/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/main.cpp
deleted file mode 100644
index 3bce3f32f4a..00000000000
--- a/lldb/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())
- }
- ();
-}
diff --git a/lldb/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/TestCompletionInLambdaAndUnnamedClass.py b/lldb/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/TestCompletionInLambdaAndUnnamedClass.py
new file mode 100644
index 00000000000..57fb94b6d66
--- /dev/null
+++ b/lldb/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(),)
diff --git a/lldb/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/main.cpp b/lldb/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/main.cpp
new file mode 100644
index 00000000000..a3d8ab6532e
--- /dev/null
+++ b/lldb/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;
+}
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 6e1c90a6911..d07adebb822 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -1519,14 +1519,44 @@ CompilerType ClangASTContext::CreateRecordType(DeclContext *decl_ctx,
// 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 ? &ast->Idents.get(name) : nullptr);
- 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 (GNU/MSVC extension)
+ // 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<CXXRecordDecl>(decl_ctx)) {
+ decl->setAnonymousStructOrUnion(true);
+ }
+ }
if (decl) {
if (metadata)
OpenPOWER on IntegriCloud