enyquist updated this revision to Diff 84478.
enyquist added a comment.

Forgot to set "AlignConsecutiveMacros = false" in getLLVMStyle()


Repository:
  rL LLVM

https://reviews.llvm.org/D28462

Files:
  ClangFormatStyleOptions.rst
  Format/Format.cpp
  Format/FormatTest.cpp
  Format/FormatToken.h
  Format/TokenAnnotator.cpp
  Format/WhitespaceManager.cpp
  Format/WhitespaceManager.h
  clang/Format/Format.h

Index: Format/FormatTest.cpp
===================================================================
--- Format/FormatTest.cpp
+++ Format/FormatTest.cpp
@@ -8532,8 +8532,78 @@
   verifyFormat("a or_eq 8;", Spaces);
 }
 
+TEST_F(FormatTest, AlignConsecutiveMacros) {
+  FormatStyle Alignment = getLLVMStyle();
+  Alignment.AlignConsecutiveAssignments = true;
+  Alignment.AlignConsecutiveDeclarations = true;
+  Alignment.AlignConsecutiveMacros = false;
+
+  verifyFormat("#define a 3\n"
+               "#define bbbb 4\n"
+               "#define ccc (5)",
+               Alignment);
+
+  verifyFormat("#define f(x) (x * x)\n"
+               "#define fff(x, y, z) (x * y + z)\n"
+               "#define ffff(x, y) (x - y)",
+               Alignment);
+
+  verifyFormat("#define foo(x, y) (x + y)\n"
+               "#define bar (5, 6)(2 + 2)",
+               Alignment);
+
+  verifyFormat("#define a 3\n"
+               "#define bbbb 4\n"
+               "#define ccc (5)\n"
+               "#define f(x) (x * x)\n"
+               "#define fff(x, y, z) (x * y + z)\n"
+               "#define ffff(x, y) (x - y)",
+               Alignment);
+
+  Alignment.AlignConsecutiveMacros = true;
+  verifyFormat("#define a    3\n"
+               "#define bbbb 4\n"
+               "#define ccc  (5)",
+               Alignment);
+
+  verifyFormat("#define f(x)         (x * x)\n"
+               "#define fff(x, y, z) (x * y + z)\n"
+               "#define ffff(x, y)   (x - y)",
+               Alignment);
+
+  verifyFormat("#define foo(x, y) (x + y)\n"
+               "#define bar       (5, 6)(2 + 2)",
+               Alignment);
+
+  verifyFormat("#define a            3\n"
+               "#define bbbb         4\n"
+               "#define ccc          (5)\n"
+               "#define f(x)         (x * x)\n"
+               "#define fff(x, y, z) (x * y + z)\n"
+               "#define ffff(x, y)   (x - y)",
+               Alignment);
+
+  verifyFormat("#define a         5\n"
+               "#define foo(x, y) (x + y)\n"
+               "#define CCC       (6)\n"
+               "auto lambda = []() {\n"
+               "  auto  ii = 0;\n"
+               "  float j  = 0;\n"
+               "  return 0;\n"
+               "};\n"
+               "int   i  = 0;\n"
+               "float i2 = 0;\n"
+               "auto  v  = type{\n"
+               "    i = 1,   //\n"
+               "    (i = 2), //\n"
+               "    i = 3    //\n"
+               "};",
+               Alignment);
+}
+
 TEST_F(FormatTest, AlignConsecutiveAssignments) {
   FormatStyle Alignment = getLLVMStyle();
+  Alignment.AlignConsecutiveMacros = true;
   Alignment.AlignConsecutiveAssignments = false;
   verifyFormat("int a = 5;\n"
                "int oneTwoThree = 123;",
@@ -8674,7 +8744,10 @@
                "int j = 2;",
                Alignment);
 
-  verifyFormat("auto lambda = []() {\n"
+  verifyFormat("#define a         5\n"
+               "#define foo(x, y) (x + y)\n"
+               "#define CCC       (6)\n"
+               "auto lambda = []() {\n"
                "  auto i = 0;\n"
                "  return 0;\n"
                "};\n"
@@ -8710,6 +8783,7 @@
 
 TEST_F(FormatTest, AlignConsecutiveDeclarations) {
   FormatStyle Alignment = getLLVMStyle();
+  Alignment.AlignConsecutiveMacros = true;
   Alignment.AlignConsecutiveDeclarations = false;
   verifyFormat("float const a = 5;\n"
                "int oneTwoThree = 123;",
@@ -8869,7 +8943,10 @@
                Alignment);
 
   Alignment.AlignConsecutiveAssignments = true;
-  verifyFormat("auto lambda = []() {\n"
+  verifyFormat("#define a         5\n"
+               "#define foo(x, y) (x + y)\n"
+               "#define CCC       (6)\n"
+               "auto lambda = []() {\n"
                "  auto  ii = 0;\n"
                "  float j  = 0;\n"
                "  return 0;\n"
@@ -9594,6 +9671,7 @@
   CHECK_PARSE_BOOL(AlignEscapedNewlinesLeft);
   CHECK_PARSE_BOOL(AlignOperands);
   CHECK_PARSE_BOOL(AlignTrailingComments);
+  CHECK_PARSE_BOOL(AlignConsecutiveMacros);
   CHECK_PARSE_BOOL(AlignConsecutiveAssignments);
   CHECK_PARSE_BOOL(AlignConsecutiveDeclarations);
   CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
Index: Format/WhitespaceManager.h
===================================================================
--- Format/WhitespaceManager.h
+++ Format/WhitespaceManager.h
@@ -107,7 +107,7 @@
            unsigned NewlinesBefore, StringRef PreviousLinePostfix,
            StringRef CurrentLinePrefix, tok::TokenKind Kind,
            bool ContinuesPPDirective, bool IsStartOfDeclName,
-           bool IsInsideToken);
+           bool IsInsideToken, bool EndsPPIdentifier);
 
     bool CreateReplacement;
     // Changes might be in the middle of a token, so we cannot just keep the
@@ -141,6 +141,9 @@
     // directly after a newline.
     bool IsInsideToken;
 
+    // If this change is at the final token of a PP macro identifier
+    bool EndsPPIdentifier;
+
     // \c IsTrailingComment, \c TokenLength, \c PreviousEndOfTokenColumn and
     // \c EscapedNewlineColumn will be calculated in
     // \c calculateLineBreakInformation.
@@ -167,6 +170,9 @@
   /// \c EscapedNewlineColumn for the first tokens or token parts in a line.
   void calculateLineBreakInformation();
 
+  /// \brief Align consecutive C/C++ preprocessor macros over all \c Changes.
+  void alignConsecutiveMacros();
+
   /// \brief Align consecutive assignments over all \c Changes.
   void alignConsecutiveAssignments();
 
Index: Format/WhitespaceManager.cpp
===================================================================
--- Format/WhitespaceManager.cpp
+++ Format/WhitespaceManager.cpp
@@ -30,15 +30,16 @@
     unsigned IndentLevel, int Spaces, unsigned StartOfTokenColumn,
     unsigned NewlinesBefore, StringRef PreviousLinePostfix,
     StringRef CurrentLinePrefix, tok::TokenKind Kind, bool ContinuesPPDirective,
-    bool IsStartOfDeclName, bool IsInsideToken)
+    bool IsStartOfDeclName, bool IsInsideToken, bool EndsPPIdentifier)
     : CreateReplacement(CreateReplacement),
       OriginalWhitespaceRange(OriginalWhitespaceRange),
       StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore),
       PreviousLinePostfix(PreviousLinePostfix),
       CurrentLinePrefix(CurrentLinePrefix), Kind(Kind),
       ContinuesPPDirective(ContinuesPPDirective),
       IsStartOfDeclName(IsStartOfDeclName), IndentLevel(IndentLevel),
-      Spaces(Spaces), IsInsideToken(IsInsideToken), IsTrailingComment(false),
+      Spaces(Spaces), IsInsideToken(IsInsideToken),
+      EndsPPIdentifier(EndsPPIdentifier), IsTrailingComment(false),
       TokenLength(0), PreviousEndOfTokenColumn(0), EscapedNewlineColumn(0),
       StartOfBlockComment(nullptr), IndentationOffset(0) {}
 
@@ -54,7 +55,8 @@
              Spaces, StartOfTokenColumn, Newlines, "", "", Tok.Tok.getKind(),
              InPPDirective && !Tok.IsFirst,
              Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName),
-             /*IsInsideToken=*/false));
+             /*IsInsideToken=*/false,
+             /* EndsPPIdentifier=*/Tok.EndsPPIdentifier));
 }
 
 void WhitespaceManager::addUntouchableToken(const FormatToken &Tok,
@@ -66,7 +68,8 @@
       /*Spaces=*/0, Tok.OriginalColumn, Tok.NewlinesBefore, "", "",
       Tok.Tok.getKind(), InPPDirective && !Tok.IsFirst,
       Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName),
-      /*IsInsideToken=*/false));
+      /*IsInsideToken=*/false,
+      /* EndsPPIdentifier=*/Tok.EndsPPIdentifier));
 }
 
 void WhitespaceManager::replaceWhitespaceInToken(
@@ -82,15 +85,17 @@
       CurrentPrefix, Tok.is(TT_LineComment) ? tok::comment : tok::unknown,
       InPPDirective && !Tok.IsFirst,
       Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName),
-      /*IsInsideToken=*/Newlines == 0));
+      /*IsInsideToken=*/Newlines == 0,
+      /* EndsPPIdentifier=*/Tok.EndsPPIdentifier));
 }
 
 const tooling::Replacements &WhitespaceManager::generateReplacements() {
   if (Changes.empty())
     return Replaces;
 
   std::sort(Changes.begin(), Changes.end(), Change::IsBeforeInFile(SourceMgr));
   calculateLineBreakInformation();
+  alignConsecutiveMacros();
   alignConsecutiveDeclarations();
   alignConsecutiveAssignments();
   alignTrailingComments();
@@ -192,26 +197,29 @@
 // finalize the previous sequence.
 template <typename F>
 static void AlignTokens(const FormatStyle &Style, F &&Matches,
-                        SmallVector<WhitespaceManager::Change, 16> &Changes) {
+                        SmallVector<WhitespaceManager::Change, 16> &Changes,
+                        unsigned MaxNestingLevelIncrease, bool ConsiderCommas) {
   unsigned MinColumn = 0;
   unsigned MaxColumn = UINT_MAX;
 
   // Line number of the start and the end of the current token sequence.
   unsigned StartOfSequence = 0;
   unsigned EndOfSequence = 0;
 
   // Keep track of the nesting level of matching tokens, i.e. the number of
-  // surrounding (), [], or {}. We will only align a sequence of matching
-  // token that share the same scope depth.
+  // surrounding (), [], or {}. If ConsiderNestingLevel is 0, we will
+  // only align a sequence of matching tokens that share the same scope depth.
+  // Otherwise, alignment will be allowed to continue until the nesting level
+  // increases by MaxNestingLevelIncrease.
   //
   // FIXME: This could use FormatToken::NestingLevel information, but there is
   // an outstanding issue wrt the brace scopes.
   unsigned NestingLevelOfLastMatch = 0;
   unsigned NestingLevel = 0;
 
-  // Keep track of the number of commas before the matching tokens, we will only
-  // align a sequence of matching tokens if they are preceded by the same number
-  // of commas.
+  // Keep track of the number of commas before the matching tokens. If
+  // ConsiderCommas is true, we will only align a sequence of matching tokens
+  // if they are preceded by the same number of commas.
   unsigned CommasBeforeLastMatch = 0;
   unsigned CommasBeforeMatch = 0;
 
@@ -268,8 +276,10 @@
     // If there is more than one matching token per line, or if the number of
     // preceding commas, or the scope depth, do not match anymore, end the
     // sequence.
-    if (FoundMatchOnLine || CommasBeforeMatch != CommasBeforeLastMatch ||
-        NestingLevel != NestingLevelOfLastMatch)
+    if (FoundMatchOnLine ||
+        (ConsiderCommas && CommasBeforeMatch != CommasBeforeLastMatch) ||
+        NestingLevel < NestingLevelOfLastMatch ||
+        NestingLevel > NestingLevelOfLastMatch + MaxNestingLevelIncrease)
       AlignCurrentSequence();
 
     CommasBeforeLastMatch = CommasBeforeMatch;
@@ -287,7 +297,7 @@
 
     // If we are restricted by the maximum column width, end the sequence.
     if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn ||
-        CommasBeforeLastMatch != CommasBeforeMatch) {
+        (ConsiderCommas && CommasBeforeLastMatch != CommasBeforeMatch)) {
       AlignCurrentSequence();
       StartOfSequence = i;
     }
@@ -300,6 +310,17 @@
   AlignCurrentSequence();
 }
 
+void WhitespaceManager::alignConsecutiveMacros() {
+  if (!Style.AlignConsecutiveMacros)
+    return;
+
+  AlignTokens(Style,
+              [&](Change const &C) {
+                return (&C != &Changes.front() && (&C - 1)->EndsPPIdentifier);
+              },
+              Changes, 1, false);
+}
+
 void WhitespaceManager::alignConsecutiveAssignments() {
   if (!Style.AlignConsecutiveAssignments)
     return;
@@ -316,7 +337,7 @@
 
                 return C.Kind == tok::equal;
               },
-              Changes);
+              Changes, 0, true);
 }
 
 void WhitespaceManager::alignConsecutiveDeclarations() {
@@ -331,7 +352,7 @@
   //   SomeVeryLongType const& v3;
 
   AlignTokens(Style, [](Change const &C) { return C.IsStartOfDeclName; },
-              Changes);
+              Changes, 0, true);
 }
 
 void WhitespaceManager::alignTrailingComments() {
Index: Format/TokenAnnotator.cpp
===================================================================
--- Format/TokenAnnotator.cpp
+++ Format/TokenAnnotator.cpp
@@ -1644,6 +1644,60 @@
   Line.First->CanBreakBefore = Line.First->MustBreakBefore;
 }
 
+// This function heuristically determines whether 'tok' is the
+// 'define' keyword in a PP macro
+static bool isDefineKeyword(const FormatToken &tok) {
+  if (!tok.Previous)
+    return false;
+  if (!tok.is(tok::identifier) || !tok.TokenText.equals("define"))
+    return false;
+
+  return tok.Previous->is(tok::hash);
+}
+
+// This function heuristically determines whether 'Current' is the identifier
+// following the 'define' keyword in a simple PP macro (i.e. no parameters)
+static bool endsMacroIdentifier(const FormatToken &Current) {
+  const FormatToken *keyword = Current.Previous;
+
+  if (!keyword || Current.Next)
+    return false;
+  if (!Current.is(tok::identifier))
+    return false;
+
+  return isDefineKeyword(*keyword);
+}
+
+// This function heuristically determines whether 'Current' is the closing
+// r_paren token for the parameter list of a function-like PP macro
+static bool endsMacroWithArgsIdentifier(const FormatToken &Current) {
+  const FormatToken *Keyword, *Param = Current.Previous;
+
+  if (!Param || !Current.is(tok::r_paren))
+    return false;
+
+  while (Param && !Param->is(tok::l_paren)) {
+    if (!Param->is(tok::identifier) && !Param->is(tok::comma))
+      return false;
+    if (!Param->Previous)
+      return false;
+
+    Param = Param->Previous;
+  }
+
+  if (!Param || Param->SpacesRequiredBefore)
+    return false;
+  if (!Param->Previous || !Param->Previous->is(tok::identifier))
+    return false;
+
+  Keyword = Param->Previous->Previous;
+  return Keyword && isDefineKeyword(*Keyword);
+}
+
+static bool endsPPIdentifier(const FormatToken &Current) {
+  return endsMacroIdentifier(Current) || endsMacroWithArgsIdentifier(Current);
+}
+
 // This function heuristically determines whether 'Current' starts the name of a
 // function declaration.
 static bool isFunctionDeclarationName(const FormatToken &Current,
@@ -1758,6 +1812,7 @@
   FormatToken *Current = Line.First->Next;
   bool InFunctionDecl = Line.MightBeFunctionDecl;
   while (Current) {
+    Current->EndsPPIdentifier = endsPPIdentifier(*Current);
     if (isFunctionDeclarationName(*Current, Line))
       Current->Type = TT_FunctionDeclarationName;
     if (Current->is(TT_LineComment)) {
@@ -2624,6 +2679,7 @@
   while (Tok) {
     llvm::errs() << " M=" << Tok->MustBreakBefore
                  << " C=" << Tok->CanBreakBefore
+                 << " E=" << Tok->EndsPPIdentifier
                  << " T=" << getTokenTypeName(Tok->Type)
                  << " S=" << Tok->SpacesRequiredBefore
                  << " B=" << Tok->BlockParameterCount
Index: Format/FormatToken.h
===================================================================
--- Format/FormatToken.h
+++ Format/FormatToken.h
@@ -145,6 +145,12 @@
   /// \brief Whether the token text contains newlines (escaped or not).
   bool IsMultiline = false;
 
+  /// \brief Whether the token is the final token in the identifier of a PP
+  // macro. This will be either 1) the identifier token following the 'define'
+  // keyword in a simple PP macro, or 2) the closing r_paren token in the
+  // parameter list of a function-like PP macro.
+  bool EndsPPIdentifier = false;
+
   /// \brief Indicates that this is the first token of the file.
   bool IsFirst = false;
 
Index: Format/Format.cpp
===================================================================
--- Format/Format.cpp
+++ Format/Format.cpp
@@ -242,6 +242,7 @@
 
     IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
     IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket);
+    IO.mapOptional("AlignConsecutiveMacros", Style.AlignConsecutiveMacros);
     IO.mapOptional("AlignConsecutiveAssignments",
                    Style.AlignConsecutiveAssignments);
     IO.mapOptional("AlignConsecutiveDeclarations",
@@ -493,6 +494,7 @@
   LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align;
   LLVMStyle.AlignOperands = true;
   LLVMStyle.AlignTrailingComments = true;
+  LLVMStyle.AlignConsecutiveMacros = false;
   LLVMStyle.AlignConsecutiveAssignments = false;
   LLVMStyle.AlignConsecutiveDeclarations = false;
   LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
Index: clang/Format/Format.h
===================================================================
--- clang/Format/Format.h
+++ clang/Format/Format.h
@@ -76,6 +76,19 @@
   /// brackets.
   BracketAlignmentStyle AlignAfterOpenBracket;
 
+  /// \brief If ``true``, aligns consecutive C/C++ preprocessor macros.
+  ///
+  /// This will align C/C++ preprocessor macros of consecutive lines.
+  /// Will result in formattings like
+  /// \code
+  ///   #define SHORT_NAME       42
+  ///   #define LONGER_NAME      0x007f
+  ///   #define EVEN_LONGER_NAME (2)
+  ///   #define foo(x)           (x * x)
+  ///   #define bar(y, z)        (y + z)
+  /// \endcode
+  bool AlignConsecutiveMacros;
+
   /// \brief If ``true``, aligns consecutive assignments.
   ///
   /// This will align the assignment operators of consecutive lines. This
Index: ClangFormatStyleOptions.rst
===================================================================
--- ClangFormatStyleOptions.rst
+++ ClangFormatStyleOptions.rst
@@ -185,6 +185,20 @@
 
 
 
+**AlignConsecutiveMacros** (``bool``)
+  If ``true``, aligns consecutive C/C++ preprocessor macros.
+
+  This will align the C/C++ preprocessor macros of consecutive lines. This
+  will result in formattings like
+
+  .. code-block:: c++
+
+    #define SHORT_NAME       42
+    #define LONGER_NAME      0x007f
+    #define EVEN_LONGER_NAME (2)
+    #define foo(x)           (x * x)
+    #define bar(y, z)        (y + z)
+
 **AlignConsecutiveAssignments** (``bool``)
   If ``true``, aligns consecutive assignments.
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to