19
19
#include " llvm/ADT/SmallVector.h"
20
20
#include " llvm/ADT/StringSet.h"
21
21
#include " llvm/ADT/StringSwitch.h"
22
+ #include " llvm/TableGen/CodeGenHelpers.h"
22
23
#include " llvm/TableGen/Error.h"
23
24
#include " llvm/TableGen/Record.h"
24
25
#include " llvm/TableGen/TableGenBackend.h"
29
30
30
31
using namespace llvm ;
31
32
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
-
49
33
namespace {
50
34
enum class Frontend { LLVM, Flang, Clang };
35
+ } // namespace
51
36
52
- StringRef getFESpelling (Frontend FE) {
37
+ static StringRef getFESpelling (Frontend FE) {
53
38
switch (FE) {
54
39
case Frontend::LLVM:
55
40
return " llvm" ;
@@ -60,7 +45,6 @@ StringRef getFESpelling(Frontend FE) {
60
45
}
61
46
llvm_unreachable (" unknown FE kind" );
62
47
}
63
- } // namespace
64
48
65
49
// Get the full namespace qualifier for the directive language.
66
50
static std::string getQualifier (const DirectiveLanguage &DirLang,
@@ -297,13 +281,8 @@ static void emitDirectivesDecl(const RecordKeeper &Records, raw_ostream &OS) {
297
281
OS << " #include <cstddef>\n " ; // for size_t
298
282
OS << " #include <utility>\n " ; // for std::pair
299
283
OS << " \n " ;
300
- OS << " namespace llvm {\n " ;
301
-
302
- // Open namespaces defined in the directive language
303
- SmallVector<StringRef, 2 > Namespaces;
304
- SplitString (DirLang.getCppNamespace (), Namespaces, " ::" );
305
- for (auto Ns : Namespaces)
306
- OS << " namespace " << Ns << " {\n " ;
284
+ NamespaceEmitter LlvmNS (OS, " llvm" );
285
+ NamespaceEmitter DirLangNS (OS, DirLang.getCppNamespace ());
307
286
308
287
if (DirLang.hasEnableBitmaskEnumInNamespace ())
309
288
OS << " \n LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();\n " ;
@@ -380,9 +359,7 @@ static void emitDirectivesDecl(const RecordKeeper &Records, raw_ostream &OS) {
380
359
OS << " \n " ;
381
360
}
382
361
383
- // Closing namespaces
384
- for (auto Ns : reverse (Namespaces))
385
- OS << " } // namespace " << Ns << " \n " ;
362
+ DirLangNS.close ();
386
363
387
364
// These specializations need to be in ::llvm.
388
365
for (StringRef Enum : {" Association" , " Category" , " Directive" , " Clause" }) {
@@ -392,9 +369,7 @@ static void emitDirectivesDecl(const RecordKeeper &Records, raw_ostream &OS) {
392
369
OS << " static constexpr bool is_iterable = true;\n " ;
393
370
OS << " };\n " ;
394
371
}
395
-
396
- OS << " } // namespace llvm\n " ;
397
-
372
+ LlvmNS.close ();
398
373
OS << " #endif // LLVM_" << Lang << " _INC\n " ;
399
374
}
400
375
@@ -971,11 +946,10 @@ static void generateDirectiveClauseSets(const DirectiveLanguage &DirLang,
971
946
std::string IfDefName{" GEN_" };
972
947
IfDefName += getFESpelling (FE).upper ();
973
948
IfDefName += " _DIRECTIVE_CLAUSE_SETS" ;
974
- IfDefScope Scope (IfDefName, OS );
949
+ IfDefEmitter Scope (OS, IfDefName );
975
950
976
951
StringRef Namespace =
977
952
getFESpelling (FE == Frontend::Flang ? Frontend::LLVM : FE);
978
- OS << " \n " ;
979
953
// The namespace has to be different for clang vs flang, as 2 structs with the
980
954
// same name but different layout is UB. So just put the 'clang' on in the
981
955
// clang namespace.
@@ -1016,9 +990,8 @@ static void generateDirectiveClauseMap(const DirectiveLanguage &DirLang,
1016
990
std::string IfDefName{" GEN_" };
1017
991
IfDefName += getFESpelling (FE).upper ();
1018
992
IfDefName += " _DIRECTIVE_CLAUSE_MAP" ;
1019
- IfDefScope Scope (IfDefName, OS );
993
+ IfDefEmitter Scope (OS, IfDefName );
1020
994
1021
- OS << " \n " ;
1022
995
OS << " {\n " ;
1023
996
1024
997
// The namespace has to be different for clang vs flang, as 2 structs with the
@@ -1062,9 +1035,7 @@ static void generateDirectiveClauseMap(const DirectiveLanguage &DirLang,
1062
1035
static void generateFlangClauseParserClass (const DirectiveLanguage &DirLang,
1063
1036
raw_ostream &OS) {
1064
1037
1065
- IfDefScope Scope (" GEN_FLANG_CLAUSE_PARSER_CLASSES" , OS);
1066
-
1067
- OS << " \n " ;
1038
+ IfDefEmitter Scope (OS, " GEN_FLANG_CLAUSE_PARSER_CLASSES" );
1068
1039
1069
1040
for (const Clause Clause : DirLang.getClauses ()) {
1070
1041
if (!Clause.getFlangClass ().empty ()) {
@@ -1089,9 +1060,8 @@ static void generateFlangClauseParserClass(const DirectiveLanguage &DirLang,
1089
1060
static void generateFlangClauseParserClassList (const DirectiveLanguage &DirLang,
1090
1061
raw_ostream &OS) {
1091
1062
1092
- IfDefScope Scope (" GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST" , OS );
1063
+ IfDefEmitter Scope (OS, " GEN_FLANG_CLAUSE_PARSER_CLASSES_LIST" );
1093
1064
1094
- OS << " \n " ;
1095
1065
interleaveComma (DirLang.getClauses (), OS, [&](const Record *C) {
1096
1066
Clause Clause (C);
1097
1067
OS << Clause.getFormattedParserClassName () << " \n " ;
@@ -1102,9 +1072,8 @@ static void generateFlangClauseParserClassList(const DirectiveLanguage &DirLang,
1102
1072
static void generateFlangClauseDump (const DirectiveLanguage &DirLang,
1103
1073
raw_ostream &OS) {
1104
1074
1105
- IfDefScope Scope (" GEN_FLANG_DUMP_PARSE_TREE_CLAUSES" , OS );
1075
+ IfDefEmitter Scope (OS, " GEN_FLANG_DUMP_PARSE_TREE_CLAUSES" );
1106
1076
1107
- OS << " \n " ;
1108
1077
for (const Clause Clause : DirLang.getClauses ()) {
1109
1078
OS << " NODE(" << DirLang.getFlangClauseBaseClass () << " , "
1110
1079
<< Clause.getFormattedParserClassName () << " )\n " ;
@@ -1116,10 +1085,9 @@ static void generateFlangClauseDump(const DirectiveLanguage &DirLang,
1116
1085
static void generateFlangClauseUnparse (const DirectiveLanguage &DirLang,
1117
1086
raw_ostream &OS) {
1118
1087
1119
- IfDefScope Scope (" GEN_FLANG_CLAUSE_UNPARSE" , OS );
1088
+ IfDefEmitter Scope (OS, " GEN_FLANG_CLAUSE_UNPARSE" );
1120
1089
1121
1090
StringRef Base = DirLang.getFlangClauseBaseClass ();
1122
- OS << " \n " ;
1123
1091
1124
1092
for (const Clause Clause : DirLang.getClauses ()) {
1125
1093
if (Clause.skipFlangUnparser ())
@@ -1172,9 +1140,8 @@ static void generateFlangClauseUnparse(const DirectiveLanguage &DirLang,
1172
1140
static void generateFlangClauseCheckPrototypes (const DirectiveLanguage &DirLang,
1173
1141
raw_ostream &OS) {
1174
1142
1175
- IfDefScope Scope (" GEN_FLANG_CLAUSE_CHECK_ENTER" , OS );
1143
+ IfDefEmitter Scope (OS, " GEN_FLANG_CLAUSE_CHECK_ENTER" );
1176
1144
1177
- OS << " \n " ;
1178
1145
for (const Clause Clause : DirLang.getClauses ()) {
1179
1146
OS << " void Enter(const parser::" << DirLang.getFlangClauseBaseClass ()
1180
1147
<< " ::" << Clause.getFormattedParserClassName () << " &);\n " ;
@@ -1186,12 +1153,11 @@ static void generateFlangClauseCheckPrototypes(const DirectiveLanguage &DirLang,
1186
1153
static void generateFlangClauseParserKindMap (const DirectiveLanguage &DirLang,
1187
1154
raw_ostream &OS) {
1188
1155
1189
- IfDefScope Scope (" GEN_FLANG_CLAUSE_PARSER_KIND_MAP" , OS );
1156
+ IfDefEmitter Scope (OS, " GEN_FLANG_CLAUSE_PARSER_KIND_MAP" );
1190
1157
1191
1158
StringRef Prefix = DirLang.getClausePrefix ();
1192
1159
std::string Qual = getQualifier (DirLang);
1193
1160
1194
- OS << " \n " ;
1195
1161
for (const Record *R : DirLang.getClauses ()) {
1196
1162
Clause C (R);
1197
1163
OS << " if constexpr (std::is_same_v<A, parser::"
@@ -1216,11 +1182,10 @@ static void generateFlangClausesParser(const DirectiveLanguage &DirLang,
1216
1182
llvm::sort (Names, [](const auto &A, const auto &B) {
1217
1183
return A.second .Name > B.second .Name ;
1218
1184
});
1219
- IfDefScope Scope (" GEN_FLANG_CLAUSES_PARSER" , OS );
1185
+ IfDefEmitter Scope (OS, " GEN_FLANG_CLAUSES_PARSER" );
1220
1186
StringRef Base = DirLang.getFlangClauseBaseClass ();
1221
1187
1222
1188
unsigned LastIndex = Names.size () - 1 ;
1223
- OS << " \n " ;
1224
1189
OS << " TYPE_PARSER(\n " ;
1225
1190
for (auto [Index, RecSp] : llvm::enumerate (Names)) {
1226
1191
auto [R, S] = RecSp;
@@ -1313,10 +1278,9 @@ static void emitDirectivesFlangImpl(const DirectiveLanguage &DirLang,
1313
1278
static void generateClauseClassMacro (const DirectiveLanguage &DirLang,
1314
1279
raw_ostream &OS) {
1315
1280
// Generate macros style information for legacy code in clang
1316
- IfDefScope Scope (" GEN_CLANG_CLAUSE_CLASS" , OS );
1281
+ IfDefEmitter Scope (OS, " GEN_CLANG_CLAUSE_CLASS" );
1317
1282
1318
1283
StringRef Prefix = DirLang.getClausePrefix ();
1319
- OS << " \n " ;
1320
1284
1321
1285
OS << " #ifndef CLAUSE\n " ;
1322
1286
OS << " #define CLAUSE(Enum, Str, Implicit)\n " ;
@@ -1375,12 +1339,11 @@ static void generateClauseClassMacro(const DirectiveLanguage &DirLang,
1375
1339
// language. This code can be included in library.
1376
1340
void emitDirectivesBasicImpl (const DirectiveLanguage &DirLang,
1377
1341
raw_ostream &OS) {
1378
- IfDefScope Scope (" GEN_DIRECTIVES_IMPL" , OS );
1342
+ IfDefEmitter Scope (OS, " GEN_DIRECTIVES_IMPL" );
1379
1343
1380
1344
StringRef DPrefix = DirLang.getDirectivePrefix ();
1381
1345
StringRef CPrefix = DirLang.getClausePrefix ();
1382
1346
1383
- OS << " \n " ;
1384
1347
OS << " #include \" llvm/Frontend/Directive/Spelling.h\"\n " ;
1385
1348
OS << " #include \" llvm/Support/ErrorHandling.h\"\n " ;
1386
1349
OS << " #include <utility>\n " ;
0 commit comments