diff --git a/.arclint b/.arclint --- a/.arclint +++ b/.arclint @@ -2,7 +2,7 @@ "linters": { "clang-format": { "type": "script-and-regex", - "script-and-regex.script": "bash utils/arcanist/clang-format.sh", + "script-and-regex.script": "cmd utils\\arcanist\\clang-format.sh", "script-and-regex.regex": "/^(?P[[:alpha:]]+)\n(?P[^\n]+)\n(====|(?P\\d),(?P\\d)\n(?P.*)>>>>\n(?P.*)<<<<\n)$/s", "include": [ "(\\.(cc|cpp|h)$)" diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -121,6 +121,32 @@ TYPE(CSharpGenericTypeConstraintComma) \ TYPE(Unknown) +static const std::set CppOperatorsFollowingVar = { + tok::l_square, tok::r_square, + tok::l_paren, tok::r_paren, + tok::r_brace, tok::period, + tok::ellipsis, tok::amp, + tok::ampamp, tok::ampequal, + tok::star, tok::starequal, + tok::plus, tok::plusplus, + tok::plusequal, tok::minus, + tok::arrow, tok::minusminus, + tok::minusequal, tok::exclaim, + tok::exclaimequal, tok::slash, + tok::slashequal, tok::percent, + tok::percentequal, tok::less, + tok::lessless, tok::lessequal, + tok::lesslessequal, tok::spaceship, + tok::greater, tok::greatergreater, + tok::greaterequal, tok::greatergreaterequal, + tok::caret, tok::caretequal, + tok::pipe, tok::pipepipe, + tok::pipeequal, tok::question, + tok::semi, tok::equal, + tok::equalequal, tok::comma, + tok::hash, tok::hashhash, + tok::hashat}; + /// Determines the semantic type of a syntactic token, e.g. whether "<" is a /// template opener or binary operator. enum TokenType : uint8_t { diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -100,7 +100,14 @@ if (Style.Language == FormatStyle::LK_Java || Style.isJavaScript() || Style.isCSharp()) return 0; - if (RootToken.isAccessSpecifier(false) || + if (RootToken.isAccessSpecifier(Style.Language == FormatStyle::LK_Cpp) || + (RootToken.Next && + RootToken.Next->isOneOf(Keywords.kw_slots, Keywords.kw_qslots) && + RootToken.Next->Next && RootToken.Next->Next->is(tok::colon)) || + (RootToken.isAccessSpecifier(false) && + (!RootToken.Next || + CppOperatorsFollowingVar.find(RootToken.Next->Tok.getKind()) == + clang::format::CppOperatorsFollowingVar.end())) || RootToken.isObjCAccessSpecifier() || (RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) && RootToken.Next && RootToken.Next->is(tok::colon))) { diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2499,9 +2499,17 @@ if (FormatTok->isOneOf(Keywords.kw_slots, Keywords.kw_qslots)) nextToken(); // Otherwise, we don't know what it is, and we'd better keep the next token. - if (FormatTok->Tok.is(tok::colon)) + if (FormatTok->Tok.is(tok::colon)) { nextToken(); - addUnwrappedLine(); + addUnwrappedLine(); + return; + } + // if followed by an operator probably intended to be a variable, dont treat + // as access specifier + if (clang::format::OperatorsFollowingVar.find(FormatTok->Tok.getKind()) == + OperatorsFollowingVar.end()) { + addUnwrappedLine(); + } } void UnwrappedLineParser::parseConcept() { diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -3030,6 +3030,8 @@ "label:\n" " signals.baz();\n" "}"); + // Var that looks like accessSpecifier + verifyFormat("private.p = 1;"); } TEST_F(FormatTest, SeparatesLogicalBlocks) {