MarcusJohnson91 updated this revision to Diff 258612.
MarcusJohnson91 edited the summary of this revision.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75791/new/

https://reviews.llvm.org/D75791

Files:
  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

Index: clang/unittests/Format/FormatTest.cpp
===================================================================
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2509,10 +2509,43 @@
                Style);
   verifyFormat("extern \"C\"\n"
                "{\n"
-               "  int foo();\n"
+               "int foo();\n"
                "}",
                Style);
 }
+  
+TEST_F(FormatTest, IndentExternBlockStyle) {
+  FormatStyle Style = getLLVMStyle();
+  Style.IndentWidth = 2;
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_Indent;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+               "  int foo1();\n"
+               "}", Style);
+  
+  Style.IndentExternBlock = FormatStyle::IEBS_NoIndent;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+               "int foo2();\n"
+               "}", Style);
+  
+  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
+  
+  Style.BraceWrapping.AfterExternBlock = true;
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\"\n{\n"
+               "  int foo3();\n"
+               "}", Style);
+  
+  Style.BraceWrapping.AfterExternBlock = false;
+  Style.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  verifyFormat("extern \"C\" {}", Style);
+  verifyFormat("extern \"C\" {\n"
+               "int foo4();\n"
+               "}", Style);
+}
 
 TEST_F(FormatTest, FormatsInlineASM) {
   verifyFormat("asm(\"xyz\" : \"=a\"(a), \"=d\"(b) : \"a\"(data));");
@@ -13262,6 +13295,13 @@
   CHECK_PARSE("AllowShortIfStatementsOnASingleLine: true",
               AllowShortIfStatementsOnASingleLine,
               FormatStyle::SIS_WithoutElse);
+  
+  Style.IndentExternBlock = FormatStyle.IEBS_Indent;
+  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.
Index: clang/lib/Format/UnwrappedLineParser.cpp
===================================================================
--- clang/lib/Format/UnwrappedLineParser.cpp
+++ clang/lib/Format/UnwrappedLineParser.cpp
@@ -1112,11 +1112,11 @@
     if (FormatTok->Tok.is(tok::string_literal)) {
       nextToken();
       if (FormatTok->Tok.is(tok::l_brace)) {
-        if (Style.BraceWrapping.AfterExternBlock) {
+        if (Style.IndentExternBlock == FormatStyle::IEBS_AfterExternBlock && Style.BraceWrapping.AfterExternBlock) {
           addUnwrappedLine();
-          parseBlock(/*MustBeDeclaration=*/true);
+          parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/Style.BraceWrapping.AfterExternBlock == true ? true : false);
         } else {
-          parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/false);
+          parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/Style.IndentExternBlock == FormatStyle::IEBS_Indent ? true : false);
         }
         addUnwrappedLine();
         return;
Index: clang/lib/Format/Format.cpp
===================================================================
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -202,6 +202,18 @@
     IO.enumCase(Value, "Always", FormatStyle::BWACS_Always);
   }
 };
+  
+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::BreakConstructorInitializersStyle> {
@@ -494,6 +506,7 @@
     IO.mapOptional("IndentWidth", Style.IndentWidth);
     IO.mapOptional("IndentWrappedFunctionNames",
                    Style.IndentWrappedFunctionNames);
+    IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
     IO.mapOptional("InsertTrailingCommas", Style.InsertTrailingCommas);
     IO.mapOptional("JavaImportGroups", Style.JavaImportGroups);
     IO.mapOptional("JavaScriptQuotes", Style.JavaScriptQuotes);
Index: clang/include/clang/Format/Format.h
===================================================================
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -948,12 +948,12 @@
     ///   }
     /// \endcode
     bool AfterUnion;
-    /// Wrap extern blocks.
+    /// Wrap extern blocks; Deprecated, replaced by ExternBlocks
     /// \code
     ///   true:
     ///   extern "C"
     ///   {
-    ///     int foo();
+    ///   int foo();
     ///   }
     ///
     ///   false:
@@ -962,6 +962,24 @@
     ///   }
     /// \endcode
     bool AfterExternBlock;
+    enum ExternBlock {
+      /// Break extern blocks before the curly brace.
+      /// \code
+      ///    extern "C"
+      ///    {
+      ///    foo();
+      ///    }
+      /// \endcode
+      EB_Before,
+      /// Break constructor initializers before the colon and commas, and align
+      /// the commas with the colon.
+      /// \code
+      ///    extern "C++" {
+      ///    foo();
+      ///    }
+      /// \endcode
+      EB_None
+    };
     /// Wrap before ``catch``.
     /// \code
     ///   true:
@@ -1462,6 +1480,41 @@
   /// \endcode
   bool IndentWrappedFunctionNames;
 
+  /// Indents extern blocks
+  enum IndentExternBlockStyle {
+    /// Does not indent extern blocks.
+    /// \code
+    ///  extern "C" {
+    ///  void foo();
+    ///  }
+    /// \endcode
+    IEBS_NoIndent,
+    /// Indents extern blocks.
+    /// \code
+    ///  extern "C" {
+    ///    void foo();
+    ///  }
+    /// \endcode
+    IEBS_Indent,
+    /// Backwards compatible with AfterExternBlock's indenting.
+    /// AfterExternBlock: true
+    /// \code
+    /// extern "C"
+    /// {
+    ///   void foo();
+    /// }
+    /// \endcode
+    /// AfterExternBlock: false
+    /// \code
+    /// extern "C" {
+    /// void foo();
+    /// }
+    /// \endcode
+    IEBS_AfterExternBlock,
+  };
+    
+  IndentExternBlockStyle IndentExternBlock;
+
   /// A vector of prefixes ordered by the desired groups for Java imports.
   ///
   /// Each group is separated by a newline. Static imports will also follow the
@@ -2210,6 +2263,7 @@
            IndentPPDirectives == R.IndentPPDirectives &&
            IndentWidth == R.IndentWidth && Language == R.Language &&
            IndentWrappedFunctionNames == R.IndentWrappedFunctionNames &&
+           IndentExternBlock == R.IndentExternBlock &&
            JavaImportGroups == R.JavaImportGroups &&
            JavaScriptQuotes == R.JavaScriptQuotes &&
            JavaScriptWrapImports == R.JavaScriptWrapImports &&
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -236,6 +236,23 @@
 ------------
 
 
+- Option ``IndentExternBlock`` has been added to optionally apply indenting inside extern "C" blocks.
+  
+  The ``BraceWrapping.AfterExternBlock`` option has been modified so it no longer indents when set to true, now it just wraps the braces around extern blocks.
+
+  .. code-block:: c++
+
+    true:                         false:
+      #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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to