Michael137 updated this revision to Diff 469267. Michael137 added a comment.
- Support certain special tokens Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D136306/new/ https://reviews.llvm.org/D136306 Files: lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h lldb/test/API/functionalities/step-avoids-regexp/TestStepAvoidsRegexp.py lldb/test/API/functionalities/step-avoids-regexp/main.cpp lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp
Index: lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp =================================================================== --- lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp +++ lldb/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp @@ -120,7 +120,47 @@ "test_return_auto<int>", "()", "const", "std::test_return_auto<int>"}, {"decltype(auto) std::test_return_auto<int>(int) const", "std", "test_return_auto<int>", "(int)", "const", - "std::test_return_auto<int>"}}; + "std::test_return_auto<int>"}, + + // abi_tag on class + {"v1::v2::Dummy[abi:c1][abi:c2]<v1::v2::Dummy[abi:c1][abi:c2]<int>> " + "v1::v2::Dummy[abi:c1][abi:c2]<v1::v2::Dummy[abi:c1][abi:c2]<int>>" + "::method2<v1::v2::Dummy[abi:c1][abi:c2]<v1::v2::Dummy[abi:c1][abi:c2]<int>>>(int, v1::v2::Dummy<int>) const &&", + // Context + "v1::v2::Dummy[abi:c1][abi:c2]<v1::v2::Dummy[abi:c1][abi:c2]<int>>", + // Basename + "method2<v1::v2::Dummy[abi:c1][abi:c2]<v1::v2::Dummy[abi:c1][abi:c2]<int>>>", + // Args, qualifiers + "(int, v1::v2::Dummy<int>)", "const &&", + // Full scope-qualified name without args + "v1::v2::Dummy[abi:c1][abi:c2]<v1::v2::Dummy[abi:c1][abi:c2]<int>>" + "::method2<v1::v2::Dummy[abi:c1][abi:c2]<v1::v2::Dummy[abi:c1][abi:c2]<int>>>"}, + + // abi_tag on free function and template argument + {"v1::v2::Dummy[abi:c1][abi:c2]<v1::v2::Dummy[abi:c1][abi:c2]<int>> " + "v1::v2::with_tag_in_ns[abi:f1][abi:f2]<v1::v2::Dummy[abi:c1][abi:c2]" + "<v1::v2::Dummy[abi:c1][abi:c2]<int>>>(int, v1::v2::Dummy<int>) const &&", + // Context + "v1::v2", + // Basename + "with_tag_in_ns[abi:f1][abi:f2]<v1::v2::Dummy[abi:c1][abi:c2]<v1::v2::Dummy[abi:c1][abi:c2]<int>>>", + // Args, qualifiers + "(int, v1::v2::Dummy<int>)", "const &&", + // Full scope-qualified name without args + "v1::v2::with_tag_in_ns[abi:f1][abi:f2]<v1::v2::Dummy[abi:c1][abi:c2]<v1::v2::Dummy[abi:c1][abi:c2]<int>>>"}, + + // abi_tag with special characters + {"auto ns::with_tag_in_ns[abi:special tag,0.0][abi:special tag,1.0]<Dummy<int>>" + "(float) const &&", + // Context + "ns", + // Basename + "with_tag_in_ns[abi:special tag,0.0][abi:special tag,1.0]<Dummy<int>>", + // Args, qualifiers + "(float)", "const &&", + // Full scope-qualified name without args + "ns::with_tag_in_ns[abi:special tag,0.0][abi:special tag,1.0]<Dummy<int>>"} + }; for (const auto &test : test_cases) { CPlusPlusLanguage::MethodName method(ConstString(test.input)); Index: lldb/test/API/functionalities/step-avoids-regexp/main.cpp =================================================================== --- lldb/test/API/functionalities/step-avoids-regexp/main.cpp +++ lldb/test/API/functionalities/step-avoids-regexp/main.cpp @@ -1,4 +1,6 @@ namespace ignore { +struct Dummy {}; + 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() { @@ -8,9 +10,15 @@ template <typename T> decltype(auto) decltype_auto_ret(T x) { return 0; } } // namespace ignore +template <typename T> +[[gnu::abi_tag("test")]] ignore::Dummy with_tag_template_returns_ignore(T x) { + return {}; +} + 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>(); + auto v5 = with_tag_template_returns_ignore<int>(5); } Index: lldb/test/API/functionalities/step-avoids-regexp/TestStepAvoidsRegexp.py =================================================================== --- lldb/test/API/functionalities/step-avoids-regexp/TestStepAvoidsRegexp.py +++ lldb/test/API/functionalities/step-avoids-regexp/TestStepAvoidsRegexp.py @@ -37,13 +37,10 @@ self.thread.StepInto() self.hit_correct_function("main") - @skipIfWindows - @expectedFailureAll(bugnumber="rdar://100645742") - def test_step_avoid_regex_abi_tagged_template(self): - """Tests stepping into an ABI tagged function that matches the avoid regex""" - self.build() - (_, _, self.thread, _) = lldbutil.run_to_source_breakpoint(self, "with_tag_template", lldb.SBFileSpec('main.cpp')) - # Try to step into ignore::with_tag_template self.thread.StepInto() self.hit_correct_function("main") + + # Step into with_tag_template_returns_ignore (outside 'ignore::' namespace) + self.thread.StepInto() + self.hit_correct_function("with_tag_template_returns_ignore") Index: lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h =================================================================== --- lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h +++ lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h @@ -117,6 +117,7 @@ void Advance(); void TakeBack(); bool ConsumeToken(clang::tok::TokenKind kind); + template <typename... Ts> bool ConsumeToken(Ts... kinds); Bookmark SetBookmark(); size_t GetCurrentPosition(); @@ -164,6 +165,16 @@ // Consumes full type name like 'Namespace::Class<int>::Method()::InnerClass' bool ConsumeTypename(); + /// Consumes ABI tags enclosed within '[abi:' ... ']' + /// + /// Since there is no restriction on what the ABI tag + /// string may contain, this API supports parsing a small + /// set of special characters. + /// + /// The following regex describes the set of supported characters: + /// [A-Za-z,.\s\d]+ + bool ConsumeAbiTag(); + llvm::Optional<ParsedNameRanges> ParseFullNameImpl(); llvm::StringRef GetTextForRange(const Range &range); Index: lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp =================================================================== --- lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp +++ lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp @@ -226,9 +226,15 @@ Advance(); break; case tok::l_square: - if (!ConsumeBrackets(tok::l_square, tok::r_square)) + // Handle templates tagged with an ABI tag. + // An example demangled/prettified version is: + // func[abi:tag1][abi:tag2]<type[abi:tag3]>(int) + if (ConsumeAbiTag()) + can_open_template = true; + else if (ConsumeBrackets(tok::l_square, tok::r_square)) + can_open_template = false; + else return false; - can_open_template = false; break; case tok::l_paren: if (!ConsumeArguments()) @@ -249,6 +255,34 @@ return true; } +bool CPlusPlusNameParser::ConsumeAbiTag() { + Bookmark start_position = SetBookmark(); + if (!ConsumeToken(tok::l_square)) { + return false; + } + + if (HasMoreTokens() && Peek().is(tok::raw_identifier) + && Peek().getRawIdentifier() == "abi") { + Advance(); + } else { + return false; + } + + if (!ConsumeToken(tok::colon)) + return false; + + // Consume the actual tag string (and allow some special characters) + while (ConsumeToken(tok::raw_identifier, tok::comma, + tok::period, tok::numeric_constant)) + ; + + if (!ConsumeToken(tok::r_square)) + return false; + + start_position.Remove(); + return true; +} + bool CPlusPlusNameParser::ConsumeAnonymousNamespace() { Bookmark start_position = SetBookmark(); if (!ConsumeToken(tok::l_paren)) { @@ -519,6 +553,19 @@ Advance(); state = State::AfterIdentifier; break; + case tok::l_square: // ABI tag + // Handles types or functions that were tagged + // with, e.g., + // [[gnu::abi_tag("tag1","tag2")]] func() + // and demangled/prettified into: + // func[abi:tag1][abi:tag2]() + if (state == State::AfterIdentifier) { + // Anything other than an ABI tag is invalid at this point. + if (!ConsumeAbiTag()) { + continue_parsing = false; + } + } + break; case tok::l_paren: { if (state == State::Beginning || state == State::AfterTwoColons) { // (anonymous namespace)
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits