<div dir="ltr"><div>Looks good. Do you have commit access?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Sep 10, 2015 at 11:45 PM, Christian Neukirchen via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
clang-format is currently lacking an option to specify how to indent<br>
goto labels, they are always outdented one level.<br>
<br>
Linux kernel style, OpenBSD style, and many other C projects have the<br>
labels completely flush left, in column 0.  The patch below adds<br>
this as "IndentGotoLabels: false".  (This indentation style is also<br>
provided by GNU indent and astyle.)<br>
<br>
(A less popular, but still common style, is to indent labels always one<br>
space, I don't know how to add that easily.)<br>
<br>
Thanks,<br>
<br>
<br>
diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst<br>
index ce6fae1..fb65f4a 100644<br>
--- a/docs/ClangFormatStyleOptions.rst<br>
+++ b/docs/ClangFormatStyleOptions.rst<br>
@@ -343,6 +343,11 @@ the configuration (without a prefix: ``Auto``).<br>
   When ``false``, use the same indentation level as for the switch statement.<br>
   Switch statement body is always indented one level more than case labels.<br>
<br>
+**IndentGotoLabels** (``bool``)<br>
+  Indent goto labels.<br>
+<br>
+  When ``false``, goto labels are flushed left.<br>
+<br>
 **IndentWidth** (``unsigned``)<br>
   The number of columns to use for indentation.<br>
<br>
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h<br>
index 60c54ab..1f43ee8 100644<br>
--- a/include/clang/Format/Format.h<br>
+++ b/include/clang/Format/Format.h<br>
@@ -129,6 +129,11 @@ struct FormatStyle {<br>
   /// Switch statement body is always indented one level more than case labels.<br>
   bool IndentCaseLabels;<br>
<br>
+  /// \brief Indent goto labels.<br>
+  ///<br>
+  /// When \c false, goto labels are flushed left.<br>
+  bool IndentGotoLabels;<br>
+<br>
   /// \brief Indent if a function definition or declaration is wrapped after the<br>
   /// type.<br>
   bool IndentWrappedFunctionNames;<br>
@@ -444,6 +449,7 @@ struct FormatStyle {<br>
            ExperimentalAutoDetectBinPacking ==<br>
                R.ExperimentalAutoDetectBinPacking &&<br>
            IndentCaseLabels == R.IndentCaseLabels &&<br>
+           IndentGotoLabels == R.IndentGotoLabels &&<br>
            IndentWrappedFunctionNames == R.IndentWrappedFunctionNames &&<br>
            IndentWidth == R.IndentWidth && Language == R.Language &&<br>
            MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&<br>
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp<br>
index 2a4721f..323c04d 100644<br>
--- a/lib/Format/Format.cpp<br>
+++ b/lib/Format/Format.cpp<br>
@@ -211,6 +211,7 @@ template <> struct MappingTraits<FormatStyle> {<br>
     IO.mapOptional("ExperimentalAutoDetectBinPacking",<br>
                    Style.ExperimentalAutoDetectBinPacking);<br>
     IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);<br>
+    IO.mapOptional("IndentGotoLabels", Style.IndentGotoLabels);<br>
     IO.mapOptional("IndentWrappedFunctionNames",<br>
                    Style.IndentWrappedFunctionNames);<br>
     IO.mapOptional("IndentFunctionDeclarationAfterType",<br>
@@ -358,6 +359,7 @@ FormatStyle getLLVMStyle() {<br>
   LLVMStyle.ForEachMacros.push_back("Q_FOREACH");<br>
   LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");<br>
   LLVMStyle.IndentCaseLabels = false;<br>
+  LLVMStyle.IndentGotoLabels = true;<br>
   LLVMStyle.IndentWrappedFunctionNames = false;<br>
   LLVMStyle.IndentWidth = 2;<br>
   LLVMStyle.TabWidth = 8;<br>
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp<br>
index ec04af5..b615bb6 100644<br>
--- a/lib/Format/UnwrappedLineParser.cpp<br>
+++ b/lib/Format/UnwrappedLineParser.cpp<br>
@@ -817,7 +817,7 @@ void UnwrappedLineParser::parseStructuralElement() {<br>
       nextToken();<br>
       if (Line->Tokens.size() == 1) {<br>
         if (FormatTok->Tok.is(tok::colon)) {<br>
-          parseLabel();<br>
+          parseLabel(true);<br>
           return;<br>
         }<br>
         // Recognize function-like macro usages without trailing semicolon as<br>
@@ -1286,11 +1286,13 @@ void UnwrappedLineParser::parseDoWhile() {<br>
   parseStructuralElement();<br>
 }<br>
<br>
-void UnwrappedLineParser::parseLabel() {<br>
+void UnwrappedLineParser::parseLabel(bool GotoLabel) {<br>
   nextToken();<br>
   unsigned OldLineLevel = Line->Level;<br>
   if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))<br>
     --Line->Level;<br>
+  if (GotoLabel && !Style.IndentGotoLabels)<br>
+    Line->Level = 0;<br>
   if (CommentsBeforeNextToken.empty() && FormatTok->Tok.is(tok::l_brace)) {<br>
     CompoundStatementIndenter Indenter(this, Style, Line->Level);<br>
     parseBlock(/*MustBeDeclaration=*/false);<br>
diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h<br>
index 3218afe..99e3bee 100644<br>
--- a/lib/Format/UnwrappedLineParser.h<br>
+++ b/lib/Format/UnwrappedLineParser.h<br>
@@ -91,7 +91,7 @@ private:<br>
   void parseTryCatch();<br>
   void parseForOrWhileLoop();<br>
   void parseDoWhile();<br>
-  void parseLabel();<br>
+  void parseLabel(bool GotoLabel = false);<br>
   void parseCaseLabel();<br>
   void parseSwitch();<br>
   void parseNamespace();<br>
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp<br>
index 8e770c2..f468170 100644<br>
--- a/unittests/Format/FormatTest.cpp<br>
+++ b/unittests/Format/FormatTest.cpp<br>
@@ -802,6 +802,20 @@ TEST_F(FormatTest, FormatsLabels) {<br>
   verifyFormat("some_code();\n"<br>
                "test_label:\n"<br>
                "some_other_code();");<br>
+  Style.IndentGotoLabel = false;<br>
+  verifyFormat("void f() {\n"<br>
+               "  some_code();\n"<br>
+               "test_label:\n"<br>
+               "  some_other_code();\n"<br>
+               "  {\n"<br>
+               "    some_more_code();\n"<br>
+               "another_label:\n"<br>
+               "    some_more_code();\n"<br>
+               "  }\n"<br>
+               "}");<br>
+  verifyFormat("some_code();\n"<br>
+               "test_label:\n"<br>
+               "some_other_code();");<br>
 }<br>
<br>
 //===----------------------------------------------------------------------===//<br>
@@ -8700,6 +8714,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) {<br>
   CHECK_PARSE_BOOL(DerivePointerAlignment);<br>
   CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding");<br>
   CHECK_PARSE_BOOL(IndentCaseLabels);<br>
+  CHECK_PARSE_BOOL(IndentGotoLabels);<br>
   CHECK_PARSE_BOOL(IndentWrappedFunctionNames);<br>
   CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);<br>
   CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
--<br>
Christian Neukirchen  <<a href="mailto:chneukirchen@gmail.com">chneukirchen@gmail.com</a>>  <a href="http://chneukirchen.org" rel="noreferrer" target="_blank">http://chneukirchen.org</a><br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</font></span></blockquote></div><br></div>