diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Format/Format.cpp | 48 | ||||
-rw-r--r-- | clang/lib/Format/TokenAnnotator.cpp | 8 |
2 files changed, 52 insertions, 4 deletions
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index f225c1a30c1..f5e7a206a56 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1765,6 +1765,15 @@ public: checkEmptyNamespace(AnnotatedLines); + for (auto &Line : AnnotatedLines) { + if (Line->Affected) { + cleanupRight(Line->First, tok::comma, tok::comma); + cleanupRight(Line->First, TT_CtorInitializerColon, tok::comma); + cleanupLeft(Line->First, TT_CtorInitializerComma, tok::l_brace); + cleanupLeft(Line->First, TT_CtorInitializerColon, tok::l_brace); + } + } + return generateFixes(); } @@ -1853,6 +1862,45 @@ private: return true; } + // Checks pairs {start, start->next},..., {end->previous, end} and deletes one + // of the token in the pair if the left token has \p LK token kind and the + // right token has \p RK token kind. If \p DeleteLeft is true, the left token + // is deleted on match; otherwise, the right token is deleted. + template <typename LeftKind, typename RightKind> + void cleanupPair(FormatToken *Start, LeftKind LK, RightKind RK, + bool DeleteLeft) { + auto NextNotDeleted = [this](const FormatToken &Tok) -> FormatToken * { + for (auto *Res = Tok.Next; Res; Res = Res->Next) + if (!Res->is(tok::comment) && + DeletedTokens.find(Res) == DeletedTokens.end()) + return Res; + return nullptr; + }; + for (auto *Left = Start; Left;) { + auto *Right = NextNotDeleted(*Left); + if (!Right) + break; + if (Left->is(LK) && Right->is(RK)) { + deleteToken(DeleteLeft ? Left : Right); + // If the right token is deleted, we should keep the left token + // unchanged and pair it with the new right token. + if (!DeleteLeft) + continue; + } + Left = Right; + } + } + + template <typename LeftKind, typename RightKind> + void cleanupLeft(FormatToken *Start, LeftKind LK, RightKind RK) { + cleanupPair(Start, LK, RK, /*DeleteLeft=*/true); + } + + template <typename LeftKind, typename RightKind> + void cleanupRight(FormatToken *Start, LeftKind LK, RightKind RK) { + cleanupPair(Start, LK, RK, /*DeleteLeft=*/false); + } + // Delete the given token. inline void deleteToken(FormatToken *Tok) { if (Tok) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index c94dd9c8329..2191864da26 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -920,6 +920,10 @@ private: Contexts.back().IsExpression = false; } else if (Current.is(TT_LambdaArrow) || Current.is(Keywords.kw_assert)) { Contexts.back().IsExpression = Style.Language == FormatStyle::LK_Java; + } else if (Current.Previous && + Current.Previous->is(TT_CtorInitializerColon)) { + Contexts.back().IsExpression = true; + Contexts.back().InCtorInitializer = true; } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) { for (FormatToken *Previous = Current.Previous; Previous && Previous->isOneOf(tok::star, tok::amp); @@ -927,10 +931,6 @@ private: Previous->Type = TT_PointerOrReference; if (Line.MustBeDeclaration && !Contexts.front().InCtorInitializer) Contexts.back().IsExpression = false; - } else if (Current.Previous && - Current.Previous->is(TT_CtorInitializerColon)) { - Contexts.back().IsExpression = true; - Contexts.back().InCtorInitializer = true; } else if (Current.is(tok::kw_new)) { Contexts.back().CanBeExpression = false; } else if (Current.isOneOf(tok::semi, tok::exclaim)) { |