r285570 - Skip over AnnotatedLines with >50 levels of nesting; don't format them.
Daniel Jasper via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 31 06:23:00 PDT 2016
Author: djasper
Date: Mon Oct 31 08:23:00 2016
New Revision: 285570
URL: http://llvm.org/viewvc/llvm-project?rev=285570&view=rev
Log:
Skip over AnnotatedLines with >50 levels of nesting; don't format them.
Reasoning:
- ExpressionParser uses a lot of stack for these, bad in some environments.
- Our formatting algorithm is N^3 and gets really slow.
- The resulting formatting is unlikely to be any good.
- This is probably generated code we're formatting by accident.
We treat these as unparseable, and signal incomplete formatting. 50 is
an arbitrary number, I've only seen real problems from ~150 levels.
Patch by Sam McCall. Thank you.
Modified:
cfe/trunk/lib/Format/TokenAnnotator.cpp
cfe/trunk/unittests/Format/FormatTest.cpp
Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=285570&r1=285569&r2=285570&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Mon Oct 31 08:23:00 2016
@@ -1566,6 +1566,13 @@ void TokenAnnotator::setCommentLineLevel
}
}
+static unsigned maxNestingDepth(const AnnotatedLine &Line) {
+ unsigned Result = 0;
+ for (const auto* Tok = Line.First; Tok != nullptr; Tok = Tok->Next)
+ Result = std::max(Result, Tok->NestingLevel);
+ return Result;
+}
+
void TokenAnnotator::annotate(AnnotatedLine &Line) {
for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(),
E = Line.Children.end();
@@ -1574,6 +1581,14 @@ void TokenAnnotator::annotate(AnnotatedL
}
AnnotatingParser Parser(Style, Line, Keywords);
Line.Type = Parser.parseLine();
+
+ // With very deep nesting, ExpressionParser uses lots of stack and the
+ // formatting algorithm is very slow. We're not going to do a good job here
+ // anyway - it's probably generated code being formatted by mistake.
+ // Just skip the whole line.
+ if (maxNestingDepth(Line) > 50)
+ Line.Type = LT_Invalid;
+
if (Line.Type == LT_Invalid)
return;
Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=285570&r1=285569&r2=285570&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Mon Oct 31 08:23:00 2016
@@ -7179,6 +7179,30 @@ TEST_F(FormatTest, SpecialTokensAtEndOfL
verifyFormat("operator");
}
+TEST_F(FormatTest, SkipsDeeplyNestedLines) {
+ // This code would be painfully slow to format if we didn't skip it.
+ std::string Code("A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(\n" // 20x
+ "A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(\n"
+ "A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(\n"
+ "A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(\n"
+ "A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(A(\n"
+ "A(1, 1)\n"
+ ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n" // 10x
+ ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n"
+ ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n"
+ ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n"
+ ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n"
+ ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n"
+ ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n"
+ ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n"
+ ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1)\n"
+ ", 1), 1), 1), 1), 1), 1), 1), 1), 1), 1);\n");
+ // Deeply nested part is untouched, rest is formatted.
+ EXPECT_EQ(std::string("int i;\n") + Code + "int j;\n",
+ format(std::string("int i;\n") + Code + "int j;\n",
+ getLLVMStyle(), IC_ExpectIncomplete));
+}
+
//===----------------------------------------------------------------------===//
// Objective-C tests.
//===----------------------------------------------------------------------===//
More information about the cfe-commits
mailing list