[clang] Fixes and closes issues, #53390 and #58710. Added new controls to IndentNamespaceAliases, IndentUsingDeclarations and DecorateReflowedComments. (PR #102894)

Rajkumar Ananthu via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 12 05:40:53 PDT 2024


https://github.com/rajkumarananthu created https://github.com/llvm/llvm-project/pull/102894

Issue #53390 was reported to have an option to control indenting namespace aliases independently of NamespaceIndentation, added this feature.

Issue #58710 was reported to have an option to control the decoration of the block comments, added this feature.

>From 2bf9ae230b1b22aa1542437827749b3c19321bc2 Mon Sep 17 00:00:00 2001
From: Rajkumar Ananthu <rajkumar.ananthu108 at gmail.com>
Date: Mon, 12 Aug 2024 18:05:10 +0530
Subject: [PATCH] Fixes and closes issues, #53390 and #58710. Added new
 controls to IndentNamespaceAliases, IndentUsingDeclarations and
 DecorateReflowedComments.

Issue #53390 was reported to have an option to control indenting
namespace aliases independently of NamespaceIndentation, added this
feature.

Issue #58710 was reported to have an option to control the decoration of
the block comments, added this feature.
---
 clang/include/clang/Format/Format.h      | 43 ++++++++++++++++++++++++
 clang/lib/Format/BreakableToken.cpp      |  6 ++--
 clang/lib/Format/Format.cpp              | 16 +++++++++
 clang/lib/Format/UnwrappedLineParser.cpp | 37 ++++++++++++++++++--
 clang/lib/Format/UnwrappedLineParser.h   |  1 +
 5 files changed, 99 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index ef6c76a070bfaa..c00d57013cb13f 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2822,6 +2822,46 @@ struct FormatStyle {
   /// \version 11
   IndentExternBlockStyle IndentExternBlock;
 
+  /// IndentNamespaceAliases is the type of indenting of namespace aliases
+  /// irrespective of NamespaceIndentation.
+  bool IndentNamespaceAliases;
+
+  /// IndentUsingDeclarations is the type of indenting of using declarations
+  /// irrespective of NamespaceIndentation.
+  bool IndentUsingDeclarations;
+
+  enum DecorateReflowedCommentsStyle : int8_t {
+    /// Never:
+    /// don't use any decorator
+    /// \code
+    /// /* blah blah blah blah blah blah blah blah blah blah blah blah blah
+    ///    blah blah blah blah blah blah blah blah */
+    /// \endcode
+    DRC_Never,
+    /// Always:
+    /// Always decorate with the decorator
+    /// \code
+    /// /* blah blah blah blah blah blah blah blah blah blah blah blah blah
+    ///  * blah blah blah blah blah blah blah blah */
+    /// \endcode
+    DRC_Always,
+    /// FirstInLine:
+    /// Use decoration only for First in line block comments
+    /// \code
+    /// using namespace std; /* blah blah blah blah blah blah blah blah blah
+    ///                         blah blah blah */
+    ///
+    /// /* blah blah blah blah blah blah blah blah blah blah blah blah blah
+    ///  * blah blah blah blah blah blah blah blah */
+    /// using namespace std;
+    /// \endcode
+    DRC_FirstInLineOnly
+  };
+
+  /// reflowed block comments decoration style
+  /// \version 17
+  DecorateReflowedCommentsStyle DecorateReflowedComments;
+
   /// Options for indenting preprocessor directives.
   enum PPDirectiveIndentStyle : int8_t {
     /// Does not indent any directives.
@@ -5104,6 +5144,9 @@ struct FormatStyle {
            IndentCaseBlocks == R.IndentCaseBlocks &&
            IndentCaseLabels == R.IndentCaseLabels &&
            IndentExternBlock == R.IndentExternBlock &&
+           IndentNamespaceAliases == R.IndentNamespaceAliases &&
+           IndentUsingDeclarations == R.IndentUsingDeclarations &&
+           DecorateReflowedComments == R.DecorateReflowedComments &&
            IndentGotoLabels == R.IndentGotoLabels &&
            IndentPPDirectives == R.IndentPPDirectives &&
            IndentRequiresClause == R.IndentRequiresClause &&
diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp
index 75304908dc6506..8bb18486e1717c 100644
--- a/clang/lib/Format/BreakableToken.cpp
+++ b/clang/lib/Format/BreakableToken.cpp
@@ -517,10 +517,12 @@ BreakableBlockComment::BreakableBlockComment(
   }
 
   Decoration = "* ";
-  if (Lines.size() == 1 && !FirstInLine) {
+  if ((Style.DecorateReflowedComments == FormatStyle::DRC_Never) ||
+      (!FirstInLine &&
+       (Style.DecorateReflowedComments == FormatStyle::DRC_FirstInLineOnly))) {
     // Comments for which FirstInLine is false can start on arbitrary column,
     // and available horizontal space can be too small to align consecutive
-    // lines with the first one.
+    // lines with the first one. Also if decoration is explicitly turned off.
     // FIXME: We could, probably, align them to current indentation level, but
     // now we just wrap them without stars.
     Decoration = "";
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 5358b35c19de25..566cbd7908ff42 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -449,6 +449,16 @@ struct ScalarEnumerationTraits<FormatStyle::NamespaceIndentationKind> {
   }
 };
 
+template <>
+struct ScalarEnumerationTraits<FormatStyle::DecorateReflowedCommentsStyle> {
+  static void enumeration(IO &IO,
+                          FormatStyle::DecorateReflowedCommentsStyle &Value) {
+    IO.enumCase(Value, "Never", FormatStyle::DRC_Never);
+    IO.enumCase(Value, "Always", FormatStyle::DRC_Always);
+    IO.enumCase(Value, "FirstInLineOnly", FormatStyle::DRC_FirstInLineOnly);
+  }
+};
+
 template <> struct ScalarEnumerationTraits<FormatStyle::OperandAlignmentStyle> {
   static void enumeration(IO &IO, FormatStyle::OperandAlignmentStyle &Value) {
     IO.enumCase(Value, "DontAlign", FormatStyle::OAS_DontAlign);
@@ -1014,6 +1024,9 @@ template <> struct MappingTraits<FormatStyle> {
     IO.mapOptional("IndentCaseBlocks", Style.IndentCaseBlocks);
     IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
     IO.mapOptional("IndentExternBlock", Style.IndentExternBlock);
+    IO.mapOptional("IndentNamespaceAliases", Style.IndentNamespaceAliases);
+    IO.mapOptional("IndentUsingDeclarations", Style.IndentUsingDeclarations);
+    IO.mapOptional("DecorateReflowedComments", Style.DecorateReflowedComments);
     IO.mapOptional("IndentGotoLabels", Style.IndentGotoLabels);
     IO.mapOptional("IndentPPDirectives", Style.IndentPPDirectives);
     IO.mapOptional("IndentRequiresClause", Style.IndentRequiresClause);
@@ -1524,6 +1537,9 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
   LLVMStyle.IndentCaseBlocks = false;
   LLVMStyle.IndentCaseLabels = false;
   LLVMStyle.IndentExternBlock = FormatStyle::IEBS_AfterExternBlock;
+  LLVMStyle.IndentNamespaceAliases = false;
+  LLVMStyle.IndentUsingDeclarations = false;
+  LLVMStyle.DecorateReflowedComments = FormatStyle::DRC_FirstInLineOnly;
   LLVMStyle.IndentGotoLabels = true;
   LLVMStyle.IndentPPDirectives = FormatStyle::PPDIS_None;
   LLVMStyle.IndentRequiresClause = true;
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 66485c91f64de9..4878e4a749c968 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -47,8 +47,7 @@ void printLine(llvm::raw_ostream &OS, const UnwrappedLine &Line,
       OS << Prefix;
       NewLine = false;
     }
-    OS << I->Tok->Tok.getName() << "["
-       << "T=" << (unsigned)I->Tok->getType()
+    OS << I->Tok->Tok.getName() << "[" << "T=" << (unsigned)I->Tok->getType()
        << ", OC=" << I->Tok->OriginalColumn << ", \"" << I->Tok->TokenText
        << "\"] ";
     for (SmallVectorImpl<UnwrappedLine>::const_iterator
@@ -346,6 +345,35 @@ bool UnwrappedLineParser::precededByCommentOrPPDirective() const {
          (Previous->IsMultiline || Previous->NewlinesBefore > 0);
 }
 
+void UnwrappedLineParser::parseStmt(bool keepIndentation) {
+  bool levelsAreAdded = (Line->Level == DeclarationScopeStack.size());
+  // move till the end of the statement
+  while (!FormatTok->is(tok::semi))
+    nextToken();
+  nextToken();
+  if (keepIndentation) {
+    // if levels are already added, just emit with existing indentation
+    // otherwise, emit with scoped indentation
+    if (levelsAreAdded) {
+      addUnwrappedLine(LineLevel::Keep);
+    } else {
+      Line->Level += (DeclarationScopeStack.size() - 1);
+      addUnwrappedLine(LineLevel::Keep);
+      Line->Level -= (DeclarationScopeStack.size() - 1);
+    }
+  } else {
+    // if levels are already added, remove the levels and emit
+    // otherwise, just emit
+    if (levelsAreAdded) {
+      Line->Level -= (DeclarationScopeStack.size() - 1);
+      addUnwrappedLine(LineLevel::Remove);
+      Line->Level += (DeclarationScopeStack.size() - 1);
+    } else {
+      addUnwrappedLine(LineLevel::Remove);
+    }
+  }
+}
+
 /// \brief Parses a level, that is ???.
 /// \param OpeningBrace Opening brace (\p nullptr if absent) of that level.
 /// \param IfKind The \p if statement kind in the level.
@@ -465,6 +493,9 @@ bool UnwrappedLineParser::parseLevel(const FormatToken *OpeningBrace,
       SwitchLabelEncountered = true;
       parseStructuralElement();
       break;
+    case tok::kw_using:
+      parseStmt(Style.IndentUsingDeclarations);
+      break;
     case tok::l_square:
       if (Style.isCSharp()) {
         nextToken();
@@ -3117,6 +3148,8 @@ void UnwrappedLineParser::parseNamespace() {
 
     if (ManageWhitesmithsBraces)
       --Line->Level;
+  } else if (FormatTok->is(tok::equal)) {
+    parseStmt(Style.IndentNamespaceAliases);
   }
   // FIXME: Add error handling.
 }
diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h
index b7daf8d9f44012..adcb0ee07994f0 100644
--- a/clang/lib/Format/UnwrappedLineParser.h
+++ b/clang/lib/Format/UnwrappedLineParser.h
@@ -120,6 +120,7 @@ class UnwrappedLineParser {
   void reset();
   void parseFile();
   bool precededByCommentOrPPDirective() const;
+  void parseStmt(bool keepIndentation);
   bool parseLevel(const FormatToken *OpeningBrace = nullptr,
                   IfStmtKind *IfKind = nullptr,
                   FormatToken **IfLeftBrace = nullptr);



More information about the cfe-commits mailing list