From fdc6aea3fd822b639baaa5b666fdf7598d08c8de Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Thu, 13 Aug 2020 15:02:16 +0200 Subject: [PATCH] [lldb] Check Decl kind when completing -flimit-debug-info types The search for the complete class definition can also produce entries which are not of the expected type. This can happen for instance when there is a function with the same name as the class we're looking up (which means that the class needs to be disambiguated with the struct/class tag in most contexts). Previously we were just picking the first Decl that the lookup returned, which later caused crashes or assertion failures if it was not of the correct type. This patch changes that to search for an entry of the correct type. Differential Revision: https://reviews.llvm.org/D85904 --- .../Plugins/ExpressionParser/Clang/ClangASTImporter.cpp | 15 ++++++++------- .../limit-debug-info/TestLimitDebugInfo.py | 3 +++ lldb/test/API/functionalities/limit-debug-info/main.cpp | 9 +++++---- lldb/test/API/functionalities/limit-debug-info/one.cpp | 4 ++++ lldb/test/API/functionalities/limit-debug-info/onetwo.h | 10 ++++++++++ 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp index 6d87737..73042c2 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp @@ -870,13 +870,14 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { return dn_or_err.takeError(); DeclContext *dc = *dc_or_err; DeclContext::lookup_result lr = dc->lookup(*dn_or_err); - if (lr.size()) { - clang::Decl *lookup_found = lr.front(); - RegisterImportedDecl(From, lookup_found); - m_decls_to_ignore.insert(lookup_found); - return lookup_found; - } else - LLDB_LOG(log, "[ClangASTImporter] Complete definition not found"); + for (clang::Decl *candidate : lr) { + if (candidate->getKind() == From->getKind()) { + RegisterImportedDecl(From, candidate); + m_decls_to_ignore.insert(candidate); + return candidate; + } + } + LLDB_LOG(log, "[ClangASTImporter] Complete definition not found"); } return ASTImporter::ImportImpl(From); diff --git a/lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py b/lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py index aa383d0..f9934df 100644 --- a/lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py +++ b/lldb/test/API/functionalities/limit-debug-info/TestLimitDebugInfo.py @@ -63,6 +63,9 @@ class LimitDebugInfoTestCase(TestBase): self.expect_expr("get_two().one().member", result_value="124") self.expect_expr("get_two().member", result_value="224") + self.expect_expr("shadowed_one.member", result_value="47") + self.expect_expr("shadowed_one.one", result_value="142") + @skipIf(bugnumber="pr46284", debug_info="gmodules") @skipIfWindows # Clang emits type info even with -flimit-debug-info def test_two_debug(self): diff --git a/lldb/test/API/functionalities/limit-debug-info/main.cpp b/lldb/test/API/functionalities/limit-debug-info/main.cpp index 1aad7e6..1fe4feb 100644 --- a/lldb/test/API/functionalities/limit-debug-info/main.cpp +++ b/lldb/test/API/functionalities/limit-debug-info/main.cpp @@ -1,23 +1,19 @@ #include "onetwo.h" struct InheritsFromOne : One { - constexpr InheritsFromOne() = default; int member = 47; } inherits_from_one; struct InheritsFromTwo : Two { - constexpr InheritsFromTwo() = default; int member = 47; } inherits_from_two; struct OneAsMember { - constexpr OneAsMember() = default; member::One one; int member = 47; } one_as_member; struct TwoAsMember { - constexpr TwoAsMember() = default; member::Two two; int member = 47; } two_as_member; @@ -28,4 +24,9 @@ array::Two array_of_two[3]; result::One get_one() { return result::One(124); } result::Two get_two() { return result::Two(224); } +// Note that there's also a function with the name func_shadow::One. +struct ShadowedOne : func_shadow::One { + int member = 47; +} shadowed_one; + int main() { return get_one().member; } diff --git a/lldb/test/API/functionalities/limit-debug-info/one.cpp b/lldb/test/API/functionalities/limit-debug-info/one.cpp index 70353a0..ce1d5d1 100644 --- a/lldb/test/API/functionalities/limit-debug-info/one.cpp +++ b/lldb/test/API/functionalities/limit-debug-info/one.cpp @@ -6,3 +6,7 @@ array::One::~One() = default; result::One::One(int member) : member(member) {} result::One::~One() = default; + +void func_shadow::One(int) {} +func_shadow::One::~One() = default; +void func_shadow::One(float) {} diff --git a/lldb/test/API/functionalities/limit-debug-info/onetwo.h b/lldb/test/API/functionalities/limit-debug-info/onetwo.h index 24a18f6a..f34c344 100644 --- a/lldb/test/API/functionalities/limit-debug-info/onetwo.h +++ b/lldb/test/API/functionalities/limit-debug-info/onetwo.h @@ -54,3 +54,13 @@ struct Two { virtual ~Two(); }; } // namespace result + +namespace func_shadow { +void One(int); +struct One { + int one = 142; + constexpr One() = default; + virtual ~One(); +}; +void One(float); +} // namespace func_shadow -- 2.7.4