Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/utils/TableGen/ClangBuiltinTemplatesEmitter.cpp
213766 views
1
//=- ClangBuiltinsEmitter.cpp - Generate Clang builtin templates-*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This tablegen backend emits Clang's builtin templates.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "TableGenBackends.h"
14
#include "llvm/ADT/StringSet.h"
15
#include "llvm/TableGen/Error.h"
16
#include "llvm/TableGen/TableGenBackend.h"
17
18
#include <sstream>
19
20
using namespace llvm;
21
22
static std::string TemplateNameList;
23
static std::string CreateBuiltinTemplateParameterList;
24
25
static llvm::StringSet<> BuiltinClasses;
26
27
namespace {
28
struct ParserState {
29
size_t UniqueCounter = 0;
30
size_t CurrentDepth = 0;
31
bool EmittedSizeTInfo = false;
32
bool EmittedUint32TInfo = false;
33
};
34
35
std::pair<std::string, std::string>
36
ParseTemplateParameterList(ParserState &PS,
37
ArrayRef<const Record *> TemplateArgs) {
38
llvm::SmallVector<std::string, 4> Params;
39
llvm::StringMap<std::string> TemplateNameToParmName;
40
41
std::ostringstream Code;
42
Code << std::boolalpha;
43
44
size_t Position = 0;
45
for (const Record *Arg : TemplateArgs) {
46
std::string ParmName = "Parm" + std::to_string(PS.UniqueCounter++);
47
if (Arg->isSubClassOf("Template")) {
48
++PS.CurrentDepth;
49
auto [TemplateCode, TPLName] =
50
ParseTemplateParameterList(PS, Arg->getValueAsListOfDefs("Args"));
51
--PS.CurrentDepth;
52
Code << TemplateCode << " auto *" << ParmName
53
<< " = TemplateTemplateParmDecl::Create(C, DC, SourceLocation(), "
54
<< PS.CurrentDepth << ", " << Position++
55
<< ", /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, "
56
<< TPLName << ");\n";
57
} else if (Arg->isSubClassOf("Class")) {
58
Code << " auto *" << ParmName
59
<< " = TemplateTypeParmDecl::Create(C, DC, SourceLocation(), "
60
"SourceLocation(), "
61
<< PS.CurrentDepth << ", " << Position++
62
<< ", /*Id=*/nullptr, /*Typename=*/false, "
63
<< Arg->getValueAsBit("IsVariadic") << ");\n";
64
} else if (Arg->isSubClassOf("NTTP")) {
65
auto Type = Arg->getValueAsString("TypeName");
66
67
if (!TemplateNameToParmName.contains(Type.str()))
68
PrintFatalError("Unknown Type Name");
69
70
auto TSIName = "TSI" + std::to_string(PS.UniqueCounter++);
71
Code << " auto *" << TSIName << " = C.getTrivialTypeSourceInfo(QualType("
72
<< TemplateNameToParmName[Type.str()] << "->getTypeForDecl(), 0));\n"
73
<< " auto *" << ParmName
74
<< " = NonTypeTemplateParmDecl::Create(C, DC, SourceLocation(), "
75
"SourceLocation(), "
76
<< PS.CurrentDepth << ", " << Position++ << ", /*Id=*/nullptr, "
77
<< TSIName << "->getType(), " << Arg->getValueAsBit("IsVariadic")
78
<< ", " << TSIName << ");\n";
79
} else if (Arg->isSubClassOf("BuiltinNTTP")) {
80
std::string SourceInfo;
81
if (Arg->getValueAsString("TypeName") == "size_t") {
82
SourceInfo = "SizeTInfo";
83
if (!PS.EmittedSizeTInfo) {
84
Code << "TypeSourceInfo *SizeTInfo = "
85
"C.getTrivialTypeSourceInfo(C.getSizeType());\n";
86
PS.EmittedSizeTInfo = true;
87
}
88
} else if (Arg->getValueAsString("TypeName") == "uint32_t") {
89
SourceInfo = "Uint32TInfo";
90
if (!PS.EmittedUint32TInfo) {
91
Code << "TypeSourceInfo *Uint32TInfo = "
92
"C.getTrivialTypeSourceInfo(C.UnsignedIntTy);\n";
93
PS.EmittedUint32TInfo = true;
94
}
95
} else {
96
PrintFatalError("Unknown Type Name");
97
}
98
Code << " auto *" << ParmName
99
<< " = NonTypeTemplateParmDecl::Create(C, DC, SourceLocation(), "
100
"SourceLocation(), "
101
<< PS.CurrentDepth << ", " << Position++ << ", /*Id=*/nullptr, "
102
<< SourceInfo
103
<< "->getType(), "
104
"/*ParameterPack=*/false, "
105
<< SourceInfo << ");\n";
106
} else {
107
PrintFatalError("Unknown Argument Type");
108
}
109
110
TemplateNameToParmName[Arg->getValueAsString("Name").str()] = ParmName;
111
Params.emplace_back(std::move(ParmName));
112
}
113
114
auto TPLName = "TPL" + std::to_string(PS.UniqueCounter++);
115
Code << " auto *" << TPLName
116
<< " = TemplateParameterList::Create(C, SourceLocation(), "
117
"SourceLocation(), {";
118
119
if (Params.empty()) {
120
PrintFatalError(
121
"Expected at least one argument in template parameter list");
122
}
123
124
bool First = true;
125
for (const auto &e : Params) {
126
if (First) {
127
First = false;
128
Code << e;
129
} else {
130
Code << ", " << e;
131
}
132
}
133
Code << "}, SourceLocation(), nullptr);\n";
134
135
return {std::move(Code).str(), std::move(TPLName)};
136
}
137
138
static void
139
EmitCreateBuiltinTemplateParameterList(std::vector<const Record *> TemplateArgs,
140
StringRef Name) {
141
using namespace std::string_literals;
142
CreateBuiltinTemplateParameterList +=
143
"case BTK"s + std::string{Name} + ": {\n"s;
144
145
ParserState PS;
146
auto [Code, TPLName] = ParseTemplateParameterList(PS, TemplateArgs);
147
CreateBuiltinTemplateParameterList += Code + "\n return " + TPLName + ";\n";
148
149
CreateBuiltinTemplateParameterList += " }\n";
150
}
151
152
void EmitBuiltinTemplate(const Record *BuiltinTemplate) {
153
auto Class = BuiltinTemplate->getType()->getAsString();
154
auto Name = BuiltinTemplate->getName();
155
156
std::vector<const Record *> TemplateHead =
157
BuiltinTemplate->getValueAsListOfDefs("TemplateHead");
158
159
EmitCreateBuiltinTemplateParameterList(TemplateHead, Name);
160
161
TemplateNameList += Class + "(";
162
TemplateNameList += Name;
163
TemplateNameList += ")\n";
164
165
BuiltinClasses.insert(Class);
166
}
167
168
void EmitDefaultDefine(llvm::raw_ostream &OS, StringRef Name) {
169
OS << "#ifndef " << Name << "\n";
170
OS << "#define " << Name << "(NAME)" << " " << "BuiltinTemplate"
171
<< "(NAME)\n";
172
OS << "#endif\n\n";
173
}
174
175
void EmitUndef(llvm::raw_ostream &OS, StringRef Name) {
176
OS << "#undef " << Name << "\n";
177
}
178
} // namespace
179
180
void clang::EmitClangBuiltinTemplates(const llvm::RecordKeeper &Records,
181
llvm::raw_ostream &OS) {
182
emitSourceFileHeader("Tables and code for Clang's builtin templates", OS);
183
184
for (const auto *Builtin :
185
Records.getAllDerivedDefinitions("BuiltinTemplate"))
186
EmitBuiltinTemplate(Builtin);
187
188
for (const auto &ClassEntry : BuiltinClasses) {
189
StringRef Class = ClassEntry.getKey();
190
if (Class == "BuiltinTemplate")
191
continue;
192
EmitDefaultDefine(OS, Class);
193
}
194
195
OS << "#if defined(CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST)\n"
196
<< CreateBuiltinTemplateParameterList
197
<< "#undef CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST\n#else\n"
198
<< TemplateNameList << "#undef BuiltinTemplate\n#endif\n";
199
200
for (const auto &ClassEntry : BuiltinClasses) {
201
StringRef Class = ClassEntry.getKey();
202
if (Class == "BuiltinTemplate")
203
continue;
204
EmitUndef(OS, Class);
205
}
206
}
207
208