diff --git a/llvm/test/TableGen/directive1.td b/llvm/test/TableGen/directive1.td --- a/llvm/test/TableGen/directive1.td +++ b/llvm/test/TableGen/directive1.td @@ -106,9 +106,17 @@ // IMPL-NEXT: bool llvm::tdl::isAllowedClauseForDirective(Directive D, Clause C, unsigned Version) { // IMPL-NEXT: assert(unsigned(D) <= llvm::tdl::Directive_enumSize); // IMPL-NEXT: assert(unsigned(C) <= llvm::tdl::Clause_enumSize); -// IMPL-NEXT: if (D == TDLD_dira && C == TDLC_clausea && 1 <= Version && 2147483647 >= Version) -// IMPL-NEXT: return true; -// IMPL-NEXT: if (D == TDLD_dira && C == TDLC_clauseb && 1 <= Version && 2147483647 >= Version) -// IMPL-NEXT: return true; -// IMPL-NEXT: return false; +// IMPL-NEXT: switch (D) { +// IMPL-NEXT: case TDLD_dira: +// IMPL-NEXT: switch (C) { +// IMPL-NEXT: case TDLC_clausea: +// IMPL-NEXT: return 1 <= Version && 2147483647 >= Version; +// IMPL-NEXT: case TDLC_clauseb: +// IMPL-NEXT: return 1 <= Version && 2147483647 >= Version; +// IMPL-NEXT: default: +// IMPL-NEXT: return false; +// IMPL-NEXT: } +// IMPL-NEXT: break; +// IMPL-NEXT: } +// IMPL-NEXT: llvm_unreachable("Invalid Tdl Directive kind"); // IMPL-NEXT: } diff --git a/llvm/test/TableGen/directive2.td b/llvm/test/TableGen/directive2.td --- a/llvm/test/TableGen/directive2.td +++ b/llvm/test/TableGen/directive2.td @@ -97,10 +97,17 @@ // IMPL-NEXT: bool llvm::tdl::isAllowedClauseForDirective(Directive D, Clause C, unsigned Version) { // IMPL-NEXT: assert(unsigned(D) <= llvm::tdl::Directive_enumSize); // IMPL-NEXT: assert(unsigned(C) <= llvm::tdl::Clause_enumSize); -// IMPL-NEXT: if (D == TDLD_dira && C == TDLC_clausea && 2 <= Version && 4 >= Version) -// IMPL-NEXT: return true; -// IMPL-NEXT: if (D == TDLD_dira && C == TDLC_clauseb && 2 <= Version && 2147483647 >= Version) -// IMPL-NEXT: return true; -// IMPL-NEXT: return false; +// IMPL-NEXT: switch (D) { +// IMPL-NEXT: case TDLD_dira: +// IMPL-NEXT: switch (C) { +// IMPL-NEXT: case TDLC_clausea: +// IMPL-NEXT: return 2 <= Version && 4 >= Version; +// IMPL-NEXT: case TDLC_clauseb: +// IMPL-NEXT: return 2 <= Version && 2147483647 >= Version; +// IMPL-NEXT: default: +// IMPL-NEXT: return false; +// IMPL-NEXT: } +// IMPL-NEXT: break; +// IMPL-NEXT: } +// IMPL-NEXT: llvm_unreachable("Invalid Tdl Directive kind"); // IMPL-NEXT: } - diff --git a/llvm/utils/TableGen/DirectiveEmitter.cpp b/llvm/utils/TableGen/DirectiveEmitter.cpp --- a/llvm/utils/TableGen/DirectiveEmitter.cpp +++ b/llvm/utils/TableGen/DirectiveEmitter.cpp @@ -202,29 +202,27 @@ OS << "}\n"; } -void GenerateTestForAllowedClauses(const std::vector &Clauses, - raw_ostream &OS, StringRef DirectiveName, - StringRef DirectivePrefix, - StringRef ClausePrefix) { - - const auto FormattedDirectiveName = getFormattedName(DirectiveName); +void GenerateCaseForVersionedClauses(const std::vector &Clauses, + raw_ostream &OS, StringRef DirectiveName, + StringRef DirectivePrefix, + StringRef ClausePrefix) { for (const auto &C : Clauses) { const auto MinVersion = C->getValueAsInt("minVersion"); const auto MaxVersion = C->getValueAsInt("maxVersion"); const auto SpecificClause = C->getValueAsDef("clause"); const auto ClauseName = SpecificClause->getValueAsString("name"); - - OS << " if (D == " << DirectivePrefix << FormattedDirectiveName - << " && C == " << ClausePrefix << getFormattedName(ClauseName) << " && " - << MinVersion << " <= Version && " << MaxVersion << " >= Version)\n"; - OS << " return true;\n"; + OS << " case " << ClausePrefix << getFormattedName(ClauseName) + << ":\n"; + OS << " return " << MinVersion << " <= Version && " << MaxVersion + << " >= Version;\n"; } } // Generate the isAllowedClauseForDirective function implementation. void GenerateIsAllowedClause(const std::vector &Directives, - raw_ostream &OS, StringRef DirectivePrefix, - StringRef ClausePrefix, StringRef CppNamespace) { + raw_ostream &OS, StringRef LanguageName, + StringRef DirectivePrefix, StringRef ClausePrefix, + StringRef CppNamespace) { OS << "\n"; OS << "bool llvm::" << CppNamespace << "::isAllowedClauseForDirective(" << "Directive D, Clause C, unsigned Version) {\n"; @@ -233,24 +231,39 @@ OS << " assert(unsigned(C) <= llvm::" << CppNamespace << "::Clause_enumSize);\n"; + OS << " switch (D) {\n"; + for (const auto &D : Directives) { + const auto DirectiveName = D->getValueAsString("name"); + OS << " case " << DirectivePrefix << getFormattedName(DirectiveName) + << ":\n"; + OS << " switch (C) {\n"; + const auto &AllowedClauses = D->getValueAsListOfDefs("allowedClauses"); - GenerateTestForAllowedClauses(AllowedClauses, OS, DirectiveName, - DirectivePrefix, ClausePrefix); + GenerateCaseForVersionedClauses(AllowedClauses, OS, DirectiveName, + DirectivePrefix, ClausePrefix); const auto &AllowedOnceClauses = D->getValueAsListOfDefs("allowedOnceClauses"); - GenerateTestForAllowedClauses(AllowedOnceClauses, OS, DirectiveName, - DirectivePrefix, ClausePrefix); + GenerateCaseForVersionedClauses(AllowedOnceClauses, OS, DirectiveName, + DirectivePrefix, ClausePrefix); const auto &RequiredClauses = D->getValueAsListOfDefs("requiredClauses"); - GenerateTestForAllowedClauses(RequiredClauses, OS, DirectiveName, - DirectivePrefix, ClausePrefix); + GenerateCaseForVersionedClauses(RequiredClauses, OS, DirectiveName, + DirectivePrefix, ClausePrefix); + + OS << " default:\n"; + OS << " return false;\n"; + OS << " }\n"; // End of clauses switch + OS << " break;\n"; } - OS << " return false;\n"; - OS << "}\n"; + + OS << " }\n"; // End of directives switch + OS << " llvm_unreachable(\"Invalid " << LanguageName + << " Directive kind\");\n"; + OS << "}\n"; // End of function isAllowedClauseForDirective } // Generate the implemenation section for the enumeration in the directive @@ -291,8 +304,8 @@ GenerateGetName(Clauses, OS, "Clause", ClausePrefix, LanguageName, CppNamespace); - GenerateIsAllowedClause(Directives, OS, DirectivePrefix, ClausePrefix, - CppNamespace); + GenerateIsAllowedClause(Directives, OS, LanguageName, DirectivePrefix, + ClausePrefix, CppNamespace); } } // namespace llvm