ClangAttrEmitter.cpp revision 7b9ff0c09025dcbe48ec7db71330e2066d1e1863
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 "llvm/ADT/StringSwitch.h"
16#include "llvm/TableGen/Record.h"
17#include <algorithm>
18#include <cctype>
19
20using namespace llvm;
21
22static const std::vector<StringRef>
23getValueAsListOfStrings(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
37      assert(false && "Got a non-string, non-code element in a ListInit");
38  }
39
40  return Strings;
41}
42
43static std::string ReadPCHRecord(StringRef type) {
44  return StringSwitch<std::string>(type)
45    .EndsWith("Decl *", "GetLocalDeclAs<"
46              + std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])")
47    .Case("QualType", "getLocalType(F, Record[Idx++])")
48    .Case("Expr *", "ReadSubExpr()")
49    .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)")
50    .Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)")
51    .Default("Record[Idx++]");
52}
53
54// Assumes that the way to get the value is SA->getname()
55static std::string WritePCHRecord(StringRef type, StringRef name) {
56  return StringSwitch<std::string>(type)
57    .EndsWith("Decl *", "AddDeclRef(" + std::string(name) +
58                        ", Record);\n")
59    .Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n")
60    .Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
61    .Case("IdentifierInfo *",
62          "AddIdentifierRef(" + std::string(name) + ", Record);\n")
63    .Case("SourceLocation",
64          "AddSourceLocation(" + std::string(name) + ", Record);\n")
65    .Default("Record.push_back(" + std::string(name) + ");\n");
66}
67
68namespace {
69  class Argument {
70    std::string lowerName, upperName;
71    StringRef attrName;
72
73  public:
74    Argument(Record &Arg, StringRef Attr)
75      : lowerName(Arg.getValueAsString("Name")), upperName(lowerName),
76        attrName(Attr) {
77      if (!lowerName.empty()) {
78        lowerName[0] = std::tolower(lowerName[0]);
79        upperName[0] = std::toupper(upperName[0]);
80      }
81    }
82    virtual ~Argument() {}
83
84    StringRef getLowerName() const { return lowerName; }
85    StringRef getUpperName() const { return upperName; }
86    StringRef getAttrName() const { return attrName; }
87
88    // These functions print the argument contents formatted in different ways.
89    virtual void writeAccessors(raw_ostream &OS) const = 0;
90    virtual void writeAccessorDefinitions(raw_ostream &OS) const {}
91    virtual void writeCloneArgs(raw_ostream &OS) const = 0;
92    virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0;
93    virtual void writeTemplateInstantiation(raw_ostream &OS) const {};
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    virtual void writeValue(raw_ostream &OS) const = 0;
102  };
103
104  class SimpleArgument : public Argument {
105    std::string type;
106
107  public:
108    SimpleArgument(Record &Arg, StringRef Attr, std::string T)
109      : Argument(Arg, Attr), type(T)
110    {}
111
112    std::string getType() const { return type; }
113
114    void writeAccessors(raw_ostream &OS) const {
115      OS << "  " << type << " get" << getUpperName() << "() const {\n";
116      OS << "    return " << getLowerName() << ";\n";
117      OS << "  }";
118    }
119    void writeCloneArgs(raw_ostream &OS) const {
120      OS << getLowerName();
121    }
122    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
123      OS << "A->get" << getUpperName() << "()";
124    }
125    void writeCtorInitializers(raw_ostream &OS) const {
126      OS << getLowerName() << "(" << getUpperName() << ")";
127    }
128    void writeCtorParameters(raw_ostream &OS) const {
129      OS << type << " " << getUpperName();
130    }
131    void writeDeclarations(raw_ostream &OS) const {
132      OS << type << " " << getLowerName() << ";";
133    }
134    void writePCHReadDecls(raw_ostream &OS) const {
135      std::string read = ReadPCHRecord(type);
136      OS << "    " << type << " " << getLowerName() << " = " << read << ";\n";
137    }
138    void writePCHReadArgs(raw_ostream &OS) const {
139      OS << getLowerName();
140    }
141    void writePCHWrite(raw_ostream &OS) const {
142      OS << "    " << WritePCHRecord(type, "SA->get" +
143                                           std::string(getUpperName()) + "()");
144    }
145    void writeValue(raw_ostream &OS) const {
146      if (type == "FunctionDecl *") {
147        OS << "\" << get" << getUpperName() << "()->getNameInfo().getAsString() << \"";
148      } else if (type == "IdentifierInfo *") {
149        OS << "\" << get" << getUpperName() << "()->getName() << \"";
150      } else if (type == "QualType") {
151        OS << "\" << get" << getUpperName() << "().getAsString() << \"";
152      } else if (type == "SourceLocation") {
153        OS << "\" << get" << getUpperName() << "().getRawEncoding() << \"";
154      } else {
155        OS << "\" << get" << getUpperName() << "() << \"";
156      }
157    }
158  };
159
160  class StringArgument : public Argument {
161  public:
162    StringArgument(Record &Arg, StringRef Attr)
163      : Argument(Arg, Attr)
164    {}
165
166    void writeAccessors(raw_ostream &OS) const {
167      OS << "  llvm::StringRef get" << getUpperName() << "() const {\n";
168      OS << "    return llvm::StringRef(" << getLowerName() << ", "
169         << getLowerName() << "Length);\n";
170      OS << "  }\n";
171      OS << "  unsigned get" << getUpperName() << "Length() const {\n";
172      OS << "    return " << getLowerName() << "Length;\n";
173      OS << "  }\n";
174      OS << "  void set" << getUpperName()
175         << "(ASTContext &C, llvm::StringRef S) {\n";
176      OS << "    " << getLowerName() << "Length = S.size();\n";
177      OS << "    this->" << getLowerName() << " = new (C, 1) char ["
178         << getLowerName() << "Length];\n";
179      OS << "    std::memcpy(this->" << getLowerName() << ", S.data(), "
180         << getLowerName() << "Length);\n";
181      OS << "  }";
182    }
183    void writeCloneArgs(raw_ostream &OS) const {
184      OS << "get" << getUpperName() << "()";
185    }
186    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
187      OS << "A->get" << getUpperName() << "()";
188    }
189    void writeCtorBody(raw_ostream &OS) const {
190      OS << "      std::memcpy(" << getLowerName() << ", " << getUpperName()
191         << ".data(), " << getLowerName() << "Length);";
192    }
193    void writeCtorInitializers(raw_ostream &OS) const {
194      OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
195         << getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
196         << "Length])";
197    }
198    void writeCtorParameters(raw_ostream &OS) const {
199      OS << "llvm::StringRef " << getUpperName();
200    }
201    void writeDeclarations(raw_ostream &OS) const {
202      OS << "unsigned " << getLowerName() << "Length;\n";
203      OS << "char *" << getLowerName() << ";";
204    }
205    void writePCHReadDecls(raw_ostream &OS) const {
206      OS << "    std::string " << getLowerName()
207         << "= ReadString(Record, Idx);\n";
208    }
209    void writePCHReadArgs(raw_ostream &OS) const {
210      OS << getLowerName();
211    }
212    void writePCHWrite(raw_ostream &OS) const {
213      OS << "    AddString(SA->get" << getUpperName() << "(), Record);\n";
214    }
215    void writeValue(raw_ostream &OS) const {
216      OS << "\\\"\" << get" << getUpperName() << "() << \"\\\"";
217    }
218  };
219
220  class AlignedArgument : public Argument {
221  public:
222    AlignedArgument(Record &Arg, StringRef Attr)
223      : Argument(Arg, Attr)
224    {}
225
226    void writeAccessors(raw_ostream &OS) const {
227      OS << "  bool is" << getUpperName() << "Dependent() const;\n";
228
229      OS << "  unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";
230
231      OS << "  bool is" << getUpperName() << "Expr() const {\n";
232      OS << "    return is" << getLowerName() << "Expr;\n";
233      OS << "  }\n";
234
235      OS << "  Expr *get" << getUpperName() << "Expr() const {\n";
236      OS << "    assert(is" << getLowerName() << "Expr);\n";
237      OS << "    return " << getLowerName() << "Expr;\n";
238      OS << "  }\n";
239
240      OS << "  TypeSourceInfo *get" << getUpperName() << "Type() const {\n";
241      OS << "    assert(!is" << getLowerName() << "Expr);\n";
242      OS << "    return " << getLowerName() << "Type;\n";
243      OS << "  }";
244    }
245    void writeAccessorDefinitions(raw_ostream &OS) const {
246      OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
247         << "Dependent() const {\n";
248      OS << "  if (is" << getLowerName() << "Expr)\n";
249      OS << "    return " << getLowerName() << "Expr && (" << getLowerName()
250         << "Expr->isValueDependent() || " << getLowerName()
251         << "Expr->isTypeDependent());\n";
252      OS << "  else\n";
253      OS << "    return " << getLowerName()
254         << "Type->getType()->isDependentType();\n";
255      OS << "}\n";
256
257      // FIXME: Do not do the calculation here
258      // FIXME: Handle types correctly
259      // A null pointer means maximum alignment
260      // FIXME: Load the platform-specific maximum alignment, rather than
261      //        16, the x86 max.
262      OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName()
263         << "(ASTContext &Ctx) const {\n";
264      OS << "  assert(!is" << getUpperName() << "Dependent());\n";
265      OS << "  if (is" << getLowerName() << "Expr)\n";
266      OS << "    return (" << getLowerName() << "Expr ? " << getLowerName()
267         << "Expr->EvaluateKnownConstInt(Ctx).getZExtValue() : 16)"
268         << "* Ctx.getCharWidth();\n";
269      OS << "  else\n";
270      OS << "    return 0; // FIXME\n";
271      OS << "}\n";
272    }
273    void writeCloneArgs(raw_ostream &OS) const {
274      OS << "is" << getLowerName() << "Expr, is" << getLowerName()
275         << "Expr ? static_cast<void*>(" << getLowerName()
276         << "Expr) : " << getLowerName()
277         << "Type";
278    }
279    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
280      // FIXME: move the definition in Sema::InstantiateAttrs to here.
281      // In the meantime, aligned attributes are cloned.
282    }
283    void writeCtorBody(raw_ostream &OS) const {
284      OS << "    if (is" << getLowerName() << "Expr)\n";
285      OS << "       " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
286         << getUpperName() << ");\n";
287      OS << "    else\n";
288      OS << "       " << getLowerName()
289         << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
290         << ");";
291    }
292    void writeCtorInitializers(raw_ostream &OS) const {
293      OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
294    }
295    void writeCtorParameters(raw_ostream &OS) const {
296      OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
297    }
298    void writeDeclarations(raw_ostream &OS) const {
299      OS << "bool is" << getLowerName() << "Expr;\n";
300      OS << "union {\n";
301      OS << "Expr *" << getLowerName() << "Expr;\n";
302      OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
303      OS << "};";
304    }
305    void writePCHReadArgs(raw_ostream &OS) const {
306      OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
307    }
308    void writePCHReadDecls(raw_ostream &OS) const {
309      OS << "    bool is" << getLowerName() << "Expr = Record[Idx++];\n";
310      OS << "    void *" << getLowerName() << "Ptr;\n";
311      OS << "    if (is" << getLowerName() << "Expr)\n";
312      OS << "      " << getLowerName() << "Ptr = ReadExpr(F);\n";
313      OS << "    else\n";
314      OS << "      " << getLowerName()
315         << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n";
316    }
317    void writePCHWrite(raw_ostream &OS) const {
318      OS << "    Record.push_back(SA->is" << getUpperName() << "Expr());\n";
319      OS << "    if (SA->is" << getUpperName() << "Expr())\n";
320      OS << "      AddStmt(SA->get" << getUpperName() << "Expr());\n";
321      OS << "    else\n";
322      OS << "      AddTypeSourceInfo(SA->get" << getUpperName()
323         << "Type(), Record);\n";
324    }
325    void writeValue(raw_ostream &OS) const {
326      OS << "\" << get" << getUpperName() << "(Ctx) << \"";
327    }
328  };
329
330  class VariadicArgument : public Argument {
331    std::string type;
332
333  public:
334    VariadicArgument(Record &Arg, StringRef Attr, std::string T)
335      : Argument(Arg, Attr), type(T)
336    {}
337
338    std::string getType() const { return type; }
339
340    void writeAccessors(raw_ostream &OS) const {
341      OS << "  typedef " << type << "* " << getLowerName() << "_iterator;\n";
342      OS << "  " << getLowerName() << "_iterator " << getLowerName()
343         << "_begin() const {\n";
344      OS << "    return " << getLowerName() << ";\n";
345      OS << "  }\n";
346      OS << "  " << getLowerName() << "_iterator " << getLowerName()
347         << "_end() const {\n";
348      OS << "    return " << getLowerName() << " + " << getLowerName()
349         << "Size;\n";
350      OS << "  }\n";
351      OS << "  unsigned " << getLowerName() << "_size() const {\n"
352         << "    return " << getLowerName() << "Size;\n;";
353      OS << "  }";
354    }
355    void writeCloneArgs(raw_ostream &OS) const {
356      OS << getLowerName() << ", " << getLowerName() << "Size";
357    }
358    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
359      // This isn't elegant, but we have to go through public methods...
360      OS << "A->" << getLowerName() << "_begin(), "
361         << "A->" << getLowerName() << "_size()";
362    }
363    void writeCtorBody(raw_ostream &OS) const {
364      // FIXME: memcpy is not safe on non-trivial types.
365      OS << "    std::memcpy(" << getLowerName() << ", " << getUpperName()
366         << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n";
367    }
368    void writeCtorInitializers(raw_ostream &OS) const {
369      OS << getLowerName() << "Size(" << getUpperName() << "Size), "
370         << getLowerName() << "(new (Ctx, 16) " << getType() << "["
371         << getLowerName() << "Size])";
372    }
373    void writeCtorParameters(raw_ostream &OS) const {
374      OS << getType() << " *" << getUpperName() << ", unsigned "
375         << getUpperName() << "Size";
376    }
377    void writeDeclarations(raw_ostream &OS) const {
378      OS << "  unsigned " << getLowerName() << "Size;\n";
379      OS << "  " << getType() << " *" << getLowerName() << ";";
380    }
381    void writePCHReadDecls(raw_ostream &OS) const {
382      OS << "  unsigned " << getLowerName() << "Size = Record[Idx++];\n";
383      OS << "  llvm::SmallVector<" << type << ", 4> " << getLowerName()
384         << ";\n";
385      OS << "  " << getLowerName() << ".reserve(" << getLowerName()
386         << "Size);\n";
387      OS << "  for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
388
389      std::string read = ReadPCHRecord(type);
390      OS << "    " << getLowerName() << ".push_back(" << read << ");\n";
391    }
392    void writePCHReadArgs(raw_ostream &OS) const {
393      OS << getLowerName() << ".data(), " << getLowerName() << "Size";
394    }
395    void writePCHWrite(raw_ostream &OS) const{
396      OS << "    Record.push_back(SA->" << getLowerName() << "_size());\n";
397      OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
398         << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
399         << getLowerName() << "_end(); i != e; ++i)\n";
400      OS << "      " << WritePCHRecord(type, "(*i)");
401    }
402    void writeValue(raw_ostream &OS) const {
403      OS << "\";\n";
404      OS << "  bool isFirst = true;\n"
405         << "  for (" << getAttrName() << "Attr::" << getLowerName()
406         << "_iterator i = " << getLowerName() << "_begin(), e = "
407         << getLowerName() << "_end(); i != e; ++i) {\n"
408         << "    if (isFirst) isFirst = false;\n"
409         << "    else OS << \", \";\n"
410         << "    OS << *i;\n"
411         << "  }\n";
412      OS << "  OS << \"";
413    }
414  };
415
416  class EnumArgument : public Argument {
417    std::string type;
418    std::vector<StringRef> values, enums;
419  public:
420    EnumArgument(Record &Arg, StringRef Attr)
421      : Argument(Arg, Attr), type(Arg.getValueAsString("Type")),
422        values(getValueAsListOfStrings(Arg, "Values")),
423        enums(getValueAsListOfStrings(Arg, "Enums"))
424    {}
425
426    void writeAccessors(raw_ostream &OS) const {
427      OS << "  " << type << " get" << getUpperName() << "() const {\n";
428      OS << "    return " << getLowerName() << ";\n";
429      OS << "  }";
430    }
431    void writeCloneArgs(raw_ostream &OS) const {
432      OS << getLowerName();
433    }
434    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
435      OS << "A->get" << getUpperName() << "()";
436    }
437    void writeCtorInitializers(raw_ostream &OS) const {
438      OS << getLowerName() << "(" << getUpperName() << ")";
439    }
440    void writeCtorParameters(raw_ostream &OS) const {
441      OS << type << " " << getUpperName();
442    }
443    void writeDeclarations(raw_ostream &OS) const {
444      // Calculate the various enum values
445      std::vector<StringRef> uniques(enums);
446      std::sort(uniques.begin(), uniques.end());
447      uniques.erase(std::unique(uniques.begin(), uniques.end()),
448                    uniques.end());
449      // FIXME: Emit a proper error
450      assert(!uniques.empty());
451
452      std::vector<StringRef>::iterator i = uniques.begin(),
453                                       e = uniques.end();
454      // The last one needs to not have a comma.
455      --e;
456
457      OS << "public:\n";
458      OS << "  enum " << type << " {\n";
459      for (; i != e; ++i)
460        OS << "    " << *i << ",\n";
461      OS << "    " << *e << "\n";
462      OS << "  };\n";
463      OS << "private:\n";
464      OS << "  " << type << " " << getLowerName() << ";";
465    }
466    void writePCHReadDecls(raw_ostream &OS) const {
467      OS << "    " << getAttrName() << "Attr::" << type << " " << getLowerName()
468         << "(static_cast<" << getAttrName() << "Attr::" << type
469         << ">(Record[Idx++]));\n";
470    }
471    void writePCHReadArgs(raw_ostream &OS) const {
472      OS << getLowerName();
473    }
474    void writePCHWrite(raw_ostream &OS) const {
475      OS << "Record.push_back(SA->get" << getUpperName() << "());\n";
476    }
477    void writeValue(raw_ostream &OS) const {
478      OS << "\" << get" << getUpperName() << "() << \"";
479    }
480  };
481
482  class VersionArgument : public Argument {
483  public:
484    VersionArgument(Record &Arg, StringRef Attr)
485      : Argument(Arg, Attr)
486    {}
487
488    void writeAccessors(raw_ostream &OS) const {
489      OS << "  VersionTuple get" << getUpperName() << "() const {\n";
490      OS << "    return " << getLowerName() << ";\n";
491      OS << "  }\n";
492      OS << "  void set" << getUpperName()
493         << "(ASTContext &C, VersionTuple V) {\n";
494      OS << "    " << getLowerName() << " = V;\n";
495      OS << "  }";
496    }
497    void writeCloneArgs(raw_ostream &OS) const {
498      OS << "get" << getUpperName() << "()";
499    }
500    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
501      OS << "A->get" << getUpperName() << "()";
502    }
503    void writeCtorBody(raw_ostream &OS) const {
504    }
505    void writeCtorInitializers(raw_ostream &OS) const {
506      OS << getLowerName() << "(" << getUpperName() << ")";
507    }
508    void writeCtorParameters(raw_ostream &OS) const {
509      OS << "VersionTuple " << getUpperName();
510    }
511    void writeDeclarations(raw_ostream &OS) const {
512      OS << "VersionTuple " << getLowerName() << ";\n";
513    }
514    void writePCHReadDecls(raw_ostream &OS) const {
515      OS << "    VersionTuple " << getLowerName()
516         << "= ReadVersionTuple(Record, Idx);\n";
517    }
518    void writePCHReadArgs(raw_ostream &OS) const {
519      OS << getLowerName();
520    }
521    void writePCHWrite(raw_ostream &OS) const {
522      OS << "    AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n";
523    }
524    void writeValue(raw_ostream &OS) const {
525      OS << getLowerName() << "=\" << get" << getUpperName() << "() << \"";
526    }
527  };
528
529  class ExprArgument : public SimpleArgument {
530  public:
531    ExprArgument(Record &Arg, StringRef Attr)
532      : SimpleArgument(Arg, Attr, "Expr *")
533    {}
534
535    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
536      OS << "tempInst" << getUpperName();
537    }
538
539    void writeTemplateInstantiation(raw_ostream &OS) const {
540      OS << "      " << getType() << " tempInst" << getUpperName() << ";\n";
541      OS << "      {\n";
542      OS << "        EnterExpressionEvaluationContext "
543         << "Unevaluated(S, Sema::Unevaluated);\n";
544      OS << "        ExprResult " << "Result = S.SubstExpr("
545         << "A->get" << getUpperName() << "(), TemplateArgs);\n";
546      OS << "        tempInst" << getUpperName() << " = "
547         << "Result.takeAs<Expr>();\n";
548      OS << "      }\n";
549    }
550  };
551
552  class VariadicExprArgument : public VariadicArgument {
553  public:
554    VariadicExprArgument(Record &Arg, StringRef Attr)
555      : VariadicArgument(Arg, Attr, "Expr *")
556    {}
557
558    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
559      OS << "tempInst" << getUpperName() << ", "
560         << "A->" << getLowerName() << "_size()";
561    }
562
563    void writeTemplateInstantiation(raw_ostream &OS) const {
564      OS << "      " << getType() << " *tempInst" << getUpperName()
565         << " = new (C, 16) " << getType()
566         << "[A->" << getLowerName() << "_size()];\n";
567      OS << "      {\n";
568      OS << "        EnterExpressionEvaluationContext "
569         << "Unevaluated(S, Sema::Unevaluated);\n";
570      OS << "        " << getType() << " *TI = tempInst" << getUpperName()
571         << ";\n";
572      OS << "        " << getType() << " *I = A->" << getLowerName()
573         << "_begin();\n";
574      OS << "        " << getType() << " *E = A->" << getLowerName()
575         << "_end();\n";
576      OS << "        for (; I != E; ++I, ++TI) {\n";
577      OS << "          ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n";
578      OS << "          *TI = Result.takeAs<Expr>();\n";
579      OS << "        }\n";
580      OS << "      }\n";
581    }
582  };
583}
584
585static Argument *createArgument(Record &Arg, StringRef Attr,
586                                Record *Search = 0) {
587  if (!Search)
588    Search = &Arg;
589
590  Argument *Ptr = 0;
591  llvm::StringRef ArgName = Search->getName();
592
593  if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr);
594  else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr);
595  else if (ArgName == "ExprArgument") Ptr = new ExprArgument(Arg, Attr);
596  else if (ArgName == "FunctionArgument")
597    Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *");
598  else if (ArgName == "IdentifierArgument")
599    Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
600  else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr,
601                                                               "bool");
602  else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
603  else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
604  else if (ArgName == "TypeArgument")
605    Ptr = new SimpleArgument(Arg, Attr, "QualType");
606  else if (ArgName == "UnsignedArgument")
607    Ptr = new SimpleArgument(Arg, Attr, "unsigned");
608  else if (ArgName == "SourceLocArgument")
609    Ptr = new SimpleArgument(Arg, Attr, "SourceLocation");
610  else if (ArgName == "VariadicUnsignedArgument")
611    Ptr = new VariadicArgument(Arg, Attr, "unsigned");
612  else if (ArgName == "VariadicExprArgument")
613    Ptr = new VariadicExprArgument(Arg, Attr);
614  else if (ArgName == "VersionArgument")
615    Ptr = new VersionArgument(Arg, Attr);
616
617  if (!Ptr) {
618    std::vector<Record*> Bases = Search->getSuperClasses();
619    for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end();
620         i != e; ++i) {
621      Ptr = createArgument(Arg, Attr, *i);
622      if (Ptr)
623        break;
624    }
625  }
626  return Ptr;
627}
628
629static void writeAvailabilityValue(raw_ostream &OS) {
630  OS << "\" << getPlatform()->getName();\n"
631     << "  if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n"
632     << "  if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n"
633     << "  if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n"
634     << "  if (getUnavailable()) OS << \", unavailable\";\n"
635     << "  OS << \"";
636}
637
638void ClangAttrClassEmitter::run(raw_ostream &OS) {
639  OS << "// This file is generated by TableGen. Do not edit.\n\n";
640  OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
641  OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n";
642
643  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
644
645  for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
646       i != e; ++i) {
647    Record &R = **i;
648    const std::string &SuperName = R.getSuperClasses().back()->getName();
649
650    OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n";
651
652    std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
653    std::vector<Argument*> Args;
654    std::vector<Argument*>::iterator ai, ae;
655    Args.reserve(ArgRecords.size());
656
657    for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
658                                        re = ArgRecords.end();
659         ri != re; ++ri) {
660      Record &ArgRecord = **ri;
661      Argument *Arg = createArgument(ArgRecord, R.getName());
662      assert(Arg);
663      Args.push_back(Arg);
664
665      Arg->writeDeclarations(OS);
666      OS << "\n\n";
667    }
668
669    ae = Args.end();
670
671    OS << "\n public:\n";
672    OS << "  " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n";
673
674    for (ai = Args.begin(); ai != ae; ++ai) {
675      OS << "              , ";
676      (*ai)->writeCtorParameters(OS);
677      OS << "\n";
678    }
679
680    OS << "             )\n";
681    OS << "    : " << SuperName << "(attr::" << R.getName() << ", R)\n";
682
683    for (ai = Args.begin(); ai != ae; ++ai) {
684      OS << "              , ";
685      (*ai)->writeCtorInitializers(OS);
686      OS << "\n";
687    }
688
689    OS << "  {\n";
690
691    for (ai = Args.begin(); ai != ae; ++ai) {
692      (*ai)->writeCtorBody(OS);
693      OS << "\n";
694    }
695    OS << "  }\n\n";
696
697    OS << "  virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n";
698    OS << "  virtual void printPretty(llvm::raw_ostream &OS, ASTContext &Ctx) const;\n";
699
700    for (ai = Args.begin(); ai != ae; ++ai) {
701      (*ai)->writeAccessors(OS);
702      OS << "\n\n";
703    }
704
705    OS << R.getValueAsString("AdditionalMembers");
706    OS << "\n\n";
707
708    OS << "  static bool classof(const Attr *A) { return A->getKind() == "
709       << "attr::" << R.getName() << "; }\n";
710    OS << "  static bool classof(const " << R.getName()
711       << "Attr *) { return true; }\n";
712    OS << "};\n\n";
713  }
714
715  OS << "#endif\n";
716}
717
718void ClangAttrImplEmitter::run(raw_ostream &OS) {
719  OS << "// This file is generated by TableGen. Do not edit.\n\n";
720
721  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
722  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re;
723  std::vector<Argument*>::iterator ai, ae;
724
725  for (; i != e; ++i) {
726    Record &R = **i;
727    std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
728    std::vector<StringRef> Spellings = getValueAsListOfStrings(R, "Spellings");
729    std::vector<Argument*> Args;
730    for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri)
731      Args.push_back(createArgument(**ri, R.getName()));
732
733    for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
734      (*ai)->writeAccessorDefinitions(OS);
735
736    OS << R.getName() << "Attr *" << R.getName()
737       << "Attr::clone(ASTContext &C) const {\n";
738    OS << "  return new (C) " << R.getName() << "Attr(getLocation(), C";
739    for (ai = Args.begin(); ai != ae; ++ai) {
740      OS << ", ";
741      (*ai)->writeCloneArgs(OS);
742    }
743    OS << ");\n}\n\n";
744
745    OS << "void " << R.getName() << "Attr::printPretty("
746       << "llvm::raw_ostream &OS, ASTContext &Ctx) const {\n";
747    if (Spellings.begin() != Spellings.end()) {
748      OS << "  OS << \" __attribute__((" << *Spellings.begin();
749      if (Args.size()) OS << "(";
750      if (*Spellings.begin()=="availability") {
751        writeAvailabilityValue(OS);
752      } else {
753        for (ai = Args.begin(); ai != ae; ++ai) {
754          if (ai!=Args.begin()) OS <<", ";
755          (*ai)->writeValue(OS);
756        }
757      }
758      if (Args.size()) OS << ")";
759      OS << "))\";\n";
760    }
761    OS << "}\n\n";
762  }
763}
764
765static void EmitAttrList(raw_ostream &OS, StringRef Class,
766                         const std::vector<Record*> &AttrList) {
767  std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end();
768
769  if (i != e) {
770    // Move the end iterator back to emit the last attribute.
771    for(--e; i != e; ++i)
772      OS << Class << "(" << (*i)->getName() << ")\n";
773
774    OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n";
775  }
776}
777
778void ClangAttrListEmitter::run(raw_ostream &OS) {
779  OS << "// This file is generated by TableGen. Do not edit.\n\n";
780
781  OS << "#ifndef LAST_ATTR\n";
782  OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n";
783  OS << "#endif\n\n";
784
785  OS << "#ifndef INHERITABLE_ATTR\n";
786  OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n";
787  OS << "#endif\n\n";
788
789  OS << "#ifndef LAST_INHERITABLE_ATTR\n";
790  OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
791  OS << "#endif\n\n";
792
793  OS << "#ifndef INHERITABLE_PARAM_ATTR\n";
794  OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n";
795  OS << "#endif\n\n";
796
797  OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n";
798  OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)"
799        " INHERITABLE_PARAM_ATTR(NAME)\n";
800  OS << "#endif\n\n";
801
802  Record *InhClass = Records.getClass("InheritableAttr");
803  Record *InhParamClass = Records.getClass("InheritableParamAttr");
804  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
805                       NonInhAttrs, InhAttrs, InhParamAttrs;
806  for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
807       i != e; ++i) {
808    if ((*i)->isSubClassOf(InhParamClass))
809      InhParamAttrs.push_back(*i);
810    else if ((*i)->isSubClassOf(InhClass))
811      InhAttrs.push_back(*i);
812    else
813      NonInhAttrs.push_back(*i);
814  }
815
816  EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
817  EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
818  EmitAttrList(OS, "ATTR", NonInhAttrs);
819
820  OS << "#undef LAST_ATTR\n";
821  OS << "#undef INHERITABLE_ATTR\n";
822  OS << "#undef LAST_INHERITABLE_ATTR\n";
823  OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
824  OS << "#undef ATTR\n";
825}
826
827void ClangAttrPCHReadEmitter::run(raw_ostream &OS) {
828  OS << "// This file is generated by TableGen. Do not edit.\n\n";
829
830  Record *InhClass = Records.getClass("InheritableAttr");
831  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
832                       ArgRecords;
833  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
834  std::vector<Argument*> Args;
835  std::vector<Argument*>::iterator ri, re;
836
837  OS << "  switch (Kind) {\n";
838  OS << "  default:\n";
839  OS << "    assert(0 && \"Unknown attribute!\");\n";
840  OS << "    break;\n";
841  for (; i != e; ++i) {
842    Record &R = **i;
843    OS << "  case attr::" << R.getName() << ": {\n";
844    if (R.isSubClassOf(InhClass))
845      OS << "    bool isInherited = Record[Idx++];\n";
846    ArgRecords = R.getValueAsListOfDefs("Args");
847    Args.clear();
848    for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) {
849      Argument *A = createArgument(**ai, R.getName());
850      Args.push_back(A);
851      A->writePCHReadDecls(OS);
852    }
853    OS << "    New = new (Context) " << R.getName() << "Attr(Range, Context";
854    for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) {
855      OS << ", ";
856      (*ri)->writePCHReadArgs(OS);
857    }
858    OS << ");\n";
859    if (R.isSubClassOf(InhClass))
860      OS << "    cast<InheritableAttr>(New)->setInherited(isInherited);\n";
861    OS << "    break;\n";
862    OS << "  }\n";
863  }
864  OS << "  }\n";
865}
866
867void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) {
868  Record *InhClass = Records.getClass("InheritableAttr");
869  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
870  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
871
872  OS << "  switch (A->getKind()) {\n";
873  OS << "  default:\n";
874  OS << "    llvm_unreachable(\"Unknown attribute kind!\");\n";
875  OS << "    break;\n";
876  for (; i != e; ++i) {
877    Record &R = **i;
878    OS << "  case attr::" << R.getName() << ": {\n";
879    Args = R.getValueAsListOfDefs("Args");
880    if (R.isSubClassOf(InhClass) || !Args.empty())
881      OS << "    const " << R.getName() << "Attr *SA = cast<" << R.getName()
882         << "Attr>(A);\n";
883    if (R.isSubClassOf(InhClass))
884      OS << "    Record.push_back(SA->isInherited());\n";
885    for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
886      createArgument(**ai, R.getName())->writePCHWrite(OS);
887    OS << "    break;\n";
888    OS << "  }\n";
889  }
890  OS << "  }\n";
891}
892
893void ClangAttrSpellingListEmitter::run(raw_ostream &OS) {
894  OS << "// This file is generated by TableGen. Do not edit.\n\n";
895
896  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
897
898  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
899    Record &Attr = **I;
900
901    std::vector<StringRef> Spellings = getValueAsListOfStrings(Attr, "Spellings");
902
903    for (std::vector<StringRef>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) {
904      StringRef Spelling = *I;
905      OS << ".Case(\"" << Spelling << "\", true)\n";
906    }
907  }
908
909}
910
911void ClangAttrLateParsedListEmitter::run(raw_ostream &OS) {
912  OS << "// This file is generated by TableGen. Do not edit.\n\n";
913
914  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
915
916  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
917       I != E; ++I) {
918    Record &Attr = **I;
919
920    bool LateParsed = Attr.getValueAsBit("LateParsed");
921
922    if (LateParsed) {
923      std::vector<StringRef> Spellings =
924        getValueAsListOfStrings(Attr, "Spellings");
925
926      for (std::vector<StringRef>::const_iterator I = Spellings.begin(),
927           E = Spellings.end(); I != E; ++I) {
928        OS << ".Case(\"" << (*I) << "\", " << LateParsed << ")\n";
929      }
930    }
931  }
932}
933
934
935void ClangAttrTemplateInstantiateEmitter::run(raw_ostream &OS) {
936  OS << "// This file is generated by TableGen. Do not edit.\n\n";
937
938  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
939
940  OS << "Attr* instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
941     << "Sema &S,\n"
942     << "        const MultiLevelTemplateArgumentList &TemplateArgs) {\n"
943     << "  switch (At->getKind()) {\n"
944     << "    default:\n"
945     << "      break;\n";
946
947  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
948       I != E; ++I) {
949    Record &R = **I;
950
951    OS << "    case attr::" << R.getName() << ": {\n";
952    OS << "      const " << R.getName() << "Attr *A = cast<"
953       << R.getName() << "Attr>(At);\n";
954    bool TDependent = R.getValueAsBit("TemplateDependent");
955
956    if (!TDependent) {
957      OS << "      return A->clone(C);\n";
958      OS << "    }\n";
959      continue;
960    }
961
962    std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
963    std::vector<Argument*> Args;
964    std::vector<Argument*>::iterator ai, ae;
965    Args.reserve(ArgRecords.size());
966
967    for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
968                                        re = ArgRecords.end();
969         ri != re; ++ri) {
970      Record &ArgRecord = **ri;
971      Argument *Arg = createArgument(ArgRecord, R.getName());
972      assert(Arg);
973      Args.push_back(Arg);
974    }
975    ae = Args.end();
976
977    for (ai = Args.begin(); ai != ae; ++ai) {
978      (*ai)->writeTemplateInstantiation(OS);
979    }
980    OS << "      return new (C) " << R.getName() << "Attr(A->getLocation(), C";
981    for (ai = Args.begin(); ai != ae; ++ai) {
982      OS << ", ";
983      (*ai)->writeTemplateInstantiationArgs(OS);
984    }
985    OS << ");\n    }\n";
986  }
987  OS << "  } // end switch\n"
988     << "  llvm_unreachable(\"Unknown attribute!\");\n"
989     << "  return 0;\n"
990     << "}\n\n";
991}
992
993