[PATCH] D79293: [clang-format] [PR45218] Fix an issue where < and > and >> in a for loop gets incorrectly interpreted at a TemplateOpener/Closer
MyDeveloperDay via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sun May 3 10:37:36 PDT 2020
MyDeveloperDay updated this revision to Diff 261705.
MyDeveloperDay added a comment.
Add more test cases to try to ensure TemplateOpener/Closer type isn't assigned incorrectly.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D79293/new/
https://reviews.llvm.org/D79293
Files:
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/FormatTest.cpp
Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -7067,6 +7067,19 @@
verifyFormat("< < < < < < < < < < < < < < < < < < < < < < < < < < < < < <");
}
+TEST_F(FormatTest, UnderstandsShiftOperators) {
+ verifyFormat("if (i < x >> 1)");
+ verifyFormat("while (i < x >> 1)");
+ verifyFormat("for (unsigned i = 0; i < i; ++i, v = v >> 1)");
+ verifyFormat("for (unsigned i = 0; i < x >> 1; ++i, v = v >> 1)");
+ verifyFormat(
+ "for (std::vector<int>::iterator i = 0; i < x >> 1; ++i, v = v >> 1)");
+ verifyFormat("Foo.call<Bar<Function>>()");
+ verifyFormat("if (Foo.call<Bar<Function>>() == 0)");
+ verifyFormat("for (std::vector<std::pair<int>>::iterator i = 0; i < x >> 1; "
+ "++i, v = v >> 1)");
+}
+
TEST_F(FormatTest, BitshiftOperatorWidth) {
EXPECT_EQ("int a = 1 << 2; /* foo\n"
" bar */",
Index: clang/lib/Format/TokenAnnotator.cpp
===================================================================
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -119,7 +119,16 @@
(Style.Language == FormatStyle::LK_Proto && Left->Previous &&
Left->Previous->isOneOf(TT_SelectorName, TT_DictLiteral)))
CurrentToken->Type = TT_DictLiteral;
- else
+ // In if/for/while (i < x >> 1) ensure we don't see the <> as
+ // TemplateOpener/Closer
+ else if (CurrentToken->Next && CurrentToken->Next->is(tok::greater) &&
+ CurrentToken->Next->Next &&
+ !CurrentToken->Next->Next->isOneOf(tok::l_paren,
+ tok::coloncolon) &&
+ Line.First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_while)) {
+ Left->Type = TT_BinaryOperator;
+ return false;
+ } else
CurrentToken->Type = TT_TemplateCloser;
next();
return true;
@@ -145,6 +154,10 @@
Contexts[Contexts.size() - 2].IsExpression &&
!Line.startsWith(tok::kw_template))
return false;
+ // If we see a ; then likely this is a for loop and not the template
+ if (CurrentToken->is(tok::semi))
+ return false;
+
updateParameterCount(Left, CurrentToken);
if (Style.Language == FormatStyle::LK_Proto) {
if (FormatToken *Previous = CurrentToken->getPreviousNonComment()) {
@@ -1523,7 +1536,8 @@
if (Current.is(tok::exclaim)) {
if (Current.Previous &&
(Keywords.IsJavaScriptIdentifier(
- *Current.Previous, /* AcceptIdentifierName= */ true) ||
+ *Current.Previous,
+ /* AcceptIdentifierName= */ true) ||
Current.Previous->isOneOf(
tok::kw_namespace, tok::r_paren, tok::r_square, tok::r_brace,
Keywords.kw_type, Keywords.kw_get, Keywords.kw_set) ||
@@ -1970,7 +1984,7 @@
// same decision irrespective of the decisions for tokens leading up to it.
// Store this information to prevent this from causing exponential runtime.
llvm::SmallPtrSet<FormatToken *, 16> NonTemplateLess;
-};
+}; // namespace
static const int PrecedenceUnaryOperator = prec::PointerToMember + 1;
static const int PrecedenceArrowAndPeriod = prec::PointerToMember + 2;
@@ -2174,7 +2188,7 @@
FormatToken *Current;
};
-} // end anonymous namespace
+} // namespace
void TokenAnnotator::setCommentLineLevels(
SmallVectorImpl<AnnotatedLine *> &Lines) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79293.261705.patch
Type: text/x-patch
Size: 3628 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200503/cf08fb4a/attachment-0001.bin>
More information about the cfe-commits
mailing list