Home | History | Annotate | Download | only in TableGen
      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 
   1093