<div dir="ltr">On Fri, Apr 12, 2013 at 7:13 AM, Manuel Klimek <span dir="ltr"><<a href="mailto:klimek@google.com" target="_blank">klimek@google.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: klimek<br>
Date: Fri Apr 12 09:13:36 2013<br>
New Revision: 179379<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=179379&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=179379&view=rev</a><br>
Log:<br>
Revamps structural error detection / handling.<br>
<br>
Previously we'd only detect structural errors on the very first level.<br>
This leads to incorrectly balanced braces not being discovered, and thus<br>
incorrect indentation.<br>
<br>
This change fixes the problem by:<br>
- changing the parser to use an error state that can be detected<br>
anywhere inside the productions, for example if we get an eof on<br>
SOME_MACRO({ some block <eof><br>
- previously we'd never break lines when we discovered a structural<br>
error; now we break even in the case of a structural error if there<br>
are two unwrapped lines within the same line; thus,<br>
void f() { while (true) { g(); y(); } }<br>
will still be re-formatted, even if there's missing braces somewhere<br>
in the file<br>
- still exclude macro definitions from generating structural error;<br>
macro definitions are inbalanced snippets<br>
<br>
Modified:<br>
cfe/trunk/lib/Format/Format.cpp<br>
cfe/trunk/lib/Format/UnwrappedLineParser.cpp<br>
cfe/trunk/lib/Format/UnwrappedLineParser.h<br>
cfe/trunk/unittests/Format/FormatTest.cpp<br>
<br>
Modified: cfe/trunk/lib/Format/Format.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=179379&r1=179378&r2=179379&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=179379&r1=179378&r2=179379&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Format/Format.cpp (original)<br>
+++ cfe/trunk/lib/Format/Format.cpp Fri Apr 12 09:13:36 2013<br>
@@ -459,7 +459,7 @@ public:<br>
UnwrappedLineFormatter(const FormatStyle &Style, SourceManager &SourceMgr,<br>
const AnnotatedLine &Line, unsigned FirstIndent,<br>
const AnnotatedToken &RootToken,<br>
- WhitespaceManager &Whitespaces, bool StructuralError)<br>
+ WhitespaceManager &Whitespaces)<br>
: Style(Style), SourceMgr(SourceMgr), Line(Line),<br>
FirstIndent(FirstIndent), RootToken(RootToken),<br>
Whitespaces(Whitespaces), Count(0) {}<br>
@@ -1381,7 +1381,7 @@ public:<br>
tooling::Replacements format() {<br>
LexerBasedFormatTokenSource Tokens(Lex, SourceMgr);<br>
UnwrappedLineParser Parser(Diag, Style, Tokens, *this);<br>
- StructuralError = Parser.parse();<br>
+ bool StructuralError = Parser.parse();<br>
unsigned PreviousEndOfLineColumn = 0;<br>
TokenAnnotator Annotator(Style, SourceMgr, Lex,<br>
Tokens.getIdentTable().get("in"));<br>
@@ -1431,17 +1431,19 @@ public:<br>
unsigned Indent = LevelIndent;<br>
if (static_cast<int>(Indent) + Offset >= 0)<br>
Indent += Offset;<br>
- if (!FirstTok.WhiteSpaceStart.isValid() || StructuralError) {<br>
- Indent = LevelIndent =<br>
- SourceMgr.getSpellingColumnNumber(FirstTok.Tok.getLocation()) - 1;<br>
- } else {<br>
+ if (FirstTok.WhiteSpaceStart.isValid() &&<br>
+ // Insert a break even if there is a structural error in case where<br>
+ // we break apart a line consisting of multiple unwrapped lines.<br>
+ (FirstTok.NewlinesBefore == 0 || !StructuralError)) {<br>
formatFirstToken(TheLine.First, PreviousLineLastToken, Indent,<br>
TheLine.InPPDirective, PreviousEndOfLineColumn);<br>
+ } else {<br>
+ Indent = LevelIndent =<br>
+ SourceMgr.getSpellingColumnNumber(FirstTok.Tok.getLocation()) - 1;<br>
}<br>
tryFitMultipleLinesInOne(Indent, I, E);<br>
UnwrappedLineFormatter Formatter(Style, SourceMgr, TheLine, Indent,<br>
- TheLine.First, Whitespaces,<br>
- StructuralError);<br>
+ TheLine.First, Whitespaces);<br>
PreviousEndOfLineColumn =<br>
Formatter.format(I + 1 != E ? &*(I + 1) : NULL);<br>
IndentForLevel[TheLine.Level] = LevelIndent;<br>
@@ -1742,7 +1744,6 @@ private:<br>
WhitespaceManager Whitespaces;<br>
std::vector<CharSourceRange> Ranges;<br>
std::vector<AnnotatedLine> AnnotatedLines;<br>
- bool StructuralError;<br>
};<br>
<br>
tooling::Replacements<br>
<br>
Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=179379&r1=179378&r2=179379&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=179379&r1=179378&r2=179379&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)<br>
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Fri Apr 12 09:13:36 2013<br>
@@ -45,9 +45,11 @@ private:<br>
class ScopedMacroState : public FormatTokenSource {<br>
public:<br>
ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource,<br>
- FormatToken &ResetToken)<br>
+ FormatToken &ResetToken, bool &StructuralError)<br>
: Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),<br>
- PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource) {<br>
+ PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource),<br>
+ StructuralError(StructuralError),<br>
+ PreviousStructuralError(StructuralError) {<br>
TokenSource = this;<br>
Line.Level = 0;<br>
Line.InPPDirective = true;<br>
@@ -58,6 +60,7 @@ public:<br>
ResetToken = Token;<br>
Line.InPPDirective = false;<br>
Line.Level = PreviousLineLevel;<br>
+ StructuralError = PreviousStructuralError;<br>
}<br>
<br>
virtual FormatToken getNextToken() {<br>
@@ -85,6 +88,8 @@ private:<br>
FormatToken &ResetToken;<br>
unsigned PreviousLineLevel;<br>
FormatTokenSource *PreviousTokenSource;<br>
+ bool &StructuralError;<br>
+ bool PreviousStructuralError;<br>
<br>
FormatToken Token;<br>
};<br>
@@ -124,13 +129,13 @@ UnwrappedLineParser::UnwrappedLineParser<br>
clang::DiagnosticsEngine &Diag, const FormatStyle &Style,<br>
FormatTokenSource &Tokens, UnwrappedLineConsumer &Callback)<br>
: Line(new UnwrappedLine), MustBreakBeforeNextToken(false),<br>
- CurrentLines(&Lines), Diag(Diag), Style(Style), Tokens(&Tokens),<br>
- Callback(Callback) {}<br>
+ CurrentLines(&Lines), StructuralError(false), Diag(Diag), Style(Style),<br>
+ Tokens(&Tokens), Callback(Callback) {}<br>
<br>
bool UnwrappedLineParser::parse() {<br>
DEBUG(llvm::dbgs() << "----\n");<br>
readToken();<br>
- bool Error = parseFile();<br>
+ parseFile();<br>
for (std::vector<UnwrappedLine>::iterator I = Lines.begin(), E = Lines.end();<br>
I != E; ++I) {<br>
Callback.consumeUnwrappedLine(*I);<br>
@@ -139,23 +144,20 @@ bool UnwrappedLineParser::parse() {<br>
// Create line with eof token.<br>
pushToken(FormatTok);<br>
Callback.consumeUnwrappedLine(*Line);<br>
-<br>
- return Error;<br>
+ return StructuralError;<br>
}<br>
<br>
-bool UnwrappedLineParser::parseFile() {<br>
+void UnwrappedLineParser::parseFile() {<br>
ScopedDeclarationState DeclarationState(<br>
*Line, DeclarationScopeStack,<br>
/*MustBeDeclaration=*/ !Line->InPPDirective);<br>
- bool Error = parseLevel(/*HasOpeningBrace=*/ false);<br>
+ parseLevel(/*HasOpeningBrace=*/ false);<br>
// Make sure to format the remaining tokens.<br>
flushComments(true);<br>
addUnwrappedLine();<br>
- return Error;<br>
}<br>
<br>
-bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {<br>
- bool Error = false;<br>
+void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {<br>
do {<br>
switch (FormatTok.Tok.getKind()) {<br>
case tok::comment:<br>
@@ -165,30 +167,27 @@ bool UnwrappedLineParser::parseLevel(boo<br>
case tok::l_brace:<br>
// FIXME: Add parameter whether this can happen - if this happens, we must<br>
// be in a non-declaration context.<br>
- Error |= parseBlock(/*MustBeDeclaration=*/ false);<br>
+ parseBlock(/*MustBeDeclaration=*/ false);<br>
addUnwrappedLine();<br>
break;<br>
case tok::r_brace:<br>
- if (HasOpeningBrace) {<br>
- return false;<br>
- } else {<br>
- Diag.Report(FormatTok.Tok.getLocation(),<br>
- Diag.getCustomDiagID(clang::DiagnosticsEngine::Error,<br>
- "unexpected '}'"));<br>
- Error = true;<br>
- nextToken();<br>
- addUnwrappedLine();<br>
- }<br>
+ if (HasOpeningBrace)<br>
+ return;<br>
+ Diag.Report(FormatTok.Tok.getLocation(),<br>
+ Diag.getCustomDiagID(clang::DiagnosticsEngine::Error,<br>
+ "unexpected '}'"));<br>
+ StructuralError = true;<br>
+ nextToken();<br>
+ addUnwrappedLine();<br>
break;<br>
default:<br>
parseStructuralElement();<br>
break;<br>
}<br>
} while (!eof());<br>
- return Error;<br>
}<br>
<br>
-bool UnwrappedLineParser::parseBlock(bool MustBeDeclaration,<br>
+void UnwrappedLineParser::parseBlock(bool MustBeDeclaration,<br>
unsigned AddLevels) {<br>
assert(<a href="http://FormatTok.Tok.is" target="_blank">FormatTok.Tok.is</a>(tok::l_brace) && "'{' expected");<br>
nextToken();<br>
@@ -202,17 +201,17 @@ bool UnwrappedLineParser::parseBlock(boo<br>
<br>
if (!<a href="http://FormatTok.Tok.is" target="_blank">FormatTok.Tok.is</a>(tok::r_brace)) {<br>
Line->Level -= AddLevels;<br>
- return true;<br>
+ StructuralError = true;<br>
+ return;<br>
}<br>
<br>
nextToken(); // Munch the closing brace.<br>
Line->Level -= AddLevels;<br>
- return false;<br>
}<br>
<br>
void UnwrappedLineParser::parsePPDirective() {<br>
assert(<a href="http://FormatTok.Tok.is" target="_blank">FormatTok.Tok.is</a>(tok::hash) && "'#' expected");<br>
- ScopedMacroState MacroState(*Line, Tokens, FormatTok);<br>
+ ScopedMacroState MacroState(*Line, Tokens, FormatTok, StructuralError);<br>
nextToken();<br>
<br>
if (FormatTok.Tok.getIdentifierInfo() == NULL) {<br>
<br>
Modified: cfe/trunk/lib/Format/UnwrappedLineParser.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.h?rev=179379&r1=179378&r2=179379&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.h?rev=179379&r1=179378&r2=179379&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Format/UnwrappedLineParser.h (original)<br>
+++ cfe/trunk/lib/Format/UnwrappedLineParser.h Fri Apr 12 09:13:36 2013<br>
@@ -125,9 +125,9 @@ public:<br>
bool parse();<br>
<br>
private:<br>
- bool parseFile();<br>
- bool parseLevel(bool HasOpeningBrace);<br>
- bool parseBlock(bool MustBeDeclaration, unsigned AddLevels = 1);<br>
+ void parseFile();<br>
+ void parseLevel(bool HasOpeningBrace);<br>
+ void parseBlock(bool MustBeDeclaration, unsigned AddLevels = 1);<br>
void parsePPDirective();<br>
void parsePPDefine();<br>
void parsePPUnknown();<br>
@@ -187,6 +187,10 @@ private:<br>
// whether we are in a compound statement or not.<br>
std::vector<bool> DeclarationScopeStack;<br>
<br>
+ // Will be true if we encounter an error that leads to possibily incorrect<br>
+ // indentation levels.<br>
+ bool StructuralError;<br>
+<br>
clang::DiagnosticsEngine &Diag;<br>
const FormatStyle &Style;<br>
FormatTokenSource *Tokens;<br>
<br>
Modified: cfe/trunk/unittests/Format/FormatTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=179379&r1=179378&r2=179379&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=179379&r1=179378&r2=179379&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)<br>
+++ cfe/trunk/unittests/Format/FormatTest.cpp Fri Apr 12 09:13:36 2013<br>
@@ -430,6 +430,7 @@ TEST_F(FormatTest, FormatsSwitchStatemen<br>
verifyFormat("switch (x) {\n"<br>
"default: {\n"<br>
" // Do nothing.\n"<br>
+ "}\n"<br>
"}");<br>
verifyFormat("switch (x) {\n"<br>
"// comment\n"<br>
@@ -3563,8 +3564,18 @@ TEST_F(FormatTest, ObjCLiterals) {<br>
verifyFormat("@{ @\"one\" : @1 }");<br>
verifyFormat("return @{ @\"one\" : @1 };");<br>
verifyFormat("@{ @\"one\" : @1, }");<br>
- verifyFormat("@{ @\"one\" : @{ @2 : @1 } }");<br>
- verifyFormat("@{ @\"one\" : @{ @2 : @1 }, }");<br>
+<br>
+ // FIXME: Breaking in cases where we think there's a structural error<br>
+ // showed that we're incorrectly parsing this code. We need to fix the<br>
+ // parsing here.<br></blockquote><div><br></div><div style>Any progress on this? This regressed working functionality.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ verifyFormat("@{ @\"one\" : @\n"<br>
+ "{ @2 : @1 }\n"<br>
+ "}");<br>
+ verifyFormat("@{ @\"one\" : @\n"<br>
+ "{ @2 : @1 }\n"<br>
+ ",\n"<br>
+ "}");<br>
+<br>
verifyFormat("@{ 1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2 }");<br>
verifyFormat("[self setDict:@{}");<br>
verifyFormat("[self setDict:@{ @1 : @2 }");<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>