• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
getValueAsListOfStrings(Record & R,StringRef FieldName)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 
ReadPCHRecord(StringRef type)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 *", "ReadExpr(F)")
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()
WritePCHRecord(StringRef type,StringRef name)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.
NormalizeAttrName(StringRef AttrName)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.
NormalizeAttrSpelling(StringRef AttrSpelling)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:
Argument(Record & Arg,StringRef Attr)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     }
~Argument()108     virtual ~Argument() {}
109 
getLowerName() const110     StringRef getLowerName() const { return lowerName; }
getUpperName() const111     StringRef getUpperName() const { return upperName; }
getAttrName() const112     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;
writeAccessorDefinitions(raw_ostream & OS) const116     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;
writeTemplateInstantiation(raw_ostream & OS) const119     virtual void writeTemplateInstantiation(raw_ostream &OS) const {}
writeCtorBody(raw_ostream & OS) const120     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     virtual void writeDump(raw_ostream &OS) const = 0;
writeDumpChildren(raw_ostream & OS) const129     virtual void writeDumpChildren(raw_ostream &OS) const {}
writeHasChildren(raw_ostream & OS) const130     virtual void writeHasChildren(raw_ostream &OS) const { OS << "false"; }
131   };
132 
133   class SimpleArgument : public Argument {
134     std::string type;
135 
136   public:
SimpleArgument(Record & Arg,StringRef Attr,std::string T)137     SimpleArgument(Record &Arg, StringRef Attr, std::string T)
138       : Argument(Arg, Attr), type(T)
139     {}
140 
getType() const141     std::string getType() const { return type; }
142 
writeAccessors(raw_ostream & OS) const143     void writeAccessors(raw_ostream &OS) const {
144       OS << "  " << type << " get" << getUpperName() << "() const {\n";
145       OS << "    return " << getLowerName() << ";\n";
146       OS << "  }";
147     }
writeCloneArgs(raw_ostream & OS) const148     void writeCloneArgs(raw_ostream &OS) const {
149       OS << getLowerName();
150     }
writeTemplateInstantiationArgs(raw_ostream & OS) const151     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
152       OS << "A->get" << getUpperName() << "()";
153     }
writeCtorInitializers(raw_ostream & OS) const154     void writeCtorInitializers(raw_ostream &OS) const {
155       OS << getLowerName() << "(" << getUpperName() << ")";
156     }
writeCtorParameters(raw_ostream & OS) const157     void writeCtorParameters(raw_ostream &OS) const {
158       OS << type << " " << getUpperName();
159     }
writeDeclarations(raw_ostream & OS) const160     void writeDeclarations(raw_ostream &OS) const {
161       OS << type << " " << getLowerName() << ";";
162     }
writePCHReadDecls(raw_ostream & OS) const163     void writePCHReadDecls(raw_ostream &OS) const {
164       std::string read = ReadPCHRecord(type);
165       OS << "    " << type << " " << getLowerName() << " = " << read << ";\n";
166     }
writePCHReadArgs(raw_ostream & OS) const167     void writePCHReadArgs(raw_ostream &OS) const {
168       OS << getLowerName();
169     }
writePCHWrite(raw_ostream & OS) const170     void writePCHWrite(raw_ostream &OS) const {
171       OS << "    " << WritePCHRecord(type, "SA->get" +
172                                            std::string(getUpperName()) + "()");
173     }
writeValue(raw_ostream & OS) const174     void writeValue(raw_ostream &OS) const {
175       if (type == "FunctionDecl *") {
176         OS << "\" << get" << getUpperName() << "()->getNameInfo().getAsString() << \"";
177       } else if (type == "IdentifierInfo *") {
178         OS << "\" << get" << getUpperName() << "()->getName() << \"";
179       } else if (type == "QualType") {
180         OS << "\" << get" << getUpperName() << "().getAsString() << \"";
181       } else if (type == "SourceLocation") {
182         OS << "\" << get" << getUpperName() << "().getRawEncoding() << \"";
183       } else {
184         OS << "\" << get" << getUpperName() << "() << \"";
185       }
186     }
writeDump(raw_ostream & OS) const187     void writeDump(raw_ostream &OS) const {
188       if (type == "FunctionDecl *") {
189         OS << "    OS << \" \";\n";
190         OS << "    dumpBareDeclRef(SA->get" << getUpperName() << "());\n";
191       } else if (type == "IdentifierInfo *") {
192         OS << "    OS << \" \" << SA->get" << getUpperName()
193            << "()->getName();\n";
194       } else if (type == "QualType") {
195         OS << "    OS << \" \" << SA->get" << getUpperName()
196            << "().getAsString();\n";
197       } else if (type == "SourceLocation") {
198         OS << "    OS << \" \";\n";
199         OS << "    SA->get" << getUpperName() << "().print(OS, *SM);\n";
200       } else if (type == "bool") {
201         OS << "    if (SA->get" << getUpperName() << "()) OS << \" "
202            << getUpperName() << "\";\n";
203       } else if (type == "int" || type == "unsigned") {
204         OS << "    OS << \" \" << SA->get" << getUpperName() << "();\n";
205       } else {
206         llvm_unreachable("Unknown SimpleArgument type!");
207       }
208     }
209   };
210 
211   class StringArgument : public Argument {
212   public:
StringArgument(Record & Arg,StringRef Attr)213     StringArgument(Record &Arg, StringRef Attr)
214       : Argument(Arg, Attr)
215     {}
216 
writeAccessors(raw_ostream & OS) const217     void writeAccessors(raw_ostream &OS) const {
218       OS << "  llvm::StringRef get" << getUpperName() << "() const {\n";
219       OS << "    return llvm::StringRef(" << getLowerName() << ", "
220          << getLowerName() << "Length);\n";
221       OS << "  }\n";
222       OS << "  unsigned get" << getUpperName() << "Length() const {\n";
223       OS << "    return " << getLowerName() << "Length;\n";
224       OS << "  }\n";
225       OS << "  void set" << getUpperName()
226          << "(ASTContext &C, llvm::StringRef S) {\n";
227       OS << "    " << getLowerName() << "Length = S.size();\n";
228       OS << "    this->" << getLowerName() << " = new (C, 1) char ["
229          << getLowerName() << "Length];\n";
230       OS << "    std::memcpy(this->" << getLowerName() << ", S.data(), "
231          << getLowerName() << "Length);\n";
232       OS << "  }";
233     }
writeCloneArgs(raw_ostream & OS) const234     void writeCloneArgs(raw_ostream &OS) const {
235       OS << "get" << getUpperName() << "()";
236     }
writeTemplateInstantiationArgs(raw_ostream & OS) const237     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
238       OS << "A->get" << getUpperName() << "()";
239     }
writeCtorBody(raw_ostream & OS) const240     void writeCtorBody(raw_ostream &OS) const {
241       OS << "      std::memcpy(" << getLowerName() << ", " << getUpperName()
242          << ".data(), " << getLowerName() << "Length);";
243     }
writeCtorInitializers(raw_ostream & OS) const244     void writeCtorInitializers(raw_ostream &OS) const {
245       OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
246          << getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
247          << "Length])";
248     }
writeCtorParameters(raw_ostream & OS) const249     void writeCtorParameters(raw_ostream &OS) const {
250       OS << "llvm::StringRef " << getUpperName();
251     }
writeDeclarations(raw_ostream & OS) const252     void writeDeclarations(raw_ostream &OS) const {
253       OS << "unsigned " << getLowerName() << "Length;\n";
254       OS << "char *" << getLowerName() << ";";
255     }
writePCHReadDecls(raw_ostream & OS) const256     void writePCHReadDecls(raw_ostream &OS) const {
257       OS << "    std::string " << getLowerName()
258          << "= ReadString(Record, Idx);\n";
259     }
writePCHReadArgs(raw_ostream & OS) const260     void writePCHReadArgs(raw_ostream &OS) const {
261       OS << getLowerName();
262     }
writePCHWrite(raw_ostream & OS) const263     void writePCHWrite(raw_ostream &OS) const {
264       OS << "    AddString(SA->get" << getUpperName() << "(), Record);\n";
265     }
writeValue(raw_ostream & OS) const266     void writeValue(raw_ostream &OS) const {
267       OS << "\\\"\" << get" << getUpperName() << "() << \"\\\"";
268     }
writeDump(raw_ostream & OS) const269     void writeDump(raw_ostream &OS) const {
270       OS << "    OS << \" \\\"\" << SA->get" << getUpperName()
271          << "() << \"\\\"\";\n";
272     }
273   };
274 
275   class AlignedArgument : public Argument {
276   public:
AlignedArgument(Record & Arg,StringRef Attr)277     AlignedArgument(Record &Arg, StringRef Attr)
278       : Argument(Arg, Attr)
279     {}
280 
writeAccessors(raw_ostream & OS) const281     void writeAccessors(raw_ostream &OS) const {
282       OS << "  bool is" << getUpperName() << "Dependent() const;\n";
283 
284       OS << "  unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";
285 
286       OS << "  bool is" << getUpperName() << "Expr() const {\n";
287       OS << "    return is" << getLowerName() << "Expr;\n";
288       OS << "  }\n";
289 
290       OS << "  Expr *get" << getUpperName() << "Expr() const {\n";
291       OS << "    assert(is" << getLowerName() << "Expr);\n";
292       OS << "    return " << getLowerName() << "Expr;\n";
293       OS << "  }\n";
294 
295       OS << "  TypeSourceInfo *get" << getUpperName() << "Type() const {\n";
296       OS << "    assert(!is" << getLowerName() << "Expr);\n";
297       OS << "    return " << getLowerName() << "Type;\n";
298       OS << "  }";
299     }
writeAccessorDefinitions(raw_ostream & OS) const300     void writeAccessorDefinitions(raw_ostream &OS) const {
301       OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
302          << "Dependent() const {\n";
303       OS << "  if (is" << getLowerName() << "Expr)\n";
304       OS << "    return " << getLowerName() << "Expr && (" << getLowerName()
305          << "Expr->isValueDependent() || " << getLowerName()
306          << "Expr->isTypeDependent());\n";
307       OS << "  else\n";
308       OS << "    return " << getLowerName()
309          << "Type->getType()->isDependentType();\n";
310       OS << "}\n";
311 
312       // FIXME: Do not do the calculation here
313       // FIXME: Handle types correctly
314       // A null pointer means maximum alignment
315       // FIXME: Load the platform-specific maximum alignment, rather than
316       //        16, the x86 max.
317       OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName()
318          << "(ASTContext &Ctx) const {\n";
319       OS << "  assert(!is" << getUpperName() << "Dependent());\n";
320       OS << "  if (is" << getLowerName() << "Expr)\n";
321       OS << "    return (" << getLowerName() << "Expr ? " << getLowerName()
322          << "Expr->EvaluateKnownConstInt(Ctx).getZExtValue() : 16)"
323          << "* Ctx.getCharWidth();\n";
324       OS << "  else\n";
325       OS << "    return 0; // FIXME\n";
326       OS << "}\n";
327     }
writeCloneArgs(raw_ostream & OS) const328     void writeCloneArgs(raw_ostream &OS) const {
329       OS << "is" << getLowerName() << "Expr, is" << getLowerName()
330          << "Expr ? static_cast<void*>(" << getLowerName()
331          << "Expr) : " << getLowerName()
332          << "Type";
333     }
writeTemplateInstantiationArgs(raw_ostream & OS) const334     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
335       // FIXME: move the definition in Sema::InstantiateAttrs to here.
336       // In the meantime, aligned attributes are cloned.
337     }
writeCtorBody(raw_ostream & OS) const338     void writeCtorBody(raw_ostream &OS) const {
339       OS << "    if (is" << getLowerName() << "Expr)\n";
340       OS << "       " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
341          << getUpperName() << ");\n";
342       OS << "    else\n";
343       OS << "       " << getLowerName()
344          << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
345          << ");";
346     }
writeCtorInitializers(raw_ostream & OS) const347     void writeCtorInitializers(raw_ostream &OS) const {
348       OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
349     }
writeCtorParameters(raw_ostream & OS) const350     void writeCtorParameters(raw_ostream &OS) const {
351       OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
352     }
writeDeclarations(raw_ostream & OS) const353     void writeDeclarations(raw_ostream &OS) const {
354       OS << "bool is" << getLowerName() << "Expr;\n";
355       OS << "union {\n";
356       OS << "Expr *" << getLowerName() << "Expr;\n";
357       OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
358       OS << "};";
359     }
writePCHReadArgs(raw_ostream & OS) const360     void writePCHReadArgs(raw_ostream &OS) const {
361       OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
362     }
writePCHReadDecls(raw_ostream & OS) const363     void writePCHReadDecls(raw_ostream &OS) const {
364       OS << "    bool is" << getLowerName() << "Expr = Record[Idx++];\n";
365       OS << "    void *" << getLowerName() << "Ptr;\n";
366       OS << "    if (is" << getLowerName() << "Expr)\n";
367       OS << "      " << getLowerName() << "Ptr = ReadExpr(F);\n";
368       OS << "    else\n";
369       OS << "      " << getLowerName()
370          << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n";
371     }
writePCHWrite(raw_ostream & OS) const372     void writePCHWrite(raw_ostream &OS) const {
373       OS << "    Record.push_back(SA->is" << getUpperName() << "Expr());\n";
374       OS << "    if (SA->is" << getUpperName() << "Expr())\n";
375       OS << "      AddStmt(SA->get" << getUpperName() << "Expr());\n";
376       OS << "    else\n";
377       OS << "      AddTypeSourceInfo(SA->get" << getUpperName()
378          << "Type(), Record);\n";
379     }
writeValue(raw_ostream & OS) const380     void writeValue(raw_ostream &OS) const {
381       OS << "\";\n"
382          << "  " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n"
383          << "  OS << \"";
384     }
writeDump(raw_ostream & OS) const385     void writeDump(raw_ostream &OS) const {
386     }
writeDumpChildren(raw_ostream & OS) const387     void writeDumpChildren(raw_ostream &OS) const {
388       OS << "    if (SA->is" << getUpperName() << "Expr()) {\n";
389       OS << "      lastChild();\n";
390       OS << "      dumpStmt(SA->get" << getUpperName() << "Expr());\n";
391       OS << "    } else\n";
392       OS << "      dumpType(SA->get" << getUpperName()
393          << "Type()->getType());\n";
394     }
writeHasChildren(raw_ostream & OS) const395     void writeHasChildren(raw_ostream &OS) const {
396       OS << "SA->is" << getUpperName() << "Expr()";
397     }
398   };
399 
400   class VariadicArgument : public Argument {
401     std::string type;
402 
403   public:
VariadicArgument(Record & Arg,StringRef Attr,std::string T)404     VariadicArgument(Record &Arg, StringRef Attr, std::string T)
405       : Argument(Arg, Attr), type(T)
406     {}
407 
getType() const408     std::string getType() const { return type; }
409 
writeAccessors(raw_ostream & OS) const410     void writeAccessors(raw_ostream &OS) const {
411       OS << "  typedef " << type << "* " << getLowerName() << "_iterator;\n";
412       OS << "  " << getLowerName() << "_iterator " << getLowerName()
413          << "_begin() const {\n";
414       OS << "    return " << getLowerName() << ";\n";
415       OS << "  }\n";
416       OS << "  " << getLowerName() << "_iterator " << getLowerName()
417          << "_end() const {\n";
418       OS << "    return " << getLowerName() << " + " << getLowerName()
419          << "Size;\n";
420       OS << "  }\n";
421       OS << "  unsigned " << getLowerName() << "_size() const {\n"
422          << "    return " << getLowerName() << "Size;\n";
423       OS << "  }";
424     }
writeCloneArgs(raw_ostream & OS) const425     void writeCloneArgs(raw_ostream &OS) const {
426       OS << getLowerName() << ", " << getLowerName() << "Size";
427     }
writeTemplateInstantiationArgs(raw_ostream & OS) const428     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
429       // This isn't elegant, but we have to go through public methods...
430       OS << "A->" << getLowerName() << "_begin(), "
431          << "A->" << getLowerName() << "_size()";
432     }
writeCtorBody(raw_ostream & OS) const433     void writeCtorBody(raw_ostream &OS) const {
434       // FIXME: memcpy is not safe on non-trivial types.
435       OS << "    std::memcpy(" << getLowerName() << ", " << getUpperName()
436          << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n";
437     }
writeCtorInitializers(raw_ostream & OS) const438     void writeCtorInitializers(raw_ostream &OS) const {
439       OS << getLowerName() << "Size(" << getUpperName() << "Size), "
440          << getLowerName() << "(new (Ctx, 16) " << getType() << "["
441          << getLowerName() << "Size])";
442     }
writeCtorParameters(raw_ostream & OS) const443     void writeCtorParameters(raw_ostream &OS) const {
444       OS << getType() << " *" << getUpperName() << ", unsigned "
445          << getUpperName() << "Size";
446     }
writeDeclarations(raw_ostream & OS) const447     void writeDeclarations(raw_ostream &OS) const {
448       OS << "  unsigned " << getLowerName() << "Size;\n";
449       OS << "  " << getType() << " *" << getLowerName() << ";";
450     }
writePCHReadDecls(raw_ostream & OS) const451     void writePCHReadDecls(raw_ostream &OS) const {
452       OS << "  unsigned " << getLowerName() << "Size = Record[Idx++];\n";
453       OS << "  SmallVector<" << type << ", 4> " << getLowerName()
454          << ";\n";
455       OS << "  " << getLowerName() << ".reserve(" << getLowerName()
456          << "Size);\n";
457       OS << "  for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
458 
459       std::string read = ReadPCHRecord(type);
460       OS << "    " << getLowerName() << ".push_back(" << read << ");\n";
461     }
writePCHReadArgs(raw_ostream & OS) const462     void writePCHReadArgs(raw_ostream &OS) const {
463       OS << getLowerName() << ".data(), " << getLowerName() << "Size";
464     }
writePCHWrite(raw_ostream & OS) const465     void writePCHWrite(raw_ostream &OS) const{
466       OS << "    Record.push_back(SA->" << getLowerName() << "_size());\n";
467       OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
468          << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
469          << getLowerName() << "_end(); i != e; ++i)\n";
470       OS << "      " << WritePCHRecord(type, "(*i)");
471     }
writeValue(raw_ostream & OS) const472     void writeValue(raw_ostream &OS) const {
473       OS << "\";\n";
474       OS << "  bool isFirst = true;\n"
475          << "  for (" << getAttrName() << "Attr::" << getLowerName()
476          << "_iterator i = " << getLowerName() << "_begin(), e = "
477          << getLowerName() << "_end(); i != e; ++i) {\n"
478          << "    if (isFirst) isFirst = false;\n"
479          << "    else OS << \", \";\n"
480          << "    OS << *i;\n"
481          << "  }\n";
482       OS << "  OS << \"";
483     }
writeDump(raw_ostream & OS) const484     void writeDump(raw_ostream &OS) const {
485       OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
486          << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
487          << getLowerName() << "_end(); I != E; ++I)\n";
488       OS << "      OS << \" \" << *I;\n";
489     }
490   };
491 
492   class EnumArgument : public Argument {
493     std::string type;
494     std::vector<StringRef> values, enums, uniques;
495   public:
EnumArgument(Record & Arg,StringRef Attr)496     EnumArgument(Record &Arg, StringRef Attr)
497       : Argument(Arg, Attr), type(Arg.getValueAsString("Type")),
498         values(getValueAsListOfStrings(Arg, "Values")),
499         enums(getValueAsListOfStrings(Arg, "Enums")),
500         uniques(enums)
501     {
502       // Calculate the various enum values
503       std::sort(uniques.begin(), uniques.end());
504       uniques.erase(std::unique(uniques.begin(), uniques.end()), uniques.end());
505       // FIXME: Emit a proper error
506       assert(!uniques.empty());
507     }
508 
writeAccessors(raw_ostream & OS) const509     void writeAccessors(raw_ostream &OS) const {
510       OS << "  " << type << " get" << getUpperName() << "() const {\n";
511       OS << "    return " << getLowerName() << ";\n";
512       OS << "  }";
513     }
writeCloneArgs(raw_ostream & OS) const514     void writeCloneArgs(raw_ostream &OS) const {
515       OS << getLowerName();
516     }
writeTemplateInstantiationArgs(raw_ostream & OS) const517     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
518       OS << "A->get" << getUpperName() << "()";
519     }
writeCtorInitializers(raw_ostream & OS) const520     void writeCtorInitializers(raw_ostream &OS) const {
521       OS << getLowerName() << "(" << getUpperName() << ")";
522     }
writeCtorParameters(raw_ostream & OS) const523     void writeCtorParameters(raw_ostream &OS) const {
524       OS << type << " " << getUpperName();
525     }
writeDeclarations(raw_ostream & OS) const526     void writeDeclarations(raw_ostream &OS) const {
527       std::vector<StringRef>::const_iterator i = uniques.begin(),
528                                              e = uniques.end();
529       // The last one needs to not have a comma.
530       --e;
531 
532       OS << "public:\n";
533       OS << "  enum " << type << " {\n";
534       for (; i != e; ++i)
535         OS << "    " << *i << ",\n";
536       OS << "    " << *e << "\n";
537       OS << "  };\n";
538       OS << "private:\n";
539       OS << "  " << type << " " << getLowerName() << ";";
540     }
writePCHReadDecls(raw_ostream & OS) const541     void writePCHReadDecls(raw_ostream &OS) const {
542       OS << "    " << getAttrName() << "Attr::" << type << " " << getLowerName()
543          << "(static_cast<" << getAttrName() << "Attr::" << type
544          << ">(Record[Idx++]));\n";
545     }
writePCHReadArgs(raw_ostream & OS) const546     void writePCHReadArgs(raw_ostream &OS) const {
547       OS << getLowerName();
548     }
writePCHWrite(raw_ostream & OS) const549     void writePCHWrite(raw_ostream &OS) const {
550       OS << "Record.push_back(SA->get" << getUpperName() << "());\n";
551     }
writeValue(raw_ostream & OS) const552     void writeValue(raw_ostream &OS) const {
553       OS << "\" << get" << getUpperName() << "() << \"";
554     }
writeDump(raw_ostream & OS) const555     void writeDump(raw_ostream &OS) const {
556       OS << "    switch(SA->get" << getUpperName() << "()) {\n";
557       for (std::vector<StringRef>::const_iterator I = uniques.begin(),
558            E = uniques.end(); I != E; ++I) {
559         OS << "    case " << getAttrName() << "Attr::" << *I << ":\n";
560         OS << "      OS << \" " << *I << "\";\n";
561         OS << "      break;\n";
562       }
563       OS << "    }\n";
564     }
565   };
566 
567   class VersionArgument : public Argument {
568   public:
VersionArgument(Record & Arg,StringRef Attr)569     VersionArgument(Record &Arg, StringRef Attr)
570       : Argument(Arg, Attr)
571     {}
572 
writeAccessors(raw_ostream & OS) const573     void writeAccessors(raw_ostream &OS) const {
574       OS << "  VersionTuple get" << getUpperName() << "() const {\n";
575       OS << "    return " << getLowerName() << ";\n";
576       OS << "  }\n";
577       OS << "  void set" << getUpperName()
578          << "(ASTContext &C, VersionTuple V) {\n";
579       OS << "    " << getLowerName() << " = V;\n";
580       OS << "  }";
581     }
writeCloneArgs(raw_ostream & OS) const582     void writeCloneArgs(raw_ostream &OS) const {
583       OS << "get" << getUpperName() << "()";
584     }
writeTemplateInstantiationArgs(raw_ostream & OS) const585     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
586       OS << "A->get" << getUpperName() << "()";
587     }
writeCtorBody(raw_ostream & OS) const588     void writeCtorBody(raw_ostream &OS) const {
589     }
writeCtorInitializers(raw_ostream & OS) const590     void writeCtorInitializers(raw_ostream &OS) const {
591       OS << getLowerName() << "(" << getUpperName() << ")";
592     }
writeCtorParameters(raw_ostream & OS) const593     void writeCtorParameters(raw_ostream &OS) const {
594       OS << "VersionTuple " << getUpperName();
595     }
writeDeclarations(raw_ostream & OS) const596     void writeDeclarations(raw_ostream &OS) const {
597       OS << "VersionTuple " << getLowerName() << ";\n";
598     }
writePCHReadDecls(raw_ostream & OS) const599     void writePCHReadDecls(raw_ostream &OS) const {
600       OS << "    VersionTuple " << getLowerName()
601          << "= ReadVersionTuple(Record, Idx);\n";
602     }
writePCHReadArgs(raw_ostream & OS) const603     void writePCHReadArgs(raw_ostream &OS) const {
604       OS << getLowerName();
605     }
writePCHWrite(raw_ostream & OS) const606     void writePCHWrite(raw_ostream &OS) const {
607       OS << "    AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n";
608     }
writeValue(raw_ostream & OS) const609     void writeValue(raw_ostream &OS) const {
610       OS << getLowerName() << "=\" << get" << getUpperName() << "() << \"";
611     }
writeDump(raw_ostream & OS) const612     void writeDump(raw_ostream &OS) const {
613       OS << "    OS << \" \" << SA->get" << getUpperName() << "();\n";
614     }
615   };
616 
617   class ExprArgument : public SimpleArgument {
618   public:
ExprArgument(Record & Arg,StringRef Attr)619     ExprArgument(Record &Arg, StringRef Attr)
620       : SimpleArgument(Arg, Attr, "Expr *")
621     {}
622 
writeTemplateInstantiationArgs(raw_ostream & OS) const623     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
624       OS << "tempInst" << getUpperName();
625     }
626 
writeTemplateInstantiation(raw_ostream & OS) const627     void writeTemplateInstantiation(raw_ostream &OS) const {
628       OS << "      " << getType() << " tempInst" << getUpperName() << ";\n";
629       OS << "      {\n";
630       OS << "        EnterExpressionEvaluationContext "
631          << "Unevaluated(S, Sema::Unevaluated);\n";
632       OS << "        ExprResult " << "Result = S.SubstExpr("
633          << "A->get" << getUpperName() << "(), TemplateArgs);\n";
634       OS << "        tempInst" << getUpperName() << " = "
635          << "Result.takeAs<Expr>();\n";
636       OS << "      }\n";
637     }
638 
writeDump(raw_ostream & OS) const639     void writeDump(raw_ostream &OS) const {
640     }
641 
writeDumpChildren(raw_ostream & OS) const642     void writeDumpChildren(raw_ostream &OS) const {
643       OS << "    lastChild();\n";
644       OS << "    dumpStmt(SA->get" << getUpperName() << "());\n";
645     }
writeHasChildren(raw_ostream & OS) const646     void writeHasChildren(raw_ostream &OS) const { OS << "true"; }
647   };
648 
649   class VariadicExprArgument : public VariadicArgument {
650   public:
VariadicExprArgument(Record & Arg,StringRef Attr)651     VariadicExprArgument(Record &Arg, StringRef Attr)
652       : VariadicArgument(Arg, Attr, "Expr *")
653     {}
654 
writeTemplateInstantiationArgs(raw_ostream & OS) const655     void writeTemplateInstantiationArgs(raw_ostream &OS) const {
656       OS << "tempInst" << getUpperName() << ", "
657          << "A->" << getLowerName() << "_size()";
658     }
659 
writeTemplateInstantiation(raw_ostream & OS) const660     void writeTemplateInstantiation(raw_ostream &OS) const {
661       OS << "      " << getType() << " *tempInst" << getUpperName()
662          << " = new (C, 16) " << getType()
663          << "[A->" << getLowerName() << "_size()];\n";
664       OS << "      {\n";
665       OS << "        EnterExpressionEvaluationContext "
666          << "Unevaluated(S, Sema::Unevaluated);\n";
667       OS << "        " << getType() << " *TI = tempInst" << getUpperName()
668          << ";\n";
669       OS << "        " << getType() << " *I = A->" << getLowerName()
670          << "_begin();\n";
671       OS << "        " << getType() << " *E = A->" << getLowerName()
672          << "_end();\n";
673       OS << "        for (; I != E; ++I, ++TI) {\n";
674       OS << "          ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n";
675       OS << "          *TI = Result.takeAs<Expr>();\n";
676       OS << "        }\n";
677       OS << "      }\n";
678     }
679 
writeDump(raw_ostream & OS) const680     void writeDump(raw_ostream &OS) const {
681     }
682 
writeDumpChildren(raw_ostream & OS) const683     void writeDumpChildren(raw_ostream &OS) const {
684       OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
685          << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
686          << getLowerName() << "_end(); I != E; ++I) {\n";
687       OS << "      if (I + 1 == E)\n";
688       OS << "        lastChild();\n";
689       OS << "      dumpStmt(*I);\n";
690       OS << "    }\n";
691     }
692 
writeHasChildren(raw_ostream & OS) const693     void writeHasChildren(raw_ostream &OS) const {
694       OS << "SA->" << getLowerName() << "_begin() != "
695          << "SA->" << getLowerName() << "_end()";
696     }
697   };
698 }
699 
createArgument(Record & Arg,StringRef Attr,Record * Search=0)700 static Argument *createArgument(Record &Arg, StringRef Attr,
701                                 Record *Search = 0) {
702   if (!Search)
703     Search = &Arg;
704 
705   Argument *Ptr = 0;
706   llvm::StringRef ArgName = Search->getName();
707 
708   if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr);
709   else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr);
710   else if (ArgName == "ExprArgument") Ptr = new ExprArgument(Arg, Attr);
711   else if (ArgName == "FunctionArgument")
712     Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *");
713   else if (ArgName == "IdentifierArgument")
714     Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
715   else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr,
716                                                                "bool");
717   else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
718   else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
719   else if (ArgName == "TypeArgument")
720     Ptr = new SimpleArgument(Arg, Attr, "QualType");
721   else if (ArgName == "UnsignedArgument")
722     Ptr = new SimpleArgument(Arg, Attr, "unsigned");
723   else if (ArgName == "SourceLocArgument")
724     Ptr = new SimpleArgument(Arg, Attr, "SourceLocation");
725   else if (ArgName == "VariadicUnsignedArgument")
726     Ptr = new VariadicArgument(Arg, Attr, "unsigned");
727   else if (ArgName == "VariadicExprArgument")
728     Ptr = new VariadicExprArgument(Arg, Attr);
729   else if (ArgName == "VersionArgument")
730     Ptr = new VersionArgument(Arg, Attr);
731 
732   if (!Ptr) {
733     std::vector<Record*> Bases = Search->getSuperClasses();
734     for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end();
735          i != e; ++i) {
736       Ptr = createArgument(Arg, Attr, *i);
737       if (Ptr)
738         break;
739     }
740   }
741   return Ptr;
742 }
743 
writeAvailabilityValue(raw_ostream & OS)744 static void writeAvailabilityValue(raw_ostream &OS) {
745   OS << "\" << getPlatform()->getName();\n"
746      << "  if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n"
747      << "  if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n"
748      << "  if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n"
749      << "  if (getUnavailable()) OS << \", unavailable\";\n"
750      << "  OS << \"";
751 }
752 
writePrettyPrintFunction(Record & R,std::vector<Argument * > & Args,raw_ostream & OS)753 static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args,
754                                      raw_ostream &OS) {
755   std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
756 
757   OS << "void " << R.getName() << "Attr::printPretty("
758     << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n";
759 
760   if (Spellings.size() == 0) {
761     OS << "}\n\n";
762     return;
763   }
764 
765   OS <<
766     "  switch (SpellingListIndex) {\n"
767     "  default:\n"
768     "    llvm_unreachable(\"Unknown attribute spelling!\");\n"
769     "    break;\n";
770 
771   for (unsigned I = 0; I < Spellings.size(); ++ I) {
772     llvm::SmallString<16> Prefix;
773     llvm::SmallString<8> Suffix;
774     // The actual spelling of the name and namespace (if applicable)
775     // of an attribute without considering prefix and suffix.
776     llvm::SmallString<64> Spelling;
777     std::string Name = Spellings[I]->getValueAsString("Name");
778     std::string Variety = Spellings[I]->getValueAsString("Variety");
779 
780     if (Variety == "GNU") {
781       Prefix = " __attribute__((";
782       Suffix = "))";
783     } else if (Variety == "CXX11") {
784       Prefix = " [[";
785       Suffix = "]]";
786       std::string Namespace = Spellings[I]->getValueAsString("Namespace");
787       if (Namespace != "") {
788         Spelling += Namespace;
789         Spelling += "::";
790       }
791     } else if (Variety == "Declspec") {
792       Prefix = " __declspec(";
793       Suffix = ")";
794     } else if (Variety == "Keyword") {
795       Prefix = " ";
796       Suffix = "";
797     } else {
798       llvm_unreachable("Unknown attribute syntax variety!");
799     }
800 
801     Spelling += Name;
802 
803     OS <<
804       "  case " << I << " : {\n"
805       "    OS << \"" + Prefix.str() + Spelling.str();
806 
807     if (Args.size()) OS << "(";
808     if (Spelling == "availability") {
809       writeAvailabilityValue(OS);
810     } else {
811       for (std::vector<Argument*>::const_iterator I = Args.begin(),
812            E = Args.end(); I != E; ++ I) {
813         if (I != Args.begin()) OS << ", ";
814         (*I)->writeValue(OS);
815       }
816     }
817 
818     if (Args.size()) OS << ")";
819     OS << Suffix.str() + "\";\n";
820 
821     OS <<
822       "    break;\n"
823       "  }\n";
824   }
825 
826   // End of the switch statement.
827   OS << "}\n";
828   // End of the print function.
829   OS << "}\n\n";
830 }
831 
832 /// \brief Return the index of a spelling in a spelling list.
getSpellingListIndex(const std::vector<Record * > & SpellingList,const Record & Spelling)833 static unsigned getSpellingListIndex(const std::vector<Record*> &SpellingList,
834                                      const Record &Spelling) {
835   assert(SpellingList.size() && "Spelling list is empty!");
836 
837   for (unsigned Index = 0; Index < SpellingList.size(); ++Index) {
838     Record *S = SpellingList[Index];
839     if (S->getValueAsString("Variety") != Spelling.getValueAsString("Variety"))
840       continue;
841     if (S->getValueAsString("Variety") == "CXX11" &&
842         S->getValueAsString("Namespace") !=
843         Spelling.getValueAsString("Namespace"))
844       continue;
845     if (S->getValueAsString("Name") != Spelling.getValueAsString("Name"))
846       continue;
847 
848     return Index;
849   }
850 
851   llvm_unreachable("Unknown spelling!");
852 }
853 
writeAttrAccessorDefinition(Record & R,raw_ostream & OS)854 static void writeAttrAccessorDefinition(Record &R, raw_ostream &OS) {
855   std::vector<Record*> Accessors = R.getValueAsListOfDefs("Accessors");
856   for (std::vector<Record*>::const_iterator I = Accessors.begin(),
857        E = Accessors.end(); I != E; ++I) {
858     Record *Accessor = *I;
859     std::string Name = Accessor->getValueAsString("Name");
860     std::vector<Record*> Spellings = Accessor->getValueAsListOfDefs(
861       "Spellings");
862     std::vector<Record*> SpellingList = R.getValueAsListOfDefs("Spellings");
863     assert(SpellingList.size() &&
864            "Attribute with empty spelling list can't have accessors!");
865 
866     OS << "  bool " << Name << "() const { return SpellingListIndex == ";
867     for (unsigned Index = 0; Index < Spellings.size(); ++Index) {
868       OS << getSpellingListIndex(SpellingList, *Spellings[Index]);
869       if (Index != Spellings.size() -1)
870         OS << " ||\n    SpellingListIndex == ";
871       else
872         OS << "; }\n";
873     }
874   }
875 }
876 
877 namespace clang {
878 
879 // Emits the class definitions for attributes.
EmitClangAttrClass(RecordKeeper & Records,raw_ostream & OS)880 void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
881   emitSourceFileHeader("Attribute classes' definitions", OS);
882 
883   OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
884   OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n";
885 
886   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
887 
888   for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
889        i != e; ++i) {
890     Record &R = **i;
891 
892     if (!R.getValueAsBit("ASTNode"))
893       continue;
894 
895     const std::string &SuperName = R.getSuperClasses().back()->getName();
896 
897     OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n";
898 
899     std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
900     std::vector<Argument*> Args;
901     std::vector<Argument*>::iterator ai, ae;
902     Args.reserve(ArgRecords.size());
903 
904     for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
905                                         re = ArgRecords.end();
906          ri != re; ++ri) {
907       Record &ArgRecord = **ri;
908       Argument *Arg = createArgument(ArgRecord, R.getName());
909       assert(Arg);
910       Args.push_back(Arg);
911 
912       Arg->writeDeclarations(OS);
913       OS << "\n\n";
914     }
915 
916     ae = Args.end();
917 
918     OS << "\n public:\n";
919     OS << "  " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n";
920 
921     for (ai = Args.begin(); ai != ae; ++ai) {
922       OS << "              , ";
923       (*ai)->writeCtorParameters(OS);
924       OS << "\n";
925     }
926 
927     OS << "              , ";
928     OS << "unsigned SI = 0\n";
929 
930     OS << "             )\n";
931     OS << "    : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n";
932 
933     for (ai = Args.begin(); ai != ae; ++ai) {
934       OS << "              , ";
935       (*ai)->writeCtorInitializers(OS);
936       OS << "\n";
937     }
938 
939     OS << "  {\n";
940 
941     for (ai = Args.begin(); ai != ae; ++ai) {
942       (*ai)->writeCtorBody(OS);
943       OS << "\n";
944     }
945     OS << "  }\n\n";
946 
947     OS << "  virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n";
948     OS << "  virtual void printPretty(raw_ostream &OS,\n"
949        << "                           const PrintingPolicy &Policy) const;\n";
950 
951     writeAttrAccessorDefinition(R, OS);
952 
953     for (ai = Args.begin(); ai != ae; ++ai) {
954       (*ai)->writeAccessors(OS);
955       OS << "\n\n";
956     }
957 
958     OS << R.getValueAsString("AdditionalMembers");
959     OS << "\n\n";
960 
961     OS << "  static bool classof(const Attr *A) { return A->getKind() == "
962        << "attr::" << R.getName() << "; }\n";
963 
964     bool LateParsed = R.getValueAsBit("LateParsed");
965     OS << "  virtual bool isLateParsed() const { return "
966        << LateParsed << "; }\n";
967 
968     OS << "};\n\n";
969   }
970 
971   OS << "#endif\n";
972 }
973 
974 // Emits the class method definitions for attributes.
EmitClangAttrImpl(RecordKeeper & Records,raw_ostream & OS)975 void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
976   emitSourceFileHeader("Attribute classes' member function definitions", OS);
977 
978   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
979   std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re;
980   std::vector<Argument*>::iterator ai, ae;
981 
982   for (; i != e; ++i) {
983     Record &R = **i;
984 
985     if (!R.getValueAsBit("ASTNode"))
986       continue;
987 
988     std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
989     std::vector<Argument*> Args;
990     for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri)
991       Args.push_back(createArgument(**ri, R.getName()));
992 
993     for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
994       (*ai)->writeAccessorDefinitions(OS);
995 
996     OS << R.getName() << "Attr *" << R.getName()
997        << "Attr::clone(ASTContext &C) const {\n";
998     OS << "  return new (C) " << R.getName() << "Attr(getLocation(), C";
999     for (ai = Args.begin(); ai != ae; ++ai) {
1000       OS << ", ";
1001       (*ai)->writeCloneArgs(OS);
1002     }
1003     OS << ", getSpellingListIndex());\n}\n\n";
1004 
1005     writePrettyPrintFunction(R, Args, OS);
1006   }
1007 }
1008 
1009 } // end namespace clang
1010 
EmitAttrList(raw_ostream & OS,StringRef Class,const std::vector<Record * > & AttrList)1011 static void EmitAttrList(raw_ostream &OS, StringRef Class,
1012                          const std::vector<Record*> &AttrList) {
1013   std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end();
1014 
1015   if (i != e) {
1016     // Move the end iterator back to emit the last attribute.
1017     for(--e; i != e; ++i) {
1018       if (!(*i)->getValueAsBit("ASTNode"))
1019         continue;
1020 
1021       OS << Class << "(" << (*i)->getName() << ")\n";
1022     }
1023 
1024     OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n";
1025   }
1026 }
1027 
1028 namespace clang {
1029 
1030 // Emits the enumeration list for attributes.
EmitClangAttrList(RecordKeeper & Records,raw_ostream & OS)1031 void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
1032   emitSourceFileHeader("List of all attributes that Clang recognizes", OS);
1033 
1034   OS << "#ifndef LAST_ATTR\n";
1035   OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n";
1036   OS << "#endif\n\n";
1037 
1038   OS << "#ifndef INHERITABLE_ATTR\n";
1039   OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n";
1040   OS << "#endif\n\n";
1041 
1042   OS << "#ifndef LAST_INHERITABLE_ATTR\n";
1043   OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
1044   OS << "#endif\n\n";
1045 
1046   OS << "#ifndef INHERITABLE_PARAM_ATTR\n";
1047   OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n";
1048   OS << "#endif\n\n";
1049 
1050   OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n";
1051   OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)"
1052         " INHERITABLE_PARAM_ATTR(NAME)\n";
1053   OS << "#endif\n\n";
1054 
1055   Record *InhClass = Records.getClass("InheritableAttr");
1056   Record *InhParamClass = Records.getClass("InheritableParamAttr");
1057   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
1058                        NonInhAttrs, InhAttrs, InhParamAttrs;
1059   for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
1060        i != e; ++i) {
1061     if (!(*i)->getValueAsBit("ASTNode"))
1062       continue;
1063 
1064     if ((*i)->isSubClassOf(InhParamClass))
1065       InhParamAttrs.push_back(*i);
1066     else if ((*i)->isSubClassOf(InhClass))
1067       InhAttrs.push_back(*i);
1068     else
1069       NonInhAttrs.push_back(*i);
1070   }
1071 
1072   EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
1073   EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
1074   EmitAttrList(OS, "ATTR", NonInhAttrs);
1075 
1076   OS << "#undef LAST_ATTR\n";
1077   OS << "#undef INHERITABLE_ATTR\n";
1078   OS << "#undef LAST_INHERITABLE_ATTR\n";
1079   OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
1080   OS << "#undef ATTR\n";
1081 }
1082 
1083 // Emits the code to read an attribute from a precompiled header.
EmitClangAttrPCHRead(RecordKeeper & Records,raw_ostream & OS)1084 void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
1085   emitSourceFileHeader("Attribute deserialization code", OS);
1086 
1087   Record *InhClass = Records.getClass("InheritableAttr");
1088   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
1089                        ArgRecords;
1090   std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
1091   std::vector<Argument*> Args;
1092   std::vector<Argument*>::iterator ri, re;
1093 
1094   OS << "  switch (Kind) {\n";
1095   OS << "  default:\n";
1096   OS << "    assert(0 && \"Unknown attribute!\");\n";
1097   OS << "    break;\n";
1098   for (; i != e; ++i) {
1099     Record &R = **i;
1100     if (!R.getValueAsBit("ASTNode"))
1101       continue;
1102 
1103     OS << "  case attr::" << R.getName() << ": {\n";
1104     if (R.isSubClassOf(InhClass))
1105       OS << "    bool isInherited = Record[Idx++];\n";
1106     ArgRecords = R.getValueAsListOfDefs("Args");
1107     Args.clear();
1108     for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) {
1109       Argument *A = createArgument(**ai, R.getName());
1110       Args.push_back(A);
1111       A->writePCHReadDecls(OS);
1112     }
1113     OS << "    New = new (Context) " << R.getName() << "Attr(Range, Context";
1114     for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) {
1115       OS << ", ";
1116       (*ri)->writePCHReadArgs(OS);
1117     }
1118     OS << ");\n";
1119     if (R.isSubClassOf(InhClass))
1120       OS << "    cast<InheritableAttr>(New)->setInherited(isInherited);\n";
1121     OS << "    break;\n";
1122     OS << "  }\n";
1123   }
1124   OS << "  }\n";
1125 }
1126 
1127 // Emits the code to write an attribute to a precompiled header.
EmitClangAttrPCHWrite(RecordKeeper & Records,raw_ostream & OS)1128 void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
1129   emitSourceFileHeader("Attribute serialization code", OS);
1130 
1131   Record *InhClass = Records.getClass("InheritableAttr");
1132   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
1133   std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
1134 
1135   OS << "  switch (A->getKind()) {\n";
1136   OS << "  default:\n";
1137   OS << "    llvm_unreachable(\"Unknown attribute kind!\");\n";
1138   OS << "    break;\n";
1139   for (; i != e; ++i) {
1140     Record &R = **i;
1141     if (!R.getValueAsBit("ASTNode"))
1142       continue;
1143     OS << "  case attr::" << R.getName() << ": {\n";
1144     Args = R.getValueAsListOfDefs("Args");
1145     if (R.isSubClassOf(InhClass) || !Args.empty())
1146       OS << "    const " << R.getName() << "Attr *SA = cast<" << R.getName()
1147          << "Attr>(A);\n";
1148     if (R.isSubClassOf(InhClass))
1149       OS << "    Record.push_back(SA->isInherited());\n";
1150     for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
1151       createArgument(**ai, R.getName())->writePCHWrite(OS);
1152     OS << "    break;\n";
1153     OS << "  }\n";
1154   }
1155   OS << "  }\n";
1156 }
1157 
1158 // Emits the list of spellings for attributes.
EmitClangAttrSpellingList(RecordKeeper & Records,raw_ostream & OS)1159 void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) {
1160   emitSourceFileHeader("llvm::StringSwitch code to match all known attributes",
1161                        OS);
1162 
1163   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1164 
1165   for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
1166     Record &Attr = **I;
1167 
1168     std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1169 
1170     for (std::vector<Record*>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) {
1171       OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", true)\n";
1172     }
1173   }
1174 
1175 }
1176 
EmitClangAttrSpellingListIndex(RecordKeeper & Records,raw_ostream & OS)1177 void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) {
1178   emitSourceFileHeader("Code to translate different attribute spellings "
1179                        "into internal identifiers", OS);
1180 
1181   OS <<
1182     "  unsigned Index = 0;\n"
1183     "  switch (AttrKind) {\n"
1184     "  default:\n"
1185     "    llvm_unreachable(\"Unknown attribute kind!\");\n"
1186     "    break;\n";
1187 
1188   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1189   for (std::vector<Record*>::const_iterator I = Attrs.begin(), E = Attrs.end();
1190        I != E; ++I) {
1191     Record &R = **I;
1192     // We only care about attributes that participate in Sema checking, so
1193     // skip those attributes that are not able to make their way to Sema.
1194     if (!R.getValueAsBit("SemaHandler"))
1195       continue;
1196 
1197     std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
1198     // Each distinct spelling yields an attribute kind.
1199     if (R.getValueAsBit("DistinctSpellings")) {
1200       for (unsigned I = 0; I < Spellings.size(); ++ I) {
1201         OS <<
1202           "  case AT_" << Spellings[I]->getValueAsString("Name") << ": \n"
1203           "    Index = " << I << ";\n"
1204           "  break;\n";
1205       }
1206     } else {
1207       OS << "  case AT_" << R.getName() << " : {\n";
1208       for (unsigned I = 0; I < Spellings.size(); ++ I) {
1209         SmallString<16> Namespace;
1210         if (Spellings[I]->getValueAsString("Variety") == "CXX11")
1211           Namespace = Spellings[I]->getValueAsString("Namespace");
1212         else
1213           Namespace = "";
1214 
1215         OS << "    if (Name == \""
1216           << Spellings[I]->getValueAsString("Name") << "\" && "
1217           << "SyntaxUsed == "
1218           << StringSwitch<unsigned>(Spellings[I]->getValueAsString("Variety"))
1219             .Case("GNU", 0)
1220             .Case("CXX11", 1)
1221             .Case("Declspec", 2)
1222             .Case("Keyword", 3)
1223             .Default(0)
1224           << " && Scope == \"" << Namespace << "\")\n"
1225           << "        return " << I << ";\n";
1226       }
1227 
1228       OS << "    break;\n";
1229       OS << "  }\n";
1230     }
1231   }
1232 
1233   OS << "  }\n";
1234   OS << "  return Index;\n";
1235 }
1236 
1237 // Emits the LateParsed property for attributes.
EmitClangAttrLateParsedList(RecordKeeper & Records,raw_ostream & OS)1238 void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) {
1239   emitSourceFileHeader("llvm::StringSwitch code to match late parsed "
1240                        "attributes", OS);
1241 
1242   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1243 
1244   for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1245        I != E; ++I) {
1246     Record &Attr = **I;
1247 
1248     bool LateParsed = Attr.getValueAsBit("LateParsed");
1249 
1250     if (LateParsed) {
1251       std::vector<Record*> Spellings =
1252         Attr.getValueAsListOfDefs("Spellings");
1253 
1254       // FIXME: Handle non-GNU attributes
1255       for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1256            E = Spellings.end(); I != E; ++I) {
1257         if ((*I)->getValueAsString("Variety") != "GNU")
1258           continue;
1259         OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", "
1260            << LateParsed << ")\n";
1261       }
1262     }
1263   }
1264 }
1265 
1266 // Emits code to instantiate dependent attributes on templates.
EmitClangAttrTemplateInstantiate(RecordKeeper & Records,raw_ostream & OS)1267 void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) {
1268   emitSourceFileHeader("Template instantiation code for attributes", OS);
1269 
1270   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1271 
1272   OS << "namespace clang {\n"
1273      << "namespace sema {\n\n"
1274      << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
1275      << "Sema &S,\n"
1276      << "        const MultiLevelTemplateArgumentList &TemplateArgs) {\n"
1277      << "  switch (At->getKind()) {\n"
1278      << "    default:\n"
1279      << "      break;\n";
1280 
1281   for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1282        I != E; ++I) {
1283     Record &R = **I;
1284     if (!R.getValueAsBit("ASTNode"))
1285       continue;
1286 
1287     OS << "    case attr::" << R.getName() << ": {\n";
1288     bool ShouldClone = R.getValueAsBit("Clone");
1289 
1290     if (!ShouldClone) {
1291       OS << "      return NULL;\n";
1292       OS << "    }\n";
1293       continue;
1294     }
1295 
1296     OS << "      const " << R.getName() << "Attr *A = cast<"
1297        << R.getName() << "Attr>(At);\n";
1298     bool TDependent = R.getValueAsBit("TemplateDependent");
1299 
1300     if (!TDependent) {
1301       OS << "      return A->clone(C);\n";
1302       OS << "    }\n";
1303       continue;
1304     }
1305 
1306     std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
1307     std::vector<Argument*> Args;
1308     std::vector<Argument*>::iterator ai, ae;
1309     Args.reserve(ArgRecords.size());
1310 
1311     for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
1312                                         re = ArgRecords.end();
1313          ri != re; ++ri) {
1314       Record &ArgRecord = **ri;
1315       Argument *Arg = createArgument(ArgRecord, R.getName());
1316       assert(Arg);
1317       Args.push_back(Arg);
1318     }
1319     ae = Args.end();
1320 
1321     for (ai = Args.begin(); ai != ae; ++ai) {
1322       (*ai)->writeTemplateInstantiation(OS);
1323     }
1324     OS << "      return new (C) " << R.getName() << "Attr(A->getLocation(), C";
1325     for (ai = Args.begin(); ai != ae; ++ai) {
1326       OS << ", ";
1327       (*ai)->writeTemplateInstantiationArgs(OS);
1328     }
1329     OS << ");\n    }\n";
1330   }
1331   OS << "  } // end switch\n"
1332      << "  llvm_unreachable(\"Unknown attribute!\");\n"
1333      << "  return 0;\n"
1334      << "}\n\n"
1335      << "} // end namespace sema\n"
1336      << "} // end namespace clang\n";
1337 }
1338 
1339 // Emits the list of parsed attributes.
EmitClangAttrParsedAttrList(RecordKeeper & Records,raw_ostream & OS)1340 void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) {
1341   emitSourceFileHeader("List of all attributes that Clang recognizes", OS);
1342 
1343   OS << "#ifndef PARSED_ATTR\n";
1344   OS << "#define PARSED_ATTR(NAME) NAME\n";
1345   OS << "#endif\n\n";
1346 
1347   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1348 
1349   for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1350        I != E; ++I) {
1351     Record &Attr = **I;
1352 
1353     bool SemaHandler = Attr.getValueAsBit("SemaHandler");
1354     bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings");
1355 
1356     if (SemaHandler) {
1357       if (DistinctSpellings) {
1358         std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1359 
1360         for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1361              E = Spellings.end(); I != E; ++I) {
1362           std::string AttrName = (*I)->getValueAsString("Name");
1363 
1364           StringRef Spelling = NormalizeAttrName(AttrName);
1365 
1366           OS << "PARSED_ATTR(" << Spelling << ")\n";
1367         }
1368       } else {
1369         StringRef AttrName = Attr.getName();
1370         AttrName = NormalizeAttrName(AttrName);
1371         OS << "PARSED_ATTR(" << AttrName << ")\n";
1372       }
1373     }
1374   }
1375 }
1376 
1377 // Emits the kind list of parsed attributes
EmitClangAttrParsedAttrKinds(RecordKeeper & Records,raw_ostream & OS)1378 void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
1379   emitSourceFileHeader("Attribute name matcher", OS);
1380 
1381   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1382 
1383   std::vector<StringMatcher::StringPair> Matches;
1384   for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1385        I != E; ++I) {
1386     Record &Attr = **I;
1387 
1388     bool SemaHandler = Attr.getValueAsBit("SemaHandler");
1389     bool Ignored = Attr.getValueAsBit("Ignored");
1390     bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings");
1391     if (SemaHandler || Ignored) {
1392       std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1393 
1394       for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1395            E = Spellings.end(); I != E; ++I) {
1396         std::string RawSpelling = (*I)->getValueAsString("Name");
1397         StringRef AttrName = NormalizeAttrName(DistinctSpellings
1398                                                  ? StringRef(RawSpelling)
1399                                                  : StringRef(Attr.getName()));
1400 
1401         SmallString<64> Spelling;
1402         if ((*I)->getValueAsString("Variety") == "CXX11") {
1403           Spelling += (*I)->getValueAsString("Namespace");
1404           Spelling += "::";
1405         }
1406         Spelling += NormalizeAttrSpelling(RawSpelling);
1407 
1408         if (SemaHandler)
1409           Matches.push_back(
1410             StringMatcher::StringPair(
1411               StringRef(Spelling),
1412               "return AttributeList::AT_" + AttrName.str() + ";"));
1413         else
1414           Matches.push_back(
1415             StringMatcher::StringPair(
1416               StringRef(Spelling),
1417               "return AttributeList::IgnoredAttribute;"));
1418       }
1419     }
1420   }
1421 
1422   OS << "static AttributeList::Kind getAttrKind(StringRef Name) {\n";
1423   StringMatcher("Name", Matches, OS).Emit();
1424   OS << "return AttributeList::UnknownAttribute;\n"
1425      << "}\n";
1426 }
1427 
1428 // Emits the code to dump an attribute.
EmitClangAttrDump(RecordKeeper & Records,raw_ostream & OS)1429 void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) {
1430   emitSourceFileHeader("Attribute dumper", OS);
1431 
1432   OS <<
1433     "  switch (A->getKind()) {\n"
1434     "  default:\n"
1435     "    llvm_unreachable(\"Unknown attribute kind!\");\n"
1436     "    break;\n";
1437   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
1438   for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1439        I != E; ++I) {
1440     Record &R = **I;
1441     if (!R.getValueAsBit("ASTNode"))
1442       continue;
1443     OS << "  case attr::" << R.getName() << ": {\n";
1444     Args = R.getValueAsListOfDefs("Args");
1445     if (!Args.empty()) {
1446       OS << "    const " << R.getName() << "Attr *SA = cast<" << R.getName()
1447          << "Attr>(A);\n";
1448       for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end();
1449            I != E; ++I)
1450         createArgument(**I, R.getName())->writeDump(OS);
1451 
1452       // Code for detecting the last child.
1453       OS << "    bool OldMoreChildren = hasMoreChildren();\n";
1454       OS << "    bool MoreChildren = OldMoreChildren;\n";
1455 
1456       for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end();
1457            I != E; ++I) {
1458         // More code for detecting the last child.
1459         OS << "    MoreChildren = OldMoreChildren";
1460         for (std::vector<Record*>::iterator Next = I + 1; Next != E; ++Next) {
1461           OS << " || ";
1462           createArgument(**Next, R.getName())->writeHasChildren(OS);
1463         }
1464         OS << ";\n";
1465         OS << "    setMoreChildren(MoreChildren);\n";
1466 
1467         createArgument(**I, R.getName())->writeDumpChildren(OS);
1468       }
1469 
1470       // Reset the last child.
1471       OS << "    setMoreChildren(OldMoreChildren);\n";
1472     }
1473     OS <<
1474       "    break;\n"
1475       "  }\n";
1476   }
1477   OS << "  }\n";
1478 }
1479 
1480 } // end namespace clang
1481