forked from OSchip/llvm-project
[openmp][openacc][NFC] Simplify access and validation of DirectiveBase information
This patch adds some helper in the DirectiveLanguage wrapper to initialize it from the RecordKeeper and validate the records. This simplify arguments in lots of function since only the DirectiveLanguge is passed. Reviewed By: kiranchandramohan Differential Revision: https://reviews.llvm.org/D90358
This commit is contained in:
parent
3c050a597c
commit
6c337945c8
|
@ -10,7 +10,11 @@ namespace llvm {
|
|||
// DirectiveBase.td and provides helper methods for accessing it.
|
||||
class DirectiveLanguage {
|
||||
public:
|
||||
explicit DirectiveLanguage(const llvm::Record *Def) : Def(Def) {}
|
||||
explicit DirectiveLanguage(const llvm::RecordKeeper &Records)
|
||||
: Records(Records) {
|
||||
const auto &DirectiveLanguages = getDirectiveLanguages();
|
||||
Def = DirectiveLanguages[0];
|
||||
}
|
||||
|
||||
StringRef getName() const { return Def->getValueAsString("name"); }
|
||||
|
||||
|
@ -46,8 +50,23 @@ public:
|
|||
return Def->getValueAsBit("enableBitmaskEnumInNamespace");
|
||||
}
|
||||
|
||||
const std::vector<Record *> getDirectives() const {
|
||||
return Records.getAllDerivedDefinitions("Directive");
|
||||
}
|
||||
|
||||
const std::vector<Record *> getClauses() const {
|
||||
return Records.getAllDerivedDefinitions("Clause");
|
||||
}
|
||||
|
||||
bool CheckRecordsValidity() const;
|
||||
|
||||
private:
|
||||
const llvm::Record *Def;
|
||||
const llvm::RecordKeeper &Records;
|
||||
|
||||
const std::vector<Record *> getDirectiveLanguages() const {
|
||||
return Records.getAllDerivedDefinitions("DirectiveLanguage");
|
||||
}
|
||||
};
|
||||
|
||||
// Base record class used for Directive and Clause class defined in
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace llvm {
|
|||
// Generate enum class
|
||||
void GenerateEnumClass(const std::vector<Record *> &Records, raw_ostream &OS,
|
||||
StringRef Enum, StringRef Prefix,
|
||||
DirectiveLanguage &DirLang) {
|
||||
const DirectiveLanguage &DirLang) {
|
||||
OS << "\n";
|
||||
OS << "enum class " << Enum << " {\n";
|
||||
for (const auto &R : Records) {
|
||||
|
@ -74,7 +74,7 @@ void GenerateEnumClass(const std::vector<Record *> &Records, raw_ostream &OS,
|
|||
// Generate enums for values that clauses can take.
|
||||
// Also generate function declarations for get<Enum>Name(StringRef Str).
|
||||
void GenerateEnumClauseVal(const std::vector<Record *> &Records,
|
||||
raw_ostream &OS, DirectiveLanguage &DirLang,
|
||||
raw_ostream &OS, const DirectiveLanguage &DirLang,
|
||||
std::string &EnumHelperFuncs) {
|
||||
for (const auto &R : Records) {
|
||||
Clause C{R};
|
||||
|
@ -146,32 +146,22 @@ bool HasDuplicateClausesInDirectives(const std::vector<Record *> &Directives) {
|
|||
|
||||
// Check consitency of records. Return true if an error has been detected.
|
||||
// Return false if the records are valid.
|
||||
bool CheckRecordsValidity(RecordKeeper &Records) {
|
||||
const auto &DirectiveLanguages =
|
||||
Records.getAllDerivedDefinitions("DirectiveLanguage");
|
||||
|
||||
if (DirectiveLanguages.size() != 1) {
|
||||
bool DirectiveLanguage::CheckRecordsValidity() const {
|
||||
if (getDirectiveLanguages().size() != 1) {
|
||||
PrintError("A single definition of DirectiveLanguage is needed.");
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto &Directives = Records.getAllDerivedDefinitions("Directive");
|
||||
return HasDuplicateClausesInDirectives(Directives);
|
||||
return HasDuplicateClausesInDirectives(getDirectives());
|
||||
}
|
||||
|
||||
// Generate the declaration section for the enumeration in the directive
|
||||
// language
|
||||
void EmitDirectivesDecl(RecordKeeper &Records, raw_ostream &OS) {
|
||||
|
||||
if (CheckRecordsValidity(Records))
|
||||
const auto DirLang = DirectiveLanguage{Records};
|
||||
if (DirLang.CheckRecordsValidity())
|
||||
return;
|
||||
|
||||
const auto &DirectiveLanguages =
|
||||
Records.getAllDerivedDefinitions("DirectiveLanguage");
|
||||
|
||||
DirectiveLanguage DirLang{DirectiveLanguages[0]};
|
||||
const auto &Directives = Records.getAllDerivedDefinitions("Directive");
|
||||
|
||||
OS << "#ifndef LLVM_" << DirLang.getName() << "_INC\n";
|
||||
OS << "#define LLVM_" << DirLang.getName() << "_INC\n";
|
||||
|
||||
|
@ -192,16 +182,16 @@ void EmitDirectivesDecl(RecordKeeper &Records, raw_ostream &OS) {
|
|||
OS << "\nLLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();\n";
|
||||
|
||||
// Emit Directive enumeration
|
||||
GenerateEnumClass(Directives, OS, "Directive", DirLang.getDirectivePrefix(),
|
||||
DirLang);
|
||||
GenerateEnumClass(DirLang.getDirectives(), OS, "Directive",
|
||||
DirLang.getDirectivePrefix(), DirLang);
|
||||
|
||||
// Emit Clause enumeration
|
||||
const auto &Clauses = Records.getAllDerivedDefinitions("Clause");
|
||||
GenerateEnumClass(Clauses, OS, "Clause", DirLang.getClausePrefix(), DirLang);
|
||||
GenerateEnumClass(DirLang.getClauses(), OS, "Clause",
|
||||
DirLang.getClausePrefix(), DirLang);
|
||||
|
||||
// Emit ClauseVal enumeration
|
||||
std::string EnumHelperFuncs;
|
||||
GenerateEnumClauseVal(Clauses, OS, DirLang, EnumHelperFuncs);
|
||||
GenerateEnumClauseVal(DirLang.getClauses(), OS, DirLang, EnumHelperFuncs);
|
||||
|
||||
// Generic function signatures
|
||||
OS << "\n";
|
||||
|
@ -238,7 +228,7 @@ void EmitDirectivesDecl(RecordKeeper &Records, raw_ostream &OS) {
|
|||
|
||||
// Generate function implementation for get<Enum>Name(StringRef Str)
|
||||
void GenerateGetName(const std::vector<Record *> &Records, raw_ostream &OS,
|
||||
StringRef Enum, DirectiveLanguage &DirLang,
|
||||
StringRef Enum, const DirectiveLanguage &DirLang,
|
||||
StringRef Prefix) {
|
||||
OS << "\n";
|
||||
OS << "llvm::StringRef llvm::" << DirLang.getCppNamespace() << "::get"
|
||||
|
@ -262,7 +252,7 @@ void GenerateGetName(const std::vector<Record *> &Records, raw_ostream &OS,
|
|||
|
||||
// Generate function implementation for get<Enum>Kind(StringRef Str)
|
||||
void GenerateGetKind(const std::vector<Record *> &Records, raw_ostream &OS,
|
||||
StringRef Enum, DirectiveLanguage &DirLang,
|
||||
StringRef Enum, const DirectiveLanguage &DirLang,
|
||||
StringRef Prefix, bool ImplicitAsUnknown) {
|
||||
|
||||
auto DefaultIt = std::find_if(Records.begin(), Records.end(), [](Record *R) {
|
||||
|
@ -296,10 +286,9 @@ void GenerateGetKind(const std::vector<Record *> &Records, raw_ostream &OS,
|
|||
}
|
||||
|
||||
// Generate function implementation for get<ClauseVal>Kind(StringRef Str)
|
||||
void GenerateGetKindClauseVal(const std::vector<Record *> &Records,
|
||||
raw_ostream &OS, StringRef Namespace) {
|
||||
|
||||
for (const auto &R : Records) {
|
||||
void GenerateGetKindClauseVal(const DirectiveLanguage &DirLang,
|
||||
raw_ostream &OS) {
|
||||
for (const auto &R : DirLang.getClauses()) {
|
||||
Clause C{R};
|
||||
const auto &ClauseVals = C.getClauseVals();
|
||||
if (ClauseVals.size() <= 0)
|
||||
|
@ -325,8 +314,8 @@ void GenerateGetKindClauseVal(const std::vector<Record *> &Records,
|
|||
}
|
||||
|
||||
OS << "\n";
|
||||
OS << EnumName << " llvm::" << Namespace << "::get" << EnumName
|
||||
<< "(llvm::StringRef Str) {\n";
|
||||
OS << EnumName << " llvm::" << DirLang.getCppNamespace() << "::get"
|
||||
<< EnumName << "(llvm::StringRef Str) {\n";
|
||||
OS << " return llvm::StringSwitch<" << EnumName << ">(Str)\n";
|
||||
for (const auto &CV : ClauseVals) {
|
||||
ClauseVal CVal{CV};
|
||||
|
@ -340,7 +329,7 @@ void GenerateGetKindClauseVal(const std::vector<Record *> &Records,
|
|||
|
||||
void GenerateCaseForVersionedClauses(const std::vector<Record *> &Clauses,
|
||||
raw_ostream &OS, StringRef DirectiveName,
|
||||
DirectiveLanguage &DirLang,
|
||||
const DirectiveLanguage &DirLang,
|
||||
llvm::StringSet<> &Cases) {
|
||||
for (const auto &C : Clauses) {
|
||||
VersionedClause VerClause{C};
|
||||
|
@ -358,8 +347,8 @@ void GenerateCaseForVersionedClauses(const std::vector<Record *> &Clauses,
|
|||
}
|
||||
|
||||
// Generate the isAllowedClauseForDirective function implementation.
|
||||
void GenerateIsAllowedClause(const std::vector<Record *> &Directives,
|
||||
raw_ostream &OS, DirectiveLanguage &DirLang) {
|
||||
void GenerateIsAllowedClause(const DirectiveLanguage &DirLang,
|
||||
raw_ostream &OS) {
|
||||
OS << "\n";
|
||||
OS << "bool llvm::" << DirLang.getCppNamespace()
|
||||
<< "::isAllowedClauseForDirective("
|
||||
|
@ -371,7 +360,7 @@ void GenerateIsAllowedClause(const std::vector<Record *> &Directives,
|
|||
|
||||
OS << " switch (D) {\n";
|
||||
|
||||
for (const auto &D : Directives) {
|
||||
for (const auto &D : DirLang.getDirectives()) {
|
||||
Directive Dir{D};
|
||||
|
||||
OS << " case " << DirLang.getDirectivePrefix() << Dir.getFormattedName()
|
||||
|
@ -414,7 +403,7 @@ void GenerateIsAllowedClause(const std::vector<Record *> &Directives,
|
|||
// Generate a simple enum set with the give clauses.
|
||||
void GenerateClauseSet(const std::vector<Record *> &Clauses, raw_ostream &OS,
|
||||
StringRef ClauseSetPrefix, Directive &Dir,
|
||||
DirectiveLanguage &DirLang) {
|
||||
const DirectiveLanguage &DirLang) {
|
||||
|
||||
OS << "\n";
|
||||
OS << " static " << DirLang.getClauseEnumSetClass() << " " << ClauseSetPrefix
|
||||
|
@ -430,8 +419,8 @@ void GenerateClauseSet(const std::vector<Record *> &Clauses, raw_ostream &OS,
|
|||
}
|
||||
|
||||
// Generate an enum set for the 4 kinds of clauses linked to a directive.
|
||||
void GenerateDirectiveClauseSets(const std::vector<Record *> &Directives,
|
||||
raw_ostream &OS, DirectiveLanguage &DirLang) {
|
||||
void GenerateDirectiveClauseSets(const DirectiveLanguage &DirLang,
|
||||
raw_ostream &OS) {
|
||||
|
||||
IfDefScope Scope("GEN_FLANG_DIRECTIVE_CLAUSE_SETS", OS);
|
||||
|
||||
|
@ -444,7 +433,7 @@ void GenerateDirectiveClauseSets(const std::vector<Record *> &Directives,
|
|||
for (auto Ns : Namespaces)
|
||||
OS << "namespace " << Ns << " {\n";
|
||||
|
||||
for (const auto &D : Directives) {
|
||||
for (const auto &D : DirLang.getDirectives()) {
|
||||
Directive Dir{D};
|
||||
|
||||
OS << "\n";
|
||||
|
@ -470,15 +459,15 @@ void GenerateDirectiveClauseSets(const std::vector<Record *> &Directives,
|
|||
// Generate a map of directive (key) with DirectiveClauses struct as values.
|
||||
// The struct holds the 4 sets of enumeration for the 4 kinds of clauses
|
||||
// allowances (allowed, allowed once, allowed exclusive and required).
|
||||
void GenerateDirectiveClauseMap(const std::vector<Record *> &Directives,
|
||||
raw_ostream &OS, DirectiveLanguage &DirLang) {
|
||||
void GenerateDirectiveClauseMap(const DirectiveLanguage &DirLang,
|
||||
raw_ostream &OS) {
|
||||
|
||||
IfDefScope Scope("GEN_FLANG_DIRECTIVE_CLAUSE_MAP", OS);
|
||||
|
||||
OS << "\n";
|
||||
OS << "{\n";
|
||||
|
||||
for (const auto &D : Directives) {
|
||||
for (const auto &D : DirLang.getDirectives()) {
|
||||
Directive Dir{D};
|
||||
OS << " {llvm::" << DirLang.getCppNamespace()
|
||||
<< "::Directive::" << DirLang.getDirectivePrefix()
|
||||
|
@ -505,14 +494,14 @@ void GenerateDirectiveClauseMap(const std::vector<Record *> &Directives,
|
|||
// If the clause does not hold a value, an EMPTY_CLASS is used.
|
||||
// If the clause class is generic then a WRAPPER_CLASS is used. When the value
|
||||
// is optional, the value class is wrapped into a std::optional.
|
||||
void GenerateFlangClauseParserClass(const std::vector<Record *> &Clauses,
|
||||
void GenerateFlangClauseParserClass(const DirectiveLanguage &DirLang,
|
||||
raw_ostream &OS) {
|
||||
|
||||
IfDefScope Scope("GEN_FLANG_CLAUSE_PARSER_CLASSES", OS);
|
||||
|
||||
OS << "\n";
|
||||
|
||||
for (const auto &C : Clauses) {
|
||||
for (const auto &C : DirLang.getClauses()) {
|
||||
Clause Clause{C};
|
||||
// Clause has a non generic class.
|
||||
if (!Clause.getFlangClass().empty())
|
||||
|
@ -537,13 +526,13 @@ void GenerateFlangClauseParserClass(const std::vector<Record *> &Clauses,
|
|||
}
|
||||
|
||||
// Generate a list of the different clause classes for Flang.
|
||||
void GenerateFlangClauseParserClassList(const std::vector<Record *> &Clauses,
|
||||
void GenerateFlangClauseParserClassList(const DirectiveLanguage &DirLang,
|
||||
raw_ostream &OS) {
|
||||
|
||||
IfDefScope Scope("GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST", OS);
|
||||
|
||||
OS << "\n";
|
||||
llvm::interleaveComma(Clauses, OS, [&](Record *C) {
|
||||
llvm::interleaveComma(DirLang.getClauses(), OS, [&](Record *C) {
|
||||
Clause Clause{C};
|
||||
if (Clause.getFlangClass().empty())
|
||||
OS << Clause.getFormattedParserClassName() << "\n";
|
||||
|
@ -553,14 +542,13 @@ void GenerateFlangClauseParserClassList(const std::vector<Record *> &Clauses,
|
|||
}
|
||||
|
||||
// Generate dump node list for the clauses holding a generic class name.
|
||||
void GenerateFlangClauseDump(const std::vector<Record *> &Clauses,
|
||||
const DirectiveLanguage &DirLang,
|
||||
void GenerateFlangClauseDump(const DirectiveLanguage &DirLang,
|
||||
raw_ostream &OS) {
|
||||
|
||||
IfDefScope Scope("GEN_FLANG_DUMP_PARSE_TREE_CLAUSES", OS);
|
||||
|
||||
OS << "\n";
|
||||
for (const auto &C : Clauses) {
|
||||
for (const auto &C : DirLang.getClauses()) {
|
||||
Clause Clause{C};
|
||||
// Clause has a non generic class.
|
||||
if (!Clause.getFlangClass().empty())
|
||||
|
@ -573,15 +561,14 @@ 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,
|
||||
void GenerateFlangClauseUnparse(const DirectiveLanguage &DirLang,
|
||||
raw_ostream &OS) {
|
||||
|
||||
IfDefScope Scope("GEN_FLANG_CLAUSE_UNPARSE", OS);
|
||||
|
||||
OS << "\n";
|
||||
|
||||
for (const auto &C : Clauses) {
|
||||
for (const auto &C : DirLang.getClauses()) {
|
||||
Clause Clause{C};
|
||||
// Clause has a non generic class.
|
||||
if (!Clause.getFlangClass().empty())
|
||||
|
@ -630,51 +617,39 @@ void GenerateFlangClauseUnparse(const std::vector<Record *> &Clauses,
|
|||
|
||||
// Generate the implemenation section for the enumeration in the directive
|
||||
// language
|
||||
void EmitDirectivesFlangImpl(const std::vector<Record *> &Directives,
|
||||
const std::vector<Record *> &Clauses,
|
||||
raw_ostream &OS,
|
||||
DirectiveLanguage &DirectiveLanguage) {
|
||||
void EmitDirectivesFlangImpl(const DirectiveLanguage &DirLang,
|
||||
raw_ostream &OS) {
|
||||
|
||||
GenerateDirectiveClauseSets(Directives, OS, DirectiveLanguage);
|
||||
GenerateDirectiveClauseSets(DirLang, OS);
|
||||
|
||||
GenerateDirectiveClauseMap(Directives, OS, DirectiveLanguage);
|
||||
GenerateDirectiveClauseMap(DirLang, OS);
|
||||
|
||||
GenerateFlangClauseParserClass(Clauses, OS);
|
||||
GenerateFlangClauseParserClass(DirLang, OS);
|
||||
|
||||
GenerateFlangClauseParserClassList(Clauses, OS);
|
||||
GenerateFlangClauseParserClassList(DirLang, OS);
|
||||
|
||||
GenerateFlangClauseDump(Clauses, DirectiveLanguage, OS);
|
||||
GenerateFlangClauseDump(DirLang, OS);
|
||||
|
||||
GenerateFlangClauseUnparse(Clauses, DirectiveLanguage, OS);
|
||||
GenerateFlangClauseUnparse(DirLang, OS);
|
||||
}
|
||||
|
||||
// Generate the implemenation section for the enumeration in the directive
|
||||
// language.
|
||||
void EmitDirectivesGen(RecordKeeper &Records, raw_ostream &OS) {
|
||||
if (CheckRecordsValidity(Records))
|
||||
const auto DirLang = DirectiveLanguage{Records};
|
||||
if (DirLang.CheckRecordsValidity())
|
||||
return;
|
||||
|
||||
const auto &DirectiveLanguages =
|
||||
Records.getAllDerivedDefinitions("DirectiveLanguage");
|
||||
const auto &Directives = Records.getAllDerivedDefinitions("Directive");
|
||||
const auto &Clauses = Records.getAllDerivedDefinitions("Clause");
|
||||
DirectiveLanguage DirectiveLanguage{DirectiveLanguages[0]};
|
||||
EmitDirectivesFlangImpl(Directives, Clauses, OS, DirectiveLanguage);
|
||||
EmitDirectivesFlangImpl(DirLang, OS);
|
||||
}
|
||||
|
||||
// Generate the implemenation for the enumeration in the directive
|
||||
// language. This code can be included in library.
|
||||
void EmitDirectivesImpl(RecordKeeper &Records, raw_ostream &OS) {
|
||||
if (CheckRecordsValidity(Records))
|
||||
const auto DirLang = DirectiveLanguage{Records};
|
||||
if (DirLang.CheckRecordsValidity())
|
||||
return;
|
||||
|
||||
const auto &DirectiveLanguages =
|
||||
Records.getAllDerivedDefinitions("DirectiveLanguage");
|
||||
const auto &Directives = Records.getAllDerivedDefinitions("Directive");
|
||||
DirectiveLanguage DirLang = DirectiveLanguage{DirectiveLanguages[0]};
|
||||
|
||||
const auto &Clauses = Records.getAllDerivedDefinitions("Clause");
|
||||
|
||||
if (!DirLang.getIncludeHeader().empty())
|
||||
OS << "#include \"" << DirLang.getIncludeHeader() << "\"\n\n";
|
||||
|
||||
|
@ -689,25 +664,27 @@ void EmitDirectivesImpl(RecordKeeper &Records, raw_ostream &OS) {
|
|||
OS << "using namespace " << Ns << ";\n";
|
||||
|
||||
// getDirectiveKind(StringRef Str)
|
||||
GenerateGetKind(Directives, OS, "Directive", DirLang,
|
||||
GenerateGetKind(DirLang.getDirectives(), OS, "Directive", DirLang,
|
||||
DirLang.getDirectivePrefix(), /*ImplicitAsUnknown=*/false);
|
||||
|
||||
// getDirectiveName(Directive Kind)
|
||||
GenerateGetName(Directives, OS, "Directive", DirLang,
|
||||
GenerateGetName(DirLang.getDirectives(), OS, "Directive", DirLang,
|
||||
DirLang.getDirectivePrefix());
|
||||
|
||||
// getClauseKind(StringRef Str)
|
||||
GenerateGetKind(Clauses, OS, "Clause", DirLang, DirLang.getClausePrefix(),
|
||||
GenerateGetKind(DirLang.getClauses(), OS, "Clause", DirLang,
|
||||
DirLang.getClausePrefix(),
|
||||
/*ImplicitAsUnknown=*/true);
|
||||
|
||||
// getClauseName(Clause Kind)
|
||||
GenerateGetName(Clauses, OS, "Clause", DirLang, DirLang.getClausePrefix());
|
||||
GenerateGetName(DirLang.getClauses(), OS, "Clause", DirLang,
|
||||
DirLang.getClausePrefix());
|
||||
|
||||
// get<ClauseVal>Kind(StringRef Str)
|
||||
GenerateGetKindClauseVal(Clauses, OS, DirLang.getCppNamespace());
|
||||
GenerateGetKindClauseVal(DirLang, OS);
|
||||
|
||||
// isAllowedClauseForDirective(Directive D, Clause C, unsigned Version)
|
||||
GenerateIsAllowedClause(Directives, OS, DirLang);
|
||||
GenerateIsAllowedClause(DirLang, OS);
|
||||
}
|
||||
|
||||
} // namespace llvm
|
||||
|
|
Loading…
Reference in New Issue