aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/TableGen
diff options
context:
space:
mode:
authorWang Pengcheng <wangpengcheng.pp@bytedance.com>2024-02-02 17:41:47 +0800
committerGitHub <noreply@github.com>2024-02-02 17:41:47 +0800
commitacf6811d0f2b6b453be46ddf7e046e1346991c98 (patch)
treefddddc4d1418a58062a8405a298a038712188742 /llvm/lib/TableGen
parent438fe1db09b0c20708ea1020519d8073c37feae8 (diff)
downloadllvm-acf6811d0f2b6b453be46ddf7e046e1346991c98.zip
llvm-acf6811d0f2b6b453be46ddf7e046e1346991c98.tar.gz
llvm-acf6811d0f2b6b453be46ddf7e046e1346991c98.tar.bz2
[TableGen] Support type aliases via new keyword deftype
We can use `deftype` (not using `typedef` here to be consistent with `def`, `defm`, `defset`, `defvar`, etc) to define type aliases. Currently, only primitive types and type aliases are supported to be the source type and `deftype` statements can only appear at the top level. Reviewers: fpetrogalli, Artem-B, nhaehnle, jroelofs Reviewed By: jroelofs, nhaehnle, Artem-B Pull Request: https://github.com/llvm/llvm-project/pull/79570
Diffstat (limited to 'llvm/lib/TableGen')
-rw-r--r--llvm/lib/TableGen/TGLexer.cpp1
-rw-r--r--llvm/lib/TableGen/TGLexer.h1
-rw-r--r--llvm/lib/TableGen/TGParser.cpp54
-rw-r--r--llvm/lib/TableGen/TGParser.h2
4 files changed, 56 insertions, 2 deletions
diff --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index c811a67d..5456432 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ b/llvm/lib/TableGen/TGLexer.cpp
@@ -360,6 +360,7 @@ tgtok::TokKind TGLexer::LexIdentifier() {
.Case("foreach", tgtok::Foreach)
.Case("defm", tgtok::Defm)
.Case("defset", tgtok::Defset)
+ .Case("deftype", tgtok::Deftype)
.Case("multiclass", tgtok::MultiClass)
.Case("field", tgtok::Field)
.Case("let", tgtok::Let)
diff --git a/llvm/lib/TableGen/TGLexer.h b/llvm/lib/TableGen/TGLexer.h
index 2e2aa59..25dcd9f 100644
--- a/llvm/lib/TableGen/TGLexer.h
+++ b/llvm/lib/TableGen/TGLexer.h
@@ -97,6 +97,7 @@ enum TokKind {
Def,
Defm,
Defset,
+ Deftype,
Defvar,
Dump,
Foreach,
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index e7dcb91..f899fdb 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -1103,11 +1103,17 @@ RecTy *TGParser::ParseType() {
case tgtok::Dag:
Lex.Lex();
return DagRecTy::get(Records);
- case tgtok::Id:
+ case tgtok::Id: {
+ auto I = TypeAliases.find(Lex.getCurStrVal());
+ if (I != TypeAliases.end()) {
+ Lex.Lex();
+ return I->second;
+ }
if (Record *R = ParseClassID())
return RecordRecTy::get(R);
TokError("unknown class name");
return nullptr;
+ }
case tgtok::Bits: {
if (Lex.Lex() != tgtok::less) { // Eat 'bits'
TokError("expected '<' after bits type");
@@ -3665,6 +3671,42 @@ bool TGParser::ParseDefset() {
return false;
}
+/// ParseDeftype - Parse a defvar statement.
+///
+/// Deftype ::= DEFTYPE Id '=' Type ';'
+///
+bool TGParser::ParseDeftype() {
+ assert(Lex.getCode() == tgtok::Deftype);
+ Lex.Lex(); // Eat the 'deftype' token
+
+ if (Lex.getCode() != tgtok::Id)
+ return TokError("expected identifier");
+
+ const std::string TypeName = Lex.getCurStrVal();
+ if (TypeAliases.count(TypeName) || Records.getClass(TypeName))
+ return TokError("type of this name '" + TypeName + "' already exists");
+
+ Lex.Lex();
+ if (!consume(tgtok::equal))
+ return TokError("expected '='");
+
+ SMLoc Loc = Lex.getLoc();
+ RecTy *Type = ParseType();
+ if (!Type)
+ return true;
+
+ if (Type->getRecTyKind() == RecTy::RecordRecTyKind)
+ return Error(Loc, "cannot define type alias for class type '" +
+ Type->getAsString() + "'");
+
+ TypeAliases[TypeName] = Type;
+
+ if (!consume(tgtok::semi))
+ return TokError("expected ';'");
+
+ return false;
+}
+
/// ParseDefvar - Parse a defvar statement.
///
/// Defvar ::= DEFVAR Id '=' Value ';'
@@ -3914,7 +3956,8 @@ bool TGParser::ParseClass() {
if (Lex.getCode() != tgtok::Id)
return TokError("expected class name after 'class' keyword");
- Record *CurRec = Records.getClass(Lex.getCurStrVal());
+ const std::string &Name = Lex.getCurStrVal();
+ Record *CurRec = Records.getClass(Name);
if (CurRec) {
// If the body was previously defined, this is an error.
if (!CurRec->getValues().empty() ||
@@ -3931,6 +3974,10 @@ bool TGParser::ParseClass() {
CurRec = NewRec.get();
Records.addClass(std::move(NewRec));
}
+
+ if (TypeAliases.count(Name))
+ return TokError("there is already a defined type alias '" + Name + "'");
+
Lex.Lex(); // eat the name.
// A class definition introduces a new scope.
@@ -4265,6 +4312,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
/// Object ::= LETCommand '{' ObjectList '}'
/// Object ::= LETCommand Object
/// Object ::= Defset
+/// Object ::= Deftype
/// Object ::= Defvar
/// Object ::= Assert
/// Object ::= Dump
@@ -4276,6 +4324,8 @@ bool TGParser::ParseObject(MultiClass *MC) {
case tgtok::Assert: return ParseAssert(MC);
case tgtok::Def: return ParseDef(MC);
case tgtok::Defm: return ParseDefm(MC);
+ case tgtok::Deftype:
+ return ParseDeftype();
case tgtok::Defvar: return ParseDefvar();
case tgtok::Dump:
return ParseDump(MC);
diff --git a/llvm/lib/TableGen/TGParser.h b/llvm/lib/TableGen/TGParser.h
index 0929154..b08e250 100644
--- a/llvm/lib/TableGen/TGParser.h
+++ b/llvm/lib/TableGen/TGParser.h
@@ -143,6 +143,7 @@ class TGParser {
TGLexer Lex;
std::vector<SmallVector<LetRecord, 4>> LetStack;
std::map<std::string, std::unique_ptr<MultiClass>> MultiClasses;
+ std::map<std::string, RecTy *> TypeAliases;
/// Loops - Keep track of any foreach loops we are within.
///
@@ -264,6 +265,7 @@ private: // Parser methods.
bool ParseDefm(MultiClass *CurMultiClass);
bool ParseDef(MultiClass *CurMultiClass);
bool ParseDefset();
+ bool ParseDeftype();
bool ParseDefvar(Record *CurRec = nullptr);
bool ParseDump(MultiClass *CurMultiClass, Record *CurRec = nullptr);
bool ParseForeach(MultiClass *CurMultiClass);