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