1 //===- ClangAttrEmitter.cpp - Generate Clang attribute handling =-*- C++ -*--=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // These tablegen backends emit Clang attribute processing code
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ADT/SmallString.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/ADT/SmallSet.h"
17 #include "llvm/TableGen/Record.h"
18 #include "llvm/TableGen/StringMatcher.h"
19 #include "llvm/TableGen/TableGenBackend.h"
25 static const std::vector<StringRef>
26 getValueAsListOfStrings(Record &R, StringRef FieldName) {
27 ListInit *List = R.getValueAsListInit(FieldName);
28 assert (List && "Got a null ListInit");
30 std::vector<StringRef> Strings;
31 Strings.reserve(List->getSize());
33 for (ListInit::const_iterator i = List->begin(), e = List->end();
36 assert(*i && "Got a null element in a ListInit");
37 if (StringInit *S = dyn_cast<StringInit>(*i))
38 Strings.push_back(S->getValue());
40 assert(false && "Got a non-string, non-code element in a ListInit");
46 static std::string ReadPCHRecord(StringRef type) {
47 return StringSwitch<std::string>(type)
48 .EndsWith("Decl *", "GetLocalDeclAs<"
49 + std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])")
50 .Case("TypeSourceInfo *", "GetTypeSourceInfo(F, Record, Idx)")
51 .Case("Expr *", "ReadExpr(F)")
52 .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)")
53 .Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)")
54 .Default("Record[Idx++]");
57 // Assumes that the way to get the value is SA->getname()
58 static std::string WritePCHRecord(StringRef type, StringRef name) {
59 return StringSwitch<std::string>(type)
60 .EndsWith("Decl *", "AddDeclRef(" + std::string(name) +
62 .Case("TypeSourceInfo *",
63 "AddTypeSourceInfo(" + std::string(name) + ", Record);\n")
64 .Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
65 .Case("IdentifierInfo *",
66 "AddIdentifierRef(" + std::string(name) + ", Record);\n")
67 .Case("SourceLocation",
68 "AddSourceLocation(" + std::string(name) + ", Record);\n")
69 .Default("Record.push_back(" + std::string(name) + ");\n");
72 // Normalize attribute name by removing leading and trailing
73 // underscores. For example, __foo, foo__, __foo__ would
75 static StringRef NormalizeAttrName(StringRef AttrName) {
76 if (AttrName.startswith("__"))
77 AttrName = AttrName.substr(2, AttrName.size());
79 if (AttrName.endswith("__"))
80 AttrName = AttrName.substr(0, AttrName.size() - 2);
85 // Normalize attribute spelling only if the spelling has both leading
86 // and trailing underscores. For example, __ms_struct__ will be
87 // normalized to "ms_struct"; __cdecl will remain intact.
88 static StringRef NormalizeAttrSpelling(StringRef AttrSpelling) {
89 if (AttrSpelling.startswith("__") && AttrSpelling.endswith("__")) {
90 AttrSpelling = AttrSpelling.substr(2, AttrSpelling.size() - 4);
98 std::string lowerName, upperName;
103 Argument(Record &Arg, StringRef Attr)
104 : lowerName(Arg.getValueAsString("Name")), upperName(lowerName),
105 attrName(Attr), isOpt(false) {
106 if (!lowerName.empty()) {
107 lowerName[0] = std::tolower(lowerName[0]);
108 upperName[0] = std::toupper(upperName[0]);
111 virtual ~Argument() {}
113 StringRef getLowerName() const { return lowerName; }
114 StringRef getUpperName() const { return upperName; }
115 StringRef getAttrName() const { return attrName; }
117 bool isOptional() const { return isOpt; }
118 void setOptional(bool set) { isOpt = set; }
120 // These functions print the argument contents formatted in different ways.
121 virtual void writeAccessors(raw_ostream &OS) const = 0;
122 virtual void writeAccessorDefinitions(raw_ostream &OS) const {}
123 virtual void writeCloneArgs(raw_ostream &OS) const = 0;
124 virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0;
125 virtual void writeTemplateInstantiation(raw_ostream &OS) const {}
126 virtual void writeCtorBody(raw_ostream &OS) const {}
127 virtual void writeCtorInitializers(raw_ostream &OS) const = 0;
128 virtual void writeCtorDefaultInitializers(raw_ostream &OS) const = 0;
129 virtual void writeCtorParameters(raw_ostream &OS) const = 0;
130 virtual void writeDeclarations(raw_ostream &OS) const = 0;
131 virtual void writePCHReadArgs(raw_ostream &OS) const = 0;
132 virtual void writePCHReadDecls(raw_ostream &OS) const = 0;
133 virtual void writePCHWrite(raw_ostream &OS) const = 0;
134 virtual void writeValue(raw_ostream &OS) const = 0;
135 virtual void writeDump(raw_ostream &OS) const = 0;
136 virtual void writeDumpChildren(raw_ostream &OS) const {}
137 virtual void writeHasChildren(raw_ostream &OS) const { OS << "false"; }
139 virtual bool isEnumArg() const { return false; }
140 virtual bool isVariadicEnumArg() const { return false; }
143 class SimpleArgument : public Argument {
147 SimpleArgument(Record &Arg, StringRef Attr, std::string T)
148 : Argument(Arg, Attr), type(T)
151 std::string getType() const { return type; }
153 void writeAccessors(raw_ostream &OS) const {
154 OS << " " << type << " get" << getUpperName() << "() const {\n";
155 OS << " return " << getLowerName() << ";\n";
158 void writeCloneArgs(raw_ostream &OS) const {
159 OS << getLowerName();
161 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
162 OS << "A->get" << getUpperName() << "()";
164 void writeCtorInitializers(raw_ostream &OS) const {
165 OS << getLowerName() << "(" << getUpperName() << ")";
167 void writeCtorDefaultInitializers(raw_ostream &OS) const {
168 OS << getLowerName() << "()";
170 void writeCtorParameters(raw_ostream &OS) const {
171 OS << type << " " << getUpperName();
173 void writeDeclarations(raw_ostream &OS) const {
174 OS << type << " " << getLowerName() << ";";
176 void writePCHReadDecls(raw_ostream &OS) const {
177 std::string read = ReadPCHRecord(type);
178 OS << " " << type << " " << getLowerName() << " = " << read << ";\n";
180 void writePCHReadArgs(raw_ostream &OS) const {
181 OS << getLowerName();
183 void writePCHWrite(raw_ostream &OS) const {
184 OS << " " << WritePCHRecord(type, "SA->get" +
185 std::string(getUpperName()) + "()");
187 void writeValue(raw_ostream &OS) const {
188 if (type == "FunctionDecl *") {
189 OS << "\" << get" << getUpperName()
190 << "()->getNameInfo().getAsString() << \"";
191 } else if (type == "IdentifierInfo *") {
192 OS << "\" << get" << getUpperName() << "()->getName() << \"";
193 } else if (type == "TypeSourceInfo *") {
194 OS << "\" << get" << getUpperName() << "().getAsString() << \"";
195 } else if (type == "SourceLocation") {
196 OS << "\" << get" << getUpperName() << "().getRawEncoding() << \"";
198 OS << "\" << get" << getUpperName() << "() << \"";
201 void writeDump(raw_ostream &OS) const {
202 if (type == "FunctionDecl *") {
203 OS << " OS << \" \";\n";
204 OS << " dumpBareDeclRef(SA->get" << getUpperName() << "());\n";
205 } else if (type == "IdentifierInfo *") {
206 OS << " OS << \" \" << SA->get" << getUpperName()
207 << "()->getName();\n";
208 } else if (type == "TypeSourceInfo *") {
209 OS << " OS << \" \" << SA->get" << getUpperName()
210 << "().getAsString();\n";
211 } else if (type == "SourceLocation") {
212 OS << " OS << \" \";\n";
213 OS << " SA->get" << getUpperName() << "().print(OS, *SM);\n";
214 } else if (type == "bool") {
215 OS << " if (SA->get" << getUpperName() << "()) OS << \" "
216 << getUpperName() << "\";\n";
217 } else if (type == "int" || type == "unsigned") {
218 OS << " OS << \" \" << SA->get" << getUpperName() << "();\n";
220 llvm_unreachable("Unknown SimpleArgument type!");
225 class StringArgument : public Argument {
227 StringArgument(Record &Arg, StringRef Attr)
228 : Argument(Arg, Attr)
231 void writeAccessors(raw_ostream &OS) const {
232 OS << " llvm::StringRef get" << getUpperName() << "() const {\n";
233 OS << " return llvm::StringRef(" << getLowerName() << ", "
234 << getLowerName() << "Length);\n";
236 OS << " unsigned get" << getUpperName() << "Length() const {\n";
237 OS << " return " << getLowerName() << "Length;\n";
239 OS << " void set" << getUpperName()
240 << "(ASTContext &C, llvm::StringRef S) {\n";
241 OS << " " << getLowerName() << "Length = S.size();\n";
242 OS << " this->" << getLowerName() << " = new (C, 1) char ["
243 << getLowerName() << "Length];\n";
244 OS << " std::memcpy(this->" << getLowerName() << ", S.data(), "
245 << getLowerName() << "Length);\n";
248 void writeCloneArgs(raw_ostream &OS) const {
249 OS << "get" << getUpperName() << "()";
251 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
252 OS << "A->get" << getUpperName() << "()";
254 void writeCtorBody(raw_ostream &OS) const {
255 OS << " std::memcpy(" << getLowerName() << ", " << getUpperName()
256 << ".data(), " << getLowerName() << "Length);";
258 void writeCtorInitializers(raw_ostream &OS) const {
259 OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
260 << getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
263 void writeCtorDefaultInitializers(raw_ostream &OS) const {
264 OS << getLowerName() << "Length(0)," << getLowerName() << "(0)";
266 void writeCtorParameters(raw_ostream &OS) const {
267 OS << "llvm::StringRef " << getUpperName();
269 void writeDeclarations(raw_ostream &OS) const {
270 OS << "unsigned " << getLowerName() << "Length;\n";
271 OS << "char *" << getLowerName() << ";";
273 void writePCHReadDecls(raw_ostream &OS) const {
274 OS << " std::string " << getLowerName()
275 << "= ReadString(Record, Idx);\n";
277 void writePCHReadArgs(raw_ostream &OS) const {
278 OS << getLowerName();
280 void writePCHWrite(raw_ostream &OS) const {
281 OS << " AddString(SA->get" << getUpperName() << "(), Record);\n";
283 void writeValue(raw_ostream &OS) const {
284 OS << "\\\"\" << get" << getUpperName() << "() << \"\\\"";
286 void writeDump(raw_ostream &OS) const {
287 OS << " OS << \" \\\"\" << SA->get" << getUpperName()
288 << "() << \"\\\"\";\n";
292 class AlignedArgument : public Argument {
294 AlignedArgument(Record &Arg, StringRef Attr)
295 : Argument(Arg, Attr)
298 void writeAccessors(raw_ostream &OS) const {
299 OS << " bool is" << getUpperName() << "Dependent() const;\n";
301 OS << " unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";
303 OS << " bool is" << getUpperName() << "Expr() const {\n";
304 OS << " return is" << getLowerName() << "Expr;\n";
307 OS << " Expr *get" << getUpperName() << "Expr() const {\n";
308 OS << " assert(is" << getLowerName() << "Expr);\n";
309 OS << " return " << getLowerName() << "Expr;\n";
312 OS << " TypeSourceInfo *get" << getUpperName() << "Type() const {\n";
313 OS << " assert(!is" << getLowerName() << "Expr);\n";
314 OS << " return " << getLowerName() << "Type;\n";
317 void writeAccessorDefinitions(raw_ostream &OS) const {
318 OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
319 << "Dependent() const {\n";
320 OS << " if (is" << getLowerName() << "Expr)\n";
321 OS << " return " << getLowerName() << "Expr && (" << getLowerName()
322 << "Expr->isValueDependent() || " << getLowerName()
323 << "Expr->isTypeDependent());\n";
325 OS << " return " << getLowerName()
326 << "Type->getType()->isDependentType();\n";
329 // FIXME: Do not do the calculation here
330 // FIXME: Handle types correctly
331 // A null pointer means maximum alignment
332 // FIXME: Load the platform-specific maximum alignment, rather than
334 OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName()
335 << "(ASTContext &Ctx) const {\n";
336 OS << " assert(!is" << getUpperName() << "Dependent());\n";
337 OS << " if (is" << getLowerName() << "Expr)\n";
338 OS << " return (" << getLowerName() << "Expr ? " << getLowerName()
339 << "Expr->EvaluateKnownConstInt(Ctx).getZExtValue() : 16)"
340 << "* Ctx.getCharWidth();\n";
342 OS << " return 0; // FIXME\n";
345 void writeCloneArgs(raw_ostream &OS) const {
346 OS << "is" << getLowerName() << "Expr, is" << getLowerName()
347 << "Expr ? static_cast<void*>(" << getLowerName()
348 << "Expr) : " << getLowerName()
351 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
352 // FIXME: move the definition in Sema::InstantiateAttrs to here.
353 // In the meantime, aligned attributes are cloned.
355 void writeCtorBody(raw_ostream &OS) const {
356 OS << " if (is" << getLowerName() << "Expr)\n";
357 OS << " " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
358 << getUpperName() << ");\n";
360 OS << " " << getLowerName()
361 << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
364 void writeCtorInitializers(raw_ostream &OS) const {
365 OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
367 void writeCtorDefaultInitializers(raw_ostream &OS) const {
368 OS << "is" << getLowerName() << "Expr(false)";
370 void writeCtorParameters(raw_ostream &OS) const {
371 OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
373 void writeDeclarations(raw_ostream &OS) const {
374 OS << "bool is" << getLowerName() << "Expr;\n";
376 OS << "Expr *" << getLowerName() << "Expr;\n";
377 OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
380 void writePCHReadArgs(raw_ostream &OS) const {
381 OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
383 void writePCHReadDecls(raw_ostream &OS) const {
384 OS << " bool is" << getLowerName() << "Expr = Record[Idx++];\n";
385 OS << " void *" << getLowerName() << "Ptr;\n";
386 OS << " if (is" << getLowerName() << "Expr)\n";
387 OS << " " << getLowerName() << "Ptr = ReadExpr(F);\n";
389 OS << " " << getLowerName()
390 << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n";
392 void writePCHWrite(raw_ostream &OS) const {
393 OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n";
394 OS << " if (SA->is" << getUpperName() << "Expr())\n";
395 OS << " AddStmt(SA->get" << getUpperName() << "Expr());\n";
397 OS << " AddTypeSourceInfo(SA->get" << getUpperName()
398 << "Type(), Record);\n";
400 void writeValue(raw_ostream &OS) const {
402 << " " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n"
405 void writeDump(raw_ostream &OS) const {
407 void writeDumpChildren(raw_ostream &OS) const {
408 OS << " if (SA->is" << getUpperName() << "Expr()) {\n";
409 OS << " lastChild();\n";
410 OS << " dumpStmt(SA->get" << getUpperName() << "Expr());\n";
412 OS << " dumpType(SA->get" << getUpperName()
413 << "Type()->getType());\n";
415 void writeHasChildren(raw_ostream &OS) const {
416 OS << "SA->is" << getUpperName() << "Expr()";
420 class VariadicArgument : public Argument {
424 VariadicArgument(Record &Arg, StringRef Attr, std::string T)
425 : Argument(Arg, Attr), type(T)
428 std::string getType() const { return type; }
430 void writeAccessors(raw_ostream &OS) const {
431 OS << " typedef " << type << "* " << getLowerName() << "_iterator;\n";
432 OS << " " << getLowerName() << "_iterator " << getLowerName()
433 << "_begin() const {\n";
434 OS << " return " << getLowerName() << ";\n";
436 OS << " " << getLowerName() << "_iterator " << getLowerName()
437 << "_end() const {\n";
438 OS << " return " << getLowerName() << " + " << getLowerName()
441 OS << " unsigned " << getLowerName() << "_size() const {\n"
442 << " return " << getLowerName() << "Size;\n";
445 void writeCloneArgs(raw_ostream &OS) const {
446 OS << getLowerName() << ", " << getLowerName() << "Size";
448 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
449 // This isn't elegant, but we have to go through public methods...
450 OS << "A->" << getLowerName() << "_begin(), "
451 << "A->" << getLowerName() << "_size()";
453 void writeCtorBody(raw_ostream &OS) const {
454 // FIXME: memcpy is not safe on non-trivial types.
455 OS << " std::memcpy(" << getLowerName() << ", " << getUpperName()
456 << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n";
458 void writeCtorInitializers(raw_ostream &OS) const {
459 OS << getLowerName() << "Size(" << getUpperName() << "Size), "
460 << getLowerName() << "(new (Ctx, 16) " << getType() << "["
461 << getLowerName() << "Size])";
463 void writeCtorDefaultInitializers(raw_ostream &OS) const {
464 OS << getLowerName() << "Size(0), " << getLowerName() << "(0)";
466 void writeCtorParameters(raw_ostream &OS) const {
467 OS << getType() << " *" << getUpperName() << ", unsigned "
468 << getUpperName() << "Size";
470 void writeDeclarations(raw_ostream &OS) const {
471 OS << " unsigned " << getLowerName() << "Size;\n";
472 OS << " " << getType() << " *" << getLowerName() << ";";
474 void writePCHReadDecls(raw_ostream &OS) const {
475 OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n";
476 OS << " SmallVector<" << type << ", 4> " << getLowerName()
478 OS << " " << getLowerName() << ".reserve(" << getLowerName()
480 OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
482 std::string read = ReadPCHRecord(type);
483 OS << " " << getLowerName() << ".push_back(" << read << ");\n";
485 void writePCHReadArgs(raw_ostream &OS) const {
486 OS << getLowerName() << ".data(), " << getLowerName() << "Size";
488 void writePCHWrite(raw_ostream &OS) const{
489 OS << " Record.push_back(SA->" << getLowerName() << "_size());\n";
490 OS << " for (" << getAttrName() << "Attr::" << getLowerName()
491 << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
492 << getLowerName() << "_end(); i != e; ++i)\n";
493 OS << " " << WritePCHRecord(type, "(*i)");
495 void writeValue(raw_ostream &OS) const {
497 OS << " bool isFirst = true;\n"
498 << " for (" << getAttrName() << "Attr::" << getLowerName()
499 << "_iterator i = " << getLowerName() << "_begin(), e = "
500 << getLowerName() << "_end(); i != e; ++i) {\n"
501 << " if (isFirst) isFirst = false;\n"
502 << " else OS << \", \";\n"
507 void writeDump(raw_ostream &OS) const {
508 OS << " for (" << getAttrName() << "Attr::" << getLowerName()
509 << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
510 << getLowerName() << "_end(); I != E; ++I)\n";
511 OS << " OS << \" \" << *I;\n";
515 class EnumArgument : public Argument {
517 std::vector<StringRef> values, enums, uniques;
519 EnumArgument(Record &Arg, StringRef Attr)
520 : Argument(Arg, Attr), type(Arg.getValueAsString("Type")),
521 values(getValueAsListOfStrings(Arg, "Values")),
522 enums(getValueAsListOfStrings(Arg, "Enums")),
525 // Calculate the various enum values
526 std::sort(uniques.begin(), uniques.end());
527 uniques.erase(std::unique(uniques.begin(), uniques.end()), uniques.end());
528 // FIXME: Emit a proper error
529 assert(!uniques.empty());
532 bool isEnumArg() const { return true; }
534 void writeAccessors(raw_ostream &OS) const {
535 OS << " " << type << " get" << getUpperName() << "() const {\n";
536 OS << " return " << getLowerName() << ";\n";
539 void writeCloneArgs(raw_ostream &OS) const {
540 OS << getLowerName();
542 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
543 OS << "A->get" << getUpperName() << "()";
545 void writeCtorInitializers(raw_ostream &OS) const {
546 OS << getLowerName() << "(" << getUpperName() << ")";
548 void writeCtorDefaultInitializers(raw_ostream &OS) const {
549 OS << getLowerName() << "(" << type << "(0))";
551 void writeCtorParameters(raw_ostream &OS) const {
552 OS << type << " " << getUpperName();
554 void writeDeclarations(raw_ostream &OS) const {
555 std::vector<StringRef>::const_iterator i = uniques.begin(),
557 // The last one needs to not have a comma.
561 OS << " enum " << type << " {\n";
563 OS << " " << *i << ",\n";
564 OS << " " << *e << "\n";
567 OS << " " << type << " " << getLowerName() << ";";
569 void writePCHReadDecls(raw_ostream &OS) const {
570 OS << " " << getAttrName() << "Attr::" << type << " " << getLowerName()
571 << "(static_cast<" << getAttrName() << "Attr::" << type
572 << ">(Record[Idx++]));\n";
574 void writePCHReadArgs(raw_ostream &OS) const {
575 OS << getLowerName();
577 void writePCHWrite(raw_ostream &OS) const {
578 OS << "Record.push_back(SA->get" << getUpperName() << "());\n";
580 void writeValue(raw_ostream &OS) const {
581 OS << "\" << get" << getUpperName() << "() << \"";
583 void writeDump(raw_ostream &OS) const {
584 OS << " switch(SA->get" << getUpperName() << "()) {\n";
585 for (std::vector<StringRef>::const_iterator I = uniques.begin(),
586 E = uniques.end(); I != E; ++I) {
587 OS << " case " << getAttrName() << "Attr::" << *I << ":\n";
588 OS << " OS << \" " << *I << "\";\n";
594 void writeConversion(raw_ostream &OS) const {
595 OS << " static bool ConvertStrTo" << type << "(StringRef Val, ";
596 OS << type << " &Out) {\n";
597 OS << " Optional<" << type << "> R = llvm::StringSwitch<Optional<";
598 OS << type << "> >(Val)\n";
599 for (size_t I = 0; I < enums.size(); ++I) {
600 OS << " .Case(\"" << values[I] << "\", ";
601 OS << getAttrName() << "Attr::" << enums[I] << ")\n";
603 OS << " .Default(Optional<" << type << ">());\n";
605 OS << " Out = *R;\n return true;\n }\n";
606 OS << " return false;\n";
611 class VariadicEnumArgument: public VariadicArgument {
612 std::string type, QualifiedTypeName;
613 std::vector<StringRef> values, enums, uniques;
615 VariadicEnumArgument(Record &Arg, StringRef Attr)
616 : VariadicArgument(Arg, Attr, Arg.getValueAsString("Type")),
617 type(Arg.getValueAsString("Type")),
618 values(getValueAsListOfStrings(Arg, "Values")),
619 enums(getValueAsListOfStrings(Arg, "Enums")),
622 // Calculate the various enum values
623 std::sort(uniques.begin(), uniques.end());
624 uniques.erase(std::unique(uniques.begin(), uniques.end()), uniques.end());
626 QualifiedTypeName = getAttrName().str() + "Attr::" + type;
628 // FIXME: Emit a proper error
629 assert(!uniques.empty());
632 bool isVariadicEnumArg() const { return true; }
634 void writeDeclarations(raw_ostream &OS) const {
635 std::vector<StringRef>::const_iterator i = uniques.begin(),
637 // The last one needs to not have a comma.
641 OS << " enum " << type << " {\n";
643 OS << " " << *i << ",\n";
644 OS << " " << *e << "\n";
648 VariadicArgument::writeDeclarations(OS);
650 void writeDump(raw_ostream &OS) const {
651 OS << " for (" << getAttrName() << "Attr::" << getLowerName()
652 << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
653 << getLowerName() << "_end(); I != E; ++I) {\n";
654 OS << " switch(*I) {\n";
655 for (std::vector<StringRef>::const_iterator UI = uniques.begin(),
656 UE = uniques.end(); UI != UE; ++UI) {
657 OS << " case " << getAttrName() << "Attr::" << *UI << ":\n";
658 OS << " OS << \" " << *UI << "\";\n";
664 void writePCHReadDecls(raw_ostream &OS) const {
665 OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n";
666 OS << " SmallVector<" << QualifiedTypeName << ", 4> " << getLowerName()
668 OS << " " << getLowerName() << ".reserve(" << getLowerName()
670 OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
671 OS << " " << getLowerName() << ".push_back(" << "static_cast<"
672 << QualifiedTypeName << ">(Record[Idx++]));\n";
674 void writePCHWrite(raw_ostream &OS) const{
675 OS << " Record.push_back(SA->" << getLowerName() << "_size());\n";
676 OS << " for (" << getAttrName() << "Attr::" << getLowerName()
677 << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
678 << getLowerName() << "_end(); i != e; ++i)\n";
679 OS << " " << WritePCHRecord(QualifiedTypeName, "(*i)");
681 void writeConversion(raw_ostream &OS) const {
682 OS << " static bool ConvertStrTo" << type << "(StringRef Val, ";
683 OS << type << " &Out) {\n";
684 OS << " Optional<" << type << "> R = llvm::StringSwitch<Optional<";
685 OS << type << "> >(Val)\n";
686 for (size_t I = 0; I < enums.size(); ++I) {
687 OS << " .Case(\"" << values[I] << "\", ";
688 OS << getAttrName() << "Attr::" << enums[I] << ")\n";
690 OS << " .Default(Optional<" << type << ">());\n";
692 OS << " Out = *R;\n return true;\n }\n";
693 OS << " return false;\n";
698 class VersionArgument : public Argument {
700 VersionArgument(Record &Arg, StringRef Attr)
701 : Argument(Arg, Attr)
704 void writeAccessors(raw_ostream &OS) const {
705 OS << " VersionTuple get" << getUpperName() << "() const {\n";
706 OS << " return " << getLowerName() << ";\n";
708 OS << " void set" << getUpperName()
709 << "(ASTContext &C, VersionTuple V) {\n";
710 OS << " " << getLowerName() << " = V;\n";
713 void writeCloneArgs(raw_ostream &OS) const {
714 OS << "get" << getUpperName() << "()";
716 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
717 OS << "A->get" << getUpperName() << "()";
719 void writeCtorBody(raw_ostream &OS) const {
721 void writeCtorInitializers(raw_ostream &OS) const {
722 OS << getLowerName() << "(" << getUpperName() << ")";
724 void writeCtorDefaultInitializers(raw_ostream &OS) const {
725 OS << getLowerName() << "()";
727 void writeCtorParameters(raw_ostream &OS) const {
728 OS << "VersionTuple " << getUpperName();
730 void writeDeclarations(raw_ostream &OS) const {
731 OS << "VersionTuple " << getLowerName() << ";\n";
733 void writePCHReadDecls(raw_ostream &OS) const {
734 OS << " VersionTuple " << getLowerName()
735 << "= ReadVersionTuple(Record, Idx);\n";
737 void writePCHReadArgs(raw_ostream &OS) const {
738 OS << getLowerName();
740 void writePCHWrite(raw_ostream &OS) const {
741 OS << " AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n";
743 void writeValue(raw_ostream &OS) const {
744 OS << getLowerName() << "=\" << get" << getUpperName() << "() << \"";
746 void writeDump(raw_ostream &OS) const {
747 OS << " OS << \" \" << SA->get" << getUpperName() << "();\n";
751 class ExprArgument : public SimpleArgument {
753 ExprArgument(Record &Arg, StringRef Attr)
754 : SimpleArgument(Arg, Attr, "Expr *")
757 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
758 OS << "tempInst" << getUpperName();
761 void writeTemplateInstantiation(raw_ostream &OS) const {
762 OS << " " << getType() << " tempInst" << getUpperName() << ";\n";
764 OS << " EnterExpressionEvaluationContext "
765 << "Unevaluated(S, Sema::Unevaluated);\n";
766 OS << " ExprResult " << "Result = S.SubstExpr("
767 << "A->get" << getUpperName() << "(), TemplateArgs);\n";
768 OS << " tempInst" << getUpperName() << " = "
769 << "Result.takeAs<Expr>();\n";
773 void writeDump(raw_ostream &OS) const {
776 void writeDumpChildren(raw_ostream &OS) const {
777 OS << " lastChild();\n";
778 OS << " dumpStmt(SA->get" << getUpperName() << "());\n";
780 void writeHasChildren(raw_ostream &OS) const { OS << "true"; }
783 class VariadicExprArgument : public VariadicArgument {
785 VariadicExprArgument(Record &Arg, StringRef Attr)
786 : VariadicArgument(Arg, Attr, "Expr *")
789 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
790 OS << "tempInst" << getUpperName() << ", "
791 << "A->" << getLowerName() << "_size()";
794 void writeTemplateInstantiation(raw_ostream &OS) const {
795 OS << " " << getType() << " *tempInst" << getUpperName()
796 << " = new (C, 16) " << getType()
797 << "[A->" << getLowerName() << "_size()];\n";
799 OS << " EnterExpressionEvaluationContext "
800 << "Unevaluated(S, Sema::Unevaluated);\n";
801 OS << " " << getType() << " *TI = tempInst" << getUpperName()
803 OS << " " << getType() << " *I = A->" << getLowerName()
805 OS << " " << getType() << " *E = A->" << getLowerName()
807 OS << " for (; I != E; ++I, ++TI) {\n";
808 OS << " ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n";
809 OS << " *TI = Result.takeAs<Expr>();\n";
814 void writeDump(raw_ostream &OS) const {
817 void writeDumpChildren(raw_ostream &OS) const {
818 OS << " for (" << getAttrName() << "Attr::" << getLowerName()
819 << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
820 << getLowerName() << "_end(); I != E; ++I) {\n";
821 OS << " if (I + 1 == E)\n";
822 OS << " lastChild();\n";
823 OS << " dumpStmt(*I);\n";
827 void writeHasChildren(raw_ostream &OS) const {
828 OS << "SA->" << getLowerName() << "_begin() != "
829 << "SA->" << getLowerName() << "_end()";
833 class TypeArgument : public SimpleArgument {
835 TypeArgument(Record &Arg, StringRef Attr)
836 : SimpleArgument(Arg, Attr, "TypeSourceInfo *")
839 void writeAccessors(raw_ostream &OS) const {
840 OS << " QualType get" << getUpperName() << "() const {\n";
841 OS << " return " << getLowerName() << "->getType();\n";
843 OS << " " << getType() << " get" << getUpperName() << "Loc() const {\n";
844 OS << " return " << getLowerName() << ";\n";
847 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
848 OS << "A->get" << getUpperName() << "Loc()";
850 void writePCHWrite(raw_ostream &OS) const {
851 OS << " " << WritePCHRecord(
852 getType(), "SA->get" + std::string(getUpperName()) + "Loc()");
857 static Argument *createArgument(Record &Arg, StringRef Attr,
858 Record *Search = 0) {
863 llvm::StringRef ArgName = Search->getName();
865 if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr);
866 else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr);
867 else if (ArgName == "ExprArgument") Ptr = new ExprArgument(Arg, Attr);
868 else if (ArgName == "FunctionArgument")
869 Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *");
870 else if (ArgName == "IdentifierArgument")
871 Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
872 else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr,
874 else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
875 else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
876 else if (ArgName == "TypeArgument") Ptr = new TypeArgument(Arg, Attr);
877 else if (ArgName == "UnsignedArgument")
878 Ptr = new SimpleArgument(Arg, Attr, "unsigned");
879 else if (ArgName == "SourceLocArgument")
880 Ptr = new SimpleArgument(Arg, Attr, "SourceLocation");
881 else if (ArgName == "VariadicUnsignedArgument")
882 Ptr = new VariadicArgument(Arg, Attr, "unsigned");
883 else if (ArgName == "VariadicEnumArgument")
884 Ptr = new VariadicEnumArgument(Arg, Attr);
885 else if (ArgName == "VariadicExprArgument")
886 Ptr = new VariadicExprArgument(Arg, Attr);
887 else if (ArgName == "VersionArgument")
888 Ptr = new VersionArgument(Arg, Attr);
891 std::vector<Record*> Bases = Search->getSuperClasses();
892 for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end();
894 Ptr = createArgument(Arg, Attr, *i);
900 if (Ptr && Arg.getValueAsBit("Optional"))
901 Ptr->setOptional(true);
906 static void writeAvailabilityValue(raw_ostream &OS) {
907 OS << "\" << getPlatform()->getName();\n"
908 << " if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n"
909 << " if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n"
910 << " if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n"
911 << " if (getUnavailable()) OS << \", unavailable\";\n"
915 static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args,
917 std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
919 OS << "void " << R.getName() << "Attr::printPretty("
920 << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n";
922 if (Spellings.size() == 0) {
928 " switch (SpellingListIndex) {\n"
930 " llvm_unreachable(\"Unknown attribute spelling!\");\n"
933 for (unsigned I = 0; I < Spellings.size(); ++ I) {
934 llvm::SmallString<16> Prefix;
935 llvm::SmallString<8> Suffix;
936 // The actual spelling of the name and namespace (if applicable)
937 // of an attribute without considering prefix and suffix.
938 llvm::SmallString<64> Spelling;
939 std::string Name = Spellings[I]->getValueAsString("Name");
940 std::string Variety = Spellings[I]->getValueAsString("Variety");
942 if (Variety == "GNU") {
943 Prefix = " __attribute__((";
945 } else if (Variety == "CXX11") {
948 std::string Namespace = Spellings[I]->getValueAsString("Namespace");
949 if (Namespace != "") {
950 Spelling += Namespace;
953 } else if (Variety == "Declspec") {
954 Prefix = " __declspec(";
956 } else if (Variety == "Keyword") {
960 llvm_unreachable("Unknown attribute syntax variety!");
966 " case " << I << " : {\n"
967 " OS << \"" + Prefix.str() + Spelling.str();
969 if (Args.size()) OS << "(";
970 if (Spelling == "availability") {
971 writeAvailabilityValue(OS);
973 for (std::vector<Argument*>::const_iterator I = Args.begin(),
974 E = Args.end(); I != E; ++ I) {
975 if (I != Args.begin()) OS << ", ";
976 (*I)->writeValue(OS);
980 if (Args.size()) OS << ")";
981 OS << Suffix.str() + "\";\n";
988 // End of the switch statement.
990 // End of the print function.
994 /// \brief Return the index of a spelling in a spelling list.
995 static unsigned getSpellingListIndex(const std::vector<Record*> &SpellingList,
996 const Record &Spelling) {
997 assert(SpellingList.size() && "Spelling list is empty!");
999 for (unsigned Index = 0; Index < SpellingList.size(); ++Index) {
1000 Record *S = SpellingList[Index];
1001 if (S->getValueAsString("Variety") != Spelling.getValueAsString("Variety"))
1003 if (S->getValueAsString("Variety") == "CXX11" &&
1004 S->getValueAsString("Namespace") !=
1005 Spelling.getValueAsString("Namespace"))
1007 if (S->getValueAsString("Name") != Spelling.getValueAsString("Name"))
1013 llvm_unreachable("Unknown spelling!");
1016 static void writeAttrAccessorDefinition(Record &R, raw_ostream &OS) {
1017 std::vector<Record*> Accessors = R.getValueAsListOfDefs("Accessors");
1018 for (std::vector<Record*>::const_iterator I = Accessors.begin(),
1019 E = Accessors.end(); I != E; ++I) {
1020 Record *Accessor = *I;
1021 std::string Name = Accessor->getValueAsString("Name");
1022 std::vector<Record*> Spellings = Accessor->getValueAsListOfDefs(
1024 std::vector<Record*> SpellingList = R.getValueAsListOfDefs("Spellings");
1025 assert(SpellingList.size() &&
1026 "Attribute with empty spelling list can't have accessors!");
1028 OS << " bool " << Name << "() const { return SpellingListIndex == ";
1029 for (unsigned Index = 0; Index < Spellings.size(); ++Index) {
1030 OS << getSpellingListIndex(SpellingList, *Spellings[Index]);
1031 if (Index != Spellings.size() -1)
1032 OS << " ||\n SpellingListIndex == ";
1041 // Emits the class definitions for attributes.
1042 void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
1043 emitSourceFileHeader("Attribute classes' definitions", OS);
1045 OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
1046 OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n";
1048 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1050 for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
1054 if (!R.getValueAsBit("ASTNode"))
1057 const std::vector<Record *> Supers = R.getSuperClasses();
1058 assert(!Supers.empty() && "Forgot to specify a superclass for the attr");
1059 std::string SuperName;
1060 for (std::vector<Record *>::const_reverse_iterator I = Supers.rbegin(),
1061 E = Supers.rend(); I != E; ++I) {
1062 const Record &R = **I;
1063 if (R.getName() != "TargetSpecificAttr" && SuperName.empty())
1064 SuperName = R.getName();
1067 OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n";
1069 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
1070 std::vector<Argument*> Args;
1071 std::vector<Argument*>::iterator ai, ae;
1072 Args.reserve(ArgRecords.size());
1074 for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
1075 re = ArgRecords.end();
1077 Record &ArgRecord = **ri;
1078 Argument *Arg = createArgument(ArgRecord, R.getName());
1080 Args.push_back(Arg);
1082 Arg->writeDeclarations(OS);
1088 OS << "\n public:\n";
1089 OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n";
1091 bool HasOpt = false;
1092 for (ai = Args.begin(); ai != ae; ++ai) {
1094 (*ai)->writeCtorParameters(OS);
1096 if ((*ai)->isOptional())
1101 OS << "unsigned SI = 0\n";
1104 OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n";
1106 for (ai = Args.begin(); ai != ae; ++ai) {
1108 (*ai)->writeCtorInitializers(OS);
1114 for (ai = Args.begin(); ai != ae; ++ai) {
1115 (*ai)->writeCtorBody(OS);
1120 // If there are optional arguments, write out a constructor that elides the
1121 // optional arguments as well.
1123 OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n";
1124 for (ai = Args.begin(); ai != ae; ++ai) {
1125 if (!(*ai)->isOptional()) {
1127 (*ai)->writeCtorParameters(OS);
1133 OS << "unsigned SI = 0\n";
1136 OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n";
1138 for (ai = Args.begin(); ai != ae; ++ai) {
1140 (*ai)->writeCtorDefaultInitializers(OS);
1146 for (ai = Args.begin(); ai != ae; ++ai) {
1147 if (!(*ai)->isOptional()) {
1148 (*ai)->writeCtorBody(OS);
1155 OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n";
1156 OS << " virtual void printPretty(raw_ostream &OS,\n"
1157 << " const PrintingPolicy &Policy) const;\n";
1159 writeAttrAccessorDefinition(R, OS);
1161 for (ai = Args.begin(); ai != ae; ++ai) {
1162 (*ai)->writeAccessors(OS);
1165 if ((*ai)->isEnumArg()) {
1166 EnumArgument *EA = (EnumArgument *)*ai;
1167 EA->writeConversion(OS);
1168 } else if ((*ai)->isVariadicEnumArg()) {
1169 VariadicEnumArgument *VEA = (VariadicEnumArgument *)*ai;
1170 VEA->writeConversion(OS);
1174 OS << R.getValueAsString("AdditionalMembers");
1177 OS << " static bool classof(const Attr *A) { return A->getKind() == "
1178 << "attr::" << R.getName() << "; }\n";
1180 bool LateParsed = R.getValueAsBit("LateParsed");
1181 OS << " virtual bool isLateParsed() const { return "
1182 << LateParsed << "; }\n";
1190 static bool isIdentifierArgument(Record *Arg) {
1191 return !Arg->getSuperClasses().empty() &&
1192 llvm::StringSwitch<bool>(Arg->getSuperClasses().back()->getName())
1193 .Case("IdentifierArgument", true)
1194 .Case("EnumArgument", true)
1198 /// \brief Emits the first-argument-is-type property for attributes.
1199 void EmitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
1200 emitSourceFileHeader("llvm::StringSwitch code to match attributes with a "
1201 "type argument", OS);
1203 std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
1205 for (std::vector<Record *>::iterator I = Attrs.begin(), E = Attrs.end();
1209 // Determine whether the first argument is a type.
1210 std::vector<Record *> Args = Attr.getValueAsListOfDefs("Args");
1214 if (Args[0]->getSuperClasses().back()->getName() != "TypeArgument")
1217 // All these spellings take a single type argument.
1218 std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1219 std::set<std::string> Emitted;
1220 for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1221 E = Spellings.end(); I != E; ++I) {
1222 if (Emitted.insert((*I)->getValueAsString("Name")).second)
1223 OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", "
1229 // Emits the first-argument-is-identifier property for attributes.
1230 void EmitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS) {
1231 emitSourceFileHeader("llvm::StringSwitch code to match attributes with "
1232 "an identifier argument", OS);
1234 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1236 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1240 // Determine whether the first argument is an identifier.
1241 std::vector<Record *> Args = Attr.getValueAsListOfDefs("Args");
1242 if (Args.empty() || !isIdentifierArgument(Args[0]))
1245 // All these spellings take an identifier argument.
1246 std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1247 std::set<std::string> Emitted;
1248 for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1249 E = Spellings.end(); I != E; ++I) {
1250 if (Emitted.insert((*I)->getValueAsString("Name")).second)
1251 OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", "
1257 // Emits the class method definitions for attributes.
1258 void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
1259 emitSourceFileHeader("Attribute classes' member function definitions", OS);
1261 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1262 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re;
1263 std::vector<Argument*>::iterator ai, ae;
1265 for (; i != e; ++i) {
1268 if (!R.getValueAsBit("ASTNode"))
1271 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
1272 std::vector<Argument*> Args;
1273 for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri)
1274 Args.push_back(createArgument(**ri, R.getName()));
1276 for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
1277 (*ai)->writeAccessorDefinitions(OS);
1279 OS << R.getName() << "Attr *" << R.getName()
1280 << "Attr::clone(ASTContext &C) const {\n";
1281 OS << " return new (C) " << R.getName() << "Attr(getLocation(), C";
1282 for (ai = Args.begin(); ai != ae; ++ai) {
1284 (*ai)->writeCloneArgs(OS);
1286 OS << ", getSpellingListIndex());\n}\n\n";
1288 writePrettyPrintFunction(R, Args, OS);
1292 } // end namespace clang
1294 static void EmitAttrList(raw_ostream &OS, StringRef Class,
1295 const std::vector<Record*> &AttrList) {
1296 std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end();
1299 // Move the end iterator back to emit the last attribute.
1300 for(--e; i != e; ++i) {
1301 if (!(*i)->getValueAsBit("ASTNode"))
1304 OS << Class << "(" << (*i)->getName() << ")\n";
1307 OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n";
1313 // Emits the enumeration list for attributes.
1314 void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
1315 emitSourceFileHeader("List of all attributes that Clang recognizes", OS);
1317 OS << "#ifndef LAST_ATTR\n";
1318 OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n";
1321 OS << "#ifndef INHERITABLE_ATTR\n";
1322 OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n";
1325 OS << "#ifndef LAST_INHERITABLE_ATTR\n";
1326 OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
1329 OS << "#ifndef INHERITABLE_PARAM_ATTR\n";
1330 OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n";
1333 OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n";
1334 OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)"
1335 " INHERITABLE_PARAM_ATTR(NAME)\n";
1338 OS << "#ifndef MS_INHERITANCE_ATTR\n";
1339 OS << "#define MS_INHERITANCE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
1342 OS << "#ifndef LAST_MS_INHERITANCE_ATTR\n";
1343 OS << "#define LAST_MS_INHERITANCE_ATTR(NAME)"
1344 " MS_INHERITANCE_ATTR(NAME)\n";
1347 Record *InhClass = Records.getClass("InheritableAttr");
1348 Record *InhParamClass = Records.getClass("InheritableParamAttr");
1349 Record *MSInheritanceClass = Records.getClass("MSInheritanceAttr");
1350 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
1351 NonInhAttrs, InhAttrs, InhParamAttrs, MSInhAttrs;
1352 for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
1354 if (!(*i)->getValueAsBit("ASTNode"))
1357 if ((*i)->isSubClassOf(InhParamClass))
1358 InhParamAttrs.push_back(*i);
1359 else if ((*i)->isSubClassOf(MSInheritanceClass))
1360 MSInhAttrs.push_back(*i);
1361 else if ((*i)->isSubClassOf(InhClass))
1362 InhAttrs.push_back(*i);
1364 NonInhAttrs.push_back(*i);
1367 EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
1368 EmitAttrList(OS, "MS_INHERITANCE_ATTR", MSInhAttrs);
1369 EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
1370 EmitAttrList(OS, "ATTR", NonInhAttrs);
1372 OS << "#undef LAST_ATTR\n";
1373 OS << "#undef INHERITABLE_ATTR\n";
1374 OS << "#undef MS_INHERITANCE_ATTR\n";
1375 OS << "#undef LAST_INHERITABLE_ATTR\n";
1376 OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
1377 OS << "#undef LAST_MS_INHERITANCE_ATTR\n";
1378 OS << "#undef ATTR\n";
1381 // Emits the code to read an attribute from a precompiled header.
1382 void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
1383 emitSourceFileHeader("Attribute deserialization code", OS);
1385 Record *InhClass = Records.getClass("InheritableAttr");
1386 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
1388 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
1389 std::vector<Argument*> Args;
1390 std::vector<Argument*>::iterator ri, re;
1392 OS << " switch (Kind) {\n";
1393 OS << " default:\n";
1394 OS << " assert(0 && \"Unknown attribute!\");\n";
1396 for (; i != e; ++i) {
1398 if (!R.getValueAsBit("ASTNode"))
1401 OS << " case attr::" << R.getName() << ": {\n";
1402 if (R.isSubClassOf(InhClass))
1403 OS << " bool isInherited = Record[Idx++];\n";
1404 ArgRecords = R.getValueAsListOfDefs("Args");
1406 for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) {
1407 Argument *A = createArgument(**ai, R.getName());
1409 A->writePCHReadDecls(OS);
1411 OS << " New = new (Context) " << R.getName() << "Attr(Range, Context";
1412 for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) {
1414 (*ri)->writePCHReadArgs(OS);
1417 if (R.isSubClassOf(InhClass))
1418 OS << " cast<InheritableAttr>(New)->setInherited(isInherited);\n";
1425 // Emits the code to write an attribute to a precompiled header.
1426 void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
1427 emitSourceFileHeader("Attribute serialization code", OS);
1429 Record *InhClass = Records.getClass("InheritableAttr");
1430 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
1431 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
1433 OS << " switch (A->getKind()) {\n";
1434 OS << " default:\n";
1435 OS << " llvm_unreachable(\"Unknown attribute kind!\");\n";
1437 for (; i != e; ++i) {
1439 if (!R.getValueAsBit("ASTNode"))
1441 OS << " case attr::" << R.getName() << ": {\n";
1442 Args = R.getValueAsListOfDefs("Args");
1443 if (R.isSubClassOf(InhClass) || !Args.empty())
1444 OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName()
1446 if (R.isSubClassOf(InhClass))
1447 OS << " Record.push_back(SA->isInherited());\n";
1448 for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
1449 createArgument(**ai, R.getName())->writePCHWrite(OS);
1456 // Emits the list of spellings for attributes.
1457 void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) {
1458 emitSourceFileHeader("llvm::StringSwitch code to match all known attributes",
1461 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1463 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
1466 std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1468 for (std::vector<Record*>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) {
1469 OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", true)\n";
1475 void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) {
1476 emitSourceFileHeader("Code to translate different attribute spellings "
1477 "into internal identifiers", OS);
1480 " unsigned Index = 0;\n"
1481 " switch (AttrKind) {\n"
1483 " llvm_unreachable(\"Unknown attribute kind!\");\n"
1486 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1487 for (std::vector<Record*>::const_iterator I = Attrs.begin(), E = Attrs.end();
1490 // We only care about attributes that participate in Sema checking, so
1491 // skip those attributes that are not able to make their way to Sema.
1492 if (!R.getValueAsBit("SemaHandler"))
1495 std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
1496 // Each distinct spelling yields an attribute kind.
1497 if (R.getValueAsBit("DistinctSpellings")) {
1498 for (unsigned I = 0; I < Spellings.size(); ++ I) {
1500 " case AT_" << Spellings[I]->getValueAsString("Name") << ": \n"
1501 " Index = " << I << ";\n"
1505 OS << " case AT_" << R.getName() << " : {\n";
1506 for (unsigned I = 0; I < Spellings.size(); ++ I) {
1507 SmallString<16> Namespace;
1508 if (Spellings[I]->getValueAsString("Variety") == "CXX11")
1509 Namespace = Spellings[I]->getValueAsString("Namespace");
1513 OS << " if (Name == \""
1514 << Spellings[I]->getValueAsString("Name") << "\" && "
1516 << StringSwitch<unsigned>(Spellings[I]->getValueAsString("Variety"))
1519 .Case("Declspec", 2)
1522 << " && Scope == \"" << Namespace << "\")\n"
1523 << " return " << I << ";\n";
1532 OS << " return Index;\n";
1535 // Emits the LateParsed property for attributes.
1536 void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) {
1537 emitSourceFileHeader("llvm::StringSwitch code to match late parsed "
1540 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1542 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1546 bool LateParsed = Attr.getValueAsBit("LateParsed");
1549 std::vector<Record*> Spellings =
1550 Attr.getValueAsListOfDefs("Spellings");
1552 // FIXME: Handle non-GNU attributes
1553 for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1554 E = Spellings.end(); I != E; ++I) {
1555 if ((*I)->getValueAsString("Variety") != "GNU")
1557 OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", "
1558 << LateParsed << ")\n";
1564 // Emits code to instantiate dependent attributes on templates.
1565 void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) {
1566 emitSourceFileHeader("Template instantiation code for attributes", OS);
1568 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1570 OS << "namespace clang {\n"
1571 << "namespace sema {\n\n"
1572 << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
1574 << " const MultiLevelTemplateArgumentList &TemplateArgs) {\n"
1575 << " switch (At->getKind()) {\n"
1579 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1582 if (!R.getValueAsBit("ASTNode"))
1585 OS << " case attr::" << R.getName() << ": {\n";
1586 bool ShouldClone = R.getValueAsBit("Clone");
1589 OS << " return NULL;\n";
1594 OS << " const " << R.getName() << "Attr *A = cast<"
1595 << R.getName() << "Attr>(At);\n";
1596 bool TDependent = R.getValueAsBit("TemplateDependent");
1599 OS << " return A->clone(C);\n";
1604 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
1605 std::vector<Argument*> Args;
1606 std::vector<Argument*>::iterator ai, ae;
1607 Args.reserve(ArgRecords.size());
1609 for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
1610 re = ArgRecords.end();
1612 Record &ArgRecord = **ri;
1613 Argument *Arg = createArgument(ArgRecord, R.getName());
1615 Args.push_back(Arg);
1619 for (ai = Args.begin(); ai != ae; ++ai) {
1620 (*ai)->writeTemplateInstantiation(OS);
1622 OS << " return new (C) " << R.getName() << "Attr(A->getLocation(), C";
1623 for (ai = Args.begin(); ai != ae; ++ai) {
1625 (*ai)->writeTemplateInstantiationArgs(OS);
1629 OS << " } // end switch\n"
1630 << " llvm_unreachable(\"Unknown attribute!\");\n"
1633 << "} // end namespace sema\n"
1634 << "} // end namespace clang\n";
1637 typedef std::vector<std::pair<std::string, Record *> > ParsedAttrMap;
1639 static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records) {
1640 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1642 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1646 bool SemaHandler = Attr.getValueAsBit("SemaHandler");
1647 bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings");
1650 if (DistinctSpellings) {
1651 std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1653 for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1654 E = Spellings.end(); I != E; ++I) {
1655 std::string AttrName = (*I)->getValueAsString("Name");
1657 StringRef Spelling = NormalizeAttrName(AttrName);
1658 R.push_back(std::make_pair(Spelling.str(), &Attr));
1661 StringRef AttrName = Attr.getName();
1662 AttrName = NormalizeAttrName(AttrName);
1663 R.push_back(std::make_pair(AttrName.str(), *I));
1670 // Emits the list of parsed attributes.
1671 void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) {
1672 emitSourceFileHeader("List of all attributes that Clang recognizes", OS);
1674 OS << "#ifndef PARSED_ATTR\n";
1675 OS << "#define PARSED_ATTR(NAME) NAME\n";
1678 ParsedAttrMap Names = getParsedAttrList(Records);
1679 for (ParsedAttrMap::iterator I = Names.begin(), E = Names.end(); I != E;
1681 OS << "PARSED_ATTR(" << I->first << ")\n";
1685 static void emitArgInfo(const Record &R, raw_ostream &OS) {
1686 // This function will count the number of arguments specified for the
1687 // attribute and emit the number of required arguments followed by the
1688 // number of optional arguments.
1689 std::vector<Record *> Args = R.getValueAsListOfDefs("Args");
1690 unsigned ArgCount = 0, OptCount = 0;
1691 for (std::vector<Record *>::const_iterator I = Args.begin(), E = Args.end();
1693 const Record &Arg = **I;
1694 Arg.getValueAsBit("Optional") ? ++OptCount : ++ArgCount;
1696 OS << ArgCount << ", " << OptCount;
1699 /// Emits the parsed attribute helpers
1700 void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
1701 emitSourceFileHeader("Parsed attribute helpers", OS);
1703 ParsedAttrMap Attrs = getParsedAttrList(Records);
1705 OS << "static const ParsedAttrInfo AttrInfoMap[AttributeList::UnknownAttribute + 1] = {\n";
1706 for (ParsedAttrMap::iterator I = Attrs.begin(), E = Attrs.end(); I != E;
1708 // We need to generate struct instances based off ParsedAttrInfo from
1709 // AttributeList.cpp.
1711 emitArgInfo(*I->second, OS);
1712 OS << ", " << I->second->getValueAsBit("HasCustomParsing");
1718 OS << " // AT_" << I->first << "\n";
1723 // Emits the kind list of parsed attributes
1724 void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
1725 emitSourceFileHeader("Attribute name matcher", OS);
1727 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1729 std::vector<StringMatcher::StringPair> Matches;
1730 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1734 bool SemaHandler = Attr.getValueAsBit("SemaHandler");
1735 bool Ignored = Attr.getValueAsBit("Ignored");
1736 bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings");
1737 if (SemaHandler || Ignored) {
1738 std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1740 for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1741 E = Spellings.end(); I != E; ++I) {
1742 std::string RawSpelling = (*I)->getValueAsString("Name");
1743 StringRef AttrName = NormalizeAttrName(DistinctSpellings
1744 ? StringRef(RawSpelling)
1745 : StringRef(Attr.getName()));
1747 SmallString<64> Spelling;
1748 if ((*I)->getValueAsString("Variety") == "CXX11") {
1749 Spelling += (*I)->getValueAsString("Namespace");
1752 Spelling += NormalizeAttrSpelling(RawSpelling);
1756 StringMatcher::StringPair(
1757 StringRef(Spelling),
1758 "return AttributeList::AT_" + AttrName.str() + ";"));
1761 StringMatcher::StringPair(
1762 StringRef(Spelling),
1763 "return AttributeList::IgnoredAttribute;"));
1768 OS << "static AttributeList::Kind getAttrKind(StringRef Name) {\n";
1769 StringMatcher("Name", Matches, OS).Emit();
1770 OS << "return AttributeList::UnknownAttribute;\n"
1774 // Emits the code to dump an attribute.
1775 void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) {
1776 emitSourceFileHeader("Attribute dumper", OS);
1779 " switch (A->getKind()) {\n"
1781 " llvm_unreachable(\"Unknown attribute kind!\");\n"
1783 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
1784 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1787 if (!R.getValueAsBit("ASTNode"))
1789 OS << " case attr::" << R.getName() << ": {\n";
1790 Args = R.getValueAsListOfDefs("Args");
1791 if (!Args.empty()) {
1792 OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName()
1794 for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end();
1796 createArgument(**I, R.getName())->writeDump(OS);
1798 // Code for detecting the last child.
1799 OS << " bool OldMoreChildren = hasMoreChildren();\n";
1800 OS << " bool MoreChildren = OldMoreChildren;\n";
1802 for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end();
1804 // More code for detecting the last child.
1805 OS << " MoreChildren = OldMoreChildren";
1806 for (std::vector<Record*>::iterator Next = I + 1; Next != E; ++Next) {
1808 createArgument(**Next, R.getName())->writeHasChildren(OS);
1811 OS << " setMoreChildren(MoreChildren);\n";
1813 createArgument(**I, R.getName())->writeDumpChildren(OS);
1816 // Reset the last child.
1817 OS << " setMoreChildren(OldMoreChildren);\n";
1826 } // end namespace clang