This is an archive of the discontinued LLVM Phabricator instance.

[lldb][ClangExpression] Filter out non-root namespaces in FindNamespace
ClosedPublic

Authored by Michael137 on Apr 3 2023, 4:44 AM.

Details

Summary

Summary

In a program such as:

namespace A {
namespace B {
struct Bar {};
}
}

namespace B {
struct Foo {};
}

...LLDB would run into issues such as:

(lldb) expr ::B::Foo f
error: expression failed to parse:
error: <user expression 0>:1:6: no type named 'Foo' in namespace 'A::B'
::B::Foo f
~~~~~^

This is because the SymbolFileDWARF::FindNamespace implementation
will return *any* namespace it finds if the parent_decl_ctx provided
is empty. In FindExternalVisibleDecls we use this API to find the
namespace that symbol B refers to. If A::B happened to be the one
that SymbolFileDWARF::FindNamespace looked at first, we would try
to find struct Foo in A::B. Hence the error.

This patch proposes a new flag to SymbolFileDWARF::FindNamespace
allows us to only consider top-level namespaces in our search, which is what
FindExternalVisibleDecls is attempting anyway; it just never
accounted for multiple namespaces of the same name.

Testing

  • Added API test-case

Diff Detail

Event Timeline

Michael137 created this revision.Apr 3 2023, 4:44 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 3 2023, 4:44 AM
Michael137 updated this revision to Diff 510478.Apr 3 2023, 6:24 AM
  • Add docs
Michael137 updated this revision to Diff 510482.Apr 3 2023, 6:35 AM
  • Merge into single API
Michael137 edited the summary of this revision. (Show Details)Apr 3 2023, 6:37 AM
Michael137 updated this revision to Diff 510489.Apr 3 2023, 7:01 AM
  • Adjust test-case. Add FIXME
Michael137 published this revision for review.Apr 3 2023, 7:01 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 3 2023, 7:01 AM
Michael137 added inline comments.Apr 3 2023, 7:03 AM
lldb/test/API/lang/cpp/namespace/TestNamespaceLookup.py
197 ↗(On Diff #510489)

I need to double check how exactly this used to work and whether there's a fix for it on top of the current patch. But not supporting this seems less problematic than choosing the wrong namespace

Just out of curiosity:

namespace A {
namespace B {
namespace C {
struct Bar {};
}
}
}

namespace B {
namespace C {
struct Foo {};
}
}

Does this work?

(lldb) expr C::Foo f
lldb/include/lldb/Symbol/SymbolFile.h
342

This looks like a great opportunity to add a Doxygen comment in the base class!

lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
704

Maybe comment why?

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
2339

I find this condition with its double negative really hard to understand. Would it be easier to read as

if (!decl_ctx.IsValid()) {
    if (only_root_namespaces)
      return die.GetParent().Tag() == dwarf::DW_TAG_compile_unit;
   return true;
}

?

Just out of curiosity:

namespace A {
namespace B {
namespace C {
struct Bar {};
}
}
}

namespace B {
namespace C {
struct Foo {};
}
}

Does this work?

(lldb) expr C::Foo f

Yup that does currently work. With this patch it wouldn't anymore

Michael137 added inline comments.Apr 3 2023, 5:43 PM
lldb/test/API/lang/cpp/namespace/TestNamespaceLookup.py
197 ↗(On Diff #510489)

I checked how expression evaluation currently works at namespace scope and it does rely on FindExternalVisibleDecls including all namespaces (not only top-level) in its search. We do the additional filtering for which function symbol to pick based on SymbolContext after the fact (in LookupFunction). This seems rather fragile but there is a decent amount of code to make this happen so I wouldn't want to just blindly stop supporting it.

aprantl accepted this revision.Apr 4 2023, 12:44 PM

So the new bool flag effectively implements the leading :: separator in the lookup. Seems reasonable!

This revision is now accepted and ready to land.Apr 4 2023, 12:44 PM
  • Only search for root namespace if we're doing a qualified lookup
  • Move doxygen comment
  • Add source comment
  • Make condition more readable
  • Fix test
Michael137 marked 3 inline comments as done.Apr 14 2023, 4:31 AM
aprantl accepted this revision.Apr 14 2023, 8:50 AM