Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/utils/TableGen/ClangAttrEmitter.cpp
35230 views
1
//===- ClangAttrEmitter.cpp - Generate Clang attribute handling =-*- 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
// These tablegen backends emit Clang attribute processing code
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "TableGenBackends.h"
14
#include "ASTTableGen.h"
15
16
#include "llvm/ADT/ArrayRef.h"
17
#include "llvm/ADT/DenseMap.h"
18
#include "llvm/ADT/DenseSet.h"
19
#include "llvm/ADT/MapVector.h"
20
#include "llvm/ADT/STLExtras.h"
21
#include "llvm/ADT/SmallString.h"
22
#include "llvm/ADT/StringExtras.h"
23
#include "llvm/ADT/StringRef.h"
24
#include "llvm/ADT/StringSet.h"
25
#include "llvm/ADT/StringSwitch.h"
26
#include "llvm/ADT/iterator_range.h"
27
#include "llvm/Support/ErrorHandling.h"
28
#include "llvm/Support/raw_ostream.h"
29
#include "llvm/TableGen/Error.h"
30
#include "llvm/TableGen/Record.h"
31
#include "llvm/TableGen/StringMatcher.h"
32
#include "llvm/TableGen/TableGenBackend.h"
33
#include <algorithm>
34
#include <cassert>
35
#include <cctype>
36
#include <cstddef>
37
#include <cstdint>
38
#include <map>
39
#include <memory>
40
#include <optional>
41
#include <set>
42
#include <sstream>
43
#include <string>
44
#include <utility>
45
#include <vector>
46
47
using namespace llvm;
48
49
namespace {
50
51
class FlattenedSpelling {
52
std::string V, N, NS;
53
bool K = false;
54
const Record &OriginalSpelling;
55
56
public:
57
FlattenedSpelling(const std::string &Variety, const std::string &Name,
58
const std::string &Namespace, bool KnownToGCC,
59
const Record &OriginalSpelling)
60
: V(Variety), N(Name), NS(Namespace), K(KnownToGCC),
61
OriginalSpelling(OriginalSpelling) {}
62
explicit FlattenedSpelling(const Record &Spelling)
63
: V(std::string(Spelling.getValueAsString("Variety"))),
64
N(std::string(Spelling.getValueAsString("Name"))),
65
OriginalSpelling(Spelling) {
66
assert(V != "GCC" && V != "Clang" &&
67
"Given a GCC spelling, which means this hasn't been flattened!");
68
if (V == "CXX11" || V == "C23" || V == "Pragma")
69
NS = std::string(Spelling.getValueAsString("Namespace"));
70
}
71
72
const std::string &variety() const { return V; }
73
const std::string &name() const { return N; }
74
const std::string &nameSpace() const { return NS; }
75
bool knownToGCC() const { return K; }
76
const Record &getSpellingRecord() const { return OriginalSpelling; }
77
};
78
79
} // end anonymous namespace
80
81
static std::vector<FlattenedSpelling>
82
GetFlattenedSpellings(const Record &Attr) {
83
std::vector<Record *> Spellings = Attr.getValueAsListOfDefs("Spellings");
84
std::vector<FlattenedSpelling> Ret;
85
86
for (const auto &Spelling : Spellings) {
87
StringRef Variety = Spelling->getValueAsString("Variety");
88
StringRef Name = Spelling->getValueAsString("Name");
89
if (Variety == "GCC") {
90
Ret.emplace_back("GNU", std::string(Name), "", true, *Spelling);
91
Ret.emplace_back("CXX11", std::string(Name), "gnu", true, *Spelling);
92
if (Spelling->getValueAsBit("AllowInC"))
93
Ret.emplace_back("C23", std::string(Name), "gnu", true, *Spelling);
94
} else if (Variety == "Clang") {
95
Ret.emplace_back("GNU", std::string(Name), "", false, *Spelling);
96
Ret.emplace_back("CXX11", std::string(Name), "clang", false, *Spelling);
97
if (Spelling->getValueAsBit("AllowInC"))
98
Ret.emplace_back("C23", std::string(Name), "clang", false, *Spelling);
99
} else
100
Ret.push_back(FlattenedSpelling(*Spelling));
101
}
102
103
return Ret;
104
}
105
106
static std::string ReadPCHRecord(StringRef type) {
107
return StringSwitch<std::string>(type)
108
.EndsWith("Decl *", "Record.readDeclAs<" +
109
std::string(type.data(), 0, type.size() - 1) +
110
">()")
111
.Case("TypeSourceInfo *", "Record.readTypeSourceInfo()")
112
.Case("Expr *", "Record.readExpr()")
113
.Case("IdentifierInfo *", "Record.readIdentifier()")
114
.Case("StringRef", "Record.readString()")
115
.Case("ParamIdx", "ParamIdx::deserialize(Record.readInt())")
116
.Case("OMPTraitInfo *", "Record.readOMPTraitInfo()")
117
.Default("Record.readInt()");
118
}
119
120
// Get a type that is suitable for storing an object of the specified type.
121
static StringRef getStorageType(StringRef type) {
122
return StringSwitch<StringRef>(type)
123
.Case("StringRef", "std::string")
124
.Default(type);
125
}
126
127
// Assumes that the way to get the value is SA->getname()
128
static std::string WritePCHRecord(StringRef type, StringRef name) {
129
return "Record." +
130
StringSwitch<std::string>(type)
131
.EndsWith("Decl *", "AddDeclRef(" + std::string(name) + ");\n")
132
.Case("TypeSourceInfo *",
133
"AddTypeSourceInfo(" + std::string(name) + ");\n")
134
.Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
135
.Case("IdentifierInfo *",
136
"AddIdentifierRef(" + std::string(name) + ");\n")
137
.Case("StringRef", "AddString(" + std::string(name) + ");\n")
138
.Case("ParamIdx",
139
"push_back(" + std::string(name) + ".serialize());\n")
140
.Case("OMPTraitInfo *",
141
"writeOMPTraitInfo(" + std::string(name) + ");\n")
142
.Default("push_back(" + std::string(name) + ");\n");
143
}
144
145
// Normalize attribute name by removing leading and trailing
146
// underscores. For example, __foo, foo__, __foo__ would
147
// become foo.
148
static StringRef NormalizeAttrName(StringRef AttrName) {
149
AttrName.consume_front("__");
150
AttrName.consume_back("__");
151
return AttrName;
152
}
153
154
// Normalize the name by removing any and all leading and trailing underscores.
155
// This is different from NormalizeAttrName in that it also handles names like
156
// _pascal and __pascal.
157
static StringRef NormalizeNameForSpellingComparison(StringRef Name) {
158
return Name.trim("_");
159
}
160
161
// Normalize the spelling of a GNU attribute (i.e. "x" in "__attribute__((x))"),
162
// removing "__" if it appears at the beginning and end of the attribute's name.
163
static StringRef NormalizeGNUAttrSpelling(StringRef AttrSpelling) {
164
if (AttrSpelling.starts_with("__") && AttrSpelling.ends_with("__")) {
165
AttrSpelling = AttrSpelling.substr(2, AttrSpelling.size() - 4);
166
}
167
168
return AttrSpelling;
169
}
170
171
typedef std::vector<std::pair<std::string, const Record *>> ParsedAttrMap;
172
173
static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records,
174
ParsedAttrMap *Dupes = nullptr,
175
bool SemaOnly = true) {
176
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
177
std::set<std::string> Seen;
178
ParsedAttrMap R;
179
for (const auto *Attr : Attrs) {
180
if (!SemaOnly || Attr->getValueAsBit("SemaHandler")) {
181
std::string AN;
182
if (Attr->isSubClassOf("TargetSpecificAttr") &&
183
!Attr->isValueUnset("ParseKind")) {
184
AN = std::string(Attr->getValueAsString("ParseKind"));
185
186
// If this attribute has already been handled, it does not need to be
187
// handled again.
188
if (Seen.find(AN) != Seen.end()) {
189
if (Dupes)
190
Dupes->push_back(std::make_pair(AN, Attr));
191
continue;
192
}
193
Seen.insert(AN);
194
} else
195
AN = NormalizeAttrName(Attr->getName()).str();
196
197
R.push_back(std::make_pair(AN, Attr));
198
}
199
}
200
return R;
201
}
202
203
namespace {
204
205
class Argument {
206
std::string lowerName, upperName;
207
StringRef attrName;
208
bool isOpt;
209
bool Fake;
210
211
public:
212
Argument(StringRef Arg, StringRef Attr)
213
: lowerName(std::string(Arg)), upperName(lowerName), attrName(Attr),
214
isOpt(false), Fake(false) {
215
if (!lowerName.empty()) {
216
lowerName[0] = std::tolower(lowerName[0]);
217
upperName[0] = std::toupper(upperName[0]);
218
}
219
// Work around MinGW's macro definition of 'interface' to 'struct'. We
220
// have an attribute argument called 'Interface', so only the lower case
221
// name conflicts with the macro definition.
222
if (lowerName == "interface")
223
lowerName = "interface_";
224
}
225
Argument(const Record &Arg, StringRef Attr)
226
: Argument(Arg.getValueAsString("Name"), Attr) {}
227
virtual ~Argument() = default;
228
229
StringRef getLowerName() const { return lowerName; }
230
StringRef getUpperName() const { return upperName; }
231
StringRef getAttrName() const { return attrName; }
232
233
bool isOptional() const { return isOpt; }
234
void setOptional(bool set) { isOpt = set; }
235
236
bool isFake() const { return Fake; }
237
void setFake(bool fake) { Fake = fake; }
238
239
// These functions print the argument contents formatted in different ways.
240
virtual void writeAccessors(raw_ostream &OS) const = 0;
241
virtual void writeAccessorDefinitions(raw_ostream &OS) const {}
242
virtual void writeASTVisitorTraversal(raw_ostream &OS) const {}
243
virtual void writeCloneArgs(raw_ostream &OS) const = 0;
244
virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0;
245
virtual void writeTemplateInstantiation(raw_ostream &OS) const {}
246
virtual void writeCtorBody(raw_ostream &OS) const {}
247
virtual void writeCtorInitializers(raw_ostream &OS) const = 0;
248
virtual void writeCtorDefaultInitializers(raw_ostream &OS) const = 0;
249
virtual void writeCtorParameters(raw_ostream &OS) const = 0;
250
virtual void writeDeclarations(raw_ostream &OS) const = 0;
251
virtual void writePCHReadArgs(raw_ostream &OS) const = 0;
252
virtual void writePCHReadDecls(raw_ostream &OS) const = 0;
253
virtual void writePCHWrite(raw_ostream &OS) const = 0;
254
virtual std::string getIsOmitted() const { return "false"; }
255
virtual void writeValue(raw_ostream &OS) const = 0;
256
virtual void writeDump(raw_ostream &OS) const = 0;
257
virtual void writeDumpChildren(raw_ostream &OS) const {}
258
virtual void writeHasChildren(raw_ostream &OS) const { OS << "false"; }
259
260
virtual bool isEnumArg() const { return false; }
261
virtual bool isVariadicEnumArg() const { return false; }
262
virtual bool isVariadic() const { return false; }
263
264
virtual void writeImplicitCtorArgs(raw_ostream &OS) const {
265
OS << getUpperName();
266
}
267
};
268
269
class SimpleArgument : public Argument {
270
std::string type;
271
272
public:
273
SimpleArgument(const Record &Arg, StringRef Attr, std::string T)
274
: Argument(Arg, Attr), type(std::move(T)) {}
275
276
std::string getType() const { return type; }
277
278
void writeAccessors(raw_ostream &OS) const override {
279
OS << " " << type << " get" << getUpperName() << "() const {\n";
280
OS << " return " << getLowerName() << ";\n";
281
OS << " }";
282
}
283
284
void writeCloneArgs(raw_ostream &OS) const override {
285
OS << getLowerName();
286
}
287
288
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
289
OS << "A->get" << getUpperName() << "()";
290
}
291
292
void writeCtorInitializers(raw_ostream &OS) const override {
293
OS << getLowerName() << "(" << getUpperName() << ")";
294
}
295
296
void writeCtorDefaultInitializers(raw_ostream &OS) const override {
297
OS << getLowerName() << "()";
298
}
299
300
void writeCtorParameters(raw_ostream &OS) const override {
301
OS << type << " " << getUpperName();
302
}
303
304
void writeDeclarations(raw_ostream &OS) const override {
305
OS << type << " " << getLowerName() << ";";
306
}
307
308
void writePCHReadDecls(raw_ostream &OS) const override {
309
std::string read = ReadPCHRecord(type);
310
OS << " " << type << " " << getLowerName() << " = " << read << ";\n";
311
}
312
313
void writePCHReadArgs(raw_ostream &OS) const override {
314
OS << getLowerName();
315
}
316
317
void writePCHWrite(raw_ostream &OS) const override {
318
OS << " "
319
<< WritePCHRecord(type,
320
"SA->get" + std::string(getUpperName()) + "()");
321
}
322
323
std::string getIsOmitted() const override {
324
auto IsOneOf = [](StringRef subject, auto... list) {
325
return ((subject == list) || ...);
326
};
327
328
if (IsOneOf(type, "IdentifierInfo *", "Expr *"))
329
return "!get" + getUpperName().str() + "()";
330
if (IsOneOf(type, "TypeSourceInfo *"))
331
return "!get" + getUpperName().str() + "Loc()";
332
if (IsOneOf(type, "ParamIdx"))
333
return "!get" + getUpperName().str() + "().isValid()";
334
335
assert(IsOneOf(type, "unsigned", "int", "bool", "FunctionDecl *",
336
"VarDecl *"));
337
return "false";
338
}
339
340
void writeValue(raw_ostream &OS) const override {
341
if (type == "FunctionDecl *")
342
OS << "\" << get" << getUpperName()
343
<< "()->getNameInfo().getAsString() << \"";
344
else if (type == "IdentifierInfo *")
345
// Some non-optional (comma required) identifier arguments can be the
346
// empty string but are then recorded as a nullptr.
347
OS << "\" << (get" << getUpperName() << "() ? get" << getUpperName()
348
<< "()->getName() : \"\") << \"";
349
else if (type == "VarDecl *")
350
OS << "\" << get" << getUpperName() << "()->getName() << \"";
351
else if (type == "TypeSourceInfo *")
352
OS << "\" << get" << getUpperName() << "().getAsString() << \"";
353
else if (type == "ParamIdx")
354
OS << "\" << get" << getUpperName() << "().getSourceIndex() << \"";
355
else
356
OS << "\" << get" << getUpperName() << "() << \"";
357
}
358
359
void writeDump(raw_ostream &OS) const override {
360
if (StringRef(type).ends_with("Decl *")) {
361
OS << " OS << \" \";\n";
362
OS << " dumpBareDeclRef(SA->get" << getUpperName() << "());\n";
363
} else if (type == "IdentifierInfo *") {
364
// Some non-optional (comma required) identifier arguments can be the
365
// empty string but are then recorded as a nullptr.
366
OS << " if (SA->get" << getUpperName() << "())\n"
367
<< " OS << \" \" << SA->get" << getUpperName()
368
<< "()->getName();\n";
369
} else if (type == "TypeSourceInfo *") {
370
if (isOptional())
371
OS << " if (SA->get" << getUpperName() << "Loc())";
372
OS << " OS << \" \" << SA->get" << getUpperName()
373
<< "().getAsString();\n";
374
} else if (type == "bool") {
375
OS << " if (SA->get" << getUpperName() << "()) OS << \" "
376
<< getUpperName() << "\";\n";
377
} else if (type == "int" || type == "unsigned") {
378
OS << " OS << \" \" << SA->get" << getUpperName() << "();\n";
379
} else if (type == "ParamIdx") {
380
if (isOptional())
381
OS << " if (SA->get" << getUpperName() << "().isValid())\n ";
382
OS << " OS << \" \" << SA->get" << getUpperName()
383
<< "().getSourceIndex();\n";
384
} else if (type == "OMPTraitInfo *") {
385
OS << " OS << \" \" << SA->get" << getUpperName() << "();\n";
386
} else {
387
llvm_unreachable("Unknown SimpleArgument type!");
388
}
389
}
390
};
391
392
class DefaultSimpleArgument : public SimpleArgument {
393
int64_t Default;
394
395
public:
396
DefaultSimpleArgument(const Record &Arg, StringRef Attr,
397
std::string T, int64_t Default)
398
: SimpleArgument(Arg, Attr, T), Default(Default) {}
399
400
void writeAccessors(raw_ostream &OS) const override {
401
SimpleArgument::writeAccessors(OS);
402
403
OS << "\n\n static const " << getType() << " Default" << getUpperName()
404
<< " = ";
405
if (getType() == "bool")
406
OS << (Default != 0 ? "true" : "false");
407
else
408
OS << Default;
409
OS << ";";
410
}
411
};
412
413
class StringArgument : public Argument {
414
public:
415
StringArgument(const Record &Arg, StringRef Attr)
416
: Argument(Arg, Attr)
417
{}
418
419
void writeAccessors(raw_ostream &OS) const override {
420
OS << " llvm::StringRef get" << getUpperName() << "() const {\n";
421
OS << " return llvm::StringRef(" << getLowerName() << ", "
422
<< getLowerName() << "Length);\n";
423
OS << " }\n";
424
OS << " unsigned get" << getUpperName() << "Length() const {\n";
425
OS << " return " << getLowerName() << "Length;\n";
426
OS << " }\n";
427
OS << " void set" << getUpperName()
428
<< "(ASTContext &C, llvm::StringRef S) {\n";
429
OS << " " << getLowerName() << "Length = S.size();\n";
430
OS << " this->" << getLowerName() << " = new (C, 1) char ["
431
<< getLowerName() << "Length];\n";
432
OS << " if (!S.empty())\n";
433
OS << " std::memcpy(this->" << getLowerName() << ", S.data(), "
434
<< getLowerName() << "Length);\n";
435
OS << " }";
436
}
437
438
void writeCloneArgs(raw_ostream &OS) const override {
439
OS << "get" << getUpperName() << "()";
440
}
441
442
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
443
OS << "A->get" << getUpperName() << "()";
444
}
445
446
void writeCtorBody(raw_ostream &OS) const override {
447
OS << " if (!" << getUpperName() << ".empty())\n";
448
OS << " std::memcpy(" << getLowerName() << ", " << getUpperName()
449
<< ".data(), " << getLowerName() << "Length);\n";
450
}
451
452
void writeCtorInitializers(raw_ostream &OS) const override {
453
OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
454
<< getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
455
<< "Length])";
456
}
457
458
void writeCtorDefaultInitializers(raw_ostream &OS) const override {
459
OS << getLowerName() << "Length(0)," << getLowerName() << "(nullptr)";
460
}
461
462
void writeCtorParameters(raw_ostream &OS) const override {
463
OS << "llvm::StringRef " << getUpperName();
464
}
465
466
void writeDeclarations(raw_ostream &OS) const override {
467
OS << "unsigned " << getLowerName() << "Length;\n";
468
OS << "char *" << getLowerName() << ";";
469
}
470
471
void writePCHReadDecls(raw_ostream &OS) const override {
472
OS << " std::string " << getLowerName()
473
<< "= Record.readString();\n";
474
}
475
476
void writePCHReadArgs(raw_ostream &OS) const override {
477
OS << getLowerName();
478
}
479
480
void writePCHWrite(raw_ostream &OS) const override {
481
OS << " Record.AddString(SA->get" << getUpperName() << "());\n";
482
}
483
484
void writeValue(raw_ostream &OS) const override {
485
OS << "\\\"\" << get" << getUpperName() << "() << \"\\\"";
486
}
487
488
void writeDump(raw_ostream &OS) const override {
489
OS << " OS << \" \\\"\" << SA->get" << getUpperName()
490
<< "() << \"\\\"\";\n";
491
}
492
};
493
494
class AlignedArgument : public Argument {
495
public:
496
AlignedArgument(const Record &Arg, StringRef Attr)
497
: Argument(Arg, Attr)
498
{}
499
500
void writeAccessors(raw_ostream &OS) const override {
501
OS << " bool is" << getUpperName() << "Dependent() const;\n";
502
OS << " bool is" << getUpperName() << "ErrorDependent() const;\n";
503
504
OS << " unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";
505
506
OS << " bool is" << getUpperName() << "Expr() const {\n";
507
OS << " return is" << getLowerName() << "Expr;\n";
508
OS << " }\n";
509
510
OS << " Expr *get" << getUpperName() << "Expr() const {\n";
511
OS << " assert(is" << getLowerName() << "Expr);\n";
512
OS << " return " << getLowerName() << "Expr;\n";
513
OS << " }\n";
514
515
OS << " TypeSourceInfo *get" << getUpperName() << "Type() const {\n";
516
OS << " assert(!is" << getLowerName() << "Expr);\n";
517
OS << " return " << getLowerName() << "Type;\n";
518
OS << " }";
519
520
OS << " std::optional<unsigned> getCached" << getUpperName()
521
<< "Value() const {\n";
522
OS << " return " << getLowerName() << "Cache;\n";
523
OS << " }";
524
525
OS << " void setCached" << getUpperName()
526
<< "Value(unsigned AlignVal) {\n";
527
OS << " " << getLowerName() << "Cache = AlignVal;\n";
528
OS << " }";
529
}
530
531
void writeAccessorDefinitions(raw_ostream &OS) const override {
532
OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
533
<< "Dependent() const {\n";
534
OS << " if (is" << getLowerName() << "Expr)\n";
535
OS << " return " << getLowerName() << "Expr && (" << getLowerName()
536
<< "Expr->isValueDependent() || " << getLowerName()
537
<< "Expr->isTypeDependent());\n";
538
OS << " else\n";
539
OS << " return " << getLowerName()
540
<< "Type->getType()->isDependentType();\n";
541
OS << "}\n";
542
543
OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
544
<< "ErrorDependent() const {\n";
545
OS << " if (is" << getLowerName() << "Expr)\n";
546
OS << " return " << getLowerName() << "Expr && " << getLowerName()
547
<< "Expr->containsErrors();\n";
548
OS << " return " << getLowerName()
549
<< "Type->getType()->containsErrors();\n";
550
OS << "}\n";
551
}
552
553
void writeASTVisitorTraversal(raw_ostream &OS) const override {
554
StringRef Name = getUpperName();
555
OS << " if (A->is" << Name << "Expr()) {\n"
556
<< " if (!getDerived().TraverseStmt(A->get" << Name << "Expr()))\n"
557
<< " return false;\n"
558
<< " } else if (auto *TSI = A->get" << Name << "Type()) {\n"
559
<< " if (!getDerived().TraverseTypeLoc(TSI->getTypeLoc()))\n"
560
<< " return false;\n"
561
<< " }\n";
562
}
563
564
void writeCloneArgs(raw_ostream &OS) const override {
565
OS << "is" << getLowerName() << "Expr, is" << getLowerName()
566
<< "Expr ? static_cast<void*>(" << getLowerName()
567
<< "Expr) : " << getLowerName()
568
<< "Type";
569
}
570
571
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
572
// FIXME: move the definition in Sema::InstantiateAttrs to here.
573
// In the meantime, aligned attributes are cloned.
574
}
575
576
void writeCtorBody(raw_ostream &OS) const override {
577
OS << " if (is" << getLowerName() << "Expr)\n";
578
OS << " " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
579
<< getUpperName() << ");\n";
580
OS << " else\n";
581
OS << " " << getLowerName()
582
<< "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
583
<< ");\n";
584
}
585
586
void writeCtorInitializers(raw_ostream &OS) const override {
587
OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
588
}
589
590
void writeCtorDefaultInitializers(raw_ostream &OS) const override {
591
OS << "is" << getLowerName() << "Expr(false)";
592
}
593
594
void writeCtorParameters(raw_ostream &OS) const override {
595
OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
596
}
597
598
void writeImplicitCtorArgs(raw_ostream &OS) const override {
599
OS << "Is" << getUpperName() << "Expr, " << getUpperName();
600
}
601
602
void writeDeclarations(raw_ostream &OS) const override {
603
OS << "bool is" << getLowerName() << "Expr;\n";
604
OS << "union {\n";
605
OS << "Expr *" << getLowerName() << "Expr;\n";
606
OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
607
OS << "};\n";
608
OS << "std::optional<unsigned> " << getLowerName() << "Cache;\n";
609
}
610
611
void writePCHReadArgs(raw_ostream &OS) const override {
612
OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
613
}
614
615
void writePCHReadDecls(raw_ostream &OS) const override {
616
OS << " bool is" << getLowerName() << "Expr = Record.readInt();\n";
617
OS << " void *" << getLowerName() << "Ptr;\n";
618
OS << " if (is" << getLowerName() << "Expr)\n";
619
OS << " " << getLowerName() << "Ptr = Record.readExpr();\n";
620
OS << " else\n";
621
OS << " " << getLowerName()
622
<< "Ptr = Record.readTypeSourceInfo();\n";
623
}
624
625
void writePCHWrite(raw_ostream &OS) const override {
626
OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n";
627
OS << " if (SA->is" << getUpperName() << "Expr())\n";
628
OS << " Record.AddStmt(SA->get" << getUpperName() << "Expr());\n";
629
OS << " else\n";
630
OS << " Record.AddTypeSourceInfo(SA->get" << getUpperName()
631
<< "Type());\n";
632
}
633
634
std::string getIsOmitted() const override {
635
return "!((is" + getLowerName().str() + "Expr && " +
636
getLowerName().str() + "Expr) || (!is" + getLowerName().str() +
637
"Expr && " + getLowerName().str() + "Type))";
638
}
639
640
void writeValue(raw_ostream &OS) const override {
641
OS << "\";\n";
642
OS << " if (is" << getLowerName() << "Expr && " << getLowerName()
643
<< "Expr)";
644
OS << " " << getLowerName()
645
<< "Expr->printPretty(OS, nullptr, Policy);\n";
646
OS << " if (!is" << getLowerName() << "Expr && " << getLowerName()
647
<< "Type)";
648
OS << " " << getLowerName()
649
<< "Type->getType().print(OS, Policy);\n";
650
OS << " OS << \"";
651
}
652
653
void writeDump(raw_ostream &OS) const override {
654
OS << " if (!SA->is" << getUpperName() << "Expr())\n";
655
OS << " dumpType(SA->get" << getUpperName()
656
<< "Type()->getType());\n";
657
}
658
659
void writeDumpChildren(raw_ostream &OS) const override {
660
OS << " if (SA->is" << getUpperName() << "Expr())\n";
661
OS << " Visit(SA->get" << getUpperName() << "Expr());\n";
662
}
663
664
void writeHasChildren(raw_ostream &OS) const override {
665
OS << "SA->is" << getUpperName() << "Expr()";
666
}
667
};
668
669
class VariadicArgument : public Argument {
670
std::string Type, ArgName, ArgSizeName, RangeName;
671
672
protected:
673
// Assumed to receive a parameter: raw_ostream OS.
674
virtual void writeValueImpl(raw_ostream &OS) const {
675
OS << " OS << Val;\n";
676
}
677
// Assumed to receive a parameter: raw_ostream OS.
678
virtual void writeDumpImpl(raw_ostream &OS) const {
679
OS << " OS << \" \" << Val;\n";
680
}
681
682
public:
683
VariadicArgument(const Record &Arg, StringRef Attr, std::string T)
684
: Argument(Arg, Attr), Type(std::move(T)),
685
ArgName(getLowerName().str() + "_"), ArgSizeName(ArgName + "Size"),
686
RangeName(std::string(getLowerName())) {}
687
688
VariadicArgument(StringRef Arg, StringRef Attr, std::string T)
689
: Argument(Arg, Attr), Type(std::move(T)),
690
ArgName(getLowerName().str() + "_"), ArgSizeName(ArgName + "Size"),
691
RangeName(std::string(getLowerName())) {}
692
693
const std::string &getType() const { return Type; }
694
const std::string &getArgName() const { return ArgName; }
695
const std::string &getArgSizeName() const { return ArgSizeName; }
696
bool isVariadic() const override { return true; }
697
698
void writeAccessors(raw_ostream &OS) const override {
699
std::string IteratorType = getLowerName().str() + "_iterator";
700
std::string BeginFn = getLowerName().str() + "_begin()";
701
std::string EndFn = getLowerName().str() + "_end()";
702
703
OS << " typedef " << Type << "* " << IteratorType << ";\n";
704
OS << " " << IteratorType << " " << BeginFn << " const {"
705
<< " return " << ArgName << "; }\n";
706
OS << " " << IteratorType << " " << EndFn << " const {"
707
<< " return " << ArgName << " + " << ArgSizeName << "; }\n";
708
OS << " unsigned " << getLowerName() << "_size() const {"
709
<< " return " << ArgSizeName << "; }\n";
710
OS << " llvm::iterator_range<" << IteratorType << "> " << RangeName
711
<< "() const { return llvm::make_range(" << BeginFn << ", " << EndFn
712
<< "); }\n";
713
}
714
715
void writeSetter(raw_ostream &OS) const {
716
OS << " void set" << getUpperName() << "(ASTContext &Ctx, ";
717
writeCtorParameters(OS);
718
OS << ") {\n";
719
OS << " " << ArgSizeName << " = " << getUpperName() << "Size;\n";
720
OS << " " << ArgName << " = new (Ctx, 16) " << getType() << "["
721
<< ArgSizeName << "];\n";
722
OS << " ";
723
writeCtorBody(OS);
724
OS << " }\n";
725
}
726
727
void writeCloneArgs(raw_ostream &OS) const override {
728
OS << ArgName << ", " << ArgSizeName;
729
}
730
731
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
732
// This isn't elegant, but we have to go through public methods...
733
OS << "A->" << getLowerName() << "_begin(), "
734
<< "A->" << getLowerName() << "_size()";
735
}
736
737
void writeASTVisitorTraversal(raw_ostream &OS) const override {
738
// FIXME: Traverse the elements.
739
}
740
741
void writeCtorBody(raw_ostream &OS) const override {
742
OS << " std::copy(" << getUpperName() << ", " << getUpperName() << " + "
743
<< ArgSizeName << ", " << ArgName << ");\n";
744
}
745
746
void writeCtorInitializers(raw_ostream &OS) const override {
747
OS << ArgSizeName << "(" << getUpperName() << "Size), "
748
<< ArgName << "(new (Ctx, 16) " << getType() << "["
749
<< ArgSizeName << "])";
750
}
751
752
void writeCtorDefaultInitializers(raw_ostream &OS) const override {
753
OS << ArgSizeName << "(0), " << ArgName << "(nullptr)";
754
}
755
756
void writeCtorParameters(raw_ostream &OS) const override {
757
OS << getType() << " *" << getUpperName() << ", unsigned "
758
<< getUpperName() << "Size";
759
}
760
761
void writeImplicitCtorArgs(raw_ostream &OS) const override {
762
OS << getUpperName() << ", " << getUpperName() << "Size";
763
}
764
765
void writeDeclarations(raw_ostream &OS) const override {
766
OS << " unsigned " << ArgSizeName << ";\n";
767
OS << " " << getType() << " *" << ArgName << ";";
768
}
769
770
void writePCHReadDecls(raw_ostream &OS) const override {
771
OS << " unsigned " << getLowerName() << "Size = Record.readInt();\n";
772
OS << " SmallVector<" << getType() << ", 4> "
773
<< getLowerName() << ";\n";
774
OS << " " << getLowerName() << ".reserve(" << getLowerName()
775
<< "Size);\n";
776
777
// If we can't store the values in the current type (if it's something
778
// like StringRef), store them in a different type and convert the
779
// container afterwards.
780
std::string StorageType = std::string(getStorageType(getType()));
781
std::string StorageName = std::string(getLowerName());
782
if (StorageType != getType()) {
783
StorageName += "Storage";
784
OS << " SmallVector<" << StorageType << ", 4> "
785
<< StorageName << ";\n";
786
OS << " " << StorageName << ".reserve(" << getLowerName()
787
<< "Size);\n";
788
}
789
790
OS << " for (unsigned i = 0; i != " << getLowerName() << "Size; ++i)\n";
791
std::string read = ReadPCHRecord(Type);
792
OS << " " << StorageName << ".push_back(" << read << ");\n";
793
794
if (StorageType != getType()) {
795
OS << " for (unsigned i = 0; i != " << getLowerName() << "Size; ++i)\n";
796
OS << " " << getLowerName() << ".push_back("
797
<< StorageName << "[i]);\n";
798
}
799
}
800
801
void writePCHReadArgs(raw_ostream &OS) const override {
802
OS << getLowerName() << ".data(), " << getLowerName() << "Size";
803
}
804
805
void writePCHWrite(raw_ostream &OS) const override {
806
OS << " Record.push_back(SA->" << getLowerName() << "_size());\n";
807
OS << " for (auto &Val : SA->" << RangeName << "())\n";
808
OS << " " << WritePCHRecord(Type, "Val");
809
}
810
811
void writeValue(raw_ostream &OS) const override {
812
OS << "\";\n";
813
OS << " for (const auto &Val : " << RangeName << "()) {\n"
814
<< " DelimitAttributeArgument(OS, IsFirstArgument);\n";
815
writeValueImpl(OS);
816
OS << " }\n";
817
OS << " OS << \"";
818
}
819
820
void writeDump(raw_ostream &OS) const override {
821
OS << " for (const auto &Val : SA->" << RangeName << "())\n";
822
writeDumpImpl(OS);
823
}
824
};
825
826
class VariadicOMPInteropInfoArgument : public VariadicArgument {
827
public:
828
VariadicOMPInteropInfoArgument(const Record &Arg, StringRef Attr)
829
: VariadicArgument(Arg, Attr, "OMPInteropInfo") {}
830
831
void writeDump(raw_ostream &OS) const override {
832
OS << " for (" << getAttrName() << "Attr::" << getLowerName()
833
<< "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
834
<< getLowerName() << "_end(); I != E; ++I) {\n";
835
OS << " if (I->IsTarget && I->IsTargetSync)\n";
836
OS << " OS << \" Target_TargetSync\";\n";
837
OS << " else if (I->IsTarget)\n";
838
OS << " OS << \" Target\";\n";
839
OS << " else\n";
840
OS << " OS << \" TargetSync\";\n";
841
OS << " }\n";
842
}
843
844
void writePCHReadDecls(raw_ostream &OS) const override {
845
OS << " unsigned " << getLowerName() << "Size = Record.readInt();\n";
846
OS << " SmallVector<OMPInteropInfo, 4> " << getLowerName() << ";\n";
847
OS << " " << getLowerName() << ".reserve(" << getLowerName()
848
<< "Size);\n";
849
OS << " for (unsigned I = 0, E = " << getLowerName() << "Size; ";
850
OS << "I != E; ++I) {\n";
851
OS << " bool IsTarget = Record.readBool();\n";
852
OS << " bool IsTargetSync = Record.readBool();\n";
853
OS << " " << getLowerName()
854
<< ".emplace_back(IsTarget, IsTargetSync);\n";
855
OS << " }\n";
856
}
857
858
void writePCHWrite(raw_ostream &OS) const override {
859
OS << " Record.push_back(SA->" << getLowerName() << "_size());\n";
860
OS << " for (" << getAttrName() << "Attr::" << getLowerName()
861
<< "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
862
<< getLowerName() << "_end(); I != E; ++I) {\n";
863
OS << " Record.writeBool(I->IsTarget);\n";
864
OS << " Record.writeBool(I->IsTargetSync);\n";
865
OS << " }\n";
866
}
867
};
868
869
class VariadicParamIdxArgument : public VariadicArgument {
870
public:
871
VariadicParamIdxArgument(const Record &Arg, StringRef Attr)
872
: VariadicArgument(Arg, Attr, "ParamIdx") {}
873
874
public:
875
void writeValueImpl(raw_ostream &OS) const override {
876
OS << " OS << Val.getSourceIndex();\n";
877
}
878
879
void writeDumpImpl(raw_ostream &OS) const override {
880
OS << " OS << \" \" << Val.getSourceIndex();\n";
881
}
882
};
883
884
struct VariadicParamOrParamIdxArgument : public VariadicArgument {
885
VariadicParamOrParamIdxArgument(const Record &Arg, StringRef Attr)
886
: VariadicArgument(Arg, Attr, "int") {}
887
};
888
889
// Unique the enums, but maintain the original declaration ordering.
890
std::vector<StringRef>
891
uniqueEnumsInOrder(const std::vector<StringRef> &enums) {
892
std::vector<StringRef> uniques;
893
SmallDenseSet<StringRef, 8> unique_set;
894
for (const auto &i : enums) {
895
if (unique_set.insert(i).second)
896
uniques.push_back(i);
897
}
898
return uniques;
899
}
900
901
class EnumArgument : public Argument {
902
std::string fullType;
903
StringRef shortType;
904
std::vector<StringRef> values, enums, uniques;
905
bool isExternal;
906
bool isCovered;
907
908
public:
909
EnumArgument(const Record &Arg, StringRef Attr)
910
: Argument(Arg, Attr), values(Arg.getValueAsListOfStrings("Values")),
911
enums(Arg.getValueAsListOfStrings("Enums")),
912
uniques(uniqueEnumsInOrder(enums)),
913
isExternal(Arg.getValueAsBit("IsExternalType")),
914
isCovered(Arg.getValueAsBit("IsCovered")) {
915
StringRef Type = Arg.getValueAsString("Type");
916
shortType = isExternal ? Type.rsplit("::").second : Type;
917
// If shortType didn't contain :: at all rsplit will give us an empty
918
// string.
919
if (shortType.empty())
920
shortType = Type;
921
fullType = isExternal ? Type : (getAttrName() + "Attr::" + Type).str();
922
923
// FIXME: Emit a proper error
924
assert(!uniques.empty());
925
}
926
927
bool isEnumArg() const override { return true; }
928
929
void writeAccessors(raw_ostream &OS) const override {
930
OS << " " << fullType << " get" << getUpperName() << "() const {\n";
931
OS << " return " << getLowerName() << ";\n";
932
OS << " }";
933
}
934
935
void writeCloneArgs(raw_ostream &OS) const override {
936
OS << getLowerName();
937
}
938
939
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
940
OS << "A->get" << getUpperName() << "()";
941
}
942
void writeCtorInitializers(raw_ostream &OS) const override {
943
OS << getLowerName() << "(" << getUpperName() << ")";
944
}
945
void writeCtorDefaultInitializers(raw_ostream &OS) const override {
946
OS << getLowerName() << "(" << fullType << "(0))";
947
}
948
void writeCtorParameters(raw_ostream &OS) const override {
949
OS << fullType << " " << getUpperName();
950
}
951
void writeDeclarations(raw_ostream &OS) const override {
952
if (!isExternal) {
953
auto i = uniques.cbegin(), e = uniques.cend();
954
// The last one needs to not have a comma.
955
--e;
956
957
OS << "public:\n";
958
OS << " enum " << shortType << " {\n";
959
for (; i != e; ++i)
960
OS << " " << *i << ",\n";
961
OS << " " << *e << "\n";
962
OS << " };\n";
963
}
964
965
OS << "private:\n";
966
OS << " " << fullType << " " << getLowerName() << ";";
967
}
968
969
void writePCHReadDecls(raw_ostream &OS) const override {
970
OS << " " << fullType << " " << getLowerName() << "(static_cast<"
971
<< fullType << ">(Record.readInt()));\n";
972
}
973
974
void writePCHReadArgs(raw_ostream &OS) const override {
975
OS << getLowerName();
976
}
977
978
void writePCHWrite(raw_ostream &OS) const override {
979
OS << "Record.push_back(static_cast<uint64_t>(SA->get" << getUpperName()
980
<< "()));\n";
981
}
982
983
void writeValue(raw_ostream &OS) const override {
984
// FIXME: this isn't 100% correct -- some enum arguments require printing
985
// as a string literal, while others require printing as an identifier.
986
// Tablegen currently does not distinguish between the two forms.
987
OS << "\\\"\" << " << getAttrName() << "Attr::Convert" << shortType
988
<< "ToStr(get" << getUpperName() << "()) << \"\\\"";
989
}
990
991
void writeDump(raw_ostream &OS) const override {
992
OS << " switch(SA->get" << getUpperName() << "()) {\n";
993
for (const auto &I : uniques) {
994
OS << " case " << fullType << "::" << I << ":\n";
995
OS << " OS << \" " << I << "\";\n";
996
OS << " break;\n";
997
}
998
if (!isCovered) {
999
OS << " default:\n";
1000
OS << " llvm_unreachable(\"Invalid attribute value\");\n";
1001
}
1002
OS << " }\n";
1003
}
1004
1005
void writeConversion(raw_ostream &OS, bool Header) const {
1006
if (Header) {
1007
OS << " static bool ConvertStrTo" << shortType << "(StringRef Val, "
1008
<< fullType << " &Out);\n";
1009
OS << " static const char *Convert" << shortType << "ToStr("
1010
<< fullType << " Val);\n";
1011
return;
1012
}
1013
1014
OS << "bool " << getAttrName() << "Attr::ConvertStrTo" << shortType
1015
<< "(StringRef Val, " << fullType << " &Out) {\n";
1016
OS << " std::optional<" << fullType << "> "
1017
<< "R = llvm::StringSwitch<std::optional<" << fullType << ">>(Val)\n";
1018
for (size_t I = 0; I < enums.size(); ++I) {
1019
OS << " .Case(\"" << values[I] << "\", ";
1020
OS << fullType << "::" << enums[I] << ")\n";
1021
}
1022
OS << " .Default(std::optional<" << fullType << ">());\n";
1023
OS << " if (R) {\n";
1024
OS << " Out = *R;\n return true;\n }\n";
1025
OS << " return false;\n";
1026
OS << "}\n\n";
1027
1028
// Mapping from enumeration values back to enumeration strings isn't
1029
// trivial because some enumeration values have multiple named
1030
// enumerators, such as type_visibility(internal) and
1031
// type_visibility(hidden) both mapping to TypeVisibilityAttr::Hidden.
1032
OS << "const char *" << getAttrName() << "Attr::Convert" << shortType
1033
<< "ToStr(" << fullType << " Val) {\n"
1034
<< " switch(Val) {\n";
1035
SmallDenseSet<StringRef, 8> Uniques;
1036
for (size_t I = 0; I < enums.size(); ++I) {
1037
if (Uniques.insert(enums[I]).second)
1038
OS << " case " << fullType << "::" << enums[I] << ": return \""
1039
<< values[I] << "\";\n";
1040
}
1041
if (!isCovered) {
1042
OS << " default: llvm_unreachable(\"Invalid attribute value\");\n";
1043
}
1044
OS << " }\n"
1045
<< " llvm_unreachable(\"No enumerator with that value\");\n"
1046
<< "}\n";
1047
}
1048
};
1049
1050
class VariadicEnumArgument: public VariadicArgument {
1051
std::string fullType;
1052
StringRef shortType;
1053
std::vector<StringRef> values, enums, uniques;
1054
bool isExternal;
1055
bool isCovered;
1056
1057
protected:
1058
void writeValueImpl(raw_ostream &OS) const override {
1059
// FIXME: this isn't 100% correct -- some enum arguments require printing
1060
// as a string literal, while others require printing as an identifier.
1061
// Tablegen currently does not distinguish between the two forms.
1062
OS << " OS << \"\\\"\" << " << getAttrName() << "Attr::Convert"
1063
<< shortType << "ToStr(Val)"
1064
<< "<< \"\\\"\";\n";
1065
}
1066
1067
public:
1068
VariadicEnumArgument(const Record &Arg, StringRef Attr)
1069
: VariadicArgument(Arg, Attr,
1070
std::string(Arg.getValueAsString("Type"))),
1071
values(Arg.getValueAsListOfStrings("Values")),
1072
enums(Arg.getValueAsListOfStrings("Enums")),
1073
uniques(uniqueEnumsInOrder(enums)),
1074
isExternal(Arg.getValueAsBit("IsExternalType")),
1075
isCovered(Arg.getValueAsBit("IsCovered")) {
1076
StringRef Type = Arg.getValueAsString("Type");
1077
shortType = isExternal ? Type.rsplit("::").second : Type;
1078
// If shortType didn't contain :: at all rsplit will give us an empty
1079
// string.
1080
if (shortType.empty())
1081
shortType = Type;
1082
fullType = isExternal ? Type : (getAttrName() + "Attr::" + Type).str();
1083
1084
// FIXME: Emit a proper error
1085
assert(!uniques.empty());
1086
}
1087
1088
bool isVariadicEnumArg() const override { return true; }
1089
1090
void writeDeclarations(raw_ostream &OS) const override {
1091
if (!isExternal) {
1092
auto i = uniques.cbegin(), e = uniques.cend();
1093
// The last one needs to not have a comma.
1094
--e;
1095
1096
OS << "public:\n";
1097
OS << " enum " << shortType << " {\n";
1098
for (; i != e; ++i)
1099
OS << " " << *i << ",\n";
1100
OS << " " << *e << "\n";
1101
OS << " };\n";
1102
}
1103
OS << "private:\n";
1104
1105
VariadicArgument::writeDeclarations(OS);
1106
}
1107
1108
void writeDump(raw_ostream &OS) const override {
1109
OS << " for (" << getAttrName() << "Attr::" << getLowerName()
1110
<< "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
1111
<< getLowerName() << "_end(); I != E; ++I) {\n";
1112
OS << " switch(*I) {\n";
1113
for (const auto &UI : uniques) {
1114
OS << " case " << fullType << "::" << UI << ":\n";
1115
OS << " OS << \" " << UI << "\";\n";
1116
OS << " break;\n";
1117
}
1118
if (!isCovered) {
1119
OS << " default:\n";
1120
OS << " llvm_unreachable(\"Invalid attribute value\");\n";
1121
}
1122
OS << " }\n";
1123
OS << " }\n";
1124
}
1125
1126
void writePCHReadDecls(raw_ostream &OS) const override {
1127
OS << " unsigned " << getLowerName() << "Size = Record.readInt();\n";
1128
OS << " SmallVector<" << fullType << ", 4> " << getLowerName()
1129
<< ";\n";
1130
OS << " " << getLowerName() << ".reserve(" << getLowerName()
1131
<< "Size);\n";
1132
OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
1133
OS << " " << getLowerName() << ".push_back("
1134
<< "static_cast<" << fullType << ">(Record.readInt()));\n";
1135
}
1136
1137
void writePCHWrite(raw_ostream &OS) const override {
1138
OS << " Record.push_back(SA->" << getLowerName() << "_size());\n";
1139
OS << " for (" << getAttrName() << "Attr::" << getLowerName()
1140
<< "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
1141
<< getLowerName() << "_end(); i != e; ++i)\n";
1142
OS << " " << WritePCHRecord(fullType, "(*i)");
1143
}
1144
1145
void writeConversion(raw_ostream &OS, bool Header) const {
1146
if (Header) {
1147
OS << " static bool ConvertStrTo" << shortType << "(StringRef Val, "
1148
<< fullType << " &Out);\n";
1149
OS << " static const char *Convert" << shortType << "ToStr("
1150
<< fullType << " Val);\n";
1151
return;
1152
}
1153
1154
OS << "bool " << getAttrName() << "Attr::ConvertStrTo" << shortType
1155
<< "(StringRef Val, ";
1156
OS << fullType << " &Out) {\n";
1157
OS << " std::optional<" << fullType
1158
<< "> R = llvm::StringSwitch<std::optional<";
1159
OS << fullType << ">>(Val)\n";
1160
for (size_t I = 0; I < enums.size(); ++I) {
1161
OS << " .Case(\"" << values[I] << "\", ";
1162
OS << fullType << "::" << enums[I] << ")\n";
1163
}
1164
OS << " .Default(std::optional<" << fullType << ">());\n";
1165
OS << " if (R) {\n";
1166
OS << " Out = *R;\n return true;\n }\n";
1167
OS << " return false;\n";
1168
OS << "}\n\n";
1169
1170
OS << "const char *" << getAttrName() << "Attr::Convert" << shortType
1171
<< "ToStr(" << fullType << " Val) {\n"
1172
<< " switch(Val) {\n";
1173
SmallDenseSet<StringRef, 8> Uniques;
1174
for (size_t I = 0; I < enums.size(); ++I) {
1175
if (Uniques.insert(enums[I]).second)
1176
OS << " case " << fullType << "::" << enums[I] << ": return \""
1177
<< values[I] << "\";\n";
1178
}
1179
if (!isCovered) {
1180
OS << " default: llvm_unreachable(\"Invalid attribute value\");\n";
1181
}
1182
OS << " }\n"
1183
<< " llvm_unreachable(\"No enumerator with that value\");\n"
1184
<< "}\n";
1185
}
1186
};
1187
1188
class VersionArgument : public Argument {
1189
public:
1190
VersionArgument(const Record &Arg, StringRef Attr)
1191
: Argument(Arg, Attr)
1192
{}
1193
1194
void writeAccessors(raw_ostream &OS) const override {
1195
OS << " VersionTuple get" << getUpperName() << "() const {\n";
1196
OS << " return " << getLowerName() << ";\n";
1197
OS << " }\n";
1198
OS << " void set" << getUpperName()
1199
<< "(ASTContext &C, VersionTuple V) {\n";
1200
OS << " " << getLowerName() << " = V;\n";
1201
OS << " }";
1202
}
1203
1204
void writeCloneArgs(raw_ostream &OS) const override {
1205
OS << "get" << getUpperName() << "()";
1206
}
1207
1208
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
1209
OS << "A->get" << getUpperName() << "()";
1210
}
1211
1212
void writeCtorInitializers(raw_ostream &OS) const override {
1213
OS << getLowerName() << "(" << getUpperName() << ")";
1214
}
1215
1216
void writeCtorDefaultInitializers(raw_ostream &OS) const override {
1217
OS << getLowerName() << "()";
1218
}
1219
1220
void writeCtorParameters(raw_ostream &OS) const override {
1221
OS << "VersionTuple " << getUpperName();
1222
}
1223
1224
void writeDeclarations(raw_ostream &OS) const override {
1225
OS << "VersionTuple " << getLowerName() << ";\n";
1226
}
1227
1228
void writePCHReadDecls(raw_ostream &OS) const override {
1229
OS << " VersionTuple " << getLowerName()
1230
<< "= Record.readVersionTuple();\n";
1231
}
1232
1233
void writePCHReadArgs(raw_ostream &OS) const override {
1234
OS << getLowerName();
1235
}
1236
1237
void writePCHWrite(raw_ostream &OS) const override {
1238
OS << " Record.AddVersionTuple(SA->get" << getUpperName() << "());\n";
1239
}
1240
1241
void writeValue(raw_ostream &OS) const override {
1242
OS << getLowerName() << "=\" << get" << getUpperName() << "() << \"";
1243
}
1244
1245
void writeDump(raw_ostream &OS) const override {
1246
OS << " OS << \" \" << SA->get" << getUpperName() << "();\n";
1247
}
1248
};
1249
1250
class ExprArgument : public SimpleArgument {
1251
public:
1252
ExprArgument(const Record &Arg, StringRef Attr)
1253
: SimpleArgument(Arg, Attr, "Expr *")
1254
{}
1255
1256
void writeASTVisitorTraversal(raw_ostream &OS) const override {
1257
OS << " if (!"
1258
<< "getDerived().TraverseStmt(A->get" << getUpperName() << "()))\n";
1259
OS << " return false;\n";
1260
}
1261
1262
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
1263
OS << "tempInst" << getUpperName();
1264
}
1265
1266
void writeTemplateInstantiation(raw_ostream &OS) const override {
1267
OS << " " << getType() << " tempInst" << getUpperName() << ";\n";
1268
OS << " {\n";
1269
OS << " EnterExpressionEvaluationContext "
1270
<< "Unevaluated(S, Sema::ExpressionEvaluationContext::Unevaluated);\n";
1271
OS << " ExprResult " << "Result = S.SubstExpr("
1272
<< "A->get" << getUpperName() << "(), TemplateArgs);\n";
1273
OS << " if (Result.isInvalid())\n";
1274
OS << " return nullptr;\n";
1275
OS << " tempInst" << getUpperName() << " = Result.get();\n";
1276
OS << " }\n";
1277
}
1278
1279
void writeValue(raw_ostream &OS) const override {
1280
OS << "\";\n";
1281
OS << " get" << getUpperName()
1282
<< "()->printPretty(OS, nullptr, Policy);\n";
1283
OS << " OS << \"";
1284
}
1285
1286
void writeDump(raw_ostream &OS) const override {}
1287
1288
void writeDumpChildren(raw_ostream &OS) const override {
1289
OS << " Visit(SA->get" << getUpperName() << "());\n";
1290
}
1291
1292
void writeHasChildren(raw_ostream &OS) const override { OS << "true"; }
1293
};
1294
1295
class VariadicExprArgument : public VariadicArgument {
1296
public:
1297
VariadicExprArgument(const Record &Arg, StringRef Attr)
1298
: VariadicArgument(Arg, Attr, "Expr *")
1299
{}
1300
1301
VariadicExprArgument(StringRef ArgName, StringRef Attr)
1302
: VariadicArgument(ArgName, Attr, "Expr *") {}
1303
1304
void writeASTVisitorTraversal(raw_ostream &OS) const override {
1305
OS << " {\n";
1306
OS << " " << getType() << " *I = A->" << getLowerName()
1307
<< "_begin();\n";
1308
OS << " " << getType() << " *E = A->" << getLowerName()
1309
<< "_end();\n";
1310
OS << " for (; I != E; ++I) {\n";
1311
OS << " if (!getDerived().TraverseStmt(*I))\n";
1312
OS << " return false;\n";
1313
OS << " }\n";
1314
OS << " }\n";
1315
}
1316
1317
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
1318
OS << "tempInst" << getUpperName() << ", "
1319
<< "A->" << getLowerName() << "_size()";
1320
}
1321
1322
void writeTemplateInstantiation(raw_ostream &OS) const override {
1323
OS << " auto *tempInst" << getUpperName()
1324
<< " = new (C, 16) " << getType()
1325
<< "[A->" << getLowerName() << "_size()];\n";
1326
OS << " {\n";
1327
OS << " EnterExpressionEvaluationContext "
1328
<< "Unevaluated(S, Sema::ExpressionEvaluationContext::Unevaluated);\n";
1329
OS << " " << getType() << " *TI = tempInst" << getUpperName()
1330
<< ";\n";
1331
OS << " " << getType() << " *I = A->" << getLowerName()
1332
<< "_begin();\n";
1333
OS << " " << getType() << " *E = A->" << getLowerName()
1334
<< "_end();\n";
1335
OS << " for (; I != E; ++I, ++TI) {\n";
1336
OS << " ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n";
1337
OS << " if (Result.isInvalid())\n";
1338
OS << " return nullptr;\n";
1339
OS << " *TI = Result.get();\n";
1340
OS << " }\n";
1341
OS << " }\n";
1342
}
1343
1344
void writeDump(raw_ostream &OS) const override {}
1345
1346
void writeDumpChildren(raw_ostream &OS) const override {
1347
OS << " for (" << getAttrName() << "Attr::" << getLowerName()
1348
<< "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
1349
<< getLowerName() << "_end(); I != E; ++I)\n";
1350
OS << " Visit(*I);\n";
1351
}
1352
1353
void writeHasChildren(raw_ostream &OS) const override {
1354
OS << "SA->" << getLowerName() << "_begin() != "
1355
<< "SA->" << getLowerName() << "_end()";
1356
}
1357
};
1358
1359
class VariadicIdentifierArgument : public VariadicArgument {
1360
public:
1361
VariadicIdentifierArgument(const Record &Arg, StringRef Attr)
1362
: VariadicArgument(Arg, Attr, "IdentifierInfo *")
1363
{}
1364
};
1365
1366
class VariadicStringArgument : public VariadicArgument {
1367
public:
1368
VariadicStringArgument(const Record &Arg, StringRef Attr)
1369
: VariadicArgument(Arg, Attr, "StringRef")
1370
{}
1371
1372
void writeCtorBody(raw_ostream &OS) const override {
1373
OS << " for (size_t I = 0, E = " << getArgSizeName() << "; I != E;\n"
1374
" ++I) {\n"
1375
" StringRef Ref = " << getUpperName() << "[I];\n"
1376
" if (!Ref.empty()) {\n"
1377
" char *Mem = new (Ctx, 1) char[Ref.size()];\n"
1378
" std::memcpy(Mem, Ref.data(), Ref.size());\n"
1379
" " << getArgName() << "[I] = StringRef(Mem, Ref.size());\n"
1380
" }\n"
1381
" }\n";
1382
}
1383
1384
void writeValueImpl(raw_ostream &OS) const override {
1385
OS << " OS << \"\\\"\" << Val << \"\\\"\";\n";
1386
}
1387
};
1388
1389
class TypeArgument : public SimpleArgument {
1390
public:
1391
TypeArgument(const Record &Arg, StringRef Attr)
1392
: SimpleArgument(Arg, Attr, "TypeSourceInfo *")
1393
{}
1394
1395
void writeAccessors(raw_ostream &OS) const override {
1396
OS << " QualType get" << getUpperName() << "() const {\n";
1397
OS << " return " << getLowerName() << "->getType();\n";
1398
OS << " }";
1399
OS << " " << getType() << " get" << getUpperName() << "Loc() const {\n";
1400
OS << " return " << getLowerName() << ";\n";
1401
OS << " }";
1402
}
1403
1404
void writeASTVisitorTraversal(raw_ostream &OS) const override {
1405
OS << " if (auto *TSI = A->get" << getUpperName() << "Loc())\n";
1406
OS << " if (!getDerived().TraverseTypeLoc(TSI->getTypeLoc()))\n";
1407
OS << " return false;\n";
1408
}
1409
1410
void writeTemplateInstantiation(raw_ostream &OS) const override {
1411
OS << " " << getType() << " tempInst" << getUpperName() << " =\n";
1412
OS << " S.SubstType(A->get" << getUpperName() << "Loc(), "
1413
<< "TemplateArgs, A->getLoc(), A->getAttrName());\n";
1414
OS << " if (!tempInst" << getUpperName() << ")\n";
1415
OS << " return nullptr;\n";
1416
}
1417
1418
void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
1419
OS << "tempInst" << getUpperName();
1420
}
1421
1422
void writePCHWrite(raw_ostream &OS) const override {
1423
OS << " "
1424
<< WritePCHRecord(getType(),
1425
"SA->get" + std::string(getUpperName()) + "Loc()");
1426
}
1427
};
1428
1429
class WrappedAttr : public SimpleArgument {
1430
public:
1431
WrappedAttr(const Record &Arg, StringRef Attr)
1432
: SimpleArgument(Arg, Attr, "Attr *") {}
1433
1434
void writePCHReadDecls(raw_ostream &OS) const override {
1435
OS << " Attr *" << getLowerName() << " = Record.readAttr();";
1436
}
1437
1438
void writePCHWrite(raw_ostream &OS) const override {
1439
OS << " AddAttr(SA->get" << getUpperName() << "());";
1440
}
1441
1442
void writeDump(raw_ostream &OS) const override {}
1443
1444
void writeDumpChildren(raw_ostream &OS) const override {
1445
OS << " Visit(SA->get" << getUpperName() << "());\n";
1446
}
1447
1448
void writeHasChildren(raw_ostream &OS) const override { OS << "true"; }
1449
};
1450
1451
} // end anonymous namespace
1452
1453
static std::unique_ptr<Argument>
1454
createArgument(const Record &Arg, StringRef Attr,
1455
const Record *Search = nullptr) {
1456
if (!Search)
1457
Search = &Arg;
1458
1459
std::unique_ptr<Argument> Ptr;
1460
llvm::StringRef ArgName = Search->getName();
1461
1462
if (ArgName == "AlignedArgument")
1463
Ptr = std::make_unique<AlignedArgument>(Arg, Attr);
1464
else if (ArgName == "EnumArgument")
1465
Ptr = std::make_unique<EnumArgument>(Arg, Attr);
1466
else if (ArgName == "ExprArgument")
1467
Ptr = std::make_unique<ExprArgument>(Arg, Attr);
1468
else if (ArgName == "DeclArgument")
1469
Ptr = std::make_unique<SimpleArgument>(
1470
Arg, Attr, (Arg.getValueAsDef("Kind")->getName() + "Decl *").str());
1471
else if (ArgName == "IdentifierArgument")
1472
Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "IdentifierInfo *");
1473
else if (ArgName == "DefaultBoolArgument")
1474
Ptr = std::make_unique<DefaultSimpleArgument>(
1475
Arg, Attr, "bool", Arg.getValueAsBit("Default"));
1476
else if (ArgName == "BoolArgument")
1477
Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "bool");
1478
else if (ArgName == "DefaultIntArgument")
1479
Ptr = std::make_unique<DefaultSimpleArgument>(
1480
Arg, Attr, "int", Arg.getValueAsInt("Default"));
1481
else if (ArgName == "IntArgument")
1482
Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "int");
1483
else if (ArgName == "StringArgument")
1484
Ptr = std::make_unique<StringArgument>(Arg, Attr);
1485
else if (ArgName == "TypeArgument")
1486
Ptr = std::make_unique<TypeArgument>(Arg, Attr);
1487
else if (ArgName == "UnsignedArgument")
1488
Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "unsigned");
1489
else if (ArgName == "VariadicUnsignedArgument")
1490
Ptr = std::make_unique<VariadicArgument>(Arg, Attr, "unsigned");
1491
else if (ArgName == "VariadicStringArgument")
1492
Ptr = std::make_unique<VariadicStringArgument>(Arg, Attr);
1493
else if (ArgName == "VariadicEnumArgument")
1494
Ptr = std::make_unique<VariadicEnumArgument>(Arg, Attr);
1495
else if (ArgName == "VariadicExprArgument")
1496
Ptr = std::make_unique<VariadicExprArgument>(Arg, Attr);
1497
else if (ArgName == "VariadicParamIdxArgument")
1498
Ptr = std::make_unique<VariadicParamIdxArgument>(Arg, Attr);
1499
else if (ArgName == "VariadicParamOrParamIdxArgument")
1500
Ptr = std::make_unique<VariadicParamOrParamIdxArgument>(Arg, Attr);
1501
else if (ArgName == "ParamIdxArgument")
1502
Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "ParamIdx");
1503
else if (ArgName == "VariadicIdentifierArgument")
1504
Ptr = std::make_unique<VariadicIdentifierArgument>(Arg, Attr);
1505
else if (ArgName == "VersionArgument")
1506
Ptr = std::make_unique<VersionArgument>(Arg, Attr);
1507
else if (ArgName == "WrappedAttr")
1508
Ptr = std::make_unique<WrappedAttr>(Arg, Attr);
1509
else if (ArgName == "OMPTraitInfoArgument")
1510
Ptr = std::make_unique<SimpleArgument>(Arg, Attr, "OMPTraitInfo *");
1511
else if (ArgName == "VariadicOMPInteropInfoArgument")
1512
Ptr = std::make_unique<VariadicOMPInteropInfoArgument>(Arg, Attr);
1513
1514
if (!Ptr) {
1515
// Search in reverse order so that the most-derived type is handled first.
1516
ArrayRef<std::pair<Record*, SMRange>> Bases = Search->getSuperClasses();
1517
for (const auto &Base : llvm::reverse(Bases)) {
1518
if ((Ptr = createArgument(Arg, Attr, Base.first)))
1519
break;
1520
}
1521
}
1522
1523
if (Ptr && Arg.getValueAsBit("Optional"))
1524
Ptr->setOptional(true);
1525
1526
if (Ptr && Arg.getValueAsBit("Fake"))
1527
Ptr->setFake(true);
1528
1529
return Ptr;
1530
}
1531
1532
static void writeAvailabilityValue(raw_ostream &OS) {
1533
OS << "\" << getPlatform()->getName();\n"
1534
<< " if (getStrict()) OS << \", strict\";\n"
1535
<< " if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n"
1536
<< " if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n"
1537
<< " if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n"
1538
<< " if (getUnavailable()) OS << \", unavailable\";\n"
1539
<< " OS << \"";
1540
}
1541
1542
static void writeDeprecatedAttrValue(raw_ostream &OS, std::string &Variety) {
1543
OS << "\\\"\" << getMessage() << \"\\\"\";\n";
1544
// Only GNU deprecated has an optional fixit argument at the second position.
1545
if (Variety == "GNU")
1546
OS << " if (!getReplacement().empty()) OS << \", \\\"\""
1547
" << getReplacement() << \"\\\"\";\n";
1548
OS << " OS << \"";
1549
}
1550
1551
static void writeGetSpellingFunction(const Record &R, raw_ostream &OS) {
1552
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
1553
1554
OS << "const char *" << R.getName() << "Attr::getSpelling() const {\n";
1555
if (Spellings.empty()) {
1556
OS << " return \"(No spelling)\";\n}\n\n";
1557
return;
1558
}
1559
1560
OS << " switch (getAttributeSpellingListIndex()) {\n"
1561
" default:\n"
1562
" llvm_unreachable(\"Unknown attribute spelling!\");\n"
1563
" return \"(No spelling)\";\n";
1564
1565
for (unsigned I = 0; I < Spellings.size(); ++I)
1566
OS << " case " << I << ":\n"
1567
" return \"" << Spellings[I].name() << "\";\n";
1568
// End of the switch statement.
1569
OS << " }\n";
1570
// End of the getSpelling function.
1571
OS << "}\n\n";
1572
}
1573
1574
static void
1575
writePrettyPrintFunction(const Record &R,
1576
const std::vector<std::unique_ptr<Argument>> &Args,
1577
raw_ostream &OS) {
1578
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
1579
1580
OS << "void " << R.getName() << "Attr::printPretty("
1581
<< "raw_ostream &OS, const PrintingPolicy &Policy) const {\n";
1582
1583
if (Spellings.empty()) {
1584
OS << "}\n\n";
1585
return;
1586
}
1587
1588
OS << " bool IsFirstArgument = true; (void)IsFirstArgument;\n"
1589
<< " unsigned TrailingOmittedArgs = 0; (void)TrailingOmittedArgs;\n"
1590
<< " switch (getAttributeSpellingListIndex()) {\n"
1591
<< " default:\n"
1592
<< " llvm_unreachable(\"Unknown attribute spelling!\");\n"
1593
<< " break;\n";
1594
1595
for (unsigned I = 0; I < Spellings.size(); ++ I) {
1596
llvm::SmallString<16> Prefix;
1597
llvm::SmallString<8> Suffix;
1598
// The actual spelling of the name and namespace (if applicable)
1599
// of an attribute without considering prefix and suffix.
1600
llvm::SmallString<64> Spelling;
1601
std::string Name = Spellings[I].name();
1602
std::string Variety = Spellings[I].variety();
1603
1604
if (Variety == "GNU") {
1605
Prefix = "__attribute__((";
1606
Suffix = "))";
1607
} else if (Variety == "CXX11" || Variety == "C23") {
1608
Prefix = "[[";
1609
Suffix = "]]";
1610
std::string Namespace = Spellings[I].nameSpace();
1611
if (!Namespace.empty()) {
1612
Spelling += Namespace;
1613
Spelling += "::";
1614
}
1615
} else if (Variety == "Declspec") {
1616
Prefix = "__declspec(";
1617
Suffix = ")";
1618
} else if (Variety == "Microsoft") {
1619
Prefix = "[";
1620
Suffix = "]";
1621
} else if (Variety == "Keyword") {
1622
Prefix = "";
1623
Suffix = "";
1624
} else if (Variety == "Pragma") {
1625
Prefix = "#pragma ";
1626
Suffix = "\n";
1627
std::string Namespace = Spellings[I].nameSpace();
1628
if (!Namespace.empty()) {
1629
Spelling += Namespace;
1630
Spelling += " ";
1631
}
1632
} else if (Variety == "HLSLAnnotation") {
1633
Prefix = ":";
1634
Suffix = "";
1635
} else {
1636
llvm_unreachable("Unknown attribute syntax variety!");
1637
}
1638
1639
Spelling += Name;
1640
1641
OS << " case " << I << " : {\n"
1642
<< " OS << \"" << Prefix << Spelling << "\";\n";
1643
1644
if (Variety == "Pragma") {
1645
OS << " printPrettyPragma(OS, Policy);\n";
1646
OS << " OS << \"\\n\";";
1647
OS << " break;\n";
1648
OS << " }\n";
1649
continue;
1650
}
1651
1652
if (Spelling == "availability") {
1653
OS << " OS << \"(";
1654
writeAvailabilityValue(OS);
1655
OS << ")\";\n";
1656
} else if (Spelling == "deprecated" || Spelling == "gnu::deprecated") {
1657
OS << " OS << \"(";
1658
writeDeprecatedAttrValue(OS, Variety);
1659
OS << ")\";\n";
1660
} else {
1661
// To avoid printing parentheses around an empty argument list or
1662
// printing spurious commas at the end of an argument list, we need to
1663
// determine where the last provided non-fake argument is.
1664
bool FoundNonOptArg = false;
1665
for (const auto &arg : llvm::reverse(Args)) {
1666
if (arg->isFake())
1667
continue;
1668
if (FoundNonOptArg)
1669
continue;
1670
// FIXME: arg->getIsOmitted() == "false" means we haven't implemented
1671
// any way to detect whether the argument was omitted.
1672
if (!arg->isOptional() || arg->getIsOmitted() == "false") {
1673
FoundNonOptArg = true;
1674
continue;
1675
}
1676
OS << " if (" << arg->getIsOmitted() << ")\n"
1677
<< " ++TrailingOmittedArgs;\n";
1678
}
1679
unsigned ArgIndex = 0;
1680
for (const auto &arg : Args) {
1681
if (arg->isFake())
1682
continue;
1683
std::string IsOmitted = arg->getIsOmitted();
1684
if (arg->isOptional() && IsOmitted != "false")
1685
OS << " if (!(" << IsOmitted << ")) {\n";
1686
// Variadic arguments print their own leading comma.
1687
if (!arg->isVariadic())
1688
OS << " DelimitAttributeArgument(OS, IsFirstArgument);\n";
1689
OS << " OS << \"";
1690
arg->writeValue(OS);
1691
OS << "\";\n";
1692
if (arg->isOptional() && IsOmitted != "false")
1693
OS << " }\n";
1694
++ArgIndex;
1695
}
1696
if (ArgIndex != 0)
1697
OS << " if (!IsFirstArgument)\n"
1698
<< " OS << \")\";\n";
1699
}
1700
OS << " OS << \"" << Suffix << "\";\n"
1701
<< " break;\n"
1702
<< " }\n";
1703
}
1704
1705
// End of the switch statement.
1706
OS << "}\n";
1707
// End of the print function.
1708
OS << "}\n\n";
1709
}
1710
1711
/// Return the index of a spelling in a spelling list.
1712
static unsigned
1713
getSpellingListIndex(const std::vector<FlattenedSpelling> &SpellingList,
1714
const FlattenedSpelling &Spelling) {
1715
assert(!SpellingList.empty() && "Spelling list is empty!");
1716
1717
for (unsigned Index = 0; Index < SpellingList.size(); ++Index) {
1718
const FlattenedSpelling &S = SpellingList[Index];
1719
if (S.variety() != Spelling.variety())
1720
continue;
1721
if (S.nameSpace() != Spelling.nameSpace())
1722
continue;
1723
if (S.name() != Spelling.name())
1724
continue;
1725
1726
return Index;
1727
}
1728
1729
llvm_unreachable("Unknown spelling!");
1730
}
1731
1732
static void writeAttrAccessorDefinition(const Record &R, raw_ostream &OS) {
1733
std::vector<Record*> Accessors = R.getValueAsListOfDefs("Accessors");
1734
if (Accessors.empty())
1735
return;
1736
1737
const std::vector<FlattenedSpelling> SpellingList = GetFlattenedSpellings(R);
1738
assert(!SpellingList.empty() &&
1739
"Attribute with empty spelling list can't have accessors!");
1740
for (const auto *Accessor : Accessors) {
1741
const StringRef Name = Accessor->getValueAsString("Name");
1742
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Accessor);
1743
1744
OS << " bool " << Name
1745
<< "() const { return getAttributeSpellingListIndex() == ";
1746
for (unsigned Index = 0; Index < Spellings.size(); ++Index) {
1747
OS << getSpellingListIndex(SpellingList, Spellings[Index]);
1748
if (Index != Spellings.size() - 1)
1749
OS << " ||\n getAttributeSpellingListIndex() == ";
1750
else
1751
OS << "; }\n";
1752
}
1753
}
1754
}
1755
1756
static bool
1757
SpellingNamesAreCommon(const std::vector<FlattenedSpelling>& Spellings) {
1758
assert(!Spellings.empty() && "An empty list of spellings was provided");
1759
std::string FirstName =
1760
std::string(NormalizeNameForSpellingComparison(Spellings.front().name()));
1761
for (const auto &Spelling : llvm::drop_begin(Spellings)) {
1762
std::string Name =
1763
std::string(NormalizeNameForSpellingComparison(Spelling.name()));
1764
if (Name != FirstName)
1765
return false;
1766
}
1767
return true;
1768
}
1769
1770
typedef std::map<unsigned, std::string> SemanticSpellingMap;
1771
static std::string
1772
CreateSemanticSpellings(const std::vector<FlattenedSpelling> &Spellings,
1773
SemanticSpellingMap &Map) {
1774
// The enumerants are automatically generated based on the variety,
1775
// namespace (if present) and name for each attribute spelling. However,
1776
// care is taken to avoid trampling on the reserved namespace due to
1777
// underscores.
1778
std::string Ret(" enum Spelling {\n");
1779
std::set<std::string> Uniques;
1780
unsigned Idx = 0;
1781
1782
// If we have a need to have this many spellings we likely need to add an
1783
// extra bit to the SpellingIndex in AttributeCommonInfo, then increase the
1784
// value of SpellingNotCalculated there and here.
1785
assert(Spellings.size() < 15 &&
1786
"Too many spellings, would step on SpellingNotCalculated in "
1787
"AttributeCommonInfo");
1788
for (auto I = Spellings.begin(), E = Spellings.end(); I != E; ++I, ++Idx) {
1789
const FlattenedSpelling &S = *I;
1790
const std::string &Variety = S.variety();
1791
const std::string &Spelling = S.name();
1792
const std::string &Namespace = S.nameSpace();
1793
std::string EnumName;
1794
1795
EnumName += (Variety + "_");
1796
if (!Namespace.empty())
1797
EnumName += (NormalizeNameForSpellingComparison(Namespace).str() +
1798
"_");
1799
EnumName += NormalizeNameForSpellingComparison(Spelling);
1800
1801
// Even if the name is not unique, this spelling index corresponds to a
1802
// particular enumerant name that we've calculated.
1803
Map[Idx] = EnumName;
1804
1805
// Since we have been stripping underscores to avoid trampling on the
1806
// reserved namespace, we may have inadvertently created duplicate
1807
// enumerant names. These duplicates are not considered part of the
1808
// semantic spelling, and can be elided.
1809
if (Uniques.find(EnumName) != Uniques.end())
1810
continue;
1811
1812
Uniques.insert(EnumName);
1813
if (I != Spellings.begin())
1814
Ret += ",\n";
1815
// Duplicate spellings are not considered part of the semantic spelling
1816
// enumeration, but the spelling index and semantic spelling values are
1817
// meant to be equivalent, so we must specify a concrete value for each
1818
// enumerator.
1819
Ret += " " + EnumName + " = " + llvm::utostr(Idx);
1820
}
1821
Ret += ",\n SpellingNotCalculated = 15\n";
1822
Ret += "\n };\n\n";
1823
return Ret;
1824
}
1825
1826
void WriteSemanticSpellingSwitch(const std::string &VarName,
1827
const SemanticSpellingMap &Map,
1828
raw_ostream &OS) {
1829
OS << " switch (" << VarName << ") {\n default: "
1830
<< "llvm_unreachable(\"Unknown spelling list index\");\n";
1831
for (const auto &I : Map)
1832
OS << " case " << I.first << ": return " << I.second << ";\n";
1833
OS << " }\n";
1834
}
1835
1836
// Note: these values need to match the values used by LateAttrParseKind in
1837
// `Attr.td`
1838
enum class LateAttrParseKind { Never = 0, Standard = 1, ExperimentalExt = 2 };
1839
1840
static LateAttrParseKind getLateAttrParseKind(const Record *Attr) {
1841
// This function basically does
1842
// `Attr->getValueAsDef("LateParsed")->getValueAsInt("Kind")` but does a bunch
1843
// of sanity checking to ensure that `LateAttrParseMode` in `Attr.td` is in
1844
// sync with the `LateAttrParseKind` enum in this source file.
1845
1846
static constexpr StringRef LateParsedStr = "LateParsed";
1847
static constexpr StringRef LateAttrParseKindStr = "LateAttrParseKind";
1848
static constexpr StringRef KindFieldStr = "Kind";
1849
1850
auto *LAPK = Attr->getValueAsDef(LateParsedStr);
1851
1852
// Typecheck the `LateParsed` field.
1853
SmallVector<Record *, 1> SuperClasses;
1854
LAPK->getDirectSuperClasses(SuperClasses);
1855
if (SuperClasses.size() != 1)
1856
PrintFatalError(Attr, "Field `" + llvm::Twine(LateParsedStr) +
1857
"`should only have one super class");
1858
1859
if (SuperClasses[0]->getName() != LateAttrParseKindStr)
1860
PrintFatalError(Attr, "Field `" + llvm::Twine(LateParsedStr) +
1861
"`should only have type `" +
1862
llvm::Twine(LateAttrParseKindStr) +
1863
"` but found type `" +
1864
SuperClasses[0]->getName() + "`");
1865
1866
// Get Kind and verify the enum name matches the name in `Attr.td`.
1867
unsigned Kind = LAPK->getValueAsInt(KindFieldStr);
1868
switch (LateAttrParseKind(Kind)) {
1869
#define CASE(X) \
1870
case LateAttrParseKind::X: \
1871
if (LAPK->getName().compare("LateAttrParse" #X) != 0) { \
1872
PrintFatalError(Attr, \
1873
"Field `" + llvm::Twine(LateParsedStr) + "` set to `" + \
1874
LAPK->getName() + \
1875
"` but this converts to `LateAttrParseKind::" + \
1876
llvm::Twine(#X) + "`"); \
1877
} \
1878
return LateAttrParseKind::X;
1879
1880
CASE(Never)
1881
CASE(Standard)
1882
CASE(ExperimentalExt)
1883
#undef CASE
1884
}
1885
1886
// The Kind value is completely invalid
1887
auto KindValueStr = llvm::utostr(Kind);
1888
PrintFatalError(Attr, "Field `" + llvm::Twine(LateParsedStr) + "` set to `" +
1889
LAPK->getName() + "` has unexpected `" +
1890
llvm::Twine(KindFieldStr) + "` value of " +
1891
KindValueStr);
1892
}
1893
1894
// Emits the LateParsed property for attributes.
1895
static void emitClangAttrLateParsedListImpl(RecordKeeper &Records,
1896
raw_ostream &OS,
1897
LateAttrParseKind LateParseMode) {
1898
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
1899
1900
for (const auto *Attr : Attrs) {
1901
if (LateAttrParseKind LateParsed = getLateAttrParseKind(Attr);
1902
LateParsed != LateParseMode)
1903
continue;
1904
1905
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);
1906
1907
// FIXME: Handle non-GNU attributes
1908
for (const auto &I : Spellings) {
1909
if (I.variety() != "GNU")
1910
continue;
1911
OS << ".Case(\"" << I.name() << "\", 1)\n";
1912
}
1913
}
1914
}
1915
1916
static void emitClangAttrLateParsedList(RecordKeeper &Records,
1917
raw_ostream &OS) {
1918
OS << "#if defined(CLANG_ATTR_LATE_PARSED_LIST)\n";
1919
emitClangAttrLateParsedListImpl(Records, OS, LateAttrParseKind::Standard);
1920
OS << "#endif // CLANG_ATTR_LATE_PARSED_LIST\n\n";
1921
}
1922
1923
static void emitClangAttrLateParsedExperimentalList(RecordKeeper &Records,
1924
raw_ostream &OS) {
1925
OS << "#if defined(CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST)\n";
1926
emitClangAttrLateParsedListImpl(Records, OS,
1927
LateAttrParseKind::ExperimentalExt);
1928
OS << "#endif // CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST\n\n";
1929
}
1930
1931
static bool hasGNUorCXX11Spelling(const Record &Attribute) {
1932
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attribute);
1933
for (const auto &I : Spellings) {
1934
if (I.variety() == "GNU" || I.variety() == "CXX11")
1935
return true;
1936
}
1937
return false;
1938
}
1939
1940
namespace {
1941
1942
struct AttributeSubjectMatchRule {
1943
const Record *MetaSubject;
1944
const Record *Constraint;
1945
1946
AttributeSubjectMatchRule(const Record *MetaSubject, const Record *Constraint)
1947
: MetaSubject(MetaSubject), Constraint(Constraint) {
1948
assert(MetaSubject && "Missing subject");
1949
}
1950
1951
bool isSubRule() const { return Constraint != nullptr; }
1952
1953
std::vector<Record *> getSubjects() const {
1954
return (Constraint ? Constraint : MetaSubject)
1955
->getValueAsListOfDefs("Subjects");
1956
}
1957
1958
std::vector<Record *> getLangOpts() const {
1959
if (Constraint) {
1960
// Lookup the options in the sub-rule first, in case the sub-rule
1961
// overrides the rules options.
1962
std::vector<Record *> Opts = Constraint->getValueAsListOfDefs("LangOpts");
1963
if (!Opts.empty())
1964
return Opts;
1965
}
1966
return MetaSubject->getValueAsListOfDefs("LangOpts");
1967
}
1968
1969
// Abstract rules are used only for sub-rules
1970
bool isAbstractRule() const { return getSubjects().empty(); }
1971
1972
StringRef getName() const {
1973
return (Constraint ? Constraint : MetaSubject)->getValueAsString("Name");
1974
}
1975
1976
bool isNegatedSubRule() const {
1977
assert(isSubRule() && "Not a sub-rule");
1978
return Constraint->getValueAsBit("Negated");
1979
}
1980
1981
std::string getSpelling() const {
1982
std::string Result = std::string(MetaSubject->getValueAsString("Name"));
1983
if (isSubRule()) {
1984
Result += '(';
1985
if (isNegatedSubRule())
1986
Result += "unless(";
1987
Result += getName();
1988
if (isNegatedSubRule())
1989
Result += ')';
1990
Result += ')';
1991
}
1992
return Result;
1993
}
1994
1995
std::string getEnumValueName() const {
1996
SmallString<128> Result;
1997
Result += "SubjectMatchRule_";
1998
Result += MetaSubject->getValueAsString("Name");
1999
if (isSubRule()) {
2000
Result += "_";
2001
if (isNegatedSubRule())
2002
Result += "not_";
2003
Result += Constraint->getValueAsString("Name");
2004
}
2005
if (isAbstractRule())
2006
Result += "_abstract";
2007
return std::string(Result);
2008
}
2009
2010
std::string getEnumValue() const { return "attr::" + getEnumValueName(); }
2011
2012
static const char *EnumName;
2013
};
2014
2015
const char *AttributeSubjectMatchRule::EnumName = "attr::SubjectMatchRule";
2016
2017
struct PragmaClangAttributeSupport {
2018
std::vector<AttributeSubjectMatchRule> Rules;
2019
2020
class RuleOrAggregateRuleSet {
2021
std::vector<AttributeSubjectMatchRule> Rules;
2022
bool IsRule;
2023
RuleOrAggregateRuleSet(ArrayRef<AttributeSubjectMatchRule> Rules,
2024
bool IsRule)
2025
: Rules(Rules), IsRule(IsRule) {}
2026
2027
public:
2028
bool isRule() const { return IsRule; }
2029
2030
const AttributeSubjectMatchRule &getRule() const {
2031
assert(IsRule && "not a rule!");
2032
return Rules[0];
2033
}
2034
2035
ArrayRef<AttributeSubjectMatchRule> getAggregateRuleSet() const {
2036
return Rules;
2037
}
2038
2039
static RuleOrAggregateRuleSet
2040
getRule(const AttributeSubjectMatchRule &Rule) {
2041
return RuleOrAggregateRuleSet(Rule, /*IsRule=*/true);
2042
}
2043
static RuleOrAggregateRuleSet
2044
getAggregateRuleSet(ArrayRef<AttributeSubjectMatchRule> Rules) {
2045
return RuleOrAggregateRuleSet(Rules, /*IsRule=*/false);
2046
}
2047
};
2048
llvm::DenseMap<const Record *, RuleOrAggregateRuleSet> SubjectsToRules;
2049
2050
PragmaClangAttributeSupport(RecordKeeper &Records);
2051
2052
bool isAttributedSupported(const Record &Attribute);
2053
2054
void emitMatchRuleList(raw_ostream &OS);
2055
2056
void generateStrictConformsTo(const Record &Attr, raw_ostream &OS);
2057
2058
void generateParsingHelpers(raw_ostream &OS);
2059
};
2060
2061
} // end anonymous namespace
2062
2063
static bool isSupportedPragmaClangAttributeSubject(const Record &Subject) {
2064
// FIXME: #pragma clang attribute does not currently support statement
2065
// attributes, so test whether the subject is one that appertains to a
2066
// declaration node. However, it may be reasonable for support for statement
2067
// attributes to be added.
2068
if (Subject.isSubClassOf("DeclNode") || Subject.isSubClassOf("DeclBase") ||
2069
Subject.getName() == "DeclBase")
2070
return true;
2071
2072
if (Subject.isSubClassOf("SubsetSubject"))
2073
return isSupportedPragmaClangAttributeSubject(
2074
*Subject.getValueAsDef("Base"));
2075
2076
return false;
2077
}
2078
2079
static bool doesDeclDeriveFrom(const Record *D, const Record *Base) {
2080
const Record *CurrentBase = D->getValueAsOptionalDef(BaseFieldName);
2081
if (!CurrentBase)
2082
return false;
2083
if (CurrentBase == Base)
2084
return true;
2085
return doesDeclDeriveFrom(CurrentBase, Base);
2086
}
2087
2088
PragmaClangAttributeSupport::PragmaClangAttributeSupport(
2089
RecordKeeper &Records) {
2090
std::vector<Record *> MetaSubjects =
2091
Records.getAllDerivedDefinitions("AttrSubjectMatcherRule");
2092
auto MapFromSubjectsToRules = [this](const Record *SubjectContainer,
2093
const Record *MetaSubject,
2094
const Record *Constraint) {
2095
Rules.emplace_back(MetaSubject, Constraint);
2096
std::vector<Record *> ApplicableSubjects =
2097
SubjectContainer->getValueAsListOfDefs("Subjects");
2098
for (const auto *Subject : ApplicableSubjects) {
2099
bool Inserted =
2100
SubjectsToRules
2101
.try_emplace(Subject, RuleOrAggregateRuleSet::getRule(
2102
AttributeSubjectMatchRule(MetaSubject,
2103
Constraint)))
2104
.second;
2105
if (!Inserted) {
2106
PrintFatalError("Attribute subject match rules should not represent"
2107
"same attribute subjects.");
2108
}
2109
}
2110
};
2111
for (const auto *MetaSubject : MetaSubjects) {
2112
MapFromSubjectsToRules(MetaSubject, MetaSubject, /*Constraints=*/nullptr);
2113
std::vector<Record *> Constraints =
2114
MetaSubject->getValueAsListOfDefs("Constraints");
2115
for (const auto *Constraint : Constraints)
2116
MapFromSubjectsToRules(Constraint, MetaSubject, Constraint);
2117
}
2118
2119
std::vector<Record *> Aggregates =
2120
Records.getAllDerivedDefinitions("AttrSubjectMatcherAggregateRule");
2121
std::vector<Record *> DeclNodes =
2122
Records.getAllDerivedDefinitions(DeclNodeClassName);
2123
for (const auto *Aggregate : Aggregates) {
2124
Record *SubjectDecl = Aggregate->getValueAsDef("Subject");
2125
2126
// Gather sub-classes of the aggregate subject that act as attribute
2127
// subject rules.
2128
std::vector<AttributeSubjectMatchRule> Rules;
2129
for (const auto *D : DeclNodes) {
2130
if (doesDeclDeriveFrom(D, SubjectDecl)) {
2131
auto It = SubjectsToRules.find(D);
2132
if (It == SubjectsToRules.end())
2133
continue;
2134
if (!It->second.isRule() || It->second.getRule().isSubRule())
2135
continue; // Assume that the rule will be included as well.
2136
Rules.push_back(It->second.getRule());
2137
}
2138
}
2139
2140
bool Inserted =
2141
SubjectsToRules
2142
.try_emplace(SubjectDecl,
2143
RuleOrAggregateRuleSet::getAggregateRuleSet(Rules))
2144
.second;
2145
if (!Inserted) {
2146
PrintFatalError("Attribute subject match rules should not represent"
2147
"same attribute subjects.");
2148
}
2149
}
2150
}
2151
2152
static PragmaClangAttributeSupport &
2153
getPragmaAttributeSupport(RecordKeeper &Records) {
2154
static PragmaClangAttributeSupport Instance(Records);
2155
return Instance;
2156
}
2157
2158
void PragmaClangAttributeSupport::emitMatchRuleList(raw_ostream &OS) {
2159
OS << "#ifndef ATTR_MATCH_SUB_RULE\n";
2160
OS << "#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, "
2161
"IsNegated) "
2162
<< "ATTR_MATCH_RULE(Value, Spelling, IsAbstract)\n";
2163
OS << "#endif\n";
2164
for (const auto &Rule : Rules) {
2165
OS << (Rule.isSubRule() ? "ATTR_MATCH_SUB_RULE" : "ATTR_MATCH_RULE") << '(';
2166
OS << Rule.getEnumValueName() << ", \"" << Rule.getSpelling() << "\", "
2167
<< Rule.isAbstractRule();
2168
if (Rule.isSubRule())
2169
OS << ", "
2170
<< AttributeSubjectMatchRule(Rule.MetaSubject, nullptr).getEnumValue()
2171
<< ", " << Rule.isNegatedSubRule();
2172
OS << ")\n";
2173
}
2174
OS << "#undef ATTR_MATCH_SUB_RULE\n";
2175
}
2176
2177
bool PragmaClangAttributeSupport::isAttributedSupported(
2178
const Record &Attribute) {
2179
// If the attribute explicitly specified whether to support #pragma clang
2180
// attribute, use that setting.
2181
bool Unset;
2182
bool SpecifiedResult =
2183
Attribute.getValueAsBitOrUnset("PragmaAttributeSupport", Unset);
2184
if (!Unset)
2185
return SpecifiedResult;
2186
2187
// Opt-out rules:
2188
2189
// An attribute requires delayed parsing (LateParsed is on).
2190
switch (getLateAttrParseKind(&Attribute)) {
2191
case LateAttrParseKind::Never:
2192
break;
2193
case LateAttrParseKind::Standard:
2194
return false;
2195
case LateAttrParseKind::ExperimentalExt:
2196
// This is only late parsed in certain parsing contexts when
2197
// `LangOpts.ExperimentalLateParseAttributes` is true. Information about the
2198
// parsing context and `LangOpts` is not available in this method so just
2199
// opt this attribute out.
2200
return false;
2201
}
2202
2203
// An attribute has no GNU/CXX11 spelling
2204
if (!hasGNUorCXX11Spelling(Attribute))
2205
return false;
2206
// An attribute subject list has a subject that isn't covered by one of the
2207
// subject match rules or has no subjects at all.
2208
if (Attribute.isValueUnset("Subjects"))
2209
return false;
2210
const Record *SubjectObj = Attribute.getValueAsDef("Subjects");
2211
std::vector<Record *> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
2212
bool HasAtLeastOneValidSubject = false;
2213
for (const auto *Subject : Subjects) {
2214
if (!isSupportedPragmaClangAttributeSubject(*Subject))
2215
continue;
2216
if (!SubjectsToRules.contains(Subject))
2217
return false;
2218
HasAtLeastOneValidSubject = true;
2219
}
2220
return HasAtLeastOneValidSubject;
2221
}
2222
2223
static std::string GenerateTestExpression(ArrayRef<Record *> LangOpts) {
2224
std::string Test;
2225
2226
for (auto *E : LangOpts) {
2227
if (!Test.empty())
2228
Test += " || ";
2229
2230
const StringRef Code = E->getValueAsString("CustomCode");
2231
if (!Code.empty()) {
2232
Test += "(";
2233
Test += Code;
2234
Test += ")";
2235
if (!E->getValueAsString("Name").empty()) {
2236
PrintWarning(
2237
E->getLoc(),
2238
"non-empty 'Name' field ignored because 'CustomCode' was supplied");
2239
}
2240
} else {
2241
Test += "LangOpts.";
2242
Test += E->getValueAsString("Name");
2243
}
2244
}
2245
2246
if (Test.empty())
2247
return "true";
2248
2249
return Test;
2250
}
2251
2252
void
2253
PragmaClangAttributeSupport::generateStrictConformsTo(const Record &Attr,
2254
raw_ostream &OS) {
2255
if (!isAttributedSupported(Attr) || Attr.isValueUnset("Subjects"))
2256
return;
2257
// Generate a function that constructs a set of matching rules that describe
2258
// to which declarations the attribute should apply to.
2259
OS << "void getPragmaAttributeMatchRules("
2260
<< "llvm::SmallVectorImpl<std::pair<"
2261
<< AttributeSubjectMatchRule::EnumName
2262
<< ", bool>> &MatchRules, const LangOptions &LangOpts) const override {\n";
2263
const Record *SubjectObj = Attr.getValueAsDef("Subjects");
2264
std::vector<Record *> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
2265
for (const auto *Subject : Subjects) {
2266
if (!isSupportedPragmaClangAttributeSubject(*Subject))
2267
continue;
2268
auto It = SubjectsToRules.find(Subject);
2269
assert(It != SubjectsToRules.end() &&
2270
"This attribute is unsupported by #pragma clang attribute");
2271
for (const auto &Rule : It->getSecond().getAggregateRuleSet()) {
2272
// The rule might be language specific, so only subtract it from the given
2273
// rules if the specific language options are specified.
2274
std::vector<Record *> LangOpts = Rule.getLangOpts();
2275
OS << " MatchRules.push_back(std::make_pair(" << Rule.getEnumValue()
2276
<< ", /*IsSupported=*/" << GenerateTestExpression(LangOpts)
2277
<< "));\n";
2278
}
2279
}
2280
OS << "}\n\n";
2281
}
2282
2283
void PragmaClangAttributeSupport::generateParsingHelpers(raw_ostream &OS) {
2284
// Generate routines that check the names of sub-rules.
2285
OS << "std::optional<attr::SubjectMatchRule> "
2286
"defaultIsAttributeSubjectMatchSubRuleFor(StringRef, bool) {\n";
2287
OS << " return std::nullopt;\n";
2288
OS << "}\n\n";
2289
2290
llvm::MapVector<const Record *, std::vector<AttributeSubjectMatchRule>>
2291
SubMatchRules;
2292
for (const auto &Rule : Rules) {
2293
if (!Rule.isSubRule())
2294
continue;
2295
SubMatchRules[Rule.MetaSubject].push_back(Rule);
2296
}
2297
2298
for (const auto &SubMatchRule : SubMatchRules) {
2299
OS << "std::optional<attr::SubjectMatchRule> "
2300
"isAttributeSubjectMatchSubRuleFor_"
2301
<< SubMatchRule.first->getValueAsString("Name")
2302
<< "(StringRef Name, bool IsUnless) {\n";
2303
OS << " if (IsUnless)\n";
2304
OS << " return "
2305
"llvm::StringSwitch<std::optional<attr::SubjectMatchRule>>(Name).\n";
2306
for (const auto &Rule : SubMatchRule.second) {
2307
if (Rule.isNegatedSubRule())
2308
OS << " Case(\"" << Rule.getName() << "\", " << Rule.getEnumValue()
2309
<< ").\n";
2310
}
2311
OS << " Default(std::nullopt);\n";
2312
OS << " return "
2313
"llvm::StringSwitch<std::optional<attr::SubjectMatchRule>>(Name).\n";
2314
for (const auto &Rule : SubMatchRule.second) {
2315
if (!Rule.isNegatedSubRule())
2316
OS << " Case(\"" << Rule.getName() << "\", " << Rule.getEnumValue()
2317
<< ").\n";
2318
}
2319
OS << " Default(std::nullopt);\n";
2320
OS << "}\n\n";
2321
}
2322
2323
// Generate the function that checks for the top-level rules.
2324
OS << "std::pair<std::optional<attr::SubjectMatchRule>, "
2325
"std::optional<attr::SubjectMatchRule> (*)(StringRef, "
2326
"bool)> isAttributeSubjectMatchRule(StringRef Name) {\n";
2327
OS << " return "
2328
"llvm::StringSwitch<std::pair<std::optional<attr::SubjectMatchRule>, "
2329
"std::optional<attr::SubjectMatchRule> (*) (StringRef, "
2330
"bool)>>(Name).\n";
2331
for (const auto &Rule : Rules) {
2332
if (Rule.isSubRule())
2333
continue;
2334
std::string SubRuleFunction;
2335
if (SubMatchRules.count(Rule.MetaSubject))
2336
SubRuleFunction =
2337
("isAttributeSubjectMatchSubRuleFor_" + Rule.getName()).str();
2338
else
2339
SubRuleFunction = "defaultIsAttributeSubjectMatchSubRuleFor";
2340
OS << " Case(\"" << Rule.getName() << "\", std::make_pair("
2341
<< Rule.getEnumValue() << ", " << SubRuleFunction << ")).\n";
2342
}
2343
OS << " Default(std::make_pair(std::nullopt, "
2344
"defaultIsAttributeSubjectMatchSubRuleFor));\n";
2345
OS << "}\n\n";
2346
2347
// Generate the function that checks for the submatch rules.
2348
OS << "const char *validAttributeSubjectMatchSubRules("
2349
<< AttributeSubjectMatchRule::EnumName << " Rule) {\n";
2350
OS << " switch (Rule) {\n";
2351
for (const auto &SubMatchRule : SubMatchRules) {
2352
OS << " case "
2353
<< AttributeSubjectMatchRule(SubMatchRule.first, nullptr).getEnumValue()
2354
<< ":\n";
2355
OS << " return \"'";
2356
bool IsFirst = true;
2357
for (const auto &Rule : SubMatchRule.second) {
2358
if (!IsFirst)
2359
OS << ", '";
2360
IsFirst = false;
2361
if (Rule.isNegatedSubRule())
2362
OS << "unless(";
2363
OS << Rule.getName();
2364
if (Rule.isNegatedSubRule())
2365
OS << ')';
2366
OS << "'";
2367
}
2368
OS << "\";\n";
2369
}
2370
OS << " default: return nullptr;\n";
2371
OS << " }\n";
2372
OS << "}\n\n";
2373
}
2374
2375
template <typename Fn>
2376
static void forEachUniqueSpelling(const Record &Attr, Fn &&F) {
2377
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
2378
SmallDenseSet<StringRef, 8> Seen;
2379
for (const FlattenedSpelling &S : Spellings) {
2380
if (Seen.insert(S.name()).second)
2381
F(S);
2382
}
2383
}
2384
2385
static bool isTypeArgument(const Record *Arg) {
2386
return !Arg->getSuperClasses().empty() &&
2387
Arg->getSuperClasses().back().first->getName() == "TypeArgument";
2388
}
2389
2390
/// Emits the first-argument-is-type property for attributes.
2391
static void emitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
2392
OS << "#if defined(CLANG_ATTR_TYPE_ARG_LIST)\n";
2393
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
2394
2395
for (const auto *Attr : Attrs) {
2396
// Determine whether the first argument is a type.
2397
std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
2398
if (Args.empty())
2399
continue;
2400
2401
if (!isTypeArgument(Args[0]))
2402
continue;
2403
2404
// All these spellings take a single type argument.
2405
forEachUniqueSpelling(*Attr, [&](const FlattenedSpelling &S) {
2406
OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
2407
});
2408
}
2409
OS << "#endif // CLANG_ATTR_TYPE_ARG_LIST\n\n";
2410
}
2411
2412
/// Emits the parse-arguments-in-unevaluated-context property for
2413
/// attributes.
2414
static void emitClangAttrArgContextList(RecordKeeper &Records, raw_ostream &OS) {
2415
OS << "#if defined(CLANG_ATTR_ARG_CONTEXT_LIST)\n";
2416
ParsedAttrMap Attrs = getParsedAttrList(Records);
2417
for (const auto &I : Attrs) {
2418
const Record &Attr = *I.second;
2419
2420
if (!Attr.getValueAsBit("ParseArgumentsAsUnevaluated"))
2421
continue;
2422
2423
// All these spellings take are parsed unevaluated.
2424
forEachUniqueSpelling(Attr, [&](const FlattenedSpelling &S) {
2425
OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
2426
});
2427
}
2428
OS << "#endif // CLANG_ATTR_ARG_CONTEXT_LIST\n\n";
2429
}
2430
2431
static bool isIdentifierArgument(const Record *Arg) {
2432
return !Arg->getSuperClasses().empty() &&
2433
llvm::StringSwitch<bool>(Arg->getSuperClasses().back().first->getName())
2434
.Case("IdentifierArgument", true)
2435
.Case("EnumArgument", true)
2436
.Case("VariadicEnumArgument", true)
2437
.Default(false);
2438
}
2439
2440
static bool isVariadicIdentifierArgument(const Record *Arg) {
2441
return !Arg->getSuperClasses().empty() &&
2442
llvm::StringSwitch<bool>(
2443
Arg->getSuperClasses().back().first->getName())
2444
.Case("VariadicIdentifierArgument", true)
2445
.Case("VariadicParamOrParamIdxArgument", true)
2446
.Default(false);
2447
}
2448
2449
static bool isVariadicExprArgument(const Record *Arg) {
2450
return !Arg->getSuperClasses().empty() &&
2451
llvm::StringSwitch<bool>(
2452
Arg->getSuperClasses().back().first->getName())
2453
.Case("VariadicExprArgument", true)
2454
.Default(false);
2455
}
2456
2457
static bool isStringLiteralArgument(const Record *Arg) {
2458
if (Arg->getSuperClasses().empty())
2459
return false;
2460
StringRef ArgKind = Arg->getSuperClasses().back().first->getName();
2461
if (ArgKind == "EnumArgument")
2462
return Arg->getValueAsBit("IsString");
2463
return ArgKind == "StringArgument";
2464
}
2465
2466
static bool isVariadicStringLiteralArgument(const Record *Arg) {
2467
if (Arg->getSuperClasses().empty())
2468
return false;
2469
StringRef ArgKind = Arg->getSuperClasses().back().first->getName();
2470
if (ArgKind == "VariadicEnumArgument")
2471
return Arg->getValueAsBit("IsString");
2472
return ArgKind == "VariadicStringArgument";
2473
}
2474
2475
static void emitClangAttrVariadicIdentifierArgList(RecordKeeper &Records,
2476
raw_ostream &OS) {
2477
OS << "#if defined(CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST)\n";
2478
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
2479
for (const auto *A : Attrs) {
2480
// Determine whether the first argument is a variadic identifier.
2481
std::vector<Record *> Args = A->getValueAsListOfDefs("Args");
2482
if (Args.empty() || !isVariadicIdentifierArgument(Args[0]))
2483
continue;
2484
2485
// All these spellings take an identifier argument.
2486
forEachUniqueSpelling(*A, [&](const FlattenedSpelling &S) {
2487
OS << ".Case(\"" << S.name() << "\", "
2488
<< "true"
2489
<< ")\n";
2490
});
2491
}
2492
OS << "#endif // CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST\n\n";
2493
}
2494
2495
static bool GenerateTargetSpecificAttrChecks(const Record *R,
2496
std::vector<StringRef> &Arches,
2497
std::string &Test,
2498
std::string *FnName);
2499
2500
// Emits the list of arguments that should be parsed as unevaluated string
2501
// literals for each attribute.
2502
static void emitClangAttrUnevaluatedStringLiteralList(RecordKeeper &Records,
2503
raw_ostream &OS) {
2504
OS << "#if defined(CLANG_ATTR_STRING_LITERAL_ARG_LIST)\n";
2505
2506
auto MakeMask = [](ArrayRef<Record *> Args) {
2507
uint32_t Bits = 0;
2508
assert(Args.size() <= 32 && "unsupported number of arguments in attribute");
2509
for (uint32_t N = 0; N < Args.size(); ++N) {
2510
Bits |= (isStringLiteralArgument(Args[N]) << N);
2511
// If we have a variadic string argument, set all the remaining bits to 1
2512
if (isVariadicStringLiteralArgument(Args[N])) {
2513
Bits |= maskTrailingZeros<decltype(Bits)>(N);
2514
break;
2515
}
2516
}
2517
return Bits;
2518
};
2519
2520
auto AddMaskWithTargetCheck = [](const Record *Attr, uint32_t Mask,
2521
std::string &MaskStr) {
2522
const Record *T = Attr->getValueAsDef("Target");
2523
std::vector<StringRef> Arches = T->getValueAsListOfStrings("Arches");
2524
std::string Test;
2525
GenerateTargetSpecificAttrChecks(T, Arches, Test, nullptr);
2526
MaskStr.append(Test + " ? " + std::to_string(Mask) + " : ");
2527
};
2528
2529
ParsedAttrMap Dupes;
2530
ParsedAttrMap Attrs = getParsedAttrList(Records, &Dupes, /*SemaOnly=*/false);
2531
for (const auto &[AttrName, Attr] : Attrs) {
2532
std::string MaskStr;
2533
if (Attr->isSubClassOf("TargetSpecificAttr") &&
2534
!Attr->isValueUnset("ParseKind")) {
2535
if (uint32_t Mask = MakeMask(Attr->getValueAsListOfDefs("Args")))
2536
AddMaskWithTargetCheck(Attr, Mask, MaskStr);
2537
StringRef ParseKind = Attr->getValueAsString("ParseKind");
2538
for (const auto &[DupeParseKind, DupAttr] : Dupes) {
2539
if (DupeParseKind != ParseKind)
2540
continue;
2541
if (uint32_t Mask = MakeMask(DupAttr->getValueAsListOfDefs("Args")))
2542
AddMaskWithTargetCheck(DupAttr, Mask, MaskStr);
2543
}
2544
if (!MaskStr.empty())
2545
MaskStr.append("0");
2546
} else {
2547
if (uint32_t Mask = MakeMask(Attr->getValueAsListOfDefs("Args")))
2548
MaskStr = std::to_string(Mask);
2549
}
2550
2551
if (MaskStr.empty())
2552
continue;
2553
2554
// All these spellings have at least one string literal has argument.
2555
forEachUniqueSpelling(*Attr, [&](const FlattenedSpelling &S) {
2556
OS << ".Case(\"" << S.name() << "\", " << MaskStr << ")\n";
2557
});
2558
}
2559
OS << "#endif // CLANG_ATTR_STRING_LITERAL_ARG_LIST\n\n";
2560
}
2561
2562
// Emits the first-argument-is-identifier property for attributes.
2563
static void emitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS) {
2564
OS << "#if defined(CLANG_ATTR_IDENTIFIER_ARG_LIST)\n";
2565
std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
2566
2567
for (const auto *Attr : Attrs) {
2568
// Determine whether the first argument is an identifier.
2569
std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
2570
if (Args.empty() || !isIdentifierArgument(Args[0]))
2571
continue;
2572
2573
// All these spellings take an identifier argument.
2574
forEachUniqueSpelling(*Attr, [&](const FlattenedSpelling &S) {
2575
OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
2576
});
2577
}
2578
OS << "#endif // CLANG_ATTR_IDENTIFIER_ARG_LIST\n\n";
2579
}
2580
2581
// Emits the indexed-argument-is-identifier property for attributes.
2582
static void emitClangAttrStrictIdentifierArgAtIndexList(RecordKeeper &Records,
2583
raw_ostream &OS) {
2584
OS << "#if defined(CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST)\n";
2585
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
2586
2587
for (const auto *Attr : Attrs) {
2588
if (!Attr->getValueAsBit("StrictEnumParameters"))
2589
continue;
2590
// Determine whether the first argument is an identifier.
2591
std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
2592
uint64_t enumAtIndex = 0;
2593
for (size_t i = 0; i < Args.size(); i++) {
2594
enumAtIndex |= ((uint64_t)isIdentifierArgument(Args[0])) << i;
2595
}
2596
if (!enumAtIndex)
2597
continue;
2598
2599
// All these spellings take an identifier argument.
2600
forEachUniqueSpelling(*Attr, [&](const FlattenedSpelling &S) {
2601
OS << ".Case(\"" << S.name() << "\", " << enumAtIndex << "ull)\n";
2602
});
2603
}
2604
OS << "#endif // CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST\n\n";
2605
}
2606
2607
static bool keywordThisIsaIdentifierInArgument(const Record *Arg) {
2608
return !Arg->getSuperClasses().empty() &&
2609
llvm::StringSwitch<bool>(
2610
Arg->getSuperClasses().back().first->getName())
2611
.Case("VariadicParamOrParamIdxArgument", true)
2612
.Default(false);
2613
}
2614
2615
static void emitClangAttrThisIsaIdentifierArgList(RecordKeeper &Records,
2616
raw_ostream &OS) {
2617
OS << "#if defined(CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST)\n";
2618
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
2619
for (const auto *A : Attrs) {
2620
// Determine whether the first argument is a variadic identifier.
2621
std::vector<Record *> Args = A->getValueAsListOfDefs("Args");
2622
if (Args.empty() || !keywordThisIsaIdentifierInArgument(Args[0]))
2623
continue;
2624
2625
// All these spellings take an identifier argument.
2626
forEachUniqueSpelling(*A, [&](const FlattenedSpelling &S) {
2627
OS << ".Case(\"" << S.name() << "\", "
2628
<< "true"
2629
<< ")\n";
2630
});
2631
}
2632
OS << "#endif // CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST\n\n";
2633
}
2634
2635
static void emitClangAttrAcceptsExprPack(RecordKeeper &Records,
2636
raw_ostream &OS) {
2637
OS << "#if defined(CLANG_ATTR_ACCEPTS_EXPR_PACK)\n";
2638
ParsedAttrMap Attrs = getParsedAttrList(Records);
2639
for (const auto &I : Attrs) {
2640
const Record &Attr = *I.second;
2641
2642
if (!Attr.getValueAsBit("AcceptsExprPack"))
2643
continue;
2644
2645
forEachUniqueSpelling(Attr, [&](const FlattenedSpelling &S) {
2646
OS << ".Case(\"" << S.name() << "\", true)\n";
2647
});
2648
}
2649
OS << "#endif // CLANG_ATTR_ACCEPTS_EXPR_PACK\n\n";
2650
}
2651
2652
static bool isRegularKeywordAttribute(const FlattenedSpelling &S) {
2653
return (S.variety() == "Keyword" &&
2654
!S.getSpellingRecord().getValueAsBit("HasOwnParseRules"));
2655
}
2656
2657
static void emitFormInitializer(raw_ostream &OS,
2658
const FlattenedSpelling &Spelling,
2659
StringRef SpellingIndex) {
2660
bool IsAlignas =
2661
(Spelling.variety() == "Keyword" && Spelling.name() == "alignas");
2662
OS << "{AttributeCommonInfo::AS_" << Spelling.variety() << ", "
2663
<< SpellingIndex << ", " << (IsAlignas ? "true" : "false")
2664
<< " /*IsAlignas*/, "
2665
<< (isRegularKeywordAttribute(Spelling) ? "true" : "false")
2666
<< " /*IsRegularKeywordAttribute*/}";
2667
}
2668
2669
static void emitAttributes(RecordKeeper &Records, raw_ostream &OS,
2670
bool Header) {
2671
std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
2672
ParsedAttrMap AttrMap = getParsedAttrList(Records);
2673
2674
// Helper to print the starting character of an attribute argument. If there
2675
// hasn't been an argument yet, it prints an opening parenthese; otherwise it
2676
// prints a comma.
2677
OS << "static inline void DelimitAttributeArgument("
2678
<< "raw_ostream& OS, bool& IsFirst) {\n"
2679
<< " if (IsFirst) {\n"
2680
<< " IsFirst = false;\n"
2681
<< " OS << \"(\";\n"
2682
<< " } else\n"
2683
<< " OS << \", \";\n"
2684
<< "}\n";
2685
2686
for (const auto *Attr : Attrs) {
2687
const Record &R = *Attr;
2688
2689
// FIXME: Currently, documentation is generated as-needed due to the fact
2690
// that there is no way to allow a generated project "reach into" the docs
2691
// directory (for instance, it may be an out-of-tree build). However, we want
2692
// to ensure that every attribute has a Documentation field, and produce an
2693
// error if it has been neglected. Otherwise, the on-demand generation which
2694
// happens server-side will fail. This code is ensuring that functionality,
2695
// even though this Emitter doesn't technically need the documentation.
2696
// When attribute documentation can be generated as part of the build
2697
// itself, this code can be removed.
2698
(void)R.getValueAsListOfDefs("Documentation");
2699
2700
if (!R.getValueAsBit("ASTNode"))
2701
continue;
2702
2703
ArrayRef<std::pair<Record *, SMRange>> Supers = R.getSuperClasses();
2704
assert(!Supers.empty() && "Forgot to specify a superclass for the attr");
2705
std::string SuperName;
2706
bool Inheritable = false;
2707
for (const auto &Super : llvm::reverse(Supers)) {
2708
const Record *R = Super.first;
2709
if (R->getName() != "TargetSpecificAttr" &&
2710
R->getName() != "DeclOrTypeAttr" && SuperName.empty())
2711
SuperName = std::string(R->getName());
2712
if (R->getName() == "InheritableAttr")
2713
Inheritable = true;
2714
}
2715
2716
if (Header)
2717
OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n";
2718
else
2719
OS << "\n// " << R.getName() << "Attr implementation\n\n";
2720
2721
std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
2722
std::vector<std::unique_ptr<Argument>> Args;
2723
Args.reserve(ArgRecords.size());
2724
2725
bool AttrAcceptsExprPack = Attr->getValueAsBit("AcceptsExprPack");
2726
if (AttrAcceptsExprPack) {
2727
for (size_t I = 0; I < ArgRecords.size(); ++I) {
2728
const Record *ArgR = ArgRecords[I];
2729
if (isIdentifierArgument(ArgR) || isVariadicIdentifierArgument(ArgR) ||
2730
isTypeArgument(ArgR))
2731
PrintFatalError(Attr->getLoc(),
2732
"Attributes accepting packs cannot also "
2733
"have identifier or type arguments.");
2734
// When trying to determine if value-dependent expressions can populate
2735
// the attribute without prior instantiation, the decision is made based
2736
// on the assumption that only the last argument is ever variadic.
2737
if (I < (ArgRecords.size() - 1) && isVariadicExprArgument(ArgR))
2738
PrintFatalError(Attr->getLoc(),
2739
"Attributes accepting packs can only have the last "
2740
"argument be variadic.");
2741
}
2742
}
2743
2744
bool HasOptArg = false;
2745
bool HasFakeArg = false;
2746
for (const auto *ArgRecord : ArgRecords) {
2747
Args.emplace_back(createArgument(*ArgRecord, R.getName()));
2748
if (Header) {
2749
Args.back()->writeDeclarations(OS);
2750
OS << "\n\n";
2751
}
2752
2753
// For these purposes, fake takes priority over optional.
2754
if (Args.back()->isFake()) {
2755
HasFakeArg = true;
2756
} else if (Args.back()->isOptional()) {
2757
HasOptArg = true;
2758
}
2759
}
2760
2761
std::unique_ptr<VariadicExprArgument> DelayedArgs = nullptr;
2762
if (AttrAcceptsExprPack) {
2763
DelayedArgs =
2764
std::make_unique<VariadicExprArgument>("DelayedArgs", R.getName());
2765
if (Header) {
2766
DelayedArgs->writeDeclarations(OS);
2767
OS << "\n\n";
2768
}
2769
}
2770
2771
if (Header)
2772
OS << "public:\n";
2773
2774
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
2775
2776
// If there are zero or one spellings, all spelling-related functionality
2777
// can be elided. If all of the spellings share the same name, the spelling
2778
// functionality can also be elided.
2779
bool ElideSpelling = (Spellings.size() <= 1) ||
2780
SpellingNamesAreCommon(Spellings);
2781
2782
// This maps spelling index values to semantic Spelling enumerants.
2783
SemanticSpellingMap SemanticToSyntacticMap;
2784
2785
std::string SpellingEnum;
2786
if (Spellings.size() > 1)
2787
SpellingEnum = CreateSemanticSpellings(Spellings, SemanticToSyntacticMap);
2788
if (Header)
2789
OS << SpellingEnum;
2790
2791
const auto &ParsedAttrSpellingItr = llvm::find_if(
2792
AttrMap, [R](const std::pair<std::string, const Record *> &P) {
2793
return &R == P.second;
2794
});
2795
2796
// Emit CreateImplicit factory methods.
2797
auto emitCreate = [&](bool Implicit, bool DelayedArgsOnly, bool emitFake) {
2798
if (Header)
2799
OS << " static ";
2800
OS << R.getName() << "Attr *";
2801
if (!Header)
2802
OS << R.getName() << "Attr::";
2803
OS << "Create";
2804
if (Implicit)
2805
OS << "Implicit";
2806
if (DelayedArgsOnly)
2807
OS << "WithDelayedArgs";
2808
OS << "(";
2809
OS << "ASTContext &Ctx";
2810
if (!DelayedArgsOnly) {
2811
for (auto const &ai : Args) {
2812
if (ai->isFake() && !emitFake)
2813
continue;
2814
OS << ", ";
2815
ai->writeCtorParameters(OS);
2816
}
2817
} else {
2818
OS << ", ";
2819
DelayedArgs->writeCtorParameters(OS);
2820
}
2821
OS << ", const AttributeCommonInfo &CommonInfo";
2822
OS << ")";
2823
if (Header) {
2824
OS << ";\n";
2825
return;
2826
}
2827
2828
OS << " {\n";
2829
OS << " auto *A = new (Ctx) " << R.getName();
2830
OS << "Attr(Ctx, CommonInfo";
2831
2832
if (!DelayedArgsOnly) {
2833
for (auto const &ai : Args) {
2834
if (ai->isFake() && !emitFake)
2835
continue;
2836
OS << ", ";
2837
ai->writeImplicitCtorArgs(OS);
2838
}
2839
}
2840
OS << ");\n";
2841
if (Implicit) {
2842
OS << " A->setImplicit(true);\n";
2843
}
2844
if (Implicit || ElideSpelling) {
2845
OS << " if (!A->isAttributeSpellingListCalculated() && "
2846
"!A->getAttrName())\n";
2847
OS << " A->setAttributeSpellingListIndex(0);\n";
2848
}
2849
if (DelayedArgsOnly) {
2850
OS << " A->setDelayedArgs(Ctx, ";
2851
DelayedArgs->writeImplicitCtorArgs(OS);
2852
OS << ");\n";
2853
}
2854
OS << " return A;\n}\n\n";
2855
};
2856
2857
auto emitCreateNoCI = [&](bool Implicit, bool DelayedArgsOnly,
2858
bool emitFake) {
2859
if (Header)
2860
OS << " static ";
2861
OS << R.getName() << "Attr *";
2862
if (!Header)
2863
OS << R.getName() << "Attr::";
2864
OS << "Create";
2865
if (Implicit)
2866
OS << "Implicit";
2867
if (DelayedArgsOnly)
2868
OS << "WithDelayedArgs";
2869
OS << "(";
2870
OS << "ASTContext &Ctx";
2871
if (!DelayedArgsOnly) {
2872
for (auto const &ai : Args) {
2873
if (ai->isFake() && !emitFake)
2874
continue;
2875
OS << ", ";
2876
ai->writeCtorParameters(OS);
2877
}
2878
} else {
2879
OS << ", ";
2880
DelayedArgs->writeCtorParameters(OS);
2881
}
2882
OS << ", SourceRange Range";
2883
if (Header)
2884
OS << " = {}";
2885
if (Spellings.size() > 1) {
2886
OS << ", Spelling S";
2887
if (Header)
2888
OS << " = " << SemanticToSyntacticMap[0];
2889
}
2890
OS << ")";
2891
if (Header) {
2892
OS << ";\n";
2893
return;
2894
}
2895
2896
OS << " {\n";
2897
OS << " AttributeCommonInfo I(Range, ";
2898
2899
if (ParsedAttrSpellingItr != std::end(AttrMap))
2900
OS << "AT_" << ParsedAttrSpellingItr->first;
2901
else
2902
OS << "NoSemaHandlerAttribute";
2903
2904
if (Spellings.size() == 0) {
2905
OS << ", AttributeCommonInfo::Form::Implicit()";
2906
} else if (Spellings.size() == 1) {
2907
OS << ", ";
2908
emitFormInitializer(OS, Spellings[0], "0");
2909
} else {
2910
OS << ", [&]() {\n";
2911
OS << " switch (S) {\n";
2912
std::set<std::string> Uniques;
2913
unsigned Idx = 0;
2914
for (auto I = Spellings.begin(), E = Spellings.end(); I != E;
2915
++I, ++Idx) {
2916
const FlattenedSpelling &S = *I;
2917
const auto &Name = SemanticToSyntacticMap[Idx];
2918
if (Uniques.insert(Name).second) {
2919
OS << " case " << Name << ":\n";
2920
OS << " return AttributeCommonInfo::Form";
2921
emitFormInitializer(OS, S, Name);
2922
OS << ";\n";
2923
}
2924
}
2925
OS << " default:\n";
2926
OS << " llvm_unreachable(\"Unknown attribute spelling!\");\n"
2927
<< " return AttributeCommonInfo::Form";
2928
emitFormInitializer(OS, Spellings[0], "0");
2929
OS << ";\n"
2930
<< " }\n"
2931
<< " }()";
2932
}
2933
2934
OS << ");\n";
2935
OS << " return Create";
2936
if (Implicit)
2937
OS << "Implicit";
2938
if (DelayedArgsOnly)
2939
OS << "WithDelayedArgs";
2940
OS << "(Ctx";
2941
if (!DelayedArgsOnly) {
2942
for (auto const &ai : Args) {
2943
if (ai->isFake() && !emitFake)
2944
continue;
2945
OS << ", ";
2946
ai->writeImplicitCtorArgs(OS);
2947
}
2948
} else {
2949
OS << ", ";
2950
DelayedArgs->writeImplicitCtorArgs(OS);
2951
}
2952
OS << ", I);\n";
2953
OS << "}\n\n";
2954
};
2955
2956
auto emitCreates = [&](bool DelayedArgsOnly, bool emitFake) {
2957
emitCreate(true, DelayedArgsOnly, emitFake);
2958
emitCreate(false, DelayedArgsOnly, emitFake);
2959
emitCreateNoCI(true, DelayedArgsOnly, emitFake);
2960
emitCreateNoCI(false, DelayedArgsOnly, emitFake);
2961
};
2962
2963
if (Header)
2964
OS << " // Factory methods\n";
2965
2966
// Emit a CreateImplicit that takes all the arguments.
2967
emitCreates(false, true);
2968
2969
// Emit a CreateImplicit that takes all the non-fake arguments.
2970
if (HasFakeArg)
2971
emitCreates(false, false);
2972
2973
// Emit a CreateWithDelayedArgs that takes only the dependent argument
2974
// expressions.
2975
if (DelayedArgs)
2976
emitCreates(true, false);
2977
2978
// Emit constructors.
2979
auto emitCtor = [&](bool emitOpt, bool emitFake, bool emitNoArgs) {
2980
auto shouldEmitArg = [=](const std::unique_ptr<Argument> &arg) {
2981
if (emitNoArgs)
2982
return false;
2983
if (arg->isFake())
2984
return emitFake;
2985
if (arg->isOptional())
2986
return emitOpt;
2987
return true;
2988
};
2989
if (Header)
2990
OS << " ";
2991
else
2992
OS << R.getName() << "Attr::";
2993
OS << R.getName()
2994
<< "Attr(ASTContext &Ctx, const AttributeCommonInfo &CommonInfo";
2995
OS << '\n';
2996
for (auto const &ai : Args) {
2997
if (!shouldEmitArg(ai))
2998
continue;
2999
OS << " , ";
3000
ai->writeCtorParameters(OS);
3001
OS << "\n";
3002
}
3003
3004
OS << " )";
3005
if (Header) {
3006
OS << ";\n";
3007
return;
3008
}
3009
OS << "\n : " << SuperName << "(Ctx, CommonInfo, ";
3010
OS << "attr::" << R.getName() << ", ";
3011
3012
// Handle different late parsing modes.
3013
OS << "/*IsLateParsed=*/";
3014
switch (getLateAttrParseKind(&R)) {
3015
case LateAttrParseKind::Never:
3016
OS << "false";
3017
break;
3018
case LateAttrParseKind::ExperimentalExt:
3019
// Currently no clients need to know the distinction between `Standard`
3020
// and `ExperimentalExt` so treat `ExperimentalExt` just like
3021
// `Standard` for now.
3022
case LateAttrParseKind::Standard:
3023
// Note: This is misleading. `IsLateParsed` doesn't mean the
3024
// attribute was actually late parsed. Instead it means the attribute in
3025
// `Attr.td` is marked as being late parsed. Maybe it should be called
3026
// `IsLateParseable`?
3027
OS << "true";
3028
break;
3029
}
3030
3031
if (Inheritable) {
3032
OS << ", "
3033
<< (R.getValueAsBit("InheritEvenIfAlreadyPresent") ? "true"
3034
: "false");
3035
}
3036
OS << ")\n";
3037
3038
for (auto const &ai : Args) {
3039
OS << " , ";
3040
if (!shouldEmitArg(ai)) {
3041
ai->writeCtorDefaultInitializers(OS);
3042
} else {
3043
ai->writeCtorInitializers(OS);
3044
}
3045
OS << "\n";
3046
}
3047
if (DelayedArgs) {
3048
OS << " , ";
3049
DelayedArgs->writeCtorDefaultInitializers(OS);
3050
OS << "\n";
3051
}
3052
3053
OS << " {\n";
3054
3055
for (auto const &ai : Args) {
3056
if (!shouldEmitArg(ai))
3057
continue;
3058
ai->writeCtorBody(OS);
3059
}
3060
OS << "}\n\n";
3061
};
3062
3063
if (Header)
3064
OS << "\n // Constructors\n";
3065
3066
// Emit a constructor that includes all the arguments.
3067
// This is necessary for cloning.
3068
emitCtor(true, true, false);
3069
3070
// Emit a constructor that takes all the non-fake arguments.
3071
if (HasFakeArg)
3072
emitCtor(true, false, false);
3073
3074
// Emit a constructor that takes all the non-fake, non-optional arguments.
3075
if (HasOptArg)
3076
emitCtor(false, false, false);
3077
3078
// Emit constructors that takes no arguments if none already exists.
3079
// This is used for delaying arguments.
3080
bool HasRequiredArgs =
3081
llvm::count_if(Args, [=](const std::unique_ptr<Argument> &arg) {
3082
return !arg->isFake() && !arg->isOptional();
3083
});
3084
if (DelayedArgs && HasRequiredArgs)
3085
emitCtor(false, false, true);
3086
3087
if (Header) {
3088
OS << '\n';
3089
OS << " " << R.getName() << "Attr *clone(ASTContext &C) const;\n";
3090
OS << " void printPretty(raw_ostream &OS,\n"
3091
<< " const PrintingPolicy &Policy) const;\n";
3092
OS << " const char *getSpelling() const;\n";
3093
}
3094
3095
if (!ElideSpelling) {
3096
assert(!SemanticToSyntacticMap.empty() && "Empty semantic mapping list");
3097
if (Header)
3098
OS << " Spelling getSemanticSpelling() const;\n";
3099
else {
3100
OS << R.getName() << "Attr::Spelling " << R.getName()
3101
<< "Attr::getSemanticSpelling() const {\n";
3102
WriteSemanticSpellingSwitch("getAttributeSpellingListIndex()",
3103
SemanticToSyntacticMap, OS);
3104
OS << "}\n";
3105
}
3106
}
3107
3108
if (Header)
3109
writeAttrAccessorDefinition(R, OS);
3110
3111
for (auto const &ai : Args) {
3112
if (Header) {
3113
ai->writeAccessors(OS);
3114
} else {
3115
ai->writeAccessorDefinitions(OS);
3116
}
3117
OS << "\n\n";
3118
3119
// Don't write conversion routines for fake arguments.
3120
if (ai->isFake()) continue;
3121
3122
if (ai->isEnumArg())
3123
static_cast<const EnumArgument *>(ai.get())->writeConversion(OS,
3124
Header);
3125
else if (ai->isVariadicEnumArg())
3126
static_cast<const VariadicEnumArgument *>(ai.get())->writeConversion(
3127
OS, Header);
3128
}
3129
3130
if (Header) {
3131
if (DelayedArgs) {
3132
DelayedArgs->writeAccessors(OS);
3133
DelayedArgs->writeSetter(OS);
3134
}
3135
3136
OS << R.getValueAsString("AdditionalMembers");
3137
OS << "\n\n";
3138
3139
OS << " static bool classof(const Attr *A) { return A->getKind() == "
3140
<< "attr::" << R.getName() << "; }\n";
3141
3142
OS << "};\n\n";
3143
} else {
3144
if (DelayedArgs)
3145
DelayedArgs->writeAccessorDefinitions(OS);
3146
3147
OS << R.getName() << "Attr *" << R.getName()
3148
<< "Attr::clone(ASTContext &C) const {\n";
3149
OS << " auto *A = new (C) " << R.getName() << "Attr(C, *this";
3150
for (auto const &ai : Args) {
3151
OS << ", ";
3152
ai->writeCloneArgs(OS);
3153
}
3154
OS << ");\n";
3155
OS << " A->Inherited = Inherited;\n";
3156
OS << " A->IsPackExpansion = IsPackExpansion;\n";
3157
OS << " A->setImplicit(Implicit);\n";
3158
if (DelayedArgs) {
3159
OS << " A->setDelayedArgs(C, ";
3160
DelayedArgs->writeCloneArgs(OS);
3161
OS << ");\n";
3162
}
3163
OS << " return A;\n}\n\n";
3164
3165
writePrettyPrintFunction(R, Args, OS);
3166
writeGetSpellingFunction(R, OS);
3167
}
3168
}
3169
}
3170
// Emits the class definitions for attributes.
3171
void clang::EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
3172
emitSourceFileHeader("Attribute classes' definitions", OS, Records);
3173
3174
OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
3175
OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n";
3176
3177
emitAttributes(Records, OS, true);
3178
3179
OS << "#endif // LLVM_CLANG_ATTR_CLASSES_INC\n";
3180
}
3181
3182
// Emits the class method definitions for attributes.
3183
void clang::EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
3184
emitSourceFileHeader("Attribute classes' member function definitions", OS,
3185
Records);
3186
3187
emitAttributes(Records, OS, false);
3188
3189
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
3190
3191
// Instead of relying on virtual dispatch we just create a huge dispatch
3192
// switch. This is both smaller and faster than virtual functions.
3193
auto EmitFunc = [&](const char *Method) {
3194
OS << " switch (getKind()) {\n";
3195
for (const auto *Attr : Attrs) {
3196
const Record &R = *Attr;
3197
if (!R.getValueAsBit("ASTNode"))
3198
continue;
3199
3200
OS << " case attr::" << R.getName() << ":\n";
3201
OS << " return cast<" << R.getName() << "Attr>(this)->" << Method
3202
<< ";\n";
3203
}
3204
OS << " }\n";
3205
OS << " llvm_unreachable(\"Unexpected attribute kind!\");\n";
3206
OS << "}\n\n";
3207
};
3208
3209
OS << "const char *Attr::getSpelling() const {\n";
3210
EmitFunc("getSpelling()");
3211
3212
OS << "Attr *Attr::clone(ASTContext &C) const {\n";
3213
EmitFunc("clone(C)");
3214
3215
OS << "void Attr::printPretty(raw_ostream &OS, "
3216
"const PrintingPolicy &Policy) const {\n";
3217
EmitFunc("printPretty(OS, Policy)");
3218
}
3219
3220
static void emitAttrList(raw_ostream &OS, StringRef Class,
3221
const std::vector<Record*> &AttrList) {
3222
for (auto Cur : AttrList) {
3223
OS << Class << "(" << Cur->getName() << ")\n";
3224
}
3225
}
3226
3227
// Determines if an attribute has a Pragma spelling.
3228
static bool AttrHasPragmaSpelling(const Record *R) {
3229
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*R);
3230
return llvm::any_of(Spellings, [](const FlattenedSpelling &S) {
3231
return S.variety() == "Pragma";
3232
});
3233
}
3234
3235
namespace {
3236
3237
struct AttrClassDescriptor {
3238
const char * const MacroName;
3239
const char * const TableGenName;
3240
};
3241
3242
} // end anonymous namespace
3243
3244
static const AttrClassDescriptor AttrClassDescriptors[] = {
3245
{ "ATTR", "Attr" },
3246
{ "TYPE_ATTR", "TypeAttr" },
3247
{ "STMT_ATTR", "StmtAttr" },
3248
{ "DECL_OR_STMT_ATTR", "DeclOrStmtAttr" },
3249
{ "INHERITABLE_ATTR", "InheritableAttr" },
3250
{ "DECL_OR_TYPE_ATTR", "DeclOrTypeAttr" },
3251
{ "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" },
3252
{ "PARAMETER_ABI_ATTR", "ParameterABIAttr" },
3253
{ "HLSL_ANNOTATION_ATTR", "HLSLAnnotationAttr"}
3254
};
3255
3256
static void emitDefaultDefine(raw_ostream &OS, StringRef name,
3257
const char *superName) {
3258
OS << "#ifndef " << name << "\n";
3259
OS << "#define " << name << "(NAME) ";
3260
if (superName) OS << superName << "(NAME)";
3261
OS << "\n#endif\n\n";
3262
}
3263
3264
namespace {
3265
3266
/// A class of attributes.
3267
struct AttrClass {
3268
const AttrClassDescriptor &Descriptor;
3269
Record *TheRecord;
3270
AttrClass *SuperClass = nullptr;
3271
std::vector<AttrClass*> SubClasses;
3272
std::vector<Record*> Attrs;
3273
3274
AttrClass(const AttrClassDescriptor &Descriptor, Record *R)
3275
: Descriptor(Descriptor), TheRecord(R) {}
3276
3277
void emitDefaultDefines(raw_ostream &OS) const {
3278
// Default the macro unless this is a root class (i.e. Attr).
3279
if (SuperClass) {
3280
emitDefaultDefine(OS, Descriptor.MacroName,
3281
SuperClass->Descriptor.MacroName);
3282
}
3283
}
3284
3285
void emitUndefs(raw_ostream &OS) const {
3286
OS << "#undef " << Descriptor.MacroName << "\n";
3287
}
3288
3289
void emitAttrList(raw_ostream &OS) const {
3290
for (auto SubClass : SubClasses) {
3291
SubClass->emitAttrList(OS);
3292
}
3293
3294
::emitAttrList(OS, Descriptor.MacroName, Attrs);
3295
}
3296
3297
void classifyAttrOnRoot(Record *Attr) {
3298
bool result = classifyAttr(Attr);
3299
assert(result && "failed to classify on root"); (void) result;
3300
}
3301
3302
void emitAttrRange(raw_ostream &OS) const {
3303
OS << "ATTR_RANGE(" << Descriptor.TableGenName
3304
<< ", " << getFirstAttr()->getName()
3305
<< ", " << getLastAttr()->getName() << ")\n";
3306
}
3307
3308
private:
3309
bool classifyAttr(Record *Attr) {
3310
// Check all the subclasses.
3311
for (auto SubClass : SubClasses) {
3312
if (SubClass->classifyAttr(Attr))
3313
return true;
3314
}
3315
3316
// It's not more specific than this class, but it might still belong here.
3317
if (Attr->isSubClassOf(TheRecord)) {
3318
Attrs.push_back(Attr);
3319
return true;
3320
}
3321
3322
return false;
3323
}
3324
3325
Record *getFirstAttr() const {
3326
if (!SubClasses.empty())
3327
return SubClasses.front()->getFirstAttr();
3328
return Attrs.front();
3329
}
3330
3331
Record *getLastAttr() const {
3332
if (!Attrs.empty())
3333
return Attrs.back();
3334
return SubClasses.back()->getLastAttr();
3335
}
3336
};
3337
3338
/// The entire hierarchy of attribute classes.
3339
class AttrClassHierarchy {
3340
std::vector<std::unique_ptr<AttrClass>> Classes;
3341
3342
public:
3343
AttrClassHierarchy(RecordKeeper &Records) {
3344
// Find records for all the classes.
3345
for (auto &Descriptor : AttrClassDescriptors) {
3346
Record *ClassRecord = Records.getClass(Descriptor.TableGenName);
3347
AttrClass *Class = new AttrClass(Descriptor, ClassRecord);
3348
Classes.emplace_back(Class);
3349
}
3350
3351
// Link up the hierarchy.
3352
for (auto &Class : Classes) {
3353
if (AttrClass *SuperClass = findSuperClass(Class->TheRecord)) {
3354
Class->SuperClass = SuperClass;
3355
SuperClass->SubClasses.push_back(Class.get());
3356
}
3357
}
3358
3359
#ifndef NDEBUG
3360
for (auto i = Classes.begin(), e = Classes.end(); i != e; ++i) {
3361
assert((i == Classes.begin()) == ((*i)->SuperClass == nullptr) &&
3362
"only the first class should be a root class!");
3363
}
3364
#endif
3365
}
3366
3367
void emitDefaultDefines(raw_ostream &OS) const {
3368
for (auto &Class : Classes) {
3369
Class->emitDefaultDefines(OS);
3370
}
3371
}
3372
3373
void emitUndefs(raw_ostream &OS) const {
3374
for (auto &Class : Classes) {
3375
Class->emitUndefs(OS);
3376
}
3377
}
3378
3379
void emitAttrLists(raw_ostream &OS) const {
3380
// Just start from the root class.
3381
Classes[0]->emitAttrList(OS);
3382
}
3383
3384
void emitAttrRanges(raw_ostream &OS) const {
3385
for (auto &Class : Classes)
3386
Class->emitAttrRange(OS);
3387
}
3388
3389
void classifyAttr(Record *Attr) {
3390
// Add the attribute to the root class.
3391
Classes[0]->classifyAttrOnRoot(Attr);
3392
}
3393
3394
private:
3395
AttrClass *findClassByRecord(Record *R) const {
3396
for (auto &Class : Classes) {
3397
if (Class->TheRecord == R)
3398
return Class.get();
3399
}
3400
return nullptr;
3401
}
3402
3403
AttrClass *findSuperClass(Record *R) const {
3404
// TableGen flattens the superclass list, so we just need to walk it
3405
// in reverse.
3406
auto SuperClasses = R->getSuperClasses();
3407
for (signed i = 0, e = SuperClasses.size(); i != e; ++i) {
3408
auto SuperClass = findClassByRecord(SuperClasses[e - i - 1].first);
3409
if (SuperClass) return SuperClass;
3410
}
3411
return nullptr;
3412
}
3413
};
3414
3415
} // end anonymous namespace
3416
3417
namespace clang {
3418
3419
// Emits the enumeration list for attributes.
3420
void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
3421
emitSourceFileHeader("List of all attributes that Clang recognizes", OS,
3422
Records);
3423
3424
AttrClassHierarchy Hierarchy(Records);
3425
3426
// Add defaulting macro definitions.
3427
Hierarchy.emitDefaultDefines(OS);
3428
emitDefaultDefine(OS, "PRAGMA_SPELLING_ATTR", nullptr);
3429
3430
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
3431
std::vector<Record *> PragmaAttrs;
3432
for (auto *Attr : Attrs) {
3433
if (!Attr->getValueAsBit("ASTNode"))
3434
continue;
3435
3436
// Add the attribute to the ad-hoc groups.
3437
if (AttrHasPragmaSpelling(Attr))
3438
PragmaAttrs.push_back(Attr);
3439
3440
// Place it in the hierarchy.
3441
Hierarchy.classifyAttr(Attr);
3442
}
3443
3444
// Emit the main attribute list.
3445
Hierarchy.emitAttrLists(OS);
3446
3447
// Emit the ad hoc groups.
3448
emitAttrList(OS, "PRAGMA_SPELLING_ATTR", PragmaAttrs);
3449
3450
// Emit the attribute ranges.
3451
OS << "#ifdef ATTR_RANGE\n";
3452
Hierarchy.emitAttrRanges(OS);
3453
OS << "#undef ATTR_RANGE\n";
3454
OS << "#endif\n";
3455
3456
Hierarchy.emitUndefs(OS);
3457
OS << "#undef PRAGMA_SPELLING_ATTR\n";
3458
}
3459
3460
// Emits the enumeration list for attributes.
3461
void EmitClangAttrSubjectMatchRuleList(RecordKeeper &Records, raw_ostream &OS) {
3462
emitSourceFileHeader(
3463
"List of all attribute subject matching rules that Clang recognizes", OS,
3464
Records);
3465
PragmaClangAttributeSupport &PragmaAttributeSupport =
3466
getPragmaAttributeSupport(Records);
3467
emitDefaultDefine(OS, "ATTR_MATCH_RULE", nullptr);
3468
PragmaAttributeSupport.emitMatchRuleList(OS);
3469
OS << "#undef ATTR_MATCH_RULE\n";
3470
}
3471
3472
// Emits the code to read an attribute from a precompiled header.
3473
void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
3474
emitSourceFileHeader("Attribute deserialization code", OS, Records);
3475
3476
Record *InhClass = Records.getClass("InheritableAttr");
3477
std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
3478
ArgRecords;
3479
std::vector<std::unique_ptr<Argument>> Args;
3480
std::unique_ptr<VariadicExprArgument> DelayedArgs;
3481
3482
OS << " switch (Kind) {\n";
3483
for (const auto *Attr : Attrs) {
3484
const Record &R = *Attr;
3485
if (!R.getValueAsBit("ASTNode"))
3486
continue;
3487
3488
OS << " case attr::" << R.getName() << ": {\n";
3489
if (R.isSubClassOf(InhClass))
3490
OS << " bool isInherited = Record.readInt();\n";
3491
OS << " bool isImplicit = Record.readInt();\n";
3492
OS << " bool isPackExpansion = Record.readInt();\n";
3493
DelayedArgs = nullptr;
3494
if (Attr->getValueAsBit("AcceptsExprPack")) {
3495
DelayedArgs =
3496
std::make_unique<VariadicExprArgument>("DelayedArgs", R.getName());
3497
DelayedArgs->writePCHReadDecls(OS);
3498
}
3499
ArgRecords = R.getValueAsListOfDefs("Args");
3500
Args.clear();
3501
for (const auto *Arg : ArgRecords) {
3502
Args.emplace_back(createArgument(*Arg, R.getName()));
3503
Args.back()->writePCHReadDecls(OS);
3504
}
3505
OS << " New = new (Context) " << R.getName() << "Attr(Context, Info";
3506
for (auto const &ri : Args) {
3507
OS << ", ";
3508
ri->writePCHReadArgs(OS);
3509
}
3510
OS << ");\n";
3511
if (R.isSubClassOf(InhClass))
3512
OS << " cast<InheritableAttr>(New)->setInherited(isInherited);\n";
3513
OS << " New->setImplicit(isImplicit);\n";
3514
OS << " New->setPackExpansion(isPackExpansion);\n";
3515
if (DelayedArgs) {
3516
OS << " cast<" << R.getName()
3517
<< "Attr>(New)->setDelayedArgs(Context, ";
3518
DelayedArgs->writePCHReadArgs(OS);
3519
OS << ");\n";
3520
}
3521
OS << " break;\n";
3522
OS << " }\n";
3523
}
3524
OS << " }\n";
3525
}
3526
3527
// Emits the code to write an attribute to a precompiled header.
3528
void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
3529
emitSourceFileHeader("Attribute serialization code", OS, Records);
3530
3531
Record *InhClass = Records.getClass("InheritableAttr");
3532
std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
3533
3534
OS << " switch (A->getKind()) {\n";
3535
for (const auto *Attr : Attrs) {
3536
const Record &R = *Attr;
3537
if (!R.getValueAsBit("ASTNode"))
3538
continue;
3539
OS << " case attr::" << R.getName() << ": {\n";
3540
Args = R.getValueAsListOfDefs("Args");
3541
if (R.isSubClassOf(InhClass) || !Args.empty())
3542
OS << " const auto *SA = cast<" << R.getName()
3543
<< "Attr>(A);\n";
3544
if (R.isSubClassOf(InhClass))
3545
OS << " Record.push_back(SA->isInherited());\n";
3546
OS << " Record.push_back(A->isImplicit());\n";
3547
OS << " Record.push_back(A->isPackExpansion());\n";
3548
if (Attr->getValueAsBit("AcceptsExprPack"))
3549
VariadicExprArgument("DelayedArgs", R.getName()).writePCHWrite(OS);
3550
3551
for (const auto *Arg : Args)
3552
createArgument(*Arg, R.getName())->writePCHWrite(OS);
3553
OS << " break;\n";
3554
OS << " }\n";
3555
}
3556
OS << " }\n";
3557
}
3558
3559
} // namespace clang
3560
3561
// Helper function for GenerateTargetSpecificAttrChecks that alters the 'Test'
3562
// parameter with only a single check type, if applicable.
3563
static bool GenerateTargetSpecificAttrCheck(const Record *R, std::string &Test,
3564
std::string *FnName,
3565
StringRef ListName,
3566
StringRef CheckAgainst,
3567
StringRef Scope) {
3568
if (!R->isValueUnset(ListName)) {
3569
Test += " && (";
3570
std::vector<StringRef> Items = R->getValueAsListOfStrings(ListName);
3571
for (auto I = Items.begin(), E = Items.end(); I != E; ++I) {
3572
StringRef Part = *I;
3573
Test += CheckAgainst;
3574
Test += " == ";
3575
Test += Scope;
3576
Test += Part;
3577
if (I + 1 != E)
3578
Test += " || ";
3579
if (FnName)
3580
*FnName += Part;
3581
}
3582
Test += ")";
3583
return true;
3584
}
3585
return false;
3586
}
3587
3588
// Generate a conditional expression to check if the current target satisfies
3589
// the conditions for a TargetSpecificAttr record, and append the code for
3590
// those checks to the Test string. If the FnName string pointer is non-null,
3591
// append a unique suffix to distinguish this set of target checks from other
3592
// TargetSpecificAttr records.
3593
static bool GenerateTargetSpecificAttrChecks(const Record *R,
3594
std::vector<StringRef> &Arches,
3595
std::string &Test,
3596
std::string *FnName) {
3597
bool AnyTargetChecks = false;
3598
3599
// It is assumed that there will be an llvm::Triple object
3600
// named "T" and a TargetInfo object named "Target" within
3601
// scope that can be used to determine whether the attribute exists in
3602
// a given target.
3603
Test += "true";
3604
// If one or more architectures is specified, check those. Arches are handled
3605
// differently because GenerateTargetRequirements needs to combine the list
3606
// with ParseKind.
3607
if (!Arches.empty()) {
3608
AnyTargetChecks = true;
3609
Test += " && (";
3610
for (auto I = Arches.begin(), E = Arches.end(); I != E; ++I) {
3611
StringRef Part = *I;
3612
Test += "T.getArch() == llvm::Triple::";
3613
Test += Part;
3614
if (I + 1 != E)
3615
Test += " || ";
3616
if (FnName)
3617
*FnName += Part;
3618
}
3619
Test += ")";
3620
}
3621
3622
// If the attribute is specific to particular OSes, check those.
3623
AnyTargetChecks |= GenerateTargetSpecificAttrCheck(
3624
R, Test, FnName, "OSes", "T.getOS()", "llvm::Triple::");
3625
3626
// If one or more object formats is specified, check those.
3627
AnyTargetChecks |=
3628
GenerateTargetSpecificAttrCheck(R, Test, FnName, "ObjectFormats",
3629
"T.getObjectFormat()", "llvm::Triple::");
3630
3631
// If custom code is specified, emit it.
3632
StringRef Code = R->getValueAsString("CustomCode");
3633
if (!Code.empty()) {
3634
AnyTargetChecks = true;
3635
Test += " && (";
3636
Test += Code;
3637
Test += ")";
3638
}
3639
3640
return AnyTargetChecks;
3641
}
3642
3643
static void GenerateHasAttrSpellingStringSwitch(
3644
const std::vector<std::pair<const Record *, FlattenedSpelling>> &Attrs,
3645
raw_ostream &OS, const std::string &Variety,
3646
const std::string &Scope = "") {
3647
for (const auto &[Attr, Spelling] : Attrs) {
3648
// C++11-style attributes have specific version information associated with
3649
// them. If the attribute has no scope, the version information must not
3650
// have the default value (1), as that's incorrect. Instead, the unscoped
3651
// attribute version information should be taken from the SD-6 standing
3652
// document, which can be found at:
3653
// https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
3654
//
3655
// C23-style attributes have the same kind of version information
3656
// associated with them. The unscoped attribute version information should
3657
// be taken from the specification of the attribute in the C Standard.
3658
//
3659
// Clang-specific attributes have the same kind of version information
3660
// associated with them. This version is typically the default value (1).
3661
// These version values are clang-specific and should typically be
3662
// incremented once the attribute changes its syntax and/or semantics in a
3663
// a way that is impactful to the end user.
3664
int Version = 1;
3665
3666
assert(Spelling.variety() == Variety);
3667
std::string Name = "";
3668
if (Spelling.nameSpace().empty() || Scope == Spelling.nameSpace()) {
3669
Name = Spelling.name();
3670
Version = static_cast<int>(
3671
Spelling.getSpellingRecord().getValueAsInt("Version"));
3672
// Verify that explicitly specified CXX11 and C23 spellings (i.e.
3673
// not inferred from Clang/GCC spellings) have a version that's
3674
// different from the default (1).
3675
bool RequiresValidVersion =
3676
(Variety == "CXX11" || Variety == "C23") &&
3677
Spelling.getSpellingRecord().getValueAsString("Variety") == Variety;
3678
if (RequiresValidVersion && Scope.empty() && Version == 1)
3679
PrintError(Spelling.getSpellingRecord().getLoc(),
3680
"Standard attributes must have "
3681
"valid version information.");
3682
}
3683
3684
std::string Test;
3685
if (Attr->isSubClassOf("TargetSpecificAttr")) {
3686
const Record *R = Attr->getValueAsDef("Target");
3687
std::vector<StringRef> Arches = R->getValueAsListOfStrings("Arches");
3688
GenerateTargetSpecificAttrChecks(R, Arches, Test, nullptr);
3689
} else if (!Attr->getValueAsListOfDefs("TargetSpecificSpellings").empty()) {
3690
// Add target checks if this spelling is target-specific.
3691
const std::vector<Record *> TargetSpellings =
3692
Attr->getValueAsListOfDefs("TargetSpecificSpellings");
3693
for (const auto &TargetSpelling : TargetSpellings) {
3694
// Find spelling that matches current scope and name.
3695
for (const auto &Spelling : GetFlattenedSpellings(*TargetSpelling)) {
3696
if (Scope == Spelling.nameSpace() && Name == Spelling.name()) {
3697
const Record *Target = TargetSpelling->getValueAsDef("Target");
3698
std::vector<StringRef> Arches =
3699
Target->getValueAsListOfStrings("Arches");
3700
GenerateTargetSpecificAttrChecks(Target, Arches, Test,
3701
/*FnName=*/nullptr);
3702
break;
3703
}
3704
}
3705
}
3706
}
3707
3708
std::string TestStr = !Test.empty()
3709
? Test + " ? " + llvm::itostr(Version) + " : 0"
3710
: llvm::itostr(Version);
3711
if (Scope.empty() || Scope == Spelling.nameSpace())
3712
OS << " .Case(\"" << Spelling.name() << "\", " << TestStr << ")\n";
3713
}
3714
OS << " .Default(0);\n";
3715
}
3716
3717
namespace clang {
3718
3719
// Emits list of regular keyword attributes with info about their arguments.
3720
void EmitClangRegularKeywordAttributeInfo(RecordKeeper &Records,
3721
raw_ostream &OS) {
3722
emitSourceFileHeader(
3723
"A list of regular keyword attributes generated from the attribute"
3724
" definitions",
3725
OS);
3726
// Assume for now that the same token is not used in multiple regular
3727
// keyword attributes.
3728
for (auto *R : Records.getAllDerivedDefinitions("Attr"))
3729
for (const auto &S : GetFlattenedSpellings(*R)) {
3730
if (!isRegularKeywordAttribute(S))
3731
continue;
3732
std::vector<Record *> Args = R->getValueAsListOfDefs("Args");
3733
bool HasArgs = llvm::any_of(
3734
Args, [](const Record *Arg) { return !Arg->getValueAsBit("Fake"); });
3735
3736
OS << "KEYWORD_ATTRIBUTE("
3737
<< S.getSpellingRecord().getValueAsString("Name") << ", "
3738
<< (HasArgs ? "true" : "false") << ", )\n";
3739
}
3740
OS << "#undef KEYWORD_ATTRIBUTE\n";
3741
}
3742
3743
// Emits the list of spellings for attributes.
3744
void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
3745
emitSourceFileHeader("Code to implement the __has_attribute logic", OS,
3746
Records);
3747
3748
// Separate all of the attributes out into four group: generic, C++11, GNU,
3749
// and declspecs. Then generate a big switch statement for each of them.
3750
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
3751
std::vector<std::pair<const Record *, FlattenedSpelling>> Declspec, Microsoft,
3752
GNU, Pragma, HLSLAnnotation;
3753
std::map<std::string,
3754
std::vector<std::pair<const Record *, FlattenedSpelling>>>
3755
CXX, C23;
3756
3757
// Walk over the list of all attributes, and split them out based on the
3758
// spelling variety.
3759
for (auto *R : Attrs) {
3760
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*R);
3761
for (const auto &SI : Spellings) {
3762
const std::string &Variety = SI.variety();
3763
if (Variety == "GNU")
3764
GNU.emplace_back(R, SI);
3765
else if (Variety == "Declspec")
3766
Declspec.emplace_back(R, SI);
3767
else if (Variety == "Microsoft")
3768
Microsoft.emplace_back(R, SI);
3769
else if (Variety == "CXX11")
3770
CXX[SI.nameSpace()].emplace_back(R, SI);
3771
else if (Variety == "C23")
3772
C23[SI.nameSpace()].emplace_back(R, SI);
3773
else if (Variety == "Pragma")
3774
Pragma.emplace_back(R, SI);
3775
else if (Variety == "HLSLAnnotation")
3776
HLSLAnnotation.emplace_back(R, SI);
3777
}
3778
}
3779
3780
OS << "const llvm::Triple &T = Target.getTriple();\n";
3781
OS << "switch (Syntax) {\n";
3782
OS << "case AttributeCommonInfo::Syntax::AS_GNU:\n";
3783
OS << " return llvm::StringSwitch<int>(Name)\n";
3784
GenerateHasAttrSpellingStringSwitch(GNU, OS, "GNU");
3785
OS << "case AttributeCommonInfo::Syntax::AS_Declspec:\n";
3786
OS << " return llvm::StringSwitch<int>(Name)\n";
3787
GenerateHasAttrSpellingStringSwitch(Declspec, OS, "Declspec");
3788
OS << "case AttributeCommonInfo::Syntax::AS_Microsoft:\n";
3789
OS << " return llvm::StringSwitch<int>(Name)\n";
3790
GenerateHasAttrSpellingStringSwitch(Microsoft, OS, "Microsoft");
3791
OS << "case AttributeCommonInfo::Syntax::AS_Pragma:\n";
3792
OS << " return llvm::StringSwitch<int>(Name)\n";
3793
GenerateHasAttrSpellingStringSwitch(Pragma, OS, "Pragma");
3794
OS << "case AttributeCommonInfo::Syntax::AS_HLSLAnnotation:\n";
3795
OS << " return llvm::StringSwitch<int>(Name)\n";
3796
GenerateHasAttrSpellingStringSwitch(HLSLAnnotation, OS, "HLSLAnnotation");
3797
auto fn = [&OS](const char *Spelling,
3798
const std::map<
3799
std::string,
3800
std::vector<std::pair<const Record *, FlattenedSpelling>>>
3801
&List) {
3802
OS << "case AttributeCommonInfo::Syntax::AS_" << Spelling << ": {\n";
3803
// C++11-style attributes are further split out based on the Scope.
3804
for (auto I = List.cbegin(), E = List.cend(); I != E; ++I) {
3805
if (I != List.cbegin())
3806
OS << " else ";
3807
if (I->first.empty())
3808
OS << "if (ScopeName == \"\") {\n";
3809
else
3810
OS << "if (ScopeName == \"" << I->first << "\") {\n";
3811
OS << " return llvm::StringSwitch<int>(Name)\n";
3812
GenerateHasAttrSpellingStringSwitch(I->second, OS, Spelling, I->first);
3813
OS << "}";
3814
}
3815
OS << "\n} break;\n";
3816
};
3817
fn("CXX11", CXX);
3818
fn("C23", C23);
3819
OS << "case AttributeCommonInfo::Syntax::AS_Keyword:\n";
3820
OS << "case AttributeCommonInfo::Syntax::AS_ContextSensitiveKeyword:\n";
3821
OS << " llvm_unreachable(\"hasAttribute not supported for keyword\");\n";
3822
OS << " return 0;\n";
3823
OS << "case AttributeCommonInfo::Syntax::AS_Implicit:\n";
3824
OS << " llvm_unreachable (\"hasAttribute not supported for "
3825
"AS_Implicit\");\n";
3826
OS << " return 0;\n";
3827
3828
OS << "}\n";
3829
}
3830
3831
void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) {
3832
emitSourceFileHeader("Code to translate different attribute spellings into "
3833
"internal identifiers",
3834
OS, Records);
3835
3836
OS << " switch (getParsedKind()) {\n";
3837
OS << " case IgnoredAttribute:\n";
3838
OS << " case UnknownAttribute:\n";
3839
OS << " case NoSemaHandlerAttribute:\n";
3840
OS << " llvm_unreachable(\"Ignored/unknown shouldn't get here\");\n";
3841
3842
ParsedAttrMap Attrs = getParsedAttrList(Records);
3843
for (const auto &I : Attrs) {
3844
const Record &R = *I.second;
3845
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
3846
OS << " case AT_" << I.first << ": {\n";
3847
for (unsigned I = 0; I < Spellings.size(); ++ I) {
3848
OS << " if (Name == \"" << Spellings[I].name() << "\" && "
3849
<< "getSyntax() == AttributeCommonInfo::AS_" << Spellings[I].variety()
3850
<< " && Scope == \"" << Spellings[I].nameSpace() << "\")\n"
3851
<< " return " << I << ";\n";
3852
}
3853
3854
OS << " break;\n";
3855
OS << " }\n";
3856
}
3857
3858
OS << " }\n";
3859
OS << " return 0;\n";
3860
}
3861
3862
// Emits code used by RecursiveASTVisitor to visit attributes
3863
void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS) {
3864
emitSourceFileHeader("Used by RecursiveASTVisitor to visit attributes.", OS,
3865
Records);
3866
3867
std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
3868
3869
// Write method declarations for Traverse* methods.
3870
// We emit this here because we only generate methods for attributes that
3871
// are declared as ASTNodes.
3872
OS << "#ifdef ATTR_VISITOR_DECLS_ONLY\n\n";
3873
for (const auto *Attr : Attrs) {
3874
const Record &R = *Attr;
3875
if (!R.getValueAsBit("ASTNode"))
3876
continue;
3877
OS << " bool Traverse"
3878
<< R.getName() << "Attr(" << R.getName() << "Attr *A);\n";
3879
OS << " bool Visit"
3880
<< R.getName() << "Attr(" << R.getName() << "Attr *A) {\n"
3881
<< " return true; \n"
3882
<< " }\n";
3883
}
3884
OS << "\n#else // ATTR_VISITOR_DECLS_ONLY\n\n";
3885
3886
// Write individual Traverse* methods for each attribute class.
3887
for (const auto *Attr : Attrs) {
3888
const Record &R = *Attr;
3889
if (!R.getValueAsBit("ASTNode"))
3890
continue;
3891
3892
OS << "template <typename Derived>\n"
3893
<< "bool VISITORCLASS<Derived>::Traverse"
3894
<< R.getName() << "Attr(" << R.getName() << "Attr *A) {\n"
3895
<< " if (!getDerived().VisitAttr(A))\n"
3896
<< " return false;\n"
3897
<< " if (!getDerived().Visit" << R.getName() << "Attr(A))\n"
3898
<< " return false;\n";
3899
3900
std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
3901
for (const auto *Arg : ArgRecords)
3902
createArgument(*Arg, R.getName())->writeASTVisitorTraversal(OS);
3903
3904
if (Attr->getValueAsBit("AcceptsExprPack"))
3905
VariadicExprArgument("DelayedArgs", R.getName())
3906
.writeASTVisitorTraversal(OS);
3907
3908
OS << " return true;\n";
3909
OS << "}\n\n";
3910
}
3911
3912
// Write generic Traverse routine
3913
OS << "template <typename Derived>\n"
3914
<< "bool VISITORCLASS<Derived>::TraverseAttr(Attr *A) {\n"
3915
<< " if (!A)\n"
3916
<< " return true;\n"
3917
<< "\n"
3918
<< " switch (A->getKind()) {\n";
3919
3920
for (const auto *Attr : Attrs) {
3921
const Record &R = *Attr;
3922
if (!R.getValueAsBit("ASTNode"))
3923
continue;
3924
3925
OS << " case attr::" << R.getName() << ":\n"
3926
<< " return getDerived().Traverse" << R.getName() << "Attr("
3927
<< "cast<" << R.getName() << "Attr>(A));\n";
3928
}
3929
OS << " }\n"; // end switch
3930
OS << " llvm_unreachable(\"bad attribute kind\");\n";
3931
OS << "}\n"; // end function
3932
OS << "#endif // ATTR_VISITOR_DECLS_ONLY\n";
3933
}
3934
3935
void EmitClangAttrTemplateInstantiateHelper(const std::vector<Record *> &Attrs,
3936
raw_ostream &OS,
3937
bool AppliesToDecl) {
3938
3939
OS << " switch (At->getKind()) {\n";
3940
for (const auto *Attr : Attrs) {
3941
const Record &R = *Attr;
3942
if (!R.getValueAsBit("ASTNode"))
3943
continue;
3944
OS << " case attr::" << R.getName() << ": {\n";
3945
bool ShouldClone = R.getValueAsBit("Clone") &&
3946
(!AppliesToDecl ||
3947
R.getValueAsBit("MeaningfulToClassTemplateDefinition"));
3948
3949
if (!ShouldClone) {
3950
OS << " return nullptr;\n";
3951
OS << " }\n";
3952
continue;
3953
}
3954
3955
OS << " const auto *A = cast<"
3956
<< R.getName() << "Attr>(At);\n";
3957
bool TDependent = R.getValueAsBit("TemplateDependent");
3958
3959
if (!TDependent) {
3960
OS << " return A->clone(C);\n";
3961
OS << " }\n";
3962
continue;
3963
}
3964
3965
std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
3966
std::vector<std::unique_ptr<Argument>> Args;
3967
Args.reserve(ArgRecords.size());
3968
3969
for (const auto *ArgRecord : ArgRecords)
3970
Args.emplace_back(createArgument(*ArgRecord, R.getName()));
3971
3972
for (auto const &ai : Args)
3973
ai->writeTemplateInstantiation(OS);
3974
3975
OS << " return new (C) " << R.getName() << "Attr(C, *A";
3976
for (auto const &ai : Args) {
3977
OS << ", ";
3978
ai->writeTemplateInstantiationArgs(OS);
3979
}
3980
OS << ");\n"
3981
<< " }\n";
3982
}
3983
OS << " } // end switch\n"
3984
<< " llvm_unreachable(\"Unknown attribute!\");\n"
3985
<< " return nullptr;\n";
3986
}
3987
3988
// Emits code to instantiate dependent attributes on templates.
3989
void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) {
3990
emitSourceFileHeader("Template instantiation code for attributes", OS,
3991
Records);
3992
3993
std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
3994
3995
OS << "namespace clang {\n"
3996
<< "namespace sema {\n\n"
3997
<< "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
3998
<< "Sema &S,\n"
3999
<< " const MultiLevelTemplateArgumentList &TemplateArgs) {\n";
4000
EmitClangAttrTemplateInstantiateHelper(Attrs, OS, /*AppliesToDecl*/false);
4001
OS << "}\n\n"
4002
<< "Attr *instantiateTemplateAttributeForDecl(const Attr *At,\n"
4003
<< " ASTContext &C, Sema &S,\n"
4004
<< " const MultiLevelTemplateArgumentList &TemplateArgs) {\n";
4005
EmitClangAttrTemplateInstantiateHelper(Attrs, OS, /*AppliesToDecl*/true);
4006
OS << "}\n\n"
4007
<< "} // end namespace sema\n"
4008
<< "} // end namespace clang\n";
4009
}
4010
4011
// Emits the list of parsed attributes.
4012
void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) {
4013
emitSourceFileHeader("List of all attributes that Clang recognizes", OS,
4014
Records);
4015
4016
OS << "#ifndef PARSED_ATTR\n";
4017
OS << "#define PARSED_ATTR(NAME) NAME\n";
4018
OS << "#endif\n\n";
4019
4020
ParsedAttrMap Names = getParsedAttrList(Records);
4021
for (const auto &I : Names) {
4022
OS << "PARSED_ATTR(" << I.first << ")\n";
4023
}
4024
}
4025
4026
static bool isArgVariadic(const Record &R, StringRef AttrName) {
4027
return createArgument(R, AttrName)->isVariadic();
4028
}
4029
4030
static void emitArgInfo(const Record &R, raw_ostream &OS) {
4031
// This function will count the number of arguments specified for the
4032
// attribute and emit the number of required arguments followed by the
4033
// number of optional arguments.
4034
std::vector<Record *> Args = R.getValueAsListOfDefs("Args");
4035
unsigned ArgCount = 0, OptCount = 0, ArgMemberCount = 0;
4036
bool HasVariadic = false;
4037
for (const auto *Arg : Args) {
4038
// If the arg is fake, it's the user's job to supply it: general parsing
4039
// logic shouldn't need to know anything about it.
4040
if (Arg->getValueAsBit("Fake"))
4041
continue;
4042
Arg->getValueAsBit("Optional") ? ++OptCount : ++ArgCount;
4043
++ArgMemberCount;
4044
if (!HasVariadic && isArgVariadic(*Arg, R.getName()))
4045
HasVariadic = true;
4046
}
4047
4048
// If there is a variadic argument, we will set the optional argument count
4049
// to its largest value. Since it's currently a 4-bit number, we set it to 15.
4050
OS << " /*NumArgs=*/" << ArgCount << ",\n";
4051
OS << " /*OptArgs=*/" << (HasVariadic ? 15 : OptCount) << ",\n";
4052
OS << " /*NumArgMembers=*/" << ArgMemberCount << ",\n";
4053
}
4054
4055
static std::string GetDiagnosticSpelling(const Record &R) {
4056
std::string Ret = std::string(R.getValueAsString("DiagSpelling"));
4057
if (!Ret.empty())
4058
return Ret;
4059
4060
// If we couldn't find the DiagSpelling in this object, we can check to see
4061
// if the object is one that has a base, and if it is, loop up to the Base
4062
// member recursively.
4063
if (auto Base = R.getValueAsOptionalDef(BaseFieldName))
4064
return GetDiagnosticSpelling(*Base);
4065
4066
return "";
4067
}
4068
4069
static std::string CalculateDiagnostic(const Record &S) {
4070
// If the SubjectList object has a custom diagnostic associated with it,
4071
// return that directly.
4072
const StringRef CustomDiag = S.getValueAsString("CustomDiag");
4073
if (!CustomDiag.empty())
4074
return ("\"" + Twine(CustomDiag) + "\"").str();
4075
4076
std::vector<std::string> DiagList;
4077
std::vector<Record *> Subjects = S.getValueAsListOfDefs("Subjects");
4078
for (const auto *Subject : Subjects) {
4079
const Record &R = *Subject;
4080
// Get the diagnostic text from the Decl or Stmt node given.
4081
std::string V = GetDiagnosticSpelling(R);
4082
if (V.empty()) {
4083
PrintError(R.getLoc(),
4084
"Could not determine diagnostic spelling for the node: " +
4085
R.getName() + "; please add one to DeclNodes.td");
4086
} else {
4087
// The node may contain a list of elements itself, so split the elements
4088
// by a comma, and trim any whitespace.
4089
SmallVector<StringRef, 2> Frags;
4090
llvm::SplitString(V, Frags, ",");
4091
for (auto Str : Frags) {
4092
DiagList.push_back(std::string(Str.trim()));
4093
}
4094
}
4095
}
4096
4097
if (DiagList.empty()) {
4098
PrintFatalError(S.getLoc(),
4099
"Could not deduce diagnostic argument for Attr subjects");
4100
return "";
4101
}
4102
4103
// FIXME: this is not particularly good for localization purposes and ideally
4104
// should be part of the diagnostics engine itself with some sort of list
4105
// specifier.
4106
4107
// A single member of the list can be returned directly.
4108
if (DiagList.size() == 1)
4109
return '"' + DiagList.front() + '"';
4110
4111
if (DiagList.size() == 2)
4112
return '"' + DiagList[0] + " and " + DiagList[1] + '"';
4113
4114
// If there are more than two in the list, we serialize the first N - 1
4115
// elements with a comma. This leaves the string in the state: foo, bar,
4116
// baz (but misses quux). We can then add ", and " for the last element
4117
// manually.
4118
std::string Diag = llvm::join(DiagList.begin(), DiagList.end() - 1, ", ");
4119
return '"' + Diag + ", and " + *(DiagList.end() - 1) + '"';
4120
}
4121
4122
static std::string GetSubjectWithSuffix(const Record *R) {
4123
const std::string &B = std::string(R->getName());
4124
if (B == "DeclBase")
4125
return "Decl";
4126
return B + "Decl";
4127
}
4128
4129
static std::string functionNameForCustomAppertainsTo(const Record &Subject) {
4130
return "is" + Subject.getName().str();
4131
}
4132
4133
static void GenerateCustomAppertainsTo(const Record &Subject, raw_ostream &OS) {
4134
std::string FnName = functionNameForCustomAppertainsTo(Subject);
4135
4136
// If this code has already been generated, we don't need to do anything.
4137
static std::set<std::string> CustomSubjectSet;
4138
auto I = CustomSubjectSet.find(FnName);
4139
if (I != CustomSubjectSet.end())
4140
return;
4141
4142
// This only works with non-root Decls.
4143
Record *Base = Subject.getValueAsDef(BaseFieldName);
4144
4145
// Not currently support custom subjects within custom subjects.
4146
if (Base->isSubClassOf("SubsetSubject")) {
4147
PrintFatalError(Subject.getLoc(),
4148
"SubsetSubjects within SubsetSubjects is not supported");
4149
return;
4150
}
4151
4152
OS << "static bool " << FnName << "(const Decl *D) {\n";
4153
OS << " if (const auto *S = dyn_cast<";
4154
OS << GetSubjectWithSuffix(Base);
4155
OS << ">(D))\n";
4156
OS << " return " << Subject.getValueAsString("CheckCode") << ";\n";
4157
OS << " return false;\n";
4158
OS << "}\n\n";
4159
4160
CustomSubjectSet.insert(FnName);
4161
}
4162
4163
static void GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) {
4164
// If the attribute does not contain a Subjects definition, then use the
4165
// default appertainsTo logic.
4166
if (Attr.isValueUnset("Subjects"))
4167
return;
4168
4169
const Record *SubjectObj = Attr.getValueAsDef("Subjects");
4170
std::vector<Record *> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
4171
4172
// If the list of subjects is empty, it is assumed that the attribute
4173
// appertains to everything.
4174
if (Subjects.empty())
4175
return;
4176
4177
bool Warn = SubjectObj->getValueAsDef("Diag")->getValueAsBit("Warn");
4178
4179
// Split the subjects into declaration subjects and statement subjects.
4180
// FIXME: subset subjects are added to the declaration list until there are
4181
// enough statement attributes with custom subject needs to warrant
4182
// the implementation effort.
4183
std::vector<Record *> DeclSubjects, StmtSubjects;
4184
llvm::copy_if(
4185
Subjects, std::back_inserter(DeclSubjects), [](const Record *R) {
4186
return R->isSubClassOf("SubsetSubject") || !R->isSubClassOf("StmtNode");
4187
});
4188
llvm::copy_if(Subjects, std::back_inserter(StmtSubjects),
4189
[](const Record *R) { return R->isSubClassOf("StmtNode"); });
4190
4191
// We should have sorted all of the subjects into two lists.
4192
// FIXME: this assertion will be wrong if we ever add type attribute subjects.
4193
assert(DeclSubjects.size() + StmtSubjects.size() == Subjects.size());
4194
4195
if (DeclSubjects.empty()) {
4196
// If there are no decl subjects but there are stmt subjects, diagnose
4197
// trying to apply a statement attribute to a declaration.
4198
if (!StmtSubjects.empty()) {
4199
OS << "bool diagAppertainsToDecl(Sema &S, const ParsedAttr &AL, ";
4200
OS << "const Decl *D) const override {\n";
4201
OS << " S.Diag(AL.getLoc(), diag::err_attribute_invalid_on_decl)\n";
4202
OS << " << AL << AL.isRegularKeywordAttribute() << "
4203
"D->getLocation();\n";
4204
OS << " return false;\n";
4205
OS << "}\n\n";
4206
}
4207
} else {
4208
// Otherwise, generate an appertainsTo check specific to this attribute
4209
// which checks all of the given subjects against the Decl passed in.
4210
OS << "bool diagAppertainsToDecl(Sema &S, ";
4211
OS << "const ParsedAttr &Attr, const Decl *D) const override {\n";
4212
OS << " if (";
4213
for (auto I = DeclSubjects.begin(), E = DeclSubjects.end(); I != E; ++I) {
4214
// If the subject has custom code associated with it, use the generated
4215
// function for it. The function cannot be inlined into this check (yet)
4216
// because it requires the subject to be of a specific type, and were that
4217
// information inlined here, it would not support an attribute with
4218
// multiple custom subjects.
4219
if ((*I)->isSubClassOf("SubsetSubject"))
4220
OS << "!" << functionNameForCustomAppertainsTo(**I) << "(D)";
4221
else
4222
OS << "!isa<" << GetSubjectWithSuffix(*I) << ">(D)";
4223
4224
if (I + 1 != E)
4225
OS << " && ";
4226
}
4227
OS << ") {\n";
4228
OS << " S.Diag(Attr.getLoc(), diag::";
4229
OS << (Warn ? "warn_attribute_wrong_decl_type_str"
4230
: "err_attribute_wrong_decl_type_str");
4231
OS << ")\n";
4232
OS << " << Attr << Attr.isRegularKeywordAttribute() << ";
4233
OS << CalculateDiagnostic(*SubjectObj) << ";\n";
4234
OS << " return false;\n";
4235
OS << " }\n";
4236
OS << " return true;\n";
4237
OS << "}\n\n";
4238
}
4239
4240
if (StmtSubjects.empty()) {
4241
// If there are no stmt subjects but there are decl subjects, diagnose
4242
// trying to apply a declaration attribute to a statement.
4243
if (!DeclSubjects.empty()) {
4244
OS << "bool diagAppertainsToStmt(Sema &S, const ParsedAttr &AL, ";
4245
OS << "const Stmt *St) const override {\n";
4246
OS << " S.Diag(AL.getLoc(), diag::err_decl_attribute_invalid_on_stmt)\n";
4247
OS << " << AL << AL.isRegularKeywordAttribute() << "
4248
"St->getBeginLoc();\n";
4249
OS << " return false;\n";
4250
OS << "}\n\n";
4251
}
4252
} else {
4253
// Now, do the same for statements.
4254
OS << "bool diagAppertainsToStmt(Sema &S, ";
4255
OS << "const ParsedAttr &Attr, const Stmt *St) const override {\n";
4256
OS << " if (";
4257
for (auto I = StmtSubjects.begin(), E = StmtSubjects.end(); I != E; ++I) {
4258
OS << "!isa<" << (*I)->getName() << ">(St)";
4259
if (I + 1 != E)
4260
OS << " && ";
4261
}
4262
OS << ") {\n";
4263
OS << " S.Diag(Attr.getLoc(), diag::";
4264
OS << (Warn ? "warn_attribute_wrong_decl_type_str"
4265
: "err_attribute_wrong_decl_type_str");
4266
OS << ")\n";
4267
OS << " << Attr << Attr.isRegularKeywordAttribute() << ";
4268
OS << CalculateDiagnostic(*SubjectObj) << ";\n";
4269
OS << " return false;\n";
4270
OS << " }\n";
4271
OS << " return true;\n";
4272
OS << "}\n\n";
4273
}
4274
}
4275
4276
// Generates the mutual exclusion checks. The checks for parsed attributes are
4277
// written into OS and the checks for merging declaration attributes are
4278
// written into MergeOS.
4279
static void GenerateMutualExclusionsChecks(const Record &Attr,
4280
const RecordKeeper &Records,
4281
raw_ostream &OS,
4282
raw_ostream &MergeDeclOS,
4283
raw_ostream &MergeStmtOS) {
4284
// Find all of the definitions that inherit from MutualExclusions and include
4285
// the given attribute in the list of exclusions to generate the
4286
// diagMutualExclusion() check.
4287
std::vector<Record *> ExclusionsList =
4288
Records.getAllDerivedDefinitions("MutualExclusions");
4289
4290
// We don't do any of this magic for type attributes yet.
4291
if (Attr.isSubClassOf("TypeAttr"))
4292
return;
4293
4294
// This means the attribute is either a statement attribute, a decl
4295
// attribute, or both; find out which.
4296
bool CurAttrIsStmtAttr =
4297
Attr.isSubClassOf("StmtAttr") || Attr.isSubClassOf("DeclOrStmtAttr");
4298
bool CurAttrIsDeclAttr =
4299
!CurAttrIsStmtAttr || Attr.isSubClassOf("DeclOrStmtAttr");
4300
4301
std::vector<std::string> DeclAttrs, StmtAttrs;
4302
4303
for (const Record *Exclusion : ExclusionsList) {
4304
std::vector<Record *> MutuallyExclusiveAttrs =
4305
Exclusion->getValueAsListOfDefs("Exclusions");
4306
auto IsCurAttr = [Attr](const Record *R) {
4307
return R->getName() == Attr.getName();
4308
};
4309
if (llvm::any_of(MutuallyExclusiveAttrs, IsCurAttr)) {
4310
// This list of exclusions includes the attribute we're looking for, so
4311
// add the exclusive attributes to the proper list for checking.
4312
for (const Record *AttrToExclude : MutuallyExclusiveAttrs) {
4313
if (IsCurAttr(AttrToExclude))
4314
continue;
4315
4316
if (CurAttrIsStmtAttr)
4317
StmtAttrs.push_back((AttrToExclude->getName() + "Attr").str());
4318
if (CurAttrIsDeclAttr)
4319
DeclAttrs.push_back((AttrToExclude->getName() + "Attr").str());
4320
}
4321
}
4322
}
4323
4324
// If there are any decl or stmt attributes, silence -Woverloaded-virtual
4325
// warnings for them both.
4326
if (!DeclAttrs.empty() || !StmtAttrs.empty())
4327
OS << " using ParsedAttrInfo::diagMutualExclusion;\n\n";
4328
4329
// If we discovered any decl or stmt attributes to test for, generate the
4330
// predicates for them now.
4331
if (!DeclAttrs.empty()) {
4332
// Generate the ParsedAttrInfo subclass logic for declarations.
4333
OS << " bool diagMutualExclusion(Sema &S, const ParsedAttr &AL, "
4334
<< "const Decl *D) const override {\n";
4335
for (const std::string &A : DeclAttrs) {
4336
OS << " if (const auto *A = D->getAttr<" << A << ">()) {\n";
4337
OS << " S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)"
4338
<< " << AL << A << (AL.isRegularKeywordAttribute() ||"
4339
<< " A->isRegularKeywordAttribute());\n";
4340
OS << " S.Diag(A->getLocation(), diag::note_conflicting_attribute);";
4341
OS << " \nreturn false;\n";
4342
OS << " }\n";
4343
}
4344
OS << " return true;\n";
4345
OS << " }\n\n";
4346
4347
// Also generate the declaration attribute merging logic if the current
4348
// attribute is one that can be inheritted on a declaration. It is assumed
4349
// this code will be executed in the context of a function with parameters:
4350
// Sema &S, Decl *D, Attr *A and that returns a bool (false on diagnostic,
4351
// true on success).
4352
if (Attr.isSubClassOf("InheritableAttr")) {
4353
MergeDeclOS << " if (const auto *Second = dyn_cast<"
4354
<< (Attr.getName() + "Attr").str() << ">(A)) {\n";
4355
for (const std::string &A : DeclAttrs) {
4356
MergeDeclOS << " if (const auto *First = D->getAttr<" << A
4357
<< ">()) {\n";
4358
MergeDeclOS << " S.Diag(First->getLocation(), "
4359
<< "diag::err_attributes_are_not_compatible) << First << "
4360
<< "Second << (First->isRegularKeywordAttribute() || "
4361
<< "Second->isRegularKeywordAttribute());\n";
4362
MergeDeclOS << " S.Diag(Second->getLocation(), "
4363
<< "diag::note_conflicting_attribute);\n";
4364
MergeDeclOS << " return false;\n";
4365
MergeDeclOS << " }\n";
4366
}
4367
MergeDeclOS << " return true;\n";
4368
MergeDeclOS << " }\n";
4369
}
4370
}
4371
4372
// Statement attributes are a bit different from declarations. With
4373
// declarations, each attribute is added to the declaration as it is
4374
// processed, and so you can look on the Decl * itself to see if there is a
4375
// conflicting attribute. Statement attributes are processed as a group
4376
// because AttributedStmt needs to tail-allocate all of the attribute nodes
4377
// at once. This means we cannot check whether the statement already contains
4378
// an attribute to check for the conflict. Instead, we need to check whether
4379
// the given list of semantic attributes contain any conflicts. It is assumed
4380
// this code will be executed in the context of a function with parameters:
4381
// Sema &S, const SmallVectorImpl<const Attr *> &C. The code will be within a
4382
// loop which loops over the container C with a loop variable named A to
4383
// represent the current attribute to check for conflicts.
4384
//
4385
// FIXME: it would be nice not to walk over the list of potential attributes
4386
// to apply to the statement more than once, but statements typically don't
4387
// have long lists of attributes on them, so re-walking the list should not
4388
// be an expensive operation.
4389
if (!StmtAttrs.empty()) {
4390
MergeStmtOS << " if (const auto *Second = dyn_cast<"
4391
<< (Attr.getName() + "Attr").str() << ">(A)) {\n";
4392
MergeStmtOS << " auto Iter = llvm::find_if(C, [](const Attr *Check) "
4393
<< "{ return isa<";
4394
interleave(
4395
StmtAttrs, [&](const std::string &Name) { MergeStmtOS << Name; },
4396
[&] { MergeStmtOS << ", "; });
4397
MergeStmtOS << ">(Check); });\n";
4398
MergeStmtOS << " if (Iter != C.end()) {\n";
4399
MergeStmtOS << " S.Diag((*Iter)->getLocation(), "
4400
<< "diag::err_attributes_are_not_compatible) << *Iter << "
4401
<< "Second << ((*Iter)->isRegularKeywordAttribute() || "
4402
<< "Second->isRegularKeywordAttribute());\n";
4403
MergeStmtOS << " S.Diag(Second->getLocation(), "
4404
<< "diag::note_conflicting_attribute);\n";
4405
MergeStmtOS << " return false;\n";
4406
MergeStmtOS << " }\n";
4407
MergeStmtOS << " }\n";
4408
}
4409
}
4410
4411
static void
4412
emitAttributeMatchRules(PragmaClangAttributeSupport &PragmaAttributeSupport,
4413
raw_ostream &OS) {
4414
OS << "static bool checkAttributeMatchRuleAppliesTo(const Decl *D, "
4415
<< AttributeSubjectMatchRule::EnumName << " rule) {\n";
4416
OS << " switch (rule) {\n";
4417
for (const auto &Rule : PragmaAttributeSupport.Rules) {
4418
if (Rule.isAbstractRule()) {
4419
OS << " case " << Rule.getEnumValue() << ":\n";
4420
OS << " assert(false && \"Abstract matcher rule isn't allowed\");\n";
4421
OS << " return false;\n";
4422
continue;
4423
}
4424
std::vector<Record *> Subjects = Rule.getSubjects();
4425
assert(!Subjects.empty() && "Missing subjects");
4426
OS << " case " << Rule.getEnumValue() << ":\n";
4427
OS << " return ";
4428
for (auto I = Subjects.begin(), E = Subjects.end(); I != E; ++I) {
4429
// If the subject has custom code associated with it, use the function
4430
// that was generated for GenerateAppertainsTo to check if the declaration
4431
// is valid.
4432
if ((*I)->isSubClassOf("SubsetSubject"))
4433
OS << functionNameForCustomAppertainsTo(**I) << "(D)";
4434
else
4435
OS << "isa<" << GetSubjectWithSuffix(*I) << ">(D)";
4436
4437
if (I + 1 != E)
4438
OS << " || ";
4439
}
4440
OS << ";\n";
4441
}
4442
OS << " }\n";
4443
OS << " llvm_unreachable(\"Invalid match rule\");\nreturn false;\n";
4444
OS << "}\n\n";
4445
}
4446
4447
static void GenerateLangOptRequirements(const Record &R,
4448
raw_ostream &OS) {
4449
// If the attribute has an empty or unset list of language requirements,
4450
// use the default handler.
4451
std::vector<Record *> LangOpts = R.getValueAsListOfDefs("LangOpts");
4452
if (LangOpts.empty())
4453
return;
4454
4455
OS << "bool acceptsLangOpts(const LangOptions &LangOpts) const override {\n";
4456
OS << " return " << GenerateTestExpression(LangOpts) << ";\n";
4457
OS << "}\n\n";
4458
}
4459
4460
static void GenerateTargetRequirements(const Record &Attr,
4461
const ParsedAttrMap &Dupes,
4462
raw_ostream &OS) {
4463
// If the attribute is not a target specific attribute, use the default
4464
// target handler.
4465
if (!Attr.isSubClassOf("TargetSpecificAttr"))
4466
return;
4467
4468
// Get the list of architectures to be tested for.
4469
const Record *R = Attr.getValueAsDef("Target");
4470
std::vector<StringRef> Arches = R->getValueAsListOfStrings("Arches");
4471
4472
// If there are other attributes which share the same parsed attribute kind,
4473
// such as target-specific attributes with a shared spelling, collapse the
4474
// duplicate architectures. This is required because a shared target-specific
4475
// attribute has only one ParsedAttr::Kind enumeration value, but it
4476
// applies to multiple target architectures. In order for the attribute to be
4477
// considered valid, all of its architectures need to be included.
4478
if (!Attr.isValueUnset("ParseKind")) {
4479
const StringRef APK = Attr.getValueAsString("ParseKind");
4480
for (const auto &I : Dupes) {
4481
if (I.first == APK) {
4482
std::vector<StringRef> DA =
4483
I.second->getValueAsDef("Target")->getValueAsListOfStrings(
4484
"Arches");
4485
Arches.insert(Arches.end(), DA.begin(), DA.end());
4486
}
4487
}
4488
}
4489
4490
std::string FnName = "isTarget";
4491
std::string Test;
4492
bool UsesT = GenerateTargetSpecificAttrChecks(R, Arches, Test, &FnName);
4493
4494
OS << "bool existsInTarget(const TargetInfo &Target) const override {\n";
4495
if (UsesT)
4496
OS << " const llvm::Triple &T = Target.getTriple(); (void)T;\n";
4497
OS << " return " << Test << ";\n";
4498
OS << "}\n\n";
4499
}
4500
4501
static void
4502
GenerateSpellingTargetRequirements(const Record &Attr,
4503
const std::vector<Record *> &TargetSpellings,
4504
raw_ostream &OS) {
4505
// If there are no target specific spellings, use the default target handler.
4506
if (TargetSpellings.empty())
4507
return;
4508
4509
std::string Test;
4510
bool UsesT = false;
4511
const std::vector<FlattenedSpelling> SpellingList =
4512
GetFlattenedSpellings(Attr);
4513
for (unsigned TargetIndex = 0; TargetIndex < TargetSpellings.size();
4514
++TargetIndex) {
4515
const auto &TargetSpelling = TargetSpellings[TargetIndex];
4516
std::vector<FlattenedSpelling> Spellings =
4517
GetFlattenedSpellings(*TargetSpelling);
4518
4519
Test += "((SpellingListIndex == ";
4520
for (unsigned Index = 0; Index < Spellings.size(); ++Index) {
4521
Test +=
4522
llvm::itostr(getSpellingListIndex(SpellingList, Spellings[Index]));
4523
if (Index != Spellings.size() - 1)
4524
Test += " ||\n SpellingListIndex == ";
4525
else
4526
Test += ") && ";
4527
}
4528
4529
const Record *Target = TargetSpelling->getValueAsDef("Target");
4530
std::vector<StringRef> Arches = Target->getValueAsListOfStrings("Arches");
4531
std::string FnName = "isTargetSpelling";
4532
UsesT |= GenerateTargetSpecificAttrChecks(Target, Arches, Test, &FnName);
4533
Test += ")";
4534
if (TargetIndex != TargetSpellings.size() - 1)
4535
Test += " || ";
4536
}
4537
4538
OS << "bool spellingExistsInTarget(const TargetInfo &Target,\n";
4539
OS << " const unsigned SpellingListIndex) const "
4540
"override {\n";
4541
if (UsesT)
4542
OS << " const llvm::Triple &T = Target.getTriple(); (void)T;\n";
4543
OS << " return " << Test << ";\n", OS << "}\n\n";
4544
}
4545
4546
static void GenerateSpellingIndexToSemanticSpelling(const Record &Attr,
4547
raw_ostream &OS) {
4548
// If the attribute does not have a semantic form, we can bail out early.
4549
if (!Attr.getValueAsBit("ASTNode"))
4550
return;
4551
4552
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
4553
4554
// If there are zero or one spellings, or all of the spellings share the same
4555
// name, we can also bail out early.
4556
if (Spellings.size() <= 1 || SpellingNamesAreCommon(Spellings))
4557
return;
4558
4559
// Generate the enumeration we will use for the mapping.
4560
SemanticSpellingMap SemanticToSyntacticMap;
4561
std::string Enum = CreateSemanticSpellings(Spellings, SemanticToSyntacticMap);
4562
std::string Name = Attr.getName().str() + "AttrSpellingMap";
4563
4564
OS << "unsigned spellingIndexToSemanticSpelling(";
4565
OS << "const ParsedAttr &Attr) const override {\n";
4566
OS << Enum;
4567
OS << " unsigned Idx = Attr.getAttributeSpellingListIndex();\n";
4568
WriteSemanticSpellingSwitch("Idx", SemanticToSyntacticMap, OS);
4569
OS << "}\n\n";
4570
}
4571
4572
static void GenerateHandleDeclAttribute(const Record &Attr, raw_ostream &OS) {
4573
// Only generate if Attr can be handled simply.
4574
if (!Attr.getValueAsBit("SimpleHandler"))
4575
return;
4576
4577
// Generate a function which just converts from ParsedAttr to the Attr type.
4578
OS << "AttrHandling handleDeclAttribute(Sema &S, Decl *D,";
4579
OS << "const ParsedAttr &Attr) const override {\n";
4580
OS << " D->addAttr(::new (S.Context) " << Attr.getName();
4581
OS << "Attr(S.Context, Attr));\n";
4582
OS << " return AttributeApplied;\n";
4583
OS << "}\n\n";
4584
}
4585
4586
static bool isParamExpr(const Record *Arg) {
4587
return !Arg->getSuperClasses().empty() &&
4588
llvm::StringSwitch<bool>(
4589
Arg->getSuperClasses().back().first->getName())
4590
.Case("ExprArgument", true)
4591
.Case("VariadicExprArgument", true)
4592
.Default(false);
4593
}
4594
4595
void GenerateIsParamExpr(const Record &Attr, raw_ostream &OS) {
4596
OS << "bool isParamExpr(size_t N) const override {\n";
4597
OS << " return ";
4598
auto Args = Attr.getValueAsListOfDefs("Args");
4599
for (size_t I = 0; I < Args.size(); ++I)
4600
if (isParamExpr(Args[I]))
4601
OS << "(N == " << I << ") || ";
4602
OS << "false;\n";
4603
OS << "}\n\n";
4604
}
4605
4606
void GenerateHandleAttrWithDelayedArgs(RecordKeeper &Records, raw_ostream &OS) {
4607
OS << "static void handleAttrWithDelayedArgs(Sema &S, Decl *D, ";
4608
OS << "const ParsedAttr &Attr) {\n";
4609
OS << " SmallVector<Expr *, 4> ArgExprs;\n";
4610
OS << " ArgExprs.reserve(Attr.getNumArgs());\n";
4611
OS << " for (unsigned I = 0; I < Attr.getNumArgs(); ++I) {\n";
4612
OS << " assert(!Attr.isArgIdent(I));\n";
4613
OS << " ArgExprs.push_back(Attr.getArgAsExpr(I));\n";
4614
OS << " }\n";
4615
OS << " clang::Attr *CreatedAttr = nullptr;\n";
4616
OS << " switch (Attr.getKind()) {\n";
4617
OS << " default:\n";
4618
OS << " llvm_unreachable(\"Attribute cannot hold delayed arguments.\");\n";
4619
ParsedAttrMap Attrs = getParsedAttrList(Records);
4620
for (const auto &I : Attrs) {
4621
const Record &R = *I.second;
4622
if (!R.getValueAsBit("AcceptsExprPack"))
4623
continue;
4624
OS << " case ParsedAttr::AT_" << I.first << ": {\n";
4625
OS << " CreatedAttr = " << R.getName() << "Attr::CreateWithDelayedArgs";
4626
OS << "(S.Context, ArgExprs.data(), ArgExprs.size(), Attr);\n";
4627
OS << " break;\n";
4628
OS << " }\n";
4629
}
4630
OS << " }\n";
4631
OS << " D->addAttr(CreatedAttr);\n";
4632
OS << "}\n\n";
4633
}
4634
4635
static bool IsKnownToGCC(const Record &Attr) {
4636
// Look at the spellings for this subject; if there are any spellings which
4637
// claim to be known to GCC, the attribute is known to GCC.
4638
return llvm::any_of(
4639
GetFlattenedSpellings(Attr),
4640
[](const FlattenedSpelling &S) { return S.knownToGCC(); });
4641
}
4642
4643
/// Emits the parsed attribute helpers
4644
void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
4645
emitSourceFileHeader("Parsed attribute helpers", OS, Records);
4646
4647
OS << "#if !defined(WANT_DECL_MERGE_LOGIC) && "
4648
<< "!defined(WANT_STMT_MERGE_LOGIC)\n";
4649
PragmaClangAttributeSupport &PragmaAttributeSupport =
4650
getPragmaAttributeSupport(Records);
4651
4652
// Get the list of parsed attributes, and accept the optional list of
4653
// duplicates due to the ParseKind.
4654
ParsedAttrMap Dupes;
4655
ParsedAttrMap Attrs = getParsedAttrList(Records, &Dupes);
4656
4657
// Generate all of the custom appertainsTo functions that the attributes
4658
// will be using.
4659
for (const auto &I : Attrs) {
4660
const Record &Attr = *I.second;
4661
if (Attr.isValueUnset("Subjects"))
4662
continue;
4663
const Record *SubjectObj = Attr.getValueAsDef("Subjects");
4664
for (auto Subject : SubjectObj->getValueAsListOfDefs("Subjects"))
4665
if (Subject->isSubClassOf("SubsetSubject"))
4666
GenerateCustomAppertainsTo(*Subject, OS);
4667
}
4668
4669
// This stream is used to collect all of the declaration attribute merging
4670
// logic for performing mutual exclusion checks. This gets emitted at the
4671
// end of the file in a helper function of its own.
4672
std::string DeclMergeChecks, StmtMergeChecks;
4673
raw_string_ostream MergeDeclOS(DeclMergeChecks), MergeStmtOS(StmtMergeChecks);
4674
4675
// Generate a ParsedAttrInfo struct for each of the attributes.
4676
for (auto I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
4677
// TODO: If the attribute's kind appears in the list of duplicates, that is
4678
// because it is a target-specific attribute that appears multiple times.
4679
// It would be beneficial to test whether the duplicates are "similar
4680
// enough" to each other to not cause problems. For instance, check that
4681
// the spellings are identical, and custom parsing rules match, etc.
4682
4683
// We need to generate struct instances based off ParsedAttrInfo from
4684
// ParsedAttr.cpp.
4685
const std::string &AttrName = I->first;
4686
const Record &Attr = *I->second;
4687
auto Spellings = GetFlattenedSpellings(Attr);
4688
if (!Spellings.empty()) {
4689
OS << "static constexpr ParsedAttrInfo::Spelling " << I->first
4690
<< "Spellings[] = {\n";
4691
for (const auto &S : Spellings) {
4692
const std::string &RawSpelling = S.name();
4693
std::string Spelling;
4694
if (!S.nameSpace().empty())
4695
Spelling += S.nameSpace() + "::";
4696
if (S.variety() == "GNU")
4697
Spelling += NormalizeGNUAttrSpelling(RawSpelling);
4698
else
4699
Spelling += RawSpelling;
4700
OS << " {AttributeCommonInfo::AS_" << S.variety();
4701
OS << ", \"" << Spelling << "\"},\n";
4702
}
4703
OS << "};\n";
4704
}
4705
4706
std::vector<std::string> ArgNames;
4707
for (const auto &Arg : Attr.getValueAsListOfDefs("Args")) {
4708
bool UnusedUnset;
4709
if (Arg->getValueAsBitOrUnset("Fake", UnusedUnset))
4710
continue;
4711
ArgNames.push_back(Arg->getValueAsString("Name").str());
4712
for (const auto &Class : Arg->getSuperClasses()) {
4713
if (Class.first->getName().starts_with("Variadic")) {
4714
ArgNames.back().append("...");
4715
break;
4716
}
4717
}
4718
}
4719
if (!ArgNames.empty()) {
4720
OS << "static constexpr const char *" << I->first << "ArgNames[] = {\n";
4721
for (const auto &N : ArgNames)
4722
OS << '"' << N << "\",";
4723
OS << "};\n";
4724
}
4725
4726
OS << "struct ParsedAttrInfo" << I->first
4727
<< " final : public ParsedAttrInfo {\n";
4728
OS << " constexpr ParsedAttrInfo" << I->first << "() : ParsedAttrInfo(\n";
4729
OS << " /*AttrKind=*/ParsedAttr::AT_" << AttrName << ",\n";
4730
emitArgInfo(Attr, OS);
4731
OS << " /*HasCustomParsing=*/";
4732
OS << Attr.getValueAsBit("HasCustomParsing") << ",\n";
4733
OS << " /*AcceptsExprPack=*/";
4734
OS << Attr.getValueAsBit("AcceptsExprPack") << ",\n";
4735
OS << " /*IsTargetSpecific=*/";
4736
OS << Attr.isSubClassOf("TargetSpecificAttr") << ",\n";
4737
OS << " /*IsType=*/";
4738
OS << (Attr.isSubClassOf("TypeAttr") || Attr.isSubClassOf("DeclOrTypeAttr"))
4739
<< ",\n";
4740
OS << " /*IsStmt=*/";
4741
OS << (Attr.isSubClassOf("StmtAttr") || Attr.isSubClassOf("DeclOrStmtAttr"))
4742
<< ",\n";
4743
OS << " /*IsKnownToGCC=*/";
4744
OS << IsKnownToGCC(Attr) << ",\n";
4745
OS << " /*IsSupportedByPragmaAttribute=*/";
4746
OS << PragmaAttributeSupport.isAttributedSupported(*I->second) << ",\n";
4747
if (!Spellings.empty())
4748
OS << " /*Spellings=*/" << I->first << "Spellings,\n";
4749
else
4750
OS << " /*Spellings=*/{},\n";
4751
if (!ArgNames.empty())
4752
OS << " /*ArgNames=*/" << I->first << "ArgNames";
4753
else
4754
OS << " /*ArgNames=*/{}";
4755
OS << ") {}\n";
4756
GenerateAppertainsTo(Attr, OS);
4757
GenerateMutualExclusionsChecks(Attr, Records, OS, MergeDeclOS, MergeStmtOS);
4758
GenerateLangOptRequirements(Attr, OS);
4759
GenerateTargetRequirements(Attr, Dupes, OS);
4760
GenerateSpellingTargetRequirements(
4761
Attr, Attr.getValueAsListOfDefs("TargetSpecificSpellings"), OS);
4762
GenerateSpellingIndexToSemanticSpelling(Attr, OS);
4763
PragmaAttributeSupport.generateStrictConformsTo(*I->second, OS);
4764
GenerateHandleDeclAttribute(Attr, OS);
4765
GenerateIsParamExpr(Attr, OS);
4766
OS << "static const ParsedAttrInfo" << I->first << " Instance;\n";
4767
OS << "};\n";
4768
OS << "const ParsedAttrInfo" << I->first << " ParsedAttrInfo" << I->first
4769
<< "::Instance;\n";
4770
}
4771
4772
OS << "static const ParsedAttrInfo *AttrInfoMap[] = {\n";
4773
for (auto I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
4774
OS << "&ParsedAttrInfo" << I->first << "::Instance,\n";
4775
}
4776
OS << "};\n\n";
4777
4778
// Generate function for handling attributes with delayed arguments
4779
GenerateHandleAttrWithDelayedArgs(Records, OS);
4780
4781
// Generate the attribute match rules.
4782
emitAttributeMatchRules(PragmaAttributeSupport, OS);
4783
4784
OS << "#elif defined(WANT_DECL_MERGE_LOGIC)\n\n";
4785
4786
// Write out the declaration merging check logic.
4787
OS << "static bool DiagnoseMutualExclusions(Sema &S, const NamedDecl *D, "
4788
<< "const Attr *A) {\n";
4789
OS << DeclMergeChecks;
4790
OS << " return true;\n";
4791
OS << "}\n\n";
4792
4793
OS << "#elif defined(WANT_STMT_MERGE_LOGIC)\n\n";
4794
4795
// Write out the statement merging check logic.
4796
OS << "static bool DiagnoseMutualExclusions(Sema &S, "
4797
<< "const SmallVectorImpl<const Attr *> &C) {\n";
4798
OS << " for (const Attr *A : C) {\n";
4799
OS << StmtMergeChecks;
4800
OS << " }\n";
4801
OS << " return true;\n";
4802
OS << "}\n\n";
4803
4804
OS << "#endif\n";
4805
}
4806
4807
// Emits the kind list of parsed attributes
4808
void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
4809
emitSourceFileHeader("Attribute name matcher", OS, Records);
4810
4811
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
4812
std::vector<StringMatcher::StringPair> GNU, Declspec, Microsoft, CXX11,
4813
Keywords, Pragma, C23, HLSLAnnotation;
4814
std::set<std::string> Seen;
4815
for (const auto *A : Attrs) {
4816
const Record &Attr = *A;
4817
4818
bool SemaHandler = Attr.getValueAsBit("SemaHandler");
4819
bool Ignored = Attr.getValueAsBit("Ignored");
4820
if (SemaHandler || Ignored) {
4821
// Attribute spellings can be shared between target-specific attributes,
4822
// and can be shared between syntaxes for the same attribute. For
4823
// instance, an attribute can be spelled GNU<"interrupt"> for an ARM-
4824
// specific attribute, or MSP430-specific attribute. Additionally, an
4825
// attribute can be spelled GNU<"dllexport"> and Declspec<"dllexport">
4826
// for the same semantic attribute. Ultimately, we need to map each of
4827
// these to a single AttributeCommonInfo::Kind value, but the
4828
// StringMatcher class cannot handle duplicate match strings. So we
4829
// generate a list of string to match based on the syntax, and emit
4830
// multiple string matchers depending on the syntax used.
4831
std::string AttrName;
4832
if (Attr.isSubClassOf("TargetSpecificAttr") &&
4833
!Attr.isValueUnset("ParseKind")) {
4834
AttrName = std::string(Attr.getValueAsString("ParseKind"));
4835
if (!Seen.insert(AttrName).second)
4836
continue;
4837
} else
4838
AttrName = NormalizeAttrName(StringRef(Attr.getName())).str();
4839
4840
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
4841
for (const auto &S : Spellings) {
4842
const std::string &RawSpelling = S.name();
4843
std::vector<StringMatcher::StringPair> *Matches = nullptr;
4844
std::string Spelling;
4845
const std::string &Variety = S.variety();
4846
if (Variety == "CXX11") {
4847
Matches = &CXX11;
4848
if (!S.nameSpace().empty())
4849
Spelling += S.nameSpace() + "::";
4850
} else if (Variety == "C23") {
4851
Matches = &C23;
4852
if (!S.nameSpace().empty())
4853
Spelling += S.nameSpace() + "::";
4854
} else if (Variety == "GNU")
4855
Matches = &GNU;
4856
else if (Variety == "Declspec")
4857
Matches = &Declspec;
4858
else if (Variety == "Microsoft")
4859
Matches = &Microsoft;
4860
else if (Variety == "Keyword")
4861
Matches = &Keywords;
4862
else if (Variety == "Pragma")
4863
Matches = &Pragma;
4864
else if (Variety == "HLSLAnnotation")
4865
Matches = &HLSLAnnotation;
4866
4867
assert(Matches && "Unsupported spelling variety found");
4868
4869
if (Variety == "GNU")
4870
Spelling += NormalizeGNUAttrSpelling(RawSpelling);
4871
else
4872
Spelling += RawSpelling;
4873
4874
if (SemaHandler)
4875
Matches->push_back(StringMatcher::StringPair(
4876
Spelling, "return AttributeCommonInfo::AT_" + AttrName + ";"));
4877
else
4878
Matches->push_back(StringMatcher::StringPair(
4879
Spelling, "return AttributeCommonInfo::IgnoredAttribute;"));
4880
}
4881
}
4882
}
4883
4884
OS << "static AttributeCommonInfo::Kind getAttrKind(StringRef Name, ";
4885
OS << "AttributeCommonInfo::Syntax Syntax) {\n";
4886
OS << " if (AttributeCommonInfo::AS_GNU == Syntax) {\n";
4887
StringMatcher("Name", GNU, OS).Emit();
4888
OS << " } else if (AttributeCommonInfo::AS_Declspec == Syntax) {\n";
4889
StringMatcher("Name", Declspec, OS).Emit();
4890
OS << " } else if (AttributeCommonInfo::AS_Microsoft == Syntax) {\n";
4891
StringMatcher("Name", Microsoft, OS).Emit();
4892
OS << " } else if (AttributeCommonInfo::AS_CXX11 == Syntax) {\n";
4893
StringMatcher("Name", CXX11, OS).Emit();
4894
OS << " } else if (AttributeCommonInfo::AS_C23 == Syntax) {\n";
4895
StringMatcher("Name", C23, OS).Emit();
4896
OS << " } else if (AttributeCommonInfo::AS_Keyword == Syntax || ";
4897
OS << "AttributeCommonInfo::AS_ContextSensitiveKeyword == Syntax) {\n";
4898
StringMatcher("Name", Keywords, OS).Emit();
4899
OS << " } else if (AttributeCommonInfo::AS_Pragma == Syntax) {\n";
4900
StringMatcher("Name", Pragma, OS).Emit();
4901
OS << " } else if (AttributeCommonInfo::AS_HLSLAnnotation == Syntax) {\n";
4902
StringMatcher("Name", HLSLAnnotation, OS).Emit();
4903
OS << " }\n";
4904
OS << " return AttributeCommonInfo::UnknownAttribute;\n"
4905
<< "}\n";
4906
}
4907
4908
// Emits the code to dump an attribute.
4909
void EmitClangAttrTextNodeDump(RecordKeeper &Records, raw_ostream &OS) {
4910
emitSourceFileHeader("Attribute text node dumper", OS, Records);
4911
4912
std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
4913
for (const auto *Attr : Attrs) {
4914
const Record &R = *Attr;
4915
if (!R.getValueAsBit("ASTNode"))
4916
continue;
4917
4918
// If the attribute has a semantically-meaningful name (which is determined
4919
// by whether there is a Spelling enumeration for it), then write out the
4920
// spelling used for the attribute.
4921
4922
std::string FunctionContent;
4923
llvm::raw_string_ostream SS(FunctionContent);
4924
4925
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
4926
if (Spellings.size() > 1 && !SpellingNamesAreCommon(Spellings))
4927
SS << " OS << \" \" << A->getSpelling();\n";
4928
4929
Args = R.getValueAsListOfDefs("Args");
4930
for (const auto *Arg : Args)
4931
createArgument(*Arg, R.getName())->writeDump(SS);
4932
4933
if (Attr->getValueAsBit("AcceptsExprPack"))
4934
VariadicExprArgument("DelayedArgs", R.getName()).writeDump(OS);
4935
4936
if (SS.tell()) {
4937
OS << " void Visit" << R.getName() << "Attr(const " << R.getName()
4938
<< "Attr *A) {\n";
4939
if (!Args.empty())
4940
OS << " const auto *SA = cast<" << R.getName()
4941
<< "Attr>(A); (void)SA;\n";
4942
OS << FunctionContent;
4943
OS << " }\n";
4944
}
4945
}
4946
}
4947
4948
void EmitClangAttrNodeTraverse(RecordKeeper &Records, raw_ostream &OS) {
4949
emitSourceFileHeader("Attribute text node traverser", OS, Records);
4950
4951
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
4952
for (const auto *Attr : Attrs) {
4953
const Record &R = *Attr;
4954
if (!R.getValueAsBit("ASTNode"))
4955
continue;
4956
4957
std::string FunctionContent;
4958
llvm::raw_string_ostream SS(FunctionContent);
4959
4960
Args = R.getValueAsListOfDefs("Args");
4961
for (const auto *Arg : Args)
4962
createArgument(*Arg, R.getName())->writeDumpChildren(SS);
4963
if (Attr->getValueAsBit("AcceptsExprPack"))
4964
VariadicExprArgument("DelayedArgs", R.getName()).writeDumpChildren(SS);
4965
if (SS.tell()) {
4966
OS << " void Visit" << R.getName() << "Attr(const " << R.getName()
4967
<< "Attr *A) {\n";
4968
if (!Args.empty())
4969
OS << " const auto *SA = cast<" << R.getName()
4970
<< "Attr>(A); (void)SA;\n";
4971
OS << FunctionContent;
4972
OS << " }\n";
4973
}
4974
}
4975
}
4976
4977
void EmitClangAttrParserStringSwitches(RecordKeeper &Records, raw_ostream &OS) {
4978
emitSourceFileHeader("Parser-related llvm::StringSwitch cases", OS, Records);
4979
emitClangAttrArgContextList(Records, OS);
4980
emitClangAttrIdentifierArgList(Records, OS);
4981
emitClangAttrUnevaluatedStringLiteralList(Records, OS);
4982
emitClangAttrVariadicIdentifierArgList(Records, OS);
4983
emitClangAttrThisIsaIdentifierArgList(Records, OS);
4984
emitClangAttrAcceptsExprPack(Records, OS);
4985
emitClangAttrTypeArgList(Records, OS);
4986
emitClangAttrLateParsedList(Records, OS);
4987
emitClangAttrLateParsedExperimentalList(Records, OS);
4988
emitClangAttrStrictIdentifierArgAtIndexList(Records, OS);
4989
}
4990
4991
void EmitClangAttrSubjectMatchRulesParserStringSwitches(RecordKeeper &Records,
4992
raw_ostream &OS) {
4993
getPragmaAttributeSupport(Records).generateParsingHelpers(OS);
4994
}
4995
4996
void EmitClangAttrDocTable(RecordKeeper &Records, raw_ostream &OS) {
4997
emitSourceFileHeader("Clang attribute documentation", OS, Records);
4998
4999
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
5000
for (const auto *A : Attrs) {
5001
if (!A->getValueAsBit("ASTNode"))
5002
continue;
5003
std::vector<Record *> Docs = A->getValueAsListOfDefs("Documentation");
5004
assert(!Docs.empty());
5005
// Only look at the first documentation if there are several.
5006
// (Currently there's only one such attr, revisit if this becomes common).
5007
StringRef Text =
5008
Docs.front()->getValueAsOptionalString("Content").value_or("");
5009
OS << "\nstatic const char AttrDoc_" << A->getName() << "[] = "
5010
<< "R\"reST(" << Text.trim() << ")reST\";\n";
5011
}
5012
}
5013
5014
enum class SpellingKind : size_t {
5015
GNU,
5016
CXX11,
5017
C23,
5018
Declspec,
5019
Microsoft,
5020
Keyword,
5021
Pragma,
5022
HLSLAnnotation,
5023
NumSpellingKinds
5024
};
5025
static const size_t NumSpellingKinds = (size_t)SpellingKind::NumSpellingKinds;
5026
5027
class SpellingList {
5028
std::vector<std::string> Spellings[NumSpellingKinds];
5029
5030
public:
5031
ArrayRef<std::string> operator[](SpellingKind K) const {
5032
return Spellings[(size_t)K];
5033
}
5034
5035
void add(const Record &Attr, FlattenedSpelling Spelling) {
5036
SpellingKind Kind =
5037
StringSwitch<SpellingKind>(Spelling.variety())
5038
.Case("GNU", SpellingKind::GNU)
5039
.Case("CXX11", SpellingKind::CXX11)
5040
.Case("C23", SpellingKind::C23)
5041
.Case("Declspec", SpellingKind::Declspec)
5042
.Case("Microsoft", SpellingKind::Microsoft)
5043
.Case("Keyword", SpellingKind::Keyword)
5044
.Case("Pragma", SpellingKind::Pragma)
5045
.Case("HLSLAnnotation", SpellingKind::HLSLAnnotation);
5046
std::string Name;
5047
if (!Spelling.nameSpace().empty()) {
5048
switch (Kind) {
5049
case SpellingKind::CXX11:
5050
case SpellingKind::C23:
5051
Name = Spelling.nameSpace() + "::";
5052
break;
5053
case SpellingKind::Pragma:
5054
Name = Spelling.nameSpace() + " ";
5055
break;
5056
default:
5057
PrintFatalError(Attr.getLoc(), "Unexpected namespace in spelling");
5058
}
5059
}
5060
Name += Spelling.name();
5061
5062
Spellings[(size_t)Kind].push_back(Name);
5063
}
5064
};
5065
5066
class DocumentationData {
5067
public:
5068
const Record *Documentation;
5069
const Record *Attribute;
5070
std::string Heading;
5071
SpellingList SupportedSpellings;
5072
5073
DocumentationData(const Record &Documentation, const Record &Attribute,
5074
std::pair<std::string, SpellingList> HeadingAndSpellings)
5075
: Documentation(&Documentation), Attribute(&Attribute),
5076
Heading(std::move(HeadingAndSpellings.first)),
5077
SupportedSpellings(std::move(HeadingAndSpellings.second)) {}
5078
};
5079
5080
static void WriteCategoryHeader(const Record *DocCategory,
5081
raw_ostream &OS) {
5082
const StringRef Name = DocCategory->getValueAsString("Name");
5083
OS << Name << "\n" << std::string(Name.size(), '=') << "\n";
5084
5085
// If there is content, print that as well.
5086
const StringRef ContentStr = DocCategory->getValueAsString("Content");
5087
// Trim leading and trailing newlines and spaces.
5088
OS << ContentStr.trim();
5089
5090
OS << "\n\n";
5091
}
5092
5093
static std::pair<std::string, SpellingList>
5094
GetAttributeHeadingAndSpellings(const Record &Documentation,
5095
const Record &Attribute,
5096
StringRef Cat) {
5097
// FIXME: there is no way to have a per-spelling category for the attribute
5098
// documentation. This may not be a limiting factor since the spellings
5099
// should generally be consistently applied across the category.
5100
5101
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attribute);
5102
if (Spellings.empty())
5103
PrintFatalError(Attribute.getLoc(),
5104
"Attribute has no supported spellings; cannot be "
5105
"documented");
5106
5107
// Determine the heading to be used for this attribute.
5108
std::string Heading = std::string(Documentation.getValueAsString("Heading"));
5109
if (Heading.empty()) {
5110
// If there's only one spelling, we can simply use that.
5111
if (Spellings.size() == 1)
5112
Heading = Spellings.begin()->name();
5113
else {
5114
std::set<std::string> Uniques;
5115
for (auto I = Spellings.begin(), E = Spellings.end();
5116
I != E; ++I) {
5117
std::string Spelling =
5118
std::string(NormalizeNameForSpellingComparison(I->name()));
5119
Uniques.insert(Spelling);
5120
}
5121
// If the semantic map has only one spelling, that is sufficient for our
5122
// needs.
5123
if (Uniques.size() == 1)
5124
Heading = *Uniques.begin();
5125
// If it's in the undocumented category, just construct a header by
5126
// concatenating all the spellings. Might not be great, but better than
5127
// nothing.
5128
else if (Cat == "Undocumented")
5129
Heading = llvm::join(Uniques.begin(), Uniques.end(), ", ");
5130
}
5131
}
5132
5133
// If the heading is still empty, it is an error.
5134
if (Heading.empty())
5135
PrintFatalError(Attribute.getLoc(),
5136
"This attribute requires a heading to be specified");
5137
5138
SpellingList SupportedSpellings;
5139
for (const auto &I : Spellings)
5140
SupportedSpellings.add(Attribute, I);
5141
5142
return std::make_pair(std::move(Heading), std::move(SupportedSpellings));
5143
}
5144
5145
static void WriteDocumentation(RecordKeeper &Records,
5146
const DocumentationData &Doc, raw_ostream &OS) {
5147
OS << Doc.Heading << "\n" << std::string(Doc.Heading.length(), '-') << "\n";
5148
5149
// List what spelling syntaxes the attribute supports.
5150
// Note: "#pragma clang attribute" is handled outside the spelling kinds loop
5151
// so it must be last.
5152
OS << ".. csv-table:: Supported Syntaxes\n";
5153
OS << " :header: \"GNU\", \"C++11\", \"C23\", \"``__declspec``\",";
5154
OS << " \"Keyword\", \"``#pragma``\", \"HLSL Annotation\", \"``#pragma "
5155
"clang ";
5156
OS << "attribute``\"\n\n \"";
5157
for (size_t Kind = 0; Kind != NumSpellingKinds; ++Kind) {
5158
SpellingKind K = (SpellingKind)Kind;
5159
// TODO: List Microsoft (IDL-style attribute) spellings once we fully
5160
// support them.
5161
if (K == SpellingKind::Microsoft)
5162
continue;
5163
5164
bool PrintedAny = false;
5165
for (StringRef Spelling : Doc.SupportedSpellings[K]) {
5166
if (PrintedAny)
5167
OS << " |br| ";
5168
OS << "``" << Spelling << "``";
5169
PrintedAny = true;
5170
}
5171
5172
OS << "\",\"";
5173
}
5174
5175
if (getPragmaAttributeSupport(Records).isAttributedSupported(
5176
*Doc.Attribute))
5177
OS << "Yes";
5178
OS << "\"\n\n";
5179
5180
// If the attribute is deprecated, print a message about it, and possibly
5181
// provide a replacement attribute.
5182
if (!Doc.Documentation->isValueUnset("Deprecated")) {
5183
OS << "This attribute has been deprecated, and may be removed in a future "
5184
<< "version of Clang.";
5185
const Record &Deprecated = *Doc.Documentation->getValueAsDef("Deprecated");
5186
const StringRef Replacement = Deprecated.getValueAsString("Replacement");
5187
if (!Replacement.empty())
5188
OS << " This attribute has been superseded by ``" << Replacement
5189
<< "``.";
5190
OS << "\n\n";
5191
}
5192
5193
const StringRef ContentStr = Doc.Documentation->getValueAsString("Content");
5194
// Trim leading and trailing newlines and spaces.
5195
OS << ContentStr.trim();
5196
5197
OS << "\n\n\n";
5198
}
5199
5200
void EmitClangAttrDocs(RecordKeeper &Records, raw_ostream &OS) {
5201
// Get the documentation introduction paragraph.
5202
const Record *Documentation = Records.getDef("GlobalDocumentation");
5203
if (!Documentation) {
5204
PrintFatalError("The Documentation top-level definition is missing, "
5205
"no documentation will be generated.");
5206
return;
5207
}
5208
5209
OS << Documentation->getValueAsString("Intro") << "\n";
5210
5211
// Gather the Documentation lists from each of the attributes, based on the
5212
// category provided.
5213
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
5214
struct CategoryLess {
5215
bool operator()(const Record *L, const Record *R) const {
5216
return L->getValueAsString("Name") < R->getValueAsString("Name");
5217
}
5218
};
5219
std::map<const Record *, std::vector<DocumentationData>, CategoryLess>
5220
SplitDocs;
5221
for (const auto *A : Attrs) {
5222
const Record &Attr = *A;
5223
std::vector<Record *> Docs = Attr.getValueAsListOfDefs("Documentation");
5224
for (const auto *D : Docs) {
5225
const Record &Doc = *D;
5226
const Record *Category = Doc.getValueAsDef("Category");
5227
// If the category is "InternalOnly", then there cannot be any other
5228
// documentation categories (otherwise, the attribute would be
5229
// emitted into the docs).
5230
const StringRef Cat = Category->getValueAsString("Name");
5231
bool InternalOnly = Cat == "InternalOnly";
5232
if (InternalOnly && Docs.size() > 1)
5233
PrintFatalError(Doc.getLoc(),
5234
"Attribute is \"InternalOnly\", but has multiple "
5235
"documentation categories");
5236
5237
if (!InternalOnly)
5238
SplitDocs[Category].push_back(DocumentationData(
5239
Doc, Attr, GetAttributeHeadingAndSpellings(Doc, Attr, Cat)));
5240
}
5241
}
5242
5243
// Having split the attributes out based on what documentation goes where,
5244
// we can begin to generate sections of documentation.
5245
for (auto &I : SplitDocs) {
5246
WriteCategoryHeader(I.first, OS);
5247
5248
llvm::sort(I.second,
5249
[](const DocumentationData &D1, const DocumentationData &D2) {
5250
return D1.Heading < D2.Heading;
5251
});
5252
5253
// Walk over each of the attributes in the category and write out their
5254
// documentation.
5255
for (const auto &Doc : I.second)
5256
WriteDocumentation(Records, Doc, OS);
5257
}
5258
}
5259
5260
void EmitTestPragmaAttributeSupportedAttributes(RecordKeeper &Records,
5261
raw_ostream &OS) {
5262
PragmaClangAttributeSupport Support = getPragmaAttributeSupport(Records);
5263
ParsedAttrMap Attrs = getParsedAttrList(Records);
5264
OS << "#pragma clang attribute supports the following attributes:\n";
5265
for (const auto &I : Attrs) {
5266
if (!Support.isAttributedSupported(*I.second))
5267
continue;
5268
OS << I.first;
5269
if (I.second->isValueUnset("Subjects")) {
5270
OS << " ()\n";
5271
continue;
5272
}
5273
const Record *SubjectObj = I.second->getValueAsDef("Subjects");
5274
std::vector<Record *> Subjects =
5275
SubjectObj->getValueAsListOfDefs("Subjects");
5276
OS << " (";
5277
bool PrintComma = false;
5278
for (const auto &Subject : llvm::enumerate(Subjects)) {
5279
if (!isSupportedPragmaClangAttributeSubject(*Subject.value()))
5280
continue;
5281
if (PrintComma)
5282
OS << ", ";
5283
PrintComma = true;
5284
PragmaClangAttributeSupport::RuleOrAggregateRuleSet &RuleSet =
5285
Support.SubjectsToRules.find(Subject.value())->getSecond();
5286
if (RuleSet.isRule()) {
5287
OS << RuleSet.getRule().getEnumValueName();
5288
continue;
5289
}
5290
OS << "(";
5291
for (const auto &Rule : llvm::enumerate(RuleSet.getAggregateRuleSet())) {
5292
if (Rule.index())
5293
OS << ", ";
5294
OS << Rule.value().getEnumValueName();
5295
}
5296
OS << ")";
5297
}
5298
OS << ")\n";
5299
}
5300
OS << "End of supported attributes.\n";
5301
}
5302
5303
} // end namespace clang
5304
5305