1// RUN: llvm-tblgen -gen-directive-decl -I %p/../../include %s | FileCheck -match-full-lines %s 2// RUN: llvm-tblgen -gen-directive-impl -I %p/../../include %s | FileCheck -match-full-lines %s -check-prefix=IMPL 3 4include "llvm/Frontend/Directive/DirectiveBase.td" 5 6def TestDirectiveLanguage : DirectiveLanguage { 7 let name = "Tdl"; 8 9 let cppNamespace = "tdl"; 10 let directivePrefix = "TDLD_"; 11 let clausePrefix = "TDLC_"; 12 let includeHeader = "tdl.h.inc"; 13 let flangClauseBaseClass = "TdlClause"; 14} 15 16def TDLC_ClauseA : Clause<"clausea"> { 17 let isImplicit = 1; 18} 19def TDLC_ClauseB : Clause<"clauseb"> { 20 let isDefault = 1; 21 let flangClass = "IntExpr"; 22 let isValueList = 1; 23} 24def TDLC_ClauseC : Clause<"clausec"> { 25 let clangClass = "ClauseC"; 26 let flangClass = "Name"; 27 let defaultValue = "*"; 28 let isValueOptional = 1; 29} 30def TDLC_ClauseD : Clause<"claused"> { 31 let clangClass = "ClauseD"; 32 let isImplicit = 1; 33} 34 35def TDL_DirA : Directive<"dira"> { 36 let allowedClauses = [ 37 VersionedClause<TDLC_ClauseA, 2, 4>, 38 VersionedClause<TDLC_ClauseB, 2> 39 ]; 40 let isDefault = 1; 41 let association = AS_Block; 42 let category = CA_Declarative; 43} 44 45// CHECK: #ifndef LLVM_Tdl_INC 46// CHECK-NEXT: #define LLVM_Tdl_INC 47// CHECK-EMPTY: 48// CHECK-NEXT: #include "llvm/ADT/ArrayRef.h" 49// CHECK-NEXT: #include "llvm/Support/Compiler.h" 50// CHECK-NEXT: #include <cstddef> 51// CHECK-EMPTY: 52// CHECK-NEXT: namespace llvm { 53// CHECK-NEXT: class StringRef; 54// CHECK-NEXT: namespace tdl { 55// CHECK-EMPTY: 56// CHECK-NEXT: enum class Association { 57// CHECK-NEXT: Block, 58// CHECK-NEXT: Declaration, 59// CHECK-NEXT: Delimited, 60// CHECK-NEXT: Loop, 61// CHECK-NEXT: None, 62// CHECK-NEXT: Separating, 63// CHECK-NEXT: }; 64// CHECK-EMPTY: 65// CHECK-NEXT: static constexpr std::size_t Association_enumSize = 6; 66// CHECK-EMPTY: 67// CHECK-NEXT: enum class Category { 68// CHECK-NEXT: Declarative, 69// CHECK-NEXT: Executable, 70// CHECK-NEXT: Informational, 71// CHECK-NEXT: Meta, 72// CHECK-NEXT: Subsidiary, 73// CHECK-NEXT: Utility, 74// CHECK-NEXT: }; 75// CHECK-EMPTY: 76// CHECK-NEXT: static constexpr std::size_t Category_enumSize = 6; 77// CHECK-EMPTY: 78// CHECK-NEXT: enum class Directive { 79// CHECK-NEXT: TDLD_dira, 80// CHECK-NEXT: }; 81// CHECK-EMPTY: 82// CHECK-NEXT: static constexpr std::size_t Directive_enumSize = 1; 83// CHECK-EMPTY: 84// CHECK-NEXT: enum class Clause { 85// CHECK-NEXT: TDLC_clausea, 86// CHECK-NEXT: TDLC_clauseb, 87// CHECK-NEXT: TDLC_clausec, 88// CHECK-NEXT: TDLC_claused, 89// CHECK-NEXT: }; 90// CHECK-EMPTY: 91// CHECK-NEXT: static constexpr std::size_t Clause_enumSize = 4; 92// CHECK-EMPTY: 93// CHECK-NEXT: // Enumeration helper functions 94// CHECK-NEXT: LLVM_ABI Directive getTdlDirectiveKind(llvm::StringRef Str); 95// CHECK-EMPTY: 96// CHECK-NEXT: LLVM_ABI llvm::StringRef getTdlDirectiveName(Directive D); 97// CHECK-EMPTY: 98// CHECK-NEXT: LLVM_ABI Clause getTdlClauseKind(llvm::StringRef Str); 99// CHECK-EMPTY: 100// CHECK-NEXT: LLVM_ABI llvm::StringRef getTdlClauseName(Clause C); 101// CHECK-EMPTY: 102// CHECK-NEXT: /// Return true if \p C is a valid clause for \p D in version \p Version. 103// CHECK-NEXT: LLVM_ABI bool isAllowedClauseForDirective(Directive D, Clause C, unsigned Version); 104// CHECK-EMPTY: 105// CHECK-NEXT: constexpr std::size_t getMaxLeafCount() { return 0; } 106// CHECK-NEXT: LLVM_ABI Association getDirectiveAssociation(Directive D); 107// CHECK-NEXT: LLVM_ABI Category getDirectiveCategory(Directive D); 108// CHECK-NEXT: } // namespace tdl 109// CHECK-NEXT: } // namespace llvm 110// CHECK-NEXT: #endif // LLVM_Tdl_INC 111 112// IMPL: #ifdef GEN_FLANG_DIRECTIVE_CLAUSE_SETS 113// IMPL-NEXT: #undef GEN_FLANG_DIRECTIVE_CLAUSE_SETS 114// IMPL-EMPTY: 115// IMPL-NEXT: namespace llvm { 116// IMPL-NEXT: namespace tdl { 117// IMPL-EMPTY: 118// IMPL-NEXT: // Sets for dira 119// IMPL-EMPTY: 120// IMPL-NEXT: static allowedClauses_TDLD_dira { 121// IMPL-NEXT: llvm::tdl::Clause::TDLC_clausea, 122// IMPL-NEXT: llvm::tdl::Clause::TDLC_clauseb, 123// IMPL-NEXT: }; 124// IMPL-EMPTY: 125// IMPL-NEXT: static allowedOnceClauses_TDLD_dira { 126// IMPL-NEXT: }; 127// IMPL-EMPTY: 128// IMPL-NEXT: static allowedExclusiveClauses_TDLD_dira { 129// IMPL-NEXT: }; 130// IMPL-EMPTY: 131// IMPL-NEXT: static requiredClauses_TDLD_dira { 132// IMPL-NEXT: }; 133// IMPL-NEXT: } // namespace tdl 134// IMPL-NEXT: } // namespace llvm 135// IMPL-EMPTY: 136// IMPL-NEXT: #endif // GEN_FLANG_DIRECTIVE_CLAUSE_SETS 137// IMPL-EMPTY: 138// IMPL-NEXT: #ifdef GEN_FLANG_DIRECTIVE_CLAUSE_MAP 139// IMPL-NEXT: #undef GEN_FLANG_DIRECTIVE_CLAUSE_MAP 140// IMPL-EMPTY: 141// IMPL-NEXT: { 142// IMPL-NEXT: {llvm::tdl::Directive::TDLD_dira, 143// IMPL-NEXT: { 144// IMPL-NEXT: llvm::tdl::allowedClauses_TDLD_dira, 145// IMPL-NEXT: llvm::tdl::allowedOnceClauses_TDLD_dira, 146// IMPL-NEXT: llvm::tdl::allowedExclusiveClauses_TDLD_dira, 147// IMPL-NEXT: llvm::tdl::requiredClauses_TDLD_dira, 148// IMPL-NEXT: } 149// IMPL-NEXT: }, 150// IMPL-NEXT: } 151// IMPL-EMPTY: 152// IMPL-NEXT: #endif // GEN_FLANG_DIRECTIVE_CLAUSE_MAP 153// IMPL-EMPTY: 154// IMPL-NEXT: #ifdef GEN_FLANG_CLAUSE_PARSER_CLASSES 155// IMPL-NEXT: #undef GEN_FLANG_CLAUSE_PARSER_CLASSES 156// IMPL-EMPTY: 157// IMPL-NEXT: EMPTY_CLASS(Clausea); 158// IMPL-NEXT: WRAPPER_CLASS(Clauseb, std::list<IntExpr>); 159// IMPL-NEXT: WRAPPER_CLASS(Clausec, std::optional<Name>); 160// IMPL-NEXT: EMPTY_CLASS(Claused); 161// IMPL-EMPTY: 162// IMPL-NEXT: #endif // GEN_FLANG_CLAUSE_PARSER_CLASSES 163// IMPL-EMPTY: 164// IMPL-NEXT: #ifdef GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST 165// IMPL-NEXT: #undef GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST 166// IMPL-EMPTY: 167// IMPL-NEXT: Clausea 168// IMPL-NEXT: , Clauseb 169// IMPL-NEXT: , Clausec 170// IMPL-NEXT: , Claused 171// IMPL-EMPTY: 172// IMPL-NEXT: #endif // GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST 173// IMPL-EMPTY: 174// IMPL-NEXT: #ifdef GEN_FLANG_DUMP_PARSE_TREE_CLAUSES 175// IMPL-NEXT: #undef GEN_FLANG_DUMP_PARSE_TREE_CLAUSES 176// IMPL-EMPTY: 177// IMPL-NEXT: NODE(TdlClause, Clausea) 178// IMPL-NEXT: NODE(TdlClause, Clauseb) 179// IMPL-NEXT: NODE(TdlClause, Clausec) 180// IMPL-NEXT: NODE(TdlClause, Claused) 181// IMPL-EMPTY: 182// IMPL-NEXT: #endif // GEN_FLANG_DUMP_PARSE_TREE_CLAUSES 183// IMPL-EMPTY: 184// IMPL-NEXT: #ifdef GEN_FLANG_CLAUSE_UNPARSE 185// IMPL-NEXT: #undef GEN_FLANG_CLAUSE_UNPARSE 186// IMPL-EMPTY: 187// IMPL-NEXT: void Before(const TdlClause::Clausea &) { Word("CLAUSEA"); } 188// IMPL-NEXT: void Unparse(const TdlClause::Clauseb &x) { 189// IMPL-NEXT: Word("CLAUSEB"); 190// IMPL-NEXT: Put("("); 191// IMPL-NEXT: Walk(x.v, ","); 192// IMPL-NEXT: Put(")"); 193// IMPL-NEXT: } 194// IMPL-NEXT: void Unparse(const TdlClause::Clausec &x) { 195// IMPL-NEXT: Word("CLAUSEC"); 196// IMPL-NEXT: Put("("); 197// IMPL-NEXT: if (x.v.has_value()) 198// IMPL-NEXT: Walk(x.v); 199// IMPL-NEXT: else 200// IMPL-NEXT: Put("*"); 201// IMPL-NEXT: Put(")"); 202// IMPL-NEXT: } 203// IMPL-NEXT: void Before(const TdlClause::Claused &) { Word("CLAUSED"); } 204// IMPL-EMPTY: 205// IMPL-NEXT: #endif // GEN_FLANG_CLAUSE_UNPARSE 206 207// IMPL: #ifdef GEN_CLANG_CLAUSE_CLASS 208// IMPL-NEXT: #undef GEN_CLANG_CLAUSE_CLASS 209// IMPL-EMPTY: 210// IMPL-NEXT: #ifndef CLAUSE 211// IMPL-NEXT: #define CLAUSE(Enum, Str, Implicit) 212// IMPL-NEXT: #endif 213// IMPL-NEXT: #ifndef CLAUSE_CLASS 214// IMPL-NEXT: #define CLAUSE_CLASS(Enum, Str, Class) 215// IMPL-NEXT: #endif 216// IMPL-NEXT: #ifndef CLAUSE_NO_CLASS 217// IMPL-NEXT: #define CLAUSE_NO_CLASS(Enum, Str) 218// IMPL-NEXT: #endif 219// IMPL-EMPTY: 220// IMPL-NEXT: #define __CLAUSE(Name, Class) \ 221// IMPL-NEXT: CLAUSE(TDLC_##Name, #Name, /* Implicit */ false) \ 222// IMPL-NEXT: CLAUSE_CLASS(TDLC_##Name, #Name, Class) 223// IMPL-NEXT: #define __CLAUSE_NO_CLASS(Name) \ 224// IMPL-NEXT: CLAUSE(TDLC_##Name, #Name, /* Implicit */ false) \ 225// IMPL-NEXT: CLAUSE_NO_CLASS(TDLC_##Name, #Name) 226// IMPL-NEXT: #define __IMPLICIT_CLAUSE_CLASS(Name, Str, Class) \ 227// IMPL-NEXT: CLAUSE(TDLC_##Name, Str, /* Implicit */ true) \ 228// IMPL-NEXT: CLAUSE_CLASS(TDLC_##Name, Str, Class) 229// IMPL-NEXT: #define __IMPLICIT_CLAUSE_NO_CLASS(Name, Str) \ 230// IMPL-NEXT: CLAUSE(TDLC_##Name, Str, /* Implicit */ true) \ 231// IMPL-NEXT: CLAUSE_NO_CLASS(TDLC_##Name, Str) 232// IMPL-EMPTY: 233// IMPL-NEXT: __IMPLICIT_CLAUSE_NO_CLASS(clausea, "clausea") 234// IMPL-NEXT: __CLAUSE_NO_CLASS(clauseb) 235// IMPL-NEXT: __CLAUSE(clausec, ClauseC) 236// IMPL-NEXT: __IMPLICIT_CLAUSE_CLASS(claused, "claused", ClauseD) 237// IMPL-EMPTY: 238// IMPL-NEXT: #undef __IMPLICIT_CLAUSE_NO_CLASS 239// IMPL-NEXT: #undef __IMPLICIT_CLAUSE_CLASS 240// IMPL-NEXT: #undef __CLAUSE_NO_CLASS 241// IMPL-NEXT: #undef __CLAUSE 242// IMPL-NEXT: #undef CLAUSE_NO_CLASS 243// IMPL-NEXT: #undef CLAUSE_CLASS 244// IMPL-NEXT: #undef CLAUSE 245// IMPL-EMPTY: 246// IMPL-NEXT: #endif // GEN_CLANG_CLAUSE_CLASS 247 248// IMPL: #ifdef GEN_DIRECTIVES_IMPL 249// IMPL-NEXT: #undef GEN_DIRECTIVES_IMPL 250// IMPL-EMPTY: 251// IMPL-NEXT: #include "llvm/Support/ErrorHandling.h" 252// IMPL-EMPTY: 253// IMPL-NEXT: Directive llvm::tdl::getTdlDirectiveKind(llvm::StringRef Str) { 254// IMPL-NEXT: return llvm::StringSwitch<Directive>(Str) 255// IMPL-NEXT: .Case("dira",TDLD_dira) 256// IMPL-NEXT: .Default(TDLD_dira); 257// IMPL-NEXT: } 258// IMPL-EMPTY: 259// IMPL-NEXT: llvm::StringRef llvm::tdl::getTdlDirectiveName(Directive Kind) { 260// IMPL-NEXT: switch (Kind) { 261// IMPL-NEXT: case TDLD_dira: 262// IMPL-NEXT: return "dira"; 263// IMPL-NEXT: } 264// IMPL-NEXT: llvm_unreachable("Invalid Tdl Directive kind"); 265// IMPL-NEXT: } 266// IMPL-EMPTY: 267// IMPL-NEXT: Clause llvm::tdl::getTdlClauseKind(llvm::StringRef Str) { 268// IMPL-NEXT: return llvm::StringSwitch<Clause>(Str) 269// IMPL-NEXT: .Case("clausea",TDLC_clauseb) 270// IMPL-NEXT: .Case("clauseb",TDLC_clauseb) 271// IMPL-NEXT: .Case("clausec",TDLC_clausec) 272// IMPL-NEXT: .Case("claused",TDLC_clauseb) 273// IMPL-NEXT: .Default(TDLC_clauseb); 274// IMPL-NEXT: } 275// IMPL-EMPTY: 276// IMPL-NEXT: llvm::StringRef llvm::tdl::getTdlClauseName(Clause Kind) { 277// IMPL-NEXT: switch (Kind) { 278// IMPL-NEXT: case TDLC_clausea: 279// IMPL-NEXT: return "clausea"; 280// IMPL-NEXT: case TDLC_clauseb: 281// IMPL-NEXT: return "clauseb"; 282// IMPL-NEXT: case TDLC_clausec: 283// IMPL-NEXT: return "clausec"; 284// IMPL-NEXT: case TDLC_claused: 285// IMPL-NEXT: return "claused"; 286// IMPL-NEXT: } 287// IMPL-NEXT: llvm_unreachable("Invalid Tdl Clause kind"); 288// IMPL-NEXT: } 289// IMPL-EMPTY: 290// IMPL-NEXT: bool llvm::tdl::isAllowedClauseForDirective(Directive D, Clause C, unsigned Version) { 291// IMPL-NEXT: assert(unsigned(D) <= llvm::tdl::Directive_enumSize); 292// IMPL-NEXT: assert(unsigned(C) <= llvm::tdl::Clause_enumSize); 293// IMPL-NEXT: switch (D) { 294// IMPL-NEXT: case TDLD_dira: 295// IMPL-NEXT: switch (C) { 296// IMPL-NEXT: case TDLC_clausea: 297// IMPL-NEXT: return 2 <= Version && 4 >= Version; 298// IMPL-NEXT: case TDLC_clauseb: 299// IMPL-NEXT: return 2 <= Version && 2147483647 >= Version; 300// IMPL-NEXT: default: 301// IMPL-NEXT: return false; 302// IMPL-NEXT: } 303// IMPL-NEXT: break; 304// IMPL-NEXT: } 305// IMPL-NEXT: llvm_unreachable("Invalid Tdl Directive kind"); 306// IMPL-NEXT: } 307// IMPL-EMPTY: 308// IMPL-NEXT: llvm::tdl::Association llvm::tdl::getDirectiveAssociation(llvm::tdl::Directive Dir) { 309// IMPL-NEXT: switch (Dir) { 310// IMPL-NEXT: case llvm::tdl::Directive::TDLD_dira: 311// IMPL-NEXT: return llvm::tdl::Association::Block; 312// IMPL-NEXT: } // switch (Dir) 313// IMPL-NEXT: llvm_unreachable("Unexpected directive"); 314// IMPL-NEXT: } 315// IMPL-EMPTY: 316// IMPL-NEXT: llvm::tdl::Category llvm::tdl::getDirectiveCategory(llvm::tdl::Directive Dir) { 317// IMPL-NEXT: switch (Dir) { 318// IMPL-NEXT: case llvm::tdl::TDLD_dira: 319// IMPL-NEXT: return llvm::tdl::Category::Declarative; 320// IMPL-NEXT: } // switch (Dir) 321// IMPL-NEXT: llvm_unreachable("Unexpected directive"); 322// IMPL-NEXT: } 323// IMPL-EMPTY: 324// IMPL-NEXT: static_assert(sizeof(llvm::tdl::Directive) == sizeof(int)); 325// IMPL-NEXT: {{.*}} static const llvm::tdl::Directive LeafConstructTable[][2] = { 326// IMPL-NEXT: {llvm::tdl::TDLD_dira, static_cast<llvm::tdl::Directive>(0),}, 327// IMPL-NEXT: }; 328// IMPL-EMPTY: 329// IMPL-NEXT: {{.*}} static auto LeafConstructTableEndDirective = LeafConstructTable + 1; 330// IMPL-EMPTY: 331// IMPL-NEXT: {{.*}} static const int LeafConstructTableOrdering[] = { 332// IMPL-NEXT: 0, 333// IMPL-NEXT: }; 334// IMPL-EMPTY: 335// IMPL-NEXT: #endif // GEN_DIRECTIVES_IMPL 336