diff --git a/src/libs/3rdparty/cplusplus/AST.cpp b/src/libs/3rdparty/cplusplus/AST.cpp index a48067ab755..360918d2af2 100644 --- a/src/libs/3rdparty/cplusplus/AST.cpp +++ b/src/libs/3rdparty/cplusplus/AST.cpp @@ -1393,7 +1393,6 @@ int ForeachStatementAST::lastToken() const return 1; } -/** \generated */ int FunctionDeclaratorAST::firstToken() const { if (lparen_token) @@ -1403,40 +1402,50 @@ int FunctionDeclaratorAST::firstToken() const return candidate; if (rparen_token) return rparen_token; - if (cv_qualifier_list) - if (int candidate = cv_qualifier_list->firstToken()) - return candidate; - if (ref_qualifier_token) + const int firstQualListToken = cv_qualifier_list ? cv_qualifier_list->firstToken() : 0; + const auto isBeforeFirstQualListToken = [firstQualListToken](int token) { + return token && (!firstQualListToken || token < firstQualListToken); + }; + if (isBeforeFirstQualListToken(ref_qualifier_token)) return ref_qualifier_token; - if (exception_specification) - if (int candidate = exception_specification->firstToken()) + if (exception_specification) { + const int candidate = exception_specification->firstToken(); + if (isBeforeFirstQualListToken(candidate)) return candidate; - if (trailing_return_type) - if (int candidate = trailing_return_type->firstToken()) + } + if (trailing_return_type) { + const int candidate = trailing_return_type->firstToken(); + if (isBeforeFirstQualListToken(candidate)) return candidate; + } + if (firstQualListToken) + return firstQualListToken; if (as_cpp_initializer) if (int candidate = as_cpp_initializer->firstToken()) return candidate; return 0; } -/** \generated */ int FunctionDeclaratorAST::lastToken() const { if (as_cpp_initializer) if (int candidate = as_cpp_initializer->lastToken()) return candidate; - if (trailing_return_type) - if (int candidate = trailing_return_type->lastToken()) - return candidate; - if (exception_specification) - if (int candidate = exception_specification->lastToken()) - return candidate; - if (ref_qualifier_token) - return ref_qualifier_token + 1; - if (cv_qualifier_list) - if (int candidate = cv_qualifier_list->lastToken()) - return candidate; + const int lastQualListToken = cv_qualifier_list ? cv_qualifier_list->lastToken() : 0; + const auto tokenOrLastQualListToken = [lastQualListToken](int token) { + return std::max(token ? token + 1 : 0, lastQualListToken); + }; + const auto tokenFromAstOrLastQualListToken = [lastQualListToken](const AST *ast) { + return std::max(ast ? ast->lastToken() : 0, lastQualListToken); + }; + if (int candidate = tokenFromAstOrLastQualListToken(trailing_return_type)) + return candidate; + if (int candidate = tokenFromAstOrLastQualListToken(exception_specification)) + return candidate; + if (int candidate = tokenOrLastQualListToken(ref_qualifier_token)) + return candidate; + if (lastQualListToken) + return lastQualListToken; if (rparen_token) return rparen_token + 1; if (parameter_declaration_clause) diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index dd85e95470e..93845b51c80 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -6110,6 +6110,41 @@ void QuickfixTest::testMoveFuncDefOutsideMemberFuncToCppWithInlinePartOfName() QuickFixOperationTest(testDocuments, &factory); } +void QuickfixTest::testMoveFuncDefOutsideMixedQualifiers() +{ + QList testDocuments; + QByteArray original; + QByteArray expected; + + // Header File + original = R"( +struct Base { + virtual auto func() const && noexcept -> void = 0; +}; +struct Derived : public Base { + auto @func() const && noexcept -> void override {} +};)"; + expected = R"( +struct Base { + virtual auto func() const && noexcept -> void = 0; +}; +struct Derived : public Base { + auto func() const && noexcept -> void override; +};)"; + testDocuments << CppTestDocument::create("file.h", original, expected); + + // Source File + original = "#include \"file.h\"\n"; + expected = R"DELIM(#include "file.h" + +void Derived::func() const &&noexcept {} +)DELIM"; + testDocuments << CppTestDocument::create("file.cpp", original, expected); + + MoveFuncDefOutside factory; + QuickFixOperationTest(testDocuments, &factory); +} + void QuickfixTest::testMoveFuncDefOutsideMemberFuncToCppInsideNS() { QList testDocuments; diff --git a/src/plugins/cppeditor/cppquickfix_test.h b/src/plugins/cppeditor/cppquickfix_test.h index 0201c5b3bb9..3995234374b 100644 --- a/src/plugins/cppeditor/cppquickfix_test.h +++ b/src/plugins/cppeditor/cppquickfix_test.h @@ -192,6 +192,7 @@ private slots: void testMoveFuncDefOutsideUnnamedTemplate(); void testMoveFuncDefOutsideMemberFuncToCppStatic(); void testMoveFuncDefOutsideMemberFuncToCppWithInlinePartOfName(); + void testMoveFuncDefOutsideMixedQualifiers(); void testMoveAllFuncDefOutsideMemberFuncToCpp(); void testMoveAllFuncDefOutsideMemberFuncOutside();