UnwrappedLineFormatter(const FormatStyle &Style, SourceManager &SourceMgr,
const AnnotatedLine &Line, unsigned FirstIndent,
const AnnotatedToken &RootToken,
- WhitespaceManager &Whitespaces, bool StructuralError)
+ WhitespaceManager &Whitespaces)
: Style(Style), SourceMgr(SourceMgr), Line(Line),
FirstIndent(FirstIndent), RootToken(RootToken),
Whitespaces(Whitespaces), Count(0) {}
tooling::Replacements format() {
LexerBasedFormatTokenSource Tokens(Lex, SourceMgr);
UnwrappedLineParser Parser(Diag, Style, Tokens, *this);
- StructuralError = Parser.parse();
+ bool StructuralError = Parser.parse();
unsigned PreviousEndOfLineColumn = 0;
TokenAnnotator Annotator(Style, SourceMgr, Lex,
Tokens.getIdentTable().get("in"));
unsigned Indent = LevelIndent;
if (static_cast<int>(Indent) + Offset >= 0)
Indent += Offset;
- if (!FirstTok.WhiteSpaceStart.isValid() || StructuralError) {
- Indent = LevelIndent =
- SourceMgr.getSpellingColumnNumber(FirstTok.Tok.getLocation()) - 1;
- } else {
+ if (FirstTok.WhiteSpaceStart.isValid() &&
+ // Insert a break even if there is a structural error in case where
+ // we break apart a line consisting of multiple unwrapped lines.
+ (FirstTok.NewlinesBefore == 0 || !StructuralError)) {
formatFirstToken(TheLine.First, PreviousLineLastToken, Indent,
TheLine.InPPDirective, PreviousEndOfLineColumn);
+ } else {
+ Indent = LevelIndent =
+ SourceMgr.getSpellingColumnNumber(FirstTok.Tok.getLocation()) - 1;
}
tryFitMultipleLinesInOne(Indent, I, E);
UnwrappedLineFormatter Formatter(Style, SourceMgr, TheLine, Indent,
- TheLine.First, Whitespaces,
- StructuralError);
+ TheLine.First, Whitespaces);
PreviousEndOfLineColumn =
Formatter.format(I + 1 != E ? &*(I + 1) : NULL);
IndentForLevel[TheLine.Level] = LevelIndent;
WhitespaceManager Whitespaces;
std::vector<CharSourceRange> Ranges;
std::vector<AnnotatedLine> AnnotatedLines;
- bool StructuralError;
};
tooling::Replacements
class ScopedMacroState : public FormatTokenSource {
public:
ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource,
- FormatToken &ResetToken)
+ FormatToken &ResetToken, bool &StructuralError)
: Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
- PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource) {
+ PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource),
+ StructuralError(StructuralError),
+ PreviousStructuralError(StructuralError) {
TokenSource = this;
Line.Level = 0;
Line.InPPDirective = true;
ResetToken = Token;
Line.InPPDirective = false;
Line.Level = PreviousLineLevel;
+ StructuralError = PreviousStructuralError;
}
virtual FormatToken getNextToken() {
FormatToken &ResetToken;
unsigned PreviousLineLevel;
FormatTokenSource *PreviousTokenSource;
+ bool &StructuralError;
+ bool PreviousStructuralError;
FormatToken Token;
};
clang::DiagnosticsEngine &Diag, const FormatStyle &Style,
FormatTokenSource &Tokens, UnwrappedLineConsumer &Callback)
: Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
- CurrentLines(&Lines), Diag(Diag), Style(Style), Tokens(&Tokens),
- Callback(Callback) {}
+ CurrentLines(&Lines), StructuralError(false), Diag(Diag), Style(Style),
+ Tokens(&Tokens), Callback(Callback) {}
bool UnwrappedLineParser::parse() {
DEBUG(llvm::dbgs() << "----\n");
readToken();
- bool Error = parseFile();
+ parseFile();
for (std::vector<UnwrappedLine>::iterator I = Lines.begin(), E = Lines.end();
I != E; ++I) {
Callback.consumeUnwrappedLine(*I);
// Create line with eof token.
pushToken(FormatTok);
Callback.consumeUnwrappedLine(*Line);
-
- return Error;
+ return StructuralError;
}
-bool UnwrappedLineParser::parseFile() {
+void UnwrappedLineParser::parseFile() {
ScopedDeclarationState DeclarationState(
*Line, DeclarationScopeStack,
/*MustBeDeclaration=*/ !Line->InPPDirective);
- bool Error = parseLevel(/*HasOpeningBrace=*/ false);
+ parseLevel(/*HasOpeningBrace=*/ false);
// Make sure to format the remaining tokens.
flushComments(true);
addUnwrappedLine();
- return Error;
}
-bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
- bool Error = false;
+void UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
do {
switch (FormatTok.Tok.getKind()) {
case tok::comment:
case tok::l_brace:
// FIXME: Add parameter whether this can happen - if this happens, we must
// be in a non-declaration context.
- Error |= parseBlock(/*MustBeDeclaration=*/ false);
+ parseBlock(/*MustBeDeclaration=*/ false);
addUnwrappedLine();
break;
case tok::r_brace:
- if (HasOpeningBrace) {
- return false;
- } else {
- Diag.Report(FormatTok.Tok.getLocation(),
- Diag.getCustomDiagID(clang::DiagnosticsEngine::Error,
- "unexpected '}'"));
- Error = true;
- nextToken();
- addUnwrappedLine();
- }
+ if (HasOpeningBrace)
+ return;
+ Diag.Report(FormatTok.Tok.getLocation(),
+ Diag.getCustomDiagID(clang::DiagnosticsEngine::Error,
+ "unexpected '}'"));
+ StructuralError = true;
+ nextToken();
+ addUnwrappedLine();
break;
default:
parseStructuralElement();
break;
}
} while (!eof());
- return Error;
}
-bool UnwrappedLineParser::parseBlock(bool MustBeDeclaration,
+void UnwrappedLineParser::parseBlock(bool MustBeDeclaration,
unsigned AddLevels) {
assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected");
nextToken();
if (!FormatTok.Tok.is(tok::r_brace)) {
Line->Level -= AddLevels;
- return true;
+ StructuralError = true;
+ return;
}
nextToken(); // Munch the closing brace.
Line->Level -= AddLevels;
- return false;
}
void UnwrappedLineParser::parsePPDirective() {
assert(FormatTok.Tok.is(tok::hash) && "'#' expected");
- ScopedMacroState MacroState(*Line, Tokens, FormatTok);
+ ScopedMacroState MacroState(*Line, Tokens, FormatTok, StructuralError);
nextToken();
if (FormatTok.Tok.getIdentifierInfo() == NULL) {