Author: shafik
Date: Wed Aug 14 15:30:29 2019
New Revision: 368937

URL: http://llvm.org/viewvc/llvm-project?rev=368937&view=rev
Log:
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

Added:
    
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/
    
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/TestCompletionInLambdaAndUnnamedClass.py
    
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/main.cpp
Removed:
    
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/TestCompletionCrashInLambda.py
    
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/main.cpp
Modified:
    lldb/trunk/source/Symbol/ClangASTContext.cpp

Removed: 
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/TestCompletionCrashInLambda.py
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/TestCompletionCrashInLambda.py?rev=368936&view=auto
==============================================================================
--- 
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/TestCompletionCrashInLambda.py
 (original)
+++ 
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/TestCompletionCrashInLambda.py
 (removed)
@@ -1,4 +0,0 @@
-from lldbsuite.test import lldbinline
-from lldbsuite.test import decorators
-
-lldbinline.MakeInlineTest(__file__, globals(), 
[decorators.skipIf(bugnumber="rdar://53755023")])

Removed: 
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/main.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/main.cpp?rev=368936&view=auto
==============================================================================
--- 
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/main.cpp
 (original)
+++ 
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-crash-lambda/main.cpp
 (removed)
@@ -1,6 +0,0 @@
-int main() {
-  []()
-  { //%self.dbg.GetCommandInterpreter().HandleCompletion("e ", len("e "), 0, 
-1, lldb.SBStringList())
-  }
-  ();
-}

Added: 
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/TestCompletionInLambdaAndUnnamedClass.py
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/TestCompletionInLambdaAndUnnamedClass.py?rev=368937&view=auto
==============================================================================
--- 
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/TestCompletionInLambdaAndUnnamedClass.py
 (added)
+++ 
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/TestCompletionInLambdaAndUnnamedClass.py
 Wed Aug 14 15:30:29 2019
@@ -0,0 +1,4 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(__file__, globals(),)

Added: 
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/main.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/main.cpp?rev=368937&view=auto
==============================================================================
--- 
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/main.cpp
 (added)
+++ 
lldb/trunk/packages/Python/lldbsuite/test/expression_command/completion-in-lambda-and-unnnamed-class/main.cpp
 Wed Aug 14 15:30:29 2019
@@ -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;
+}

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=368937&r1=368936&r2=368937&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Wed Aug 14 15:30:29 2019
@@ -1519,14 +1519,44 @@ CompilerType ClangASTContext::CreateReco
   // 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)


_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to