1 //===- ClangAttrEmitter.cpp - Generate Clang attribute handling =-*- C++ -*--=//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // These tablegen backends emit Clang attribute processing code
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/ADT/SmallString.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/SmallSet.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/TableGen/Error.h"
19 #include "llvm/TableGen/Record.h"
20 #include "llvm/TableGen/StringMatcher.h"
21 #include "llvm/TableGen/TableGenBackend.h"
22 #include <algorithm>
23 #include <cctype>
24 #include <memory>
25 #include <set>
26 #include <sstream>
27
28 using namespace llvm;
29
30 class FlattenedSpelling {
31 std::string V, N, NS;
32 bool K;
33
34 public:
FlattenedSpelling(const std::string & Variety,const std::string & Name,const std::string & Namespace,bool KnownToGCC)35 FlattenedSpelling(const std::string &Variety, const std::string &Name,
36 const std::string &Namespace, bool KnownToGCC) :
37 V(Variety), N(Name), NS(Namespace), K(KnownToGCC) {}
FlattenedSpelling(const Record & Spelling)38 explicit FlattenedSpelling(const Record &Spelling) :
39 V(Spelling.getValueAsString("Variety")),
40 N(Spelling.getValueAsString("Name")) {
41
42 assert(V != "GCC" && "Given a GCC spelling, which means this hasn't been"
43 "flattened!");
44 if (V == "CXX11" || V == "Pragma")
45 NS = Spelling.getValueAsString("Namespace");
46 bool Unset;
47 K = Spelling.getValueAsBitOrUnset("KnownToGCC", Unset);
48 }
49
variety() const50 const std::string &variety() const { return V; }
name() const51 const std::string &name() const { return N; }
nameSpace() const52 const std::string &nameSpace() const { return NS; }
knownToGCC() const53 bool knownToGCC() const { return K; }
54 };
55
GetFlattenedSpellings(const Record & Attr)56 std::vector<FlattenedSpelling> GetFlattenedSpellings(const Record &Attr) {
57 std::vector<Record *> Spellings = Attr.getValueAsListOfDefs("Spellings");
58 std::vector<FlattenedSpelling> Ret;
59
60 for (const auto &Spelling : Spellings) {
61 if (Spelling->getValueAsString("Variety") == "GCC") {
62 // Gin up two new spelling objects to add into the list.
63 Ret.push_back(FlattenedSpelling("GNU", Spelling->getValueAsString("Name"),
64 "", true));
65 Ret.push_back(FlattenedSpelling(
66 "CXX11", Spelling->getValueAsString("Name"), "gnu", true));
67 } else
68 Ret.push_back(FlattenedSpelling(*Spelling));
69 }
70
71 return Ret;
72 }
73
ReadPCHRecord(StringRef type)74 static std::string ReadPCHRecord(StringRef type) {
75 return StringSwitch<std::string>(type)
76 .EndsWith("Decl *", "GetLocalDeclAs<"
77 + std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])")
78 .Case("TypeSourceInfo *", "GetTypeSourceInfo(F, Record, Idx)")
79 .Case("Expr *", "ReadExpr(F)")
80 .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)")
81 .Default("Record[Idx++]");
82 }
83
84 // Assumes that the way to get the value is SA->getname()
WritePCHRecord(StringRef type,StringRef name)85 static std::string WritePCHRecord(StringRef type, StringRef name) {
86 return StringSwitch<std::string>(type)
87 .EndsWith("Decl *", "AddDeclRef(" + std::string(name) +
88 ", Record);\n")
89 .Case("TypeSourceInfo *",
90 "AddTypeSourceInfo(" + std::string(name) + ", Record);\n")
91 .Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
92 .Case("IdentifierInfo *",
93 "AddIdentifierRef(" + std::string(name) + ", Record);\n")
94 .Default("Record.push_back(" + std::string(name) + ");\n");
95 }
96
97 // Normalize attribute name by removing leading and trailing
98 // underscores. For example, __foo, foo__, __foo__ would
99 // become foo.
NormalizeAttrName(StringRef AttrName)100 static StringRef NormalizeAttrName(StringRef AttrName) {
101 if (AttrName.startswith("__"))
102 AttrName = AttrName.substr(2, AttrName.size());
103
104 if (AttrName.endswith("__"))
105 AttrName = AttrName.substr(0, AttrName.size() - 2);
106
107 return AttrName;
108 }
109
110 // Normalize the name by removing any and all leading and trailing underscores.
111 // This is different from NormalizeAttrName in that it also handles names like
112 // _pascal and __pascal.
NormalizeNameForSpellingComparison(StringRef Name)113 static StringRef NormalizeNameForSpellingComparison(StringRef Name) {
114 while (Name.startswith("_"))
115 Name = Name.substr(1, Name.size());
116 while (Name.endswith("_"))
117 Name = Name.substr(0, Name.size() - 1);
118 return Name;
119 }
120
121 // Normalize attribute spelling only if the spelling has both leading
122 // and trailing underscores. For example, __ms_struct__ will be
123 // normalized to "ms_struct"; __cdecl will remain intact.
NormalizeAttrSpelling(StringRef AttrSpelling)124 static StringRef NormalizeAttrSpelling(StringRef AttrSpelling) {
125 if (AttrSpelling.startswith("__") && AttrSpelling.endswith("__")) {
126 AttrSpelling = AttrSpelling.substr(2, AttrSpelling.size() - 4);
127 }
128
129 return AttrSpelling;
130 }
131
132 typedef std::vector<std::pair<std::string, const Record *>> ParsedAttrMap;
133
getParsedAttrList(const RecordKeeper & Records,ParsedAttrMap * Dupes=nullptr)134 static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records,
135 ParsedAttrMap *Dupes = nullptr) {
136 std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
137 std::set<std::string> Seen;
138 ParsedAttrMap R;
139 for (const auto *Attr : Attrs) {
140 if (Attr->getValueAsBit("SemaHandler")) {
141 std::string AN;
142 if (Attr->isSubClassOf("TargetSpecificAttr") &&
143 !Attr->isValueUnset("ParseKind")) {
144 AN = Attr->getValueAsString("ParseKind");
145
146 // If this attribute has already been handled, it does not need to be
147 // handled again.
148 if (Seen.find(AN) != Seen.end()) {
149 if (Dupes)
150 Dupes->push_back(std::make_pair(AN, Attr));
151 continue;
152 }
153 Seen.insert(AN);
154 } else
155 AN = NormalizeAttrName(Attr->getName()).str();
156
157 R.push_back(std::make_pair(AN, Attr));
158 }
159 }
160 return R;
161 }
162
163 namespace {
164 class Argument {
165 std::string lowerName, upperName;
166 StringRef attrName;
167 bool isOpt;
168
169 public:
Argument(const Record & Arg,StringRef Attr)170 Argument(const Record &Arg, StringRef Attr)
171 : lowerName(Arg.getValueAsString("Name")), upperName(lowerName),
172 attrName(Attr), isOpt(false) {
173 if (!lowerName.empty()) {
174 lowerName[0] = std::tolower(lowerName[0]);
175 upperName[0] = std::toupper(upperName[0]);
176 }
177 }
~Argument()178 virtual ~Argument() {}
179
getLowerName() const180 StringRef getLowerName() const { return lowerName; }
getUpperName() const181 StringRef getUpperName() const { return upperName; }
getAttrName() const182 StringRef getAttrName() const { return attrName; }
183
isOptional() const184 bool isOptional() const { return isOpt; }
setOptional(bool set)185 void setOptional(bool set) { isOpt = set; }
186
187 // These functions print the argument contents formatted in different ways.
188 virtual void writeAccessors(raw_ostream &OS) const = 0;
writeAccessorDefinitions(raw_ostream & OS) const189 virtual void writeAccessorDefinitions(raw_ostream &OS) const {}
writeASTVisitorTraversal(raw_ostream & OS) const190 virtual void writeASTVisitorTraversal(raw_ostream &OS) const {}
191 virtual void writeCloneArgs(raw_ostream &OS) const = 0;
192 virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0;
writeTemplateInstantiation(raw_ostream & OS) const193 virtual void writeTemplateInstantiation(raw_ostream &OS) const {}
writeCtorBody(raw_ostream & OS) const194 virtual void writeCtorBody(raw_ostream &OS) const {}
195 virtual void writeCtorInitializers(raw_ostream &OS) const = 0;
196 virtual void writeCtorDefaultInitializers(raw_ostream &OS) const = 0;
197 virtual void writeCtorParameters(raw_ostream &OS) const = 0;
198 virtual void writeDeclarations(raw_ostream &OS) const = 0;
199 virtual void writePCHReadArgs(raw_ostream &OS) const = 0;
200 virtual void writePCHReadDecls(raw_ostream &OS) const = 0;
201 virtual void writePCHWrite(raw_ostream &OS) const = 0;
202 virtual void writeValue(raw_ostream &OS) const = 0;
203 virtual void writeDump(raw_ostream &OS) const = 0;
writeDumpChildren(raw_ostream & OS) const204 virtual void writeDumpChildren(raw_ostream &OS) const {}
writeHasChildren(raw_ostream & OS) const205 virtual void writeHasChildren(raw_ostream &OS) const { OS << "false"; }
206
isEnumArg() const207 virtual bool isEnumArg() const { return false; }
isVariadicEnumArg() const208 virtual bool isVariadicEnumArg() const { return false; }
209
writeImplicitCtorArgs(raw_ostream & OS) const210 virtual void writeImplicitCtorArgs(raw_ostream &OS) const {
211 OS << getUpperName();
212 }
213 };
214
215 class SimpleArgument : public Argument {
216 std::string type;
217
218 public:
SimpleArgument(const Record & Arg,StringRef Attr,std::string T)219 SimpleArgument(const Record &Arg, StringRef Attr, std::string T)
220 : Argument(Arg, Attr), type(T)
221 {}
222
getType() const223 std::string getType() const { return type; }
224
writeAccessors(raw_ostream & OS) const225 void writeAccessors(raw_ostream &OS) const override {
226 OS << " " << type << " get" << getUpperName() << "() const {\n";
227 OS << " return " << getLowerName() << ";\n";
228 OS << " }";
229 }
writeCloneArgs(raw_ostream & OS) const230 void writeCloneArgs(raw_ostream &OS) const override {
231 OS << getLowerName();
232 }
writeTemplateInstantiationArgs(raw_ostream & OS) const233 void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
234 OS << "A->get" << getUpperName() << "()";
235 }
writeCtorInitializers(raw_ostream & OS) const236 void writeCtorInitializers(raw_ostream &OS) const override {
237 OS << getLowerName() << "(" << getUpperName() << ")";
238 }
writeCtorDefaultInitializers(raw_ostream & OS) const239 void writeCtorDefaultInitializers(raw_ostream &OS) const override {
240 OS << getLowerName() << "()";
241 }
writeCtorParameters(raw_ostream & OS) const242 void writeCtorParameters(raw_ostream &OS) const override {
243 OS << type << " " << getUpperName();
244 }
writeDeclarations(raw_ostream & OS) const245 void writeDeclarations(raw_ostream &OS) const override {
246 OS << type << " " << getLowerName() << ";";
247 }
writePCHReadDecls(raw_ostream & OS) const248 void writePCHReadDecls(raw_ostream &OS) const override {
249 std::string read = ReadPCHRecord(type);
250 OS << " " << type << " " << getLowerName() << " = " << read << ";\n";
251 }
writePCHReadArgs(raw_ostream & OS) const252 void writePCHReadArgs(raw_ostream &OS) const override {
253 OS << getLowerName();
254 }
writePCHWrite(raw_ostream & OS) const255 void writePCHWrite(raw_ostream &OS) const override {
256 OS << " " << WritePCHRecord(type, "SA->get" +
257 std::string(getUpperName()) + "()");
258 }
writeValue(raw_ostream & OS) const259 void writeValue(raw_ostream &OS) const override {
260 if (type == "FunctionDecl *") {
261 OS << "\" << get" << getUpperName()
262 << "()->getNameInfo().getAsString() << \"";
263 } else if (type == "IdentifierInfo *") {
264 OS << "\" << get" << getUpperName() << "()->getName() << \"";
265 } else if (type == "TypeSourceInfo *") {
266 OS << "\" << get" << getUpperName() << "().getAsString() << \"";
267 } else {
268 OS << "\" << get" << getUpperName() << "() << \"";
269 }
270 }
writeDump(raw_ostream & OS) const271 void writeDump(raw_ostream &OS) const override {
272 if (type == "FunctionDecl *") {
273 OS << " OS << \" \";\n";
274 OS << " dumpBareDeclRef(SA->get" << getUpperName() << "());\n";
275 } else if (type == "IdentifierInfo *") {
276 OS << " OS << \" \" << SA->get" << getUpperName()
277 << "()->getName();\n";
278 } else if (type == "TypeSourceInfo *") {
279 OS << " OS << \" \" << SA->get" << getUpperName()
280 << "().getAsString();\n";
281 } else if (type == "bool") {
282 OS << " if (SA->get" << getUpperName() << "()) OS << \" "
283 << getUpperName() << "\";\n";
284 } else if (type == "int" || type == "unsigned") {
285 OS << " OS << \" \" << SA->get" << getUpperName() << "();\n";
286 } else {
287 llvm_unreachable("Unknown SimpleArgument type!");
288 }
289 }
290 };
291
292 class DefaultSimpleArgument : public SimpleArgument {
293 int64_t Default;
294
295 public:
DefaultSimpleArgument(const Record & Arg,StringRef Attr,std::string T,int64_t Default)296 DefaultSimpleArgument(const Record &Arg, StringRef Attr,
297 std::string T, int64_t Default)
298 : SimpleArgument(Arg, Attr, T), Default(Default) {}
299
writeAccessors(raw_ostream & OS) const300 void writeAccessors(raw_ostream &OS) const override {
301 SimpleArgument::writeAccessors(OS);
302
303 OS << "\n\n static const " << getType() << " Default" << getUpperName()
304 << " = " << Default << ";";
305 }
306 };
307
308 class StringArgument : public Argument {
309 public:
StringArgument(const Record & Arg,StringRef Attr)310 StringArgument(const Record &Arg, StringRef Attr)
311 : Argument(Arg, Attr)
312 {}
313
writeAccessors(raw_ostream & OS) const314 void writeAccessors(raw_ostream &OS) const override {
315 OS << " llvm::StringRef get" << getUpperName() << "() const {\n";
316 OS << " return llvm::StringRef(" << getLowerName() << ", "
317 << getLowerName() << "Length);\n";
318 OS << " }\n";
319 OS << " unsigned get" << getUpperName() << "Length() const {\n";
320 OS << " return " << getLowerName() << "Length;\n";
321 OS << " }\n";
322 OS << " void set" << getUpperName()
323 << "(ASTContext &C, llvm::StringRef S) {\n";
324 OS << " " << getLowerName() << "Length = S.size();\n";
325 OS << " this->" << getLowerName() << " = new (C, 1) char ["
326 << getLowerName() << "Length];\n";
327 OS << " std::memcpy(this->" << getLowerName() << ", S.data(), "
328 << getLowerName() << "Length);\n";
329 OS << " }";
330 }
writeCloneArgs(raw_ostream & OS) const331 void writeCloneArgs(raw_ostream &OS) const override {
332 OS << "get" << getUpperName() << "()";
333 }
writeTemplateInstantiationArgs(raw_ostream & OS) const334 void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
335 OS << "A->get" << getUpperName() << "()";
336 }
writeCtorBody(raw_ostream & OS) const337 void writeCtorBody(raw_ostream &OS) const override {
338 OS << " std::memcpy(" << getLowerName() << ", " << getUpperName()
339 << ".data(), " << getLowerName() << "Length);";
340 }
writeCtorInitializers(raw_ostream & OS) const341 void writeCtorInitializers(raw_ostream &OS) const override {
342 OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
343 << getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
344 << "Length])";
345 }
writeCtorDefaultInitializers(raw_ostream & OS) const346 void writeCtorDefaultInitializers(raw_ostream &OS) const override {
347 OS << getLowerName() << "Length(0)," << getLowerName() << "(0)";
348 }
writeCtorParameters(raw_ostream & OS) const349 void writeCtorParameters(raw_ostream &OS) const override {
350 OS << "llvm::StringRef " << getUpperName();
351 }
writeDeclarations(raw_ostream & OS) const352 void writeDeclarations(raw_ostream &OS) const override {
353 OS << "unsigned " << getLowerName() << "Length;\n";
354 OS << "char *" << getLowerName() << ";";
355 }
writePCHReadDecls(raw_ostream & OS) const356 void writePCHReadDecls(raw_ostream &OS) const override {
357 OS << " std::string " << getLowerName()
358 << "= ReadString(Record, Idx);\n";
359 }
writePCHReadArgs(raw_ostream & OS) const360 void writePCHReadArgs(raw_ostream &OS) const override {
361 OS << getLowerName();
362 }
writePCHWrite(raw_ostream & OS) const363 void writePCHWrite(raw_ostream &OS) const override {
364 OS << " AddString(SA->get" << getUpperName() << "(), Record);\n";
365 }
writeValue(raw_ostream & OS) const366 void writeValue(raw_ostream &OS) const override {
367 OS << "\\\"\" << get" << getUpperName() << "() << \"\\\"";
368 }
writeDump(raw_ostream & OS) const369 void writeDump(raw_ostream &OS) const override {
370 OS << " OS << \" \\\"\" << SA->get" << getUpperName()
371 << "() << \"\\\"\";\n";
372 }
373 };
374
375 class AlignedArgument : public Argument {
376 public:
AlignedArgument(const Record & Arg,StringRef Attr)377 AlignedArgument(const Record &Arg, StringRef Attr)
378 : Argument(Arg, Attr)
379 {}
380
writeAccessors(raw_ostream & OS) const381 void writeAccessors(raw_ostream &OS) const override {
382 OS << " bool is" << getUpperName() << "Dependent() const;\n";
383
384 OS << " unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";
385
386 OS << " bool is" << getUpperName() << "Expr() const {\n";
387 OS << " return is" << getLowerName() << "Expr;\n";
388 OS << " }\n";
389
390 OS << " Expr *get" << getUpperName() << "Expr() const {\n";
391 OS << " assert(is" << getLowerName() << "Expr);\n";
392 OS << " return " << getLowerName() << "Expr;\n";
393 OS << " }\n";
394
395 OS << " TypeSourceInfo *get" << getUpperName() << "Type() const {\n";
396 OS << " assert(!is" << getLowerName() << "Expr);\n";
397 OS << " return " << getLowerName() << "Type;\n";
398 OS << " }";
399 }
writeAccessorDefinitions(raw_ostream & OS) const400 void writeAccessorDefinitions(raw_ostream &OS) const override {
401 OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
402 << "Dependent() const {\n";
403 OS << " if (is" << getLowerName() << "Expr)\n";
404 OS << " return " << getLowerName() << "Expr && (" << getLowerName()
405 << "Expr->isValueDependent() || " << getLowerName()
406 << "Expr->isTypeDependent());\n";
407 OS << " else\n";
408 OS << " return " << getLowerName()
409 << "Type->getType()->isDependentType();\n";
410 OS << "}\n";
411
412 // FIXME: Do not do the calculation here
413 // FIXME: Handle types correctly
414 // A null pointer means maximum alignment
415 // FIXME: Load the platform-specific maximum alignment, rather than
416 // 16, the x86 max.
417 OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName()
418 << "(ASTContext &Ctx) const {\n";
419 OS << " assert(!is" << getUpperName() << "Dependent());\n";
420 OS << " if (is" << getLowerName() << "Expr)\n";
421 OS << " return (" << getLowerName() << "Expr ? " << getLowerName()
422 << "Expr->EvaluateKnownConstInt(Ctx).getZExtValue() : 16)"
423 << "* Ctx.getCharWidth();\n";
424 OS << " else\n";
425 OS << " return 0; // FIXME\n";
426 OS << "}\n";
427 }
writeCloneArgs(raw_ostream & OS) const428 void writeCloneArgs(raw_ostream &OS) const override {
429 OS << "is" << getLowerName() << "Expr, is" << getLowerName()
430 << "Expr ? static_cast<void*>(" << getLowerName()
431 << "Expr) : " << getLowerName()
432 << "Type";
433 }
writeTemplateInstantiationArgs(raw_ostream & OS) const434 void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
435 // FIXME: move the definition in Sema::InstantiateAttrs to here.
436 // In the meantime, aligned attributes are cloned.
437 }
writeCtorBody(raw_ostream & OS) const438 void writeCtorBody(raw_ostream &OS) const override {
439 OS << " if (is" << getLowerName() << "Expr)\n";
440 OS << " " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
441 << getUpperName() << ");\n";
442 OS << " else\n";
443 OS << " " << getLowerName()
444 << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
445 << ");";
446 }
writeCtorInitializers(raw_ostream & OS) const447 void writeCtorInitializers(raw_ostream &OS) const override {
448 OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
449 }
writeCtorDefaultInitializers(raw_ostream & OS) const450 void writeCtorDefaultInitializers(raw_ostream &OS) const override {
451 OS << "is" << getLowerName() << "Expr(false)";
452 }
writeCtorParameters(raw_ostream & OS) const453 void writeCtorParameters(raw_ostream &OS) const override {
454 OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
455 }
writeImplicitCtorArgs(raw_ostream & OS) const456 void writeImplicitCtorArgs(raw_ostream &OS) const override {
457 OS << "Is" << getUpperName() << "Expr, " << getUpperName();
458 }
writeDeclarations(raw_ostream & OS) const459 void writeDeclarations(raw_ostream &OS) const override {
460 OS << "bool is" << getLowerName() << "Expr;\n";
461 OS << "union {\n";
462 OS << "Expr *" << getLowerName() << "Expr;\n";
463 OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
464 OS << "};";
465 }
writePCHReadArgs(raw_ostream & OS) const466 void writePCHReadArgs(raw_ostream &OS) const override {
467 OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
468 }
writePCHReadDecls(raw_ostream & OS) const469 void writePCHReadDecls(raw_ostream &OS) const override {
470 OS << " bool is" << getLowerName() << "Expr = Record[Idx++];\n";
471 OS << " void *" << getLowerName() << "Ptr;\n";
472 OS << " if (is" << getLowerName() << "Expr)\n";
473 OS << " " << getLowerName() << "Ptr = ReadExpr(F);\n";
474 OS << " else\n";
475 OS << " " << getLowerName()
476 << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n";
477 }
writePCHWrite(raw_ostream & OS) const478 void writePCHWrite(raw_ostream &OS) const override {
479 OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n";
480 OS << " if (SA->is" << getUpperName() << "Expr())\n";
481 OS << " AddStmt(SA->get" << getUpperName() << "Expr());\n";
482 OS << " else\n";
483 OS << " AddTypeSourceInfo(SA->get" << getUpperName()
484 << "Type(), Record);\n";
485 }
writeValue(raw_ostream & OS) const486 void writeValue(raw_ostream &OS) const override {
487 OS << "\";\n";
488 OS << " assert(is" << getLowerName() << "Expr && " << getLowerName()
489 << "Expr != nullptr);\n";
490 OS << " " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n";
491 OS << " OS << \"";
492 }
writeDump(raw_ostream & OS) const493 void writeDump(raw_ostream &OS) const override {
494 }
writeDumpChildren(raw_ostream & OS) const495 void writeDumpChildren(raw_ostream &OS) const override {
496 OS << " if (SA->is" << getUpperName() << "Expr()) {\n";
497 OS << " lastChild();\n";
498 OS << " dumpStmt(SA->get" << getUpperName() << "Expr());\n";
499 OS << " } else\n";
500 OS << " dumpType(SA->get" << getUpperName()
501 << "Type()->getType());\n";
502 }
writeHasChildren(raw_ostream & OS) const503 void writeHasChildren(raw_ostream &OS) const override {
504 OS << "SA->is" << getUpperName() << "Expr()";
505 }
506 };
507
508 class VariadicArgument : public Argument {
509 std::string Type, ArgName, ArgSizeName, RangeName;
510
511 public:
VariadicArgument(const Record & Arg,StringRef Attr,std::string T)512 VariadicArgument(const Record &Arg, StringRef Attr, std::string T)
513 : Argument(Arg, Attr), Type(T), ArgName(getLowerName().str() + "_"),
514 ArgSizeName(ArgName + "Size"), RangeName(getLowerName()) {}
515
getType() const516 std::string getType() const { return Type; }
517
writeAccessors(raw_ostream & OS) const518 void writeAccessors(raw_ostream &OS) const override {
519 std::string IteratorType = getLowerName().str() + "_iterator";
520 std::string BeginFn = getLowerName().str() + "_begin()";
521 std::string EndFn = getLowerName().str() + "_end()";
522
523 OS << " typedef " << Type << "* " << IteratorType << ";\n";
524 OS << " " << IteratorType << " " << BeginFn << " const {"
525 << " return " << ArgName << "; }\n";
526 OS << " " << IteratorType << " " << EndFn << " const {"
527 << " return " << ArgName << " + " << ArgSizeName << "; }\n";
528 OS << " unsigned " << getLowerName() << "_size() const {"
529 << " return " << ArgSizeName << "; }\n";
530 OS << " llvm::iterator_range<" << IteratorType << "> " << RangeName
531 << "() const { return llvm::make_range(" << BeginFn << ", " << EndFn
532 << "); }\n";
533 }
writeCloneArgs(raw_ostream & OS) const534 void writeCloneArgs(raw_ostream &OS) const override {
535 OS << ArgName << ", " << ArgSizeName;
536 }
writeTemplateInstantiationArgs(raw_ostream & OS) const537 void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
538 // This isn't elegant, but we have to go through public methods...
539 OS << "A->" << getLowerName() << "_begin(), "
540 << "A->" << getLowerName() << "_size()";
541 }
writeCtorBody(raw_ostream & OS) const542 void writeCtorBody(raw_ostream &OS) const override {
543 OS << " std::copy(" << getUpperName() << ", " << getUpperName()
544 << " + " << ArgSizeName << ", " << ArgName << ");";
545 }
writeCtorInitializers(raw_ostream & OS) const546 void writeCtorInitializers(raw_ostream &OS) const override {
547 OS << ArgSizeName << "(" << getUpperName() << "Size), "
548 << ArgName << "(new (Ctx, 16) " << getType() << "["
549 << ArgSizeName << "])";
550 }
writeCtorDefaultInitializers(raw_ostream & OS) const551 void writeCtorDefaultInitializers(raw_ostream &OS) const override {
552 OS << ArgSizeName << "(0), " << ArgName << "(nullptr)";
553 }
writeCtorParameters(raw_ostream & OS) const554 void writeCtorParameters(raw_ostream &OS) const override {
555 OS << getType() << " *" << getUpperName() << ", unsigned "
556 << getUpperName() << "Size";
557 }
writeImplicitCtorArgs(raw_ostream & OS) const558 void writeImplicitCtorArgs(raw_ostream &OS) const override {
559 OS << getUpperName() << ", " << getUpperName() << "Size";
560 }
writeDeclarations(raw_ostream & OS) const561 void writeDeclarations(raw_ostream &OS) const override {
562 OS << " unsigned " << ArgSizeName << ";\n";
563 OS << " " << getType() << " *" << ArgName << ";";
564 }
writePCHReadDecls(raw_ostream & OS) const565 void writePCHReadDecls(raw_ostream &OS) const override {
566 OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n";
567 OS << " SmallVector<" << Type << ", 4> " << getLowerName()
568 << ";\n";
569 OS << " " << getLowerName() << ".reserve(" << getLowerName()
570 << "Size);\n";
571 OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
572
573 std::string read = ReadPCHRecord(Type);
574 OS << " " << getLowerName() << ".push_back(" << read << ");\n";
575 }
writePCHReadArgs(raw_ostream & OS) const576 void writePCHReadArgs(raw_ostream &OS) const override {
577 OS << getLowerName() << ".data(), " << getLowerName() << "Size";
578 }
writePCHWrite(raw_ostream & OS) const579 void writePCHWrite(raw_ostream &OS) const override {
580 OS << " Record.push_back(SA->" << getLowerName() << "_size());\n";
581 OS << " for (auto &Val : SA->" << RangeName << "())\n";
582 OS << " " << WritePCHRecord(Type, "Val");
583 }
writeValue(raw_ostream & OS) const584 void writeValue(raw_ostream &OS) const override {
585 OS << "\";\n";
586 OS << " bool isFirst = true;\n"
587 << " for (const auto &Val : " << RangeName << "()) {\n"
588 << " if (isFirst) isFirst = false;\n"
589 << " else OS << \", \";\n"
590 << " OS << Val;\n"
591 << " }\n";
592 OS << " OS << \"";
593 }
writeDump(raw_ostream & OS) const594 void writeDump(raw_ostream &OS) const override {
595 OS << " for (const auto &Val : SA->" << RangeName << "())\n";
596 OS << " OS << \" \" << Val;\n";
597 }
598 };
599
600 // Unique the enums, but maintain the original declaration ordering.
601 std::vector<std::string>
uniqueEnumsInOrder(const std::vector<std::string> & enums)602 uniqueEnumsInOrder(const std::vector<std::string> &enums) {
603 std::vector<std::string> uniques;
604 std::set<std::string> unique_set(enums.begin(), enums.end());
605 for (const auto &i : enums) {
606 std::set<std::string>::iterator set_i = unique_set.find(i);
607 if (set_i != unique_set.end()) {
608 uniques.push_back(i);
609 unique_set.erase(set_i);
610 }
611 }
612 return uniques;
613 }
614
615 class EnumArgument : public Argument {
616 std::string type;
617 std::vector<std::string> values, enums, uniques;
618 public:
EnumArgument(const Record & Arg,StringRef Attr)619 EnumArgument(const Record &Arg, StringRef Attr)
620 : Argument(Arg, Attr), type(Arg.getValueAsString("Type")),
621 values(Arg.getValueAsListOfStrings("Values")),
622 enums(Arg.getValueAsListOfStrings("Enums")),
623 uniques(uniqueEnumsInOrder(enums))
624 {
625 // FIXME: Emit a proper error
626 assert(!uniques.empty());
627 }
628
isEnumArg() const629 bool isEnumArg() const override { return true; }
630
writeAccessors(raw_ostream & OS) const631 void writeAccessors(raw_ostream &OS) const override {
632 OS << " " << type << " get" << getUpperName() << "() const {\n";
633 OS << " return " << getLowerName() << ";\n";
634 OS << " }";
635 }
writeCloneArgs(raw_ostream & OS) const636 void writeCloneArgs(raw_ostream &OS) const override {
637 OS << getLowerName();
638 }
writeTemplateInstantiationArgs(raw_ostream & OS) const639 void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
640 OS << "A->get" << getUpperName() << "()";
641 }
writeCtorInitializers(raw_ostream & OS) const642 void writeCtorInitializers(raw_ostream &OS) const override {
643 OS << getLowerName() << "(" << getUpperName() << ")";
644 }
writeCtorDefaultInitializers(raw_ostream & OS) const645 void writeCtorDefaultInitializers(raw_ostream &OS) const override {
646 OS << getLowerName() << "(" << type << "(0))";
647 }
writeCtorParameters(raw_ostream & OS) const648 void writeCtorParameters(raw_ostream &OS) const override {
649 OS << type << " " << getUpperName();
650 }
writeDeclarations(raw_ostream & OS) const651 void writeDeclarations(raw_ostream &OS) const override {
652 std::vector<std::string>::const_iterator i = uniques.begin(),
653 e = uniques.end();
654 // The last one needs to not have a comma.
655 --e;
656
657 OS << "public:\n";
658 OS << " enum " << type << " {\n";
659 for (; i != e; ++i)
660 OS << " " << *i << ",\n";
661 OS << " " << *e << "\n";
662 OS << " };\n";
663 OS << "private:\n";
664 OS << " " << type << " " << getLowerName() << ";";
665 }
writePCHReadDecls(raw_ostream & OS) const666 void writePCHReadDecls(raw_ostream &OS) const override {
667 OS << " " << getAttrName() << "Attr::" << type << " " << getLowerName()
668 << "(static_cast<" << getAttrName() << "Attr::" << type
669 << ">(Record[Idx++]));\n";
670 }
writePCHReadArgs(raw_ostream & OS) const671 void writePCHReadArgs(raw_ostream &OS) const override {
672 OS << getLowerName();
673 }
writePCHWrite(raw_ostream & OS) const674 void writePCHWrite(raw_ostream &OS) const override {
675 OS << "Record.push_back(SA->get" << getUpperName() << "());\n";
676 }
writeValue(raw_ostream & OS) const677 void writeValue(raw_ostream &OS) const override {
678 OS << "\" << get" << getUpperName() << "() << \"";
679 }
writeDump(raw_ostream & OS) const680 void writeDump(raw_ostream &OS) const override {
681 OS << " switch(SA->get" << getUpperName() << "()) {\n";
682 for (const auto &I : uniques) {
683 OS << " case " << getAttrName() << "Attr::" << I << ":\n";
684 OS << " OS << \" " << I << "\";\n";
685 OS << " break;\n";
686 }
687 OS << " }\n";
688 }
689
writeConversion(raw_ostream & OS) const690 void writeConversion(raw_ostream &OS) const {
691 OS << " static bool ConvertStrTo" << type << "(StringRef Val, ";
692 OS << type << " &Out) {\n";
693 OS << " Optional<" << type << "> R = llvm::StringSwitch<Optional<";
694 OS << type << ">>(Val)\n";
695 for (size_t I = 0; I < enums.size(); ++I) {
696 OS << " .Case(\"" << values[I] << "\", ";
697 OS << getAttrName() << "Attr::" << enums[I] << ")\n";
698 }
699 OS << " .Default(Optional<" << type << ">());\n";
700 OS << " if (R) {\n";
701 OS << " Out = *R;\n return true;\n }\n";
702 OS << " return false;\n";
703 OS << " }\n";
704 }
705 };
706
707 class VariadicEnumArgument: public VariadicArgument {
708 std::string type, QualifiedTypeName;
709 std::vector<std::string> values, enums, uniques;
710 public:
VariadicEnumArgument(const Record & Arg,StringRef Attr)711 VariadicEnumArgument(const Record &Arg, StringRef Attr)
712 : VariadicArgument(Arg, Attr, Arg.getValueAsString("Type")),
713 type(Arg.getValueAsString("Type")),
714 values(Arg.getValueAsListOfStrings("Values")),
715 enums(Arg.getValueAsListOfStrings("Enums")),
716 uniques(uniqueEnumsInOrder(enums))
717 {
718 QualifiedTypeName = getAttrName().str() + "Attr::" + type;
719
720 // FIXME: Emit a proper error
721 assert(!uniques.empty());
722 }
723
isVariadicEnumArg() const724 bool isVariadicEnumArg() const override { return true; }
725
writeDeclarations(raw_ostream & OS) const726 void writeDeclarations(raw_ostream &OS) const override {
727 std::vector<std::string>::const_iterator i = uniques.begin(),
728 e = uniques.end();
729 // The last one needs to not have a comma.
730 --e;
731
732 OS << "public:\n";
733 OS << " enum " << type << " {\n";
734 for (; i != e; ++i)
735 OS << " " << *i << ",\n";
736 OS << " " << *e << "\n";
737 OS << " };\n";
738 OS << "private:\n";
739
740 VariadicArgument::writeDeclarations(OS);
741 }
writeDump(raw_ostream & OS) const742 void writeDump(raw_ostream &OS) const override {
743 OS << " for (" << getAttrName() << "Attr::" << getLowerName()
744 << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
745 << getLowerName() << "_end(); I != E; ++I) {\n";
746 OS << " switch(*I) {\n";
747 for (const auto &UI : uniques) {
748 OS << " case " << getAttrName() << "Attr::" << UI << ":\n";
749 OS << " OS << \" " << UI << "\";\n";
750 OS << " break;\n";
751 }
752 OS << " }\n";
753 OS << " }\n";
754 }
writePCHReadDecls(raw_ostream & OS) const755 void writePCHReadDecls(raw_ostream &OS) const override {
756 OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n";
757 OS << " SmallVector<" << QualifiedTypeName << ", 4> " << getLowerName()
758 << ";\n";
759 OS << " " << getLowerName() << ".reserve(" << getLowerName()
760 << "Size);\n";
761 OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
762 OS << " " << getLowerName() << ".push_back(" << "static_cast<"
763 << QualifiedTypeName << ">(Record[Idx++]));\n";
764 }
writePCHWrite(raw_ostream & OS) const765 void writePCHWrite(raw_ostream &OS) const override {
766 OS << " Record.push_back(SA->" << getLowerName() << "_size());\n";
767 OS << " for (" << getAttrName() << "Attr::" << getLowerName()
768 << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
769 << getLowerName() << "_end(); i != e; ++i)\n";
770 OS << " " << WritePCHRecord(QualifiedTypeName, "(*i)");
771 }
writeConversion(raw_ostream & OS) const772 void writeConversion(raw_ostream &OS) const {
773 OS << " static bool ConvertStrTo" << type << "(StringRef Val, ";
774 OS << type << " &Out) {\n";
775 OS << " Optional<" << type << "> R = llvm::StringSwitch<Optional<";
776 OS << type << ">>(Val)\n";
777 for (size_t I = 0; I < enums.size(); ++I) {
778 OS << " .Case(\"" << values[I] << "\", ";
779 OS << getAttrName() << "Attr::" << enums[I] << ")\n";
780 }
781 OS << " .Default(Optional<" << type << ">());\n";
782 OS << " if (R) {\n";
783 OS << " Out = *R;\n return true;\n }\n";
784 OS << " return false;\n";
785 OS << " }\n";
786 }
787 };
788
789 class VersionArgument : public Argument {
790 public:
VersionArgument(const Record & Arg,StringRef Attr)791 VersionArgument(const Record &Arg, StringRef Attr)
792 : Argument(Arg, Attr)
793 {}
794
writeAccessors(raw_ostream & OS) const795 void writeAccessors(raw_ostream &OS) const override {
796 OS << " VersionTuple get" << getUpperName() << "() const {\n";
797 OS << " return " << getLowerName() << ";\n";
798 OS << " }\n";
799 OS << " void set" << getUpperName()
800 << "(ASTContext &C, VersionTuple V) {\n";
801 OS << " " << getLowerName() << " = V;\n";
802 OS << " }";
803 }
writeCloneArgs(raw_ostream & OS) const804 void writeCloneArgs(raw_ostream &OS) const override {
805 OS << "get" << getUpperName() << "()";
806 }
writeTemplateInstantiationArgs(raw_ostream & OS) const807 void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
808 OS << "A->get" << getUpperName() << "()";
809 }
writeCtorInitializers(raw_ostream & OS) const810 void writeCtorInitializers(raw_ostream &OS) const override {
811 OS << getLowerName() << "(" << getUpperName() << ")";
812 }
writeCtorDefaultInitializers(raw_ostream & OS) const813 void writeCtorDefaultInitializers(raw_ostream &OS) const override {
814 OS << getLowerName() << "()";
815 }
writeCtorParameters(raw_ostream & OS) const816 void writeCtorParameters(raw_ostream &OS) const override {
817 OS << "VersionTuple " << getUpperName();
818 }
writeDeclarations(raw_ostream & OS) const819 void writeDeclarations(raw_ostream &OS) const override {
820 OS << "VersionTuple " << getLowerName() << ";\n";
821 }
writePCHReadDecls(raw_ostream & OS) const822 void writePCHReadDecls(raw_ostream &OS) const override {
823 OS << " VersionTuple " << getLowerName()
824 << "= ReadVersionTuple(Record, Idx);\n";
825 }
writePCHReadArgs(raw_ostream & OS) const826 void writePCHReadArgs(raw_ostream &OS) const override {
827 OS << getLowerName();
828 }
writePCHWrite(raw_ostream & OS) const829 void writePCHWrite(raw_ostream &OS) const override {
830 OS << " AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n";
831 }
writeValue(raw_ostream & OS) const832 void writeValue(raw_ostream &OS) const override {
833 OS << getLowerName() << "=\" << get" << getUpperName() << "() << \"";
834 }
writeDump(raw_ostream & OS) const835 void writeDump(raw_ostream &OS) const override {
836 OS << " OS << \" \" << SA->get" << getUpperName() << "();\n";
837 }
838 };
839
840 class ExprArgument : public SimpleArgument {
841 public:
ExprArgument(const Record & Arg,StringRef Attr)842 ExprArgument(const Record &Arg, StringRef Attr)
843 : SimpleArgument(Arg, Attr, "Expr *")
844 {}
845
writeASTVisitorTraversal(raw_ostream & OS) const846 void writeASTVisitorTraversal(raw_ostream &OS) const override {
847 OS << " if (!"
848 << "getDerived().TraverseStmt(A->get" << getUpperName() << "()))\n";
849 OS << " return false;\n";
850 }
851
writeTemplateInstantiationArgs(raw_ostream & OS) const852 void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
853 OS << "tempInst" << getUpperName();
854 }
855
writeTemplateInstantiation(raw_ostream & OS) const856 void writeTemplateInstantiation(raw_ostream &OS) const override {
857 OS << " " << getType() << " tempInst" << getUpperName() << ";\n";
858 OS << " {\n";
859 OS << " EnterExpressionEvaluationContext "
860 << "Unevaluated(S, Sema::Unevaluated);\n";
861 OS << " ExprResult " << "Result = S.SubstExpr("
862 << "A->get" << getUpperName() << "(), TemplateArgs);\n";
863 OS << " tempInst" << getUpperName() << " = "
864 << "Result.getAs<Expr>();\n";
865 OS << " }\n";
866 }
867
writeDump(raw_ostream & OS) const868 void writeDump(raw_ostream &OS) const override {}
869
writeDumpChildren(raw_ostream & OS) const870 void writeDumpChildren(raw_ostream &OS) const override {
871 OS << " lastChild();\n";
872 OS << " dumpStmt(SA->get" << getUpperName() << "());\n";
873 }
writeHasChildren(raw_ostream & OS) const874 void writeHasChildren(raw_ostream &OS) const override { OS << "true"; }
875 };
876
877 class VariadicExprArgument : public VariadicArgument {
878 public:
VariadicExprArgument(const Record & Arg,StringRef Attr)879 VariadicExprArgument(const Record &Arg, StringRef Attr)
880 : VariadicArgument(Arg, Attr, "Expr *")
881 {}
882
writeASTVisitorTraversal(raw_ostream & OS) const883 void writeASTVisitorTraversal(raw_ostream &OS) const override {
884 OS << " {\n";
885 OS << " " << getType() << " *I = A->" << getLowerName()
886 << "_begin();\n";
887 OS << " " << getType() << " *E = A->" << getLowerName()
888 << "_end();\n";
889 OS << " for (; I != E; ++I) {\n";
890 OS << " if (!getDerived().TraverseStmt(*I))\n";
891 OS << " return false;\n";
892 OS << " }\n";
893 OS << " }\n";
894 }
895
writeTemplateInstantiationArgs(raw_ostream & OS) const896 void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
897 OS << "tempInst" << getUpperName() << ", "
898 << "A->" << getLowerName() << "_size()";
899 }
900
writeTemplateInstantiation(raw_ostream & OS) const901 void writeTemplateInstantiation(raw_ostream &OS) const override {
902 OS << " " << getType() << " *tempInst" << getUpperName()
903 << " = new (C, 16) " << getType()
904 << "[A->" << getLowerName() << "_size()];\n";
905 OS << " {\n";
906 OS << " EnterExpressionEvaluationContext "
907 << "Unevaluated(S, Sema::Unevaluated);\n";
908 OS << " " << getType() << " *TI = tempInst" << getUpperName()
909 << ";\n";
910 OS << " " << getType() << " *I = A->" << getLowerName()
911 << "_begin();\n";
912 OS << " " << getType() << " *E = A->" << getLowerName()
913 << "_end();\n";
914 OS << " for (; I != E; ++I, ++TI) {\n";
915 OS << " ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n";
916 OS << " *TI = Result.getAs<Expr>();\n";
917 OS << " }\n";
918 OS << " }\n";
919 }
920
writeDump(raw_ostream & OS) const921 void writeDump(raw_ostream &OS) const override {}
922
writeDumpChildren(raw_ostream & OS) const923 void writeDumpChildren(raw_ostream &OS) const override {
924 OS << " for (" << getAttrName() << "Attr::" << getLowerName()
925 << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
926 << getLowerName() << "_end(); I != E; ++I) {\n";
927 OS << " if (I + 1 == E)\n";
928 OS << " lastChild();\n";
929 OS << " dumpStmt(*I);\n";
930 OS << " }\n";
931 }
932
writeHasChildren(raw_ostream & OS) const933 void writeHasChildren(raw_ostream &OS) const override {
934 OS << "SA->" << getLowerName() << "_begin() != "
935 << "SA->" << getLowerName() << "_end()";
936 }
937 };
938
939 class TypeArgument : public SimpleArgument {
940 public:
TypeArgument(const Record & Arg,StringRef Attr)941 TypeArgument(const Record &Arg, StringRef Attr)
942 : SimpleArgument(Arg, Attr, "TypeSourceInfo *")
943 {}
944
writeAccessors(raw_ostream & OS) const945 void writeAccessors(raw_ostream &OS) const override {
946 OS << " QualType get" << getUpperName() << "() const {\n";
947 OS << " return " << getLowerName() << "->getType();\n";
948 OS << " }";
949 OS << " " << getType() << " get" << getUpperName() << "Loc() const {\n";
950 OS << " return " << getLowerName() << ";\n";
951 OS << " }";
952 }
writeTemplateInstantiationArgs(raw_ostream & OS) const953 void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
954 OS << "A->get" << getUpperName() << "Loc()";
955 }
writePCHWrite(raw_ostream & OS) const956 void writePCHWrite(raw_ostream &OS) const override {
957 OS << " " << WritePCHRecord(
958 getType(), "SA->get" + std::string(getUpperName()) + "Loc()");
959 }
960 };
961 }
962
963 static std::unique_ptr<Argument>
createArgument(const Record & Arg,StringRef Attr,const Record * Search=nullptr)964 createArgument(const Record &Arg, StringRef Attr,
965 const Record *Search = nullptr) {
966 if (!Search)
967 Search = &Arg;
968
969 Argument *Ptr = nullptr;
970 llvm::StringRef ArgName = Search->getName();
971
972 if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr);
973 else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr);
974 else if (ArgName == "ExprArgument") Ptr = new ExprArgument(Arg, Attr);
975 else if (ArgName == "FunctionArgument")
976 Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *");
977 else if (ArgName == "IdentifierArgument")
978 Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
979 else if (ArgName == "DefaultBoolArgument")
980 Ptr = new DefaultSimpleArgument(Arg, Attr, "bool",
981 Arg.getValueAsBit("Default"));
982 else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr,
983 "bool");
984 else if (ArgName == "DefaultIntArgument")
985 Ptr = new DefaultSimpleArgument(Arg, Attr, "int",
986 Arg.getValueAsInt("Default"));
987 else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
988 else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
989 else if (ArgName == "TypeArgument") Ptr = new TypeArgument(Arg, Attr);
990 else if (ArgName == "UnsignedArgument")
991 Ptr = new SimpleArgument(Arg, Attr, "unsigned");
992 else if (ArgName == "VariadicUnsignedArgument")
993 Ptr = new VariadicArgument(Arg, Attr, "unsigned");
994 else if (ArgName == "VariadicEnumArgument")
995 Ptr = new VariadicEnumArgument(Arg, Attr);
996 else if (ArgName == "VariadicExprArgument")
997 Ptr = new VariadicExprArgument(Arg, Attr);
998 else if (ArgName == "VersionArgument")
999 Ptr = new VersionArgument(Arg, Attr);
1000
1001 if (!Ptr) {
1002 // Search in reverse order so that the most-derived type is handled first.
1003 std::vector<Record*> Bases = Search->getSuperClasses();
1004 for (const auto *Base : llvm::make_range(Bases.rbegin(), Bases.rend())) {
1005 Ptr = createArgument(Arg, Attr, Base).release();
1006 if (Ptr)
1007 break;
1008 }
1009 }
1010
1011 if (Ptr && Arg.getValueAsBit("Optional"))
1012 Ptr->setOptional(true);
1013
1014 return std::unique_ptr<Argument>(Ptr);
1015 }
1016
writeAvailabilityValue(raw_ostream & OS)1017 static void writeAvailabilityValue(raw_ostream &OS) {
1018 OS << "\" << getPlatform()->getName();\n"
1019 << " if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n"
1020 << " if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n"
1021 << " if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n"
1022 << " if (getUnavailable()) OS << \", unavailable\";\n"
1023 << " OS << \"";
1024 }
1025
writeGetSpellingFunction(Record & R,raw_ostream & OS)1026 static void writeGetSpellingFunction(Record &R, raw_ostream &OS) {
1027 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
1028
1029 OS << "const char *" << R.getName() << "Attr::getSpelling() const {\n";
1030 if (Spellings.empty()) {
1031 OS << " return \"(No spelling)\";\n}\n\n";
1032 return;
1033 }
1034
1035 OS << " switch (SpellingListIndex) {\n"
1036 " default:\n"
1037 " llvm_unreachable(\"Unknown attribute spelling!\");\n"
1038 " return \"(No spelling)\";\n";
1039
1040 for (unsigned I = 0; I < Spellings.size(); ++I)
1041 OS << " case " << I << ":\n"
1042 " return \"" << Spellings[I].name() << "\";\n";
1043 // End of the switch statement.
1044 OS << " }\n";
1045 // End of the getSpelling function.
1046 OS << "}\n\n";
1047 }
1048
1049 static void
writePrettyPrintFunction(Record & R,const std::vector<std::unique_ptr<Argument>> & Args,raw_ostream & OS)1050 writePrettyPrintFunction(Record &R,
1051 const std::vector<std::unique_ptr<Argument>> &Args,
1052 raw_ostream &OS) {
1053 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
1054
1055 OS << "void " << R.getName() << "Attr::printPretty("
1056 << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n";
1057
1058 if (Spellings.empty()) {
1059 OS << "}\n\n";
1060 return;
1061 }
1062
1063 OS <<
1064 " switch (SpellingListIndex) {\n"
1065 " default:\n"
1066 " llvm_unreachable(\"Unknown attribute spelling!\");\n"
1067 " break;\n";
1068
1069 for (unsigned I = 0; I < Spellings.size(); ++ I) {
1070 llvm::SmallString<16> Prefix;
1071 llvm::SmallString<8> Suffix;
1072 // The actual spelling of the name and namespace (if applicable)
1073 // of an attribute without considering prefix and suffix.
1074 llvm::SmallString<64> Spelling;
1075 std::string Name = Spellings[I].name();
1076 std::string Variety = Spellings[I].variety();
1077
1078 if (Variety == "GNU") {
1079 Prefix = " __attribute__((";
1080 Suffix = "))";
1081 } else if (Variety == "CXX11") {
1082 Prefix = " [[";
1083 Suffix = "]]";
1084 std::string Namespace = Spellings[I].nameSpace();
1085 if (!Namespace.empty()) {
1086 Spelling += Namespace;
1087 Spelling += "::";
1088 }
1089 } else if (Variety == "Declspec") {
1090 Prefix = " __declspec(";
1091 Suffix = ")";
1092 } else if (Variety == "Keyword") {
1093 Prefix = " ";
1094 Suffix = "";
1095 } else if (Variety == "Pragma") {
1096 Prefix = "#pragma ";
1097 Suffix = "\n";
1098 std::string Namespace = Spellings[I].nameSpace();
1099 if (!Namespace.empty()) {
1100 Spelling += Namespace;
1101 Spelling += " ";
1102 }
1103 } else {
1104 llvm_unreachable("Unknown attribute syntax variety!");
1105 }
1106
1107 Spelling += Name;
1108
1109 OS <<
1110 " case " << I << " : {\n"
1111 " OS << \"" + Prefix.str() + Spelling.str();
1112
1113 if (Variety == "Pragma") {
1114 OS << " \";\n";
1115 OS << " printPrettyPragma(OS, Policy);\n";
1116 OS << " break;\n";
1117 OS << " }\n";
1118 continue;
1119 }
1120
1121 if (!Args.empty())
1122 OS << "(";
1123 if (Spelling == "availability") {
1124 writeAvailabilityValue(OS);
1125 } else {
1126 for (auto I = Args.begin(), E = Args.end(); I != E; ++ I) {
1127 if (I != Args.begin()) OS << ", ";
1128 (*I)->writeValue(OS);
1129 }
1130 }
1131
1132 if (!Args.empty())
1133 OS << ")";
1134 OS << Suffix.str() + "\";\n";
1135
1136 OS <<
1137 " break;\n"
1138 " }\n";
1139 }
1140
1141 // End of the switch statement.
1142 OS << "}\n";
1143 // End of the print function.
1144 OS << "}\n\n";
1145 }
1146
1147 /// \brief Return the index of a spelling in a spelling list.
1148 static unsigned
getSpellingListIndex(const std::vector<FlattenedSpelling> & SpellingList,const FlattenedSpelling & Spelling)1149 getSpellingListIndex(const std::vector<FlattenedSpelling> &SpellingList,
1150 const FlattenedSpelling &Spelling) {
1151 assert(SpellingList.size() && "Spelling list is empty!");
1152
1153 for (unsigned Index = 0; Index < SpellingList.size(); ++Index) {
1154 const FlattenedSpelling &S = SpellingList[Index];
1155 if (S.variety() != Spelling.variety())
1156 continue;
1157 if (S.nameSpace() != Spelling.nameSpace())
1158 continue;
1159 if (S.name() != Spelling.name())
1160 continue;
1161
1162 return Index;
1163 }
1164
1165 llvm_unreachable("Unknown spelling!");
1166 }
1167
writeAttrAccessorDefinition(const Record & R,raw_ostream & OS)1168 static void writeAttrAccessorDefinition(const Record &R, raw_ostream &OS) {
1169 std::vector<Record*> Accessors = R.getValueAsListOfDefs("Accessors");
1170 for (const auto *Accessor : Accessors) {
1171 std::string Name = Accessor->getValueAsString("Name");
1172 std::vector<FlattenedSpelling> Spellings =
1173 GetFlattenedSpellings(*Accessor);
1174 std::vector<FlattenedSpelling> SpellingList = GetFlattenedSpellings(R);
1175 assert(SpellingList.size() &&
1176 "Attribute with empty spelling list can't have accessors!");
1177
1178 OS << " bool " << Name << "() const { return SpellingListIndex == ";
1179 for (unsigned Index = 0; Index < Spellings.size(); ++Index) {
1180 OS << getSpellingListIndex(SpellingList, Spellings[Index]);
1181 if (Index != Spellings.size() -1)
1182 OS << " ||\n SpellingListIndex == ";
1183 else
1184 OS << "; }\n";
1185 }
1186 }
1187 }
1188
1189 static bool
SpellingNamesAreCommon(const std::vector<FlattenedSpelling> & Spellings)1190 SpellingNamesAreCommon(const std::vector<FlattenedSpelling>& Spellings) {
1191 assert(!Spellings.empty() && "An empty list of spellings was provided");
1192 std::string FirstName = NormalizeNameForSpellingComparison(
1193 Spellings.front().name());
1194 for (const auto &Spelling :
1195 llvm::make_range(std::next(Spellings.begin()), Spellings.end())) {
1196 std::string Name = NormalizeNameForSpellingComparison(Spelling.name());
1197 if (Name != FirstName)
1198 return false;
1199 }
1200 return true;
1201 }
1202
1203 typedef std::map<unsigned, std::string> SemanticSpellingMap;
1204 static std::string
CreateSemanticSpellings(const std::vector<FlattenedSpelling> & Spellings,SemanticSpellingMap & Map)1205 CreateSemanticSpellings(const std::vector<FlattenedSpelling> &Spellings,
1206 SemanticSpellingMap &Map) {
1207 // The enumerants are automatically generated based on the variety,
1208 // namespace (if present) and name for each attribute spelling. However,
1209 // care is taken to avoid trampling on the reserved namespace due to
1210 // underscores.
1211 std::string Ret(" enum Spelling {\n");
1212 std::set<std::string> Uniques;
1213 unsigned Idx = 0;
1214 for (auto I = Spellings.begin(), E = Spellings.end(); I != E; ++I, ++Idx) {
1215 const FlattenedSpelling &S = *I;
1216 std::string Variety = S.variety();
1217 std::string Spelling = S.name();
1218 std::string Namespace = S.nameSpace();
1219 std::string EnumName = "";
1220
1221 EnumName += (Variety + "_");
1222 if (!Namespace.empty())
1223 EnumName += (NormalizeNameForSpellingComparison(Namespace).str() +
1224 "_");
1225 EnumName += NormalizeNameForSpellingComparison(Spelling);
1226
1227 // Even if the name is not unique, this spelling index corresponds to a
1228 // particular enumerant name that we've calculated.
1229 Map[Idx] = EnumName;
1230
1231 // Since we have been stripping underscores to avoid trampling on the
1232 // reserved namespace, we may have inadvertently created duplicate
1233 // enumerant names. These duplicates are not considered part of the
1234 // semantic spelling, and can be elided.
1235 if (Uniques.find(EnumName) != Uniques.end())
1236 continue;
1237
1238 Uniques.insert(EnumName);
1239 if (I != Spellings.begin())
1240 Ret += ",\n";
1241 Ret += " " + EnumName;
1242 }
1243 Ret += "\n };\n\n";
1244 return Ret;
1245 }
1246
WriteSemanticSpellingSwitch(const std::string & VarName,const SemanticSpellingMap & Map,raw_ostream & OS)1247 void WriteSemanticSpellingSwitch(const std::string &VarName,
1248 const SemanticSpellingMap &Map,
1249 raw_ostream &OS) {
1250 OS << " switch (" << VarName << ") {\n default: "
1251 << "llvm_unreachable(\"Unknown spelling list index\");\n";
1252 for (const auto &I : Map)
1253 OS << " case " << I.first << ": return " << I.second << ";\n";
1254 OS << " }\n";
1255 }
1256
1257 // Emits the LateParsed property for attributes.
emitClangAttrLateParsedList(RecordKeeper & Records,raw_ostream & OS)1258 static void emitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) {
1259 OS << "#if defined(CLANG_ATTR_LATE_PARSED_LIST)\n";
1260 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1261
1262 for (const auto *Attr : Attrs) {
1263 bool LateParsed = Attr->getValueAsBit("LateParsed");
1264
1265 if (LateParsed) {
1266 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);
1267
1268 // FIXME: Handle non-GNU attributes
1269 for (const auto &I : Spellings) {
1270 if (I.variety() != "GNU")
1271 continue;
1272 OS << ".Case(\"" << I.name() << "\", " << LateParsed << ")\n";
1273 }
1274 }
1275 }
1276 OS << "#endif // CLANG_ATTR_LATE_PARSED_LIST\n\n";
1277 }
1278
1279 /// \brief Emits the first-argument-is-type property for attributes.
emitClangAttrTypeArgList(RecordKeeper & Records,raw_ostream & OS)1280 static void emitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
1281 OS << "#if defined(CLANG_ATTR_TYPE_ARG_LIST)\n";
1282 std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
1283
1284 for (const auto *Attr : Attrs) {
1285 // Determine whether the first argument is a type.
1286 std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
1287 if (Args.empty())
1288 continue;
1289
1290 if (Args[0]->getSuperClasses().back()->getName() != "TypeArgument")
1291 continue;
1292
1293 // All these spellings take a single type argument.
1294 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);
1295 std::set<std::string> Emitted;
1296 for (const auto &S : Spellings) {
1297 if (Emitted.insert(S.name()).second)
1298 OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
1299 }
1300 }
1301 OS << "#endif // CLANG_ATTR_TYPE_ARG_LIST\n\n";
1302 }
1303
1304 /// \brief Emits the parse-arguments-in-unevaluated-context property for
1305 /// attributes.
emitClangAttrArgContextList(RecordKeeper & Records,raw_ostream & OS)1306 static void emitClangAttrArgContextList(RecordKeeper &Records, raw_ostream &OS) {
1307 OS << "#if defined(CLANG_ATTR_ARG_CONTEXT_LIST)\n";
1308 ParsedAttrMap Attrs = getParsedAttrList(Records);
1309 for (const auto &I : Attrs) {
1310 const Record &Attr = *I.second;
1311
1312 if (!Attr.getValueAsBit("ParseArgumentsAsUnevaluated"))
1313 continue;
1314
1315 // All these spellings take are parsed unevaluated.
1316 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
1317 std::set<std::string> Emitted;
1318 for (const auto &S : Spellings) {
1319 if (Emitted.insert(S.name()).second)
1320 OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
1321 }
1322 }
1323 OS << "#endif // CLANG_ATTR_ARG_CONTEXT_LIST\n\n";
1324 }
1325
isIdentifierArgument(Record * Arg)1326 static bool isIdentifierArgument(Record *Arg) {
1327 return !Arg->getSuperClasses().empty() &&
1328 llvm::StringSwitch<bool>(Arg->getSuperClasses().back()->getName())
1329 .Case("IdentifierArgument", true)
1330 .Case("EnumArgument", true)
1331 .Default(false);
1332 }
1333
1334 // Emits the first-argument-is-identifier property for attributes.
emitClangAttrIdentifierArgList(RecordKeeper & Records,raw_ostream & OS)1335 static void emitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS) {
1336 OS << "#if defined(CLANG_ATTR_IDENTIFIER_ARG_LIST)\n";
1337 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1338
1339 for (const auto *Attr : Attrs) {
1340 // Determine whether the first argument is an identifier.
1341 std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
1342 if (Args.empty() || !isIdentifierArgument(Args[0]))
1343 continue;
1344
1345 // All these spellings take an identifier argument.
1346 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);
1347 std::set<std::string> Emitted;
1348 for (const auto &S : Spellings) {
1349 if (Emitted.insert(S.name()).second)
1350 OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
1351 }
1352 }
1353 OS << "#endif // CLANG_ATTR_IDENTIFIER_ARG_LIST\n\n";
1354 }
1355
1356 namespace clang {
1357
1358 // Emits the class definitions for attributes.
EmitClangAttrClass(RecordKeeper & Records,raw_ostream & OS)1359 void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
1360 emitSourceFileHeader("Attribute classes' definitions", OS);
1361
1362 OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
1363 OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n";
1364
1365 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1366
1367 for (const auto *Attr : Attrs) {
1368 const Record &R = *Attr;
1369
1370 // FIXME: Currently, documentation is generated as-needed due to the fact
1371 // that there is no way to allow a generated project "reach into" the docs
1372 // directory (for instance, it may be an out-of-tree build). However, we want
1373 // to ensure that every attribute has a Documentation field, and produce an
1374 // error if it has been neglected. Otherwise, the on-demand generation which
1375 // happens server-side will fail. This code is ensuring that functionality,
1376 // even though this Emitter doesn't technically need the documentation.
1377 // When attribute documentation can be generated as part of the build
1378 // itself, this code can be removed.
1379 (void)R.getValueAsListOfDefs("Documentation");
1380
1381 if (!R.getValueAsBit("ASTNode"))
1382 continue;
1383
1384 const std::vector<Record *> Supers = R.getSuperClasses();
1385 assert(!Supers.empty() && "Forgot to specify a superclass for the attr");
1386 std::string SuperName;
1387 for (const auto *Super : llvm::make_range(Supers.rbegin(), Supers.rend())) {
1388 const Record &R = *Super;
1389 if (R.getName() != "TargetSpecificAttr" && SuperName.empty())
1390 SuperName = R.getName();
1391 }
1392
1393 OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n";
1394
1395 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
1396 std::vector<std::unique_ptr<Argument>> Args;
1397 Args.reserve(ArgRecords.size());
1398
1399 for (const auto *ArgRecord : ArgRecords) {
1400 Args.emplace_back(createArgument(*ArgRecord, R.getName()));
1401 Args.back()->writeDeclarations(OS);
1402 OS << "\n\n";
1403 }
1404
1405 OS << "\npublic:\n";
1406
1407 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
1408
1409 // If there are zero or one spellings, all spelling-related functionality
1410 // can be elided. If all of the spellings share the same name, the spelling
1411 // functionality can also be elided.
1412 bool ElideSpelling = (Spellings.size() <= 1) ||
1413 SpellingNamesAreCommon(Spellings);
1414
1415 // This maps spelling index values to semantic Spelling enumerants.
1416 SemanticSpellingMap SemanticToSyntacticMap;
1417
1418 if (!ElideSpelling)
1419 OS << CreateSemanticSpellings(Spellings, SemanticToSyntacticMap);
1420
1421 OS << " static " << R.getName() << "Attr *CreateImplicit(";
1422 OS << "ASTContext &Ctx";
1423 if (!ElideSpelling)
1424 OS << ", Spelling S";
1425 for (auto const &ai : Args) {
1426 OS << ", ";
1427 ai->writeCtorParameters(OS);
1428 }
1429 OS << ", SourceRange Loc = SourceRange()";
1430 OS << ") {\n";
1431 OS << " " << R.getName() << "Attr *A = new (Ctx) " << R.getName();
1432 OS << "Attr(Loc, Ctx, ";
1433 for (auto const &ai : Args) {
1434 ai->writeImplicitCtorArgs(OS);
1435 OS << ", ";
1436 }
1437 OS << (ElideSpelling ? "0" : "S") << ");\n";
1438 OS << " A->setImplicit(true);\n";
1439 OS << " return A;\n }\n\n";
1440
1441 OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n";
1442
1443 bool HasOpt = false;
1444 for (auto const &ai : Args) {
1445 OS << " , ";
1446 ai->writeCtorParameters(OS);
1447 OS << "\n";
1448 if (ai->isOptional())
1449 HasOpt = true;
1450 }
1451
1452 OS << " , ";
1453 OS << "unsigned SI\n";
1454
1455 OS << " )\n";
1456 OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n";
1457
1458 for (auto const &ai : Args) {
1459 OS << " , ";
1460 ai->writeCtorInitializers(OS);
1461 OS << "\n";
1462 }
1463
1464 OS << " {\n";
1465
1466 for (auto const &ai : Args) {
1467 ai->writeCtorBody(OS);
1468 OS << "\n";
1469 }
1470 OS << " }\n\n";
1471
1472 // If there are optional arguments, write out a constructor that elides the
1473 // optional arguments as well.
1474 if (HasOpt) {
1475 OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n";
1476 for (auto const &ai : Args) {
1477 if (!ai->isOptional()) {
1478 OS << " , ";
1479 ai->writeCtorParameters(OS);
1480 OS << "\n";
1481 }
1482 }
1483
1484 OS << " , ";
1485 OS << "unsigned SI\n";
1486
1487 OS << " )\n";
1488 OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n";
1489
1490 for (auto const &ai : Args) {
1491 OS << " , ";
1492 ai->writeCtorDefaultInitializers(OS);
1493 OS << "\n";
1494 }
1495
1496 OS << " {\n";
1497
1498 for (auto const &ai : Args) {
1499 if (!ai->isOptional()) {
1500 ai->writeCtorBody(OS);
1501 OS << "\n";
1502 }
1503 }
1504 OS << " }\n\n";
1505 }
1506
1507 OS << " " << R.getName() << "Attr *clone(ASTContext &C) const override;\n";
1508 OS << " void printPretty(raw_ostream &OS,\n"
1509 << " const PrintingPolicy &Policy) const override;\n";
1510 OS << " const char *getSpelling() const override;\n";
1511
1512 if (!ElideSpelling) {
1513 assert(!SemanticToSyntacticMap.empty() && "Empty semantic mapping list");
1514 OS << " Spelling getSemanticSpelling() const {\n";
1515 WriteSemanticSpellingSwitch("SpellingListIndex", SemanticToSyntacticMap,
1516 OS);
1517 OS << " }\n";
1518 }
1519
1520 writeAttrAccessorDefinition(R, OS);
1521
1522 for (auto const &ai : Args) {
1523 ai->writeAccessors(OS);
1524 OS << "\n\n";
1525
1526 if (ai->isEnumArg())
1527 static_cast<const EnumArgument *>(ai.get())->writeConversion(OS);
1528 else if (ai->isVariadicEnumArg())
1529 static_cast<const VariadicEnumArgument *>(ai.get())
1530 ->writeConversion(OS);
1531 }
1532
1533 OS << R.getValueAsString("AdditionalMembers");
1534 OS << "\n\n";
1535
1536 OS << " static bool classof(const Attr *A) { return A->getKind() == "
1537 << "attr::" << R.getName() << "; }\n";
1538
1539 bool LateParsed = R.getValueAsBit("LateParsed");
1540 OS << " bool isLateParsed() const override { return "
1541 << LateParsed << "; }\n";
1542
1543 if (R.getValueAsBit("DuplicatesAllowedWhileMerging"))
1544 OS << " bool duplicatesAllowed() const override { return true; }\n\n";
1545
1546 OS << "};\n\n";
1547 }
1548
1549 OS << "#endif\n";
1550 }
1551
1552 // Emits the class method definitions for attributes.
EmitClangAttrImpl(RecordKeeper & Records,raw_ostream & OS)1553 void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
1554 emitSourceFileHeader("Attribute classes' member function definitions", OS);
1555
1556 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1557
1558 for (auto *Attr : Attrs) {
1559 Record &R = *Attr;
1560
1561 if (!R.getValueAsBit("ASTNode"))
1562 continue;
1563
1564 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
1565 std::vector<std::unique_ptr<Argument>> Args;
1566 for (const auto *Arg : ArgRecords)
1567 Args.emplace_back(createArgument(*Arg, R.getName()));
1568
1569 for (auto const &ai : Args)
1570 ai->writeAccessorDefinitions(OS);
1571
1572 OS << R.getName() << "Attr *" << R.getName()
1573 << "Attr::clone(ASTContext &C) const {\n";
1574 OS << " auto *A = new (C) " << R.getName() << "Attr(getLocation(), C";
1575 for (auto const &ai : Args) {
1576 OS << ", ";
1577 ai->writeCloneArgs(OS);
1578 }
1579 OS << ", getSpellingListIndex());\n";
1580 OS << " A->Inherited = Inherited;\n";
1581 OS << " A->IsPackExpansion = IsPackExpansion;\n";
1582 OS << " A->Implicit = Implicit;\n";
1583 OS << " return A;\n}\n\n";
1584
1585 writePrettyPrintFunction(R, Args, OS);
1586 writeGetSpellingFunction(R, OS);
1587 }
1588 }
1589
1590 } // end namespace clang
1591
EmitAttrList(raw_ostream & OS,StringRef Class,const std::vector<Record * > & AttrList)1592 static void EmitAttrList(raw_ostream &OS, StringRef Class,
1593 const std::vector<Record*> &AttrList) {
1594 std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end();
1595
1596 if (i != e) {
1597 // Move the end iterator back to emit the last attribute.
1598 for(--e; i != e; ++i) {
1599 if (!(*i)->getValueAsBit("ASTNode"))
1600 continue;
1601
1602 OS << Class << "(" << (*i)->getName() << ")\n";
1603 }
1604
1605 OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n";
1606 }
1607 }
1608
1609 namespace clang {
1610
1611 // Emits the enumeration list for attributes.
EmitClangAttrList(RecordKeeper & Records,raw_ostream & OS)1612 void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
1613 emitSourceFileHeader("List of all attributes that Clang recognizes", OS);
1614
1615 OS << "#ifndef LAST_ATTR\n";
1616 OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n";
1617 OS << "#endif\n\n";
1618
1619 OS << "#ifndef INHERITABLE_ATTR\n";
1620 OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n";
1621 OS << "#endif\n\n";
1622
1623 OS << "#ifndef LAST_INHERITABLE_ATTR\n";
1624 OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
1625 OS << "#endif\n\n";
1626
1627 OS << "#ifndef INHERITABLE_PARAM_ATTR\n";
1628 OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n";
1629 OS << "#endif\n\n";
1630
1631 OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n";
1632 OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)"
1633 " INHERITABLE_PARAM_ATTR(NAME)\n";
1634 OS << "#endif\n\n";
1635
1636 Record *InhClass = Records.getClass("InheritableAttr");
1637 Record *InhParamClass = Records.getClass("InheritableParamAttr");
1638 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
1639 NonInhAttrs, InhAttrs, InhParamAttrs;
1640 for (auto *Attr : Attrs) {
1641 if (!Attr->getValueAsBit("ASTNode"))
1642 continue;
1643
1644 if (Attr->isSubClassOf(InhParamClass))
1645 InhParamAttrs.push_back(Attr);
1646 else if (Attr->isSubClassOf(InhClass))
1647 InhAttrs.push_back(Attr);
1648 else
1649 NonInhAttrs.push_back(Attr);
1650 }
1651
1652 EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
1653 EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
1654 EmitAttrList(OS, "ATTR", NonInhAttrs);
1655
1656 OS << "#undef LAST_ATTR\n";
1657 OS << "#undef INHERITABLE_ATTR\n";
1658 OS << "#undef LAST_INHERITABLE_ATTR\n";
1659 OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
1660 OS << "#undef ATTR\n";
1661 }
1662
1663 // Emits the code to read an attribute from a precompiled header.
EmitClangAttrPCHRead(RecordKeeper & Records,raw_ostream & OS)1664 void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
1665 emitSourceFileHeader("Attribute deserialization code", OS);
1666
1667 Record *InhClass = Records.getClass("InheritableAttr");
1668 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
1669 ArgRecords;
1670 std::vector<std::unique_ptr<Argument>> Args;
1671
1672 OS << " switch (Kind) {\n";
1673 OS << " default:\n";
1674 OS << " llvm_unreachable(\"Unknown attribute!\");\n";
1675 for (const auto *Attr : Attrs) {
1676 const Record &R = *Attr;
1677 if (!R.getValueAsBit("ASTNode"))
1678 continue;
1679
1680 OS << " case attr::" << R.getName() << ": {\n";
1681 if (R.isSubClassOf(InhClass))
1682 OS << " bool isInherited = Record[Idx++];\n";
1683 OS << " bool isImplicit = Record[Idx++];\n";
1684 OS << " unsigned Spelling = Record[Idx++];\n";
1685 ArgRecords = R.getValueAsListOfDefs("Args");
1686 Args.clear();
1687 for (const auto *Arg : ArgRecords) {
1688 Args.emplace_back(createArgument(*Arg, R.getName()));
1689 Args.back()->writePCHReadDecls(OS);
1690 }
1691 OS << " New = new (Context) " << R.getName() << "Attr(Range, Context";
1692 for (auto const &ri : Args) {
1693 OS << ", ";
1694 ri->writePCHReadArgs(OS);
1695 }
1696 OS << ", Spelling);\n";
1697 if (R.isSubClassOf(InhClass))
1698 OS << " cast<InheritableAttr>(New)->setInherited(isInherited);\n";
1699 OS << " New->setImplicit(isImplicit);\n";
1700 OS << " break;\n";
1701 OS << " }\n";
1702 }
1703 OS << " }\n";
1704 }
1705
1706 // Emits the code to write an attribute to a precompiled header.
EmitClangAttrPCHWrite(RecordKeeper & Records,raw_ostream & OS)1707 void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
1708 emitSourceFileHeader("Attribute serialization code", OS);
1709
1710 Record *InhClass = Records.getClass("InheritableAttr");
1711 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
1712
1713 OS << " switch (A->getKind()) {\n";
1714 OS << " default:\n";
1715 OS << " llvm_unreachable(\"Unknown attribute kind!\");\n";
1716 OS << " break;\n";
1717 for (const auto *Attr : Attrs) {
1718 const Record &R = *Attr;
1719 if (!R.getValueAsBit("ASTNode"))
1720 continue;
1721 OS << " case attr::" << R.getName() << ": {\n";
1722 Args = R.getValueAsListOfDefs("Args");
1723 if (R.isSubClassOf(InhClass) || !Args.empty())
1724 OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName()
1725 << "Attr>(A);\n";
1726 if (R.isSubClassOf(InhClass))
1727 OS << " Record.push_back(SA->isInherited());\n";
1728 OS << " Record.push_back(A->isImplicit());\n";
1729 OS << " Record.push_back(A->getSpellingListIndex());\n";
1730
1731 for (const auto *Arg : Args)
1732 createArgument(*Arg, R.getName())->writePCHWrite(OS);
1733 OS << " break;\n";
1734 OS << " }\n";
1735 }
1736 OS << " }\n";
1737 }
1738
GenerateHasAttrSpellingStringSwitch(const std::vector<Record * > & Attrs,raw_ostream & OS,const std::string & Variety="",const std::string & Scope="")1739 static void GenerateHasAttrSpellingStringSwitch(
1740 const std::vector<Record *> &Attrs, raw_ostream &OS,
1741 const std::string &Variety = "", const std::string &Scope = "") {
1742 for (const auto *Attr : Attrs) {
1743 // It is assumed that there will be an llvm::Triple object named T within
1744 // scope that can be used to determine whether the attribute exists in
1745 // a given target.
1746 std::string Test;
1747 if (Attr->isSubClassOf("TargetSpecificAttr")) {
1748 const Record *R = Attr->getValueAsDef("Target");
1749 std::vector<std::string> Arches = R->getValueAsListOfStrings("Arches");
1750
1751 Test += "(";
1752 for (auto AI = Arches.begin(), AE = Arches.end(); AI != AE; ++AI) {
1753 std::string Part = *AI;
1754 Test += "T.getArch() == llvm::Triple::" + Part;
1755 if (AI + 1 != AE)
1756 Test += " || ";
1757 }
1758 Test += ")";
1759
1760 std::vector<std::string> OSes;
1761 if (!R->isValueUnset("OSes")) {
1762 Test += " && (";
1763 std::vector<std::string> OSes = R->getValueAsListOfStrings("OSes");
1764 for (auto AI = OSes.begin(), AE = OSes.end(); AI != AE; ++AI) {
1765 std::string Part = *AI;
1766
1767 Test += "T.getOS() == llvm::Triple::" + Part;
1768 if (AI + 1 != AE)
1769 Test += " || ";
1770 }
1771 Test += ")";
1772 }
1773
1774 // If this is the C++11 variety, also add in the LangOpts test.
1775 if (Variety == "CXX11")
1776 Test += " && LangOpts.CPlusPlus11";
1777 } else if (Variety == "CXX11")
1778 // C++11 mode should be checked against LangOpts, which is presumed to be
1779 // present in the caller.
1780 Test = "LangOpts.CPlusPlus11";
1781 else
1782 Test = "true";
1783
1784 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);
1785 for (const auto &S : Spellings)
1786 if (Variety.empty() || (Variety == S.variety() &&
1787 (Scope.empty() || Scope == S.nameSpace())))
1788 OS << " .Case(\"" << S.name() << "\", " << Test << ")\n";
1789 }
1790 OS << " .Default(false);\n";
1791 }
1792
1793 // Emits the list of spellings for attributes.
EmitClangAttrHasAttrImpl(RecordKeeper & Records,raw_ostream & OS)1794 void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
1795 emitSourceFileHeader("Code to implement the __has_attribute logic", OS);
1796
1797 // Separate all of the attributes out into four group: generic, C++11, GNU,
1798 // and declspecs. Then generate a big switch statement for each of them.
1799 std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
1800 std::vector<Record *> Declspec, GNU, Pragma;
1801 std::map<std::string, std::vector<Record *>> CXX;
1802
1803 // Walk over the list of all attributes, and split them out based on the
1804 // spelling variety.
1805 for (auto *R : Attrs) {
1806 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*R);
1807 for (const auto &SI : Spellings) {
1808 std::string Variety = SI.variety();
1809 if (Variety == "GNU")
1810 GNU.push_back(R);
1811 else if (Variety == "Declspec")
1812 Declspec.push_back(R);
1813 else if (Variety == "CXX11")
1814 CXX[SI.nameSpace()].push_back(R);
1815 else if (Variety == "Pragma")
1816 Pragma.push_back(R);
1817 }
1818 }
1819
1820 OS << "switch (Syntax) {\n";
1821 OS << "case AttrSyntax::Generic:\n";
1822 OS << " return llvm::StringSwitch<bool>(Name)\n";
1823 GenerateHasAttrSpellingStringSwitch(Attrs, OS);
1824 OS << "case AttrSyntax::GNU:\n";
1825 OS << " return llvm::StringSwitch<bool>(Name)\n";
1826 GenerateHasAttrSpellingStringSwitch(GNU, OS, "GNU");
1827 OS << "case AttrSyntax::Declspec:\n";
1828 OS << " return llvm::StringSwitch<bool>(Name)\n";
1829 GenerateHasAttrSpellingStringSwitch(Declspec, OS, "Declspec");
1830 OS << "case AttrSyntax::Pragma:\n";
1831 OS << " return llvm::StringSwitch<bool>(Name)\n";
1832 GenerateHasAttrSpellingStringSwitch(Pragma, OS, "Pragma");
1833 OS << "case AttrSyntax::CXX: {\n";
1834 // C++11-style attributes are further split out based on the Scope.
1835 for (std::map<std::string, std::vector<Record *>>::iterator I = CXX.begin(),
1836 E = CXX.end();
1837 I != E; ++I) {
1838 if (I != CXX.begin())
1839 OS << " else ";
1840 if (I->first.empty())
1841 OS << "if (!Scope || Scope->getName() == \"\") {\n";
1842 else
1843 OS << "if (Scope->getName() == \"" << I->first << "\") {\n";
1844 OS << " return llvm::StringSwitch<bool>(Name)\n";
1845 GenerateHasAttrSpellingStringSwitch(I->second, OS, "CXX11", I->first);
1846 OS << "}";
1847 }
1848 OS << "\n}\n";
1849 OS << "}\n";
1850 }
1851
EmitClangAttrSpellingListIndex(RecordKeeper & Records,raw_ostream & OS)1852 void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) {
1853 emitSourceFileHeader("Code to translate different attribute spellings "
1854 "into internal identifiers", OS);
1855
1856 OS <<
1857 " switch (AttrKind) {\n"
1858 " default:\n"
1859 " llvm_unreachable(\"Unknown attribute kind!\");\n"
1860 " break;\n";
1861
1862 ParsedAttrMap Attrs = getParsedAttrList(Records);
1863 for (const auto &I : Attrs) {
1864 const Record &R = *I.second;
1865 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
1866 OS << " case AT_" << I.first << ": {\n";
1867 for (unsigned I = 0; I < Spellings.size(); ++ I) {
1868 OS << " if (Name == \"" << Spellings[I].name() << "\" && "
1869 << "SyntaxUsed == "
1870 << StringSwitch<unsigned>(Spellings[I].variety())
1871 .Case("GNU", 0)
1872 .Case("CXX11", 1)
1873 .Case("Declspec", 2)
1874 .Case("Keyword", 3)
1875 .Case("Pragma", 4)
1876 .Default(0)
1877 << " && Scope == \"" << Spellings[I].nameSpace() << "\")\n"
1878 << " return " << I << ";\n";
1879 }
1880
1881 OS << " break;\n";
1882 OS << " }\n";
1883 }
1884
1885 OS << " }\n";
1886 OS << " return 0;\n";
1887 }
1888
1889 // Emits code used by RecursiveASTVisitor to visit attributes
EmitClangAttrASTVisitor(RecordKeeper & Records,raw_ostream & OS)1890 void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS) {
1891 emitSourceFileHeader("Used by RecursiveASTVisitor to visit attributes.", OS);
1892
1893 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1894
1895 // Write method declarations for Traverse* methods.
1896 // We emit this here because we only generate methods for attributes that
1897 // are declared as ASTNodes.
1898 OS << "#ifdef ATTR_VISITOR_DECLS_ONLY\n\n";
1899 for (const auto *Attr : Attrs) {
1900 const Record &R = *Attr;
1901 if (!R.getValueAsBit("ASTNode"))
1902 continue;
1903 OS << " bool Traverse"
1904 << R.getName() << "Attr(" << R.getName() << "Attr *A);\n";
1905 OS << " bool Visit"
1906 << R.getName() << "Attr(" << R.getName() << "Attr *A) {\n"
1907 << " return true; \n"
1908 << " };\n";
1909 }
1910 OS << "\n#else // ATTR_VISITOR_DECLS_ONLY\n\n";
1911
1912 // Write individual Traverse* methods for each attribute class.
1913 for (const auto *Attr : Attrs) {
1914 const Record &R = *Attr;
1915 if (!R.getValueAsBit("ASTNode"))
1916 continue;
1917
1918 OS << "template <typename Derived>\n"
1919 << "bool VISITORCLASS<Derived>::Traverse"
1920 << R.getName() << "Attr(" << R.getName() << "Attr *A) {\n"
1921 << " if (!getDerived().VisitAttr(A))\n"
1922 << " return false;\n"
1923 << " if (!getDerived().Visit" << R.getName() << "Attr(A))\n"
1924 << " return false;\n";
1925
1926 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
1927 for (const auto *Arg : ArgRecords)
1928 createArgument(*Arg, R.getName())->writeASTVisitorTraversal(OS);
1929
1930 OS << " return true;\n";
1931 OS << "}\n\n";
1932 }
1933
1934 // Write generic Traverse routine
1935 OS << "template <typename Derived>\n"
1936 << "bool VISITORCLASS<Derived>::TraverseAttr(Attr *A) {\n"
1937 << " if (!A)\n"
1938 << " return true;\n"
1939 << "\n"
1940 << " switch (A->getKind()) {\n"
1941 << " default:\n"
1942 << " return true;\n";
1943
1944 for (const auto *Attr : Attrs) {
1945 const Record &R = *Attr;
1946 if (!R.getValueAsBit("ASTNode"))
1947 continue;
1948
1949 OS << " case attr::" << R.getName() << ":\n"
1950 << " return getDerived().Traverse" << R.getName() << "Attr("
1951 << "cast<" << R.getName() << "Attr>(A));\n";
1952 }
1953 OS << " }\n"; // end case
1954 OS << "}\n"; // end function
1955 OS << "#endif // ATTR_VISITOR_DECLS_ONLY\n";
1956 }
1957
1958 // Emits code to instantiate dependent attributes on templates.
EmitClangAttrTemplateInstantiate(RecordKeeper & Records,raw_ostream & OS)1959 void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) {
1960 emitSourceFileHeader("Template instantiation code for attributes", OS);
1961
1962 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1963
1964 OS << "namespace clang {\n"
1965 << "namespace sema {\n\n"
1966 << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
1967 << "Sema &S,\n"
1968 << " const MultiLevelTemplateArgumentList &TemplateArgs) {\n"
1969 << " switch (At->getKind()) {\n"
1970 << " default:\n"
1971 << " break;\n";
1972
1973 for (const auto *Attr : Attrs) {
1974 const Record &R = *Attr;
1975 if (!R.getValueAsBit("ASTNode"))
1976 continue;
1977
1978 OS << " case attr::" << R.getName() << ": {\n";
1979 bool ShouldClone = R.getValueAsBit("Clone");
1980
1981 if (!ShouldClone) {
1982 OS << " return NULL;\n";
1983 OS << " }\n";
1984 continue;
1985 }
1986
1987 OS << " const " << R.getName() << "Attr *A = cast<"
1988 << R.getName() << "Attr>(At);\n";
1989 bool TDependent = R.getValueAsBit("TemplateDependent");
1990
1991 if (!TDependent) {
1992 OS << " return A->clone(C);\n";
1993 OS << " }\n";
1994 continue;
1995 }
1996
1997 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
1998 std::vector<std::unique_ptr<Argument>> Args;
1999 Args.reserve(ArgRecords.size());
2000
2001 for (const auto *ArgRecord : ArgRecords)
2002 Args.emplace_back(createArgument(*ArgRecord, R.getName()));
2003
2004 for (auto const &ai : Args)
2005 ai->writeTemplateInstantiation(OS);
2006
2007 OS << " return new (C) " << R.getName() << "Attr(A->getLocation(), C";
2008 for (auto const &ai : Args) {
2009 OS << ", ";
2010 ai->writeTemplateInstantiationArgs(OS);
2011 }
2012 OS << ", A->getSpellingListIndex());\n }\n";
2013 }
2014 OS << " } // end switch\n"
2015 << " llvm_unreachable(\"Unknown attribute!\");\n"
2016 << " return 0;\n"
2017 << "}\n\n"
2018 << "} // end namespace sema\n"
2019 << "} // end namespace clang\n";
2020 }
2021
2022 // Emits the list of parsed attributes.
EmitClangAttrParsedAttrList(RecordKeeper & Records,raw_ostream & OS)2023 void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) {
2024 emitSourceFileHeader("List of all attributes that Clang recognizes", OS);
2025
2026 OS << "#ifndef PARSED_ATTR\n";
2027 OS << "#define PARSED_ATTR(NAME) NAME\n";
2028 OS << "#endif\n\n";
2029
2030 ParsedAttrMap Names = getParsedAttrList(Records);
2031 for (const auto &I : Names) {
2032 OS << "PARSED_ATTR(" << I.first << ")\n";
2033 }
2034 }
2035
emitArgInfo(const Record & R,std::stringstream & OS)2036 static void emitArgInfo(const Record &R, std::stringstream &OS) {
2037 // This function will count the number of arguments specified for the
2038 // attribute and emit the number of required arguments followed by the
2039 // number of optional arguments.
2040 std::vector<Record *> Args = R.getValueAsListOfDefs("Args");
2041 unsigned ArgCount = 0, OptCount = 0;
2042 for (const auto *Arg : Args) {
2043 Arg->getValueAsBit("Optional") ? ++OptCount : ++ArgCount;
2044 }
2045 OS << ArgCount << ", " << OptCount;
2046 }
2047
GenerateDefaultAppertainsTo(raw_ostream & OS)2048 static void GenerateDefaultAppertainsTo(raw_ostream &OS) {
2049 OS << "static bool defaultAppertainsTo(Sema &, const AttributeList &,";
2050 OS << "const Decl *) {\n";
2051 OS << " return true;\n";
2052 OS << "}\n\n";
2053 }
2054
CalculateDiagnostic(const Record & S)2055 static std::string CalculateDiagnostic(const Record &S) {
2056 // If the SubjectList object has a custom diagnostic associated with it,
2057 // return that directly.
2058 std::string CustomDiag = S.getValueAsString("CustomDiag");
2059 if (!CustomDiag.empty())
2060 return CustomDiag;
2061
2062 // Given the list of subjects, determine what diagnostic best fits.
2063 enum {
2064 Func = 1U << 0,
2065 Var = 1U << 1,
2066 ObjCMethod = 1U << 2,
2067 Param = 1U << 3,
2068 Class = 1U << 4,
2069 GenericRecord = 1U << 5,
2070 Type = 1U << 6,
2071 ObjCIVar = 1U << 7,
2072 ObjCProp = 1U << 8,
2073 ObjCInterface = 1U << 9,
2074 Block = 1U << 10,
2075 Namespace = 1U << 11,
2076 Field = 1U << 12,
2077 CXXMethod = 1U << 13,
2078 ObjCProtocol = 1U << 14
2079 };
2080 uint32_t SubMask = 0;
2081
2082 std::vector<Record *> Subjects = S.getValueAsListOfDefs("Subjects");
2083 for (const auto *Subject : Subjects) {
2084 const Record &R = *Subject;
2085 std::string Name;
2086
2087 if (R.isSubClassOf("SubsetSubject")) {
2088 PrintError(R.getLoc(), "SubsetSubjects should use a custom diagnostic");
2089 // As a fallback, look through the SubsetSubject to see what its base
2090 // type is, and use that. This needs to be updated if SubsetSubjects
2091 // are allowed within other SubsetSubjects.
2092 Name = R.getValueAsDef("Base")->getName();
2093 } else
2094 Name = R.getName();
2095
2096 uint32_t V = StringSwitch<uint32_t>(Name)
2097 .Case("Function", Func)
2098 .Case("Var", Var)
2099 .Case("ObjCMethod", ObjCMethod)
2100 .Case("ParmVar", Param)
2101 .Case("TypedefName", Type)
2102 .Case("ObjCIvar", ObjCIVar)
2103 .Case("ObjCProperty", ObjCProp)
2104 .Case("Record", GenericRecord)
2105 .Case("ObjCInterface", ObjCInterface)
2106 .Case("ObjCProtocol", ObjCProtocol)
2107 .Case("Block", Block)
2108 .Case("CXXRecord", Class)
2109 .Case("Namespace", Namespace)
2110 .Case("Field", Field)
2111 .Case("CXXMethod", CXXMethod)
2112 .Default(0);
2113 if (!V) {
2114 // Something wasn't in our mapping, so be helpful and let the developer
2115 // know about it.
2116 PrintFatalError(R.getLoc(), "Unknown subject type: " + R.getName());
2117 return "";
2118 }
2119
2120 SubMask |= V;
2121 }
2122
2123 switch (SubMask) {
2124 // For the simple cases where there's only a single entry in the mask, we
2125 // don't have to resort to bit fiddling.
2126 case Func: return "ExpectedFunction";
2127 case Var: return "ExpectedVariable";
2128 case Param: return "ExpectedParameter";
2129 case Class: return "ExpectedClass";
2130 case CXXMethod:
2131 // FIXME: Currently, this maps to ExpectedMethod based on existing code,
2132 // but should map to something a bit more accurate at some point.
2133 case ObjCMethod: return "ExpectedMethod";
2134 case Type: return "ExpectedType";
2135 case ObjCInterface: return "ExpectedObjectiveCInterface";
2136 case ObjCProtocol: return "ExpectedObjectiveCProtocol";
2137
2138 // "GenericRecord" means struct, union or class; check the language options
2139 // and if not compiling for C++, strip off the class part. Note that this
2140 // relies on the fact that the context for this declares "Sema &S".
2141 case GenericRecord:
2142 return "(S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass : "
2143 "ExpectedStructOrUnion)";
2144 case Func | ObjCMethod | Block: return "ExpectedFunctionMethodOrBlock";
2145 case Func | ObjCMethod | Class: return "ExpectedFunctionMethodOrClass";
2146 case Func | Param:
2147 case Func | ObjCMethod | Param: return "ExpectedFunctionMethodOrParameter";
2148 case Func | ObjCMethod: return "ExpectedFunctionOrMethod";
2149 case Func | Var: return "ExpectedVariableOrFunction";
2150
2151 // If not compiling for C++, the class portion does not apply.
2152 case Func | Var | Class:
2153 return "(S.getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass : "
2154 "ExpectedVariableOrFunction)";
2155
2156 case ObjCMethod | ObjCProp: return "ExpectedMethodOrProperty";
2157 case Field | Var: return "ExpectedFieldOrGlobalVar";
2158 }
2159
2160 PrintFatalError(S.getLoc(),
2161 "Could not deduce diagnostic argument for Attr subjects");
2162
2163 return "";
2164 }
2165
GetSubjectWithSuffix(const Record * R)2166 static std::string GetSubjectWithSuffix(const Record *R) {
2167 std::string B = R->getName();
2168 if (B == "DeclBase")
2169 return "Decl";
2170 return B + "Decl";
2171 }
GenerateCustomAppertainsTo(const Record & Subject,raw_ostream & OS)2172 static std::string GenerateCustomAppertainsTo(const Record &Subject,
2173 raw_ostream &OS) {
2174 std::string FnName = "is" + Subject.getName();
2175
2176 // If this code has already been generated, simply return the previous
2177 // instance of it.
2178 static std::set<std::string> CustomSubjectSet;
2179 std::set<std::string>::iterator I = CustomSubjectSet.find(FnName);
2180 if (I != CustomSubjectSet.end())
2181 return *I;
2182
2183 Record *Base = Subject.getValueAsDef("Base");
2184
2185 // Not currently support custom subjects within custom subjects.
2186 if (Base->isSubClassOf("SubsetSubject")) {
2187 PrintFatalError(Subject.getLoc(),
2188 "SubsetSubjects within SubsetSubjects is not supported");
2189 return "";
2190 }
2191
2192 OS << "static bool " << FnName << "(const Decl *D) {\n";
2193 OS << " if (const " << GetSubjectWithSuffix(Base) << " *S = dyn_cast<";
2194 OS << GetSubjectWithSuffix(Base);
2195 OS << ">(D))\n";
2196 OS << " return " << Subject.getValueAsString("CheckCode") << ";\n";
2197 OS << " return false;\n";
2198 OS << "}\n\n";
2199
2200 CustomSubjectSet.insert(FnName);
2201 return FnName;
2202 }
2203
GenerateAppertainsTo(const Record & Attr,raw_ostream & OS)2204 static std::string GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) {
2205 // If the attribute does not contain a Subjects definition, then use the
2206 // default appertainsTo logic.
2207 if (Attr.isValueUnset("Subjects"))
2208 return "defaultAppertainsTo";
2209
2210 const Record *SubjectObj = Attr.getValueAsDef("Subjects");
2211 std::vector<Record*> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
2212
2213 // If the list of subjects is empty, it is assumed that the attribute
2214 // appertains to everything.
2215 if (Subjects.empty())
2216 return "defaultAppertainsTo";
2217
2218 bool Warn = SubjectObj->getValueAsDef("Diag")->getValueAsBit("Warn");
2219
2220 // Otherwise, generate an appertainsTo check specific to this attribute which
2221 // checks all of the given subjects against the Decl passed in. Return the
2222 // name of that check to the caller.
2223 std::string FnName = "check" + Attr.getName() + "AppertainsTo";
2224 std::stringstream SS;
2225 SS << "static bool " << FnName << "(Sema &S, const AttributeList &Attr, ";
2226 SS << "const Decl *D) {\n";
2227 SS << " if (";
2228 for (auto I = Subjects.begin(), E = Subjects.end(); I != E; ++I) {
2229 // If the subject has custom code associated with it, generate a function
2230 // for it. The function cannot be inlined into this check (yet) because it
2231 // requires the subject to be of a specific type, and were that information
2232 // inlined here, it would not support an attribute with multiple custom
2233 // subjects.
2234 if ((*I)->isSubClassOf("SubsetSubject")) {
2235 SS << "!" << GenerateCustomAppertainsTo(**I, OS) << "(D)";
2236 } else {
2237 SS << "!isa<" << GetSubjectWithSuffix(*I) << ">(D)";
2238 }
2239
2240 if (I + 1 != E)
2241 SS << " && ";
2242 }
2243 SS << ") {\n";
2244 SS << " S.Diag(Attr.getLoc(), diag::";
2245 SS << (Warn ? "warn_attribute_wrong_decl_type" :
2246 "err_attribute_wrong_decl_type");
2247 SS << ")\n";
2248 SS << " << Attr.getName() << ";
2249 SS << CalculateDiagnostic(*SubjectObj) << ";\n";
2250 SS << " return false;\n";
2251 SS << " }\n";
2252 SS << " return true;\n";
2253 SS << "}\n\n";
2254
2255 OS << SS.str();
2256 return FnName;
2257 }
2258
GenerateDefaultLangOptRequirements(raw_ostream & OS)2259 static void GenerateDefaultLangOptRequirements(raw_ostream &OS) {
2260 OS << "static bool defaultDiagnoseLangOpts(Sema &, ";
2261 OS << "const AttributeList &) {\n";
2262 OS << " return true;\n";
2263 OS << "}\n\n";
2264 }
2265
GenerateLangOptRequirements(const Record & R,raw_ostream & OS)2266 static std::string GenerateLangOptRequirements(const Record &R,
2267 raw_ostream &OS) {
2268 // If the attribute has an empty or unset list of language requirements,
2269 // return the default handler.
2270 std::vector<Record *> LangOpts = R.getValueAsListOfDefs("LangOpts");
2271 if (LangOpts.empty())
2272 return "defaultDiagnoseLangOpts";
2273
2274 // Generate the test condition, as well as a unique function name for the
2275 // diagnostic test. The list of options should usually be short (one or two
2276 // options), and the uniqueness isn't strictly necessary (it is just for
2277 // codegen efficiency).
2278 std::string FnName = "check", Test;
2279 for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) {
2280 std::string Part = (*I)->getValueAsString("Name");
2281 Test += "S.LangOpts." + Part;
2282 if (I + 1 != E)
2283 Test += " || ";
2284 FnName += Part;
2285 }
2286 FnName += "LangOpts";
2287
2288 // If this code has already been generated, simply return the previous
2289 // instance of it.
2290 static std::set<std::string> CustomLangOptsSet;
2291 std::set<std::string>::iterator I = CustomLangOptsSet.find(FnName);
2292 if (I != CustomLangOptsSet.end())
2293 return *I;
2294
2295 OS << "static bool " << FnName << "(Sema &S, const AttributeList &Attr) {\n";
2296 OS << " if (" << Test << ")\n";
2297 OS << " return true;\n\n";
2298 OS << " S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) ";
2299 OS << "<< Attr.getName();\n";
2300 OS << " return false;\n";
2301 OS << "}\n\n";
2302
2303 CustomLangOptsSet.insert(FnName);
2304 return FnName;
2305 }
2306
GenerateDefaultTargetRequirements(raw_ostream & OS)2307 static void GenerateDefaultTargetRequirements(raw_ostream &OS) {
2308 OS << "static bool defaultTargetRequirements(const llvm::Triple &) {\n";
2309 OS << " return true;\n";
2310 OS << "}\n\n";
2311 }
2312
GenerateTargetRequirements(const Record & Attr,const ParsedAttrMap & Dupes,raw_ostream & OS)2313 static std::string GenerateTargetRequirements(const Record &Attr,
2314 const ParsedAttrMap &Dupes,
2315 raw_ostream &OS) {
2316 // If the attribute is not a target specific attribute, return the default
2317 // target handler.
2318 if (!Attr.isSubClassOf("TargetSpecificAttr"))
2319 return "defaultTargetRequirements";
2320
2321 // Get the list of architectures to be tested for.
2322 const Record *R = Attr.getValueAsDef("Target");
2323 std::vector<std::string> Arches = R->getValueAsListOfStrings("Arches");
2324 if (Arches.empty()) {
2325 PrintError(Attr.getLoc(), "Empty list of target architectures for a "
2326 "target-specific attr");
2327 return "defaultTargetRequirements";
2328 }
2329
2330 // If there are other attributes which share the same parsed attribute kind,
2331 // such as target-specific attributes with a shared spelling, collapse the
2332 // duplicate architectures. This is required because a shared target-specific
2333 // attribute has only one AttributeList::Kind enumeration value, but it
2334 // applies to multiple target architectures. In order for the attribute to be
2335 // considered valid, all of its architectures need to be included.
2336 if (!Attr.isValueUnset("ParseKind")) {
2337 std::string APK = Attr.getValueAsString("ParseKind");
2338 for (const auto &I : Dupes) {
2339 if (I.first == APK) {
2340 std::vector<std::string> DA = I.second->getValueAsDef("Target")
2341 ->getValueAsListOfStrings("Arches");
2342 std::copy(DA.begin(), DA.end(), std::back_inserter(Arches));
2343 }
2344 }
2345 }
2346
2347 std::string FnName = "isTarget", Test = "(";
2348 for (auto I = Arches.begin(), E = Arches.end(); I != E; ++I) {
2349 std::string Part = *I;
2350 Test += "Arch == llvm::Triple::" + Part;
2351 if (I + 1 != E)
2352 Test += " || ";
2353 FnName += Part;
2354 }
2355 Test += ")";
2356
2357 // If the target also requires OS testing, generate those tests as well.
2358 bool UsesOS = false;
2359 if (!R->isValueUnset("OSes")) {
2360 UsesOS = true;
2361
2362 // We know that there was at least one arch test, so we need to and in the
2363 // OS tests.
2364 Test += " && (";
2365 std::vector<std::string> OSes = R->getValueAsListOfStrings("OSes");
2366 for (auto I = OSes.begin(), E = OSes.end(); I != E; ++I) {
2367 std::string Part = *I;
2368
2369 Test += "OS == llvm::Triple::" + Part;
2370 if (I + 1 != E)
2371 Test += " || ";
2372 FnName += Part;
2373 }
2374 Test += ")";
2375 }
2376
2377 // If this code has already been generated, simply return the previous
2378 // instance of it.
2379 static std::set<std::string> CustomTargetSet;
2380 std::set<std::string>::iterator I = CustomTargetSet.find(FnName);
2381 if (I != CustomTargetSet.end())
2382 return *I;
2383
2384 OS << "static bool " << FnName << "(const llvm::Triple &T) {\n";
2385 OS << " llvm::Triple::ArchType Arch = T.getArch();\n";
2386 if (UsesOS)
2387 OS << " llvm::Triple::OSType OS = T.getOS();\n";
2388 OS << " return " << Test << ";\n";
2389 OS << "}\n\n";
2390
2391 CustomTargetSet.insert(FnName);
2392 return FnName;
2393 }
2394
GenerateDefaultSpellingIndexToSemanticSpelling(raw_ostream & OS)2395 static void GenerateDefaultSpellingIndexToSemanticSpelling(raw_ostream &OS) {
2396 OS << "static unsigned defaultSpellingIndexToSemanticSpelling("
2397 << "const AttributeList &Attr) {\n";
2398 OS << " return UINT_MAX;\n";
2399 OS << "}\n\n";
2400 }
2401
GenerateSpellingIndexToSemanticSpelling(const Record & Attr,raw_ostream & OS)2402 static std::string GenerateSpellingIndexToSemanticSpelling(const Record &Attr,
2403 raw_ostream &OS) {
2404 // If the attribute does not have a semantic form, we can bail out early.
2405 if (!Attr.getValueAsBit("ASTNode"))
2406 return "defaultSpellingIndexToSemanticSpelling";
2407
2408 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
2409
2410 // If there are zero or one spellings, or all of the spellings share the same
2411 // name, we can also bail out early.
2412 if (Spellings.size() <= 1 || SpellingNamesAreCommon(Spellings))
2413 return "defaultSpellingIndexToSemanticSpelling";
2414
2415 // Generate the enumeration we will use for the mapping.
2416 SemanticSpellingMap SemanticToSyntacticMap;
2417 std::string Enum = CreateSemanticSpellings(Spellings, SemanticToSyntacticMap);
2418 std::string Name = Attr.getName() + "AttrSpellingMap";
2419
2420 OS << "static unsigned " << Name << "(const AttributeList &Attr) {\n";
2421 OS << Enum;
2422 OS << " unsigned Idx = Attr.getAttributeSpellingListIndex();\n";
2423 WriteSemanticSpellingSwitch("Idx", SemanticToSyntacticMap, OS);
2424 OS << "}\n\n";
2425
2426 return Name;
2427 }
2428
IsKnownToGCC(const Record & Attr)2429 static bool IsKnownToGCC(const Record &Attr) {
2430 // Look at the spellings for this subject; if there are any spellings which
2431 // claim to be known to GCC, the attribute is known to GCC.
2432 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
2433 for (const auto &I : Spellings) {
2434 if (I.knownToGCC())
2435 return true;
2436 }
2437 return false;
2438 }
2439
2440 /// Emits the parsed attribute helpers
EmitClangAttrParsedAttrImpl(RecordKeeper & Records,raw_ostream & OS)2441 void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
2442 emitSourceFileHeader("Parsed attribute helpers", OS);
2443
2444 // Get the list of parsed attributes, and accept the optional list of
2445 // duplicates due to the ParseKind.
2446 ParsedAttrMap Dupes;
2447 ParsedAttrMap Attrs = getParsedAttrList(Records, &Dupes);
2448
2449 // Generate the default appertainsTo, target and language option diagnostic,
2450 // and spelling list index mapping methods.
2451 GenerateDefaultAppertainsTo(OS);
2452 GenerateDefaultLangOptRequirements(OS);
2453 GenerateDefaultTargetRequirements(OS);
2454 GenerateDefaultSpellingIndexToSemanticSpelling(OS);
2455
2456 // Generate the appertainsTo diagnostic methods and write their names into
2457 // another mapping. At the same time, generate the AttrInfoMap object
2458 // contents. Due to the reliance on generated code, use separate streams so
2459 // that code will not be interleaved.
2460 std::stringstream SS;
2461 for (auto I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
2462 // TODO: If the attribute's kind appears in the list of duplicates, that is
2463 // because it is a target-specific attribute that appears multiple times.
2464 // It would be beneficial to test whether the duplicates are "similar
2465 // enough" to each other to not cause problems. For instance, check that
2466 // the spellings are identical, and custom parsing rules match, etc.
2467
2468 // We need to generate struct instances based off ParsedAttrInfo from
2469 // AttributeList.cpp.
2470 SS << " { ";
2471 emitArgInfo(*I->second, SS);
2472 SS << ", " << I->second->getValueAsBit("HasCustomParsing");
2473 SS << ", " << I->second->isSubClassOf("TargetSpecificAttr");
2474 SS << ", " << I->second->isSubClassOf("TypeAttr");
2475 SS << ", " << IsKnownToGCC(*I->second);
2476 SS << ", " << GenerateAppertainsTo(*I->second, OS);
2477 SS << ", " << GenerateLangOptRequirements(*I->second, OS);
2478 SS << ", " << GenerateTargetRequirements(*I->second, Dupes, OS);
2479 SS << ", " << GenerateSpellingIndexToSemanticSpelling(*I->second, OS);
2480 SS << " }";
2481
2482 if (I + 1 != E)
2483 SS << ",";
2484
2485 SS << " // AT_" << I->first << "\n";
2486 }
2487
2488 OS << "static const ParsedAttrInfo AttrInfoMap[AttributeList::UnknownAttribute + 1] = {\n";
2489 OS << SS.str();
2490 OS << "};\n\n";
2491 }
2492
2493 // Emits the kind list of parsed attributes
EmitClangAttrParsedAttrKinds(RecordKeeper & Records,raw_ostream & OS)2494 void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
2495 emitSourceFileHeader("Attribute name matcher", OS);
2496
2497 std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
2498 std::vector<StringMatcher::StringPair> GNU, Declspec, CXX11, Keywords, Pragma;
2499 std::set<std::string> Seen;
2500 for (const auto *A : Attrs) {
2501 const Record &Attr = *A;
2502
2503 bool SemaHandler = Attr.getValueAsBit("SemaHandler");
2504 bool Ignored = Attr.getValueAsBit("Ignored");
2505 if (SemaHandler || Ignored) {
2506 // Attribute spellings can be shared between target-specific attributes,
2507 // and can be shared between syntaxes for the same attribute. For
2508 // instance, an attribute can be spelled GNU<"interrupt"> for an ARM-
2509 // specific attribute, or MSP430-specific attribute. Additionally, an
2510 // attribute can be spelled GNU<"dllexport"> and Declspec<"dllexport">
2511 // for the same semantic attribute. Ultimately, we need to map each of
2512 // these to a single AttributeList::Kind value, but the StringMatcher
2513 // class cannot handle duplicate match strings. So we generate a list of
2514 // string to match based on the syntax, and emit multiple string matchers
2515 // depending on the syntax used.
2516 std::string AttrName;
2517 if (Attr.isSubClassOf("TargetSpecificAttr") &&
2518 !Attr.isValueUnset("ParseKind")) {
2519 AttrName = Attr.getValueAsString("ParseKind");
2520 if (Seen.find(AttrName) != Seen.end())
2521 continue;
2522 Seen.insert(AttrName);
2523 } else
2524 AttrName = NormalizeAttrName(StringRef(Attr.getName())).str();
2525
2526 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
2527 for (const auto &S : Spellings) {
2528 std::string RawSpelling = S.name();
2529 std::vector<StringMatcher::StringPair> *Matches = nullptr;
2530 std::string Spelling, Variety = S.variety();
2531 if (Variety == "CXX11") {
2532 Matches = &CXX11;
2533 Spelling += S.nameSpace();
2534 Spelling += "::";
2535 } else if (Variety == "GNU")
2536 Matches = &GNU;
2537 else if (Variety == "Declspec")
2538 Matches = &Declspec;
2539 else if (Variety == "Keyword")
2540 Matches = &Keywords;
2541 else if (Variety == "Pragma")
2542 Matches = &Pragma;
2543
2544 assert(Matches && "Unsupported spelling variety found");
2545
2546 Spelling += NormalizeAttrSpelling(RawSpelling);
2547 if (SemaHandler)
2548 Matches->push_back(StringMatcher::StringPair(Spelling,
2549 "return AttributeList::AT_" + AttrName + ";"));
2550 else
2551 Matches->push_back(StringMatcher::StringPair(Spelling,
2552 "return AttributeList::IgnoredAttribute;"));
2553 }
2554 }
2555 }
2556
2557 OS << "static AttributeList::Kind getAttrKind(StringRef Name, ";
2558 OS << "AttributeList::Syntax Syntax) {\n";
2559 OS << " if (AttributeList::AS_GNU == Syntax) {\n";
2560 StringMatcher("Name", GNU, OS).Emit();
2561 OS << " } else if (AttributeList::AS_Declspec == Syntax) {\n";
2562 StringMatcher("Name", Declspec, OS).Emit();
2563 OS << " } else if (AttributeList::AS_CXX11 == Syntax) {\n";
2564 StringMatcher("Name", CXX11, OS).Emit();
2565 OS << " } else if (AttributeList::AS_Keyword == Syntax) {\n";
2566 StringMatcher("Name", Keywords, OS).Emit();
2567 OS << " } else if (AttributeList::AS_Pragma == Syntax) {\n";
2568 StringMatcher("Name", Pragma, OS).Emit();
2569 OS << " }\n";
2570 OS << " return AttributeList::UnknownAttribute;\n"
2571 << "}\n";
2572 }
2573
2574 // Emits the code to dump an attribute.
EmitClangAttrDump(RecordKeeper & Records,raw_ostream & OS)2575 void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) {
2576 emitSourceFileHeader("Attribute dumper", OS);
2577
2578 OS <<
2579 " switch (A->getKind()) {\n"
2580 " default:\n"
2581 " llvm_unreachable(\"Unknown attribute kind!\");\n"
2582 " break;\n";
2583 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
2584 for (const auto *Attr : Attrs) {
2585 const Record &R = *Attr;
2586 if (!R.getValueAsBit("ASTNode"))
2587 continue;
2588 OS << " case attr::" << R.getName() << ": {\n";
2589
2590 // If the attribute has a semantically-meaningful name (which is determined
2591 // by whether there is a Spelling enumeration for it), then write out the
2592 // spelling used for the attribute.
2593 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
2594 if (Spellings.size() > 1 && !SpellingNamesAreCommon(Spellings))
2595 OS << " OS << \" \" << A->getSpelling();\n";
2596
2597 Args = R.getValueAsListOfDefs("Args");
2598 if (!Args.empty()) {
2599 OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName()
2600 << "Attr>(A);\n";
2601 for (const auto *Arg : Args)
2602 createArgument(*Arg, R.getName())->writeDump(OS);
2603
2604 // Code for detecting the last child.
2605 OS << " bool OldMoreChildren = hasMoreChildren();\n";
2606 OS << " bool MoreChildren;\n";
2607
2608 for (auto AI = Args.begin(), AE = Args.end(); AI != AE; ++AI) {
2609 // More code for detecting the last child.
2610 OS << " MoreChildren = OldMoreChildren";
2611 for (auto Next = AI + 1; Next != AE; ++Next) {
2612 OS << " || ";
2613 createArgument(**Next, R.getName())->writeHasChildren(OS);
2614 }
2615 OS << ";\n";
2616 OS << " setMoreChildren(MoreChildren);\n";
2617
2618 createArgument(**AI, R.getName())->writeDumpChildren(OS);
2619 }
2620
2621 // Reset the last child.
2622 OS << " setMoreChildren(OldMoreChildren);\n";
2623 }
2624 OS <<
2625 " break;\n"
2626 " }\n";
2627 }
2628 OS << " }\n";
2629 }
2630
EmitClangAttrParserStringSwitches(RecordKeeper & Records,raw_ostream & OS)2631 void EmitClangAttrParserStringSwitches(RecordKeeper &Records,
2632 raw_ostream &OS) {
2633 emitSourceFileHeader("Parser-related llvm::StringSwitch cases", OS);
2634 emitClangAttrArgContextList(Records, OS);
2635 emitClangAttrIdentifierArgList(Records, OS);
2636 emitClangAttrTypeArgList(Records, OS);
2637 emitClangAttrLateParsedList(Records, OS);
2638 }
2639
2640 class DocumentationData {
2641 public:
2642 const Record *Documentation;
2643 const Record *Attribute;
2644
DocumentationData(const Record & Documentation,const Record & Attribute)2645 DocumentationData(const Record &Documentation, const Record &Attribute)
2646 : Documentation(&Documentation), Attribute(&Attribute) {}
2647 };
2648
WriteCategoryHeader(const Record * DocCategory,raw_ostream & OS)2649 static void WriteCategoryHeader(const Record *DocCategory,
2650 raw_ostream &OS) {
2651 const std::string &Name = DocCategory->getValueAsString("Name");
2652 OS << Name << "\n" << std::string(Name.length(), '=') << "\n";
2653
2654 // If there is content, print that as well.
2655 std::string ContentStr = DocCategory->getValueAsString("Content");
2656 if (!ContentStr.empty()) {
2657 // Trim leading and trailing newlines and spaces.
2658 StringRef Content(ContentStr);
2659 while (Content.startswith("\r") || Content.startswith("\n") ||
2660 Content.startswith(" ") || Content.startswith("\t"))
2661 Content = Content.substr(1);
2662 while (Content.endswith("\r") || Content.endswith("\n") ||
2663 Content.endswith(" ") || Content.endswith("\t"))
2664 Content = Content.substr(0, Content.size() - 1);
2665 OS << Content;
2666 }
2667 OS << "\n\n";
2668 }
2669
2670 enum SpellingKind {
2671 GNU = 1 << 0,
2672 CXX11 = 1 << 1,
2673 Declspec = 1 << 2,
2674 Keyword = 1 << 3,
2675 Pragma = 1 << 4
2676 };
2677
WriteDocumentation(const DocumentationData & Doc,raw_ostream & OS)2678 static void WriteDocumentation(const DocumentationData &Doc,
2679 raw_ostream &OS) {
2680 // FIXME: there is no way to have a per-spelling category for the attribute
2681 // documentation. This may not be a limiting factor since the spellings
2682 // should generally be consistently applied across the category.
2683
2684 std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Doc.Attribute);
2685
2686 // Determine the heading to be used for this attribute.
2687 std::string Heading = Doc.Documentation->getValueAsString("Heading");
2688 bool CustomHeading = !Heading.empty();
2689 if (Heading.empty()) {
2690 // If there's only one spelling, we can simply use that.
2691 if (Spellings.size() == 1)
2692 Heading = Spellings.begin()->name();
2693 else {
2694 std::set<std::string> Uniques;
2695 for (auto I = Spellings.begin(), E = Spellings.end();
2696 I != E && Uniques.size() <= 1; ++I) {
2697 std::string Spelling = NormalizeNameForSpellingComparison(I->name());
2698 Uniques.insert(Spelling);
2699 }
2700 // If the semantic map has only one spelling, that is sufficient for our
2701 // needs.
2702 if (Uniques.size() == 1)
2703 Heading = *Uniques.begin();
2704 }
2705 }
2706
2707 // If the heading is still empty, it is an error.
2708 if (Heading.empty())
2709 PrintFatalError(Doc.Attribute->getLoc(),
2710 "This attribute requires a heading to be specified");
2711
2712 // Gather a list of unique spellings; this is not the same as the semantic
2713 // spelling for the attribute. Variations in underscores and other non-
2714 // semantic characters are still acceptable.
2715 std::vector<std::string> Names;
2716
2717 unsigned SupportedSpellings = 0;
2718 for (const auto &I : Spellings) {
2719 SpellingKind Kind = StringSwitch<SpellingKind>(I.variety())
2720 .Case("GNU", GNU)
2721 .Case("CXX11", CXX11)
2722 .Case("Declspec", Declspec)
2723 .Case("Keyword", Keyword)
2724 .Case("Pragma", Pragma);
2725
2726 // Mask in the supported spelling.
2727 SupportedSpellings |= Kind;
2728
2729 std::string Name;
2730 if (Kind == CXX11 && !I.nameSpace().empty())
2731 Name = I.nameSpace() + "::";
2732 Name += I.name();
2733
2734 // If this name is the same as the heading, do not add it.
2735 if (Name != Heading)
2736 Names.push_back(Name);
2737 }
2738
2739 // Print out the heading for the attribute. If there are alternate spellings,
2740 // then display those after the heading.
2741 if (!CustomHeading && !Names.empty()) {
2742 Heading += " (";
2743 for (auto I = Names.begin(), E = Names.end(); I != E; ++I) {
2744 if (I != Names.begin())
2745 Heading += ", ";
2746 Heading += *I;
2747 }
2748 Heading += ")";
2749 }
2750 OS << Heading << "\n" << std::string(Heading.length(), '-') << "\n";
2751
2752 if (!SupportedSpellings)
2753 PrintFatalError(Doc.Attribute->getLoc(),
2754 "Attribute has no supported spellings; cannot be "
2755 "documented");
2756
2757 // List what spelling syntaxes the attribute supports.
2758 OS << ".. csv-table:: Supported Syntaxes\n";
2759 OS << " :header: \"GNU\", \"C++11\", \"__declspec\", \"Keyword\",";
2760 OS << " \"Pragma\"\n\n";
2761 OS << " \"";
2762 if (SupportedSpellings & GNU) OS << "X";
2763 OS << "\",\"";
2764 if (SupportedSpellings & CXX11) OS << "X";
2765 OS << "\",\"";
2766 if (SupportedSpellings & Declspec) OS << "X";
2767 OS << "\",\"";
2768 if (SupportedSpellings & Keyword) OS << "X";
2769 OS << "\", \"";
2770 if (SupportedSpellings & Pragma) OS << "X";
2771 OS << "\"\n\n";
2772
2773 // If the attribute is deprecated, print a message about it, and possibly
2774 // provide a replacement attribute.
2775 if (!Doc.Documentation->isValueUnset("Deprecated")) {
2776 OS << "This attribute has been deprecated, and may be removed in a future "
2777 << "version of Clang.";
2778 const Record &Deprecated = *Doc.Documentation->getValueAsDef("Deprecated");
2779 std::string Replacement = Deprecated.getValueAsString("Replacement");
2780 if (!Replacement.empty())
2781 OS << " This attribute has been superseded by ``"
2782 << Replacement << "``.";
2783 OS << "\n\n";
2784 }
2785
2786 std::string ContentStr = Doc.Documentation->getValueAsString("Content");
2787 // Trim leading and trailing newlines and spaces.
2788 StringRef Content(ContentStr);
2789 while (Content.startswith("\r") || Content.startswith("\n") ||
2790 Content.startswith(" ") || Content.startswith("\t"))
2791 Content = Content.substr(1);
2792 while (Content.endswith("\r") || Content.endswith("\n") ||
2793 Content.endswith(" ") || Content.endswith("\t"))
2794 Content = Content.substr(0, Content.size() - 1);
2795 OS << Content;
2796
2797 OS << "\n\n\n";
2798 }
2799
EmitClangAttrDocs(RecordKeeper & Records,raw_ostream & OS)2800 void EmitClangAttrDocs(RecordKeeper &Records, raw_ostream &OS) {
2801 // Get the documentation introduction paragraph.
2802 const Record *Documentation = Records.getDef("GlobalDocumentation");
2803 if (!Documentation) {
2804 PrintFatalError("The Documentation top-level definition is missing, "
2805 "no documentation will be generated.");
2806 return;
2807 }
2808
2809 OS << Documentation->getValueAsString("Intro") << "\n";
2810
2811 // Gather the Documentation lists from each of the attributes, based on the
2812 // category provided.
2813 std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
2814 std::map<const Record *, std::vector<DocumentationData>> SplitDocs;
2815 for (const auto *A : Attrs) {
2816 const Record &Attr = *A;
2817 std::vector<Record *> Docs = Attr.getValueAsListOfDefs("Documentation");
2818 for (const auto *D : Docs) {
2819 const Record &Doc = *D;
2820 const Record *Category = Doc.getValueAsDef("Category");
2821 // If the category is "undocumented", then there cannot be any other
2822 // documentation categories (otherwise, the attribute would become
2823 // documented).
2824 std::string Cat = Category->getValueAsString("Name");
2825 bool Undocumented = Cat == "Undocumented";
2826 if (Undocumented && Docs.size() > 1)
2827 PrintFatalError(Doc.getLoc(),
2828 "Attribute is \"Undocumented\", but has multiple "
2829 "documentation categories");
2830
2831 if (!Undocumented)
2832 SplitDocs[Category].push_back(DocumentationData(Doc, Attr));
2833 }
2834 }
2835
2836 // Having split the attributes out based on what documentation goes where,
2837 // we can begin to generate sections of documentation.
2838 for (const auto &I : SplitDocs) {
2839 WriteCategoryHeader(I.first, OS);
2840
2841 // Walk over each of the attributes in the category and write out their
2842 // documentation.
2843 for (const auto &Doc : I.second)
2844 WriteDocumentation(Doc, OS);
2845 }
2846 }
2847
2848 } // end namespace clang
2849