Author: mydeveloperday Date: 2020-05-20T21:27:15+01:00 New Revision: 6ef45b0426a8c7b9764e102fb1a49561a3a2c118
URL: https://github.com/llvm/llvm-project/commit/6ef45b0426a8c7b9764e102fb1a49561a3a2c118 DIFF: https://github.com/llvm/llvm-project/commit/6ef45b0426a8c7b9764e102fb1a49561a3a2c118.diff LOG: [clang-format] Added new option IndentExternBlock Reviewers: MyDeveloperDay, krasimir, klimek, mitchell-stellar, Abpostelnicu Patch By: MarcusJohnson91 Reviewed By: MyDeveloperDay, Abpostelnicu Subscribers: sylvestre.ledru, Abpostelnicu, cfe-commits Tags: #clang, #clang-format, #clang-tools-extra Differential Revision: https://reviews.llvm.org/D75791 Added: Modified: clang/docs/ClangFormatStyleOptions.rst clang/docs/ReleaseNotes.rst clang/include/clang/Format/Format.h clang/lib/Format/Format.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp Removed: ################################################################################ diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index e5a5fd154849..2afa17973454 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -1739,6 +1739,52 @@ the configuration (without a prefix: ``Auto``). plop(); plop(); } } +**IndentExternBlock** (``IndentExternBlockStyle``) + IndentExternBlockStyle is the type of indenting of extern blocks. + + Possible values: + + * ``IEBS_AfterExternBlock`` (in configuration: ``AfterExternBlock``) + Backwards compatible with AfterExternBlock's indenting. + + .. code-block:: c++ + + IndentExternBlock: AfterExternBlock + BraceWrapping.AfterExternBlock: true + extern "C" + { + void foo(); + } + + + .. code-block:: c++ + + IndentExternBlock: AfterExternBlock + BraceWrapping.AfterExternBlock: false + extern "C" { + void foo(); + } + + * ``IEBS_NoIndent`` (in configuration: ``NoIndent``) + Does not indent extern blocks. + + .. code-block:: c++ + + extern "C" { + void foo(); + } + + * ``IEBS_Indent`` (in configuration: ``Indent``) + Indents extern blocks. + + .. code-block:: c++ + + extern "C" { + void foo(); + } + + + **IndentGotoLabels** (``bool``) Indent goto labels. diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 48c1c9ea019d..16f5915856fd 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -251,6 +251,23 @@ AST Matchers clang-format ------------ +- Option ``IndentExternBlock`` has been added to optionally apply indenting inside ``extern "C"`` and ``extern "C++"`` blocks. + +- ``IndentExternBlock`` option accepts ``AfterExternBlock`` to use the old behavior, as well as Indent and NoIndent options, which map to true and false, respectively. + + .. code-block:: c++ + + Indent: NoIndent: + #ifdef __cplusplus #ifdef __cplusplus + extern "C" { extern "C++" { + #endif #endif + + void f(void); void f(void); + + #ifdef __cplusplus #ifdef __cplusplus + } } + #endif #endif + - Option ``IndentCaseBlocks`` has been added to support treating the block following a switch case label as a scope block which gets indented itself. It helps avoid having the closing bracket align with the switch statement's @@ -316,7 +333,7 @@ clang-format before the ```while`` in a do..while loop. By default the value is (``false``) In previous releases ``IndentBraces`` implied ``BraceWrapping.BeforeWhile``. - If using a Custom BraceWrapping style you may need to now set + If using a Custom BraceWrapping style you may need to now set ``BraceWrapping.BeforeWhile`` to (``true``) to be explicit. .. code-block:: c++ @@ -332,7 +349,6 @@ clang-format foo(); } while(1); - libclang -------- diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 05a9cd2d418d..96b73211d9ff 100755 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -1028,7 +1028,7 @@ struct FormatStyle { /// int foo(); /// } /// \endcode - bool AfterExternBlock; + bool AfterExternBlock; // Partially superseded by IndentExternBlock /// Wrap before ``catch``. /// \code /// true: @@ -1517,6 +1517,45 @@ struct FormatStyle { /// The preprocessor directive indenting style to use. PPDirectiveIndentStyle IndentPPDirectives; + /// Indents extern blocks + enum IndentExternBlockStyle { + /// Backwards compatible with AfterExternBlock's indenting. + /// \code + /// IndentExternBlock: AfterExternBlock + /// BraceWrapping.AfterExternBlock: true + /// extern "C" + /// { + /// void foo(); + /// } + /// \endcode + /// + /// \code + /// IndentExternBlock: AfterExternBlock + /// BraceWrapping.AfterExternBlock: false + /// extern "C" { + /// void foo(); + /// } + /// \endcode + IEBS_AfterExternBlock, + /// Does not indent extern blocks. + /// \code + /// extern "C" { + /// void foo(); + /// } + /// \endcode + IEBS_NoIndent, + /// Indents extern blocks. + /// \code + /// extern "C" { + /// void foo(); + /// } + /// \endcode + IEBS_Indent, + }; + + /// IndentExternBlockStyle is the type of indenting of extern blocks. + IndentExternBlockStyle IndentExternBlock; + /// The number of columns to use for indentation. /// \code /// IndentWidth: 3 @@ -2302,6 +2341,7 @@ struct FormatStyle { IndentCaseBlocks == R.IndentCaseBlocks && IndentGotoLabels == R.IndentGotoLabels && IndentPPDirectives == R.IndentPPDirectives && + IndentExternBlock == R.IndentExternBlock && IndentWidth == R.IndentWidth && Language == R.Language && IndentWrappedFunctionNames == R.IndentWrappedFunctionNames && JavaImportGroups == R.JavaImportGroups && diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 79e9f35de707..f3743921d52e 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -234,6 +234,17 @@ struct ScalarEnumerationTraits<FormatStyle::PPDirectiveIndentStyle> { } }; +template <> +struct ScalarEnumerationTraits<FormatStyle::IndentExternBlockStyle> { + static void enumeration(IO &IO, FormatStyle::IndentExternBlockStyle &Value) { + IO.enumCase(Value, "AfterExternBlock", FormatStyle::IEBS_AfterExternBlock); + IO.enumCase(Value, "Indent", FormatStyle::IEBS_Indent); + IO.enumCase(Value, "NoIndent", FormatStyle::IEBS_NoIndent); + IO.enumCase(Value, "true", FormatStyle::IEBS_Indent); + IO.enumCase(Value, "false", FormatStyle::IEBS_NoIndent); + } +}; + template <> struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> { static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) { @@ -512,6 +523,7 @@ template <> struct MappingTraits<FormatStyle> { IO.mapOptional("IndentCaseBlocks", Style.IndentCaseBlocks); IO.mapOptional("IndentGotoLabels", Style.IndentGotoLabels); IO.mapOptional("IndentPPDirectives", Style.IndentPPDirectives); + IO.mapOptional("IndentExternBlock", Style.IndentExternBlock); IO.mapOptional("IndentWidth", Style.IndentWidth); IO.mapOptional("IndentWrappedFunctionNames", Style.IndentWrappedFunctionNames); @@ -719,6 +731,7 @@ static FormatStyle expandPresets(const FormatStyle &Style) { Expanded.BraceWrapping.AfterStruct = true; Expanded.BraceWrapping.AfterUnion = true; Expanded.BraceWrapping.AfterExternBlock = true; + Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; Expanded.BraceWrapping.SplitEmptyFunction = true; Expanded.BraceWrapping.SplitEmptyRecord = false; break; @@ -738,6 +751,7 @@ static FormatStyle expandPresets(const FormatStyle &Style) { Expanded.BraceWrapping.AfterStruct = true; Expanded.BraceWrapping.AfterUnion = true; Expanded.BraceWrapping.AfterExternBlock = true; + Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; Expanded.BraceWrapping.BeforeCatch = true; Expanded.BraceWrapping.BeforeElse = true; break; @@ -751,6 +765,7 @@ static FormatStyle expandPresets(const FormatStyle &Style) { Expanded.BraceWrapping.AfterObjCDeclaration = true; Expanded.BraceWrapping.AfterStruct = true; Expanded.BraceWrapping.AfterExternBlock = true; + Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; Expanded.BraceWrapping.BeforeCatch = true; Expanded.BraceWrapping.BeforeElse = true; Expanded.BraceWrapping.BeforeLambdaBody = true; @@ -775,6 +790,7 @@ static FormatStyle expandPresets(const FormatStyle &Style) { /*SplitEmptyFunction=*/true, /*SplitEmptyRecord=*/true, /*SplitEmptyNamespace=*/true}; + Expanded.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; break; case FormatStyle::BS_WebKit: Expanded.BraceWrapping.AfterFunction = true; @@ -834,6 +850,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { /*SplitEmptyFunction=*/true, /*SplitEmptyRecord=*/true, /*SplitEmptyNamespace=*/true}; + LLVMStyle.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; LLVMStyle.BreakAfterJavaFieldAnnotations = false; LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon; @@ -1195,6 +1212,7 @@ FormatStyle getMicrosoftStyle(FormatStyle::LanguageKind Language) { Style.BraceWrapping.AfterObjCDeclaration = true; Style.BraceWrapping.AfterStruct = true; Style.BraceWrapping.AfterExternBlock = true; + Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; Style.BraceWrapping.BeforeCatch = true; Style.BraceWrapping.BeforeElse = true; Style.BraceWrapping.BeforeWhile = false; diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index ba509f218ffc..03b6e0c9ef74 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -1113,11 +1113,16 @@ void UnwrappedLineParser::parseStructuralElement() { if (FormatTok->Tok.is(tok::string_literal)) { nextToken(); if (FormatTok->Tok.is(tok::l_brace)) { - if (Style.BraceWrapping.AfterExternBlock) { - addUnwrappedLine(); - parseBlock(/*MustBeDeclaration=*/true); + if (!Style.IndentExternBlock) { + if (Style.BraceWrapping.AfterExternBlock) { + addUnwrappedLine(); + } + parseBlock(/*MustBeDeclaration=*/true, + /*AddLevel=*/Style.BraceWrapping.AfterExternBlock); } else { - parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false); + parseBlock(/*MustBeDeclaration=*/true, + /*AddLevel=*/Style.IndentExternBlock == + FormatStyle::IEBS_Indent); } addUnwrappedLine(); return; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index ff31601e537a..a3b70bfd2824 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2558,6 +2558,43 @@ TEST_F(FormatTest, FormatsExternC) { Style); } +TEST_F(FormatTest, IndentExternBlockStyle) { + FormatStyle Style = getLLVMStyle(); + Style.IndentWidth = 2; + + Style.IndentExternBlock = FormatStyle::IEBS_Indent; + verifyFormat("extern \"C\" { /*9*/\n}", Style); + verifyFormat("extern \"C\" {\n" + " int foo10();\n" + "}", + Style); + + Style.IndentExternBlock = FormatStyle::IEBS_NoIndent; + verifyFormat("extern \"C\" { /*11*/\n}", Style); + verifyFormat("extern \"C\" {\n" + "int foo12();\n" + "}", + Style); + + Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.AfterExternBlock = true; + verifyFormat("extern \"C\"\n{ /*13*/\n}", Style); + verifyFormat("extern \"C\"\n{\n" + " int foo14();\n" + "}", + Style); + + Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock; + Style.BreakBeforeBraces = FormatStyle::BS_Custom; + Style.BraceWrapping.AfterExternBlock = false; + verifyFormat("extern \"C\" { /*15*/\n}", Style); + verifyFormat("extern \"C\" {\n" + "int foo16();\n" + "}", + Style); +} + TEST_F(FormatTest, FormatsInlineASM) { verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));"); verifyFormat("asm(\"nop\" ::: \"memory\");"); @@ -13846,6 +13883,18 @@ TEST_F(FormatTest, ParsesConfiguration) { AllowShortIfStatementsOnASingleLine, FormatStyle::SIS_WithoutElse); + Style.IndentExternBlock = FormatStyle::IEBS_NoIndent; + CHECK_PARSE("IndentExternBlock: AfterExternBlock", IndentExternBlock, + FormatStyle::IEBS_AfterExternBlock); + CHECK_PARSE("IndentExternBlock: Indent", IndentExternBlock, + FormatStyle::IEBS_Indent); + CHECK_PARSE("IndentExternBlock: NoIndent", IndentExternBlock, + FormatStyle::IEBS_NoIndent); + CHECK_PARSE("IndentExternBlock: true", IndentExternBlock, + FormatStyle::IEBS_Indent); + CHECK_PARSE("IndentExternBlock: false", IndentExternBlock, + FormatStyle::IEBS_NoIndent); + // FIXME: This is required because parsing a configuration simply overwrites // the first N elements of the list instead of resetting it. Style.ForEachMacros.clear(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits