Skip to content

Commit fcae75d

Browse files
committed
Restored FormatToken::isSimpleTypeSpecifier() and added
FormatToken::isTypeName(). Also added test cases for user-defined types.
1 parent 939f2f4 commit fcae75d

File tree

6 files changed

+48
-36
lines changed

6 files changed

+48
-36
lines changed

clang/lib/Format/FormatToken.cpp

+15-12
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,9 @@ const char *getTokenTypeName(TokenType Type) {
3434
return nullptr;
3535
}
3636

37-
// Sorted common C++ non-keyword types.
38-
static SmallVector<StringRef> CppNonKeywordTypes = {
39-
"int16_t", "int32_t", "int64_t", "int8_t", "intptr_t", "size_t",
40-
"uint16_t", "uint32_t", "uint64_t", "uint8_t", "uintptr_t",
41-
};
42-
4337
// FIXME: This is copy&pasted from Sema. Put it in a common place and remove
4438
// duplication.
45-
bool FormatToken::isSimpleTypeSpecifier(bool IsCpp) const {
39+
bool FormatToken::isSimpleTypeSpecifier() const {
4640
switch (Tok.getKind()) {
4741
case tok::kw_short:
4842
case tok::kw_long:
@@ -72,17 +66,26 @@ bool FormatToken::isSimpleTypeSpecifier(bool IsCpp) const {
7266
case tok::kw_decltype:
7367
case tok::kw__Atomic:
7468
return true;
75-
case tok::identifier:
76-
return IsCpp && std::binary_search(CppNonKeywordTypes.begin(),
77-
CppNonKeywordTypes.end(), TokenText);
7869
default:
7970
return false;
8071
}
8172
}
8273

74+
// Sorted common C++ non-keyword types.
75+
static SmallVector<StringRef> CppNonKeywordTypes = {
76+
"int16_t", "int32_t", "int64_t", "int8_t", "intptr_t", "size_t",
77+
"uint16_t", "uint32_t", "uint64_t", "uint8_t", "uintptr_t",
78+
};
79+
80+
bool FormatToken::isTypeName(bool IsCpp) const {
81+
return is(TT_TypeName) || isSimpleTypeSpecifier() ||
82+
(IsCpp && is(tok::identifier) &&
83+
std::binary_search(CppNonKeywordTypes.begin(),
84+
CppNonKeywordTypes.end(), TokenText));
85+
}
86+
8387
bool FormatToken::isTypeOrIdentifier(bool IsCpp) const {
84-
return isSimpleTypeSpecifier(IsCpp) ||
85-
Tok.isOneOf(tok::kw_auto, tok::identifier);
88+
return isTypeName(IsCpp) || Tok.isOneOf(tok::kw_auto, tok::identifier);
8689
}
8790

8891
bool FormatToken::isBlockIndentedInitRBrace(const FormatStyle &Style) const {

clang/lib/Format/FormatToken.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,9 @@ struct FormatToken {
674674
}
675675

676676
/// Determine whether the token is a simple-type-specifier.
677-
[[nodiscard]] bool isSimpleTypeSpecifier(bool IsCpp) const;
677+
[[nodiscard]] bool isSimpleTypeSpecifier() const;
678+
679+
[[nodiscard]] bool isTypeName(bool IsCpp) const;
678680

679681
[[nodiscard]] bool isTypeOrIdentifier(bool IsCpp) const;
680682

clang/lib/Format/QualifierAlignmentFixer.cpp

+6-7
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight(
274274
// The case `long const long int volatile` -> `long long int const volatile`
275275
// The case `long long volatile int const` -> `long long int const volatile`
276276
// The case `const long long volatile int` -> `long long int const volatile`
277-
if (TypeToken->isSimpleTypeSpecifier(IsCpp)) {
277+
if (TypeToken->isTypeName(IsCpp)) {
278278
// The case `const decltype(foo)` -> `const decltype(foo)`
279279
// The case `const typeof(foo)` -> `const typeof(foo)`
280280
// The case `const _Atomic(foo)` -> `const _Atomic(foo)`
@@ -295,7 +295,7 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight(
295295
// The case `unsigned short const` -> `unsigned short const`
296296
// The case:
297297
// `unsigned short volatile const` -> `unsigned short const volatile`
298-
if (PreviousCheck && PreviousCheck->isSimpleTypeSpecifier(IsCpp)) {
298+
if (PreviousCheck && PreviousCheck->isTypeName(IsCpp)) {
299299
if (LastQual != Tok)
300300
rotateTokens(SourceMgr, Fixes, Tok, LastQual, /*Left=*/false);
301301
return Tok;
@@ -412,8 +412,7 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft(
412412
// The case `volatile long long const int` -> `const volatile long long int`
413413
// The case `const long long volatile int` -> `const volatile long long int`
414414
// The case `long volatile long int const` -> `const volatile long long int`
415-
if (const bool IsCpp = Style.isCpp();
416-
TypeToken->isSimpleTypeSpecifier(IsCpp)) {
415+
if (const bool IsCpp = Style.isCpp(); TypeToken->isTypeName(IsCpp)) {
417416
const FormatToken *LastSimpleTypeSpecifier = TypeToken;
418417
while (isConfiguredQualifierOrType(
419418
LastSimpleTypeSpecifier->getPreviousNonComment(),
@@ -617,14 +616,14 @@ void prepareLeftRightOrderingForQualifierAlignmentFixer(
617616

618617
bool LeftRightQualifierAlignmentFixer::isQualifierOrType(
619618
const FormatToken *const Tok, bool IsCpp) {
620-
return Tok && (Tok->isSimpleTypeSpecifier(IsCpp) || Tok->is(tok::kw_auto) ||
621-
isQualifier(Tok));
619+
return Tok &&
620+
(Tok->isTypeName(IsCpp) || Tok->is(tok::kw_auto) || isQualifier(Tok));
622621
}
623622

624623
bool LeftRightQualifierAlignmentFixer::isConfiguredQualifierOrType(
625624
const FormatToken *const Tok, const std::vector<tok::TokenKind> &Qualifiers,
626625
bool IsCpp) {
627-
return Tok && (Tok->isSimpleTypeSpecifier(IsCpp) || Tok->is(tok::kw_auto) ||
626+
return Tok && (Tok->isTypeName(IsCpp) || Tok->is(tok::kw_auto) ||
628627
isConfiguredQualifier(Tok, Qualifiers));
629628
}
630629

clang/lib/Format/TokenAnnotator.cpp

+9-12
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ class AnnotatingParser {
562562
(CurrentToken->is(tok::l_paren) && CurrentToken->Next &&
563563
CurrentToken->Next->isOneOf(tok::star, tok::amp, tok::caret));
564564
if ((CurrentToken->Previous->isOneOf(tok::kw_const, tok::kw_auto) ||
565-
CurrentToken->Previous->isSimpleTypeSpecifier(IsCpp)) &&
565+
CurrentToken->Previous->isTypeName(IsCpp)) &&
566566
!(CurrentToken->is(tok::l_brace) ||
567567
(CurrentToken->is(tok::l_paren) && !ProbablyFunctionTypeLParen))) {
568568
Contexts.back().IsExpression = false;
@@ -2573,7 +2573,7 @@ class AnnotatingParser {
25732573
return true;
25742574

25752575
// MyClass a;
2576-
if (PreviousNotConst->isSimpleTypeSpecifier(IsCpp))
2576+
if (PreviousNotConst->isTypeName(IsCpp))
25772577
return true;
25782578

25792579
// type[] a in Java
@@ -2706,8 +2706,7 @@ class AnnotatingParser {
27062706
// Heuristically try to determine whether the parentheses contain a type.
27072707
auto IsQualifiedPointerOrReference = [this](FormatToken *T) {
27082708
// This is used to handle cases such as x = (foo *const)&y;
2709-
assert(!T->isSimpleTypeSpecifier(IsCpp) &&
2710-
"Should have already been checked");
2709+
assert(!T->isTypeName(IsCpp) && "Should have already been checked");
27112710
// Strip trailing qualifiers such as const or volatile when checking
27122711
// whether the parens could be a cast to a pointer/reference type.
27132712
while (T) {
@@ -2739,7 +2738,7 @@ class AnnotatingParser {
27392738
bool ParensAreType =
27402739
!Tok.Previous ||
27412740
Tok.Previous->isOneOf(TT_TemplateCloser, TT_TypeDeclarationParen) ||
2742-
Tok.Previous->isSimpleTypeSpecifier(IsCpp) ||
2741+
Tok.Previous->isTypeName(IsCpp) ||
27432742
IsQualifiedPointerOrReference(Tok.Previous);
27442743
bool ParensCouldEndDecl =
27452744
Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
@@ -3616,7 +3615,7 @@ static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current,
36163615
Next = Next->Next;
36173616
continue;
36183617
}
3619-
if ((Next->isSimpleTypeSpecifier(IsCpp) || Next->is(tok::identifier)) &&
3618+
if ((Next->isTypeName(IsCpp) || Next->is(tok::identifier)) &&
36203619
Next->Next && Next->Next->isPointerOrReference()) {
36213620
// For operator void*(), operator char*(), operator Foo*().
36223621
Next = Next->Next;
@@ -3714,9 +3713,8 @@ static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current,
37143713
Tok = Tok->MatchingParen;
37153714
continue;
37163715
}
3717-
if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier(IsCpp) ||
3718-
Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis,
3719-
TT_TypeName)) {
3716+
if (Tok->is(tok::kw_const) || Tok->isTypeName(IsCpp) ||
3717+
Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) {
37203718
return true;
37213719
}
37223720
if (Tok->isOneOf(tok::l_brace, TT_ObjCMethodExpr) || Tok->Tok.isLiteral())
@@ -4460,8 +4458,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
44604458
if (Right.isPointerOrReference()) {
44614459
const FormatToken *Previous = &Left;
44624460
while (Previous && Previous->isNot(tok::kw_operator)) {
4463-
if (Previous->is(tok::identifier) ||
4464-
Previous->isSimpleTypeSpecifier(IsCpp)) {
4461+
if (Previous->is(tok::identifier) || Previous->isTypeName(IsCpp)) {
44654462
Previous = Previous->getPreviousNonComment();
44664463
continue;
44674464
}
@@ -4650,7 +4647,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
46504647
if (!Style.isVerilog() &&
46514648
(Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
46524649
tok::r_paren) ||
4653-
Left.isSimpleTypeSpecifier(IsCpp)) &&
4650+
Left.isTypeName(IsCpp)) &&
46544651
Right.is(tok::l_brace) && Right.getNextNonComment() &&
46554652
Right.isNot(BK_Block)) {
46564653
return false;

clang/lib/Format/UnwrappedLineParser.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -1865,8 +1865,7 @@ void UnwrappedLineParser::parseStructuralElement(
18651865
case tok::caret:
18661866
nextToken();
18671867
// Block return type.
1868-
if (FormatTok->Tok.isAnyIdentifier() ||
1869-
FormatTok->isSimpleTypeSpecifier(IsCpp)) {
1868+
if (FormatTok->Tok.isAnyIdentifier() || FormatTok->isTypeName(IsCpp)) {
18701869
nextToken();
18711870
// Return types: pointers are ok too.
18721871
while (FormatTok->is(tok::star))
@@ -2222,7 +2221,7 @@ bool UnwrappedLineParser::tryToParseLambda() {
22222221
bool InTemplateParameterList = false;
22232222

22242223
while (FormatTok->isNot(tok::l_brace)) {
2225-
if (FormatTok->isSimpleTypeSpecifier(IsCpp)) {
2224+
if (FormatTok->isTypeName(IsCpp)) {
22262225
nextToken();
22272226
continue;
22282227
}
@@ -3478,7 +3477,7 @@ bool clang::format::UnwrappedLineParser::parseRequires() {
34783477
--OpenAngles;
34793478
break;
34803479
default:
3481-
if (NextToken->isSimpleTypeSpecifier(IsCpp)) {
3480+
if (NextToken->isTypeName(IsCpp)) {
34823481
FormatTok = Tokens->setPosition(StoredPosition);
34833482
parseRequiresExpression(RequiresToken);
34843483
return false;

clang/unittests/Format/TokenAnnotatorTest.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,18 @@ TEST_F(TokenAnnotatorTest, UnderstandsCasts) {
625625
ASSERT_EQ(Tokens.size(), 15u) << Tokens;
626626
EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_CastRParen);
627627
EXPECT_TOKEN(Tokens[11], tok::amp, TT_UnaryOperator);
628+
629+
Tokens = annotate("#define FOO(bar) foo((time_t) & bar)");
630+
ASSERT_EQ(Tokens.size(), 15u) << Tokens;
631+
EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_Unknown);
632+
EXPECT_TOKEN(Tokens[11], tok::amp, TT_BinaryOperator);
633+
634+
auto Style = getLLVMStyle();
635+
Style.TypeNames.push_back("time_t");
636+
Tokens = annotate("#define FOO(bar) foo((time_t)&bar)", Style);
637+
ASSERT_EQ(Tokens.size(), 15u) << Tokens;
638+
EXPECT_TOKEN(Tokens[10], tok::r_paren, TT_CastRParen);
639+
EXPECT_TOKEN(Tokens[11], tok::amp, TT_UnaryOperator);
628640
}
629641

630642
TEST_F(TokenAnnotatorTest, UnderstandsDynamicExceptionSpecifier) {

0 commit comments

Comments
 (0)