Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 6 additions & 24 deletions clang/lib/Format/UnwrappedLineFormatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,36 +116,18 @@ class LevelIndentTracker {
Style.isCSharp()) {
return 0;
}

auto IsAccessModifier = [&](const FormatToken &RootToken) {
if (Line.Type == LT_AccessModifier || RootToken.isObjCAccessSpecifier())
return true;

const auto *Next = RootToken.Next;

// Handle Qt signals.
if (RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) &&
Next && Next->is(tok::colon)) {
return true;
}

if (Next && Next->isOneOf(Keywords.kw_slots, Keywords.kw_qslots) &&
Next->Next && Next->Next->is(tok::colon)) {
return true;
}

// Handle malformed access specifier e.g. 'private' without trailing ':'.
return !Next && RootToken.isAccessSpecifier(false);
};

if (IsAccessModifier(*Line.First)) {
const auto &RootToken = *Line.First;
if (Line.Type == LT_AccessModifier ||
RootToken.isAccessSpecifier(/*ColonRequired=*/false) ||
RootToken.isObjCAccessSpecifier() ||
(RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) &&
RootToken.Next && RootToken.Next->is(tok::colon))) {
// The AccessModifierOffset may be overridden by IndentAccessModifiers,
// in which case we take a negative value of the IndentWidth to simulate
// the upper indent level.
return Style.IndentAccessModifiers ? -Style.IndentWidth
: Style.AccessModifierOffset;
}

return 0;
}

Expand Down
64 changes: 2 additions & 62 deletions clang/lib/Format/UnwrappedLineParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3386,75 +3386,15 @@ void UnwrappedLineParser::parseSwitch(bool IsExpr) {
NestedTooDeep.pop_back();
}

// Operators that can follow a C variable.
static bool isCOperatorFollowingVar(tok::TokenKind Kind) {
switch (Kind) {
case tok::ampamp:
case tok::ampequal:
case tok::arrow:
case tok::caret:
case tok::caretequal:
case tok::comma:
case tok::ellipsis:
case tok::equal:
case tok::equalequal:
case tok::exclaim:
case tok::exclaimequal:
case tok::greater:
case tok::greaterequal:
case tok::greatergreater:
case tok::greatergreaterequal:
case tok::l_paren:
case tok::l_square:
case tok::less:
case tok::lessequal:
case tok::lessless:
case tok::lesslessequal:
case tok::minus:
case tok::minusequal:
case tok::minusminus:
case tok::percent:
case tok::percentequal:
case tok::period:
case tok::pipe:
case tok::pipeequal:
case tok::pipepipe:
case tok::plus:
case tok::plusequal:
case tok::plusplus:
case tok::question:
case tok::r_brace:
case tok::r_paren:
case tok::r_square:
case tok::semi:
case tok::slash:
case tok::slashequal:
case tok::star:
case tok::starequal:
return true;
default:
return false;
}
}

void UnwrappedLineParser::parseAccessSpecifier() {
FormatToken *AccessSpecifierCandidate = FormatTok;
nextToken();
// Understand Qt's slots.
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->is(tok::colon)) {
if (FormatTok->is(tok::colon))
nextToken();
addUnwrappedLine();
} else if (FormatTok->isNot(tok::coloncolon) &&
!isCOperatorFollowingVar(FormatTok->Tok.getKind())) {
// Not a variable name nor namespace name.
addUnwrappedLine();
} else if (AccessSpecifierCandidate) {
// Consider the access specifier to be a C identifier.
AccessSpecifierCandidate->Tok.setKind(tok::identifier);
}
addUnwrappedLine();
}

/// \brief Parses a requires, decides if it is a clause or an expression.
Expand Down
49 changes: 25 additions & 24 deletions clang/unittests/Format/FormatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3501,46 +3501,47 @@ TEST_F(FormatTest, UnderstandsAccessSpecifiers) {
"label:\n"
" signals.baz();\n"
"}");
verifyFormat("private[1];");

const auto Style = getLLVMStyle(FormatStyle::LK_C);
verifyFormat("private[1];", Style);
verifyFormat("testArray[public] = 1;");
verifyFormat("public();");
verifyFormat("public();", Style);
verifyFormat("myFunc(public);");
verifyFormat("std::vector<int> testVec = {private};");
verifyFormat("private.p = 1;");
verifyFormat("private.p = 1;", Style);
verifyFormat("void function(private...) {};");
verifyFormat("if (private && public)");
verifyFormat("private &= true;");
verifyFormat("private &= true;", Style);
verifyFormat("int x = private * public;");
verifyFormat("public *= private;");
verifyFormat("public *= private;", Style);
verifyFormat("int x = public + private;");
verifyFormat("private++;");
verifyFormat("private++;", Style);
verifyFormat("++private;");
verifyFormat("public += private;");
verifyFormat("public = public - private;");
verifyFormat("public->foo();");
verifyFormat("private--;");
verifyFormat("public += private;", Style);
verifyFormat("public = public - private;", Style);
verifyFormat("public->foo();", Style);
verifyFormat("private--;", Style);
verifyFormat("--private;");
verifyFormat("public -= 1;");
verifyFormat("public -= 1;", Style);
verifyFormat("if (!private && !public)");
verifyFormat("public != private;");
verifyFormat("public != private;", Style);
verifyFormat("int x = public / private;");
verifyFormat("public /= 2;");
verifyFormat("public = public % 2;");
verifyFormat("public %= 2;");
verifyFormat("public /= 2;", Style);
verifyFormat("public = public % 2;", Style);
verifyFormat("public %= 2;", Style);
verifyFormat("if (public < private)");
verifyFormat("public << private;");
verifyFormat("public <<= private;");
verifyFormat("public << private;", Style);
verifyFormat("public <<= private;", Style);
verifyFormat("if (public > private)");
verifyFormat("public >> private;");
verifyFormat("public >>= private;");
verifyFormat("public ^ private;");
verifyFormat("public ^= private;");
verifyFormat("public | private;");
verifyFormat("public |= private;");
verifyFormat("public >> private;", Style);
verifyFormat("public >>= private;", Style);
verifyFormat("public ^ private;", Style);
verifyFormat("public ^= private;", Style);
verifyFormat("public | private;", Style);
verifyFormat("public |= private;", Style);
verifyFormat("auto x = private ? 1 : 2;");
verifyFormat("if (public == private)");
verifyFormat("void foo(public, private)");
verifyFormat("public::foo();");

verifyFormat("class A {\n"
"public:\n"
Expand Down