[Lldb-commits] [lldb] 65c807e - [lldb][TypeSystemClang] Allow transparent lookup through anonymous namespaces (#97275)

via lldb-commits lldb-commits at lists.llvm.org
Mon Jul 1 08:22:01 PDT 2024


Author: Michael Buch
Date: 2024-07-01T17:21:58+02:00
New Revision: 65c807e69545ec23c1a258f66f744874531c7d26

URL: https://github.com/llvm/llvm-project/commit/65c807e69545ec23c1a258f66f744874531c7d26
DIFF: https://github.com/llvm/llvm-project/commit/65c807e69545ec23c1a258f66f744874531c7d26.diff

LOG: [lldb][TypeSystemClang] Allow transparent lookup through anonymous namespaces (#97275)

This patch allows expressions to reference entities in anonymous
namespaces. Previously this would have resulted in:
```
(lldb) expr foo::FooAnonymousVar
error: <user expression 0>:1:6: no member named 'FooAnonymousVar' in namespace 'foo'
    1 | foo::FooAnonymousVar
      | ~~~~~^
```

We already allow such lookups through inline namespaces, and for the
purposes of lookup, anonymous namespaces shouldn't behave any different.

Fixes https://github.com/llvm/llvm-project/issues/96963.

Added: 
    

Modified: 
    lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
    lldb/test/API/lang/cpp/namespace/TestNamespace.py
    lldb/test/API/lang/cpp/namespace/main.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index cd1c500d9aa29..093d27a92d718 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -9484,14 +9484,24 @@ bool TypeSystemClang::DeclContextIsContainedInLookup(
   auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
   auto *other = (clang::DeclContext *)other_opaque_decl_ctx;
 
+  // If we have an inline or anonymous namespace, then the lookup of the
+  // parent context also includes those namespace contents.
+  auto is_transparent_lookup_allowed = [](clang::DeclContext *DC) {
+    if (DC->isInlineNamespace())
+      return true;
+
+    if (auto const *NS = dyn_cast<NamespaceDecl>(DC))
+      return NS->isAnonymousNamespace();
+
+    return false;
+  };
+
   do {
     // A decl context always includes its own contents in its lookup.
     if (decl_ctx == other)
       return true;
-
-    // If we have an inline namespace, then the lookup of the parent context
-    // also includes the inline namespace contents.
-  } while (other->isInlineNamespace() && (other = other->getParent()));
+  } while (is_transparent_lookup_allowed(other) &&
+           (other = other->getParent()));
 
   return false;
 }

diff  --git a/lldb/test/API/lang/cpp/namespace/TestNamespace.py b/lldb/test/API/lang/cpp/namespace/TestNamespace.py
index d747e2be77c8e..84891b322180c 100644
--- a/lldb/test/API/lang/cpp/namespace/TestNamespace.py
+++ b/lldb/test/API/lang/cpp/namespace/TestNamespace.py
@@ -253,3 +253,16 @@ def test_with_run_command(self):
         self.expect_expr(
             "((::B::Bar*)&::B::bar)->x()", result_type="int", result_value="42"
         )
+
+        self.expect_expr("InAnon1::var_in_anon", result_type="int", result_value="10")
+        self.expect_expr(
+            "InAnon1::InAnon2::var_in_anon", result_type="int", result_value="5"
+        )
+        self.expect_expr(
+            "InAnon1::inline_ns::var_in_anon", result_type="int", result_value="15"
+        )
+        self.expect_expr(
+            "InAnon1::inline_ns::InAnon2::var_in_anon",
+            result_type="int",
+            result_value="5",
+        )

diff  --git a/lldb/test/API/lang/cpp/namespace/main.cpp b/lldb/test/API/lang/cpp/namespace/main.cpp
index 6a8efa160766b..2edfab8437639 100644
--- a/lldb/test/API/lang/cpp/namespace/main.cpp
+++ b/lldb/test/API/lang/cpp/namespace/main.cpp
@@ -127,6 +127,22 @@ struct Foo {
 };
 } // namespace NS2
 
+namespace {
+namespace InAnon1 {
+int var_in_anon = 10;
+namespace {
+inline namespace inline_ns {
+int var_in_anon = 15;
+namespace InAnon2 {
+namespace {
+int var_in_anon = 5;
+} // namespace
+} // namespace InAnon2
+} // namespace inline_ns
+} // namespace
+} // namespace InAnon1
+} // namespace
+
 int
 main (int argc, char const *argv[])
 {
@@ -140,5 +156,6 @@ main (int argc, char const *argv[])
     ::B::Bar bb;
     A::B::Bar ab;
     return Foo::myfunc(12) + bb.x() + ab.y() + NS1::NS2::Foo{}.bar() +
-           NS2::Foo{}.bar();
+           NS2::Foo{}.bar() + InAnon1::var_in_anon +
+           InAnon1::InAnon2::var_in_anon + InAnon1::inline_ns::var_in_anon;
 }


        


More information about the lldb-commits mailing list