Extend Clang's TableGen emitter for attributes to support bool arguments.
[oota-llvm.git] / utils / TableGen / ClangAttrEmitter.cpp
1 //===- ClangAttrEmitter.cpp - Generate Clang attribute handling =-*- C++ -*--=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // These tablegen backends emit Clang attribute processing code
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "ClangAttrEmitter.h"
15 #include "Record.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include <algorithm>
18 #include <cctype>
19
20 using namespace llvm;
21
22 static const std::vector<StringRef>
23 getValueAsListOfStrings(Record &R, StringRef FieldName) {
24   ListInit *List = R.getValueAsListInit(FieldName);
25   assert (List && "Got a null ListInit");
26
27   std::vector<StringRef> Strings;
28   Strings.reserve(List->getSize());
29
30   for (ListInit::iterator i = List->begin(), e = List->end(); i != e; ++i) {
31     assert(*i && "Got a null element in a ListInit");
32     if (StringInit *S = dynamic_cast<StringInit *>(*i))
33       Strings.push_back(S->getValue());
34     else if (CodeInit *C = dynamic_cast<CodeInit *>(*i))
35       Strings.push_back(C->getValue());
36     else
37       assert(false && "Got a non-string, non-code element in a ListInit");
38   }
39
40   return Strings;
41 }
42
43 std::string ReadPCHRecord(StringRef type) {
44   return StringSwitch<std::string>(type)
45     .EndsWith("Decl *", "cast_or_null<" + std::string(type, 0, type.size()-1) +
46               ">(GetDecl(Record[Idx++]))")
47     .Case("QualType", "GetType(Record[Idx++])")
48     .Case("Expr *", "ReadSubExpr()")
49     .Case("IdentifierInfo *", "GetIdentifierInfo(Record, Idx)")
50     .Default("Record[Idx++]");
51 }
52
53 // Assumes that the way to get the value is SA->getname()
54 std::string WritePCHRecord(StringRef type, StringRef name) {
55   return StringSwitch<std::string>(type)
56     .EndsWith("Decl *", "AddDeclRef(" + std::string(name) +
57                         ", Record);\n")
58     .Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n")
59     .Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
60     .Case("IdentifierInfo *", 
61           "AddIdentifierRef(" + std::string(name) + ", Record);\n")
62     .Default("Record.push_back(" + std::string(name) + ");\n");
63 }
64
65 namespace {
66   class Argument {
67     std::string lowerName, upperName;
68     StringRef attrName;
69
70   public:
71     Argument(Record &Arg, StringRef Attr)
72       : lowerName(Arg.getValueAsString("Name")), upperName(lowerName),
73         attrName(Attr) {
74       if (!lowerName.empty()) {
75         lowerName[0] = std::tolower(lowerName[0]);
76         upperName[0] = std::toupper(upperName[0]);
77       }
78     }
79     virtual ~Argument() {}
80
81     StringRef getLowerName() const { return lowerName; }
82     StringRef getUpperName() const { return upperName; }
83     StringRef getAttrName() const { return attrName; }
84
85     // These functions print the argument contents formatted in different ways.
86     virtual void writeAccessors(raw_ostream &OS) const = 0;
87     virtual void writeAccessorDefinitions(raw_ostream &OS) const {}
88     virtual void writeCloneArgs(raw_ostream &OS) const = 0;
89     virtual void writeCtorBody(raw_ostream &OS) const {}
90     virtual void writeCtorInitializers(raw_ostream &OS) const = 0;
91     virtual void writeCtorParameters(raw_ostream &OS) const = 0;
92     virtual void writeDeclarations(raw_ostream &OS) const = 0;
93     virtual void writePCHReadArgs(raw_ostream &OS) const = 0;
94     virtual void writePCHReadDecls(raw_ostream &OS) const = 0;
95     virtual void writePCHWrite(raw_ostream &OS) const = 0;
96   };
97
98   class SimpleArgument : public Argument {
99     std::string type;
100
101   public:
102     SimpleArgument(Record &Arg, StringRef Attr, std::string T)
103       : Argument(Arg, Attr), type(T)
104     {}
105
106     void writeAccessors(raw_ostream &OS) const {
107       OS << "  " << type << " get" << getUpperName() << "() const {\n";
108       OS << "    return " << getLowerName() << ";\n";
109       OS << "  }";
110     }
111     void writeCloneArgs(raw_ostream &OS) const {
112       OS << getLowerName();
113     }
114     void writeCtorInitializers(raw_ostream &OS) const {
115       OS << getLowerName() << "(" << getUpperName() << ")";
116     }
117     void writeCtorParameters(raw_ostream &OS) const {
118       OS << type << " " << getUpperName();
119     }
120     void writeDeclarations(raw_ostream &OS) const {
121       OS << type << " " << getLowerName() << ";";
122     }
123     void writePCHReadDecls(raw_ostream &OS) const {
124       std::string read = ReadPCHRecord(type);
125       OS << "    " << type << " " << getLowerName() << " = " << read << ";\n";
126     }
127     void writePCHReadArgs(raw_ostream &OS) const {
128       OS << getLowerName();
129     }
130     void writePCHWrite(raw_ostream &OS) const {
131       OS << "    " << WritePCHRecord(type, "SA->get" +
132                                            std::string(getUpperName()) + "()");
133     }
134   };
135
136   class StringArgument : public Argument {
137   public:
138     StringArgument(Record &Arg, StringRef Attr)
139       : Argument(Arg, Attr)
140     {}
141
142     void writeAccessors(raw_ostream &OS) const {
143       OS << "  llvm::StringRef get" << getUpperName() << "() const {\n";
144       OS << "    return llvm::StringRef(" << getLowerName() << ", "
145          << getLowerName() << "Length);\n";
146       OS << "  }\n";
147       OS << "  unsigned get" << getUpperName() << "Length() const {\n";
148       OS << "    return " << getLowerName() << "Length;\n";
149       OS << "  }\n";
150       OS << "  void set" << getUpperName()
151          << "(ASTContext &C, llvm::StringRef S) {\n";
152       OS << "    " << getLowerName() << "Length = S.size();\n";
153       OS << "    this->" << getLowerName() << " = new (C, 1) char ["
154          << getLowerName() << "Length];\n";
155       OS << "    std::memcpy(this->" << getLowerName() << ", S.data(), "
156          << getLowerName() << "Length);\n";
157       OS << "  }";
158     }
159     void writeCloneArgs(raw_ostream &OS) const {
160       OS << "get" << getUpperName() << "()";
161     }
162     void writeCtorBody(raw_ostream &OS) const {
163       OS << "      std::memcpy(" << getLowerName() << ", " << getUpperName()
164          << ".data(), " << getLowerName() << "Length);";
165     }
166     void writeCtorInitializers(raw_ostream &OS) const {
167       OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
168          << getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
169          << "Length])";
170     }
171     void writeCtorParameters(raw_ostream &OS) const {
172       OS << "llvm::StringRef " << getUpperName();
173     }
174     void writeDeclarations(raw_ostream &OS) const {
175       OS << "unsigned " << getLowerName() << "Length;\n";
176       OS << "char *" << getLowerName() << ";";
177     }
178     void writePCHReadDecls(raw_ostream &OS) const {
179       OS << "    std::string " << getLowerName()
180          << "= ReadString(Record, Idx);\n";
181     }
182     void writePCHReadArgs(raw_ostream &OS) const {
183       OS << getLowerName();
184     }
185     void writePCHWrite(raw_ostream &OS) const {
186       OS << "    AddString(SA->get" << getUpperName() << "(), Record);\n";
187     }
188   };
189
190   class AlignedArgument : public Argument {
191   public:
192     AlignedArgument(Record &Arg, StringRef Attr)
193       : Argument(Arg, Attr)
194     {}
195
196     void writeAccessors(raw_ostream &OS) const {
197       OS << "  bool is" << getUpperName() << "Dependent() const;\n";
198
199       OS << "  unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";
200
201       OS << "  bool is" << getUpperName() << "Expr() const {\n";
202       OS << "    return is" << getLowerName() << "Expr;\n";
203       OS << "  }\n";
204
205       OS << "  Expr *get" << getUpperName() << "Expr() const {\n";
206       OS << "    assert(is" << getLowerName() << "Expr);\n";
207       OS << "    return " << getLowerName() << "Expr;\n";
208       OS << "  }\n";
209
210       OS << "  TypeSourceInfo *get" << getUpperName() << "Type() const {\n";
211       OS << "    assert(!is" << getLowerName() << "Expr);\n";
212       OS << "    return " << getLowerName() << "Type;\n";
213       OS << "  }";
214     }
215     void writeAccessorDefinitions(raw_ostream &OS) const {
216       OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
217          << "Dependent() const {\n";
218       OS << "  if (is" << getLowerName() << "Expr)\n";
219       OS << "    return " << getLowerName() << "Expr && (" << getLowerName()
220          << "Expr->isValueDependent() || " << getLowerName()
221          << "Expr->isTypeDependent());\n"; 
222       OS << "  else\n";
223       OS << "    return " << getLowerName()
224          << "Type->getType()->isDependentType();\n";
225       OS << "}\n";
226
227       // FIXME: Do not do the calculation here
228       // FIXME: Handle types correctly
229       // A null pointer means maximum alignment
230       // FIXME: Load the platform-specific maximum alignment, rather than
231       //        16, the x86 max.
232       OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName()
233          << "(ASTContext &Ctx) const {\n";
234       OS << "  assert(!is" << getUpperName() << "Dependent());\n";
235       OS << "  if (is" << getLowerName() << "Expr)\n";
236       OS << "    return (" << getLowerName() << "Expr ? " << getLowerName()
237          << "Expr->EvaluateAsInt(Ctx).getZExtValue() : 16)"
238          << "* Ctx.getCharWidth();\n";
239       OS << "  else\n";
240       OS << "    return 0; // FIXME\n";
241       OS << "}\n";
242     }
243     void writeCloneArgs(raw_ostream &OS) const {
244       OS << "is" << getLowerName() << "Expr, is" << getLowerName()
245          << "Expr ? static_cast<void*>(" << getLowerName()
246          << "Expr) : " << getLowerName()
247          << "Type";
248     }
249     void writeCtorBody(raw_ostream &OS) const {
250       OS << "    if (is" << getLowerName() << "Expr)\n";
251       OS << "       " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
252          << getUpperName() << ");\n";
253       OS << "    else\n";
254       OS << "       " << getLowerName()
255          << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
256          << ");";
257     }
258     void writeCtorInitializers(raw_ostream &OS) const {
259       OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
260     }
261     void writeCtorParameters(raw_ostream &OS) const {
262       OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
263     }
264     void writeDeclarations(raw_ostream &OS) const {
265       OS << "bool is" << getLowerName() << "Expr;\n";
266       OS << "union {\n";
267       OS << "Expr *" << getLowerName() << "Expr;\n";
268       OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
269       OS << "};";
270     }
271     void writePCHReadArgs(raw_ostream &OS) const {
272       OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
273     }
274     void writePCHReadDecls(raw_ostream &OS) const {
275       OS << "    bool is" << getLowerName() << "Expr = Record[Idx++];\n";
276       OS << "    void *" << getLowerName() << "Ptr;\n";
277       OS << "    if (is" << getLowerName() << "Expr)\n";
278       OS << "      " << getLowerName() << "Ptr = ReadExpr(F);\n";
279       OS << "    else\n";
280       OS << "      " << getLowerName()
281          << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n";
282     }
283     void writePCHWrite(raw_ostream &OS) const {
284       OS << "    Record.push_back(SA->is" << getUpperName() << "Expr());\n";
285       OS << "    if (SA->is" << getUpperName() << "Expr())\n";
286       OS << "      AddStmt(SA->get" << getUpperName() << "Expr());\n";
287       OS << "    else\n";
288       OS << "      AddTypeSourceInfo(SA->get" << getUpperName()
289          << "Type(), Record);\n";
290     }
291   };
292
293   class VariadicArgument : public Argument {
294     std::string type;
295
296   public:
297     VariadicArgument(Record &Arg, StringRef Attr, std::string T)
298       : Argument(Arg, Attr), type(T)
299     {}
300
301     std::string getType() const { return type; }
302
303     void writeAccessors(raw_ostream &OS) const {
304       OS << "  typedef " << type << "* " << getLowerName() << "_iterator;\n";
305       OS << "  " << getLowerName() << "_iterator " << getLowerName()
306          << "_begin() const {\n";
307       OS << "    return " << getLowerName() << ";\n";
308       OS << "  }\n";
309       OS << "  " << getLowerName() << "_iterator " << getLowerName()
310          << "_end() const {\n";
311       OS << "    return " << getLowerName() << " + " << getLowerName()
312          << "Size;\n";
313       OS << "  }\n";
314       OS << "  unsigned " << getLowerName() << "_size() const {\n"
315          << "    return " << getLowerName() << "Size;\n;";
316       OS << "  }";
317     }
318     void writeCloneArgs(raw_ostream &OS) const {
319       OS << getLowerName() << ", " << getLowerName() << "Size";
320     }
321     void writeCtorBody(raw_ostream &OS) const {
322       // FIXME: memcpy is not safe on non-trivial types.
323       OS << "    std::memcpy(" << getLowerName() << ", " << getUpperName()
324          << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n";
325     }
326     void writeCtorInitializers(raw_ostream &OS) const {
327       OS << getLowerName() << "Size(" << getUpperName() << "Size), "
328          << getLowerName() << "(new (Ctx, 16) " << getType() << "["
329          << getLowerName() << "Size])";
330     }
331     void writeCtorParameters(raw_ostream &OS) const {
332       OS << getType() << " *" << getUpperName() << ", unsigned "
333          << getUpperName() << "Size";
334     }
335     void writeDeclarations(raw_ostream &OS) const {
336       OS << "  unsigned " << getLowerName() << "Size;\n";
337       OS << "  " << getType() << " *" << getLowerName() << ";";
338     }
339     void writePCHReadDecls(raw_ostream &OS) const {
340       OS << "  unsigned " << getLowerName() << "Size = Record[Idx++];\n";
341       OS << "  llvm::SmallVector<" << type << ", 4> " << getLowerName()
342          << ";\n";
343       OS << "  " << getLowerName() << ".reserve(" << getLowerName()
344          << "Size);\n";
345       OS << "  for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
346       
347       std::string read = ReadPCHRecord(type);
348       OS << "    " << getLowerName() << ".push_back(" << read << ");\n";
349     }
350     void writePCHReadArgs(raw_ostream &OS) const {
351       OS << getLowerName() << ".data(), " << getLowerName() << "Size";
352     }
353     void writePCHWrite(raw_ostream &OS) const{
354       OS << "    Record.push_back(SA->" << getLowerName() << "_size());\n";
355       OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
356          << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
357          << getLowerName() << "_end(); i != e; ++i)\n";
358       OS << "      " << WritePCHRecord(type, "(*i)");
359     }
360   };
361
362   class EnumArgument : public Argument {
363     std::string type;
364     std::vector<StringRef> values, enums;
365   public:
366     EnumArgument(Record &Arg, StringRef Attr)
367       : Argument(Arg, Attr), type(Arg.getValueAsString("Type")),
368         values(getValueAsListOfStrings(Arg, "Values")),
369         enums(getValueAsListOfStrings(Arg, "Enums"))
370     {}
371
372     void writeAccessors(raw_ostream &OS) const {
373       OS << "  " << type << " get" << getUpperName() << "() const {\n";
374       OS << "    return " << getLowerName() << ";\n";
375       OS << "  }";
376     }
377     void writeCloneArgs(raw_ostream &OS) const {
378       OS << getLowerName();
379     }
380     void writeCtorInitializers(raw_ostream &OS) const {
381       OS << getLowerName() << "(" << getUpperName() << ")";
382     }
383     void writeCtorParameters(raw_ostream &OS) const {
384       OS << type << " " << getUpperName();
385     }
386     void writeDeclarations(raw_ostream &OS) const {
387       // Calculate the various enum values
388       std::vector<StringRef> uniques(enums);
389       std::sort(uniques.begin(), uniques.end());
390       uniques.erase(std::unique(uniques.begin(), uniques.end()),
391                     uniques.end());
392       // FIXME: Emit a proper error
393       assert(!uniques.empty());
394
395       std::vector<StringRef>::iterator i = uniques.begin(),
396                                        e = uniques.end();
397       // The last one needs to not have a comma.
398       --e;
399
400       OS << "public:\n";
401       OS << "  enum " << type << " {\n";
402       for (; i != e; ++i)
403         OS << "    " << *i << ",\n";
404       OS << "    " << *e << "\n";
405       OS << "  };\n";
406       OS << "private:\n";
407       OS << "  " << type << " " << getLowerName() << ";";
408     }
409     void writePCHReadDecls(raw_ostream &OS) const {
410       OS << "    " << getAttrName() << "Attr::" << type << " " << getLowerName()
411          << "(static_cast<" << getAttrName() << "Attr::" << type
412          << ">(Record[Idx++]));\n";
413     }
414     void writePCHReadArgs(raw_ostream &OS) const {
415       OS << getLowerName();
416     }
417     void writePCHWrite(raw_ostream &OS) const {
418       OS << "Record.push_back(SA->get" << getUpperName() << "());\n";
419     }
420   };
421
422   class VersionArgument : public Argument {
423   public:
424     VersionArgument(Record &Arg, StringRef Attr)
425       : Argument(Arg, Attr)
426     {}
427
428     void writeAccessors(raw_ostream &OS) const {
429       OS << "  VersionTuple get" << getUpperName() << "() const {\n";
430       OS << "    return " << getLowerName() << ";\n";
431       OS << "  }\n";
432       OS << "  void set" << getUpperName() 
433          << "(ASTContext &C, VersionTuple V) {\n";
434       OS << "    " << getLowerName() << " = V;\n";
435       OS << "  }";
436     }
437     void writeCloneArgs(raw_ostream &OS) const {
438       OS << "get" << getUpperName() << "()";
439     }
440     void writeCtorBody(raw_ostream &OS) const {
441     }
442     void writeCtorInitializers(raw_ostream &OS) const {
443       OS << getLowerName() << "(" << getUpperName() << ")";
444     }
445     void writeCtorParameters(raw_ostream &OS) const {
446       OS << "VersionTuple " << getUpperName();
447     }
448     void writeDeclarations(raw_ostream &OS) const {
449       OS << "VersionTuple " << getLowerName() << ";\n";
450     }
451     void writePCHReadDecls(raw_ostream &OS) const {
452       OS << "    VersionTuple " << getLowerName()
453          << "= ReadVersionTuple(Record, Idx);\n";
454     }
455     void writePCHReadArgs(raw_ostream &OS) const {
456       OS << getLowerName();
457     }
458     void writePCHWrite(raw_ostream &OS) const {
459       OS << "    AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n";
460     }
461   };
462 }
463
464 static Argument *createArgument(Record &Arg, StringRef Attr,
465                                 Record *Search = 0) {
466   if (!Search)
467     Search = &Arg;
468
469   Argument *Ptr = 0;
470   llvm::StringRef ArgName = Search->getName();
471
472   if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr);
473   else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr);
474   else if (ArgName == "ExprArgument") Ptr = new SimpleArgument(Arg, Attr,
475                                                                "Expr *");
476   else if (ArgName == "FunctionArgument")
477     Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *");
478   else if (ArgName == "IdentifierArgument")
479     Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
480   else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr, 
481                                                                "bool");
482   else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
483   else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
484   else if (ArgName == "TypeArgument")
485     Ptr = new SimpleArgument(Arg, Attr, "QualType");
486   else if (ArgName == "UnsignedArgument")
487     Ptr = new SimpleArgument(Arg, Attr, "unsigned");
488   else if (ArgName == "VariadicUnsignedArgument")
489     Ptr = new VariadicArgument(Arg, Attr, "unsigned");
490   else if (ArgName == "VersionArgument")
491     Ptr = new VersionArgument(Arg, Attr);
492
493   if (!Ptr) {
494     std::vector<Record*> Bases = Search->getSuperClasses();
495     for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end();
496          i != e; ++i) {
497       Ptr = createArgument(Arg, Attr, *i);
498       if (Ptr)
499         break;
500     }
501   }
502   return Ptr;
503 }
504
505 void ClangAttrClassEmitter::run(raw_ostream &OS) {
506   OS << "// This file is generated by TableGen. Do not edit.\n\n";
507   OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
508   OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n";
509
510   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
511
512   for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
513        i != e; ++i) {
514     Record &R = **i;
515     const std::string &SuperName = R.getSuperClasses().back()->getName();
516
517     OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n";
518
519     std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
520     std::vector<Argument*> Args;
521     std::vector<Argument*>::iterator ai, ae;
522     Args.reserve(ArgRecords.size());
523
524     for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
525                                         re = ArgRecords.end();
526          ri != re; ++ri) {
527       Record &ArgRecord = **ri;
528       Argument *Arg = createArgument(ArgRecord, R.getName());
529       assert(Arg);
530       Args.push_back(Arg);
531
532       Arg->writeDeclarations(OS);
533       OS << "\n\n";
534     }
535
536     ae = Args.end();
537
538     OS << "\n public:\n";
539     OS << "  " << R.getName() << "Attr(SourceLocation L, ASTContext &Ctx\n";
540     
541     for (ai = Args.begin(); ai != ae; ++ai) {
542       OS << "              , ";
543       (*ai)->writeCtorParameters(OS);
544       OS << "\n";
545     }
546     
547     OS << "             )\n";
548     OS << "    : " << SuperName << "(attr::" << R.getName() << ", L)\n";
549
550     for (ai = Args.begin(); ai != ae; ++ai) {
551       OS << "              , ";
552       (*ai)->writeCtorInitializers(OS);
553       OS << "\n";
554     }
555
556     OS << "  {\n";
557   
558     for (ai = Args.begin(); ai != ae; ++ai) {
559       (*ai)->writeCtorBody(OS);
560       OS << "\n";
561     }
562     OS << "  }\n\n";
563
564     OS << "  virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n";
565
566     for (ai = Args.begin(); ai != ae; ++ai) {
567       (*ai)->writeAccessors(OS);
568       OS << "\n\n";
569     }
570
571     OS << R.getValueAsCode("AdditionalMembers");
572     OS << "\n\n";
573
574     OS << "  static bool classof(const Attr *A) { return A->getKind() == "
575        << "attr::" << R.getName() << "; }\n";
576     OS << "  static bool classof(const " << R.getName()
577        << "Attr *) { return true; }\n";
578     OS << "};\n\n";
579   }
580
581   OS << "#endif\n";
582 }
583
584 void ClangAttrImplEmitter::run(raw_ostream &OS) {
585   OS << "// This file is generated by TableGen. Do not edit.\n\n";
586
587   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
588   std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re;
589   std::vector<Argument*>::iterator ai, ae;
590
591   for (; i != e; ++i) {
592     Record &R = **i;
593     std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
594     std::vector<Argument*> Args;
595     for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri)
596       Args.push_back(createArgument(**ri, R.getName()));
597
598     for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
599       (*ai)->writeAccessorDefinitions(OS);
600
601     OS << R.getName() << "Attr *" << R.getName()
602        << "Attr::clone(ASTContext &C) const {\n";
603     OS << "  return new (C) " << R.getName() << "Attr(getLocation(), C";
604     for (ai = Args.begin(); ai != ae; ++ai) {
605       OS << ", ";
606       (*ai)->writeCloneArgs(OS);
607     }
608     OS << ");\n}\n\n";
609   }
610 }
611
612 static void EmitAttrList(raw_ostream &OS, StringRef Class,
613                          const std::vector<Record*> &AttrList) {
614   std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end();
615
616   if (i != e) {
617     // Move the end iterator back to emit the last attribute.
618     for(--e; i != e; ++i)
619       OS << Class << "(" << (*i)->getName() << ")\n";
620     
621     OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n";
622   }
623 }
624
625 void ClangAttrListEmitter::run(raw_ostream &OS) {
626   OS << "// This file is generated by TableGen. Do not edit.\n\n";
627
628   OS << "#ifndef LAST_ATTR\n";
629   OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n";
630   OS << "#endif\n\n";
631
632   OS << "#ifndef INHERITABLE_ATTR\n";
633   OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n";
634   OS << "#endif\n\n";
635
636   OS << "#ifndef LAST_INHERITABLE_ATTR\n";
637   OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
638   OS << "#endif\n\n";
639
640   OS << "#ifndef INHERITABLE_PARAM_ATTR\n";
641   OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n";
642   OS << "#endif\n\n";
643
644   OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n";
645   OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)"
646         " INHERITABLE_PARAM_ATTR(NAME)\n";
647   OS << "#endif\n\n";
648
649   Record *InhClass = Records.getClass("InheritableAttr");
650   Record *InhParamClass = Records.getClass("InheritableParamAttr");
651   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
652                        NonInhAttrs, InhAttrs, InhParamAttrs;
653   for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
654        i != e; ++i) {
655     if ((*i)->isSubClassOf(InhParamClass))
656       InhParamAttrs.push_back(*i);
657     else if ((*i)->isSubClassOf(InhClass))
658       InhAttrs.push_back(*i);
659     else
660       NonInhAttrs.push_back(*i);
661   }
662
663   EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
664   EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
665   EmitAttrList(OS, "ATTR", NonInhAttrs);
666
667   OS << "#undef LAST_ATTR\n";
668   OS << "#undef INHERITABLE_ATTR\n";
669   OS << "#undef LAST_INHERITABLE_ATTR\n";
670   OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
671   OS << "#undef ATTR\n";
672 }
673
674 void ClangAttrPCHReadEmitter::run(raw_ostream &OS) {
675   OS << "// This file is generated by TableGen. Do not edit.\n\n";
676
677   Record *InhClass = Records.getClass("InheritableAttr");
678   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
679                        ArgRecords;
680   std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
681   std::vector<Argument*> Args;
682   std::vector<Argument*>::iterator ri, re;
683
684   OS << "  switch (Kind) {\n";
685   OS << "  default:\n";
686   OS << "    assert(0 && \"Unknown attribute!\");\n";
687   OS << "    break;\n";
688   for (; i != e; ++i) {
689     Record &R = **i;
690     OS << "  case attr::" << R.getName() << ": {\n";
691     if (R.isSubClassOf(InhClass))
692       OS << "    bool isInherited = Record[Idx++];\n";
693     ArgRecords = R.getValueAsListOfDefs("Args");
694     Args.clear();
695     for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) {
696       Argument *A = createArgument(**ai, R.getName());
697       Args.push_back(A);
698       A->writePCHReadDecls(OS);
699     }
700     OS << "    New = new (*Context) " << R.getName() << "Attr(Loc, *Context";
701     for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) {
702       OS << ", ";
703       (*ri)->writePCHReadArgs(OS);
704     }
705     OS << ");\n";
706     if (R.isSubClassOf(InhClass))
707       OS << "    cast<InheritableAttr>(New)->setInherited(isInherited);\n";
708     OS << "    break;\n";
709     OS << "  }\n";
710   }
711   OS << "  }\n";
712 }
713
714 void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) {
715   Record *InhClass = Records.getClass("InheritableAttr");
716   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
717   std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
718
719   OS << "  switch (A->getKind()) {\n";
720   OS << "  default:\n";
721   OS << "    llvm_unreachable(\"Unknown attribute kind!\");\n";
722   OS << "    break;\n";
723   for (; i != e; ++i) {
724     Record &R = **i;
725     OS << "  case attr::" << R.getName() << ": {\n";
726     Args = R.getValueAsListOfDefs("Args");
727     if (R.isSubClassOf(InhClass) || !Args.empty())
728       OS << "    const " << R.getName() << "Attr *SA = cast<" << R.getName()
729          << "Attr>(A);\n";
730     if (R.isSubClassOf(InhClass))
731       OS << "    Record.push_back(SA->isInherited());\n";
732     for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
733       createArgument(**ai, R.getName())->writePCHWrite(OS);
734     OS << "    break;\n";
735     OS << "  }\n";
736   }
737   OS << "  }\n";
738 }
739
740 void ClangAttrSpellingListEmitter::run(raw_ostream &OS) {
741   OS << "// This file is generated by TableGen. Do not edit.\n\n";
742
743   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
744   
745   for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
746     Record &Attr = **I;
747
748     std::vector<StringRef> Spellings = getValueAsListOfStrings(Attr, "Spellings");
749
750     for (std::vector<StringRef>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) {
751       StringRef Spelling = *I;
752       OS << ".Case(\"" << Spelling << "\", true)\n";
753     }
754   }
755
756 }