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