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