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

Michael Buch via lldb-commits lldb-commits at lists.llvm.org
Mon Jul 1 03:09:15 PDT 2024


https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/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.

>From f6c801efec331a832f2f10386be9cc14c8bb9565 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 1 Jul 2024 11:46:37 +0200
Subject: [PATCH] [lldb][TypeSystemClang] Allow transparent lookup through
 anonymous namespaces

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.
---
 .../TypeSystem/Clang/TypeSystemClang.cpp      | 18 ++++++++++++++----
 .../API/lang/cpp/namespace/TestNamespace.py   |  5 +++++
 lldb/test/API/lang/cpp/namespace/main.cpp     | 19 ++++++++++++++++++-
 3 files changed, 37 insertions(+), 5 deletions(-)

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..83bfe173658cc 100644
--- a/lldb/test/API/lang/cpp/namespace/TestNamespace.py
+++ b/lldb/test/API/lang/cpp/namespace/TestNamespace.py
@@ -253,3 +253,8 @@ 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