krasimir created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. krasimir added a reviewer: mprobst.
Revision a75f8d98d7ac9e557b238a229a9a2647c71feed1 <https://reviews.llvm.org/rGa75f8d98d7ac9e557b238a229a9a2647c71feed1> fixed spacing for operators, but caused the const and non-const versions to diverge: // With Style.PointerAlignment = FormatStyle::PAS_Left: struct A { operator char*() { return ""; } operator const char *() const { return ""; } }; The code was checking if the type specifier was directly preceded by `operator`. However there could be comments and `const/volatile` in between. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D72911 Files: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTest.cpp Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -15007,6 +15007,9 @@ Style.PointerAlignment = FormatStyle::PAS_Left; verifyFormat("Foo::operator*();", Style); verifyFormat("Foo::operator void*();", Style); + verifyFormat("Foo::operator/*comment*/ void*();", Style); + verifyFormat("Foo::operator/*a*/ const /*b*/ void*();", Style); + verifyFormat("Foo::operator/*a*/ volatile /*b*/ void*();", Style); verifyFormat("Foo::operator()(void*);", Style); verifyFormat("Foo::operator*(void*);", Style); verifyFormat("Foo::operator*();", Style); Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -2706,12 +2706,26 @@ if (Right.is(tok::star) && Left.is(tok::l_paren)) return false; if (Right.isOneOf(tok::star, tok::amp, tok::ampamp) && - (Left.is(tok::identifier) || Left.isSimpleTypeSpecifier()) && - Left.Previous && Left.Previous->is(tok::kw_operator)) - // Space between the type and the * - // operator void*(), operator char*(), operator Foo*() dependant - // on PointerAlignment style. - return (Style.PointerAlignment != FormatStyle::PAS_Left); + (Left.is(tok::identifier) || Left.isSimpleTypeSpecifier())) { + // Space between the type and the * in: + // operator void*() + // operator void*() + // operator char*() + // operator /*comment*/ const char*() + // operator volatile /*comment*/ char*() + // operator Foo*() + // dependant on PointerAlignment style. + + // Here, Left points to the type specifier. Skip back over const and + // volatile, looking for `operator`. + FormatToken *Before = Left.getPreviousNonComment(); + while (Before && Before->isOneOf(tok::kw_const, tok::kw_volatile)) { + Before = Before->getPreviousNonComment(); + } + if (Before && Before->is(tok::kw_operator)) { + return (Style.PointerAlignment != FormatStyle::PAS_Left); + } + } const auto SpaceRequiredForArrayInitializerLSquare = [](const FormatToken &LSquareTok, const FormatStyle &Style) { return Style.SpacesInContainerLiterals ||
Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -15007,6 +15007,9 @@ Style.PointerAlignment = FormatStyle::PAS_Left; verifyFormat("Foo::operator*();", Style); verifyFormat("Foo::operator void*();", Style); + verifyFormat("Foo::operator/*comment*/ void*();", Style); + verifyFormat("Foo::operator/*a*/ const /*b*/ void*();", Style); + verifyFormat("Foo::operator/*a*/ volatile /*b*/ void*();", Style); verifyFormat("Foo::operator()(void*);", Style); verifyFormat("Foo::operator*(void*);", Style); verifyFormat("Foo::operator*();", Style); Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -2706,12 +2706,26 @@ if (Right.is(tok::star) && Left.is(tok::l_paren)) return false; if (Right.isOneOf(tok::star, tok::amp, tok::ampamp) && - (Left.is(tok::identifier) || Left.isSimpleTypeSpecifier()) && - Left.Previous && Left.Previous->is(tok::kw_operator)) - // Space between the type and the * - // operator void*(), operator char*(), operator Foo*() dependant - // on PointerAlignment style. - return (Style.PointerAlignment != FormatStyle::PAS_Left); + (Left.is(tok::identifier) || Left.isSimpleTypeSpecifier())) { + // Space between the type and the * in: + // operator void*() + // operator void*() + // operator char*() + // operator /*comment*/ const char*() + // operator volatile /*comment*/ char*() + // operator Foo*() + // dependant on PointerAlignment style. + + // Here, Left points to the type specifier. Skip back over const and + // volatile, looking for `operator`. + FormatToken *Before = Left.getPreviousNonComment(); + while (Before && Before->isOneOf(tok::kw_const, tok::kw_volatile)) { + Before = Before->getPreviousNonComment(); + } + if (Before && Before->is(tok::kw_operator)) { + return (Style.PointerAlignment != FormatStyle::PAS_Left); + } + } const auto SpaceRequiredForArrayInitializerLSquare = [](const FormatToken &LSquareTok, const FormatStyle &Style) { return Style.SpacesInContainerLiterals ||
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits