Skip to content

Commit

Permalink
[clang-format] TableGen keywords support. (#77477)
Browse files Browse the repository at this point in the history
Add TableGen keywords to the additional keyword list of the formatter.

This pull request is the splited part from
#76059 .
  • Loading branch information
hnakamura5 committed Jan 11, 2024
1 parent 2bb511e commit 0cc3157
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 0 deletions.
1 change: 1 addition & 0 deletions clang/include/clang/Format/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -3055,6 +3055,7 @@ struct FormatStyle {
bool isProto() const {
return Language == LK_Proto || Language == LK_TextProto;
}
bool isTableGen() const { return Language == LK_TableGen; }

/// Language, this format style is targeted at.
/// \version 3.5
Expand Down
75 changes: 75 additions & 0 deletions clang/lib/Format/FormatToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,21 @@ struct AdditionalKeywords {
kw_verilogHashHash = &IdentTable.get("##");
kw_apostrophe = &IdentTable.get("\'");

// TableGen keywords
kw_bit = &IdentTable.get("bit");
kw_bits = &IdentTable.get("bits");
kw_code = &IdentTable.get("code");
kw_dag = &IdentTable.get("dag");
kw_def = &IdentTable.get("def");
kw_defm = &IdentTable.get("defm");
kw_defset = &IdentTable.get("defset");
kw_defvar = &IdentTable.get("defvar");
kw_dump = &IdentTable.get("dump");
kw_include = &IdentTable.get("include");
kw_list = &IdentTable.get("list");
kw_multiclass = &IdentTable.get("multiclass");
kw_then = &IdentTable.get("then");

// Keep this at the end of the constructor to make sure everything here
// is
// already initialized.
Expand Down Expand Up @@ -1303,6 +1318,27 @@ struct AdditionalKeywords {
kw_wildcard, kw_wire,
kw_with, kw_wor,
kw_verilogHash, kw_verilogHashHash});

TableGenExtraKeywords = std::unordered_set<IdentifierInfo *>({
kw_assert,
kw_bit,
kw_bits,
kw_code,
kw_dag,
kw_def,
kw_defm,
kw_defset,
kw_defvar,
kw_dump,
kw_foreach,
kw_in,
kw_include,
kw_let,
kw_list,
kw_multiclass,
kw_string,
kw_then,
});
}

// Context sensitive keywords.
Expand Down Expand Up @@ -1548,6 +1584,21 @@ struct AdditionalKeywords {
// Symbols in Verilog that don't exist in C++.
IdentifierInfo *kw_apostrophe;

// TableGen keywords
IdentifierInfo *kw_bit;
IdentifierInfo *kw_bits;
IdentifierInfo *kw_code;
IdentifierInfo *kw_dag;
IdentifierInfo *kw_def;
IdentifierInfo *kw_defm;
IdentifierInfo *kw_defset;
IdentifierInfo *kw_defvar;
IdentifierInfo *kw_dump;
IdentifierInfo *kw_include;
IdentifierInfo *kw_list;
IdentifierInfo *kw_multiclass;
IdentifierInfo *kw_then;

/// Returns \c true if \p Tok is a keyword or an identifier.
bool isWordLike(const FormatToken &Tok) const {
// getIdentifierinfo returns non-null for keywords as well as identifiers.
Expand Down Expand Up @@ -1820,6 +1871,27 @@ struct AdditionalKeywords {
}
}

bool isTableGenDefinition(const FormatToken &Tok) const {
return Tok.isOneOf(kw_def, kw_defm, kw_defset, kw_defvar, kw_multiclass,
kw_let, tok::kw_class);
}

bool isTableGenKeyword(const FormatToken &Tok) const {
switch (Tok.Tok.getKind()) {
case tok::kw_class:
case tok::kw_else:
case tok::kw_false:
case tok::kw_if:
case tok::kw_int:
case tok::kw_true:
return true;
default:
return Tok.is(tok::identifier) &&
TableGenExtraKeywords.find(Tok.Tok.getIdentifierInfo()) !=
TableGenExtraKeywords.end();
}
}

private:
/// The JavaScript keywords beyond the C++ keyword set.
std::unordered_set<IdentifierInfo *> JsExtraKeywords;
Expand All @@ -1829,6 +1901,9 @@ struct AdditionalKeywords {

/// The Verilog keywords beyond the C++ keyword set.
std::unordered_set<IdentifierInfo *> VerilogExtraKeywords;

/// The TableGen keywords beyond the C++ keyword set.
std::unordered_set<IdentifierInfo *> TableGenExtraKeywords;
};

inline bool isLineComment(const FormatToken &FormatTok) {
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Format/FormatTokenLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1182,6 +1182,9 @@ FormatToken *FormatTokenLexer::getNextToken() {
tok::kw_operator)) {
FormatTok->Tok.setKind(tok::identifier);
FormatTok->Tok.setIdentifierInfo(nullptr);
} else if (Style.isTableGen() && !Keywords.isTableGenKeyword(*FormatTok)) {
FormatTok->Tok.setKind(tok::identifier);
FormatTok->Tok.setIdentifierInfo(nullptr);
}
} else if (FormatTok->is(tok::greatergreater)) {
FormatTok->Tok.setKind(tok::greater);
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Format/TokenAnnotator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2234,6 +2234,12 @@ class AnnotatingParser {
if (PreviousNotConst->ClosesRequiresClause)
return false;

if (Style.isTableGen()) {
// keywords such as let and def* defines names.
if (Keywords.isTableGenDefinition(*PreviousNotConst))
return true;
}

bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
PreviousNotConst->Previous &&
PreviousNotConst->Previous->is(tok::hash);
Expand Down
18 changes: 18 additions & 0 deletions clang/unittests/Format/TokenAnnotatorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2172,6 +2172,24 @@ TEST_F(TokenAnnotatorTest, UnderstandsVerilogOperators) {
EXPECT_TOKEN(Tokens[4], tok::string_literal, TT_Unknown);
}

TEST_F(TokenAnnotatorTest, UnderstandTableGenTokens) {
auto Style = getLLVMStyle(FormatStyle::LK_TableGen);
ASSERT_TRUE(Style.isTableGen());

TestLexer Lexer(Allocator, Buffers, Style);
AdditionalKeywords Keywords(Lexer.IdentTable);
auto Annotate = [&Lexer, &Style](llvm::StringRef Code) {
return Lexer.annotate(Code);
};

// Additional keywords representation test.
auto Tokens = Annotate("def foo : Bar<1>;");
ASSERT_TRUE(Keywords.isTableGenKeyword(*Tokens[0]));
ASSERT_TRUE(Keywords.isTableGenDefinition(*Tokens[0]));
ASSERT_TRUE(Tokens[0]->is(Keywords.kw_def));
ASSERT_TRUE(Tokens[1]->is(TT_StartOfName));
}

TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
auto Tokens = annotate("Class::Class() : BaseClass(), Member() {}");

Expand Down

0 comments on commit 0cc3157

Please sign in to comment.