Skip to content

Commit c81dd3d

Browse files
[clang-format] Handle shifts within conditions
In some situation shifts can be treated as a template, and is thus formatted as one. So, by doing a couple extra checks to assure that the condition doesn't contain a template, and is in fact a bit shift should solve this problem. This is a fix for [[ https://bugs.llvm.org/show_bug.cgi?id=46969 | bug 46969 ]] Reviewed By: MyDeveloperDay Patch By: Saldivarcher Differential Revision: https://reviews.llvm.org/D86581
1 parent c2f6a00 commit c81dd3d

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ static bool isLambdaParameterList(const FormatToken *Left) {
5656
Left->Previous->MatchingParen->is(TT_LambdaLSquare);
5757
}
5858

59+
/// Returns \c true if the token is followed by a boolean condition, \c false
60+
/// otherwise.
61+
static bool isKeywordWithCondition(const FormatToken &Tok) {
62+
return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
63+
tok::kw_constexpr, tok::kw_catch);
64+
}
65+
5966
/// A parser that gathers additional information about tokens.
6067
///
6168
/// The \c TokenAnnotator tries to match parenthesis and square brakets and
@@ -108,6 +115,12 @@ class AnnotatingParser {
108115

109116
while (CurrentToken) {
110117
if (CurrentToken->is(tok::greater)) {
118+
// Try to do a better job at looking for ">>" within the condition of
119+
// a statement.
120+
if (CurrentToken->Next && CurrentToken->Next->is(tok::greater) &&
121+
Left->ParentBracket != tok::less &&
122+
isKeywordWithCondition(*Line.First))
123+
return false;
111124
Left->MatchingParen = CurrentToken;
112125
CurrentToken->MatchingParen = Left;
113126
// In TT_Proto, we must distignuish between:
@@ -2768,13 +2781,6 @@ bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken &Right) const {
27682781
Right.ParameterCount > 0);
27692782
}
27702783

2771-
/// Returns \c true if the token is followed by a boolean condition, \c false
2772-
/// otherwise.
2773-
static bool isKeywordWithCondition(const FormatToken &Tok) {
2774-
return Tok.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
2775-
tok::kw_constexpr, tok::kw_catch);
2776-
}
2777-
27782784
bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
27792785
const FormatToken &Left,
27802786
const FormatToken &Right) {

clang/unittests/Format/FormatTest.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7565,6 +7565,21 @@ TEST_F(FormatTest, UnderstandsTemplateParameters) {
75657565
verifyFormat("static_assert(is_convertible<A &&, B>::value, \"AAA\");");
75667566
verifyFormat("Constructor(A... a) : a_(X<A>{std::forward<A>(a)}...) {}");
75677567
verifyFormat("< < < < < < < < < < < < < < < < < < < < < < < < < < < < < <");
7568+
verifyFormat("some_templated_type<decltype([](int i) { return i; })>");
7569+
}
7570+
7571+
TEST_F(FormatTest, UnderstandsShiftOperators) {
7572+
verifyFormat("if (i < x >> 1)");
7573+
verifyFormat("while (i < x >> 1)");
7574+
verifyFormat("for (unsigned i = 0; i < i; ++i, v = v >> 1)");
7575+
verifyFormat("for (unsigned i = 0; i < x >> 1; ++i, v = v >> 1)");
7576+
verifyFormat(
7577+
"for (std::vector<int>::iterator i = 0; i < x >> 1; ++i, v = v >> 1)");
7578+
verifyFormat("Foo.call<Bar<Function>>()");
7579+
verifyFormat("if (Foo.call<Bar<Function>>() == 0)");
7580+
verifyFormat("for (std::vector<std::pair<int>>::iterator i = 0; i < x >> 1; "
7581+
"++i, v = v >> 1)");
7582+
verifyFormat("if (w<u<v<x>>, 1>::t)");
75687583
}
75697584

75707585
TEST_F(FormatTest, BitshiftOperatorWidth) {

0 commit comments

Comments
 (0)