aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Format
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Format')
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp42
-rw-r--r--clang/lib/Format/UnwrappedLineParser.cpp5
-rw-r--r--clang/lib/Format/WhitespaceManager.cpp16
3 files changed, 55 insertions, 8 deletions
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 11dc661abc24..86c9ac4aa364 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -3604,6 +3604,16 @@ static bool isAllmanLambdaBrace(const FormatToken &Tok) {
!Tok.isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral));
}
+// Returns the first token on the line that is not a comment.
+static const FormatToken *getFirstNonComment(const AnnotatedLine &Line) {
+ const FormatToken *Next = Line.First;
+ if (!Next)
+ return Next;
+ if (Next->is(tok::comment))
+ Next = Next->getNextNonComment();
+ return Next;
+}
+
bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
const FormatToken &Right) {
const FormatToken &Left = *Right.Previous;
@@ -3785,12 +3795,34 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
if (Right.is(TT_InlineASMBrace))
return Right.HasUnescapedNewline;
- if (isAllmanBrace(Left) || isAllmanBrace(Right))
- return (Line.startsWith(tok::kw_enum) && Style.BraceWrapping.AfterEnum) ||
- (Line.startsWith(tok::kw_typedef, tok::kw_enum) &&
- Style.BraceWrapping.AfterEnum) ||
- (Line.startsWith(tok::kw_class) && Style.BraceWrapping.AfterClass) ||
+ if (isAllmanBrace(Left) || isAllmanBrace(Right)) {
+ auto FirstNonComment = getFirstNonComment(Line);
+ bool AccessSpecifier =
+ FirstNonComment &&
+ FirstNonComment->isOneOf(Keywords.kw_internal, tok::kw_public,
+ tok::kw_private, tok::kw_protected);
+
+ if (Style.BraceWrapping.AfterEnum) {
+ if (Line.startsWith(tok::kw_enum) ||
+ Line.startsWith(tok::kw_typedef, tok::kw_enum))
+ return true;
+ // Ensure BraceWrapping for `public enum A {`.
+ if (AccessSpecifier && FirstNonComment->Next &&
+ FirstNonComment->Next->is(tok::kw_enum))
+ return true;
+ }
+
+ // Ensure BraceWrapping for `public interface A {`.
+ if (Style.BraceWrapping.AfterClass &&
+ ((AccessSpecifier && FirstNonComment->Next &&
+ FirstNonComment->Next->is(Keywords.kw_interface)) ||
+ Line.startsWith(Keywords.kw_interface)))
+ return true;
+
+ return (Line.startsWith(tok::kw_class) && Style.BraceWrapping.AfterClass) ||
(Line.startsWith(tok::kw_struct) && Style.BraceWrapping.AfterStruct);
+ }
+
if (Left.is(TT_ObjCBlockLBrace) &&
Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Never)
return true;
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 673986d16af2..8487875064aa 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -2532,6 +2532,8 @@ bool UnwrappedLineParser::parseEnum() {
if (FormatTok->Tok.is(tok::kw_enum))
nextToken();
+ const FormatToken &InitialToken = *FormatTok;
+
// In TypeScript, "enum" can also be used as property name, e.g. in interface
// declarations. An "enum" keyword followed by a colon would be a syntax
// error and thus assume it is just an identifier.
@@ -2578,7 +2580,8 @@ bool UnwrappedLineParser::parseEnum() {
return true;
}
- if (!Style.AllowShortEnumsOnASingleLine)
+ if (!Style.AllowShortEnumsOnASingleLine &&
+ ShouldBreakBeforeBrace(Style, InitialToken))
addUnwrappedLine();
// Parse enum body.
nextToken();
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index a822e0aaf1f9..74136d2f5caa 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -1146,14 +1146,15 @@ WhitespaceManager::CellDescriptions WhitespaceManager::getCells(unsigned Start,
} else if (C.Tok->is(tok::comma)) {
if (!Cells.empty())
Cells.back().EndIndex = i;
- Cell++;
+ if (C.Tok->getNextNonComment()->isNot(tok::r_brace)) // dangling comma
+ ++Cell;
}
} else if (Depth == 1) {
if (C.Tok == MatchingParen) {
if (!Cells.empty())
Cells.back().EndIndex = i;
Cells.push_back(CellDescription{i, ++Cell, i + 1, false, nullptr});
- CellCount = Cell + 1;
+ CellCount = C.Tok->Previous->isNot(tok::comma) ? Cell + 1 : Cell;
// Go to the next non-comment and ensure there is a break in front
const auto *NextNonComment = C.Tok->getNextNonComment();
while (NextNonComment->is(tok::comma))
@@ -1190,6 +1191,17 @@ WhitespaceManager::CellDescriptions WhitespaceManager::getCells(unsigned Start,
// So if we split a line previously and the tail line + this token is
// less then the column limit we remove the split here and just put
// the column start at a space past the comma
+ //
+ // FIXME This if branch covers the cases where the column is not
+ // the first column. This leads to weird pathologies like the formatting
+ // auto foo = Items{
+ // Section{
+ // 0, bar(),
+ // }
+ // };
+ // Well if it doesn't lead to that it's indicative that the line
+ // breaking should be revisited. Unfortunately alot of other options
+ // interact with this
auto j = i - 1;
if ((j - 1) > Start && Changes[j].Tok->is(tok::comma) &&
Changes[j - 1].NewlinesBefore > 0) {