1919#include " llvm/ADT/SmallVector.h"
2020#include " llvm/ADT/StringSet.h"
2121#include " llvm/ADT/StringSwitch.h"
22+ #include " llvm/TableGen/CodeGenHelpers.h"
2223#include " llvm/TableGen/Error.h"
2324#include " llvm/TableGen/Record.h"
2425#include " llvm/TableGen/TableGenBackend.h"
2930
3031using namespace llvm ;
3132
32- namespace {
33- // Simple RAII helper for defining ifdef-undef-endif scopes.
34- class IfDefScope {
35- public:
36- IfDefScope (StringRef Name, raw_ostream &OS) : Name(Name), OS(OS) {
37- OS << " #ifdef " << Name << " \n "
38- << " #undef " << Name << " \n " ;
39- }
40-
41- ~IfDefScope () { OS << " \n #endif // " << Name << " \n\n " ; }
42-
43- private:
44- StringRef Name;
45- raw_ostream &OS;
46- };
47- } // namespace
48-
4933namespace {
5034enum class Frontend { LLVM, Flang, Clang };
35+ } // namespace
5136
52- StringRef getFESpelling (Frontend FE) {
37+ static StringRef getFESpelling (Frontend FE) {
5338 switch (FE) {
5439 case Frontend::LLVM:
5540 return " llvm" ;
@@ -60,7 +45,6 @@ StringRef getFESpelling(Frontend FE) {
6045 }
6146 llvm_unreachable (" unknown FE kind" );
6247}
63- } // namespace
6448
6549// Get the full namespace qualifier for the directive language.
6650static std::string getQualifier (const DirectiveLanguage &DirLang,
@@ -971,11 +955,10 @@ static void generateDirectiveClauseSets(const DirectiveLanguage &DirLang,
971955 std::string IfDefName{" GEN_" };
972956 IfDefName += getFESpelling (FE).upper ();
973957 IfDefName += " _DIRECTIVE_CLAUSE_SETS" ;
974- IfDefScope Scope (IfDefName, OS );
958+ IfDefEmitter Scope (OS, IfDefName );
975959
976960 StringRef Namespace =
977961 getFESpelling (FE == Frontend::Flang ? Frontend::LLVM : FE);
978- OS << " \n " ;
979962 // The namespace has to be different for clang vs flang, as 2 structs with the
980963 // same name but different layout is UB. So just put the 'clang' on in the
981964 // clang namespace.
@@ -1016,9 +999,8 @@ static void generateDirectiveClauseMap(const DirectiveLanguage &DirLang,
1016999 std::string IfDefName{" GEN_" };
10171000 IfDefName += getFESpelling (FE).upper ();
10181001 IfDefName += " _DIRECTIVE_CLAUSE_MAP" ;
1019- IfDefScope Scope (IfDefName, OS );
1002+ IfDefEmitter Scope (OS, IfDefName );
10201003
1021- OS << " \n " ;
10221004 OS << " {\n " ;
10231005
10241006 // The namespace has to be different for clang vs flang, as 2 structs with the
@@ -1062,9 +1044,7 @@ static void generateDirectiveClauseMap(const DirectiveLanguage &DirLang,
10621044static void generateFlangClauseParserClass (const DirectiveLanguage &DirLang,
10631045 raw_ostream &OS) {
10641046
1065- IfDefScope Scope (" GEN_FLANG_CLAUSE_PARSER_CLASSES" , OS);
1066-
1067- OS << " \n " ;
1047+ IfDefEmitter Scope (OS, " GEN_FLANG_CLAUSE_PARSER_CLASSES" );
10681048
10691049 for (const Clause Clause : DirLang.getClauses ()) {
10701050 if (!Clause.getFlangClass ().empty ()) {
@@ -1089,9 +1069,8 @@ static void generateFlangClauseParserClass(const DirectiveLanguage &DirLang,
10891069static void generateFlangClauseParserClassList (const DirectiveLanguage &DirLang,
10901070 raw_ostream &OS) {
10911071
1092- IfDefScope Scope (" GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST" , OS );
1072+ IfDefEmitter Scope (OS, " GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST" );
10931073
1094- OS << " \n " ;
10951074 interleaveComma (DirLang.getClauses (), OS, [&](const Record *C) {
10961075 Clause Clause (C);
10971076 OS << Clause.getFormattedParserClassName () << " \n " ;
@@ -1102,9 +1081,8 @@ static void generateFlangClauseParserClassList(const DirectiveLanguage &DirLang,
11021081static void generateFlangClauseDump (const DirectiveLanguage &DirLang,
11031082 raw_ostream &OS) {
11041083
1105- IfDefScope Scope (" GEN_FLANG_DUMP_PARSE_TREE_CLAUSES" , OS );
1084+ IfDefEmitter Scope (OS, " GEN_FLANG_DUMP_PARSE_TREE_CLAUSES" );
11061085
1107- OS << " \n " ;
11081086 for (const Clause Clause : DirLang.getClauses ()) {
11091087 OS << " NODE(" << DirLang.getFlangClauseBaseClass () << " , "
11101088 << Clause.getFormattedParserClassName () << " )\n " ;
@@ -1116,10 +1094,9 @@ static void generateFlangClauseDump(const DirectiveLanguage &DirLang,
11161094static void generateFlangClauseUnparse (const DirectiveLanguage &DirLang,
11171095 raw_ostream &OS) {
11181096
1119- IfDefScope Scope (" GEN_FLANG_CLAUSE_UNPARSE" , OS );
1097+ IfDefEmitter Scope (OS, " GEN_FLANG_CLAUSE_UNPARSE" );
11201098
11211099 StringRef Base = DirLang.getFlangClauseBaseClass ();
1122- OS << " \n " ;
11231100
11241101 for (const Clause Clause : DirLang.getClauses ()) {
11251102 if (Clause.skipFlangUnparser ())
@@ -1172,9 +1149,8 @@ static void generateFlangClauseUnparse(const DirectiveLanguage &DirLang,
11721149static void generateFlangClauseCheckPrototypes (const DirectiveLanguage &DirLang,
11731150 raw_ostream &OS) {
11741151
1175- IfDefScope Scope (" GEN_FLANG_CLAUSE_CHECK_ENTER" , OS );
1152+ IfDefEmitter Scope (OS, " GEN_FLANG_CLAUSE_CHECK_ENTER" );
11761153
1177- OS << " \n " ;
11781154 for (const Clause Clause : DirLang.getClauses ()) {
11791155 OS << " void Enter(const parser::" << DirLang.getFlangClauseBaseClass ()
11801156 << " ::" << Clause.getFormattedParserClassName () << " &);\n " ;
@@ -1186,12 +1162,11 @@ static void generateFlangClauseCheckPrototypes(const DirectiveLanguage &DirLang,
11861162static void generateFlangClauseParserKindMap (const DirectiveLanguage &DirLang,
11871163 raw_ostream &OS) {
11881164
1189- IfDefScope Scope (" GEN_FLANG_CLAUSE_PARSER_KIND_MAP" , OS );
1165+ IfDefEmitter Scope (OS, " GEN_FLANG_CLAUSE_PARSER_KIND_MAP" );
11901166
11911167 StringRef Prefix = DirLang.getClausePrefix ();
11921168 std::string Qual = getQualifier (DirLang);
11931169
1194- OS << " \n " ;
11951170 for (const Record *R : DirLang.getClauses ()) {
11961171 Clause C (R);
11971172 OS << " if constexpr (std::is_same_v<A, parser::"
@@ -1216,11 +1191,10 @@ static void generateFlangClausesParser(const DirectiveLanguage &DirLang,
12161191 llvm::sort (Names, [](const auto &A, const auto &B) {
12171192 return A.second .Name > B.second .Name ;
12181193 });
1219- IfDefScope Scope (" GEN_FLANG_CLAUSES_PARSER" , OS );
1194+ IfDefEmitter Scope (OS, " GEN_FLANG_CLAUSES_PARSER" );
12201195 StringRef Base = DirLang.getFlangClauseBaseClass ();
12211196
12221197 unsigned LastIndex = Names.size () - 1 ;
1223- OS << " \n " ;
12241198 OS << " TYPE_PARSER(\n " ;
12251199 for (auto [Index, RecSp] : llvm::enumerate (Names)) {
12261200 auto [R, S] = RecSp;
@@ -1313,10 +1287,9 @@ static void emitDirectivesFlangImpl(const DirectiveLanguage &DirLang,
13131287static void generateClauseClassMacro (const DirectiveLanguage &DirLang,
13141288 raw_ostream &OS) {
13151289 // Generate macros style information for legacy code in clang
1316- IfDefScope Scope (" GEN_CLANG_CLAUSE_CLASS" , OS );
1290+ IfDefEmitter Scope (OS, " GEN_CLANG_CLAUSE_CLASS" );
13171291
13181292 StringRef Prefix = DirLang.getClausePrefix ();
1319- OS << " \n " ;
13201293
13211294 OS << " #ifndef CLAUSE\n " ;
13221295 OS << " #define CLAUSE(Enum, Str, Implicit)\n " ;
@@ -1375,12 +1348,11 @@ static void generateClauseClassMacro(const DirectiveLanguage &DirLang,
13751348// language. This code can be included in library.
13761349void emitDirectivesBasicImpl (const DirectiveLanguage &DirLang,
13771350 raw_ostream &OS) {
1378- IfDefScope Scope (" GEN_DIRECTIVES_IMPL" , OS );
1351+ IfDefEmitter Scope (OS, " GEN_DIRECTIVES_IMPL" );
13791352
13801353 StringRef DPrefix = DirLang.getDirectivePrefix ();
13811354 StringRef CPrefix = DirLang.getClausePrefix ();
13821355
1383- OS << " \n " ;
13841356 OS << " #include \" llvm/Frontend/Directive/Spelling.h\"\n " ;
13851357 OS << " #include \" llvm/Support/ErrorHandling.h\"\n " ;
13861358 OS << " #include <utility>\n " ;
0 commit comments