Skip to content

Commit

Permalink
Improve anonymous class heuristic in ClangASTContext::CreateRecordType
Browse files Browse the repository at this point in the history
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
  • Loading branch information
shafik committed Aug 14, 2019
1 parent 6ba7992 commit 62abe49
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 14 deletions.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from lldbsuite.test import lldbinline
from lldbsuite.test import decorators

lldbinline.MakeInlineTest(__file__, globals(),)
Original file line number Diff line number Diff line change
@@ -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;
}
38 changes: 34 additions & 4 deletions lldb/source/Symbol/ClangASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 62abe49

Please sign in to comment.