clayborg created this revision. clayborg added reviewers: jingham, aprantl, JDevlieghere. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
Objective C may or may not be enabled when running expressions. There was code that was no allowing "Class" or "id" to be looked up in expressions, but it was preventing these names from being able to be looked up in a namespace or class context. This fixes the issue by passing the namespace_decl along and testing it to make sure we only stop ones at the root namespace level. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D76964 Files: lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp lldb/test/API/commands/expression/ignore/Makefile lldb/test/API/commands/expression/ignore/TestIgnoreName.py lldb/test/API/commands/expression/ignore/main.cpp
Index: lldb/test/API/commands/expression/ignore/main.cpp =================================================================== --- /dev/null +++ lldb/test/API/commands/expression/ignore/main.cpp @@ -0,0 +1,10 @@ +namespace a { + struct Class { + }; +} + +int main(int argc, char **argv) +{ + a::Class c; + return 0; +} Index: lldb/test/API/commands/expression/ignore/TestIgnoreName.py =================================================================== --- /dev/null +++ lldb/test/API/commands/expression/ignore/TestIgnoreName.py @@ -0,0 +1,39 @@ +""" +Test calling user defined functions using expression evaluation. +This test checks that typesystem lookup works correctly for typedefs of +untagged structures. + +Ticket: https://llvm.org/bugs/show_bug.cgi?id=26790 +""" + + +import lldb + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestIgnoreName(TestBase): + mydir = TestBase.compute_mydir(__file__) + + def test(self): + """Test that we can evaluate an expression that finds something inside + a namespace that uses an Objective C keyword. + """ + self.build() + exe_path = self.getBuildArtifact("a.out") + error = lldb.SBError() + triple = None + platform = None + add_dependent_modules = False + target = self.dbg.CreateTarget(exe_path, triple, platform, + add_dependent_modules, error) + self.assertTrue(error.Success(), "Make sure our target got created") + expr_result = target.EvaluateExpression("a::Class a; a") + self.assertTrue(expr_result.GetError().Success(), + "Make sure our expression evaluated without errors") + self.assertTrue(expr_result.GetValue() == None, + 'Expression value is None') + self.assertTrue(expr_result.GetType().GetName() == "a::Class", + 'Expression result type is "a::Class"') Index: lldb/test/API/commands/expression/ignore/Makefile =================================================================== --- /dev/null +++ lldb/test/API/commands/expression/ignore/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -1321,7 +1321,7 @@ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); const ConstString name(context.m_decl_name.getAsString().c_str()); - if (IgnoreName(name, false)) + if (IgnoreName(name, namespace_decl, false)) return; // Only look for functions by name out in our symbols if the function doesn't Index: lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h +++ lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h @@ -325,13 +325,19 @@ /// \param[in] name /// The name to be considered. /// + /// \param[in] namespace_decl + /// The namespace decl that this name is being searched. This can be + /// invalid if we are searching the root namespace. + /// /// \param[in] ignore_all_dollar_names /// True if $-names of all sorts should be ignored. /// /// \return /// True if the name is one of a class of names that are ignored by /// global lookup for performance reasons. - bool IgnoreName(const ConstString name, bool ignore_all_dollar_names); + bool IgnoreName(const ConstString name, + const CompilerDeclContext &namespace_decl, + bool ignore_all_dollar_names); public: /// Copies a single Decl into the parser's AST context. Index: lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -574,13 +574,23 @@ } bool ClangASTSource::IgnoreName(const ConstString name, + const CompilerDeclContext &namespace_decl, bool ignore_all_dollar_names) { - static const ConstString id_name("id"); - static const ConstString Class_name("Class"); - - if (m_ast_context->getLangOpts().ObjC) - if (name == id_name || name == Class_name) + if (m_ast_context->getLangOpts().ObjC) { + static const ConstString id_name("id"); + static const ConstString Class_name("Class"); + if (name == id_name || name == Class_name) { + // Only disallow using "id" and "Class" if we are searching from the root + // namespace or translation unit level. If namespace_decl is valid, then + // this is not the root namespace. + if (namespace_decl.IsValid()) + return false; + LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS), + " CAS::IgnoreName(name=\"{0}\") Ignoring reserved keryword", + name); return true; + } + } StringRef name_string_ref = name.GetStringRef(); @@ -600,7 +610,7 @@ SymbolContextList sc_list; const ConstString name(context.m_decl_name.getAsString().c_str()); - if (IgnoreName(name, true)) + if (IgnoreName(name, namespace_decl, true)) return; if (!m_target) @@ -663,7 +673,7 @@ NameSearchContext &context, lldb::ModuleSP module_sp, const CompilerDeclContext &namespace_decl) { const ConstString name(context.m_decl_name.getAsString().c_str()); - if (IgnoreName(name, true)) + if (IgnoreName(name, namespace_decl, true)) return; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits