Skip to content

Commit 3f72b65

Browse files
committed
[Clang] Repair the functionrParenEndsCast to make incorrect judgments in template variable cases
1 parent db2307d commit 3f72b65

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "clang/Basic/SourceManager.h"
1818
#include "clang/Basic/TokenKinds.h"
1919
#include "llvm/ADT/SmallPtrSet.h"
20+
#include "llvm/ADT/SmallVector.h"
21+
#include "llvm/ADT/StringRef.h"
2022
#include "llvm/Support/Debug.h"
2123

2224
#define DEBUG_TYPE "format-token-annotator"
@@ -38,6 +40,10 @@ static bool mustBreakAfterAttributes(const FormatToken &Tok,
3840

3941
namespace {
4042

43+
// TODO: Add new Type modifiers
44+
llvm::SmallVector<llvm::StringRef> castIdentifiers{"__type_identity_t",
45+
"remove_reference_t"};
46+
4147
/// Returns \c true if the line starts with a token that can start a statement
4248
/// with an initializer.
4349
static bool startsWithInitStatement(const AnnotatedLine &Line) {
@@ -2474,6 +2480,11 @@ class AnnotatingParser {
24742480
Current.getNextNonComment()->isOneOf(tok::comma, tok::r_brace)) {
24752481
Current.setType(TT_StringInConcatenation);
24762482
}
2483+
} else if (Style.isCpp() && Current.is(tok::kw_using)) {
2484+
if (Current.Next && Current.Next->Next && Current.Next->Next->Next) {
2485+
if (Current.Next->Next->Next->isTypeName(LangOpts))
2486+
castIdentifiers.push_back(Current.Next->TokenText);
2487+
}
24772488
} else if (Current.is(tok::l_paren)) {
24782489
if (lParenStartsCppCast(Current))
24792490
Current.setType(TT_CppCastLParen);
@@ -2831,8 +2842,21 @@ class AnnotatingParser {
28312842
IsQualifiedPointerOrReference(BeforeRParen, LangOpts);
28322843
bool ParensCouldEndDecl =
28332844
AfterRParen->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
2834-
if (ParensAreType && !ParensCouldEndDecl)
2845+
if (ParensAreType && !ParensCouldEndDecl) {
2846+
if (BeforeRParen->is(TT_TemplateCloser)) {
2847+
if (determineUnaryOperatorByUsage(*AfterRParen))
2848+
return true;
2849+
if (AfterRParen->isOneOf(tok::plus, tok::minus, tok::star, tok::exclaim,
2850+
tok::amp)) {
2851+
auto *Prev = BeforeRParen->MatchingParen->getPreviousNonComment();
2852+
for (auto &name : castIdentifiers)
2853+
if (Prev->TokenText == name)
2854+
return true;
2855+
return false;
2856+
}
2857+
}
28352858
return true;
2859+
}
28362860

28372861
// At this point, we heuristically assume that there are no casts at the
28382862
// start of the line. We assume that we have found most cases where there

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,20 @@ TEST_F(TokenAnnotatorTest, UnderstandsCasts) {
752752
ASSERT_EQ(Tokens.size(), 11u) << Tokens;
753753
EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
754754

755+
Tokens = annotate("(std::__type_identity_t<int>)-2;");
756+
ASSERT_EQ(Tokens.size(), 12u) << Tokens;
757+
EXPECT_TOKEN(Tokens[7], tok::r_paren, TT_CastRParen);
758+
759+
Tokens = annotate("template <typename> using type = int;\n"
760+
"auto = (type<int>)+5;");
761+
ASSERT_EQ(Tokens.size(), 21u) << Tokens;
762+
EXPECT_TOKEN(Tokens[16], tok::r_paren, TT_CastRParen);
763+
764+
Tokens = annotate("template <class t> t c;"
765+
"auto = (c<int>) + 5;");
766+
ASSERT_EQ(Tokens.size(), 20u) << Tokens;
767+
EXPECT_TOKEN(Tokens[15], tok::r_paren, TT_Unknown);
768+
755769
Tokens = annotate("return (Foo)p;");
756770
ASSERT_EQ(Tokens.size(), 7u) << Tokens;
757771
EXPECT_TOKEN(Tokens[3], tok::r_paren, TT_CastRParen);

0 commit comments

Comments
 (0)