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

Reply via email to