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