mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-26 23:38:31 +00:00
[flang][directives] Use TableGen to generate clause unparsing
Use the TableGen directive back-end to generate code for the clauses unparsing. Reviewed By: sscalpone, kiranchandramohan Differential Revision: https://reviews.llvm.org/D85851
This commit is contained in:
parent
6b6b4b3040
commit
a11d8d3dcc
@ -95,6 +95,11 @@ class Clause<string c> {
|
||||
|
||||
// List of allowed clause values
|
||||
list<ClauseVal> allowedClauseValues = [];
|
||||
// If set to 1, value class is part of a list. Single class by default.
|
||||
bit isValueList = 0;
|
||||
|
||||
// Define a default value such as "*".
|
||||
string defaultValue = "";
|
||||
|
||||
// Is clause implicit? If clause is set as implicit, the default kind will
|
||||
// be return in get<LanguageName>ClauseKind instead of their own kind.
|
||||
|
@ -121,9 +121,10 @@ def ACCC_DeviceResident : Clause<"device_resident"> {
|
||||
|
||||
// 2.4
|
||||
def ACCC_DeviceType : Clause<"device_type"> {
|
||||
// (DeviceType, "*"
|
||||
let flangClassValue = "std::list<Name>";
|
||||
let flangClassValue = "Name";
|
||||
let defaultValue = "*";
|
||||
let isValueOptional = 1;
|
||||
let isValueList = 1;
|
||||
}
|
||||
|
||||
// 2.6.6
|
||||
|
@ -184,6 +184,7 @@ def OMPC_Hint : Clause<"hint"> {
|
||||
}
|
||||
def OMPC_DistSchedule : Clause<"dist_schedule"> {
|
||||
let clangClass = "OMPDistScheduleClause";
|
||||
let flangClass = "OmpDistScheduleClause";
|
||||
let flangClassValue = "ScalarIntExpr";
|
||||
let isValueOptional = 1;
|
||||
}
|
||||
@ -201,11 +202,13 @@ def OMPC_From : Clause<"from"> {
|
||||
}
|
||||
def OMPC_UseDevicePtr : Clause<"use_device_ptr"> {
|
||||
let clangClass = "OMPUseDevicePtrClause";
|
||||
let flangClassValue = "std::list<Name>";
|
||||
let flangClassValue = "Name";
|
||||
let isValueList = 1;
|
||||
}
|
||||
def OMPC_IsDevicePtr : Clause<"is_device_ptr"> {
|
||||
let clangClass = "OMPIsDevicePtrClause";
|
||||
let flangClassValue = "std::list<Name>";
|
||||
let flangClassValue = "Name";
|
||||
let isValueList = 1;
|
||||
}
|
||||
def OMPC_TaskReduction : Clause<"task_reduction"> {
|
||||
let clangClass = "OMPTaskReductionClause";
|
||||
@ -260,7 +263,8 @@ def OMPC_UseDeviceAddr : Clause<"use_device_addr"> {
|
||||
let clangClass = "OMPUseDeviceAddrClause";
|
||||
}
|
||||
def OMPC_Uniform : Clause<"uniform"> {
|
||||
let flangClassValue = "std::list<Name>";
|
||||
let flangClassValue = "Name";
|
||||
let isValueList = 1;
|
||||
}
|
||||
def OMPC_DeviceType : Clause<"device_type"> {}
|
||||
def OMPC_Match : Clause<"match"> {}
|
||||
|
@ -154,6 +154,12 @@ public:
|
||||
|
||||
bool isValueOptional() const { return Def->getValueAsBit("isValueOptional"); }
|
||||
|
||||
bool isValueList() const { return Def->getValueAsBit("isValueList"); }
|
||||
|
||||
StringRef getDefaultValue() const {
|
||||
return Def->getValueAsString("defaultValue");
|
||||
}
|
||||
|
||||
bool isImplict() const { return Def->getValueAsBit("isImplicit"); }
|
||||
};
|
||||
|
||||
|
@ -231,5 +231,13 @@ def TDL_DirA : Directive<"dira"> {
|
||||
// GEN-NEXT: NODE(TdlClause, Clauseb)
|
||||
// GEN-EMPTY:
|
||||
// GEN-NEXT: #endif // GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
|
||||
|
||||
|
||||
// GEN-EMPTY:
|
||||
// GEN-NEXT: #ifdef GEN_FLANG_CLAUSE_UNPARSE
|
||||
// GEN-NEXT: #undef GEN_FLANG_CLAUSE_UNPARSE
|
||||
// GEN-EMPTY:
|
||||
// GEN-NEXT: void Unparse(const TdlClause::Clauseb &x) {
|
||||
// GEN-NEXT: Word("CLAUSEB");
|
||||
// GEN-NEXT: Walk("(", x.v, ")");
|
||||
// GEN-NEXT: }
|
||||
// GEN-EMPTY:
|
||||
// GEN-NEXT: #endif // GEN_FLANG_CLAUSE_UNPARSE
|
||||
|
@ -20,6 +20,12 @@ def TDLC_ClauseA : Clause<"clausea"> {
|
||||
def TDLC_ClauseB : Clause<"clauseb"> {
|
||||
let isDefault = 1;
|
||||
let flangClassValue = "IntExpr";
|
||||
let isValueList = 1;
|
||||
}
|
||||
def TDLC_ClauseC : Clause<"clausec"> {
|
||||
let flangClassValue = "Name";
|
||||
let defaultValue = "*";
|
||||
let isValueOptional = 1;
|
||||
}
|
||||
|
||||
def TDL_DirA : Directive<"dira"> {
|
||||
@ -46,9 +52,10 @@ def TDL_DirA : Directive<"dira"> {
|
||||
// CHECK-NEXT: enum class Clause {
|
||||
// CHECK-NEXT: TDLC_clausea,
|
||||
// CHECK-NEXT: TDLC_clauseb,
|
||||
// CHECK-NEXT: TDLC_clausec,
|
||||
// CHECK-NEXT: };
|
||||
// CHECK-EMPTY:
|
||||
// CHECK-NEXT: static constexpr std::size_t Clause_enumSize = 2;
|
||||
// CHECK-NEXT: static constexpr std::size_t Clause_enumSize = 3;
|
||||
// CHECK-EMPTY:
|
||||
// CHECK-NEXT: // Enumeration helper functions
|
||||
// CHECK-NEXT: Directive getTdlDirectiveKind(llvm::StringRef Str);
|
||||
@ -93,6 +100,7 @@ def TDL_DirA : Directive<"dira"> {
|
||||
// IMPL-NEXT: return llvm::StringSwitch<Clause>(Str)
|
||||
// IMPL-NEXT: .Case("clausea",TDLC_clauseb)
|
||||
// IMPL-NEXT: .Case("clauseb",TDLC_clauseb)
|
||||
// IMPL-NEXT: .Case("clausec",TDLC_clausec)
|
||||
// IMPL-NEXT: .Default(TDLC_clauseb);
|
||||
// IMPL-NEXT: }
|
||||
// IMPL-EMPTY:
|
||||
@ -102,6 +110,8 @@ def TDL_DirA : Directive<"dira"> {
|
||||
// IMPL-NEXT: return "clausea";
|
||||
// IMPL-NEXT: case TDLC_clauseb:
|
||||
// IMPL-NEXT: return "clauseb";
|
||||
// IMPL-NEXT: case TDLC_clausec:
|
||||
// IMPL-NEXT: return "clausec";
|
||||
// IMPL-NEXT: }
|
||||
// IMPL-NEXT: llvm_unreachable("Invalid Tdl Clause kind");
|
||||
// IMPL-NEXT: }
|
||||
@ -171,7 +181,8 @@ def TDL_DirA : Directive<"dira"> {
|
||||
// GEN-NEXT: #undef GEN_FLANG_CLAUSE_PARSER_CLASSES
|
||||
// GEN-EMPTY:
|
||||
// GEN-NEXT: EMPTY_CLASS(Clausea);
|
||||
// GEN-NEXT: WRAPPER_CLASS(Clauseb, IntExpr);
|
||||
// GEN-NEXT: WRAPPER_CLASS(Clauseb, std::list<IntExpr>);
|
||||
// GEN-NEXT: WRAPPER_CLASS(Clausec, std::optional<Name>);
|
||||
// GEN-EMPTY:
|
||||
// GEN-NEXT: #endif // GEN_FLANG_CLAUSE_PARSER_CLASSES
|
||||
// GEN-EMPTY:
|
||||
@ -180,6 +191,7 @@ def TDL_DirA : Directive<"dira"> {
|
||||
// GEN-EMPTY:
|
||||
// GEN-NEXT: Clausea
|
||||
// GEN-NEXT: , Clauseb
|
||||
// GEN-NEXT: , Clausec
|
||||
// GEN-EMPTY:
|
||||
// GEN-NEXT: #endif // GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST
|
||||
// GEN-EMPTY:
|
||||
@ -188,5 +200,28 @@ def TDL_DirA : Directive<"dira"> {
|
||||
// GEN-EMPTY:
|
||||
// GEN-NEXT: NODE(TdlClause, Clausea)
|
||||
// GEN-NEXT: NODE(TdlClause, Clauseb)
|
||||
// GEN-NEXT: NODE(TdlClause, Clausec)
|
||||
// GEN-EMPTY:
|
||||
// GEN-NEXT: #endif // GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
|
||||
// GEN-NEXT: #endif // GEN_FLANG_DUMP_PARSE_TREE_CLAUSES
|
||||
// GEN-EMPTY:
|
||||
// GEN-NEXT: #ifdef GEN_FLANG_CLAUSE_UNPARSE
|
||||
// GEN-NEXT: #undef GEN_FLANG_CLAUSE_UNPARSE
|
||||
// GEN-EMPTY:
|
||||
// GEN-NEXT: void Before(const TdlClause::Clausea &) { Word("CLAUSEA"); }
|
||||
// GEN-NEXT: void Unparse(const TdlClause::Clauseb &x) {
|
||||
// GEN-NEXT: Word("CLAUSEB");
|
||||
// GEN-NEXT: Put("(");
|
||||
// GEN-NEXT: Walk(x.v, ",");
|
||||
// GEN-NEXT: Put(")");
|
||||
// GEN-NEXT: }
|
||||
// GEN-NEXT: void Unparse(const TdlClause::Clausec &x) {
|
||||
// GEN-NEXT: Word("CLAUSEC");
|
||||
// GEN-NEXT: Put("(");
|
||||
// GEN-NEXT: if (x.v.has_value())
|
||||
// GEN-NEXT: Walk(x.v);
|
||||
// GEN-NEXT: else
|
||||
// GEN-NEXT: Put("*");
|
||||
// GEN-NEXT: Put(")");
|
||||
// GEN-NEXT: }
|
||||
// GEN-EMPTY:
|
||||
// GEN-NEXT: #endif // GEN_FLANG_CLAUSE_UNPARSE
|
||||
|
@ -471,18 +471,22 @@ void GenerateFlangClauseParserClass(const std::vector<Record *> &Clauses,
|
||||
// Clause has a non generic class.
|
||||
if (!Clause.getFlangClass().empty())
|
||||
continue;
|
||||
// G
|
||||
if (!Clause.getFlangClassValue().empty()) {
|
||||
if (Clause.isValueOptional()) {
|
||||
OS << "WRAPPER_CLASS(" << Clause.getFormattedParserClassName()
|
||||
<< ", std::optional<" << Clause.getFlangClassValue() << ">);\n";
|
||||
OS << "WRAPPER_CLASS(" << Clause.getFormattedParserClassName() << ", ";
|
||||
if (Clause.isValueOptional() && Clause.isValueList()) {
|
||||
OS << "std::optional<std::list<" << Clause.getFlangClassValue()
|
||||
<< ">>";
|
||||
} else if (Clause.isValueOptional()) {
|
||||
OS << "std::optional<" << Clause.getFlangClassValue() << ">";
|
||||
} else if (Clause.isValueList()) {
|
||||
OS << "std::list<" << Clause.getFlangClassValue() << ">";
|
||||
} else {
|
||||
OS << "WRAPPER_CLASS(" << Clause.getFormattedParserClassName() << ", "
|
||||
<< Clause.getFlangClassValue() << ");\n";
|
||||
OS << Clause.getFlangClassValue();
|
||||
}
|
||||
} else {
|
||||
OS << "EMPTY_CLASS(" << Clause.getFormattedParserClassName() << ");\n";
|
||||
OS << "EMPTY_CLASS(" << Clause.getFormattedParserClassName();
|
||||
}
|
||||
OS << ");\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -521,6 +525,63 @@ void GenerateFlangClauseDump(const std::vector<Record *> &Clauses,
|
||||
}
|
||||
}
|
||||
|
||||
// Generate Unparse functions for clauses classes in the Flang parse-tree
|
||||
// If the clause is a non-generic class, no entry is generated.
|
||||
void GenerateFlangClauseUnparse(const std::vector<Record *> &Clauses,
|
||||
const DirectiveLanguage &DirLang,
|
||||
raw_ostream &OS) {
|
||||
|
||||
IfDefScope Scope("GEN_FLANG_CLAUSE_UNPARSE", OS);
|
||||
|
||||
OS << "\n";
|
||||
|
||||
for (const auto &C : Clauses) {
|
||||
Clause Clause{C};
|
||||
// Clause has a non generic class.
|
||||
if (!Clause.getFlangClass().empty())
|
||||
continue;
|
||||
if (!Clause.getFlangClassValue().empty()) {
|
||||
if (Clause.isValueOptional() && Clause.getDefaultValue().empty()) {
|
||||
OS << "void Unparse(const " << DirLang.getFlangClauseBaseClass()
|
||||
<< "::" << Clause.getFormattedParserClassName() << " &x) {\n";
|
||||
OS << " Word(\"" << Clause.getName().upper() << "\");\n";
|
||||
|
||||
OS << " Walk(\"(\", x.v, \")\");\n";
|
||||
OS << "}\n";
|
||||
} else if (Clause.isValueOptional()) {
|
||||
OS << "void Unparse(const " << DirLang.getFlangClauseBaseClass()
|
||||
<< "::" << Clause.getFormattedParserClassName() << " &x) {\n";
|
||||
OS << " Word(\"" << Clause.getName().upper() << "\");\n";
|
||||
OS << " Put(\"(\");\n";
|
||||
OS << " if (x.v.has_value())\n";
|
||||
if (Clause.isValueList())
|
||||
OS << " Walk(x.v, \",\");\n";
|
||||
else
|
||||
OS << " Walk(x.v);\n";
|
||||
OS << " else\n";
|
||||
OS << " Put(\"" << Clause.getDefaultValue() << "\");\n";
|
||||
OS << " Put(\")\");\n";
|
||||
OS << "}\n";
|
||||
} else {
|
||||
OS << "void Unparse(const " << DirLang.getFlangClauseBaseClass()
|
||||
<< "::" << Clause.getFormattedParserClassName() << " &x) {\n";
|
||||
OS << " Word(\"" << Clause.getName().upper() << "\");\n";
|
||||
OS << " Put(\"(\");\n";
|
||||
if (Clause.isValueList())
|
||||
OS << " Walk(x.v, \",\");\n";
|
||||
else
|
||||
OS << " Walk(x.v);\n";
|
||||
OS << " Put(\")\");\n";
|
||||
OS << "}\n";
|
||||
}
|
||||
} else {
|
||||
OS << "void Before(const " << DirLang.getFlangClauseBaseClass()
|
||||
<< "::" << Clause.getFormattedParserClassName() << " &) { Word(\""
|
||||
<< Clause.getName().upper() << "\"); }\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the implemenation section for the enumeration in the directive
|
||||
// language
|
||||
void EmitDirectivesFlangImpl(const std::vector<Record *> &Directives,
|
||||
@ -537,6 +598,8 @@ void EmitDirectivesFlangImpl(const std::vector<Record *> &Directives,
|
||||
GenerateFlangClauseParserClassList(Clauses, OS);
|
||||
|
||||
GenerateFlangClauseDump(Clauses, DirectiveLanguage, OS);
|
||||
|
||||
GenerateFlangClauseUnparse(Clauses, DirectiveLanguage, OS);
|
||||
}
|
||||
|
||||
// Generate the implemenation section for the enumeration in the directive
|
||||
|
Loading…
x
Reference in New Issue
Block a user