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

source code of clang/utils/TableGen/ClangAttrEmitter.cpp