zturner updated this revision to Diff 42774.
zturner added a comment.

This patch was very old, so it didn't apply against ToT.  So this initial 
update is just to rebase against ToT.  I will make changes in a followup patch.


http://reviews.llvm.org/D10370

Files:
  include/clang/Format/Format.h
  lib/Format/ContinuationIndenter.cpp
  lib/Format/Format.cpp
  lib/Format/TokenAnnotator.cpp
  lib/Format/TokenAnnotator.h
  unittests/Format/FormatTest.cpp

Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -4732,6 +4732,44 @@
                "              \"c\";");
 }
 
+TEST_F(FormatTest, DeclarationReturnTypeBreakingStyle) {
+  FormatStyle Style = getLLVMStyle();
+  Style.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_TopLevel;
+  verifyFormat("class C {\n"
+               "  int f();\n"
+               "};\n"
+               "int\n"
+               "f();",
+               Style);
+  Style.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_All;
+  verifyFormat("class C {\n"
+               "  int\n"
+               "  f();\n"
+               "};\n"
+               "int\n"
+               "f();",
+               Style);
+  verifyFormat("const char *f(void) { return \"\"; }\n"
+               "const char *\n"
+               "bar(void);\n",
+               Style);
+  verifyFormat("template <class T> T *f(T &c) { return NULL; }\n"
+               "template <class T>\n"
+               "T *\n"
+               "f(T &c);\n",
+               Style);
+  Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
+  verifyFormat("const char *f(void) { return \"\"; }\n"
+               "const char *\n"
+               "bar(void);\n",
+               Style);
+  verifyFormat("template <class T> T *f(T &c) { return NULL; }\n"
+               "template <class T>\n"
+               "T *\n"
+               "f(T &c);\n",
+               Style);
+}
+
 TEST_F(FormatTest, DefinitionReturnTypeBreakingStyle) {
   FormatStyle Style = getLLVMStyle();
   Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_TopLevel;
@@ -4812,6 +4850,46 @@
                Style);
 }
 
+TEST_F(FormatTest, AlwaysBreakAfterDeclarationAndDefinitionReturnTypeMixed) {
+  FormatStyle AfterType = getLLVMStyle();
+  AfterType.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_None;
+  AfterType.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
+  verifyFormat("void f(void) {\n" // No break here.
+               "  f();\n"
+               "  f();\n"
+               "}\n"
+               "void bar(void);\n", // No break here.
+               AfterType);
+  AfterType.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_All;
+  AfterType.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
+  verifyFormat("void f(void) {\n" // No break here.
+               "  f();\n"
+               "  f();\n"
+               "}\n"
+               "void\n"
+               "bar(void);\n", // Break here.
+               AfterType);
+  AfterType.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_None;
+  AfterType.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
+  verifyFormat("void\n"
+               "f(void) {\n" // Break here.
+               "  f();\n"
+               "  f();\n"
+               "}\n"
+               "void bar(void);\n", // No break here.
+               AfterType);
+  AfterType.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_All;
+  AfterType.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
+  verifyFormat("void\n"
+               "f(void) {\n" // Break here.
+               "  f();\n"
+               "  f();\n"
+               "}\n"
+               "void\n"
+               "bar(void);\n", // Break here.
+               AfterType);
+}
+
 TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) {
   FormatStyle NoBreak = getLLVMStyle();
   NoBreak.AlwaysBreakBeforeMultilineStrings = false;
@@ -9829,6 +9907,15 @@
   CHECK_PARSE("BreakBeforeBraces: Custom", BreakBeforeBraces,
               FormatStyle::BS_Custom);
 
+  Style.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_All;
+  CHECK_PARSE("AlwaysBreakAfterDeclarationReturnType: None",
+              AlwaysBreakAfterDeclarationReturnType, FormatStyle::DRTBS_None);
+  CHECK_PARSE("AlwaysBreakAfterDeclarationReturnType: All",
+              AlwaysBreakAfterDeclarationReturnType, FormatStyle::DRTBS_All);
+  CHECK_PARSE("AlwaysBreakAfterDeclarationReturnType: TopLevel",
+              AlwaysBreakAfterDeclarationReturnType,
+              FormatStyle::DRTBS_TopLevel);
+
   Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
   CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: None",
               AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_None);
Index: lib/Format/TokenAnnotator.h
===================================================================
--- lib/Format/TokenAnnotator.h
+++ lib/Format/TokenAnnotator.h
@@ -86,6 +86,15 @@
     return startsWith(First, Tokens...);
   }
 
+  /// \c true if this line looks like a function definition instead of a
+  /// function declaration. Asserts MightBeFunctionDecl.
+  bool mightBeFunctionDefinition() const {
+    assert(MightBeFunctionDecl);
+    // FIXME: Line.Last points to other characters than tok::semi
+    // and tok::lbrace.
+    return !Last->isOneOf(tok::semi, tok::comment);
+  }
+
   FormatToken *First;
   FormatToken *Last;
 
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -1613,15 +1613,16 @@
     Current->MustBreakBefore =
         Current->MustBreakBefore || mustBreakBefore(Line, *Current);
 
-    if ((Style.AlwaysBreakAfterDefinitionReturnType == FormatStyle::DRTBS_All ||
-         (Style.AlwaysBreakAfterDefinitionReturnType ==
-              FormatStyle::DRTBS_TopLevel &&
-          Line.Level == 0)) &&
-        InFunctionDecl && Current->is(TT_FunctionDeclarationName) &&
-        !Line.Last->isOneOf(tok::semi, tok::comment)) // Only for definitions.
-      // FIXME: Line.Last points to other characters than tok::semi
-      // and tok::lbrace.
-      Current->MustBreakBefore = true;
+    if (!Current->MustBreakBefore && InFunctionDecl &&
+        Current->is(TT_FunctionDeclarationName)) {
+      FormatStyle::ReturnTypeBreakingStyle BreakStyle =
+          Line.mightBeFunctionDefinition()
+              ? Style.AlwaysBreakAfterDefinitionReturnType
+              : Style.AlwaysBreakAfterDeclarationReturnType;
+      if ((BreakStyle == FormatStyle::DRTBS_All ||
+           (BreakStyle == FormatStyle::DRTBS_TopLevel && Line.Level == 0)))
+        Current->MustBreakBefore = true;
+    }
 
     Current->CanBreakBefore =
         Current->MustBreakBefore || canBreakBefore(Line, *Current);
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -105,9 +105,8 @@
 };
 
 template <>
-struct ScalarEnumerationTraits<FormatStyle::DefinitionReturnTypeBreakingStyle> {
-  static void
-  enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) {
+struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> {
+  static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) {
     IO.enumCase(Value, "None", FormatStyle::DRTBS_None);
     IO.enumCase(Value, "All", FormatStyle::DRTBS_All);
     IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel);
@@ -231,6 +230,8 @@
                    Style.AllowShortIfStatementsOnASingleLine);
     IO.mapOptional("AllowShortLoopsOnASingleLine",
                    Style.AllowShortLoopsOnASingleLine);
+    IO.mapOptional("AlwaysBreakAfterDeclarationReturnType",
+                   Style.AlwaysBreakAfterDeclarationReturnType);
     IO.mapOptional("AlwaysBreakAfterDefinitionReturnType",
                    Style.AlwaysBreakAfterDefinitionReturnType);
     IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
@@ -449,6 +450,7 @@
   LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
   LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
   LLVMStyle.AllowShortLoopsOnASingleLine = false;
+  LLVMStyle.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_None;
   LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
   LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
   LLVMStyle.AlwaysBreakTemplateDeclarations = false;
Index: lib/Format/ContinuationIndenter.cpp
===================================================================
--- lib/Format/ContinuationIndenter.cpp
+++ lib/Format/ContinuationIndenter.cpp
@@ -125,10 +125,14 @@
 
   // Don't break after very short return types (e.g. "void") as that is often
   // unexpected.
-  if (Current.is(TT_FunctionDeclarationName) &&
-      Style.AlwaysBreakAfterDefinitionReturnType == FormatStyle::DRTBS_None &&
-      State.Column < 6)
-    return false;
+  if (Current.is(TT_FunctionDeclarationName) && State.Column < 6) {
+    FormatStyle::ReturnTypeBreakingStyle BreakStyle =
+        State.Line->mightBeFunctionDefinition()
+            ? Style.AlwaysBreakAfterDefinitionReturnType
+            : Style.AlwaysBreakAfterDeclarationReturnType;
+    if (BreakStyle == FormatStyle::DRTBS_None)
+      return false;
+  }
 
   return !State.Stack.back().NoLineBreak;
 }
Index: include/clang/Format/Format.h
===================================================================
--- include/clang/Format/Format.h
+++ include/clang/Format/Format.h
@@ -149,8 +149,9 @@
   /// single line.
   bool AllowShortLoopsOnASingleLine;
 
-  /// \brief Different ways to break after the function definition return type.
-  enum DefinitionReturnTypeBreakingStyle {
+  /// \brief Different ways to break after the function declaration or
+  /// definition return type.
+  enum ReturnTypeBreakingStyle {
     /// Break after return type automatically.
     /// \c PenaltyReturnTypeOnItsOwnLine is taken into account.
     DRTBS_None,
@@ -160,8 +161,11 @@
     DRTBS_TopLevel,
   };
 
+  /// \brief The function declaration return type breaking style to use.
+  ReturnTypeBreakingStyle AlwaysBreakAfterDeclarationReturnType;
+
   /// \brief The function definition return type breaking style to use.
-  DefinitionReturnTypeBreakingStyle AlwaysBreakAfterDefinitionReturnType;
+  ReturnTypeBreakingStyle AlwaysBreakAfterDefinitionReturnType;
 
   /// \brief If \c true, always break before multiline string literals.
   ///
@@ -582,6 +586,8 @@
            AllowShortIfStatementsOnASingleLine ==
                R.AllowShortIfStatementsOnASingleLine &&
            AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine &&
+           AlwaysBreakAfterDeclarationReturnType ==
+               R.AlwaysBreakAfterDeclarationReturnType &&
            AlwaysBreakAfterDefinitionReturnType ==
                R.AlwaysBreakAfterDefinitionReturnType &&
            AlwaysBreakBeforeMultilineStrings ==
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to