-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[clang-format] Allow ternary in all templates #96801
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Currently, question mark and colon tokens are not allowed between angle brackets, as a template argument, if we are in an expression context. However, expressions can still allowed in non-expression contexts, leading to inconsitent formatting. Removing this check entirely fixes this issue, and, surprisingly, breaks no tests. Fixes llvm#81385
@llvm/pr-subscribers-clang-format Author: Emilia Kond (rymiel) ChangesCurrently, question mark and colon tokens are not allowed between angle brackets, as a template argument, if we are in an expression context. However, expressions can still allowed in non-expression contexts, leading to inconsistent formatting. Removing this check entirely fixes this issue, and, surprisingly, breaks no tests. Fixes #81385 Full diff: https://github.com/llvm/llvm-project/pull/96801.diff 2 Files Affected:
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 89e134144d433..03082cd2742c8 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -176,10 +176,6 @@ class AnnotatingParser {
Left->ParentBracket = Contexts.back().ContextKind;
ScopedContextCreator ContextCreator(*this, tok::less, 12);
- // If this angle is in the context of an expression, we need to be more
- // hesitant to detect it as opening template parameters.
- bool InExprContext = Contexts.back().IsExpression;
-
Contexts.back().IsExpression = false;
// If there's a template keyword before the opening angle bracket, this is a
// template parameter, not an argument.
@@ -231,11 +227,8 @@ class AnnotatingParser {
next();
continue;
}
- if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace) ||
- (CurrentToken->isOneOf(tok::colon, tok::question) && InExprContext &&
- !Style.isCSharp() && !Style.isProto())) {
+ if (CurrentToken->isOneOf(tok::r_paren, tok::r_square, tok::r_brace))
return false;
- }
// If a && or || is found and interpreted as a binary operator, this set
// of angles is likely part of something like "a < b && c > d". If the
// angles are inside an expression, the ||/&& might also be a binary
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index d3b310fe59527..5d83d8a0c4429 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -567,6 +567,24 @@ TEST_F(TokenAnnotatorTest, UnderstandsGreaterAfterTemplateCloser) {
EXPECT_TOKEN(Tokens[8], tok::greater, TT_BinaryOperator);
}
+TEST_F(TokenAnnotatorTest, UnderstandsTernaryInTemplate) {
+ // IsExpression = false
+ auto Tokens = annotate("foo<true ? 1 : 2>();");
+ ASSERT_EQ(Tokens.size(), 12u) << Tokens;
+ EXPECT_TOKEN(Tokens[1], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[3], tok::question, TT_ConditionalExpr);
+ EXPECT_TOKEN(Tokens[5], tok::colon, TT_ConditionalExpr);
+ EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser);
+
+ // IsExpression = true
+ Tokens = annotate("return foo<true ? 1 : 2>();");
+ ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+ EXPECT_TOKEN(Tokens[2], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[4], tok::question, TT_ConditionalExpr);
+ EXPECT_TOKEN(Tokens[6], tok::colon, TT_ConditionalExpr);
+ EXPECT_TOKEN(Tokens[8], tok::greater, TT_TemplateCloser);
+}
+
TEST_F(TokenAnnotatorTest, UnderstandsNonTemplateAngleBrackets) {
auto Tokens = annotate("return a < b && c > d;");
ASSERT_EQ(Tokens.size(), 10u) << Tokens;
|
I'm not even sure if this change is a good idea! I think it's very likely it will lead to regressions, for we don't have tests for such cases yet, it seems |
I'm sure you will look after them, so I'd say let them come. ;) |
Currently, question mark and colon tokens are not allowed between angle brackets, as a template argument, if we are in an expression context. However, expressions can still allowed in non-expression contexts, leading to inconsistent formatting. Removing this check entirely fixes this issue, and, surprisingly, breaks no tests. Fixes llvm#81385
Currently, question mark and colon tokens are not allowed between angle brackets, as a template argument, if we are in an expression context.
However, expressions can still allowed in non-expression contexts, leading to inconsistent formatting.
Removing this check entirely fixes this issue, and, surprisingly, breaks no tests.
Fixes #81385