[cfe-commits] r169384 - in /cfe/trunk: lib/Format/Format.cpp lib/Format/UnwrappedLineParser.cpp unittests/Format/FormatTest.cpp
Daniel Jasper
djasper at google.com
Wed Dec 5 06:57:28 PST 2012
Author: djasper
Date: Wed Dec 5 08:57:28 2012
New Revision: 169384
URL: http://llvm.org/viewvc/llvm-project?rev=169384&view=rev
Log:
Indentation fixes for clang-format.
- Fix behavior of memoization together with optimization
- Correctly attribute the PenaltyIndentLevel (breaking directly after "(" did
not count towards the inner level)
- Recognize more tokens as assignments
Review: http://llvm-reviews.chandlerc.com/D172
Modified:
cfe/trunk/lib/Format/Format.cpp
cfe/trunk/lib/Format/UnwrappedLineParser.cpp
cfe/trunk/unittests/Format/FormatTest.cpp
Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=169384&r1=169383&r2=169384&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Wed Dec 5 08:57:28 2012
@@ -28,10 +28,18 @@
// FIXME: Move somewhere sane.
struct TokenAnnotation {
- enum TokenType { TT_Unknown, TT_TemplateOpener, TT_TemplateCloser,
- TT_BinaryOperator, TT_UnaryOperator, TT_OverloadedOperator,
- TT_PointerOrReference, TT_ConditionalExpr, TT_LineComment,
- TT_BlockComment };
+ enum TokenType {
+ TT_Unknown,
+ TT_TemplateOpener,
+ TT_TemplateCloser,
+ TT_BinaryOperator,
+ TT_UnaryOperator,
+ TT_OverloadedOperator,
+ TT_PointerOrReference,
+ TT_ConditionalExpr,
+ TT_LineComment,
+ TT_BlockComment
+ };
TokenType Type;
@@ -85,7 +93,6 @@
void format() {
unsigned Indent = formatFirstToken();
- count = 0;
IndentState State;
State.Column = Indent + Line.Tokens[0].Tok.getLength();
State.CtorInitializerOnNewLine = false;
@@ -230,9 +237,6 @@
++State.ConsumedTokens;
}
- typedef std::map<IndentState, unsigned> StateMap;
- StateMap Memory;
-
unsigned splitPenalty(const FormatToken &Token) {
if (Token.Tok.is(tok::semi))
return 0;
@@ -272,36 +276,41 @@
if (NewLine && State.InCtorInitializer && !State.CtorInitializerOnNewLine)
return UINT_MAX;
- addTokenToState(NewLine, true, State);
-
- // Exceeding column limit is bad.
- if (State.Column > Style.ColumnLimit)
- return UINT_MAX;
-
unsigned CurrentPenalty = 0;
if (NewLine) {
CurrentPenalty += Parameters.PenaltyIndentLevel * State.Indent.size() +
Parameters.PenaltyExtraLine +
- splitPenalty(Line.Tokens[State.ConsumedTokens - 2]);
+ splitPenalty(Line.Tokens[State.ConsumedTokens - 1]);
}
+ addTokenToState(NewLine, true, State);
+
+ // Exceeding column limit is bad.
+ if (State.Column > Style.ColumnLimit)
+ return UINT_MAX;
+
if (StopAt <= CurrentPenalty)
return UINT_MAX;
StopAt -= CurrentPenalty;
- // Has this state already been examined?
StateMap::iterator I = Memory.find(State);
- if (I != Memory.end())
- return I->second;
- ++count;
+ if (I != Memory.end()) {
+ // If this state has already been examined, we can safely return the
+ // previous result if we
+ // - have not hit the optimatization (and thus returned UINT_MAX) OR
+ // - are now computing for a smaller or equal StopAt.
+ unsigned SavedResult = I->second.first;
+ unsigned SavedStopAt = I->second.second;
+ if (SavedResult != UINT_MAX || StopAt <= SavedStopAt)
+ return SavedResult;
+ }
unsigned NoBreak = calcPenalty(State, false, StopAt);
unsigned WithBreak = calcPenalty(State, true, std::min(StopAt, NoBreak));
unsigned Result = std::min(NoBreak, WithBreak);
if (Result != UINT_MAX)
Result += CurrentPenalty;
- Memory[State] = Result;
- assert(Memory.find(State) != Memory.end());
+ Memory[State] = std::pair<unsigned, unsigned>(Result, StopAt);
return Result;
}
@@ -340,9 +349,12 @@
const UnwrappedLine &Line;
const std::vector<TokenAnnotation> &Annotations;
tooling::Replacements &Replaces;
- unsigned int count;
bool StructuralError;
+ // A map from an indent state to a pair (Result, Used-StopAt).
+ typedef std::map<IndentState, std::pair<unsigned, unsigned> > StateMap;
+ StateMap Memory;
+
OptimizationParameters Parameters;
};
@@ -548,16 +560,18 @@
private:
void determineTokenTypes() {
- bool EqualEncountered = false;
+ bool AssignmentEncountered = false;
for (int i = 0, e = Line.Tokens.size(); i != e; ++i) {
TokenAnnotation &Annotation = Annotations[i];
const FormatToken &Tok = Line.Tokens[i];
- if (Tok.Tok.is(tok::equal))
- EqualEncountered = true;
+ if (Tok.Tok.is(tok::equal) || Tok.Tok.is(tok::plusequal) ||
+ Tok.Tok.is(tok::minusequal) || Tok.Tok.is(tok::starequal) ||
+ Tok.Tok.is(tok::slashequal))
+ AssignmentEncountered = true;
if (Tok.Tok.is(tok::star) || Tok.Tok.is(tok::amp))
- Annotation.Type = determineStarAmpUsage(i, EqualEncountered);
+ Annotation.Type = determineStarAmpUsage(i, AssignmentEncountered);
else if (isUnaryOperator(i))
Annotation.Type = TokenAnnotation::TT_UnaryOperator;
else if (isBinaryOperator(Line.Tokens[i]))
@@ -605,7 +619,7 @@
}
TokenAnnotation::TokenType determineStarAmpUsage(unsigned Index,
- bool EqualEncountered) {
+ bool AssignmentEncountered) {
if (Index == Annotations.size())
return TokenAnnotation::TT_Unknown;
@@ -620,7 +634,7 @@
// It is very unlikely that we are going to find a pointer or reference type
// definition on the RHS of an assignment.
- if (EqualEncountered)
+ if (AssignmentEncountered)
return TokenAnnotation::TT_BinaryOperator;
return TokenAnnotation::TT_PointerOrReference;
@@ -676,8 +690,9 @@
return false;
if (isBinaryOperator(Left))
return true;
- return Right.Tok.is(tok::colon) || Left.Tok.is(tok::comma) || Left.Tok.is(
- tok::semi) || Left.Tok.is(tok::equal) || Left.Tok.is(tok::ampamp) ||
+ return Right.Tok.is(tok::colon) || Left.Tok.is(tok::comma) ||
+ Left.Tok.is(tok::semi) || Left.Tok.is(tok::equal) ||
+ Left.Tok.is(tok::ampamp) || Left.Tok.is(tok::pipepipe) ||
(Left.Tok.is(tok::l_paren) && !Right.Tok.is(tok::r_paren));
}
Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=169384&r1=169383&r2=169384&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Wed Dec 5 08:57:28 2012
@@ -106,6 +106,12 @@
}
void UnwrappedLineParser::parseStatement() {
+ // Consume leading line comments, e.g. for branches without compounds.
+ while (FormatTok.Tok.is(tok::comment)) {
+ nextToken();
+ addUnwrappedLine();
+ }
+
switch (FormatTok.Tok.getKind()) {
case tok::kw_public:
case tok::kw_protected:
Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=169384&r1=169383&r2=169384&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Wed Dec 5 08:57:28 2012
@@ -110,6 +110,7 @@
verifyFormat("if (true)\n f();\ng();");
verifyFormat("if (a)\n if (b)\n if (c)\n g();\nh();");
verifyFormat("if (a)\n if (b) {\n f();\n }\ng();");
+ EXPECT_EQ("if (a)\n // comment\n f();", format("if(a)\n// comment\nf();"));
}
TEST_F(FormatTest, ParseIfThenElse) {
@@ -277,6 +278,17 @@
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)),\n"
" aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)));");
+
+ verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
+ " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
+
+ // This test case breaks on an incorrect memoization, i.e. an optimization not
+ // taking into account the StopAt value.
+ verifyFormat(
+ "return aaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaa ||\n"
+ " aaaaaaaaaaa(aaaaaaaaa) || aaaaaaaaaaaaaaaaaaaaaaa ||\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaa ||\n"
+ " (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
}
TEST_F(FormatTest, AlignsStringLiterals) {
@@ -350,6 +362,10 @@
verifyFormat("int a = b * 10;");
verifyFormat("int a = 10 * b;");
verifyFormat("int a = b * c;");
+ verifyFormat("int a += b * c;");
+ verifyFormat("int a -= b * c;");
+ verifyFormat("int a *= b * c;");
+ verifyFormat("int a /= b * c;");
verifyFormat("int a = *b;");
verifyFormat("int a = *b * c;");
verifyFormat("int a = b * *c;");
More information about the cfe-commits
mailing list