diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -2615,6 +2615,20 @@ } } +**PPIndentWidth** (``unsigned``) + The number of columns to use for indentation of preprocessor statements. + When set to -1 this defaults to IndentWidth for backwards compatibility. + + .. code-block:: c++ + + PPIndentWidth: 1 + + #ifdef __linux__ + # define FOO + #else + # define BAR + #endif + **IndentWrappedFunctionNames** (``bool``) Indent if a function definition or declaration is wrapped after the type. diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -2659,6 +2659,19 @@ /// Pointer and reference alignment style. PointerAlignmentStyle PointerAlignment; + /// The number of columns to use for indentation of preprocessor statements. + /// When set to -1 this defaults to IndentWidth for backwards compatibility. + /// \code + /// PPIndentWidth: 1 + /// + /// #ifdef __linux__ + /// # define FOO + /// #else + /// # define BAR + /// #endif + /// \endcode + signed PPIndentWidth; + /// See documentation of ``RawStringFormats``. struct RawStringFormat { /// The language of this raw string. diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -664,6 +664,7 @@ IO.mapOptional("PenaltyIndentedWhitespace", Style.PenaltyIndentedWhitespace); IO.mapOptional("PointerAlignment", Style.PointerAlignment); + IO.mapOptional("PPIndentWidth", Style.PPIndentWidth); IO.mapOptional("RawStringFormats", Style.RawStringFormats); IO.mapOptional("ReflowComments", Style.ReflowComments); IO.mapOptional("ShortNamespaceLines", Style.ShortNamespaceLines); @@ -1021,6 +1022,7 @@ LLVMStyle.IndentRequires = false; LLVMStyle.IndentWrappedFunctionNames = false; LLVMStyle.IndentWidth = 2; + LLVMStyle.PPIndentWidth = -1; LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None; LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave; LLVMStyle.JavaScriptWrapImports = true; diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -57,7 +57,9 @@ while (IndentForLevel.size() <= Line.Level) IndentForLevel.push_back(-1); if (Line.InPPDirective) { - Indent = Line.Level * Style.IndentWidth + AdditionalIndent; + unsigned IndentWidth = + (Style.PPIndentWidth >= 0) ? Style.PPIndentWidth : Style.IndentWidth; + Indent = Line.Level * IndentWidth + AdditionalIndent; } else { IndentForLevel.resize(Line.Level + 1); Indent = getIndent(IndentForLevel, Line.Level); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -3431,6 +3431,48 @@ verifyFormat("a\f\\"); } +TEST_F(FormatTest, IndentsPPDirectiveWithPPIndentWidth) { + FormatStyle style = getChromiumStyle(FormatStyle::LK_Cpp); + style.IndentWidth = 4; + style.PPIndentWidth = 1; + + style.IndentPPDirectives = FormatStyle::PPDIS_None; + verifyFormat("#ifdef __linux__\n" + "void foo() {\n" + " int x = 0;\n" + "}\n" + "#define FOO\n" + "#endif\n" + "void bar() {\n" + " int y = 0;\n" + "}\n", + style); + + style.IndentPPDirectives = FormatStyle::PPDIS_AfterHash; + verifyFormat("#ifdef __linux__\n" + "void foo() {\n" + " int x = 0;\n" + "}\n" + "# define FOO foo\n" + "#endif\n" + "void bar() {\n" + " int y = 0;\n" + "}\n", + style); + + style.IndentPPDirectives = FormatStyle::PPDIS_BeforeHash; + verifyFormat("#ifdef __linux__\n" + "void foo() {\n" + " int x = 0;\n" + "}\n" + " #define FOO foo\n" + "#endif\n" + "void bar() {\n" + " int y = 0;\n" + "}\n", + style); +} + TEST_F(FormatTest, IndentsPPDirectiveInReducedSpace) { verifyFormat("#define A(BB)", getLLVMStyleWithColumns(13)); verifyFormat("#define A( \\\n BB)", getLLVMStyleWithColumns(12));