]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp
MFC r244628:
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / 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 "llvm/ADT/SmallString.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/TableGen/Record.h"
17 #include "llvm/TableGen/StringMatcher.h"
18 #include "llvm/TableGen/TableGenBackend.h"
19 #include <algorithm>
20 #include <cctype>
21
22 using namespace llvm;
23
24 static const std::vector<StringRef>
25 getValueAsListOfStrings(Record &R, StringRef FieldName) {
26   ListInit *List = R.getValueAsListInit(FieldName);
27   assert (List && "Got a null ListInit");
28
29   std::vector<StringRef> Strings;
30   Strings.reserve(List->getSize());
31
32   for (ListInit::const_iterator i = List->begin(), e = List->end();
33        i != e;
34        ++i) {
35     assert(*i && "Got a null element in a ListInit");
36     if (StringInit *S = dyn_cast<StringInit>(*i))
37       Strings.push_back(S->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 // Normalize attribute name by removing leading and trailing
71 // underscores. For example, __foo, foo__, __foo__ would
72 // become foo.
73 static StringRef NormalizeAttrName(StringRef AttrName) {
74   if (AttrName.startswith("__"))
75     AttrName = AttrName.substr(2, AttrName.size());
76
77   if (AttrName.endswith("__"))
78     AttrName = AttrName.substr(0, AttrName.size() - 2);
79
80   return AttrName;
81 }
82
83 // Normalize attribute spelling only if the spelling has both leading
84 // and trailing underscores. For example, __ms_struct__ will be 
85 // normalized to "ms_struct"; __cdecl will remain intact.
86 static StringRef NormalizeAttrSpelling(StringRef AttrSpelling) {
87   if (AttrSpelling.startswith("__") && AttrSpelling.endswith("__")) {
88     AttrSpelling = AttrSpelling.substr(2, AttrSpelling.size() - 4);
89   }
90
91   return AttrSpelling;
92 }
93
94 namespace {
95   class Argument {
96     std::string lowerName, upperName;
97     StringRef attrName;
98
99   public:
100     Argument(Record &Arg, StringRef Attr)
101       : lowerName(Arg.getValueAsString("Name")), upperName(lowerName),
102         attrName(Attr) {
103       if (!lowerName.empty()) {
104         lowerName[0] = std::tolower(lowerName[0]);
105         upperName[0] = std::toupper(upperName[0]);
106       }
107     }
108     virtual ~Argument() {}
109
110     StringRef getLowerName() const { return lowerName; }
111     StringRef getUpperName() const { return upperName; }
112     StringRef getAttrName() const { return attrName; }
113
114     // These functions print the argument contents formatted in different ways.
115     virtual void writeAccessors(raw_ostream &OS) const = 0;
116     virtual void writeAccessorDefinitions(raw_ostream &OS) const {}
117     virtual void writeCloneArgs(raw_ostream &OS) const = 0;
118     virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0;
119     virtual void writeTemplateInstantiation(raw_ostream &OS) const {}
120     virtual void writeCtorBody(raw_ostream &OS) const {}
121     virtual void writeCtorInitializers(raw_ostream &OS) const = 0;
122     virtual void writeCtorParameters(raw_ostream &OS) const = 0;
123     virtual void writeDeclarations(raw_ostream &OS) const = 0;
124     virtual void writePCHReadArgs(raw_ostream &OS) const = 0;
125     virtual void writePCHReadDecls(raw_ostream &OS) const = 0;
126     virtual void writePCHWrite(raw_ostream &OS) const = 0;
127     virtual void writeValue(raw_ostream &OS) const = 0;
128   };
129
130   class SimpleArgument : public Argument {
131     std::string type;
132
133   public:
134     SimpleArgument(Record &Arg, StringRef Attr, std::string T)
135       : Argument(Arg, Attr), type(T)
136     {}
137
138     std::string getType() const { return type; }
139
140     void writeAccessors(raw_ostream &OS) const {
141       OS << "  " << type << " get" << getUpperName() << "() const {\n";
142       OS << "    return " << getLowerName() << ";\n";
143       OS << "  }";
144     }
145     void writeCloneArgs(raw_ostream &OS) const {
146       OS << getLowerName();
147     }
148     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
149       OS << "A->get" << getUpperName() << "()";
150     }
151     void writeCtorInitializers(raw_ostream &OS) const {
152       OS << getLowerName() << "(" << getUpperName() << ")";
153     }
154     void writeCtorParameters(raw_ostream &OS) const {
155       OS << type << " " << getUpperName();
156     }
157     void writeDeclarations(raw_ostream &OS) const {
158       OS << type << " " << getLowerName() << ";";
159     }
160     void writePCHReadDecls(raw_ostream &OS) const {
161       std::string read = ReadPCHRecord(type);
162       OS << "    " << type << " " << getLowerName() << " = " << read << ";\n";
163     }
164     void writePCHReadArgs(raw_ostream &OS) const {
165       OS << getLowerName();
166     }
167     void writePCHWrite(raw_ostream &OS) const {
168       OS << "    " << WritePCHRecord(type, "SA->get" +
169                                            std::string(getUpperName()) + "()");
170     }
171     void writeValue(raw_ostream &OS) const {
172       if (type == "FunctionDecl *") {
173         OS << "\" << get" << getUpperName() << "()->getNameInfo().getAsString() << \"";
174       } else if (type == "IdentifierInfo *") {
175         OS << "\" << get" << getUpperName() << "()->getName() << \"";
176       } else if (type == "QualType") {
177         OS << "\" << get" << getUpperName() << "().getAsString() << \"";
178       } else if (type == "SourceLocation") {
179         OS << "\" << get" << getUpperName() << "().getRawEncoding() << \"";
180       } else {
181         OS << "\" << get" << getUpperName() << "() << \"";
182       }
183     }
184   };
185
186   class StringArgument : public Argument {
187   public:
188     StringArgument(Record &Arg, StringRef Attr)
189       : Argument(Arg, Attr)
190     {}
191
192     void writeAccessors(raw_ostream &OS) const {
193       OS << "  llvm::StringRef get" << getUpperName() << "() const {\n";
194       OS << "    return llvm::StringRef(" << getLowerName() << ", "
195          << getLowerName() << "Length);\n";
196       OS << "  }\n";
197       OS << "  unsigned get" << getUpperName() << "Length() const {\n";
198       OS << "    return " << getLowerName() << "Length;\n";
199       OS << "  }\n";
200       OS << "  void set" << getUpperName()
201          << "(ASTContext &C, llvm::StringRef S) {\n";
202       OS << "    " << getLowerName() << "Length = S.size();\n";
203       OS << "    this->" << getLowerName() << " = new (C, 1) char ["
204          << getLowerName() << "Length];\n";
205       OS << "    std::memcpy(this->" << getLowerName() << ", S.data(), "
206          << getLowerName() << "Length);\n";
207       OS << "  }";
208     }
209     void writeCloneArgs(raw_ostream &OS) const {
210       OS << "get" << getUpperName() << "()";
211     }
212     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
213       OS << "A->get" << getUpperName() << "()";
214     }
215     void writeCtorBody(raw_ostream &OS) const {
216       OS << "      std::memcpy(" << getLowerName() << ", " << getUpperName()
217          << ".data(), " << getLowerName() << "Length);";
218     }
219     void writeCtorInitializers(raw_ostream &OS) const {
220       OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
221          << getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
222          << "Length])";
223     }
224     void writeCtorParameters(raw_ostream &OS) const {
225       OS << "llvm::StringRef " << getUpperName();
226     }
227     void writeDeclarations(raw_ostream &OS) const {
228       OS << "unsigned " << getLowerName() << "Length;\n";
229       OS << "char *" << getLowerName() << ";";
230     }
231     void writePCHReadDecls(raw_ostream &OS) const {
232       OS << "    std::string " << getLowerName()
233          << "= ReadString(Record, Idx);\n";
234     }
235     void writePCHReadArgs(raw_ostream &OS) const {
236       OS << getLowerName();
237     }
238     void writePCHWrite(raw_ostream &OS) const {
239       OS << "    AddString(SA->get" << getUpperName() << "(), Record);\n";
240     }
241     void writeValue(raw_ostream &OS) const {
242       OS << "\\\"\" << get" << getUpperName() << "() << \"\\\"";
243     }
244   };
245
246   class AlignedArgument : public Argument {
247   public:
248     AlignedArgument(Record &Arg, StringRef Attr)
249       : Argument(Arg, Attr)
250     {}
251
252     void writeAccessors(raw_ostream &OS) const {
253       OS << "  bool is" << getUpperName() << "Dependent() const;\n";
254
255       OS << "  unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";
256
257       OS << "  bool is" << getUpperName() << "Expr() const {\n";
258       OS << "    return is" << getLowerName() << "Expr;\n";
259       OS << "  }\n";
260
261       OS << "  Expr *get" << getUpperName() << "Expr() const {\n";
262       OS << "    assert(is" << getLowerName() << "Expr);\n";
263       OS << "    return " << getLowerName() << "Expr;\n";
264       OS << "  }\n";
265
266       OS << "  TypeSourceInfo *get" << getUpperName() << "Type() const {\n";
267       OS << "    assert(!is" << getLowerName() << "Expr);\n";
268       OS << "    return " << getLowerName() << "Type;\n";
269       OS << "  }";
270     }
271     void writeAccessorDefinitions(raw_ostream &OS) const {
272       OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
273          << "Dependent() const {\n";
274       OS << "  if (is" << getLowerName() << "Expr)\n";
275       OS << "    return " << getLowerName() << "Expr && (" << getLowerName()
276          << "Expr->isValueDependent() || " << getLowerName()
277          << "Expr->isTypeDependent());\n"; 
278       OS << "  else\n";
279       OS << "    return " << getLowerName()
280          << "Type->getType()->isDependentType();\n";
281       OS << "}\n";
282
283       // FIXME: Do not do the calculation here
284       // FIXME: Handle types correctly
285       // A null pointer means maximum alignment
286       // FIXME: Load the platform-specific maximum alignment, rather than
287       //        16, the x86 max.
288       OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName()
289          << "(ASTContext &Ctx) const {\n";
290       OS << "  assert(!is" << getUpperName() << "Dependent());\n";
291       OS << "  if (is" << getLowerName() << "Expr)\n";
292       OS << "    return (" << getLowerName() << "Expr ? " << getLowerName()
293          << "Expr->EvaluateKnownConstInt(Ctx).getZExtValue() : 16)"
294          << "* Ctx.getCharWidth();\n";
295       OS << "  else\n";
296       OS << "    return 0; // FIXME\n";
297       OS << "}\n";
298     }
299     void writeCloneArgs(raw_ostream &OS) const {
300       OS << "is" << getLowerName() << "Expr, is" << getLowerName()
301          << "Expr ? static_cast<void*>(" << getLowerName()
302          << "Expr) : " << getLowerName()
303          << "Type";
304     }
305     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
306       // FIXME: move the definition in Sema::InstantiateAttrs to here.
307       // In the meantime, aligned attributes are cloned.
308     }
309     void writeCtorBody(raw_ostream &OS) const {
310       OS << "    if (is" << getLowerName() << "Expr)\n";
311       OS << "       " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
312          << getUpperName() << ");\n";
313       OS << "    else\n";
314       OS << "       " << getLowerName()
315          << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
316          << ");";
317     }
318     void writeCtorInitializers(raw_ostream &OS) const {
319       OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
320     }
321     void writeCtorParameters(raw_ostream &OS) const {
322       OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
323     }
324     void writeDeclarations(raw_ostream &OS) const {
325       OS << "bool is" << getLowerName() << "Expr;\n";
326       OS << "union {\n";
327       OS << "Expr *" << getLowerName() << "Expr;\n";
328       OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
329       OS << "};";
330     }
331     void writePCHReadArgs(raw_ostream &OS) const {
332       OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
333     }
334     void writePCHReadDecls(raw_ostream &OS) const {
335       OS << "    bool is" << getLowerName() << "Expr = Record[Idx++];\n";
336       OS << "    void *" << getLowerName() << "Ptr;\n";
337       OS << "    if (is" << getLowerName() << "Expr)\n";
338       OS << "      " << getLowerName() << "Ptr = ReadExpr(F);\n";
339       OS << "    else\n";
340       OS << "      " << getLowerName()
341          << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n";
342     }
343     void writePCHWrite(raw_ostream &OS) const {
344       OS << "    Record.push_back(SA->is" << getUpperName() << "Expr());\n";
345       OS << "    if (SA->is" << getUpperName() << "Expr())\n";
346       OS << "      AddStmt(SA->get" << getUpperName() << "Expr());\n";
347       OS << "    else\n";
348       OS << "      AddTypeSourceInfo(SA->get" << getUpperName()
349          << "Type(), Record);\n";
350     }
351     void writeValue(raw_ostream &OS) const {
352       OS << "\";\n"
353          << "  " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n"
354          << "  OS << \"";
355     }
356   };
357
358   class VariadicArgument : public Argument {
359     std::string type;
360
361   public:
362     VariadicArgument(Record &Arg, StringRef Attr, std::string T)
363       : Argument(Arg, Attr), type(T)
364     {}
365
366     std::string getType() const { return type; }
367
368     void writeAccessors(raw_ostream &OS) const {
369       OS << "  typedef " << type << "* " << getLowerName() << "_iterator;\n";
370       OS << "  " << getLowerName() << "_iterator " << getLowerName()
371          << "_begin() const {\n";
372       OS << "    return " << getLowerName() << ";\n";
373       OS << "  }\n";
374       OS << "  " << getLowerName() << "_iterator " << getLowerName()
375          << "_end() const {\n";
376       OS << "    return " << getLowerName() << " + " << getLowerName()
377          << "Size;\n";
378       OS << "  }\n";
379       OS << "  unsigned " << getLowerName() << "_size() const {\n"
380          << "    return " << getLowerName() << "Size;\n";
381       OS << "  }";
382     }
383     void writeCloneArgs(raw_ostream &OS) const {
384       OS << getLowerName() << ", " << getLowerName() << "Size";
385     }
386     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
387       // This isn't elegant, but we have to go through public methods...
388       OS << "A->" << getLowerName() << "_begin(), "
389          << "A->" << getLowerName() << "_size()";
390     }
391     void writeCtorBody(raw_ostream &OS) const {
392       // FIXME: memcpy is not safe on non-trivial types.
393       OS << "    std::memcpy(" << getLowerName() << ", " << getUpperName()
394          << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n";
395     }
396     void writeCtorInitializers(raw_ostream &OS) const {
397       OS << getLowerName() << "Size(" << getUpperName() << "Size), "
398          << getLowerName() << "(new (Ctx, 16) " << getType() << "["
399          << getLowerName() << "Size])";
400     }
401     void writeCtorParameters(raw_ostream &OS) const {
402       OS << getType() << " *" << getUpperName() << ", unsigned "
403          << getUpperName() << "Size";
404     }
405     void writeDeclarations(raw_ostream &OS) const {
406       OS << "  unsigned " << getLowerName() << "Size;\n";
407       OS << "  " << getType() << " *" << getLowerName() << ";";
408     }
409     void writePCHReadDecls(raw_ostream &OS) const {
410       OS << "  unsigned " << getLowerName() << "Size = Record[Idx++];\n";
411       OS << "  llvm::SmallVector<" << type << ", 4> " << getLowerName()
412          << ";\n";
413       OS << "  " << getLowerName() << ".reserve(" << getLowerName()
414          << "Size);\n";
415       OS << "  for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
416       
417       std::string read = ReadPCHRecord(type);
418       OS << "    " << getLowerName() << ".push_back(" << read << ");\n";
419     }
420     void writePCHReadArgs(raw_ostream &OS) const {
421       OS << getLowerName() << ".data(), " << getLowerName() << "Size";
422     }
423     void writePCHWrite(raw_ostream &OS) const{
424       OS << "    Record.push_back(SA->" << getLowerName() << "_size());\n";
425       OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
426          << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
427          << getLowerName() << "_end(); i != e; ++i)\n";
428       OS << "      " << WritePCHRecord(type, "(*i)");
429     }
430     void writeValue(raw_ostream &OS) const {
431       OS << "\";\n";
432       OS << "  bool isFirst = true;\n"
433          << "  for (" << getAttrName() << "Attr::" << getLowerName()
434          << "_iterator i = " << getLowerName() << "_begin(), e = "
435          << getLowerName() << "_end(); i != e; ++i) {\n"
436          << "    if (isFirst) isFirst = false;\n"
437          << "    else OS << \", \";\n"
438          << "    OS << *i;\n"
439          << "  }\n";
440       OS << "  OS << \"";
441     }
442   };
443
444   class EnumArgument : public Argument {
445     std::string type;
446     std::vector<StringRef> values, enums;
447   public:
448     EnumArgument(Record &Arg, StringRef Attr)
449       : Argument(Arg, Attr), type(Arg.getValueAsString("Type")),
450         values(getValueAsListOfStrings(Arg, "Values")),
451         enums(getValueAsListOfStrings(Arg, "Enums"))
452     {}
453
454     void writeAccessors(raw_ostream &OS) const {
455       OS << "  " << type << " get" << getUpperName() << "() const {\n";
456       OS << "    return " << getLowerName() << ";\n";
457       OS << "  }";
458     }
459     void writeCloneArgs(raw_ostream &OS) const {
460       OS << getLowerName();
461     }
462     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
463       OS << "A->get" << getUpperName() << "()";
464     }
465     void writeCtorInitializers(raw_ostream &OS) const {
466       OS << getLowerName() << "(" << getUpperName() << ")";
467     }
468     void writeCtorParameters(raw_ostream &OS) const {
469       OS << type << " " << getUpperName();
470     }
471     void writeDeclarations(raw_ostream &OS) const {
472       // Calculate the various enum values
473       std::vector<StringRef> uniques(enums);
474       std::sort(uniques.begin(), uniques.end());
475       uniques.erase(std::unique(uniques.begin(), uniques.end()),
476                     uniques.end());
477       // FIXME: Emit a proper error
478       assert(!uniques.empty());
479
480       std::vector<StringRef>::iterator i = uniques.begin(),
481                                        e = uniques.end();
482       // The last one needs to not have a comma.
483       --e;
484
485       OS << "public:\n";
486       OS << "  enum " << type << " {\n";
487       for (; i != e; ++i)
488         OS << "    " << *i << ",\n";
489       OS << "    " << *e << "\n";
490       OS << "  };\n";
491       OS << "private:\n";
492       OS << "  " << type << " " << getLowerName() << ";";
493     }
494     void writePCHReadDecls(raw_ostream &OS) const {
495       OS << "    " << getAttrName() << "Attr::" << type << " " << getLowerName()
496          << "(static_cast<" << getAttrName() << "Attr::" << type
497          << ">(Record[Idx++]));\n";
498     }
499     void writePCHReadArgs(raw_ostream &OS) const {
500       OS << getLowerName();
501     }
502     void writePCHWrite(raw_ostream &OS) const {
503       OS << "Record.push_back(SA->get" << getUpperName() << "());\n";
504     }
505     void writeValue(raw_ostream &OS) const {
506       OS << "\" << get" << getUpperName() << "() << \"";
507     }
508   };
509
510   class VersionArgument : public Argument {
511   public:
512     VersionArgument(Record &Arg, StringRef Attr)
513       : Argument(Arg, Attr)
514     {}
515
516     void writeAccessors(raw_ostream &OS) const {
517       OS << "  VersionTuple get" << getUpperName() << "() const {\n";
518       OS << "    return " << getLowerName() << ";\n";
519       OS << "  }\n";
520       OS << "  void set" << getUpperName() 
521          << "(ASTContext &C, VersionTuple V) {\n";
522       OS << "    " << getLowerName() << " = V;\n";
523       OS << "  }";
524     }
525     void writeCloneArgs(raw_ostream &OS) const {
526       OS << "get" << getUpperName() << "()";
527     }
528     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
529       OS << "A->get" << getUpperName() << "()";
530     }
531     void writeCtorBody(raw_ostream &OS) const {
532     }
533     void writeCtorInitializers(raw_ostream &OS) const {
534       OS << getLowerName() << "(" << getUpperName() << ")";
535     }
536     void writeCtorParameters(raw_ostream &OS) const {
537       OS << "VersionTuple " << getUpperName();
538     }
539     void writeDeclarations(raw_ostream &OS) const {
540       OS << "VersionTuple " << getLowerName() << ";\n";
541     }
542     void writePCHReadDecls(raw_ostream &OS) const {
543       OS << "    VersionTuple " << getLowerName()
544          << "= ReadVersionTuple(Record, Idx);\n";
545     }
546     void writePCHReadArgs(raw_ostream &OS) const {
547       OS << getLowerName();
548     }
549     void writePCHWrite(raw_ostream &OS) const {
550       OS << "    AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n";
551     }
552     void writeValue(raw_ostream &OS) const {
553       OS << getLowerName() << "=\" << get" << getUpperName() << "() << \"";
554     }
555   };
556
557   class ExprArgument : public SimpleArgument {
558   public:
559     ExprArgument(Record &Arg, StringRef Attr)
560       : SimpleArgument(Arg, Attr, "Expr *")
561     {}
562
563     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
564       OS << "tempInst" << getUpperName();
565     }
566
567     void writeTemplateInstantiation(raw_ostream &OS) const {
568       OS << "      " << getType() << " tempInst" << getUpperName() << ";\n";
569       OS << "      {\n";
570       OS << "        EnterExpressionEvaluationContext "
571          << "Unevaluated(S, Sema::Unevaluated);\n";
572       OS << "        ExprResult " << "Result = S.SubstExpr("
573          << "A->get" << getUpperName() << "(), TemplateArgs);\n";
574       OS << "        tempInst" << getUpperName() << " = "
575          << "Result.takeAs<Expr>();\n";
576       OS << "      }\n";
577     }
578   };
579
580   class VariadicExprArgument : public VariadicArgument {
581   public:
582     VariadicExprArgument(Record &Arg, StringRef Attr)
583       : VariadicArgument(Arg, Attr, "Expr *")
584     {}
585
586     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
587       OS << "tempInst" << getUpperName() << ", "
588          << "A->" << getLowerName() << "_size()";
589     }
590
591     void writeTemplateInstantiation(raw_ostream &OS) const {
592       OS << "      " << getType() << " *tempInst" << getUpperName()
593          << " = new (C, 16) " << getType()
594          << "[A->" << getLowerName() << "_size()];\n";
595       OS << "      {\n";
596       OS << "        EnterExpressionEvaluationContext "
597          << "Unevaluated(S, Sema::Unevaluated);\n";
598       OS << "        " << getType() << " *TI = tempInst" << getUpperName()
599          << ";\n";
600       OS << "        " << getType() << " *I = A->" << getLowerName()
601          << "_begin();\n";
602       OS << "        " << getType() << " *E = A->" << getLowerName()
603          << "_end();\n";
604       OS << "        for (; I != E; ++I, ++TI) {\n";
605       OS << "          ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n";
606       OS << "          *TI = Result.takeAs<Expr>();\n";
607       OS << "        }\n";
608       OS << "      }\n";
609     }
610   };
611 }
612
613 static Argument *createArgument(Record &Arg, StringRef Attr,
614                                 Record *Search = 0) {
615   if (!Search)
616     Search = &Arg;
617
618   Argument *Ptr = 0;
619   llvm::StringRef ArgName = Search->getName();
620
621   if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr);
622   else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr);
623   else if (ArgName == "ExprArgument") Ptr = new ExprArgument(Arg, Attr);
624   else if (ArgName == "FunctionArgument")
625     Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *");
626   else if (ArgName == "IdentifierArgument")
627     Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
628   else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr, 
629                                                                "bool");
630   else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
631   else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
632   else if (ArgName == "TypeArgument")
633     Ptr = new SimpleArgument(Arg, Attr, "QualType");
634   else if (ArgName == "UnsignedArgument")
635     Ptr = new SimpleArgument(Arg, Attr, "unsigned");
636   else if (ArgName == "SourceLocArgument")
637     Ptr = new SimpleArgument(Arg, Attr, "SourceLocation");
638   else if (ArgName == "VariadicUnsignedArgument")
639     Ptr = new VariadicArgument(Arg, Attr, "unsigned");
640   else if (ArgName == "VariadicExprArgument")
641     Ptr = new VariadicExprArgument(Arg, Attr);
642   else if (ArgName == "VersionArgument")
643     Ptr = new VersionArgument(Arg, Attr);
644
645   if (!Ptr) {
646     std::vector<Record*> Bases = Search->getSuperClasses();
647     for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end();
648          i != e; ++i) {
649       Ptr = createArgument(Arg, Attr, *i);
650       if (Ptr)
651         break;
652     }
653   }
654   return Ptr;
655 }
656
657 static void writeAvailabilityValue(raw_ostream &OS) {
658   OS << "\" << getPlatform()->getName();\n"
659      << "  if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n"
660      << "  if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n"
661      << "  if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n"
662      << "  if (getUnavailable()) OS << \", unavailable\";\n"
663      << "  OS << \"";
664 }
665
666 namespace clang {
667
668 // Emits the class definitions for attributes.
669 void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
670   OS << "// This file is generated by TableGen. Do not edit.\n\n";
671   OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
672   OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n";
673
674   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
675
676   for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
677        i != e; ++i) {
678     Record &R = **i;
679     
680     if (!R.getValueAsBit("ASTNode"))
681       continue;
682     
683     const std::string &SuperName = R.getSuperClasses().back()->getName();
684
685     OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n";
686
687     std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
688     std::vector<Argument*> Args;
689     std::vector<Argument*>::iterator ai, ae;
690     Args.reserve(ArgRecords.size());
691
692     for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
693                                         re = ArgRecords.end();
694          ri != re; ++ri) {
695       Record &ArgRecord = **ri;
696       Argument *Arg = createArgument(ArgRecord, R.getName());
697       assert(Arg);
698       Args.push_back(Arg);
699
700       Arg->writeDeclarations(OS);
701       OS << "\n\n";
702     }
703
704     ae = Args.end();
705
706     OS << "\n public:\n";
707     OS << "  " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n";
708     
709     for (ai = Args.begin(); ai != ae; ++ai) {
710       OS << "              , ";
711       (*ai)->writeCtorParameters(OS);
712       OS << "\n";
713     }
714     
715     OS << "             )\n";
716     OS << "    : " << SuperName << "(attr::" << R.getName() << ", R)\n";
717
718     for (ai = Args.begin(); ai != ae; ++ai) {
719       OS << "              , ";
720       (*ai)->writeCtorInitializers(OS);
721       OS << "\n";
722     }
723
724     OS << "  {\n";
725   
726     for (ai = Args.begin(); ai != ae; ++ai) {
727       (*ai)->writeCtorBody(OS);
728       OS << "\n";
729     }
730     OS << "  }\n\n";
731
732     OS << "  virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n";
733     OS << "  virtual void printPretty(llvm::raw_ostream &OS,"
734        << "                           const PrintingPolicy &Policy) const;\n";
735
736     for (ai = Args.begin(); ai != ae; ++ai) {
737       (*ai)->writeAccessors(OS);
738       OS << "\n\n";
739     }
740
741     OS << R.getValueAsString("AdditionalMembers");
742     OS << "\n\n";
743
744     OS << "  static bool classof(const Attr *A) { return A->getKind() == "
745        << "attr::" << R.getName() << "; }\n";
746
747     bool LateParsed = R.getValueAsBit("LateParsed");
748     OS << "  virtual bool isLateParsed() const { return "
749        << LateParsed << "; }\n";
750
751     OS << "};\n\n";
752   }
753
754   OS << "#endif\n";
755 }
756
757 // Emits the class method definitions for attributes.
758 void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
759   OS << "// This file is generated by TableGen. Do not edit.\n\n";
760
761   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
762   std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re;
763   std::vector<Argument*>::iterator ai, ae;
764
765   for (; i != e; ++i) {
766     Record &R = **i;
767     
768     if (!R.getValueAsBit("ASTNode"))
769       continue;
770     
771     std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
772     std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
773     std::vector<Argument*> Args;
774     for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri)
775       Args.push_back(createArgument(**ri, R.getName()));
776
777     for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
778       (*ai)->writeAccessorDefinitions(OS);
779
780     OS << R.getName() << "Attr *" << R.getName()
781        << "Attr::clone(ASTContext &C) const {\n";
782     OS << "  return new (C) " << R.getName() << "Attr(getLocation(), C";
783     for (ai = Args.begin(); ai != ae; ++ai) {
784       OS << ", ";
785       (*ai)->writeCloneArgs(OS);
786     }
787     OS << ");\n}\n\n";
788
789     OS << "void " << R.getName() << "Attr::printPretty("
790        << "llvm::raw_ostream &OS, const PrintingPolicy &Policy) const {\n";
791     if (Spellings.begin() != Spellings.end()) {
792       std::string Spelling = (*Spellings.begin())->getValueAsString("Name");
793       OS << "  OS << \" __attribute__((" << Spelling;
794       if (Args.size()) OS << "(";
795       if (Spelling == "availability") {
796         writeAvailabilityValue(OS);
797       } else {
798         for (ai = Args.begin(); ai != ae; ++ai) {
799           if (ai!=Args.begin()) OS <<", ";
800           (*ai)->writeValue(OS);
801         }
802       }
803       if (Args.size()) OS << ")";
804       OS << "))\";\n";
805     }
806     OS << "}\n\n";
807   }
808 }
809
810 } // end namespace clang
811
812 static void EmitAttrList(raw_ostream &OS, StringRef Class,
813                          const std::vector<Record*> &AttrList) {
814   std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end();
815
816   if (i != e) {
817     // Move the end iterator back to emit the last attribute.
818     for(--e; i != e; ++i) {
819       if (!(*i)->getValueAsBit("ASTNode"))
820         continue;
821       
822       OS << Class << "(" << (*i)->getName() << ")\n";
823     }
824     
825     OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n";
826   }
827 }
828
829 namespace clang {
830
831 // Emits the enumeration list for attributes.
832 void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
833   OS << "// This file is generated by TableGen. Do not edit.\n\n";
834
835   OS << "#ifndef LAST_ATTR\n";
836   OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n";
837   OS << "#endif\n\n";
838
839   OS << "#ifndef INHERITABLE_ATTR\n";
840   OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n";
841   OS << "#endif\n\n";
842
843   OS << "#ifndef LAST_INHERITABLE_ATTR\n";
844   OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
845   OS << "#endif\n\n";
846
847   OS << "#ifndef INHERITABLE_PARAM_ATTR\n";
848   OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n";
849   OS << "#endif\n\n";
850
851   OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n";
852   OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)"
853         " INHERITABLE_PARAM_ATTR(NAME)\n";
854   OS << "#endif\n\n";
855
856   Record *InhClass = Records.getClass("InheritableAttr");
857   Record *InhParamClass = Records.getClass("InheritableParamAttr");
858   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
859                        NonInhAttrs, InhAttrs, InhParamAttrs;
860   for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
861        i != e; ++i) {
862     if (!(*i)->getValueAsBit("ASTNode"))
863       continue;
864     
865     if ((*i)->isSubClassOf(InhParamClass))
866       InhParamAttrs.push_back(*i);
867     else if ((*i)->isSubClassOf(InhClass))
868       InhAttrs.push_back(*i);
869     else
870       NonInhAttrs.push_back(*i);
871   }
872
873   EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
874   EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
875   EmitAttrList(OS, "ATTR", NonInhAttrs);
876
877   OS << "#undef LAST_ATTR\n";
878   OS << "#undef INHERITABLE_ATTR\n";
879   OS << "#undef LAST_INHERITABLE_ATTR\n";
880   OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
881   OS << "#undef ATTR\n";
882 }
883
884 // Emits the code to read an attribute from a precompiled header.
885 void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
886   OS << "// This file is generated by TableGen. Do not edit.\n\n";
887
888   Record *InhClass = Records.getClass("InheritableAttr");
889   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
890                        ArgRecords;
891   std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
892   std::vector<Argument*> Args;
893   std::vector<Argument*>::iterator ri, re;
894
895   OS << "  switch (Kind) {\n";
896   OS << "  default:\n";
897   OS << "    assert(0 && \"Unknown attribute!\");\n";
898   OS << "    break;\n";
899   for (; i != e; ++i) {
900     Record &R = **i;
901     if (!R.getValueAsBit("ASTNode"))
902       continue;
903     
904     OS << "  case attr::" << R.getName() << ": {\n";
905     if (R.isSubClassOf(InhClass))
906       OS << "    bool isInherited = Record[Idx++];\n";
907     ArgRecords = R.getValueAsListOfDefs("Args");
908     Args.clear();
909     for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) {
910       Argument *A = createArgument(**ai, R.getName());
911       Args.push_back(A);
912       A->writePCHReadDecls(OS);
913     }
914     OS << "    New = new (Context) " << R.getName() << "Attr(Range, Context";
915     for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) {
916       OS << ", ";
917       (*ri)->writePCHReadArgs(OS);
918     }
919     OS << ");\n";
920     if (R.isSubClassOf(InhClass))
921       OS << "    cast<InheritableAttr>(New)->setInherited(isInherited);\n";
922     OS << "    break;\n";
923     OS << "  }\n";
924   }
925   OS << "  }\n";
926 }
927
928 // Emits the code to write an attribute to a precompiled header.
929 void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
930   Record *InhClass = Records.getClass("InheritableAttr");
931   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
932   std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
933
934   OS << "  switch (A->getKind()) {\n";
935   OS << "  default:\n";
936   OS << "    llvm_unreachable(\"Unknown attribute kind!\");\n";
937   OS << "    break;\n";
938   for (; i != e; ++i) {
939     Record &R = **i;
940     if (!R.getValueAsBit("ASTNode"))
941       continue;
942     OS << "  case attr::" << R.getName() << ": {\n";
943     Args = R.getValueAsListOfDefs("Args");
944     if (R.isSubClassOf(InhClass) || !Args.empty())
945       OS << "    const " << R.getName() << "Attr *SA = cast<" << R.getName()
946          << "Attr>(A);\n";
947     if (R.isSubClassOf(InhClass))
948       OS << "    Record.push_back(SA->isInherited());\n";
949     for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
950       createArgument(**ai, R.getName())->writePCHWrite(OS);
951     OS << "    break;\n";
952     OS << "  }\n";
953   }
954   OS << "  }\n";
955 }
956
957 // Emits the list of spellings for attributes.
958 void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) {
959   OS << "// This file is generated by TableGen. Do not edit.\n\n";
960
961   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
962   
963   for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
964     Record &Attr = **I;
965
966     std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
967
968     for (std::vector<Record*>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) {
969       OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", true)\n";
970     }
971   }
972
973 }
974
975 // Emits the LateParsed property for attributes.
976 void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) {
977   OS << "// This file is generated by TableGen. Do not edit.\n\n";
978
979   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
980
981   for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
982        I != E; ++I) {
983     Record &Attr = **I;
984
985     bool LateParsed = Attr.getValueAsBit("LateParsed");
986
987     if (LateParsed) {
988       std::vector<Record*> Spellings =
989         Attr.getValueAsListOfDefs("Spellings");
990
991       // FIXME: Handle non-GNU attributes
992       for (std::vector<Record*>::const_iterator I = Spellings.begin(),
993            E = Spellings.end(); I != E; ++I) {
994         if ((*I)->getValueAsString("Variety") != "GNU")
995           continue;
996         OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", "
997            << LateParsed << ")\n";
998       }
999     }
1000   }
1001 }
1002
1003 // Emits code to instantiate dependent attributes on templates.
1004 void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) {
1005   OS << "// This file is generated by TableGen. Do not edit.\n\n";
1006
1007   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1008
1009   OS << "namespace clang {\n"
1010      << "namespace sema {\n\n"
1011      << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
1012      << "Sema &S,\n"
1013      << "        const MultiLevelTemplateArgumentList &TemplateArgs) {\n"
1014      << "  switch (At->getKind()) {\n"
1015      << "    default:\n"
1016      << "      break;\n";
1017
1018   for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1019        I != E; ++I) {
1020     Record &R = **I;
1021     if (!R.getValueAsBit("ASTNode"))
1022       continue;
1023
1024     OS << "    case attr::" << R.getName() << ": {\n";
1025     bool ShouldClone = R.getValueAsBit("Clone");
1026
1027     if (!ShouldClone) {
1028       OS << "      return NULL;\n";
1029       OS << "    }\n";
1030       continue;
1031     }
1032
1033     OS << "      const " << R.getName() << "Attr *A = cast<"
1034        << R.getName() << "Attr>(At);\n";
1035     bool TDependent = R.getValueAsBit("TemplateDependent");
1036
1037     if (!TDependent) {
1038       OS << "      return A->clone(C);\n";
1039       OS << "    }\n";
1040       continue;
1041     }
1042
1043     std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
1044     std::vector<Argument*> Args;
1045     std::vector<Argument*>::iterator ai, ae;
1046     Args.reserve(ArgRecords.size());
1047
1048     for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
1049                                         re = ArgRecords.end();
1050          ri != re; ++ri) {
1051       Record &ArgRecord = **ri;
1052       Argument *Arg = createArgument(ArgRecord, R.getName());
1053       assert(Arg);
1054       Args.push_back(Arg);
1055     }
1056     ae = Args.end();
1057
1058     for (ai = Args.begin(); ai != ae; ++ai) {
1059       (*ai)->writeTemplateInstantiation(OS);
1060     }
1061     OS << "      return new (C) " << R.getName() << "Attr(A->getLocation(), C";
1062     for (ai = Args.begin(); ai != ae; ++ai) {
1063       OS << ", ";
1064       (*ai)->writeTemplateInstantiationArgs(OS);
1065     }
1066     OS << ");\n    }\n";
1067   }
1068   OS << "  } // end switch\n"
1069      << "  llvm_unreachable(\"Unknown attribute!\");\n"
1070      << "  return 0;\n"
1071      << "}\n\n"
1072      << "} // end namespace sema\n"
1073      << "} // end namespace clang\n";
1074 }
1075
1076 // Emits the list of parsed attributes.
1077 void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) {
1078   OS << "// This file is generated by TableGen. Do not edit.\n\n";
1079   
1080   OS << "#ifndef PARSED_ATTR\n";
1081   OS << "#define PARSED_ATTR(NAME) NAME\n";
1082   OS << "#endif\n\n";
1083   
1084   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1085
1086   for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1087        I != E; ++I) {
1088     Record &Attr = **I;
1089     
1090     bool SemaHandler = Attr.getValueAsBit("SemaHandler");
1091     bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings");
1092
1093     if (SemaHandler) {
1094       if (DistinctSpellings) {
1095         std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1096         
1097         for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1098              E = Spellings.end(); I != E; ++I) {
1099           std::string AttrName = (*I)->getValueAsString("Name");
1100
1101           StringRef Spelling = NormalizeAttrName(AttrName);
1102
1103           OS << "PARSED_ATTR(" << Spelling << ")\n";
1104         }
1105       } else {
1106         StringRef AttrName = Attr.getName();
1107         AttrName = NormalizeAttrName(AttrName);
1108         OS << "PARSED_ATTR(" << AttrName << ")\n";
1109       }
1110     }
1111   }
1112 }
1113
1114 // Emits the kind list of parsed attributes
1115 void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
1116   OS << "// This file is generated by TableGen. Do not edit.\n\n";
1117   OS << "\n";
1118   
1119   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1120
1121   std::vector<StringMatcher::StringPair> Matches;
1122   for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1123        I != E; ++I) {
1124     Record &Attr = **I;
1125     
1126     bool SemaHandler = Attr.getValueAsBit("SemaHandler");
1127     bool Ignored = Attr.getValueAsBit("Ignored");
1128     bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings");
1129     if (SemaHandler || Ignored) {
1130       std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1131
1132       for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1133            E = Spellings.end(); I != E; ++I) {
1134         std::string RawSpelling = (*I)->getValueAsString("Name");
1135         StringRef AttrName = NormalizeAttrName(DistinctSpellings
1136                                                  ? StringRef(RawSpelling)
1137                                                  : StringRef(Attr.getName()));
1138
1139         SmallString<64> Spelling;
1140         if ((*I)->getValueAsString("Variety") == "CXX11") {
1141           Spelling += (*I)->getValueAsString("Namespace");
1142           Spelling += "::";
1143         }
1144         Spelling += NormalizeAttrSpelling(RawSpelling);
1145
1146         if (SemaHandler)
1147           Matches.push_back(
1148             StringMatcher::StringPair(
1149               StringRef(Spelling),
1150               "return AttributeList::AT_" + AttrName.str() + ";"));
1151         else
1152           Matches.push_back(
1153             StringMatcher::StringPair(
1154               StringRef(Spelling),
1155               "return AttributeList::IgnoredAttribute;"));
1156       }
1157     }
1158   }
1159   
1160   OS << "static AttributeList::Kind getAttrKind(StringRef Name) {\n";
1161   StringMatcher("Name", Matches, OS).Emit();
1162   OS << "return AttributeList::UnknownAttribute;\n"
1163      << "}\n";
1164 }
1165
1166 } // end namespace clang