diff --git a/src/mapleall/maple_ir/BUILD.gn b/src/mapleall/maple_ir/BUILD.gn index e9d028ba0e36fa39f3b7e43466e61a261f29fe07..4f0428f9cfaeea788214d9682265a4ace29ec1f9 100755 --- a/src/mapleall/maple_ir/BUILD.gn +++ b/src/mapleall/maple_ir/BUILD.gn @@ -43,6 +43,7 @@ src_libmplir = [ "src/mir_nodes.cpp", "src/mir_symbol.cpp", "src/mir_type.cpp", + "src/mir_enumeration.cpp", "src/opcode_info.cpp", "src/option.cpp", "src/mpl2mpl_options.cpp", diff --git a/src/mapleall/maple_ir/include/bin_mpl_export.h b/src/mapleall/maple_ir/include/bin_mpl_export.h index e24638b8bed21bb8ecf059bab22e6ce85e6c6f00..68258f3b6aadb605af8992646079d29d1bdca63b 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_export.h +++ b/src/mapleall/maple_ir/include/bin_mpl_export.h @@ -18,6 +18,7 @@ #include "mir_nodes.h" #include "mir_function.h" #include "mir_preg.h" +#include "mir_enumeration.h" #include "parser_opt.h" #include "ea_connection_graph.h" @@ -67,8 +68,8 @@ enum : uint8 { kBinEaCgStart = 41, kBinEaStart = 42, kBinNodeBlock = 43, -// kBinOpStatement : 44, -// kBinOpExpression : 45, + kBinEnumeration = 44, + kBinEnumStart = 45, kBinReturnvals = 46, kBinTypeTabStart = 47, kBinSymStart = 48, @@ -125,6 +126,7 @@ class BinaryMplExport { void OutputPragmaVec(const std::vector &pragmaVec); void OutputClassTypeData(const MIRClassType &type); void OutputSymbol(MIRSymbol *sym); + void OutputEnumeration(MIREnum *mirEnum); void OutputFunction(PUIdx puIdx); void OutputInterfaceTypeData(const MIRInterfaceType &type); void OutputSrcPos(const SrcPosition &pos); @@ -179,6 +181,7 @@ class BinaryMplExport { void DumpBuf(const std::string &name); void AppendAt(const std::string &name, int32 offset); void ExpandFourBuffSize(); + void WriteEnumField(uint64 contentIdx); MIRModule &mod; size_t bufI = 0; diff --git a/src/mapleall/maple_ir/include/bin_mpl_import.h b/src/mapleall/maple_ir/include/bin_mpl_import.h index fe4f53d38713c45f80b515e04d0a4537e78a8f90..bc3ba10fb8fbe9c3e4ae0330c8c438e3eee64e03 100644 --- a/src/mapleall/maple_ir/include/bin_mpl_import.h +++ b/src/mapleall/maple_ir/include/bin_mpl_import.h @@ -126,6 +126,7 @@ class BinaryMplImport { void ImportInfoVector(MIRInfoVector &infoVector, MapleVector &infoVectorIsString); void ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab); void ImportFuncIdInfo(MIRFunction *func); + void ImportEnumeration(); MIRSymbol *ImportLocalSymbol(MIRFunction *func); PregIdx ImportPreg(MIRFunction *func); LabelIdx ImportLabel(MIRFunction *func); @@ -138,6 +139,7 @@ class BinaryMplImport { void ImportReturnValues(MIRFunction *func, CallReturnVector *retv); BlockNode *ImportBlockNode(MIRFunction *func); void ReadFunctionBodyField(); + void ReadEnumField(); void ReadFileAt(const std::string &name, int32 offset); uint8 Read(); int64 ReadInt64(); diff --git a/src/mapleall/maple_ir/include/global_tables.h b/src/mapleall/maple_ir/include/global_tables.h index 492cadf8827e073ba8e314de7a5e5e0ea05c961f..0f2078b5aba84fd063bb0e4ad23eb665b30e8653 100644 --- a/src/mapleall/maple_ir/include/global_tables.h +++ b/src/mapleall/maple_ir/include/global_tables.h @@ -28,6 +28,7 @@ #include "namemangler.h" #include "mir_type.h" #include "mir_const.h" +#include "mir_enumeration.h" namespace maple { using TyIdxFieldAttrPair = std::pair; @@ -838,6 +839,10 @@ class GlobalTables { return *(globalTables.intConstTablePtr); } + static EnumTable &GetEnumTable() { + return globalTables.enumTable; + } + GlobalTables(const GlobalTables &globalTables) = delete; GlobalTables(const GlobalTables &&globalTables) = delete; GlobalTables &operator=(const GlobalTables &globalTables) = delete; @@ -863,6 +868,7 @@ class GlobalTables { StringTable gStringTable; StringTable uStrTable; StringTable u16StringTable; + EnumTable enumTable; }; inline MIRType &GetTypeFromTyIdx(TyIdx idx) { diff --git a/src/mapleall/maple_ir/include/keywords.def b/src/mapleall/maple_ir/include/keywords.def index ad4d20d229895352461c5b841c16fd61267b0f21..6fe8262fcdf2c2b23c8089287e26f98f9101f7a9 100644 --- a/src/mapleall/maple_ir/include/keywords.def +++ b/src/mapleall/maple_ir/include/keywords.def @@ -32,6 +32,7 @@ KEYWORD(tempvar) KEYWORD(reg) KEYWORD(type) + KEYWORD(enumeration) KEYWORD(func) KEYWORD(struct) KEYWORD(structincomplete) diff --git a/src/mapleall/maple_ir/include/mir_enumeration.h b/src/mapleall/maple_ir/include/mir_enumeration.h new file mode 100644 index 0000000000000000000000000000000000000000..8c90f960bcdc33bede8f489cad645c9042f8f608 --- /dev/null +++ b/src/mapleall/maple_ir/include/mir_enumeration.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) [2022] Futurewei Technologies, Inc. All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#ifndef MAPLEIR_INCLUDE_MIR_ENUMERATION_H +#define MAPLEIR_INCLUDE_MIR_ENUMERATION_H + +namespace maple { + +using EnumElem = std::pair; +class MIREnum { + public: + explicit MIREnum(PrimType ptyp, GStrIdx stridx): primType(ptyp), nameStrIdx(stridx) {} + ~MIREnum() = default; + + void NewElement(GStrIdx sidx, IntVal value) { + elements.push_back(EnumElem(sidx, value)); + } + void AddNextElement(GStrIdx sidx) { + if (elements.empty()) { + elements.push_back(EnumElem(sidx, IntVal(0, primType))); + return; + } + IntVal newValue = elements.back().second + 1; + elements.push_back(EnumElem(sidx, newValue)); + } + const std::string &GetName() const; + void Dump() const; + + public: + PrimType primType = PTY_i32; // must be integer primtype + GStrIdx nameStrIdx{ 0 }; // name of this enum in global string table + std::vector elements{}; +}; + +struct EnumTable { + std::vector enumTable; + void Dump() { + for (MIREnum *mirEnum : enumTable) { + mirEnum->Dump(); + } + } +}; + +} /* namespace maple */ + +#endif /* MAPLEIR_INCLUDE_MIR_ENUMERATION_H */ diff --git a/src/mapleall/maple_ir/include/mir_parser.h b/src/mapleall/maple_ir/include/mir_parser.h index c68bec143811dff0c442f300208b1ce04237904f..3a1305f522af72748068f5b33b013f9aa185d7ea 100755 --- a/src/mapleall/maple_ir/include/mir_parser.h +++ b/src/mapleall/maple_ir/include/mir_parser.h @@ -95,6 +95,7 @@ class MIRParser { bool ParseGenericInstantVector(MIRInstantVectorType &insVecType); bool ParseDerivedType(TyIdx &tyIdx, MIRTypeKind kind = kTypeUnknown, const GStrIdx &strIdx = GStrIdx(0)); bool ParseType(TyIdx &tyIdx); + bool ParseEnumeration(); bool ParseStatement(StmtNodePtr &stmt); bool ParseSpecialReg(PregIdx &pRegIdx); bool ParsePseudoReg(PrimType primType, PregIdx &pRegIdx); diff --git a/src/mapleall/maple_ir/src/bin_mpl_export.cpp b/src/mapleall/maple_ir/src/bin_mpl_export.cpp index 674ab98ce5c89870e93adb8184d276bed39950c8..22693bda0609927703747e86ed6fec431f3a80e7 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_export.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_export.cpp @@ -1097,6 +1097,27 @@ void BinaryMplExport::WriteEaCgField(EAConnectionGraph *eaCg) { WriteNum(~kBinEaCgStart); } +void BinaryMplExport::WriteEnumField(uint64 contentIdx) { + if (GlobalTables::GetEnumTable().enumTable.empty()) { + return; + } + Fixup(contentIdx, buf.size()); + WriteNum(kBinEnumStart); + uint64 totalSizeIdx = buf.size(); + ExpandFourBuffSize(); // total size of this field to ~BIN_SYM_START + uint64 outEnumSizeIdx = buf.size(); + ExpandFourBuffSize(); // size of OutEnum + int32 size = 0; + for (MIREnum *mirEnum : GlobalTables::GetEnumTable().enumTable) { + OutputEnumeration(mirEnum); + size++; + } + Fixup(totalSizeIdx, buf.size() - totalSizeIdx); + Fixup(outEnumSizeIdx, size); + WriteNum(~kBinEnumStart); + return; +} + void BinaryMplExport::WriteSymField(uint64 contentIdx) { Fixup(contentIdx, buf.size()); WriteNum(kBinSymStart); @@ -1193,7 +1214,7 @@ void BinaryMplExport::WriteContentField4nonJava(int fieldNum, uint64 *fieldStart fieldStartP[kSecondField] = buf.size(); ExpandFourBuffSize(); - WriteNum(kBinTypeStart); + WriteNum(kBinEnumStart); fieldStartP[kThirdField] = buf.size(); ExpandFourBuffSize(); @@ -1228,6 +1249,7 @@ void BinaryMplExport::Export(const std::string &fname, std::unordered_set(mirEnum->primType)); + OutputStr(mirEnum->nameStrIdx); + WriteNum(mirEnum->elements.size()); + for (size_t i = 0; i < mirEnum->elements.size(); ++i) { + OutputStr(mirEnum->elements[i].first); + WriteNum(mirEnum->elements[i].second.GetSXTValue()); + } +} + void UpdateMplt::UpdateCgField(BinaryMplt &binMplt, const CallGraph &cg) const { BinaryMplImport &binImport = binMplt.GetBinImport(); BinaryMplExport &binExport = binMplt.GetBinExport(); diff --git a/src/mapleall/maple_ir/src/bin_mpl_import.cpp b/src/mapleall/maple_ir/src/bin_mpl_import.cpp index 0303b4a4f9cca638a04b0f2064224ca472b66966..fd67f481f22f72d3f882124c1f09631b4923685a 100644 --- a/src/mapleall/maple_ir/src/bin_mpl_import.cpp +++ b/src/mapleall/maple_ir/src/bin_mpl_import.cpp @@ -1192,6 +1192,32 @@ void BinaryMplImport::ReadTypeField() { CHECK_FATAL(tag == ~kBinTypeStart, "pattern mismatch in Read TYPE"); } +void BinaryMplImport::ImportEnumeration() { + int64 tag = ReadNum(); + CHECK_FATAL(tag == kBinEnumeration, "expecting kBinEnumeration"); + PrimType ptyp = static_cast(Read()); + GStrIdx gStrIdx = ImportStr(); + MIREnum *mirEnum = new MIREnum(ptyp, gStrIdx); + size_t siz = ReadNum(); + for (size_t i = 0; i < siz; i++) { + gStrIdx = ImportStr(); + IntVal intVal(ReadNum(), ptyp); + mirEnum->NewElement(gStrIdx, intVal); + } + GlobalTables::GetEnumTable().enumTable.push_back(mirEnum); +} + +void BinaryMplImport::ReadEnumField() { + SkipTotalSize(); + + int32 size = ReadInt(); + for (int64 i = 0; i < size; ++i) { + (void)ImportEnumeration(); + } + int64 tag = ReadNum(); + CHECK_FATAL(tag == ~kBinEnumStart, "pattern mismatch in Reading ENUM"); +} + CallInfo *BinaryMplImport::ImportCallInfo() { int64 tag = ReadNum(); if (tag < 0) { @@ -1658,6 +1684,10 @@ bool BinaryMplImport::Import(const std::string &fname, bool readSymbols, bool re ReadFunctionBodyField(); break; } + case kBinEnumStart: { + ReadEnumField(); + break; + } default: CHECK_FATAL(false, "should not run here"); } diff --git a/src/mapleall/maple_ir/src/mir_enumeration.cpp b/src/mapleall/maple_ir/src/mir_enumeration.cpp new file mode 100644 index 0000000000000000000000000000000000000000..be26f3bc9f606dbb7dc386e465446020d9e0946e --- /dev/null +++ b/src/mapleall/maple_ir/src/mir_enumeration.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) [2022] Futurewei Technologies, Inc. All rights reserved. + * + * OpenArkCompiler is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR + * FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include "global_tables.h" +#include "printing.h" +#include "mir_enumeration.h" + +// The syntax of enumerated type in Maple IR is: +// enumeration { = , ... } +// If '=' is not specified, will adopt the last value plus 1. +// The default starting is 0. + +namespace maple { + +const std::string &MIREnum::GetName() const { + return GlobalTables::GetStrTable().GetStringFromStrIdx(nameStrIdx); +} + +void MIREnum::Dump() const { + LogInfo::MapleLogger() << "enumeration $" << GetName() << " " << GetPrimTypeName(primType) << " {"; + IntVal lastValue(elements.front().second-9, primType); // so as to fail first check + for (size_t i = 0; i < elements.size(); i++) { + EnumElem curElem = elements[i]; + LogInfo::MapleLogger() << " $" << GlobalTables::GetStrTable().GetStringFromStrIdx(curElem.first); + if (curElem.second != lastValue+1) { + LogInfo::MapleLogger() << " = " << curElem.second; + } + lastValue = curElem.second; + if (i+1 != elements.size()) { + LogInfo::MapleLogger() << ","; + } + } + LogInfo::MapleLogger() << " }\n"; +} + +} // namespace maple diff --git a/src/mapleall/maple_ir/src/mir_module.cpp b/src/mapleall/maple_ir/src/mir_module.cpp index 1b0771c0dd3462e23c3192902a10e37871956de4..d028ea8fda9cef4405d2cf262a791577575be60e 100644 --- a/src/mapleall/maple_ir/src/mir_module.cpp +++ b/src/mapleall/maple_ir/src/mir_module.cpp @@ -231,6 +231,7 @@ void MIRModule::DumpGlobals(bool emitStructureType) const { } LogInfo::MapleLogger() << std::dec; } + GlobalTables::GetEnumTable().Dump(); if (flavor < kMmpl || flavor == kFlavorLmbc) { for (auto it = typeDefOrder.begin(); it != typeDefOrder.end(); ++it) { TyIdx tyIdx = typeNameTab->GetTyIdxFromGStrIdx(*it); diff --git a/src/mapleall/maple_ir/src/parser.cpp b/src/mapleall/maple_ir/src/parser.cpp index 088ab648583c4fcdaf58c81abdc206f47e337daf..dc40f9b3deb36373e56f173e64457cd5ab879c34 100644 --- a/src/mapleall/maple_ir/src/parser.cpp +++ b/src/mapleall/maple_ir/src/parser.cpp @@ -27,6 +27,7 @@ #include "clone.h" #include "string_utils.h" #include "debug_info.h" +#include "mir_enumeration.h" namespace { using namespace maple; @@ -1684,6 +1685,81 @@ bool MIRParser::ParseTypedef() { return true; } +bool MIRParser::ParseEnumeration() { + if (lexer.GetTokenKind() != TK_enumeration) { + Error("expect enum but get "); + return false; + } + TokenKind tokenKind = lexer.NextToken(); + if (tokenKind != TK_gname) { + Error("expect global type name but get "); + return false; + } + const std::string &name = lexer.GetName(); + GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name); + lexer.NextToken(); + TyIdx tyIdx(0); + if (!ParsePrimType(tyIdx)) { + Error("expect primitive type name but get "); + return false; + } + PrimType ptyp = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)->GetPrimType(); + if (!IsPrimitiveInteger(ptyp)) { + Error("base type of enum cannot be non-integer"); + return false; + } + if (lexer.GetTokenKind() != TK_lbrace) { + Error("expect left brace but get "); + return false; + } + tokenKind = lexer.NextToken(); + if (tokenKind != TK_gname) { + Error("expect global enum value name but get "); + return false; + } + MIREnum *mirEnum = new MIREnum(ptyp, strIdx); + strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name); + tokenKind = lexer.NextToken(); + if (tokenKind == TK_eqsign) { + tokenKind = lexer.NextToken(); + if (tokenKind != TK_intconst) { + Error("expect integer constant but get "); + return false; + } + mirEnum->NewElement(strIdx, IntVal(lexer.GetTheIntVal(), ptyp)); + tokenKind = lexer.NextToken(); + } else { + mirEnum->AddNextElement(strIdx); + } + while (tokenKind == TK_coma) { + tokenKind = lexer.NextToken(); + if (tokenKind != TK_gname) { + Error("expect global enum value name but get "); + return false; + } + strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name); + tokenKind = lexer.NextToken(); + if (tokenKind == TK_eqsign) { + tokenKind = lexer.NextToken(); + if (tokenKind != TK_intconst) { + Error("expect integer constant but get "); + return false; + } + mirEnum->NewElement(strIdx, IntVal(lexer.GetTheIntVal(), ptyp)); + tokenKind = lexer.NextToken(); + } else { + mirEnum->AddNextElement(strIdx); + } + } + if (tokenKind != TK_rbrace) { + Error("expect right brace but get "); + return false; + } + lexer.NextToken(); + GlobalTables::GetEnumTable().enumTable.push_back(mirEnum); + return true; +} + bool MIRParser::ParseJavaClassInterface(MIRSymbol &symbol, bool isClass) { TokenKind tk = lexer.NextToken(); if (tk != TK_gname) { @@ -2734,6 +2810,7 @@ std::map MIRParser::InitFuncPtrMap funcPtrMap[TK_javaclass] = &MIRParser::ParseMIRForClass; funcPtrMap[TK_javainterface] = &MIRParser::ParseMIRForInterface; funcPtrMap[TK_type] = &MIRParser::ParseTypedef; + funcPtrMap[TK_enumeration] = &MIRParser::ParseEnumeration; funcPtrMap[TK_flavor] = &MIRParser::ParseMIRForFlavor; funcPtrMap[TK_srclang] = &MIRParser::ParseMIRForSrcLang; funcPtrMap[TK_globalmemsize] = &MIRParser::ParseMIRForGlobalMemSize;