[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