r191527 - Implemented tab usage only for indentation (http://llvm.org/PR17363)
Alexander Kornienko
alexfh at google.com
Fri Sep 27 09:14:23 PDT 2013
Author: alexfh
Date: Fri Sep 27 11:14:22 2013
New Revision: 191527
URL: http://llvm.org/viewvc/llvm-project?rev=191527&view=rev
Log:
Implemented tab usage only for indentation (http://llvm.org/PR17363)
Summary:
Changed UseTab to be a enum with three options: Never, Always,
ForIndentation (true/false are still supported when reading .clang-format).
IndentLevel should currently be propagated correctly for all tokens, except for
block comments. Please take a look at the general idea before I start dealing
with block comments.
Reviewers: klimek, djasper
Reviewed By: klimek
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D1770
Modified:
cfe/trunk/include/clang/Format/Format.h
cfe/trunk/lib/Format/BreakableToken.cpp
cfe/trunk/lib/Format/BreakableToken.h
cfe/trunk/lib/Format/ContinuationIndenter.cpp
cfe/trunk/lib/Format/Format.cpp
cfe/trunk/lib/Format/WhitespaceManager.cpp
cfe/trunk/lib/Format/WhitespaceManager.h
cfe/trunk/unittests/Format/FormatTest.cpp
Modified: cfe/trunk/include/clang/Format/Format.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=191527&r1=191526&r2=191527&view=diff
==============================================================================
--- cfe/trunk/include/clang/Format/Format.h (original)
+++ cfe/trunk/include/clang/Format/Format.h Fri Sep 27 11:14:22 2013
@@ -166,9 +166,19 @@ struct FormatStyle {
/// \brief If \c true, always break before multiline string literals.
bool AlwaysBreakBeforeMultilineStrings;
- /// \brief If \c true, \c IndentWidth consecutive spaces will be replaced
- /// with tab characters.
- bool UseTab;
+ /// \brief Different ways to use tab in formatting.
+ enum UseTabStyle {
+ /// Never use tab.
+ UT_Never,
+ /// Use tabs only for indentation.
+ UT_ForIndentation,
+ /// Use tabs whenever we need to fill whitespace that spans at least from
+ /// one tab stop to the next one.
+ UT_Always
+ };
+
+ /// \brief The way to use tab characters in the resulting file.
+ UseTabStyle UseTab;
/// \brief If \c true, binary operators will be placed after line breaks.
bool BreakBeforeBinaryOperators;
Modified: cfe/trunk/lib/Format/BreakableToken.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/BreakableToken.cpp?rev=191527&r1=191526&r2=191527&view=diff
==============================================================================
--- cfe/trunk/lib/Format/BreakableToken.cpp (original)
+++ cfe/trunk/lib/Format/BreakableToken.cpp Fri Sep 27 11:14:22 2013
@@ -145,10 +145,10 @@ unsigned BreakableSingleLineToken::getLi
}
BreakableSingleLineToken::BreakableSingleLineToken(
- const FormatToken &Tok, unsigned StartColumn, StringRef Prefix,
- StringRef Postfix, bool InPPDirective, encoding::Encoding Encoding,
- const FormatStyle &Style)
- : BreakableToken(Tok, InPPDirective, Encoding, Style),
+ const FormatToken &Tok, unsigned IndentLevel, unsigned StartColumn,
+ StringRef Prefix, StringRef Postfix, bool InPPDirective,
+ encoding::Encoding Encoding, const FormatStyle &Style)
+ : BreakableToken(Tok, IndentLevel, InPPDirective, Encoding, Style),
StartColumn(StartColumn), Prefix(Prefix), Postfix(Postfix) {
assert(Tok.TokenText.startswith(Prefix) && Tok.TokenText.endswith(Postfix));
Line = Tok.TokenText.substr(
@@ -156,11 +156,11 @@ BreakableSingleLineToken::BreakableSingl
}
BreakableStringLiteral::BreakableStringLiteral(
- const FormatToken &Tok, unsigned StartColumn, StringRef Prefix,
- StringRef Postfix, bool InPPDirective, encoding::Encoding Encoding,
- const FormatStyle &Style)
- : BreakableSingleLineToken(Tok, StartColumn, Prefix, Postfix, InPPDirective,
- Encoding, Style) {}
+ const FormatToken &Tok, unsigned IndentLevel, unsigned StartColumn,
+ StringRef Prefix, StringRef Postfix, bool InPPDirective,
+ encoding::Encoding Encoding, const FormatStyle &Style)
+ : BreakableSingleLineToken(Tok, IndentLevel, StartColumn, Prefix, Postfix,
+ InPPDirective, Encoding, Style) {}
BreakableToken::Split
BreakableStringLiteral::getSplit(unsigned LineIndex, unsigned TailOffset,
@@ -175,7 +175,7 @@ void BreakableStringLiteral::insertBreak
WhitespaceManager &Whitespaces) {
Whitespaces.replaceWhitespaceInToken(
Tok, Prefix.size() + TailOffset + Split.first, Split.second, Postfix,
- Prefix, InPPDirective, 1, StartColumn);
+ Prefix, InPPDirective, 1, IndentLevel, StartColumn);
}
static StringRef getLineCommentPrefix(StringRef Comment) {
@@ -186,12 +186,10 @@ static StringRef getLineCommentPrefix(St
return "";
}
-BreakableLineComment::BreakableLineComment(const FormatToken &Token,
- unsigned StartColumn,
- bool InPPDirective,
- encoding::Encoding Encoding,
- const FormatStyle &Style)
- : BreakableSingleLineToken(Token, StartColumn,
+BreakableLineComment::BreakableLineComment(
+ const FormatToken &Token, unsigned IndentLevel, unsigned StartColumn,
+ bool InPPDirective, encoding::Encoding Encoding, const FormatStyle &Style)
+ : BreakableSingleLineToken(Token, IndentLevel, StartColumn,
getLineCommentPrefix(Token.TokenText), "",
InPPDirective, Encoding, Style) {
OriginalPrefix = Prefix;
@@ -216,7 +214,7 @@ void BreakableLineComment::insertBreak(u
WhitespaceManager &Whitespaces) {
Whitespaces.replaceWhitespaceInToken(
Tok, OriginalPrefix.size() + TailOffset + Split.first, Split.second,
- Postfix, Prefix, InPPDirective, 1, StartColumn);
+ Postfix, Prefix, InPPDirective, 1, IndentLevel, StartColumn);
}
void
@@ -224,15 +222,15 @@ BreakableLineComment::replaceWhitespaceB
WhitespaceManager &Whitespaces) {
if (OriginalPrefix != Prefix) {
Whitespaces.replaceWhitespaceInToken(Tok, OriginalPrefix.size(), 0, "", "",
- false, 0, 1);
+ false, 0, /*IndentLevel=*/0, 1);
}
}
BreakableBlockComment::BreakableBlockComment(
- const FormatToken &Token, unsigned StartColumn,
+ const FormatToken &Token, unsigned IndentLevel, unsigned StartColumn,
unsigned OriginalStartColumn, bool FirstInLine, bool InPPDirective,
encoding::Encoding Encoding, const FormatStyle &Style)
- : BreakableToken(Token, InPPDirective, Encoding, Style) {
+ : BreakableToken(Token, IndentLevel, InPPDirective, Encoding, Style) {
StringRef TokenText(Token.TokenText);
assert(TokenText.startswith("/*") && TokenText.endswith("*/"));
TokenText.substr(2, TokenText.size() - 4).split(Lines, "\n");
@@ -327,12 +325,6 @@ void BreakableBlockComment::adjustWhites
LeadingWhitespace[LineIndex] =
Lines[LineIndex].begin() - Lines[LineIndex - 1].end();
- // FIXME: We currently count tabs as 1 character. To solve this, we need to
- // get the correct indentation width of the start of the comment, which
- // requires correct counting of the tab expansions before the comment, and
- // a configurable tab width. Since the current implementation only breaks
- // if leading tabs are intermixed with spaces, that is not a high priority.
-
// Adjust the start column uniformly accross all lines.
StartOfLineColumn[LineIndex] = std::max<int>(
0,
@@ -376,9 +368,9 @@ void BreakableBlockComment::insertBreak(
Text.data() - Tok.TokenText.data() + Split.first;
unsigned CharsToRemove = Split.second;
assert(IndentAtLineBreak >= Decoration.size());
- Whitespaces.replaceWhitespaceInToken(Tok, BreakOffsetInToken, CharsToRemove,
- "", Prefix, InPPDirective, 1,
- IndentAtLineBreak - Decoration.size());
+ Whitespaces.replaceWhitespaceInToken(
+ Tok, BreakOffsetInToken, CharsToRemove, "", Prefix, InPPDirective, 1,
+ IndentLevel, IndentAtLineBreak - Decoration.size());
}
void
@@ -412,7 +404,8 @@ BreakableBlockComment::replaceWhitespace
assert(StartOfLineColumn[LineIndex] >= Prefix.size());
Whitespaces.replaceWhitespaceInToken(
Tok, WhitespaceOffsetInToken, LeadingWhitespace[LineIndex], "", Prefix,
- InPPDirective, 1, StartOfLineColumn[LineIndex] - Prefix.size());
+ InPPDirective, 1, IndentLevel,
+ StartOfLineColumn[LineIndex] - Prefix.size());
}
unsigned
Modified: cfe/trunk/lib/Format/BreakableToken.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/BreakableToken.h?rev=191527&r1=191526&r2=191527&view=diff
==============================================================================
--- cfe/trunk/lib/Format/BreakableToken.h (original)
+++ cfe/trunk/lib/Format/BreakableToken.h Fri Sep 27 11:14:22 2013
@@ -66,12 +66,14 @@ public:
WhitespaceManager &Whitespaces) {}
protected:
- BreakableToken(const FormatToken &Tok, bool InPPDirective,
- encoding::Encoding Encoding, const FormatStyle &Style)
- : Tok(Tok), InPPDirective(InPPDirective), Encoding(Encoding),
- Style(Style) {}
+ BreakableToken(const FormatToken &Tok, unsigned IndentLevel,
+ bool InPPDirective, encoding::Encoding Encoding,
+ const FormatStyle &Style)
+ : Tok(Tok), IndentLevel(IndentLevel), InPPDirective(InPPDirective),
+ Encoding(Encoding), Style(Style) {}
const FormatToken &Tok;
+ const unsigned IndentLevel;
const bool InPPDirective;
const encoding::Encoding Encoding;
const FormatStyle &Style;
@@ -88,9 +90,10 @@ public:
StringRef::size_type Length) const;
protected:
- BreakableSingleLineToken(const FormatToken &Tok, unsigned StartColumn,
- StringRef Prefix, StringRef Postfix,
- bool InPPDirective, encoding::Encoding Encoding,
+ BreakableSingleLineToken(const FormatToken &Tok, unsigned IndentLevel,
+ unsigned StartColumn, StringRef Prefix,
+ StringRef Postfix, bool InPPDirective,
+ encoding::Encoding Encoding,
const FormatStyle &Style);
// The column in which the token starts.
@@ -109,10 +112,10 @@ public:
///
/// \p StartColumn specifies the column in which the token will start
/// after formatting.
- BreakableStringLiteral(const FormatToken &Tok, unsigned StartColumn,
- StringRef Prefix, StringRef Postfix,
- bool InPPDirective, encoding::Encoding Encoding,
- const FormatStyle &Style);
+ BreakableStringLiteral(const FormatToken &Tok, unsigned IndentLevel,
+ unsigned StartColumn, StringRef Prefix,
+ StringRef Postfix, bool InPPDirective,
+ encoding::Encoding Encoding, const FormatStyle &Style);
virtual Split getSplit(unsigned LineIndex, unsigned TailOffset,
unsigned ColumnLimit) const;
@@ -126,9 +129,9 @@ public:
///
/// \p StartColumn specifies the column in which the comment will start
/// after formatting.
- BreakableLineComment(const FormatToken &Token, unsigned StartColumn,
- bool InPPDirective, encoding::Encoding Encoding,
- const FormatStyle &Style);
+ BreakableLineComment(const FormatToken &Token, unsigned IndentLevel,
+ unsigned StartColumn, bool InPPDirective,
+ encoding::Encoding Encoding, const FormatStyle &Style);
virtual Split getSplit(unsigned LineIndex, unsigned TailOffset,
unsigned ColumnLimit) const;
@@ -150,10 +153,10 @@ public:
/// after formatting, while \p OriginalStartColumn specifies in which
/// column the comment started before formatting.
/// If the comment starts a line after formatting, set \p FirstInLine to true.
- BreakableBlockComment(const FormatToken &Token, unsigned StartColumn,
- unsigned OriginaStartColumn, bool FirstInLine,
- bool InPPDirective, encoding::Encoding Encoding,
- const FormatStyle &Style);
+ BreakableBlockComment(const FormatToken &Token, unsigned IndentLevel,
+ unsigned StartColumn, unsigned OriginaStartColumn,
+ bool FirstInLine, bool InPPDirective,
+ encoding::Encoding Encoding, const FormatStyle &Style);
virtual unsigned getLineCount() const;
virtual unsigned getLineLengthAfterSplit(unsigned LineIndex,
Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=191527&r1=191526&r2=191527&view=diff
==============================================================================
--- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original)
+++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Fri Sep 27 11:14:22 2013
@@ -303,12 +303,13 @@ unsigned ContinuationIndenter::addTokenT
State.Stack.back().BreakBeforeParameter = false;
if (!DryRun) {
- unsigned NewLines = 1;
+ unsigned Newlines = 1;
if (Current.is(tok::comment))
- NewLines = std::max(NewLines, std::min(Current.NewlinesBefore,
+ Newlines = std::max(Newlines, std::min(Current.NewlinesBefore,
Style.MaxEmptyLinesToKeep + 1));
- Whitespaces.replaceWhitespace(Current, NewLines, State.Column,
- State.Column, State.Line->InPPDirective);
+ Whitespaces.replaceWhitespace(Current, Newlines, State.Line->Level,
+ State.Column, State.Column,
+ State.Line->InPPDirective);
}
if (!Current.isTrailingComment())
@@ -363,7 +364,8 @@ unsigned ContinuationIndenter::addTokenT
unsigned Spaces = State.NextToken->SpacesRequiredBefore + ExtraSpaces;
if (!DryRun)
- Whitespaces.replaceWhitespace(Current, 0, Spaces, State.Column + Spaces);
+ Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, /*IndentLevel=*/0,
+ Spaces, State.Column + Spaces);
if (Current.Type == TT_ObjCSelectorName &&
State.Stack.back().ColonPos == 0) {
@@ -693,21 +695,22 @@ unsigned ContinuationIndenter::breakProt
Text.startswith(Prefix = "L\""))) ||
(Text.startswith(Prefix = "_T(\"") && Text.endswith(Postfix = "\")")) ||
getRawStringLiteralPrefixPostfix(Text, Prefix, Postfix)) {
- Token.reset(new BreakableStringLiteral(Current, StartColumn, Prefix,
- Postfix, State.Line->InPPDirective,
- Encoding, Style));
+ Token.reset(new BreakableStringLiteral(
+ Current, State.Line->Level, StartColumn, Prefix, Postfix,
+ State.Line->InPPDirective, Encoding, Style));
} else {
return 0;
}
} else if (Current.Type == TT_BlockComment && Current.isTrailingComment()) {
Token.reset(new BreakableBlockComment(
- Current, StartColumn, Current.OriginalColumn, !Current.Previous,
- State.Line->InPPDirective, Encoding, Style));
+ Current, State.Line->Level, StartColumn, Current.OriginalColumn,
+ !Current.Previous, State.Line->InPPDirective, Encoding, Style));
} else if (Current.Type == TT_LineComment &&
(Current.Previous == NULL ||
Current.Previous->Type != TT_ImplicitStringLiteral)) {
- Token.reset(new BreakableLineComment(
- Current, StartColumn, State.Line->InPPDirective, Encoding, Style));
+ Token.reset(new BreakableLineComment(Current, State.Line->Level,
+ StartColumn, State.Line->InPPDirective,
+ Encoding, Style));
} else {
return 0;
}
Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=191527&r1=191526&r2=191527&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Fri Sep 27 11:14:22 2013
@@ -45,6 +45,19 @@ struct ScalarEnumerationTraits<clang::fo
};
template <>
+struct ScalarEnumerationTraits<clang::format::FormatStyle::UseTabStyle> {
+ static void
+ enumeration(IO &IO, clang::format::FormatStyle::UseTabStyle &Value) {
+ IO.enumCase(Value, "Never", clang::format::FormatStyle::UT_Never);
+ IO.enumCase(Value, "false", clang::format::FormatStyle::UT_Never);
+ IO.enumCase(Value, "Always", clang::format::FormatStyle::UT_Always);
+ IO.enumCase(Value, "true", clang::format::FormatStyle::UT_Always);
+ IO.enumCase(Value, "ForIndentation",
+ clang::format::FormatStyle::UT_ForIndentation);
+ }
+};
+
+template <>
struct ScalarEnumerationTraits<clang::format::FormatStyle::BraceBreakingStyle> {
static void
enumeration(IO &IO, clang::format::FormatStyle::BraceBreakingStyle &Value) {
@@ -194,7 +207,7 @@ FormatStyle getLLVMStyle() {
LLVMStyle.PointerBindsToType = false;
LLVMStyle.SpacesBeforeTrailingComments = 1;
LLVMStyle.Standard = FormatStyle::LS_Cpp03;
- LLVMStyle.UseTab = false;
+ LLVMStyle.UseTab = FormatStyle::UT_Never;
LLVMStyle.SpacesInParentheses = false;
LLVMStyle.SpaceInEmptyParentheses = false;
LLVMStyle.SpacesInCStyleCastParentheses = false;
@@ -237,7 +250,7 @@ FormatStyle getGoogleStyle() {
GoogleStyle.PointerBindsToType = true;
GoogleStyle.SpacesBeforeTrailingComments = 2;
GoogleStyle.Standard = FormatStyle::LS_Auto;
- GoogleStyle.UseTab = false;
+ GoogleStyle.UseTab = FormatStyle::UT_Never;
GoogleStyle.SpacesInParentheses = false;
GoogleStyle.SpaceInEmptyParentheses = false;
GoogleStyle.SpacesInCStyleCastParentheses = false;
@@ -539,7 +552,7 @@ private:
Style.MaxEmptyLinesToKeep + 1);
Newlines = std::max(1u, Newlines);
Whitespaces->replaceWhitespace(
- *(*I)->First, Newlines, /*Spaces=*/Indent,
+ *(*I)->First, Newlines, (*I)->Level, /*Spaces=*/Indent,
/*StartOfTokenColumn=*/Indent, Line.InPPDirective);
}
UnwrappedLineFormatter Formatter(Indenter, Whitespaces, Style, **I);
@@ -556,10 +569,10 @@ private:
return false;
if (!DryRun) {
- Whitespaces->replaceWhitespace(*LBrace.Children[0]->First,
- /*Newlines=*/0, /*Spaces=*/1,
- /*StartOfTokenColumn=*/State.Column,
- State.Line->InPPDirective);
+ Whitespaces->replaceWhitespace(
+ *LBrace.Children[0]->First,
+ /*Newlines=*/0, /*IndentLevel=*/1, /*Spaces=*/1,
+ /*StartOfTokenColumn=*/State.Column, State.Line->InPPDirective);
UnwrappedLineFormatter Formatter(Indenter, Whitespaces, Style,
*LBrace.Children[0]);
Penalty += Formatter.format(State.Column + 1, DryRun);
@@ -847,8 +860,9 @@ public:
if (TheLine.First->is(tok::eof)) {
if (PreviousLineWasTouched) {
unsigned NewLines = std::min(FirstTok->NewlinesBefore, 1u);
- Whitespaces.replaceWhitespace(*TheLine.First, NewLines, /*Indent*/ 0,
- /*TargetColumn*/ 0);
+ Whitespaces.replaceWhitespace(*TheLine.First, NewLines,
+ /*IndentLevel=*/0, /*Spaces=*/0,
+ /*TargetColumn=*/0);
}
} else if (TheLine.Type != LT_Invalid &&
(WasMoved || FormatPPDirective || touchesLine(TheLine))) {
@@ -1225,7 +1239,7 @@ private:
++Newlines;
Whitespaces.replaceWhitespace(
- RootToken, Newlines, Indent, Indent,
+ RootToken, Newlines, Indent / Style.IndentWidth, Indent, Indent,
InPPDirective && !RootToken.HasUnescapedNewline);
}
Modified: cfe/trunk/lib/Format/WhitespaceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/WhitespaceManager.cpp?rev=191527&r1=191526&r2=191527&view=diff
==============================================================================
--- cfe/trunk/lib/Format/WhitespaceManager.cpp (original)
+++ cfe/trunk/lib/Format/WhitespaceManager.cpp Fri Sep 27 11:14:22 2013
@@ -28,41 +28,44 @@ WhitespaceManager::Change::IsBeforeInFil
WhitespaceManager::Change::Change(
bool CreateReplacement, const SourceRange &OriginalWhitespaceRange,
- unsigned Spaces, unsigned StartOfTokenColumn, unsigned NewlinesBefore,
- StringRef PreviousLinePostfix, StringRef CurrentLinePrefix,
- tok::TokenKind Kind, bool ContinuesPPDirective)
+ unsigned IndentLevel, unsigned Spaces, unsigned StartOfTokenColumn,
+ unsigned NewlinesBefore, StringRef PreviousLinePostfix,
+ StringRef CurrentLinePrefix, tok::TokenKind Kind, bool ContinuesPPDirective)
: CreateReplacement(CreateReplacement),
OriginalWhitespaceRange(OriginalWhitespaceRange),
StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore),
PreviousLinePostfix(PreviousLinePostfix),
CurrentLinePrefix(CurrentLinePrefix), Kind(Kind),
- ContinuesPPDirective(ContinuesPPDirective), Spaces(Spaces) {}
+ ContinuesPPDirective(ContinuesPPDirective), IndentLevel(IndentLevel),
+ Spaces(Spaces) {}
void WhitespaceManager::replaceWhitespace(const FormatToken &Tok,
- unsigned Newlines, unsigned Spaces,
+ unsigned Newlines,
+ unsigned IndentLevel, unsigned Spaces,
unsigned StartOfTokenColumn,
bool InPPDirective) {
- Changes.push_back(Change(true, Tok.WhitespaceRange, Spaces,
+ Changes.push_back(Change(true, Tok.WhitespaceRange, IndentLevel, Spaces,
StartOfTokenColumn, Newlines, "", "",
Tok.Tok.getKind(), InPPDirective && !Tok.IsFirst));
}
void WhitespaceManager::addUntouchableToken(const FormatToken &Tok,
bool InPPDirective) {
- Changes.push_back(Change(false, Tok.WhitespaceRange, /*Spaces=*/0,
- Tok.OriginalColumn, Tok.NewlinesBefore, "", "",
- Tok.Tok.getKind(), InPPDirective && !Tok.IsFirst));
+ Changes.push_back(Change(false, Tok.WhitespaceRange, /*IndentLevel=*/0,
+ /*Spaces=*/0, Tok.OriginalColumn, Tok.NewlinesBefore,
+ "", "", Tok.Tok.getKind(),
+ InPPDirective && !Tok.IsFirst));
}
void WhitespaceManager::replaceWhitespaceInToken(
const FormatToken &Tok, unsigned Offset, unsigned ReplaceChars,
StringRef PreviousPostfix, StringRef CurrentPrefix, bool InPPDirective,
- unsigned Newlines, unsigned Spaces) {
+ unsigned Newlines, unsigned IndentLevel, unsigned Spaces) {
Changes.push_back(Change(
true, SourceRange(Tok.getStartOfNonWhitespace().getLocWithOffset(Offset),
Tok.getStartOfNonWhitespace().getLocWithOffset(
Offset + ReplaceChars)),
- Spaces, Spaces, Newlines, PreviousPostfix, CurrentPrefix,
+ IndentLevel, Spaces, Spaces, Newlines, PreviousPostfix, CurrentPrefix,
// If we don't add a newline this change doesn't start a comment. Thus,
// when we align line comments, we don't need to treat this change as one.
// FIXME: We still need to take this change in account to properly
@@ -225,7 +228,8 @@ void WhitespaceManager::generateChanges(
C.PreviousEndOfTokenColumn, C.EscapedNewlineColumn);
else
appendNewlineText(ReplacementText, C.NewlinesBefore);
- appendIndentText(ReplacementText, C.Spaces, C.StartOfTokenColumn - C.Spaces);
+ appendIndentText(ReplacementText, C.IndentLevel, C.Spaces,
+ C.StartOfTokenColumn - C.Spaces);
ReplacementText.append(C.CurrentLinePrefix);
storeReplacement(C.OriginalWhitespaceRange, ReplacementText);
}
@@ -264,11 +268,14 @@ void WhitespaceManager::appendNewlineTex
}
}
-void WhitespaceManager::appendIndentText(std::string &Text, unsigned Spaces,
+void WhitespaceManager::appendIndentText(std::string &Text,
+ unsigned IndentLevel, unsigned Spaces,
unsigned WhitespaceStartColumn) {
- if (!Style.UseTab) {
+ switch (Style.UseTab) {
+ case FormatStyle::UT_Never:
Text.append(std::string(Spaces, ' '));
- } else {
+ break;
+ case FormatStyle::UT_Always: {
unsigned FirstTabWidth =
Style.TabWidth - WhitespaceStartColumn % Style.TabWidth;
// Indent with tabs only when there's at least one full tab.
@@ -278,6 +285,19 @@ void WhitespaceManager::appendIndentText
}
Text.append(std::string(Spaces / Style.TabWidth, '\t'));
Text.append(std::string(Spaces % Style.TabWidth, ' '));
+ break;
+ }
+ case FormatStyle::UT_ForIndentation:
+ if (WhitespaceStartColumn == 0) {
+ unsigned Indentation = IndentLevel * Style.IndentWidth;
+ if (Indentation > Spaces)
+ Indentation = Spaces;
+ unsigned Tabs = Indentation / Style.TabWidth;
+ Text.append(std::string(Tabs, '\t'));
+ Spaces -= Tabs * Style.TabWidth;
+ }
+ Text.append(std::string(Spaces, ' '));
+ break;
}
}
Modified: cfe/trunk/lib/Format/WhitespaceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/WhitespaceManager.h?rev=191527&r1=191526&r2=191527&view=diff
==============================================================================
--- cfe/trunk/lib/Format/WhitespaceManager.h (original)
+++ cfe/trunk/lib/Format/WhitespaceManager.h Fri Sep 27 11:14:22 2013
@@ -44,7 +44,8 @@ public:
/// \brief Replaces the whitespace in front of \p Tok. Only call once for
/// each \c AnnotatedToken.
void replaceWhitespace(const FormatToken &Tok, unsigned Newlines,
- unsigned Spaces, unsigned StartOfTokenColumn,
+ unsigned IndentLevel, unsigned Spaces,
+ unsigned StartOfTokenColumn,
bool InPPDirective = false);
/// \brief Adds information about an unchangable token's whitespace.
@@ -65,7 +66,8 @@ public:
unsigned ReplaceChars,
StringRef PreviousPostfix,
StringRef CurrentPrefix, bool InPPDirective,
- unsigned Newlines, unsigned Spaces);
+ unsigned Newlines, unsigned IndentLevel,
+ unsigned Spaces);
/// \brief Returns all the \c Replacements created during formatting.
const tooling::Replacements &generateReplacements();
@@ -96,7 +98,7 @@ private:
/// \p StartOfTokenColumn and \p InPPDirective will be used to lay out
/// trailing comments and escaped newlines.
Change(bool CreateReplacement, const SourceRange &OriginalWhitespaceRange,
- unsigned Spaces, unsigned StartOfTokenColumn,
+ unsigned IndentLevel, unsigned Spaces, unsigned StartOfTokenColumn,
unsigned NewlinesBefore, StringRef PreviousLinePostfix,
StringRef CurrentLinePrefix, tok::TokenKind Kind,
bool ContinuesPPDirective);
@@ -116,6 +118,11 @@ private:
tok::TokenKind Kind;
bool ContinuesPPDirective;
+ // The number of nested blocks the token is in. This is used to add tabs
+ // only for the indentation, and not for alignment, when
+ // UseTab = US_ForIndentation.
+ unsigned IndentLevel;
+
// The number of spaces in front of the token or broken part of the token.
// This will be adapted when aligning tokens.
unsigned Spaces;
@@ -157,8 +164,8 @@ private:
void appendNewlineText(std::string &Text, unsigned Newlines,
unsigned PreviousEndOfTokenColumn,
unsigned EscapedNewlineColumn);
- void appendIndentText(std::string &Text, unsigned Spaces,
- unsigned WhitespaceStartColumn);
+ void appendIndentText(std::string &Text, unsigned IndentLevel,
+ unsigned Spaces, unsigned WhitespaceStartColumn);
SmallVector<Change, 16> Changes;
SourceManager &SourceMgr;
Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=191527&r1=191526&r2=191527&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Fri Sep 27 11:14:22 2013
@@ -5758,7 +5758,7 @@ TEST_F(FormatTest, ConfigurableFunctionD
TEST_F(FormatTest, ConfigurableUseOfTab) {
FormatStyle Tab = getLLVMStyleWithColumns(42);
Tab.IndentWidth = 8;
- Tab.UseTab = true;
+ Tab.UseTab = FormatStyle::UT_Always;
Tab.AlignEscapedNewlinesLeft = true;
EXPECT_EQ("if (aaaaaaaa && // q\n"
@@ -5858,7 +5858,83 @@ TEST_F(FormatTest, ConfigurableUseOfTab)
" \t */",
Tab));
- Tab.UseTab = false;
+ Tab.UseTab = FormatStyle::UT_ForIndentation;
+ EXPECT_EQ("if (aaaaaaaa && // q\n"
+ " bb) // w\n"
+ "\t;",
+ format("if (aaaaaaaa &&// q\n"
+ "bb)// w\n"
+ ";",
+ Tab));
+ verifyFormat("class X {\n"
+ "\tvoid f() {\n"
+ "\t\tsomeFunction(parameter1,\n"
+ "\t\t parameter2);\n"
+ "\t}\n"
+ "};",
+ Tab);
+ verifyFormat("{\n"
+ "\tQ({\n"
+ "\t\t int a;\n"
+ "\t\t someFunction(aaaaaaaaaa,\n"
+ "\t\t bbbbbbbbb);\n"
+ "\t },\n"
+ "\t p);\n"
+ "}",
+ Tab);
+ EXPECT_EQ("{\n"
+ "\t/* aaaa\n"
+ "\t bbbb */\n"
+ "}",
+ format("{\n"
+ "/* aaaa\n"
+ " bbbb */\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ "\t bbbbbbbbbbbbb\n"
+ "\t*/\n"
+ "}",
+ format("{\n"
+ "/*\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
+ "*/\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ "\t// bbbbbbbbbbbbb\n"
+ "}",
+ format("{\n"
+ "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ "\t aaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ "\t bbbbbbbbbbbbb\n"
+ "\t*/\n"
+ "}",
+ format("{\n"
+ "\t/*\n"
+ "\t aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n"
+ "\t*/\n"
+ "}",
+ Tab));
+ EXPECT_EQ("{\n"
+ "\t/*\n"
+ "\n"
+ "\t*/\n"
+ "}",
+ format("{\n"
+ "\t/*\n"
+ "\n"
+ "\t*/\n"
+ "}", Tab));
+
+ Tab.UseTab = FormatStyle::UT_Never;
EXPECT_EQ("/*\n"
" a\t\tcomment\n"
" in multiple lines\n"
@@ -6265,7 +6341,6 @@ TEST_F(FormatTest, ParsesConfiguration)
CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
CHECK_PARSE_BOOL(PointerBindsToType);
CHECK_PARSE_BOOL(Cpp11BracedListStyle);
- CHECK_PARSE_BOOL(UseTab);
CHECK_PARSE_BOOL(IndentFunctionDeclarationAfterType);
CHECK_PARSE_BOOL(SpacesInParentheses);
CHECK_PARSE_BOOL(SpaceInEmptyParentheses);
@@ -6292,6 +6367,13 @@ TEST_F(FormatTest, ParsesConfiguration)
CHECK_PARSE("Standard: C++11", Standard, FormatStyle::LS_Cpp11);
CHECK_PARSE("Standard: Auto", Standard, FormatStyle::LS_Auto);
+ Style.UseTab = FormatStyle::UT_ForIndentation;
+ CHECK_PARSE("UseTab: false", UseTab, FormatStyle::UT_Never);
+ CHECK_PARSE("UseTab: true", UseTab, FormatStyle::UT_Always);
+ CHECK_PARSE("UseTab: Never", UseTab, FormatStyle::UT_Never);
+ CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation);
+ CHECK_PARSE("UseTab: Always", UseTab, FormatStyle::UT_Always);
+
Style.ColumnLimit = 123;
FormatStyle BaseStyle = getLLVMStyle();
CHECK_PARSE("BasedOnStyle: LLVM", ColumnLimit, BaseStyle.ColumnLimit);
More information about the cfe-commits
mailing list