[clang] be9a87f - [clang-format] Add IfMacros option
Vitali Lovich via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 23 08:53:32 PDT 2021
Author: Vitali Lovich
Date: 2021-06-23T08:51:53-07:00
New Revision: be9a87fe9bc395074c383c07fbd9c0bce953985f
URL: https://github.com/llvm/llvm-project/commit/be9a87fe9bc395074c383c07fbd9c0bce953985f
DIFF: https://github.com/llvm/llvm-project/commit/be9a87fe9bc395074c383c07fbd9c0bce953985f.diff
LOG: [clang-format] Add IfMacros option
https://bugs.llvm.org/show_bug.cgi?id=49354
Differential Revision: https://reviews.llvm.org/D102730
Added:
Modified:
clang/docs/ClangFormatStyleOptions.rst
clang/docs/ReleaseNotes.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/lib/Format/FormatToken.h
clang/lib/Format/FormatTokenLexer.cpp
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/FormatTest.cpp
Removed:
################################################################################
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index f05e11469a7b5..77c07284085c8 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -2377,6 +2377,28 @@ the configuration (without a prefix: ``Auto``).
For example: BOOST_FOREACH.
+**IfMacros** (``std::vector<std::string>``)
+ A vector of macros that should be interpreted as conditionals
+ instead of as function calls.
+
+ These are expected to be macros of the form:
+
+ .. code-block:: c++
+
+ IF(...)
+ <conditional-body>
+ else IF(...)
+ <conditional-body>
+
+ In the .clang-format configuration file, this can be configured like:
+
+ .. code-block:: yaml
+
+ IfMacros: ['IF']
+
+ For example: `KJ_IF_MAYBE
+ <https://github.com/capnproto/capnproto/blob/master/kjdoc/tour.md#maybes>`_
+
**IncludeBlocks** (``IncludeBlocksStyle``)
Dependent on the value, multiple ``#include`` blocks can be sorted
as one and divided based on category.
@@ -3480,10 +3502,12 @@ the configuration (without a prefix: ``Auto``).
}
}
- * ``SBPO_ControlStatementsExceptForEachMacros`` (in configuration: ``ControlStatementsExceptForEachMacros``)
+ * ``SBPO_ControlStatementsExceptControlMacros`` (in configuration: ``ControlStatementsExceptControlMacros``)
Same as ``SBPO_ControlStatements`` except this option doesn't apply to
- ForEach macros. This is useful in projects where ForEach macros are
- treated as function calls instead of control statements.
+ ForEach and If macros. This is useful in projects where ForEach/If
+ macros are treated as function calls instead of control statements.
+ ``SBPO_ControlStatementsExceptForEachMacros`` remains an alias for
+ backward compatability.
.. code-block:: c++
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4b432c1f3bb8d..7b23c1ef77af2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -265,6 +265,10 @@ clang-format
change that so that the lambda body is indented one level relative to the scope
containing the lambda, regardless of where the lambda signature was placed.
+- Option ``IfMacros`` has been added. This lets you define macros that get
+ formatted like conditionals much like ``ForEachMacros`` get styled like
+ foreach loops.
+
- ``git-clang-format`` no longer formats changes to symbolic links. (Fixes
https://llvm.org/PR46992.)
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index d51666fe9a1b0..506feea26e8dc 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2117,6 +2117,26 @@ struct FormatStyle {
/// For example: BOOST_FOREACH.
std::vector<std::string> ForEachMacros;
+ /// A vector of macros that should be interpreted as conditionals
+ /// instead of as function calls.
+ ///
+ /// These are expected to be macros of the form:
+ /// \code
+ /// IF(...)
+ /// <conditional-body>
+ /// else IF(...)
+ /// <conditional-body>
+ /// \endcode
+ ///
+ /// In the .clang-format configuration file, this can be configured like:
+ /// \code{.yaml}
+ /// IfMacros: ['IF']
+ /// \endcode
+ ///
+ /// For example: `KJ_IF_MAYBE
+ /// <https://github.com/capnproto/capnproto/blob/master/kjdoc/tour.md#maybes>`_
+ std::vector<std::string> IfMacros;
+
/// \brief A vector of macros that should be interpreted as type declarations
/// instead of as function calls.
///
@@ -3033,8 +3053,10 @@ struct FormatStyle {
/// \endcode
SBPO_ControlStatements,
/// Same as ``SBPO_ControlStatements`` except this option doesn't apply to
- /// ForEach macros. This is useful in projects where ForEach macros are
- /// treated as function calls instead of control statements.
+ /// ForEach and If macros. This is useful in projects where ForEach/If
+ /// macros are treated as function calls instead of control statements.
+ /// ``SBPO_ControlStatementsExceptForEachMacros`` remains an alias for
+ /// backward compatability.
/// \code
/// void f() {
/// Q_FOREACH(...) {
@@ -3042,7 +3064,7 @@ struct FormatStyle {
/// }
/// }
/// \endcode
- SBPO_ControlStatementsExceptForEachMacros,
+ SBPO_ControlStatementsExceptControlMacros,
/// Put a space before opening parentheses only if the parentheses are not
/// empty i.e. '()'
/// \code
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index b83fcaebf18c3..bfd4d8b5af503 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -424,8 +424,8 @@ struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
IO.enumCase(Value, "ControlStatements",
FormatStyle::SBPO_ControlStatements);
- IO.enumCase(Value, "ControlStatementsExceptForEachMacros",
- FormatStyle::SBPO_ControlStatementsExceptForEachMacros);
+ IO.enumCase(Value, "ControlStatementsExceptControlMacros",
+ FormatStyle::SBPO_ControlStatementsExceptControlMacros);
IO.enumCase(Value, "NonEmptyParentheses",
FormatStyle::SBPO_NonEmptyParentheses);
IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);
@@ -433,6 +433,8 @@ struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
// For backward compatibility.
IO.enumCase(Value, "false", FormatStyle::SBPO_Never);
IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements);
+ IO.enumCase(Value, "ControlStatementsExceptForEachMacros",
+ FormatStyle::SBPO_ControlStatementsExceptControlMacros);
}
};
@@ -637,6 +639,8 @@ template <> struct MappingTraits<FormatStyle> {
Style.ExperimentalAutoDetectBinPacking);
IO.mapOptional("FixNamespaceComments", Style.FixNamespaceComments);
IO.mapOptional("ForEachMacros", Style.ForEachMacros);
+ IO.mapOptional("IfMacros", Style.IfMacros);
+
IO.mapOptional("IncludeBlocks", Style.IncludeStyle.IncludeBlocks);
IO.mapOptional("IncludeCategories", Style.IncludeStyle.IncludeCategories);
IO.mapOptional("IncludeIsMainRegex", Style.IncludeStyle.IncludeIsMainRegex);
@@ -1031,6 +1035,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.ForEachMacros.push_back("foreach");
LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
+ LLVMStyle.IfMacros.push_back("KJ_IF_MAYBE");
LLVMStyle.IncludeStyle.IncludeCategories = {
{"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
{"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
@@ -3143,4 +3148,4 @@ llvm::Expected<FormatStyle> getStyle(StringRef StyleName, StringRef FileName,
}
} // namespace format
-} // namespace clang
+} // namespace clang
\ No newline at end of file
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index 57c5eeb5a091f..0506cd554bcba 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -52,6 +52,7 @@ namespace format {
TYPE(FunctionDeclarationName) \
TYPE(FunctionLBrace) \
TYPE(FunctionTypeLParen) \
+ TYPE(IfMacro) \
TYPE(ImplicitStringLiteral) \
TYPE(InheritanceColon) \
TYPE(InheritanceComma) \
diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp
index 0faa18c348289..a9cfb4a247f09 100644
--- a/clang/lib/Format/FormatTokenLexer.cpp
+++ b/clang/lib/Format/FormatTokenLexer.cpp
@@ -39,6 +39,8 @@ FormatTokenLexer::FormatTokenLexer(
for (const std::string &ForEachMacro : Style.ForEachMacros)
Macros.insert({&IdentTable.get(ForEachMacro), TT_ForEachMacro});
+ for (const std::string &IfMacro : Style.IfMacros)
+ Macros.insert({&IdentTable.get(IfMacro), TT_IfMacro});
for (const std::string &AttributeMacro : Style.AttributeMacros)
Macros.insert({&IdentTable.get(AttributeMacro), TT_AttributeMacro});
for (const std::string &StatementMacro : Style.StatementMacros)
@@ -1014,6 +1016,13 @@ FormatToken *FormatTokenLexer::getNextToken() {
tok::pp_define) &&
it != Macros.end()) {
FormatTok->setType(it->second);
+ if (it->second == TT_IfMacro) {
+ // The lexer token currently has type tok::kw_unknown. However, for this
+ // substitution to be treated correctly in the TokenAnnotator, faking
+ // the tok value seems to be needed. Not sure if there's a more elegant
+ // way.
+ FormatTok->Tok.setKind(tok::kw_if);
+ }
} else if (FormatTok->is(tok::identifier)) {
if (MacroBlockBeginRegex.match(Text)) {
FormatTok->setType(TT_MacroBlockBegin);
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
old mode 100755
new mode 100644
index 48309af24aa81..92fb1b14056ab
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -1409,7 +1409,7 @@ class AnnotatingParser {
// Reset token type in case we have already looked at it and then
// recovered from an error (e.g. failure to find the matching >).
if (!CurrentToken->isOneOf(
- TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro,
+ TT_LambdaLSquare, TT_LambdaLBrace, TT_AttributeMacro, TT_IfMacro,
TT_ForEachMacro, TT_TypenameMacro, TT_FunctionLBrace,
TT_ImplicitStringLiteral, TT_InlineASMBrace, TT_FatArrow,
TT_LambdaArrow, TT_NamespaceMacro, TT_OverloadedOperator,
@@ -3120,9 +3120,13 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
(Left.is(tok::r_square) && Left.is(TT_AttributeSquare)))
return true;
if (Style.SpaceBeforeParens ==
- FormatStyle::SBPO_ControlStatementsExceptForEachMacros &&
+ FormatStyle::SBPO_ControlStatementsExceptControlMacros &&
Left.is(TT_ForEachMacro))
return false;
+ if (Style.SpaceBeforeParens ==
+ FormatStyle::SBPO_ControlStatementsExceptControlMacros &&
+ Left.is(TT_IfMacro))
+ return false;
return Line.Type == LT_ObjCDecl || Left.is(tok::semi) ||
(Style.SpaceBeforeParens != FormatStyle::SBPO_Never &&
(Left.isOneOf(tok::pp_elif, tok::kw_for, tok::kw_while,
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 59690c722a9ed..cc702e81c2c37 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -525,6 +525,7 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) {
"}");
FormatStyle AllowsMergedIf = getLLVMStyle();
+ AllowsMergedIf.IfMacros.push_back("MYIF");
AllowsMergedIf.AlignEscapedNewlines = FormatStyle::ENAS_Left;
AllowsMergedIf.AllowShortIfStatementsOnASingleLine =
FormatStyle::SIS_WithoutElse;
@@ -564,17 +565,62 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) {
" f();\n"
"}",
AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " // comment\n"
+ " f();",
+ AllowsMergedIf);
+ verifyFormat("{\n"
+ " MYIF (a)\n"
+ " label:\n"
+ " f();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("#define A \\\n"
+ " MYIF (a) \\\n"
+ " label: \\\n"
+ " f()",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " ;",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " MYIF (b) return;",
+ AllowsMergedIf);
+
+ verifyFormat("MYIF (a) // Can't merge this\n"
+ " f();\n",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) /* still don't merge */\n"
+ " f();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) { // Never merge this\n"
+ " f();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) { /* Never merge this */\n"
+ " f();\n"
+ "}",
+ AllowsMergedIf);
AllowsMergedIf.ColumnLimit = 14;
+ // Where line-lengths matter, a 2-letter synonym that maintains line length.
+ // Not IF to avoid any confusion that IF is somehow special.
+ AllowsMergedIf.IfMacros.push_back("FI");
verifyFormat("if (a) return;", AllowsMergedIf);
verifyFormat("if (aaaaaaaaa)\n"
" return;",
AllowsMergedIf);
+ verifyFormat("FI (a) return;", AllowsMergedIf);
+ verifyFormat("FI (aaaaaaaaa)\n"
+ " return;",
+ AllowsMergedIf);
AllowsMergedIf.ColumnLimit = 13;
verifyFormat("if (a)\n return;", AllowsMergedIf);
+ verifyFormat("FI (a)\n return;", AllowsMergedIf);
FormatStyle AllowsMergedIfElse = getLLVMStyle();
+ AllowsMergedIfElse.IfMacros.push_back("MYIF");
AllowsMergedIfElse.AllowShortIfStatementsOnASingleLine =
FormatStyle::SIS_AllIfsAndElse;
verifyFormat("if (a)\n"
@@ -626,10 +672,60 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) {
" else if constexpr (c) return;\n"
" else return;",
AllowsMergedIfElse);
+ verifyFormat("MYIF (a)\n"
+ " // comment\n"
+ " f();\n"
+ "else\n"
+ " // comment\n"
+ " f();",
+ AllowsMergedIfElse);
+ verifyFormat("{\n"
+ " MYIF (a)\n"
+ " label:\n"
+ " f();\n"
+ " else\n"
+ " label:\n"
+ " f();\n"
+ "}",
+ AllowsMergedIfElse);
+ verifyFormat("MYIF (a)\n"
+ " ;\n"
+ "else\n"
+ " ;",
+ AllowsMergedIfElse);
+ verifyFormat("MYIF (a) {\n"
+ "} else {\n"
+ "}",
+ AllowsMergedIfElse);
+ verifyFormat("MYIF (a) return;\n"
+ "else MYIF (b) return;\n"
+ "else return;",
+ AllowsMergedIfElse);
+ verifyFormat("MYIF (a) {\n"
+ "} else return;",
+ AllowsMergedIfElse);
+ verifyFormat("MYIF (a) {\n"
+ "} else MYIF (b) return;\n"
+ "else return;",
+ AllowsMergedIfElse);
+ verifyFormat("MYIF (a) return;\n"
+ "else MYIF (b) {\n"
+ "} else return;",
+ AllowsMergedIfElse);
+ verifyFormat("MYIF (a)\n"
+ " MYIF (b) return;\n"
+ " else return;",
+ AllowsMergedIfElse);
+ verifyFormat("MYIF constexpr (a)\n"
+ " MYIF constexpr (b) return;\n"
+ " else MYIF constexpr (c) return;\n"
+ " else return;",
+ AllowsMergedIfElse);
}
TEST_F(FormatTest, FormatIfWithoutCompoundStatementButElseWith) {
FormatStyle AllowsMergedIf = getLLVMStyle();
+ AllowsMergedIf.IfMacros.push_back("MYIF");
AllowsMergedIf.AlignEscapedNewlines = FormatStyle::ENAS_Left;
AllowsMergedIf.AllowShortIfStatementsOnASingleLine =
FormatStyle::SIS_WithoutElse;
@@ -717,6 +813,135 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatementButElseWith) {
" g();\n"
"}",
AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " f();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " f();\n"
+ "else\n"
+ " g();\n",
+ AllowsMergedIf);
+
+ verifyFormat("MYIF (a) g();", AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g()\n"
+ "};",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " g();\n"
+ "else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " g();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " g();\n"
+ "else MYIF (b)\n"
+ " g();\n"
+ "else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " g();\n"
+ "else if (b)\n"
+ " g();\n"
+ "else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else MYIF (b)\n"
+ " g();\n"
+ "else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else if (b)\n"
+ " g();\n"
+ "else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " g();\n"
+ "else MYIF (b) {\n"
+ " g();\n"
+ "} else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " g();\n"
+ "else if (b) {\n"
+ " g();\n"
+ "} else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " g();\n"
+ "else MYIF (b)\n"
+ " g();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " g();\n"
+ "else if (b)\n"
+ " g();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " g();\n"
+ "else MYIF (b) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a)\n"
+ " g();\n"
+ "else if (b) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else MYIF (b) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else if (b) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
AllowsMergedIf.AllowShortIfStatementsOnASingleLine =
FormatStyle::SIS_OnlyFirstIf;
@@ -802,6 +1027,128 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatementButElseWith) {
" g();\n"
"}",
AllowsMergedIf);
+ verifyFormat("MYIF (a) f();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) f();\n"
+ "else {\n"
+ " if (a) f();\n"
+ " else {\n"
+ " g();\n"
+ " }\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+
+ verifyFormat("MYIF (a) g();", AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g()\n"
+ "};",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else MYIF (b)\n"
+ " g();\n"
+ "else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else if (b)\n"
+ " g();\n"
+ "else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else MYIF (b)\n"
+ " g();\n"
+ "else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else if (b)\n"
+ " g();\n"
+ "else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else MYIF (b) {\n"
+ " g();\n"
+ "} else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else if (b) {\n"
+ " g();\n"
+ "} else\n"
+ " g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else MYIF (b)\n"
+ " g();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else if (b)\n"
+ " g();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else MYIF (b) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else if (b) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else MYIF (b) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else if (b) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
AllowsMergedIf.AllowShortIfStatementsOnASingleLine =
FormatStyle::SIS_AllIfsAndElse;
@@ -879,6 +1226,114 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatementButElseWith) {
" g();\n"
"}",
AllowsMergedIf);
+ verifyFormat("MYIF (a) f();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) f();\n"
+ "else {\n"
+ " if (a) f();\n"
+ " else {\n"
+ " g();\n"
+ " }\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+
+ verifyFormat("MYIF (a) g();", AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g()\n"
+ "};",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else MYIF (b) g();\n"
+ "else g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else if (b) g();\n"
+ "else g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else MYIF (b) g();\n"
+ "else g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else if (b) g();\n"
+ "else g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else MYIF (b) {\n"
+ " g();\n"
+ "} else g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else if (b) {\n"
+ " g();\n"
+ "} else g();",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else MYIF (b) g();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else if (b) g();\n"
+ "else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else MYIF (b) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) g();\n"
+ "else if (b) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else MYIF (b) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
+ verifyFormat("MYIF (a) {\n"
+ " g();\n"
+ "} else if (b) {\n"
+ " g();\n"
+ "} else {\n"
+ " g();\n"
+ "}",
+ AllowsMergedIf);
}
TEST_F(FormatTest, FormatLoopsWithoutCompoundStatement) {
@@ -930,6 +1385,10 @@ TEST_F(FormatTest, FormatLoopsWithoutCompoundStatement) {
TEST_F(FormatTest, FormatShortBracedStatements) {
FormatStyle AllowSimpleBracedStatements = getLLVMStyle();
+ AllowSimpleBracedStatements.IfMacros.push_back("MYIF");
+ // Where line-lengths matter, a 2-letter synonym that maintains line length.
+ // Not IF to avoid any confusion that IF is somehow special.
+ AllowSimpleBracedStatements.IfMacros.push_back("FI");
AllowSimpleBracedStatements.ColumnLimit = 40;
AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine =
FormatStyle::SBS_Always;
@@ -945,11 +1404,17 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
verifyFormat("if (true) {}", AllowSimpleBracedStatements);
verifyFormat("if constexpr (true) {}", AllowSimpleBracedStatements);
verifyFormat("if CONSTEXPR (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("MYIF constexpr (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("MYIF CONSTEXPR (true) {}", AllowSimpleBracedStatements);
verifyFormat("while (true) {}", AllowSimpleBracedStatements);
verifyFormat("for (;;) {}", AllowSimpleBracedStatements);
verifyFormat("if (true) { f(); }", AllowSimpleBracedStatements);
verifyFormat("if constexpr (true) { f(); }", AllowSimpleBracedStatements);
verifyFormat("if CONSTEXPR (true) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("MYIF constexpr (true) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("MYIF CONSTEXPR (true) { f(); }", AllowSimpleBracedStatements);
verifyFormat("while (true) { f(); }", AllowSimpleBracedStatements);
verifyFormat("for (;;) { f(); }", AllowSimpleBracedStatements);
verifyFormat("if (true) { fffffffffffffffffffffff(); }",
@@ -977,6 +1442,31 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
" f();\n"
"}",
AllowSimpleBracedStatements);
+ verifyFormat("FI (true) { fffffffffffffffffffffff(); }",
+ AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true) {\n"
+ " ffffffffffffffffffffffff();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true) {\n"
+ " ffffffffffffffffffffffffffffffffffffffffffffffffffffff();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true) { //\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true) {\n"
+ " f();\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true) {\n"
+ " f();\n"
+ "} else {\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
verifyFormat("struct A2 {\n"
" int X;\n"
@@ -1004,6 +1494,17 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
" f();\n"
"}",
AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true) {\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true) {\n"
+ " f();\n"
+ "} else {\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = false;
verifyFormat("while (true) {}", AllowSimpleBracedStatements);
@@ -1026,11 +1527,17 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
verifyFormat("if (true) {}", AllowSimpleBracedStatements);
verifyFormat("if constexpr (true) {}", AllowSimpleBracedStatements);
verifyFormat("if CONSTEXPR (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("MYIF constexpr (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("MYIF CONSTEXPR (true) {}", AllowSimpleBracedStatements);
verifyFormat("while (true) {}", AllowSimpleBracedStatements);
verifyFormat("for (;;) {}", AllowSimpleBracedStatements);
verifyFormat("if (true) { f(); }", AllowSimpleBracedStatements);
verifyFormat("if constexpr (true) { f(); }", AllowSimpleBracedStatements);
verifyFormat("if CONSTEXPR (true) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("MYIF constexpr (true) { f(); }", AllowSimpleBracedStatements);
+ verifyFormat("MYIF CONSTEXPR (true) { f(); }", AllowSimpleBracedStatements);
verifyFormat("while (true) { f(); }", AllowSimpleBracedStatements);
verifyFormat("for (;;) { f(); }", AllowSimpleBracedStatements);
verifyFormat("if (true) { fffffffffffffffffffffff(); }",
@@ -1064,6 +1571,37 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
" f();\n"
"}",
AllowSimpleBracedStatements);
+ verifyFormat("FI (true) { fffffffffffffffffffffff(); }",
+ AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true)\n"
+ "{\n"
+ " ffffffffffffffffffffffff();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true)\n"
+ "{\n"
+ " ffffffffffffffffffffffffffffffffffffffffffffffffffffff();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true)\n"
+ "{ //\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true)\n"
+ "{\n"
+ " f();\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true)\n"
+ "{\n"
+ " f();\n"
+ "} else\n"
+ "{\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine =
FormatStyle::SIS_Never;
@@ -1081,6 +1619,20 @@ TEST_F(FormatTest, FormatShortBracedStatements) {
" f();\n"
"}",
AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true) {}", AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true)\n"
+ "{\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
+ verifyFormat("MYIF (true)\n"
+ "{\n"
+ " f();\n"
+ "} else\n"
+ "{\n"
+ " f();\n"
+ "}",
+ AllowSimpleBracedStatements);
AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = false;
verifyFormat("while (true) {}", AllowSimpleBracedStatements);
@@ -1342,7 +1894,7 @@ TEST_F(FormatTest, ForEachLoops) {
FormatStyle Style = getLLVMStyle();
Style.SpaceBeforeParens =
- FormatStyle::SBPO_ControlStatementsExceptForEachMacros;
+ FormatStyle::SBPO_ControlStatementsExceptControlMacros;
verifyFormat("void f() {\n"
" foreach(Item *item, itemlist) {}\n"
" Q_FOREACH(Item *item, itemlist) {}\n"
@@ -17624,6 +18176,9 @@ TEST_F(FormatTest, ParsesConfiguration) {
FormatStyle::SBPO_Always);
CHECK_PARSE("SpaceBeforeParens: ControlStatements", SpaceBeforeParens,
FormatStyle::SBPO_ControlStatements);
+ CHECK_PARSE("SpaceBeforeParens: ControlStatementsExceptControlMacros",
+ SpaceBeforeParens,
+ FormatStyle::SBPO_ControlStatementsExceptControlMacros);
CHECK_PARSE("SpaceBeforeParens: NonEmptyParentheses", SpaceBeforeParens,
FormatStyle::SBPO_NonEmptyParentheses);
// For backward compatibility:
@@ -17631,6 +18186,9 @@ TEST_F(FormatTest, ParsesConfiguration) {
FormatStyle::SBPO_Never);
CHECK_PARSE("SpaceAfterControlStatementKeyword: true", SpaceBeforeParens,
FormatStyle::SBPO_ControlStatements);
+ CHECK_PARSE("SpaceBeforeParens: ControlStatementsExceptForEachMacros",
+ SpaceBeforeParens,
+ FormatStyle::SBPO_ControlStatementsExceptControlMacros);
Style.ColumnLimit = 123;
FormatStyle BaseStyle = getLLVMStyle();
@@ -17778,6 +18336,11 @@ TEST_F(FormatTest, ParsesConfiguration) {
CHECK_PARSE("ForEachMacros: [BOOST_FOREACH, Q_FOREACH]", ForEachMacros,
BoostAndQForeach);
+ Style.IfMacros.clear();
+ std::vector<std::string> CustomIfs;
+ CustomIfs.push_back("MYIF");
+ CHECK_PARSE("IfMacros: [MYIF]", IfMacros, CustomIfs);
+
Style.AttributeMacros.clear();
CHECK_PARSE("BasedOnStyle: LLVM", AttributeMacros,
std::vector<std::string>{"__capability"});
@@ -20463,11 +21026,16 @@ TEST_F(FormatTest, AmbersandInLamda) {
TEST_F(FormatTest, SpacesInConditionalStatement) {
FormatStyle Spaces = getLLVMStyle();
+ Spaces.IfMacros.clear();
+ Spaces.IfMacros.push_back("MYIF");
Spaces.SpacesInConditionalStatement = true;
verifyFormat("for ( int i = 0; i; i++ )\n continue;", Spaces);
verifyFormat("if ( !a )\n return;", Spaces);
verifyFormat("if ( a )\n return;", Spaces);
verifyFormat("if constexpr ( a )\n return;", Spaces);
+ verifyFormat("MYIF ( a )\n return;", Spaces);
+ verifyFormat("MYIF ( a )\n return;\nelse MYIF ( b )\n return;", Spaces);
+ verifyFormat("MYIF ( a )\n return;\nelse\n return;", Spaces);
verifyFormat("switch ( a )\ncase 1:\n return;", Spaces);
verifyFormat("while ( a )\n return;", Spaces);
verifyFormat("while ( (a && b) )\n return;", Spaces);
@@ -20476,6 +21044,13 @@ TEST_F(FormatTest, SpacesInConditionalStatement) {
// Check that space on the left of "::" is inserted as expected at beginning
// of condition.
verifyFormat("while ( ::func() )\n return;", Spaces);
+
+ // Check impact of ControlStatementsExceptControlMacros is honored.
+ Spaces.SpaceBeforeParens =
+ FormatStyle::SBPO_ControlStatementsExceptControlMacros;
+ verifyFormat("MYIF( a )\n return;", Spaces);
+ verifyFormat("MYIF( a )\n return;\nelse MYIF( b )\n return;", Spaces);
+ verifyFormat("MYIF( a )\n return;\nelse\n return;", Spaces);
}
TEST_F(FormatTest, AlternativeOperators) {
More information about the cfe-commits
mailing list