diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 021d8c658eb11..3ca4ec7e1dda1 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -150,14 +150,14 @@ class AnnotatingParser {
if (!CurrentToken)
return false;
- auto *Left = CurrentToken->Previous; // The '<'.
+ auto *const Left = CurrentToken->Previous; // The '<'.
if (!Left)
return false;
if (NonTemplateLess.count(Left) > 0)
return false;
- const auto *BeforeLess = Left->Previous;
+ const auto *const BeforeLess = Left->Previous;
if (BeforeLess) {
if (BeforeLess->Tok.isLiteral())
@@ -206,8 +206,18 @@ class AnnotatingParser {
(!Next || Next->isNoneOf(tok::l_paren, tok::l_brace))) {
return false;
}
- if (!MaybeAngles)
- return false;
+ if (!MaybeAngles) {
+ const bool IsCommonCppTemplate =
+ (BeforeLess && BeforeLess->is(tok::identifier) &&
+ (BeforeLess->TokenText.ends_with("_t") ||
+ BeforeLess->TokenText.ends_with("_v"))) ||
+ (Next &&
+ Next->startsSequence(tok::coloncolon, tok::identifier) &&
+ (Next->Next->TokenText == "type" ||
+ Next->Next->TokenText == "value"));
+ if (!IsCommonCppTemplate)
+ return false;
+ }
}
Left->MatchingParen = CurrentToken;
CurrentToken->MatchingParen = Left;
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index c046142c613b0..8335cdade756a 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -799,6 +799,30 @@ TEST_F(TokenAnnotatorTest, UnderstandsTemplateTemplateParameters) {
EXPECT_TOKEN(Tokens[23], tok::identifier, TT_ClassHeadName);
}
+TEST_F(TokenAnnotatorTest, UnderstandsCommonCppTemplates) {
+ auto Tokens =
+ annotate("static_assert(std::conditional_t::value);");
+ ASSERT_EQ(Tokens.size(), 19u) << Tokens;
+ EXPECT_TOKEN(Tokens[5], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[13], tok::greater, TT_TemplateCloser);
+
+ Tokens =
+ annotate("static_assert(std::conditional::type::value);");
+ ASSERT_EQ(Tokens.size(), 21u) << Tokens;
+ EXPECT_TOKEN(Tokens[5], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[13], tok::greater, TT_TemplateCloser);
+
+ Tokens = annotate("static_assert(fancy_v);");
+ ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser);
+
+ Tokens = annotate("static_assert(fancy::value);");
+ ASSERT_EQ(Tokens.size(), 13u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::less, TT_TemplateOpener);
+ EXPECT_TOKEN(Tokens[7], tok::greater, TT_TemplateCloser);
+}
+
TEST_F(TokenAnnotatorTest, UnderstandsWhitespaceSensitiveMacros) {
FormatStyle Style = getLLVMStyle();
Style.WhitespaceSensitiveMacros.push_back("FOO");