Skip to content

Commit

Permalink
Reland "[clang-format] Fix FormatToken::isSimpleTypeSpecifier() (#91712
Browse files Browse the repository at this point in the history
…)"

Remove FormatToken::isSimpleTypeSpecifier() and call
Token::isSimpleTypeSpecifier(LangOpts) instead.
  • Loading branch information
owenca committed May 14, 2024
1 parent 96c23af commit 364f988
Show file tree
Hide file tree
Showing 13 changed files with 116 additions and 127 deletions.
3 changes: 1 addition & 2 deletions clang/lib/Format/Format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3858,8 +3858,7 @@ LangOptions getFormattingLangOpts(const FormatStyle &Style) {
LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11;

LangOpts.LineComment = 1;
bool AlternativeOperators = Style.isCpp();
LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0;
LangOpts.CXXOperatorNames = Style.isCpp();
LangOpts.Bool = 1;
LangOpts.ObjC = 1;
LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally.
Expand Down
46 changes: 5 additions & 41 deletions clang/lib/Format/FormatToken.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,59 +34,23 @@ const char *getTokenTypeName(TokenType Type) {
return nullptr;
}

// FIXME: This is copy&pasted from Sema. Put it in a common place and remove
// duplication.
bool FormatToken::isSimpleTypeSpecifier() const {
switch (Tok.getKind()) {
case tok::kw_short:
case tok::kw_long:
case tok::kw___int64:
case tok::kw___int128:
case tok::kw_signed:
case tok::kw_unsigned:
case tok::kw_void:
case tok::kw_char:
case tok::kw_int:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
case tok::kw___bf16:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw___ibm128:
case tok::kw_wchar_t:
case tok::kw_bool:
#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
#include "clang/Basic/TransformTypeTraits.def"
case tok::annot_typename:
case tok::kw_char8_t:
case tok::kw_char16_t:
case tok::kw_char32_t:
case tok::kw_typeof:
case tok::kw_decltype:
case tok::kw__Atomic:
return true;
default:
return false;
}
}

// Sorted common C++ non-keyword types.
static SmallVector<StringRef> CppNonKeywordTypes = {
"clock_t", "int16_t", "int32_t", "int64_t", "int8_t",
"intptr_t", "ptrdiff_t", "size_t", "time_t", "uint16_t",
"uint32_t", "uint64_t", "uint8_t", "uintptr_t",
};

bool FormatToken::isTypeName(bool IsCpp) const {
return is(TT_TypeName) || isSimpleTypeSpecifier() ||
bool FormatToken::isTypeName(const LangOptions &LangOpts) const {
const bool IsCpp = LangOpts.CXXOperatorNames;
return is(TT_TypeName) || Tok.isSimpleTypeSpecifier(LangOpts) ||
(IsCpp && is(tok::identifier) &&
std::binary_search(CppNonKeywordTypes.begin(),
CppNonKeywordTypes.end(), TokenText));
}

bool FormatToken::isTypeOrIdentifier(bool IsCpp) const {
return isTypeName(IsCpp) || isOneOf(tok::kw_auto, tok::identifier);
bool FormatToken::isTypeOrIdentifier(const LangOptions &LangOpts) const {
return isTypeName(LangOpts) || isOneOf(tok::kw_auto, tok::identifier);
}

bool FormatToken::isBlockIndentedInitRBrace(const FormatStyle &Style) const {
Expand Down
8 changes: 2 additions & 6 deletions clang/lib/Format/FormatToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -684,12 +684,8 @@ struct FormatToken {
isAttribute();
}

/// Determine whether the token is a simple-type-specifier.
[[nodiscard]] bool isSimpleTypeSpecifier() const;

[[nodiscard]] bool isTypeName(bool IsCpp) const;

[[nodiscard]] bool isTypeOrIdentifier(bool IsCpp) const;
[[nodiscard]] bool isTypeName(const LangOptions &LangOpts) const;
[[nodiscard]] bool isTypeOrIdentifier(const LangOptions &LangOpts) const;

bool isObjCAccessSpecifier() const {
return is(tok::at) && Next &&
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Format/FormatTokenLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1442,7 +1442,6 @@ void FormatTokenLexer::readRawToken(FormatToken &Tok) {

void FormatTokenLexer::resetLexer(unsigned Offset) {
StringRef Buffer = SourceMgr.getBufferData(ID);
LangOpts = getFormattingLangOpts(Style);
Lex.reset(new Lexer(SourceMgr.getLocForStartOfFile(ID), LangOpts,
Buffer.begin(), Buffer.begin() + Offset, Buffer.end()));
Lex->SetKeepWhitespaceMode(true);
Expand Down
22 changes: 10 additions & 12 deletions clang/lib/Format/QualifierAlignmentFixer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,11 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight(
if (isPossibleMacro(TypeToken))
return Tok;

const bool IsCpp = Style.isCpp();

// The case `const long long int volatile` -> `long long int const volatile`
// The case `long const long int volatile` -> `long long int const volatile`
// The case `long long volatile int const` -> `long long int const volatile`
// The case `const long long volatile int` -> `long long int const volatile`
if (TypeToken->isTypeName(IsCpp)) {
if (TypeToken->isTypeName(LangOpts)) {
// The case `const decltype(foo)` -> `const decltype(foo)`
// The case `const typeof(foo)` -> `const typeof(foo)`
// The case `const _Atomic(foo)` -> `const _Atomic(foo)`
Expand All @@ -283,7 +281,7 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight(

const FormatToken *LastSimpleTypeSpecifier = TypeToken;
while (isQualifierOrType(LastSimpleTypeSpecifier->getNextNonComment(),
IsCpp)) {
LangOpts)) {
LastSimpleTypeSpecifier = LastSimpleTypeSpecifier->getNextNonComment();
}

Expand All @@ -295,7 +293,7 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeRight(
// The case `unsigned short const` -> `unsigned short const`
// The case:
// `unsigned short volatile const` -> `unsigned short const volatile`
if (PreviousCheck && PreviousCheck->isTypeName(IsCpp)) {
if (PreviousCheck && PreviousCheck->isTypeName(LangOpts)) {
if (LastQual != Tok)
rotateTokens(SourceMgr, Fixes, Tok, LastQual, /*Left=*/false);
return Tok;
Expand Down Expand Up @@ -412,11 +410,11 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft(
// The case `volatile long long const int` -> `const volatile long long int`
// The case `const long long volatile int` -> `const volatile long long int`
// The case `long volatile long int const` -> `const volatile long long int`
if (const bool IsCpp = Style.isCpp(); TypeToken->isTypeName(IsCpp)) {
if (TypeToken->isTypeName(LangOpts)) {
const FormatToken *LastSimpleTypeSpecifier = TypeToken;
while (isConfiguredQualifierOrType(
LastSimpleTypeSpecifier->getPreviousNonComment(),
ConfiguredQualifierTokens, IsCpp)) {
ConfiguredQualifierTokens, LangOpts)) {
LastSimpleTypeSpecifier =
LastSimpleTypeSpecifier->getPreviousNonComment();
}
Expand Down Expand Up @@ -614,15 +612,15 @@ void prepareLeftRightOrderingForQualifierAlignmentFixer(
}
}

bool isQualifierOrType(const FormatToken *Tok, bool IsCpp) {
return Tok &&
(Tok->isTypeName(IsCpp) || Tok->is(tok::kw_auto) || isQualifier(Tok));
bool isQualifierOrType(const FormatToken *Tok, const LangOptions &LangOpts) {
return Tok && (Tok->isTypeName(LangOpts) || Tok->is(tok::kw_auto) ||
isQualifier(Tok));
}

bool isConfiguredQualifierOrType(const FormatToken *Tok,
const std::vector<tok::TokenKind> &Qualifiers,
bool IsCpp) {
return Tok && (Tok->isTypeName(IsCpp) || Tok->is(tok::kw_auto) ||
const LangOptions &LangOpts) {
return Tok && (Tok->isTypeName(LangOpts) || Tok->is(tok::kw_auto) ||
isConfiguredQualifier(Tok, Qualifiers));
}

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Format/QualifierAlignmentFixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ void prepareLeftRightOrderingForQualifierAlignmentFixer(
std::vector<tok::TokenKind> &Qualifiers);

// Is the Token a simple or qualifier type
bool isQualifierOrType(const FormatToken *Tok, bool IsCpp = true);
bool isQualifierOrType(const FormatToken *Tok, const LangOptions &LangOpts);
bool isConfiguredQualifierOrType(const FormatToken *Tok,
const std::vector<tok::TokenKind> &Qualifiers,
bool IsCpp = true);
const LangOptions &LangOpts);

// Is the Token likely a Macro
bool isPossibleMacro(const FormatToken *Tok);
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Format/TokenAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Environment::Environment(StringRef Code, StringRef FileName,
NextStartColumn(NextStartColumn), LastStartColumn(LastStartColumn) {}

TokenAnalyzer::TokenAnalyzer(const Environment &Env, const FormatStyle &Style)
: Style(Style), Env(Env),
: Style(Style), LangOpts(getFormattingLangOpts(Style)), Env(Env),
AffectedRangeMgr(Env.getSourceManager(), Env.getCharRanges()),
UnwrappedLines(1),
Encoding(encoding::detectEncoding(
Expand All @@ -101,7 +101,7 @@ std::pair<tooling::Replacements, unsigned>
TokenAnalyzer::process(bool SkipAnnotation) {
tooling::Replacements Result;
llvm::SpecificBumpPtrAllocator<FormatToken> Allocator;
IdentifierTable IdentTable(getFormattingLangOpts(Style));
IdentifierTable IdentTable(LangOpts);
FormatTokenLexer Lex(Env.getSourceManager(), Env.getFileID(),
Env.getFirstStartColumn(), Style, Encoding, Allocator,
IdentTable);
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Format/TokenAnalyzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class TokenAnalyzer : public UnwrappedLineConsumer {
void finishRun() override;

FormatStyle Style;
LangOptions LangOpts;
// Stores Style, FileID and SourceManager etc.
const Environment &Env;
// AffectedRangeMgr stores ranges to be fixed.
Expand Down
43 changes: 25 additions & 18 deletions clang/lib/Format/TokenAnnotator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ class AnnotatingParser {
const AdditionalKeywords &Keywords,
SmallVector<ScopeType> &Scopes)
: Style(Style), Line(Line), CurrentToken(Line.First), AutoFound(false),
IsCpp(Style.isCpp()), Keywords(Keywords), Scopes(Scopes) {
IsCpp(Style.isCpp()), LangOpts(getFormattingLangOpts(Style)),
Keywords(Keywords), Scopes(Scopes) {
assert(IsCpp == LangOpts.CXXOperatorNames);
Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false));
resetTokenMetadata();
}
Expand Down Expand Up @@ -562,7 +564,7 @@ class AnnotatingParser {
(CurrentToken->is(tok::l_paren) && CurrentToken->Next &&
CurrentToken->Next->isOneOf(tok::star, tok::amp, tok::caret));
if ((CurrentToken->Previous->isOneOf(tok::kw_const, tok::kw_auto) ||
CurrentToken->Previous->isTypeName(IsCpp)) &&
CurrentToken->Previous->isTypeName(LangOpts)) &&
!(CurrentToken->is(tok::l_brace) ||
(CurrentToken->is(tok::l_paren) && !ProbablyFunctionTypeLParen))) {
Contexts.back().IsExpression = false;
Expand Down Expand Up @@ -2624,7 +2626,7 @@ class AnnotatingParser {
return true;

// MyClass a;
if (PreviousNotConst->isTypeName(IsCpp))
if (PreviousNotConst->isTypeName(LangOpts))
return true;

// type[] a in Java
Expand Down Expand Up @@ -2728,7 +2730,7 @@ class AnnotatingParser {
}

if (Tok.Next->is(tok::question) ||
(Tok.Next->is(tok::ampamp) && !Tok.Previous->isTypeName(IsCpp))) {
(Tok.Next->is(tok::ampamp) && !Tok.Previous->isTypeName(LangOpts))) {
return false;
}

Expand Down Expand Up @@ -2757,9 +2759,10 @@ class AnnotatingParser {
}

// Heuristically try to determine whether the parentheses contain a type.
auto IsQualifiedPointerOrReference = [](FormatToken *T, bool IsCpp) {
auto IsQualifiedPointerOrReference = [](FormatToken *T,
const LangOptions &LangOpts) {
// This is used to handle cases such as x = (foo *const)&y;
assert(!T->isTypeName(IsCpp) && "Should have already been checked");
assert(!T->isTypeName(LangOpts) && "Should have already been checked");
// Strip trailing qualifiers such as const or volatile when checking
// whether the parens could be a cast to a pointer/reference type.
while (T) {
Expand Down Expand Up @@ -2791,8 +2794,8 @@ class AnnotatingParser {
bool ParensAreType =
!Tok.Previous ||
Tok.Previous->isOneOf(TT_TemplateCloser, TT_TypeDeclarationParen) ||
Tok.Previous->isTypeName(IsCpp) ||
IsQualifiedPointerOrReference(Tok.Previous, IsCpp);
Tok.Previous->isTypeName(LangOpts) ||
IsQualifiedPointerOrReference(Tok.Previous, LangOpts);
bool ParensCouldEndDecl =
Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace, tok::greater);
if (ParensAreType && !ParensCouldEndDecl)
Expand Down Expand Up @@ -3065,6 +3068,7 @@ class AnnotatingParser {
FormatToken *CurrentToken;
bool AutoFound;
bool IsCpp;
LangOptions LangOpts;
const AdditionalKeywords &Keywords;

SmallVector<ScopeType> &Scopes;
Expand Down Expand Up @@ -3639,7 +3643,8 @@ void TokenAnnotator::annotate(AnnotatedLine &Line) {

// This function heuristically determines whether 'Current' starts the name of a
// function declaration.
static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current,
static bool isFunctionDeclarationName(const LangOptions &LangOpts,
const FormatToken &Current,
const AnnotatedLine &Line,
FormatToken *&ClosingParen) {
assert(Current.Previous);
Expand All @@ -3658,7 +3663,7 @@ static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current,
}

auto skipOperatorName =
[IsCpp](const FormatToken *Next) -> const FormatToken * {
[&LangOpts](const FormatToken *Next) -> const FormatToken * {
for (; Next; Next = Next->Next) {
if (Next->is(TT_OverloadedOperatorLParen))
return Next;
Expand All @@ -3677,7 +3682,7 @@ static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current,
Next = Next->Next;
continue;
}
if ((Next->isTypeName(IsCpp) || Next->is(tok::identifier)) &&
if ((Next->isTypeName(LangOpts) || Next->is(tok::identifier)) &&
Next->Next && Next->Next->isPointerOrReference()) {
// For operator void*(), operator char*(), operator Foo*().
Next = Next->Next;
Expand All @@ -3693,8 +3698,10 @@ static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current,
return nullptr;
};

const auto *Next = Current.Next;
const bool IsCpp = LangOpts.CXXOperatorNames;

// Find parentheses of parameter list.
const FormatToken *Next = Current.Next;
if (Current.is(tok::kw_operator)) {
if (Previous.Tok.getIdentifierInfo() &&
!Previous.isOneOf(tok::kw_return, tok::kw_co_return)) {
Expand Down Expand Up @@ -3774,7 +3781,7 @@ static bool isFunctionDeclarationName(bool IsCpp, const FormatToken &Current,
Tok = Tok->MatchingParen;
continue;
}
if (Tok->is(tok::kw_const) || Tok->isTypeName(IsCpp) ||
if (Tok->is(tok::kw_const) || Tok->isTypeName(LangOpts) ||
Tok->isOneOf(TT_PointerOrReference, TT_StartOfName, tok::ellipsis)) {
return true;
}
Expand Down Expand Up @@ -3837,7 +3844,7 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const {
AfterLastAttribute = Tok;
if (const bool IsCtorOrDtor = Tok->is(TT_CtorDtorDeclName);
IsCtorOrDtor ||
isFunctionDeclarationName(IsCpp, *Tok, Line, ClosingParen)) {
isFunctionDeclarationName(LangOpts, *Tok, Line, ClosingParen)) {
if (!IsCtorOrDtor)
Tok->setFinalizedType(TT_FunctionDeclarationName);
LineIsFunctionDeclaration = true;
Expand Down Expand Up @@ -4447,7 +4454,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
if (Left.Tok.isLiteral())
return true;
// for (auto a = 0, b = 0; const auto & c : {1, 2, 3})
if (Left.isTypeOrIdentifier(IsCpp) && Right.Next && Right.Next->Next &&
if (Left.isTypeOrIdentifier(LangOpts) && Right.Next && Right.Next->Next &&
Right.Next->Next->is(TT_RangeBasedForLoopColon)) {
return getTokenPointerOrReferenceAlignment(Right) !=
FormatStyle::PAS_Left;
Expand Down Expand Up @@ -4490,7 +4497,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
if (Right.is(tok::l_brace) && Right.is(BK_Block))
return true;
// for (auto a = 0, b = 0; const auto& c : {1, 2, 3})
if (BeforeLeft && BeforeLeft->isTypeOrIdentifier(IsCpp) && Right.Next &&
if (BeforeLeft && BeforeLeft->isTypeOrIdentifier(LangOpts) && Right.Next &&
Right.Next->is(TT_RangeBasedForLoopColon)) {
return getTokenPointerOrReferenceAlignment(Left) !=
FormatStyle::PAS_Right;
Expand Down Expand Up @@ -4534,7 +4541,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
if (Right.isPointerOrReference()) {
const FormatToken *Previous = &Left;
while (Previous && Previous->isNot(tok::kw_operator)) {
if (Previous->is(tok::identifier) || Previous->isTypeName(IsCpp)) {
if (Previous->is(tok::identifier) || Previous->isTypeName(LangOpts)) {
Previous = Previous->getPreviousNonComment();
continue;
}
Expand Down Expand Up @@ -4723,7 +4730,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
if (!Style.isVerilog() &&
(Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
tok::r_paren) ||
Left.isTypeName(IsCpp)) &&
Left.isTypeName(LangOpts)) &&
Right.is(tok::l_brace) && Right.getNextNonComment() &&
Right.isNot(BK_Block)) {
return false;
Expand Down
6 changes: 5 additions & 1 deletion clang/lib/Format/TokenAnnotator.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,10 @@ class AnnotatedLine {
class TokenAnnotator {
public:
TokenAnnotator(const FormatStyle &Style, const AdditionalKeywords &Keywords)
: Style(Style), IsCpp(Style.isCpp()), Keywords(Keywords) {}
: Style(Style), IsCpp(Style.isCpp()),
LangOpts(getFormattingLangOpts(Style)), Keywords(Keywords) {
assert(IsCpp == LangOpts.CXXOperatorNames);
}

/// Adapts the indent levels of comment lines to the indent of the
/// subsequent line.
Expand Down Expand Up @@ -260,6 +263,7 @@ class TokenAnnotator {
const FormatStyle &Style;

bool IsCpp;
LangOptions LangOpts;

const AdditionalKeywords &Keywords;

Expand Down
Loading

0 comments on commit 364f988

Please sign in to comment.