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,19 @@ } } +**PPIndentWidth** (``unsigned``) + The number of columns to use for indentation of preprocessor statements. + + .. 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 @@ -2323,6 +2323,18 @@ /// \endcode unsigned IndentWidth; + /// The number of columns to use for indentation of preprocessor statements. + /// \code + /// PPIndentWidth: 1 + /// + /// #ifdef __linux__ + /// # define FOO + /// #else + /// # define BAR + /// #endif + /// \endcode + unsigned PPIndentWidth; + /// Indent if a function definition or declaration is wrapped after the /// type. /// \code 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 = 2; // default to old value LLVMStyle.InsertTrailingCommas = FormatStyle::TCS_None; LLVMStyle.JavaScriptQuotes = FormatStyle::JSQS_Leave; LLVMStyle.JavaScriptWrapImports = true; @@ -1263,6 +1265,7 @@ ChromiumStyle.BreakAfterJavaFieldAnnotations = true; ChromiumStyle.ContinuationIndentWidth = 8; ChromiumStyle.IndentWidth = 4; + ChromiumStyle.PPIndentWidth = 4; // default to old value // See styleguide for import groups: // https://chromium.googlesource.com/chromium/src/+/master/styleguide/java/java.md#Import-Order ChromiumStyle.JavaImportGroups = { @@ -1309,6 +1312,7 @@ MozillaStyle.BreakInheritanceList = FormatStyle::BILS_BeforeComma; MozillaStyle.ConstructorInitializerIndentWidth = 2; MozillaStyle.ContinuationIndentWidth = 2; + MozillaStyle.PPIndentWidth = 2; // default to old value MozillaStyle.Cpp11BracedListStyle = false; MozillaStyle.FixNamespaceComments = false; MozillaStyle.IndentCaseLabels = true; @@ -1334,6 +1338,7 @@ Style.ColumnLimit = 0; Style.FixNamespaceComments = false; Style.IndentWidth = 4; + Style.PPIndentWidth = 4; // default to old value Style.NamespaceIndentation = FormatStyle::NI_Inner; Style.ObjCBlockIndentWidth = 4; Style.ObjCSpaceAfterProperty = true; @@ -1363,6 +1368,7 @@ Style.ColumnLimit = 120; Style.TabWidth = 4; Style.IndentWidth = 4; + Style.PPIndentWidth = 4; // default to old value Style.UseTab = FormatStyle::UT_Never; Style.BreakBeforeBraces = FormatStyle::BS_Custom; Style.BraceWrapping.AfterClass = 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,7 @@ while (IndentForLevel.size() <= Line.Level) IndentForLevel.push_back(-1); if (Line.InPPDirective) { - Indent = Line.Level * Style.IndentWidth + AdditionalIndent; + Indent = Line.Level * Style.PPIndentWidth + 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,21 @@ verifyFormat("a\f\\"); } +TEST_F(FormatTest, IndentsPPDirectiveWithPPIndentWidth) { + FormatStyle style = getChromiumStyle(FormatStyle::LK_Cpp); + style.IndentWidth = 4; + style.PPIndentWidth = 1; + style.IndentPPDirectives = FormatStyle::PPDIS_AfterHash; + + verifyFormat("#ifdef __linux__\n" + "# define FOO\n" + "#endif\n" + "void foo() {\n" + " int x = 0;\n" + "}\n", + style); +} + TEST_F(FormatTest, IndentsPPDirectiveInReducedSpace) { verifyFormat("#define A(BB)", getLLVMStyleWithColumns(13)); verifyFormat("#define A( \\\n BB)", getLLVMStyleWithColumns(12)); @@ -4080,6 +4095,7 @@ FormatStyle Tabbed = Style; Tabbed.UseTab = FormatStyle::UT_Always; Tabbed.IndentWidth = 8; + Tabbed.PPIndentWidth = 8; Tabbed.TabWidth = 8; verifyFormat("#ifdef _WIN32\n" "#\tdefine A 0\n" @@ -12182,6 +12198,7 @@ TEST_F(FormatTest, ConfigurableUseOfTab) { FormatStyle Tab = getLLVMStyleWithColumns(42); Tab.IndentWidth = 8; + Tab.PPIndentWidth = 8; Tab.UseTab = FormatStyle::UT_Always; Tab.AlignEscapedNewlines = FormatStyle::ENAS_Left; @@ -12228,6 +12245,7 @@ Tab.TabWidth = 4; Tab.IndentWidth = 4; + Tab.PPIndentWidth = 4; verifyFormat("class TabWidth4Indent4 {\n" "\tvoid f() {\n" "\t\tsomeFunction(parameter1,\n" @@ -12248,6 +12266,7 @@ Tab.TabWidth = 8; Tab.IndentWidth = 8; + Tab.PPIndentWidth = 8; EXPECT_EQ("/*\n" "\t a\t\tcomment\n" "\t in multiple lines\n" @@ -12410,6 +12429,7 @@ Tab.UseTab = FormatStyle::UT_ForContinuationAndIndentation; Tab.TabWidth = 8; Tab.IndentWidth = 8; + Tab.PPIndentWidth = 8; EXPECT_EQ("if (aaaaaaaa && // q\n" " bb) // w\n" "\t;", @@ -12447,6 +12467,7 @@ Tab); Tab.TabWidth = 4; Tab.IndentWidth = 4; + Tab.PPIndentWidth = 4; verifyFormat("class TabWidth4Indent4 {\n" "\tvoid f() {\n" "\t\tsomeFunction(parameter1,\n" @@ -12465,6 +12486,7 @@ Tab); Tab.TabWidth = 8; Tab.IndentWidth = 8; + Tab.PPIndentWidth = 8; EXPECT_EQ("/*\n" "\t a\t\tcomment\n" "\t in multiple lines\n" @@ -12649,6 +12671,7 @@ Tab.UseTab = FormatStyle::UT_AlignWithSpaces; Tab.TabWidth = 8; Tab.IndentWidth = 8; + Tab.PPIndentWidth = 8; EXPECT_EQ("if (aaaaaaaa && // q\n" " bb) // w\n" "\t;",