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/TableGen/Record.h"
17 #include "llvm/TableGen/StringMatcher.h"
18 #include "llvm/TableGen/TableGenBackend.h"
24 static const std::vector<StringRef>
25 getValueAsListOfStrings(Record &R, StringRef FieldName) {
26 ListInit *List = R.getValueAsListInit(FieldName);
27 assert (List && "Got a null ListInit");
29 std::vector<StringRef> Strings;
30 Strings.reserve(List->getSize());
32 for (ListInit::const_iterator i = List->begin(), e = List->end();
35 assert(*i && "Got a null element in a ListInit");
36 if (StringInit *S = dyn_cast<StringInit>(*i))
37 Strings.push_back(S->getValue());
39 assert(false && "Got a non-string, non-code element in a ListInit");
45 static std::string ReadPCHRecord(StringRef type) {
46 return StringSwitch<std::string>(type)
47 .EndsWith("Decl *", "GetLocalDeclAs<"
48 + std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])")
49 .Case("QualType", "getLocalType(F, Record[Idx++])")
50 .Case("Expr *", "ReadSubExpr()")
51 .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)")
52 .Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)")
53 .Default("Record[Idx++]");
56 // Assumes that the way to get the value is SA->getname()
57 static std::string WritePCHRecord(StringRef type, StringRef name) {
58 return StringSwitch<std::string>(type)
59 .EndsWith("Decl *", "AddDeclRef(" + std::string(name) +
61 .Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n")
62 .Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
63 .Case("IdentifierInfo *",
64 "AddIdentifierRef(" + std::string(name) + ", Record);\n")
65 .Case("SourceLocation",
66 "AddSourceLocation(" + std::string(name) + ", Record);\n")
67 .Default("Record.push_back(" + std::string(name) + ");\n");
70 // Normalize attribute name by removing leading and trailing
71 // underscores. For example, __foo, foo__, __foo__ would
73 static StringRef NormalizeAttrName(StringRef AttrName) {
74 if (AttrName.startswith("__"))
75 AttrName = AttrName.substr(2, AttrName.size());
77 if (AttrName.endswith("__"))
78 AttrName = AttrName.substr(0, AttrName.size() - 2);
83 // Normalize attribute spelling only if the spelling has both leading
84 // and trailing underscores. For example, __ms_struct__ will be
85 // normalized to "ms_struct"; __cdecl will remain intact.
86 static StringRef NormalizeAttrSpelling(StringRef AttrSpelling) {
87 if (AttrSpelling.startswith("__") && AttrSpelling.endswith("__")) {
88 AttrSpelling = AttrSpelling.substr(2, AttrSpelling.size() - 4);
96 std::string lowerName, upperName;
100 Argument(Record &Arg, StringRef Attr)
101 : lowerName(Arg.getValueAsString("Name")), upperName(lowerName),
103 if (!lowerName.empty()) {
104 lowerName[0] = std::tolower(lowerName[0]);
105 upperName[0] = std::toupper(upperName[0]);
108 virtual ~Argument() {}
110 StringRef getLowerName() const { return lowerName; }
111 StringRef getUpperName() const { return upperName; }
112 StringRef getAttrName() const { return attrName; }
114 // These functions print the argument contents formatted in different ways.
115 virtual void writeAccessors(raw_ostream &OS) const = 0;
116 virtual void writeAccessorDefinitions(raw_ostream &OS) const {}
117 virtual void writeCloneArgs(raw_ostream &OS) const = 0;
118 virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0;
119 virtual void writeTemplateInstantiation(raw_ostream &OS) const {}
120 virtual void writeCtorBody(raw_ostream &OS) const {}
121 virtual void writeCtorInitializers(raw_ostream &OS) const = 0;
122 virtual void writeCtorParameters(raw_ostream &OS) const = 0;
123 virtual void writeDeclarations(raw_ostream &OS) const = 0;
124 virtual void writePCHReadArgs(raw_ostream &OS) const = 0;
125 virtual void writePCHReadDecls(raw_ostream &OS) const = 0;
126 virtual void writePCHWrite(raw_ostream &OS) const = 0;
127 virtual void writeValue(raw_ostream &OS) const = 0;
130 class SimpleArgument : public Argument {
134 SimpleArgument(Record &Arg, StringRef Attr, std::string T)
135 : Argument(Arg, Attr), type(T)
138 std::string getType() const { return type; }
140 void writeAccessors(raw_ostream &OS) const {
141 OS << " " << type << " get" << getUpperName() << "() const {\n";
142 OS << " return " << getLowerName() << ";\n";
145 void writeCloneArgs(raw_ostream &OS) const {
146 OS << getLowerName();
148 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
149 OS << "A->get" << getUpperName() << "()";
151 void writeCtorInitializers(raw_ostream &OS) const {
152 OS << getLowerName() << "(" << getUpperName() << ")";
154 void writeCtorParameters(raw_ostream &OS) const {
155 OS << type << " " << getUpperName();
157 void writeDeclarations(raw_ostream &OS) const {
158 OS << type << " " << getLowerName() << ";";
160 void writePCHReadDecls(raw_ostream &OS) const {
161 std::string read = ReadPCHRecord(type);
162 OS << " " << type << " " << getLowerName() << " = " << read << ";\n";
164 void writePCHReadArgs(raw_ostream &OS) const {
165 OS << getLowerName();
167 void writePCHWrite(raw_ostream &OS) const {
168 OS << " " << WritePCHRecord(type, "SA->get" +
169 std::string(getUpperName()) + "()");
171 void writeValue(raw_ostream &OS) const {
172 if (type == "FunctionDecl *") {
173 OS << "\" << get" << getUpperName() << "()->getNameInfo().getAsString() << \"";
174 } else if (type == "IdentifierInfo *") {
175 OS << "\" << get" << getUpperName() << "()->getName() << \"";
176 } else if (type == "QualType") {
177 OS << "\" << get" << getUpperName() << "().getAsString() << \"";
178 } else if (type == "SourceLocation") {
179 OS << "\" << get" << getUpperName() << "().getRawEncoding() << \"";
181 OS << "\" << get" << getUpperName() << "() << \"";
186 class StringArgument : public Argument {
188 StringArgument(Record &Arg, StringRef Attr)
189 : Argument(Arg, Attr)
192 void writeAccessors(raw_ostream &OS) const {
193 OS << " llvm::StringRef get" << getUpperName() << "() const {\n";
194 OS << " return llvm::StringRef(" << getLowerName() << ", "
195 << getLowerName() << "Length);\n";
197 OS << " unsigned get" << getUpperName() << "Length() const {\n";
198 OS << " return " << getLowerName() << "Length;\n";
200 OS << " void set" << getUpperName()
201 << "(ASTContext &C, llvm::StringRef S) {\n";
202 OS << " " << getLowerName() << "Length = S.size();\n";
203 OS << " this->" << getLowerName() << " = new (C, 1) char ["
204 << getLowerName() << "Length];\n";
205 OS << " std::memcpy(this->" << getLowerName() << ", S.data(), "
206 << getLowerName() << "Length);\n";
209 void writeCloneArgs(raw_ostream &OS) const {
210 OS << "get" << getUpperName() << "()";
212 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
213 OS << "A->get" << getUpperName() << "()";
215 void writeCtorBody(raw_ostream &OS) const {
216 OS << " std::memcpy(" << getLowerName() << ", " << getUpperName()
217 << ".data(), " << getLowerName() << "Length);";
219 void writeCtorInitializers(raw_ostream &OS) const {
220 OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
221 << getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
224 void writeCtorParameters(raw_ostream &OS) const {
225 OS << "llvm::StringRef " << getUpperName();
227 void writeDeclarations(raw_ostream &OS) const {
228 OS << "unsigned " << getLowerName() << "Length;\n";
229 OS << "char *" << getLowerName() << ";";
231 void writePCHReadDecls(raw_ostream &OS) const {
232 OS << " std::string " << getLowerName()
233 << "= ReadString(Record, Idx);\n";
235 void writePCHReadArgs(raw_ostream &OS) const {
236 OS << getLowerName();
238 void writePCHWrite(raw_ostream &OS) const {
239 OS << " AddString(SA->get" << getUpperName() << "(), Record);\n";
241 void writeValue(raw_ostream &OS) const {
242 OS << "\\\"\" << get" << getUpperName() << "() << \"\\\"";
246 class AlignedArgument : public Argument {
248 AlignedArgument(Record &Arg, StringRef Attr)
249 : Argument(Arg, Attr)
252 void writeAccessors(raw_ostream &OS) const {
253 OS << " bool is" << getUpperName() << "Dependent() const;\n";
255 OS << " unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";
257 OS << " bool is" << getUpperName() << "Expr() const {\n";
258 OS << " return is" << getLowerName() << "Expr;\n";
261 OS << " Expr *get" << getUpperName() << "Expr() const {\n";
262 OS << " assert(is" << getLowerName() << "Expr);\n";
263 OS << " return " << getLowerName() << "Expr;\n";
266 OS << " TypeSourceInfo *get" << getUpperName() << "Type() const {\n";
267 OS << " assert(!is" << getLowerName() << "Expr);\n";
268 OS << " return " << getLowerName() << "Type;\n";
271 void writeAccessorDefinitions(raw_ostream &OS) const {
272 OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
273 << "Dependent() const {\n";
274 OS << " if (is" << getLowerName() << "Expr)\n";
275 OS << " return " << getLowerName() << "Expr && (" << getLowerName()
276 << "Expr->isValueDependent() || " << getLowerName()
277 << "Expr->isTypeDependent());\n";
279 OS << " return " << getLowerName()
280 << "Type->getType()->isDependentType();\n";
283 // FIXME: Do not do the calculation here
284 // FIXME: Handle types correctly
285 // A null pointer means maximum alignment
286 // FIXME: Load the platform-specific maximum alignment, rather than
288 OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName()
289 << "(ASTContext &Ctx) const {\n";
290 OS << " assert(!is" << getUpperName() << "Dependent());\n";
291 OS << " if (is" << getLowerName() << "Expr)\n";
292 OS << " return (" << getLowerName() << "Expr ? " << getLowerName()
293 << "Expr->EvaluateKnownConstInt(Ctx).getZExtValue() : 16)"
294 << "* Ctx.getCharWidth();\n";
296 OS << " return 0; // FIXME\n";
299 void writeCloneArgs(raw_ostream &OS) const {
300 OS << "is" << getLowerName() << "Expr, is" << getLowerName()
301 << "Expr ? static_cast<void*>(" << getLowerName()
302 << "Expr) : " << getLowerName()
305 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
306 // FIXME: move the definition in Sema::InstantiateAttrs to here.
307 // In the meantime, aligned attributes are cloned.
309 void writeCtorBody(raw_ostream &OS) const {
310 OS << " if (is" << getLowerName() << "Expr)\n";
311 OS << " " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
312 << getUpperName() << ");\n";
314 OS << " " << getLowerName()
315 << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
318 void writeCtorInitializers(raw_ostream &OS) const {
319 OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
321 void writeCtorParameters(raw_ostream &OS) const {
322 OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
324 void writeDeclarations(raw_ostream &OS) const {
325 OS << "bool is" << getLowerName() << "Expr;\n";
327 OS << "Expr *" << getLowerName() << "Expr;\n";
328 OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
331 void writePCHReadArgs(raw_ostream &OS) const {
332 OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
334 void writePCHReadDecls(raw_ostream &OS) const {
335 OS << " bool is" << getLowerName() << "Expr = Record[Idx++];\n";
336 OS << " void *" << getLowerName() << "Ptr;\n";
337 OS << " if (is" << getLowerName() << "Expr)\n";
338 OS << " " << getLowerName() << "Ptr = ReadExpr(F);\n";
340 OS << " " << getLowerName()
341 << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n";
343 void writePCHWrite(raw_ostream &OS) const {
344 OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n";
345 OS << " if (SA->is" << getUpperName() << "Expr())\n";
346 OS << " AddStmt(SA->get" << getUpperName() << "Expr());\n";
348 OS << " AddTypeSourceInfo(SA->get" << getUpperName()
349 << "Type(), Record);\n";
351 void writeValue(raw_ostream &OS) const {
353 << " " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n"
358 class VariadicArgument : public Argument {
362 VariadicArgument(Record &Arg, StringRef Attr, std::string T)
363 : Argument(Arg, Attr), type(T)
366 std::string getType() const { return type; }
368 void writeAccessors(raw_ostream &OS) const {
369 OS << " typedef " << type << "* " << getLowerName() << "_iterator;\n";
370 OS << " " << getLowerName() << "_iterator " << getLowerName()
371 << "_begin() const {\n";
372 OS << " return " << getLowerName() << ";\n";
374 OS << " " << getLowerName() << "_iterator " << getLowerName()
375 << "_end() const {\n";
376 OS << " return " << getLowerName() << " + " << getLowerName()
379 OS << " unsigned " << getLowerName() << "_size() const {\n"
380 << " return " << getLowerName() << "Size;\n";
383 void writeCloneArgs(raw_ostream &OS) const {
384 OS << getLowerName() << ", " << getLowerName() << "Size";
386 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
387 // This isn't elegant, but we have to go through public methods...
388 OS << "A->" << getLowerName() << "_begin(), "
389 << "A->" << getLowerName() << "_size()";
391 void writeCtorBody(raw_ostream &OS) const {
392 // FIXME: memcpy is not safe on non-trivial types.
393 OS << " std::memcpy(" << getLowerName() << ", " << getUpperName()
394 << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n";
396 void writeCtorInitializers(raw_ostream &OS) const {
397 OS << getLowerName() << "Size(" << getUpperName() << "Size), "
398 << getLowerName() << "(new (Ctx, 16) " << getType() << "["
399 << getLowerName() << "Size])";
401 void writeCtorParameters(raw_ostream &OS) const {
402 OS << getType() << " *" << getUpperName() << ", unsigned "
403 << getUpperName() << "Size";
405 void writeDeclarations(raw_ostream &OS) const {
406 OS << " unsigned " << getLowerName() << "Size;\n";
407 OS << " " << getType() << " *" << getLowerName() << ";";
409 void writePCHReadDecls(raw_ostream &OS) const {
410 OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n";
411 OS << " llvm::SmallVector<" << type << ", 4> " << getLowerName()
413 OS << " " << getLowerName() << ".reserve(" << getLowerName()
415 OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
417 std::string read = ReadPCHRecord(type);
418 OS << " " << getLowerName() << ".push_back(" << read << ");\n";
420 void writePCHReadArgs(raw_ostream &OS) const {
421 OS << getLowerName() << ".data(), " << getLowerName() << "Size";
423 void writePCHWrite(raw_ostream &OS) const{
424 OS << " Record.push_back(SA->" << getLowerName() << "_size());\n";
425 OS << " for (" << getAttrName() << "Attr::" << getLowerName()
426 << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
427 << getLowerName() << "_end(); i != e; ++i)\n";
428 OS << " " << WritePCHRecord(type, "(*i)");
430 void writeValue(raw_ostream &OS) const {
432 OS << " bool isFirst = true;\n"
433 << " for (" << getAttrName() << "Attr::" << getLowerName()
434 << "_iterator i = " << getLowerName() << "_begin(), e = "
435 << getLowerName() << "_end(); i != e; ++i) {\n"
436 << " if (isFirst) isFirst = false;\n"
437 << " else OS << \", \";\n"
444 class EnumArgument : public Argument {
446 std::vector<StringRef> values, enums;
448 EnumArgument(Record &Arg, StringRef Attr)
449 : Argument(Arg, Attr), type(Arg.getValueAsString("Type")),
450 values(getValueAsListOfStrings(Arg, "Values")),
451 enums(getValueAsListOfStrings(Arg, "Enums"))
454 void writeAccessors(raw_ostream &OS) const {
455 OS << " " << type << " get" << getUpperName() << "() const {\n";
456 OS << " return " << getLowerName() << ";\n";
459 void writeCloneArgs(raw_ostream &OS) const {
460 OS << getLowerName();
462 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
463 OS << "A->get" << getUpperName() << "()";
465 void writeCtorInitializers(raw_ostream &OS) const {
466 OS << getLowerName() << "(" << getUpperName() << ")";
468 void writeCtorParameters(raw_ostream &OS) const {
469 OS << type << " " << getUpperName();
471 void writeDeclarations(raw_ostream &OS) const {
472 // Calculate the various enum values
473 std::vector<StringRef> uniques(enums);
474 std::sort(uniques.begin(), uniques.end());
475 uniques.erase(std::unique(uniques.begin(), uniques.end()),
477 // FIXME: Emit a proper error
478 assert(!uniques.empty());
480 std::vector<StringRef>::iterator i = uniques.begin(),
482 // The last one needs to not have a comma.
486 OS << " enum " << type << " {\n";
488 OS << " " << *i << ",\n";
489 OS << " " << *e << "\n";
492 OS << " " << type << " " << getLowerName() << ";";
494 void writePCHReadDecls(raw_ostream &OS) const {
495 OS << " " << getAttrName() << "Attr::" << type << " " << getLowerName()
496 << "(static_cast<" << getAttrName() << "Attr::" << type
497 << ">(Record[Idx++]));\n";
499 void writePCHReadArgs(raw_ostream &OS) const {
500 OS << getLowerName();
502 void writePCHWrite(raw_ostream &OS) const {
503 OS << "Record.push_back(SA->get" << getUpperName() << "());\n";
505 void writeValue(raw_ostream &OS) const {
506 OS << "\" << get" << getUpperName() << "() << \"";
510 class VersionArgument : public Argument {
512 VersionArgument(Record &Arg, StringRef Attr)
513 : Argument(Arg, Attr)
516 void writeAccessors(raw_ostream &OS) const {
517 OS << " VersionTuple get" << getUpperName() << "() const {\n";
518 OS << " return " << getLowerName() << ";\n";
520 OS << " void set" << getUpperName()
521 << "(ASTContext &C, VersionTuple V) {\n";
522 OS << " " << getLowerName() << " = V;\n";
525 void writeCloneArgs(raw_ostream &OS) const {
526 OS << "get" << getUpperName() << "()";
528 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
529 OS << "A->get" << getUpperName() << "()";
531 void writeCtorBody(raw_ostream &OS) const {
533 void writeCtorInitializers(raw_ostream &OS) const {
534 OS << getLowerName() << "(" << getUpperName() << ")";
536 void writeCtorParameters(raw_ostream &OS) const {
537 OS << "VersionTuple " << getUpperName();
539 void writeDeclarations(raw_ostream &OS) const {
540 OS << "VersionTuple " << getLowerName() << ";\n";
542 void writePCHReadDecls(raw_ostream &OS) const {
543 OS << " VersionTuple " << getLowerName()
544 << "= ReadVersionTuple(Record, Idx);\n";
546 void writePCHReadArgs(raw_ostream &OS) const {
547 OS << getLowerName();
549 void writePCHWrite(raw_ostream &OS) const {
550 OS << " AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n";
552 void writeValue(raw_ostream &OS) const {
553 OS << getLowerName() << "=\" << get" << getUpperName() << "() << \"";
557 class ExprArgument : public SimpleArgument {
559 ExprArgument(Record &Arg, StringRef Attr)
560 : SimpleArgument(Arg, Attr, "Expr *")
563 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
564 OS << "tempInst" << getUpperName();
567 void writeTemplateInstantiation(raw_ostream &OS) const {
568 OS << " " << getType() << " tempInst" << getUpperName() << ";\n";
570 OS << " EnterExpressionEvaluationContext "
571 << "Unevaluated(S, Sema::Unevaluated);\n";
572 OS << " ExprResult " << "Result = S.SubstExpr("
573 << "A->get" << getUpperName() << "(), TemplateArgs);\n";
574 OS << " tempInst" << getUpperName() << " = "
575 << "Result.takeAs<Expr>();\n";
580 class VariadicExprArgument : public VariadicArgument {
582 VariadicExprArgument(Record &Arg, StringRef Attr)
583 : VariadicArgument(Arg, Attr, "Expr *")
586 void writeTemplateInstantiationArgs(raw_ostream &OS) const {
587 OS << "tempInst" << getUpperName() << ", "
588 << "A->" << getLowerName() << "_size()";
591 void writeTemplateInstantiation(raw_ostream &OS) const {
592 OS << " " << getType() << " *tempInst" << getUpperName()
593 << " = new (C, 16) " << getType()
594 << "[A->" << getLowerName() << "_size()];\n";
596 OS << " EnterExpressionEvaluationContext "
597 << "Unevaluated(S, Sema::Unevaluated);\n";
598 OS << " " << getType() << " *TI = tempInst" << getUpperName()
600 OS << " " << getType() << " *I = A->" << getLowerName()
602 OS << " " << getType() << " *E = A->" << getLowerName()
604 OS << " for (; I != E; ++I, ++TI) {\n";
605 OS << " ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n";
606 OS << " *TI = Result.takeAs<Expr>();\n";
613 static Argument *createArgument(Record &Arg, StringRef Attr,
614 Record *Search = 0) {
619 llvm::StringRef ArgName = Search->getName();
621 if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr);
622 else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr);
623 else if (ArgName == "ExprArgument") Ptr = new ExprArgument(Arg, Attr);
624 else if (ArgName == "FunctionArgument")
625 Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *");
626 else if (ArgName == "IdentifierArgument")
627 Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
628 else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr,
630 else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
631 else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
632 else if (ArgName == "TypeArgument")
633 Ptr = new SimpleArgument(Arg, Attr, "QualType");
634 else if (ArgName == "UnsignedArgument")
635 Ptr = new SimpleArgument(Arg, Attr, "unsigned");
636 else if (ArgName == "SourceLocArgument")
637 Ptr = new SimpleArgument(Arg, Attr, "SourceLocation");
638 else if (ArgName == "VariadicUnsignedArgument")
639 Ptr = new VariadicArgument(Arg, Attr, "unsigned");
640 else if (ArgName == "VariadicExprArgument")
641 Ptr = new VariadicExprArgument(Arg, Attr);
642 else if (ArgName == "VersionArgument")
643 Ptr = new VersionArgument(Arg, Attr);
646 std::vector<Record*> Bases = Search->getSuperClasses();
647 for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end();
649 Ptr = createArgument(Arg, Attr, *i);
657 static void writeAvailabilityValue(raw_ostream &OS) {
658 OS << "\" << getPlatform()->getName();\n"
659 << " if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n"
660 << " if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n"
661 << " if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n"
662 << " if (getUnavailable()) OS << \", unavailable\";\n"
668 // Emits the class definitions for attributes.
669 void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
670 OS << "// This file is generated by TableGen. Do not edit.\n\n";
671 OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
672 OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n";
674 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
676 for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
680 if (!R.getValueAsBit("ASTNode"))
683 const std::string &SuperName = R.getSuperClasses().back()->getName();
685 OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n";
687 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
688 std::vector<Argument*> Args;
689 std::vector<Argument*>::iterator ai, ae;
690 Args.reserve(ArgRecords.size());
692 for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
693 re = ArgRecords.end();
695 Record &ArgRecord = **ri;
696 Argument *Arg = createArgument(ArgRecord, R.getName());
700 Arg->writeDeclarations(OS);
706 OS << "\n public:\n";
707 OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n";
709 for (ai = Args.begin(); ai != ae; ++ai) {
711 (*ai)->writeCtorParameters(OS);
716 OS << " : " << SuperName << "(attr::" << R.getName() << ", R)\n";
718 for (ai = Args.begin(); ai != ae; ++ai) {
720 (*ai)->writeCtorInitializers(OS);
726 for (ai = Args.begin(); ai != ae; ++ai) {
727 (*ai)->writeCtorBody(OS);
732 OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n";
733 OS << " virtual void printPretty(llvm::raw_ostream &OS,"
734 << " const PrintingPolicy &Policy) const;\n";
736 for (ai = Args.begin(); ai != ae; ++ai) {
737 (*ai)->writeAccessors(OS);
741 OS << R.getValueAsString("AdditionalMembers");
744 OS << " static bool classof(const Attr *A) { return A->getKind() == "
745 << "attr::" << R.getName() << "; }\n";
747 bool LateParsed = R.getValueAsBit("LateParsed");
748 OS << " virtual bool isLateParsed() const { return "
749 << LateParsed << "; }\n";
757 // Emits the class method definitions for attributes.
758 void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
759 OS << "// This file is generated by TableGen. Do not edit.\n\n";
761 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
762 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re;
763 std::vector<Argument*>::iterator ai, ae;
765 for (; i != e; ++i) {
768 if (!R.getValueAsBit("ASTNode"))
771 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
772 std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
773 std::vector<Argument*> Args;
774 for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri)
775 Args.push_back(createArgument(**ri, R.getName()));
777 for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
778 (*ai)->writeAccessorDefinitions(OS);
780 OS << R.getName() << "Attr *" << R.getName()
781 << "Attr::clone(ASTContext &C) const {\n";
782 OS << " return new (C) " << R.getName() << "Attr(getLocation(), C";
783 for (ai = Args.begin(); ai != ae; ++ai) {
785 (*ai)->writeCloneArgs(OS);
789 OS << "void " << R.getName() << "Attr::printPretty("
790 << "llvm::raw_ostream &OS, const PrintingPolicy &Policy) const {\n";
791 if (Spellings.begin() != Spellings.end()) {
792 std::string Spelling = (*Spellings.begin())->getValueAsString("Name");
793 OS << " OS << \" __attribute__((" << Spelling;
794 if (Args.size()) OS << "(";
795 if (Spelling == "availability") {
796 writeAvailabilityValue(OS);
798 for (ai = Args.begin(); ai != ae; ++ai) {
799 if (ai!=Args.begin()) OS <<", ";
800 (*ai)->writeValue(OS);
803 if (Args.size()) OS << ")";
810 } // end namespace clang
812 static void EmitAttrList(raw_ostream &OS, StringRef Class,
813 const std::vector<Record*> &AttrList) {
814 std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end();
817 // Move the end iterator back to emit the last attribute.
818 for(--e; i != e; ++i) {
819 if (!(*i)->getValueAsBit("ASTNode"))
822 OS << Class << "(" << (*i)->getName() << ")\n";
825 OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n";
831 // Emits the enumeration list for attributes.
832 void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
833 OS << "// This file is generated by TableGen. Do not edit.\n\n";
835 OS << "#ifndef LAST_ATTR\n";
836 OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n";
839 OS << "#ifndef INHERITABLE_ATTR\n";
840 OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n";
843 OS << "#ifndef LAST_INHERITABLE_ATTR\n";
844 OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
847 OS << "#ifndef INHERITABLE_PARAM_ATTR\n";
848 OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n";
851 OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n";
852 OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)"
853 " INHERITABLE_PARAM_ATTR(NAME)\n";
856 Record *InhClass = Records.getClass("InheritableAttr");
857 Record *InhParamClass = Records.getClass("InheritableParamAttr");
858 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
859 NonInhAttrs, InhAttrs, InhParamAttrs;
860 for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
862 if (!(*i)->getValueAsBit("ASTNode"))
865 if ((*i)->isSubClassOf(InhParamClass))
866 InhParamAttrs.push_back(*i);
867 else if ((*i)->isSubClassOf(InhClass))
868 InhAttrs.push_back(*i);
870 NonInhAttrs.push_back(*i);
873 EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
874 EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
875 EmitAttrList(OS, "ATTR", NonInhAttrs);
877 OS << "#undef LAST_ATTR\n";
878 OS << "#undef INHERITABLE_ATTR\n";
879 OS << "#undef LAST_INHERITABLE_ATTR\n";
880 OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
881 OS << "#undef ATTR\n";
884 // Emits the code to read an attribute from a precompiled header.
885 void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
886 OS << "// This file is generated by TableGen. Do not edit.\n\n";
888 Record *InhClass = Records.getClass("InheritableAttr");
889 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
891 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
892 std::vector<Argument*> Args;
893 std::vector<Argument*>::iterator ri, re;
895 OS << " switch (Kind) {\n";
897 OS << " assert(0 && \"Unknown attribute!\");\n";
899 for (; i != e; ++i) {
901 if (!R.getValueAsBit("ASTNode"))
904 OS << " case attr::" << R.getName() << ": {\n";
905 if (R.isSubClassOf(InhClass))
906 OS << " bool isInherited = Record[Idx++];\n";
907 ArgRecords = R.getValueAsListOfDefs("Args");
909 for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) {
910 Argument *A = createArgument(**ai, R.getName());
912 A->writePCHReadDecls(OS);
914 OS << " New = new (Context) " << R.getName() << "Attr(Range, Context";
915 for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) {
917 (*ri)->writePCHReadArgs(OS);
920 if (R.isSubClassOf(InhClass))
921 OS << " cast<InheritableAttr>(New)->setInherited(isInherited);\n";
928 // Emits the code to write an attribute to a precompiled header.
929 void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
930 Record *InhClass = Records.getClass("InheritableAttr");
931 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
932 std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
934 OS << " switch (A->getKind()) {\n";
936 OS << " llvm_unreachable(\"Unknown attribute kind!\");\n";
938 for (; i != e; ++i) {
940 if (!R.getValueAsBit("ASTNode"))
942 OS << " case attr::" << R.getName() << ": {\n";
943 Args = R.getValueAsListOfDefs("Args");
944 if (R.isSubClassOf(InhClass) || !Args.empty())
945 OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName()
947 if (R.isSubClassOf(InhClass))
948 OS << " Record.push_back(SA->isInherited());\n";
949 for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
950 createArgument(**ai, R.getName())->writePCHWrite(OS);
957 // Emits the list of spellings for attributes.
958 void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) {
959 OS << "// This file is generated by TableGen. Do not edit.\n\n";
961 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
963 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
966 std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
968 for (std::vector<Record*>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) {
969 OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", true)\n";
975 // Emits the LateParsed property for attributes.
976 void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) {
977 OS << "// This file is generated by TableGen. Do not edit.\n\n";
979 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
981 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
985 bool LateParsed = Attr.getValueAsBit("LateParsed");
988 std::vector<Record*> Spellings =
989 Attr.getValueAsListOfDefs("Spellings");
991 // FIXME: Handle non-GNU attributes
992 for (std::vector<Record*>::const_iterator I = Spellings.begin(),
993 E = Spellings.end(); I != E; ++I) {
994 if ((*I)->getValueAsString("Variety") != "GNU")
996 OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", "
997 << LateParsed << ")\n";
1003 // Emits code to instantiate dependent attributes on templates.
1004 void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) {
1005 OS << "// This file is generated by TableGen. Do not edit.\n\n";
1007 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1009 OS << "namespace clang {\n"
1010 << "namespace sema {\n\n"
1011 << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
1013 << " const MultiLevelTemplateArgumentList &TemplateArgs) {\n"
1014 << " switch (At->getKind()) {\n"
1018 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1021 if (!R.getValueAsBit("ASTNode"))
1024 OS << " case attr::" << R.getName() << ": {\n";
1025 bool ShouldClone = R.getValueAsBit("Clone");
1028 OS << " return NULL;\n";
1033 OS << " const " << R.getName() << "Attr *A = cast<"
1034 << R.getName() << "Attr>(At);\n";
1035 bool TDependent = R.getValueAsBit("TemplateDependent");
1038 OS << " return A->clone(C);\n";
1043 std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
1044 std::vector<Argument*> Args;
1045 std::vector<Argument*>::iterator ai, ae;
1046 Args.reserve(ArgRecords.size());
1048 for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
1049 re = ArgRecords.end();
1051 Record &ArgRecord = **ri;
1052 Argument *Arg = createArgument(ArgRecord, R.getName());
1054 Args.push_back(Arg);
1058 for (ai = Args.begin(); ai != ae; ++ai) {
1059 (*ai)->writeTemplateInstantiation(OS);
1061 OS << " return new (C) " << R.getName() << "Attr(A->getLocation(), C";
1062 for (ai = Args.begin(); ai != ae; ++ai) {
1064 (*ai)->writeTemplateInstantiationArgs(OS);
1068 OS << " } // end switch\n"
1069 << " llvm_unreachable(\"Unknown attribute!\");\n"
1072 << "} // end namespace sema\n"
1073 << "} // end namespace clang\n";
1076 // Emits the list of parsed attributes.
1077 void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) {
1078 OS << "// This file is generated by TableGen. Do not edit.\n\n";
1080 OS << "#ifndef PARSED_ATTR\n";
1081 OS << "#define PARSED_ATTR(NAME) NAME\n";
1084 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1086 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1090 bool SemaHandler = Attr.getValueAsBit("SemaHandler");
1091 bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings");
1094 if (DistinctSpellings) {
1095 std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1097 for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1098 E = Spellings.end(); I != E; ++I) {
1099 std::string AttrName = (*I)->getValueAsString("Name");
1101 StringRef Spelling = NormalizeAttrName(AttrName);
1103 OS << "PARSED_ATTR(" << Spelling << ")\n";
1106 StringRef AttrName = Attr.getName();
1107 AttrName = NormalizeAttrName(AttrName);
1108 OS << "PARSED_ATTR(" << AttrName << ")\n";
1114 // Emits the kind list of parsed attributes
1115 void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
1116 OS << "// This file is generated by TableGen. Do not edit.\n\n";
1119 std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1121 std::vector<StringMatcher::StringPair> Matches;
1122 for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1126 bool SemaHandler = Attr.getValueAsBit("SemaHandler");
1127 bool Ignored = Attr.getValueAsBit("Ignored");
1128 bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings");
1129 if (SemaHandler || Ignored) {
1130 std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1132 for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1133 E = Spellings.end(); I != E; ++I) {
1134 std::string RawSpelling = (*I)->getValueAsString("Name");
1135 StringRef AttrName = NormalizeAttrName(DistinctSpellings
1136 ? StringRef(RawSpelling)
1137 : StringRef(Attr.getName()));
1139 SmallString<64> Spelling;
1140 if ((*I)->getValueAsString("Variety") == "CXX11") {
1141 Spelling += (*I)->getValueAsString("Namespace");
1144 Spelling += NormalizeAttrSpelling(RawSpelling);
1148 StringMatcher::StringPair(
1149 StringRef(Spelling),
1150 "return AttributeList::AT_" + AttrName.str() + ";"));
1153 StringMatcher::StringPair(
1154 StringRef(Spelling),
1155 "return AttributeList::IgnoredAttribute;"));
1160 OS << "static AttributeList::Kind getAttrKind(StringRef Name) {\n";
1161 StringMatcher("Name", Matches, OS).Emit();
1162 OS << "return AttributeList::UnknownAttribute;\n"
1166 } // end namespace clang