<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>