diff options
author | Manuel Klimek <klimek@google.com> | 2013-01-02 18:33:23 +0000 |
---|---|---|
committer | Manuel Klimek <klimek@google.com> | 2013-01-02 18:33:23 +0000 |
commit | 060143e4ad7f80c4349d472c06a63a953650c2a9 (patch) | |
tree | 66bc38156700622107b3459855ba1ebc84892c0f /lib/Format/Format.cpp | |
parent | 5eda31ee30106c769b5829683761d42e6e50467f (diff) |
Fixes multiple formatting bugs.
Fixes:
- incorrect handling of multiple consecutive preprocessor directives
- crash when trying to right align the escpaed newline for a line that
is longer than the column limit
- using only ColumnLimit-1 columns when layouting with escaped newlines
inside preprocessor directives
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@171401 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format/Format.cpp')
-rw-r--r-- | lib/Format/Format.cpp | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index 6fb75a657a..54a2771eb9 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -237,6 +237,7 @@ private: unsigned ParenLevel = State.Indent.size() - 1; if (Newline) { + unsigned WhitespaceStartColumn = State.Column; if (Current.Tok.is(tok::string_literal) && Previous.Tok.is(tok::string_literal)) { State.Column = State.Column - Previous.Tok.getLength(); @@ -264,8 +265,12 @@ private: State.LineContainsContinuedForLoopSection = Previous.Tok.isNot(tok::semi); - if (!DryRun) - replaceWhitespace(Current, 1, State.Column); + if (!DryRun) { + if (!Line.InPPDirective) + replaceWhitespace(Current, 1, State.Column); + else + replacePPWhitespace(Current, 1, State.Column, WhitespaceStartColumn); + } State.LastSpace[ParenLevel] = State.Indent[ParenLevel]; if (Current.Tok.is(tok::colon) && @@ -398,7 +403,7 @@ private: addTokenToState(NewLine, true, State); // Exceeding column limit is bad. - if (State.Column > Style.ColumnLimit) + if (State.Column > Style.ColumnLimit - (Line.InPPDirective ? 1 : 0)) return UINT_MAX; if (StopAt <= CurrentPenalty) @@ -434,12 +439,22 @@ private: /// each \c FormatToken. void replaceWhitespace(const FormatToken &Tok, unsigned NewLines, unsigned Spaces) { + Replaces.insert(tooling::Replacement( + SourceMgr, Tok.WhiteSpaceStart, Tok.WhiteSpaceLength, + std::string(NewLines, '\n') + std::string(Spaces, ' '))); + } + + /// \brief Like \c replaceWhitespace, but additionally adds right-aligned + /// backslashes to escape newlines inside a preprocessor directive. + /// + /// This function and \c replaceWhitespace have the same behavior if + /// \c Newlines == 0. + void replacePPWhitespace(const FormatToken &Tok, unsigned NewLines, + unsigned Spaces, unsigned WhitespaceStartColumn) { std::string NewLineText; - if (!Line.InPPDirective) { - NewLineText = std::string(NewLines, '\n'); - } else if (NewLines > 0) { + if (NewLines > 0) { unsigned Offset = - SourceMgr.getSpellingColumnNumber(Tok.WhiteSpaceStart) - 1; + std::min<int>(Style.ColumnLimit - 1, WhitespaceStartColumn); for (unsigned i = 0; i < NewLines; ++i) { NewLineText += std::string(Style.ColumnLimit - Offset - 1, ' '); NewLineText += "\\\n"; @@ -469,7 +484,11 @@ private: Token.Tok.is(tok::kw_private)) && static_cast<int>(Indent) + Style.AccessModifierOffset >= 0) Indent += Style.AccessModifierOffset; - replaceWhitespace(Token, Newlines, Indent); + if (!Line.InPPDirective || Token.HasUnescapedNewline) + replaceWhitespace(Token, Newlines, Indent); + else + // FIXME: Figure out how to get the previous end-of-line column. + replacePPWhitespace(Token, Newlines, Indent, 0); return Indent; } |