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