diff options
author | Wang Pengcheng <wangpengcheng.pp@bytedance.com> | 2024-02-02 17:41:47 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-02 17:41:47 +0800 |
commit | acf6811d0f2b6b453be46ddf7e046e1346991c98 (patch) | |
tree | fddddc4d1418a58062a8405a298a038712188742 /llvm/lib/TableGen | |
parent | 438fe1db09b0c20708ea1020519d8073c37feae8 (diff) | |
download | llvm-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.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/TableGen/TGLexer.h | 1 | ||||
-rw-r--r-- | llvm/lib/TableGen/TGParser.cpp | 54 | ||||
-rw-r--r-- | llvm/lib/TableGen/TGParser.h | 2 |
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); |