**Summary** The primary motivation for this patch is to make sure we handle the step-in behaviour for functions in the `std` namespace which have an `auto` return type. Currently the default `step-avoid-regex` setting is `^std::` but LLDB will still step into template functions with `auto` return types in the `std` namespace. **Details** When we hit a breakpoint and check whether we should stop, we call into `ThreadPlanStepInRange::FrameMatchesAvoidCriteria`. We then ask for the frame function name via `SymbolContext::GetFunctionName(Mangled::ePreferDemangledWithoutArguments)`. This ends up trying to parse the function name using `CPlusPlusLanguage::MethodName::GetBasename` which parses the raw demangled name string. `CPlusPlusNameParser::ParseFunctionImpl` calls `ConsumeTypename` to skip the (in our case auto) return type of the demangled name (according to the Itanium ABI this is a valid thing to encode into the mangled name). However, `ConsumeTypename` doesn't strip out a plain `auto` identifier (it will strip a `decltype(auto) return type though). So we are now left with a basename that still has the return type in it, thus failing to match the `^std::` regex. Example frame where the return type is still part of the function name: ``` Process 1234 stopped * thread #1, stop reason = step in frame #0: 0x12345678 repro`auto std::test_return_auto<int>() at main.cpp:12:5 9 10 template <class> 11 auto test_return_auto() { -> 12 return 42; 13 } ``` This is another case where the `CPlusPlusNameParser` breaks us in subtle ways due to evolving C++ syntax. There are longer-term plans of replacing the hand-rolled C++ parser with an alternative that uses the mangle tree API to do the parsing for us. **Testing** * Added API and unit-tests * Adding support for ABI tags into the parser is a larger undertaking which we would rather solve properly by using libcxxabi's mangle tree parser Differential Revision: https://reviews.llvm.org/D135413
17 lines
491 B
C++
17 lines
491 B
C++
namespace ignore {
|
|
template <typename T> auto auto_ret(T x) { return 0; }
|
|
[[gnu::abi_tag("test")]] int with_tag() { return 0; }
|
|
template <typename T> [[gnu::abi_tag("test")]] int with_tag_template() {
|
|
return 0;
|
|
}
|
|
|
|
template <typename T> decltype(auto) decltype_auto_ret(T x) { return 0; }
|
|
} // namespace ignore
|
|
|
|
int main() {
|
|
auto v1 = ignore::auto_ret<int>(5);
|
|
auto v2 = ignore::with_tag();
|
|
auto v3 = ignore::decltype_auto_ret<int>(5);
|
|
auto v4 = ignore::with_tag_template<int>();
|
|
}
|