Index: include/clang/Format/Format.h
===================================================================
--- include/clang/Format/Format.h
+++ include/clang/Format/Format.h
@@ -112,6 +112,10 @@
/// single line.
bool AllowShortLoopsOnASingleLine;
+ /// \brief If \c true, namespace a { class b; } can be put
+ /// on a single line
+ bool AllowShortNamespacesOnASingleLine;
+
/// \brief Different ways to break after the function definition return type.
enum DefinitionReturnTypeBreakingStyle {
/// Break after return type automatically.
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -212,6 +212,8 @@
Style.AllowShortIfStatementsOnASingleLine);
IO.mapOptional("AllowShortLoopsOnASingleLine",
Style.AllowShortLoopsOnASingleLine);
+ IO.mapOptional("AllowShortNamespacesOnASingleLine",
+ Style.AllowShortNamespacesOnASingleLine);
IO.mapOptional("AlwaysBreakAfterDefinitionReturnType",
Style.AlwaysBreakAfterDefinitionReturnType);
IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
@@ -354,6 +356,7 @@
LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
LLVMStyle.AllowShortLoopsOnASingleLine = false;
+ LLVMStyle.AllowShortNamespacesOnASingleLine = false;
LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
LLVMStyle.AlwaysBreakTemplateDeclarations = false;
Index: lib/Format/UnwrappedLineFormatter.cpp
===================================================================
--- lib/Format/UnwrappedLineFormatter.cpp
+++ lib/Format/UnwrappedLineFormatter.cpp
@@ -199,6 +199,12 @@
return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0;
}
if (TheLine->Last->is(tok::l_brace)) {
+ if (Style.AllowShortNamespacesOnASingleLine &&
+ TheLine->First->is(tok::kw_namespace)) {
+ if (unsigned result = tryMergeNamespace(I, E, Limit)) {
+ return result;
+ }
+ }
return Style.BreakBeforeBraces == FormatStyle::BS_Attach
? tryMergeSimpleBlock(I, E, Limit)
: 0;
@@ -258,6 +264,35 @@
return 1;
}
+ unsigned tryMergeNamespace(
+ SmallVectorImpl::const_iterator I,
+ SmallVectorImpl::const_iterator E, unsigned Limit) {
+ if (Limit == 0)
+ return 0;
+ if (I[1]->InPPDirective != (*I)->InPPDirective ||
+ (I[1]->InPPDirective && I[1]->First->HasUnescapedNewline))
+ return 0;
+
+ Limit = limitConsideringMacros(I + 1, E, Limit);
+
+ if (1 + I[1]->Last->TotalLength > Limit)
+ return 0;
+
+ // An assumption of the function is that the first line begins with
+ // keyword namespace (i.e. I[0]->First->is(tok::kw_namespace))
+
+ // The line which is in the namespace should end with semicolon
+ if (I[1]->Last->isNot(tok::semi))
+ return 0;
+
+ // Last, check that the third line starts with a closing brace.
+ if (I[2]->First->isNot(tok::r_brace))
+ return 0;
+
+ // If so, merge all three lines.
+ return 2;
+ }
+
unsigned tryMergeSimpleControlStatement(
SmallVectorImpl::const_iterator I,
SmallVectorImpl::const_iterator E, unsigned Limit) {
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -10433,6 +10433,17 @@
verifyNoCrash("#define a\\\n /**/}");
}
+TEST_F(FormatTest, ShortNamespacesOption) {
+ FormatStyle style = getLLVMStyle();
+ style.AllowShortNamespacesOnASingleLine = true;
+
+ verifyFormat("namespace foo { class bar; }", style);
+ verifyFormat("namespace foo {\nclass bar;\nclass baz;\n}", style);
+ verifyFormat("namespace foo {\nint f() { return 5; }\n}", style);
+ verifyFormat("namespace foo { template struct bar; }", style);
+ verifyFormat("namespace foo { constexpr int num = 42; }", style);
+}
+
} // end namespace
} // end namespace format
} // end namespace clang