to-miz updated this revision to Diff 189048.
to-miz added a comment.
Added an entry to ReleaseNotes.rst about the new option.
This diff doesn't contain unrelated formatting changes due to running
clang-format on some source files that apparently weren't formatted before.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D52150/new/
https://reviews.llvm.org/D52150
Files:
docs/ClangFormatStyleOptions.rst
docs/ReleaseNotes.rst
include/clang/Format/Format.h
lib/Format/Format.cpp
lib/Format/TokenAnnotator.cpp
lib/Format/UnwrappedLineFormatter.cpp
lib/Format/UnwrappedLineParser.cpp
unittests/Format/FormatTest.cpp
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -1812,8 +1812,8 @@
Style.CompactNamespaces = true;
verifyFormat("namespace A { namespace B {\n"
- "}} // namespace A::B",
- Style);
+ "}} // namespace A::B",
+ Style);
EXPECT_EQ("namespace out { namespace in {\n"
"}} // namespace out::in",
@@ -2953,22 +2953,25 @@
EXPECT_EQ(Expected, format(ToFormat, Style));
EXPECT_EQ(Expected, format(Expected, Style));
}
- // Test with tabs.
- Style.UseTab = FormatStyle::UT_Always;
- Style.IndentWidth = 8;
- Style.TabWidth = 8;
- verifyFormat("#ifdef _WIN32\n"
- "#\tdefine A 0\n"
- "#\tifdef VAR2\n"
- "#\t\tdefine B 1\n"
- "#\t\tinclude <someheader.h>\n"
- "#\t\tdefine MACRO \\\n"
- "\t\t\tsome_very_long_func_aaaaaaaaaa();\n"
- "#\tendif\n"
- "#else\n"
- "#\tdefine A 1\n"
- "#endif",
- Style);
+ // Test AfterHash with tabs.
+ {
+ FormatStyle Tabbed = Style;
+ Tabbed.UseTab = FormatStyle::UT_Always;
+ Tabbed.IndentWidth = 8;
+ Tabbed.TabWidth = 8;
+ verifyFormat("#ifdef _WIN32\n"
+ "#\tdefine A 0\n"
+ "#\tifdef VAR2\n"
+ "#\t\tdefine B 1\n"
+ "#\t\tinclude <someheader.h>\n"
+ "#\t\tdefine MACRO \\\n"
+ "\t\t\tsome_very_long_func_aaaaaaaaaa();\n"
+ "#\tendif\n"
+ "#else\n"
+ "#\tdefine A 1\n"
+ "#endif",
+ Tabbed);
+ }
// Regression test: Multiline-macro inside include guards.
verifyFormat("#ifndef HEADER_H\n"
@@ -2978,6 +2981,102 @@
" int j;\n"
"#endif // HEADER_H",
getLLVMStyleWithColumns(20));
+
+ Style.IndentPPDirectives = FormatStyle::PPDIS_BeforeHash;
+ // Basic before hash indent tests
+ verifyFormat("#ifdef _WIN32\n"
+ " #define A 0\n"
+ " #ifdef VAR2\n"
+ " #define B 1\n"
+ " #include <someheader.h>\n"
+ " #define MACRO \\\n"
+ " some_very_long_func_aaaaaaaaaa();\n"
+ " #endif\n"
+ "#else\n"
+ " #define A 1\n"
+ "#endif",
+ Style);
+ verifyFormat("#if A\n"
+ " #define MACRO \\\n"
+ " void a(int x) { \\\n"
+ " b(); \\\n"
+ " c(); \\\n"
+ " d(); \\\n"
+ " e(); \\\n"
+ " f(); \\\n"
+ " }\n"
+ "#endif",
+ Style);
+ // Keep comments aligned with indented directives. These
+ // tests cannot use verifyFormat because messUp manipulates leading
+ // whitespace.
+ {
+ const char *Expected = "void f() {\n"
+ "// Aligned to preprocessor.\n"
+ "#if 1\n"
+ " // Aligned to code.\n"
+ " int a;\n"
+ " #if 1\n"
+ " // Aligned to preprocessor.\n"
+ " #define A 0\n"
+ " // Aligned to code.\n"
+ " int b;\n"
+ " #endif\n"
+ "#endif\n"
+ "}";
+ const char *ToFormat = "void f() {\n"
+ "// Aligned to preprocessor.\n"
+ "#if 1\n"
+ "// Aligned to code.\n"
+ "int a;\n"
+ "#if 1\n"
+ "// Aligned to preprocessor.\n"
+ "#define A 0\n"
+ "// Aligned to code.\n"
+ "int b;\n"
+ "#endif\n"
+ "#endif\n"
+ "}";
+ EXPECT_EQ(Expected, format(ToFormat, Style));
+ EXPECT_EQ(Expected, format(Expected, Style));
+ }
+ {
+ const char *Expected = "void f() {\n"
+ "/* Aligned to preprocessor. */\n"
+ "#if 1\n"
+ " /* Aligned to code. */\n"
+ " int a;\n"
+ " #if 1\n"
+ " /* Aligned to preprocessor. */\n"
+ " #define A 0\n"
+ " /* Aligned to code. */\n"
+ " int b;\n"
+ " #endif\n"
+ "#endif\n"
+ "}";
+ const char *ToFormat = "void f() {\n"
+ "/* Aligned to preprocessor. */\n"
+ "#if 1\n"
+ "/* Aligned to code. */\n"
+ "int a;\n"
+ "#if 1\n"
+ "/* Aligned to preprocessor. */\n"
+ "#define A 0\n"
+ "/* Aligned to code. */\n"
+ "int b;\n"
+ "#endif\n"
+ "#endif\n"
+ "}";
+ EXPECT_EQ(Expected, format(ToFormat, Style));
+ EXPECT_EQ(Expected, format(Expected, Style));
+ }
+
+ // Test single comment before preprocessor
+ verifyFormat("// Comment\n"
+ "\n"
+ "#if 1\n"
+ "#endif",
+ Style);
}
TEST_F(FormatTest, FormatHashIfNotAtStartOfLine) {
@@ -3838,39 +3937,39 @@
verifyFormat(
"SomeClass::Constructor() :\n"
" aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}",
- Style);
+ Style);
verifyFormat(
"SomeClass::Constructor() :\n"
" aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n"
" aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}",
- Style);
+ Style);
verifyFormat(
"SomeClass::Constructor() :\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n"
" aaaaaaaaaaaaaaa(aaaaaaaaaaaa) {}",
- Style);
+ Style);
verifyFormat("Constructor(aaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
" aaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) :\n"
" aaaaaaaaaa(aaaaaa) {}",
- Style);
+ Style);
verifyFormat("Constructor() :\n"
" aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa),\n"
" aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaa),\n"
" aaaaaaaaaaaaaaaaaaaaaaa() {}",
- Style);
+ Style);
verifyFormat("Constructor() :\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}",
- Style);
+ Style);
verifyFormat("Constructor(int Parameter = 0) :\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa),\n"
" aaaaaaaaaaaa(aaaaaaaaaaaaaaaaa) {}",
- Style);
+ Style);
verifyFormat("Constructor() :\n"
" aaaaaaaaaaaaaaaaaaaaaa(a), bbbbbbbbbbbbbbbbbbbbbbbb(b) {\n"
"}",
@@ -3878,7 +3977,7 @@
verifyFormat("Constructor() :\n"
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
" aaaaaaaaaaaaaaaaaaaaaaaaa(aaaa, aaaa)) {}",
- Style);
+ Style);
// Here a line could be saved by splitting the second initializer onto two
// lines, but that is not desirable.
@@ -3886,7 +3985,7 @@
" aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaa),\n"
" aaaaaaaaaaa(aaaaaaaaaaa),\n"
" aaaaaaaaaaaaaaaaaaaaat(aaaaaaaaaaaaaaaaaaaaaaaaaaaa) {}",
- Style);
+ Style);
FormatStyle OnePerLine = Style;
OnePerLine.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
@@ -3936,7 +4035,7 @@
format("Constructor() :\n"
" // Comment forcing unwanted break.\n"
" aaaa(aaaa) {}",
- Style));
+ Style));
Style.ColumnLimit = 0;
verifyFormat("SomeClass::Constructor() :\n"
@@ -3946,7 +4045,7 @@
" a(a) {}",
Style);
verifyFormat("SomeClass::Constructor() :\n"
- " a(a), b(b), c(c) {}",
+ " a(a), b(b), c(c) {}",
Style);
verifyFormat("SomeClass::Constructor() :\n"
" a(a) {\n"
@@ -3957,12 +4056,12 @@
Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
verifyFormat("SomeClass::Constructor() :\n"
- " a(a), b(b), c(c) {\n"
- "}",
+ " a(a), b(b), c(c) {\n"
+ "}",
Style);
verifyFormat("SomeClass::Constructor() :\n"
" a(a) {\n"
- "}",
+ "}",
Style);
Style.ColumnLimit = 80;
@@ -7122,7 +7221,7 @@
// Binpacking only if there is no trailing comma
verifyFormat("const Aaaaaa aaaaa = {aaaaaaaaaa, bbbbbbbbbb,\n"
" cccccccccc, dddddddddd};",
- getLLVMStyleWithColumns(50));
+ getLLVMStyleWithColumns(50));
verifyFormat("const Aaaaaa aaaaa = {\n"
" aaaaaaaaaaa,\n"
" bbbbbbbbbbb,\n"
Index: lib/Format/UnwrappedLineParser.cpp
===================================================================
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -655,6 +655,7 @@
void UnwrappedLineParser::parsePPDirective() {
assert(FormatTok->Tok.is(tok::hash) && "'#' expected");
ScopedMacroState MacroState(*Line, Tokens, FormatTok);
+
nextToken();
if (!FormatTok->Tok.getIdentifierInfo()) {
@@ -823,7 +824,7 @@
FormatTok->WhitespaceRange.getEnd()) {
parseParens();
}
- if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash)
+ if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
Line->Level += PPBranchLevel + 1;
addUnwrappedLine();
++Line->Level;
@@ -840,7 +841,7 @@
do {
nextToken();
} while (!eof());
- if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash)
+ if (Style.IndentPPDirectives != FormatStyle::PPDIS_None)
Line->Level += PPBranchLevel + 1;
addUnwrappedLine();
}
@@ -2633,6 +2634,9 @@
// Comments stored before the preprocessor directive need to be output
// before the preprocessor directive, at the same level as the
// preprocessor directive, as we consider them to apply to the directive.
+ if (Style.IndentPPDirectives == FormatStyle::PPDIS_BeforeHash &&
+ PPBranchLevel > 0)
+ Line->Level += PPBranchLevel;
flushComments(isOnNewLine(*FormatTok));
parsePPDirective();
}
Index: lib/Format/UnwrappedLineFormatter.cpp
===================================================================
--- lib/Format/UnwrappedLineFormatter.cpp
+++ lib/Format/UnwrappedLineFormatter.cpp
@@ -1176,8 +1176,10 @@
if (Newlines)
Indent = NewlineIndent;
- // Preprocessor directives get indented after the hash, if indented.
- if (Line.Type == LT_PreprocessorDirective || Line.Type == LT_ImportStatement)
+ // Preprocessor directives get indented before the hash only if specified
+ if (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+ (Line.Type == LT_PreprocessorDirective ||
+ Line.Type == LT_ImportStatement))
Indent = 0;
Whitespaces->replaceWhitespace(RootToken, Newlines, Indent, Indent,
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -1921,12 +1921,15 @@
NextNonCommentLine->First->NewlinesBefore <= 1 &&
NextNonCommentLine->First->OriginalColumn ==
(*I)->First->OriginalColumn) {
- // Align comments for preprocessor lines with the # in column 0.
- // Otherwise, align with the next line.
- (*I)->Level = (NextNonCommentLine->Type == LT_PreprocessorDirective ||
- NextNonCommentLine->Type == LT_ImportStatement)
- ? 0
- : NextNonCommentLine->Level;
+ // Align comments for preprocessor lines with the # in column 0 if
+ // preprocessor lines are not indented. Otherwise, align with the next
+ // line.
+ (*I)->Level =
+ (Style.IndentPPDirectives != FormatStyle::PPDIS_BeforeHash &&
+ (NextNonCommentLine->Type == LT_PreprocessorDirective ||
+ NextNonCommentLine->Type == LT_ImportStatement))
+ ? 0
+ : NextNonCommentLine->Level;
} else {
NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr;
}
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -162,6 +162,7 @@
static void enumeration(IO &IO, FormatStyle::PPDirectiveIndentStyle &Value) {
IO.enumCase(Value, "None", FormatStyle::PPDIS_None);
IO.enumCase(Value, "AfterHash", FormatStyle::PPDIS_AfterHash);
+ IO.enumCase(Value, "BeforeHash", FormatStyle::PPDIS_BeforeHash);
}
};
Index: include/clang/Format/Format.h
===================================================================
--- include/clang/Format/Format.h
+++ include/clang/Format/Format.h
@@ -1096,7 +1096,16 @@
/// # endif
/// #endif
/// \endcode
- PPDIS_AfterHash
+ PPDIS_AfterHash,
+ /// Indents directives before the hash.
+ /// \code
+ /// #if FOO
+ /// #if BAR
+ /// #include <foo>
+ /// #endif
+ /// #endif
+ /// \endcode
+ PPDIS_BeforeHash
};
/// The preprocessor directive indenting style to use.
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -157,8 +157,8 @@
clang-format
------------
-
-- ...
+- Added new option `PPDIS_BeforeHash` (in configuration: `BeforeHash`) to
+ `IndentPPDirectives` which indents preprocessor directives before the hash.
libclang
--------
Index: docs/ClangFormatStyleOptions.rst
===================================================================
--- docs/ClangFormatStyleOptions.rst
+++ docs/ClangFormatStyleOptions.rst
@@ -1365,6 +1365,16 @@
# endif
#endif
+ * ``PPDIS_BeforeHash`` (in configuration: ``BeforeHash``)
+ Indents directives before the hash.
+
+ .. code-block:: c++
+
+ #if FOO
+ #if BAR
+ #include <foo>
+ #endif
+ #endif
**IndentWidth** (``unsigned``)
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits