ClangAttrEmitter.cpp revision a31f65b10e61ca8f2f427b1df176c10ea8a0efa2
1bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew//===- ClangAttrEmitter.cpp - Generate Clang attribute handling =-*- C++ -*--=//
2bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew//
3bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew//                     The LLVM Compiler Infrastructure
4bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew//
5bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew// This file is distributed under the University of Illinois Open Source
6bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew// License. See LICENSE.TXT for details.
7bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew//
8bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew//===----------------------------------------------------------------------===//
9bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew//
10bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew// These tablegen backends emit Clang attribute processing code
11bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew//
12bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew//===----------------------------------------------------------------------===//
13bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
14bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include "llvm/ADT/SmallString.h"
15bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include "llvm/ADT/StringSwitch.h"
16bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include "llvm/TableGen/Record.h"
174548c6cf9bcdd96d8303caa4130ab638b61f8a30Wanlong Gao#include "llvm/TableGen/StringMatcher.h"
18bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include "llvm/TableGen/TableGenBackend.h"
19bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include <algorithm>
20bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew#include <cctype>
214b264476cb3f10b994b39e4b61cca0594ea79279robbiew
222c28215423293e443469a07ae7011135d058b671Garrett Cooperusing namespace llvm;
23bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
244b264476cb3f10b994b39e4b61cca0594ea79279robbiewstatic const std::vector<StringRef>
25bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiewgetValueAsListOfStrings(Record &R, StringRef FieldName) {
26bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew  ListInit *List = R.getValueAsListInit(FieldName);
27bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew  assert (List && "Got a null ListInit");
28bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
29bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew  std::vector<StringRef> Strings;
30bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew  Strings.reserve(List->getSize());
31bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
32bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew  for (ListInit::const_iterator i = List->begin(), e = List->end();
33bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew       i != e;
34bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew       ++i) {
35bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    assert(*i && "Got a null element in a ListInit");
36bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    if (StringInit *S = dyn_cast<StringInit>(*i))
37a70576c4834d89f937e46698fef4114736cce4d7robbiew      Strings.push_back(S->getValue());
38bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    else
39bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      assert(false && "Got a non-string, non-code element in a ListInit");
40bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew  }
41bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
42bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew  return Strings;
43bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
44bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
454b264476cb3f10b994b39e4b61cca0594ea79279robbiewstatic std::string ReadPCHRecord(StringRef type) {
464b264476cb3f10b994b39e4b61cca0594ea79279robbiew  return StringSwitch<std::string>(type)
474b264476cb3f10b994b39e4b61cca0594ea79279robbiew    .EndsWith("Decl *", "GetLocalDeclAs<"
484b264476cb3f10b994b39e4b61cca0594ea79279robbiew              + std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])")
494b264476cb3f10b994b39e4b61cca0594ea79279robbiew    .Case("QualType", "getLocalType(F, Record[Idx++])")
50bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    .Case("Expr *", "ReadExpr(F)")
51bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)")
52bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    .Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)")
53bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    .Default("Record[Idx++]");
54bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
55bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
56bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew// Assumes that the way to get the value is SA->getname()
57bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiewstatic std::string WritePCHRecord(StringRef type, StringRef name) {
58bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew  return StringSwitch<std::string>(type)
59bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    .EndsWith("Decl *", "AddDeclRef(" + std::string(name) +
60bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew                        ", Record);\n")
61bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    .Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n")
62bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    .Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
63bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    .Case("IdentifierInfo *",
64354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao          "AddIdentifierRef(" + std::string(name) + ", Record);\n")
65354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    .Case("SourceLocation",
66bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew          "AddSourceLocation(" + std::string(name) + ", Record);\n")
67bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    .Default("Record.push_back(" + std::string(name) + ");\n");
68bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew}
694b264476cb3f10b994b39e4b61cca0594ea79279robbiew
704b264476cb3f10b994b39e4b61cca0594ea79279robbiew// Normalize attribute name by removing leading and trailing
714b264476cb3f10b994b39e4b61cca0594ea79279robbiew// underscores. For example, __foo, foo__, __foo__ would
72354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao// become foo.
73bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiewstatic StringRef NormalizeAttrName(StringRef AttrName) {
74829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger  if (AttrName.startswith("__"))
75829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger    AttrName = AttrName.substr(2, AttrName.size());
76829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger
77829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger  if (AttrName.endswith("__"))
78829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger    AttrName = AttrName.substr(0, AttrName.size() - 2);
79829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger
80829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger  return AttrName;
81829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger}
82bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
83bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew// Normalize attribute spelling only if the spelling has both leading
84354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao// and trailing underscores. For example, __ms_struct__ will be
85354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao// normalized to "ms_struct"; __cdecl will remain intact.
869e78ade7d6c596a709d0228909bd5d37a85cf4a5vapierstatic StringRef NormalizeAttrSpelling(StringRef AttrSpelling) {
87354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao  if (AttrSpelling.startswith("__") && AttrSpelling.endswith("__")) {
88354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    AttrSpelling = AttrSpelling.substr(2, AttrSpelling.size() - 4);
89354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao  }
90354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
91354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao  return AttrSpelling;
92354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao}
93354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
94354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaonamespace {
95bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew  class Argument {
96829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger    std::string lowerName, upperName;
97bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    StringRef attrName;
98354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
99bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew  public:
1004b264476cb3f10b994b39e4b61cca0594ea79279robbiew    Argument(Record &Arg, StringRef Attr)
101bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      : lowerName(Arg.getValueAsString("Name")), upperName(lowerName),
1024b264476cb3f10b994b39e4b61cca0594ea79279robbiew        attrName(Attr) {
1034b264476cb3f10b994b39e4b61cca0594ea79279robbiew      if (!lowerName.empty()) {
1044b264476cb3f10b994b39e4b61cca0594ea79279robbiew        lowerName[0] = std::tolower(lowerName[0]);
1054b264476cb3f10b994b39e4b61cca0594ea79279robbiew        upperName[0] = std::toupper(upperName[0]);
1064b264476cb3f10b994b39e4b61cca0594ea79279robbiew      }
107bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    }
1084b264476cb3f10b994b39e4b61cca0594ea79279robbiew    virtual ~Argument() {}
109bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
110354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    StringRef getLowerName() const { return lowerName; }
1114b264476cb3f10b994b39e4b61cca0594ea79279robbiew    StringRef getUpperName() const { return upperName; }
1124b264476cb3f10b994b39e4b61cca0594ea79279robbiew    StringRef getAttrName() const { return attrName; }
113bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
1144b264476cb3f10b994b39e4b61cca0594ea79279robbiew    // These functions print the argument contents formatted in different ways.
115354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    virtual void writeAccessors(raw_ostream &OS) const = 0;
1164b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper    virtual void writeAccessorDefinitions(raw_ostream &OS) const {}
117bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    virtual void writeCloneArgs(raw_ostream &OS) const = 0;
118bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0;
119bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    virtual void writeTemplateInstantiation(raw_ostream &OS) const {}
1204b264476cb3f10b994b39e4b61cca0594ea79279robbiew    virtual void writeCtorBody(raw_ostream &OS) const {}
121bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    virtual void writeCtorInitializers(raw_ostream &OS) const = 0;
122829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger    virtual void writeCtorParameters(raw_ostream &OS) const = 0;
123bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    virtual void writeDeclarations(raw_ostream &OS) const = 0;
1244b264476cb3f10b994b39e4b61cca0594ea79279robbiew    virtual void writePCHReadArgs(raw_ostream &OS) const = 0;
1254b264476cb3f10b994b39e4b61cca0594ea79279robbiew    virtual void writePCHReadDecls(raw_ostream &OS) const = 0;
126bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    virtual void writePCHWrite(raw_ostream &OS) const = 0;
127354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    virtual void writeValue(raw_ostream &OS) const = 0;
128354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    virtual void writeDump(raw_ostream &OS) const = 0;
129354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    virtual void writeDumpChildren(raw_ostream &OS) const {}
130354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    virtual void writeHasChildren(raw_ostream &OS) const { OS << "false"; }
131354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao  };
132354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
133bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew  class SimpleArgument : public Argument {
134354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    std::string type;
135354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
136354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao  public:
137bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    SimpleArgument(Record &Arg, StringRef Attr, std::string T)
138354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      : Argument(Arg, Attr), type(T)
1394b264476cb3f10b994b39e4b61cca0594ea79279robbiew    {}
1404b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper
141bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    std::string getType() const { return type; }
142354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
143354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    void writeAccessors(raw_ostream &OS) const {
1444b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "  " << type << " get" << getUpperName() << "() const {\n";
145bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      OS << "    return " << getLowerName() << ";\n";
146354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "  }";
147bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    }
148354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    void writeCloneArgs(raw_ostream &OS) const {
149bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      OS << getLowerName();
1504b264476cb3f10b994b39e4b61cca0594ea79279robbiew    }
151bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
152829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger      OS << "A->get" << getUpperName() << "()";
153bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    }
1544b264476cb3f10b994b39e4b61cca0594ea79279robbiew    void writeCtorInitializers(raw_ostream &OS) const {
1554b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << getLowerName() << "(" << getUpperName() << ")";
1564b264476cb3f10b994b39e4b61cca0594ea79279robbiew    }
1574b264476cb3f10b994b39e4b61cca0594ea79279robbiew    void writeCtorParameters(raw_ostream &OS) const {
1584b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << type << " " << getUpperName();
159354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    }
1604b264476cb3f10b994b39e4b61cca0594ea79279robbiew    void writeDeclarations(raw_ostream &OS) const {
1614b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << type << " " << getLowerName() << ";";
162354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    }
1634b264476cb3f10b994b39e4b61cca0594ea79279robbiew    void writePCHReadDecls(raw_ostream &OS) const {
1644b264476cb3f10b994b39e4b61cca0594ea79279robbiew      std::string read = ReadPCHRecord(type);
1654b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "    " << type << " " << getLowerName() << " = " << read << ";\n";
1664b264476cb3f10b994b39e4b61cca0594ea79279robbiew    }
1674b264476cb3f10b994b39e4b61cca0594ea79279robbiew    void writePCHReadArgs(raw_ostream &OS) const {
1684b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << getLowerName();
169354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    }
1704b264476cb3f10b994b39e4b61cca0594ea79279robbiew    void writePCHWrite(raw_ostream &OS) const {
171354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "    " << WritePCHRecord(type, "SA->get" +
172354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao                                           std::string(getUpperName()) + "()");
173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    }
1744b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper    void writeValue(raw_ostream &OS) const {
1754b264476cb3f10b994b39e4b61cca0594ea79279robbiew      if (type == "FunctionDecl *") {
1764b264476cb3f10b994b39e4b61cca0594ea79279robbiew        OS << "\" << get" << getUpperName() << "()->getNameInfo().getAsString() << \"";
1774b264476cb3f10b994b39e4b61cca0594ea79279robbiew      } else if (type == "IdentifierInfo *") {
1784b264476cb3f10b994b39e4b61cca0594ea79279robbiew        OS << "\" << get" << getUpperName() << "()->getName() << \"";
1794b264476cb3f10b994b39e4b61cca0594ea79279robbiew      } else if (type == "QualType") {
1804b264476cb3f10b994b39e4b61cca0594ea79279robbiew        OS << "\" << get" << getUpperName() << "().getAsString() << \"";
1814b264476cb3f10b994b39e4b61cca0594ea79279robbiew      } else if (type == "SourceLocation") {
182354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao        OS << "\" << get" << getUpperName() << "().getRawEncoding() << \"";
1834b264476cb3f10b994b39e4b61cca0594ea79279robbiew      } else {
184354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao        OS << "\" << get" << getUpperName() << "() << \"";
185354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      }
186354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    }
1874b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper    void writeDump(raw_ostream &OS) const {
1884b264476cb3f10b994b39e4b61cca0594ea79279robbiew      if (type == "FunctionDecl *") {
189354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao        OS << "    OS << \" \";\n";
190bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew        OS << "    dumpBareDeclRef(SA->get" << getUpperName() << "());\n";
191354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      } else if (type == "IdentifierInfo *") {
192bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew        OS << "    OS << \" \" << SA->get" << getUpperName()
1934b264476cb3f10b994b39e4b61cca0594ea79279robbiew           << "()->getName();\n";
194bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      } else if (type == "QualType") {
195829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger        OS << "    OS << \" \" << SA->get" << getUpperName()
196bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew           << "().getAsString();\n";
1974b264476cb3f10b994b39e4b61cca0594ea79279robbiew      } else if (type == "SourceLocation") {
198354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao        OS << "    OS << \" \";\n";
199354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao        OS << "    SA->get" << getUpperName() << "().print(OS, *SM);\n";
200354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      } else if (type == "bool") {
201354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao        OS << "    if (SA->get" << getUpperName() << "()) OS << \" "
202354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao           << getUpperName() << "\";\n";
203354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      } else if (type == "int" || type == "unsigned") {
204354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao        OS << "    OS << \" \" << SA->get" << getUpperName() << "();\n";
205354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      } else {
2064b264476cb3f10b994b39e4b61cca0594ea79279robbiew        llvm_unreachable("Unknown SimpleArgument type!");
2074b264476cb3f10b994b39e4b61cca0594ea79279robbiew      }
2084b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper    }
2092c28215423293e443469a07ae7011135d058b671Garrett Cooper  };
210354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
2114b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper  class StringArgument : public Argument {
2124b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper  public:
213354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    StringArgument(Record &Arg, StringRef Attr)
214bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      : Argument(Arg, Attr)
215354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    {}
216bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
2174b264476cb3f10b994b39e4b61cca0594ea79279robbiew    void writeAccessors(raw_ostream &OS) const {
218bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      OS << "  llvm::StringRef get" << getUpperName() << "() const {\n";
219829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger      OS << "    return llvm::StringRef(" << getLowerName() << ", "
220bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew         << getLowerName() << "Length);\n";
221354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "  }\n";
222354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "  unsigned get" << getUpperName() << "Length() const {\n";
2234b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "    return " << getLowerName() << "Length;\n";
224bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      OS << "  }\n";
225354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "  void set" << getUpperName()
226354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao         << "(ASTContext &C, llvm::StringRef S) {\n";
227354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "    " << getLowerName() << "Length = S.size();\n";
228354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "    this->" << getLowerName() << " = new (C, 1) char ["
2294b264476cb3f10b994b39e4b61cca0594ea79279robbiew         << getLowerName() << "Length];\n";
2304b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "    std::memcpy(this->" << getLowerName() << ", S.data(), "
2312c28215423293e443469a07ae7011135d058b671Garrett Cooper         << getLowerName() << "Length);\n";
2324b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "  }";
2334b264476cb3f10b994b39e4b61cca0594ea79279robbiew    }
2344b264476cb3f10b994b39e4b61cca0594ea79279robbiew    void writeCloneArgs(raw_ostream &OS) const {
2354b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "get" << getUpperName() << "()";
236354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    }
237354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
2384b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "A->get" << getUpperName() << "()";
239cf0d626fe6224db3c714843dc7007e9f81d94a80Cyril Hrubis    }
240bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    void writeCtorBody(raw_ostream &OS) const {
241354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "      std::memcpy(" << getLowerName() << ", " << getUpperName()
242bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew         << ".data(), " << getLowerName() << "Length);";
2434b264476cb3f10b994b39e4b61cca0594ea79279robbiew    }
244bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    void writeCtorInitializers(raw_ostream &OS) const {
245829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger      OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
246bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew         << getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
247354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao         << "Length])";
248354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    }
249bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    void writeCtorParameters(raw_ostream &OS) const {
250354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "llvm::StringRef " << getUpperName();
251bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    }
2524b264476cb3f10b994b39e4b61cca0594ea79279robbiew    void writeDeclarations(raw_ostream &OS) const {
253bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      OS << "unsigned " << getLowerName() << "Length;\n";
254829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger      OS << "char *" << getLowerName() << ";";
255bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    }
2564b264476cb3f10b994b39e4b61cca0594ea79279robbiew    void writePCHReadDecls(raw_ostream &OS) const {
257354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "    std::string " << getLowerName()
2584b264476cb3f10b994b39e4b61cca0594ea79279robbiew         << "= ReadString(Record, Idx);\n";
259354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    }
260bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    void writePCHReadArgs(raw_ostream &OS) const {
261354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << getLowerName();
262829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger    }
263bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    void writePCHWrite(raw_ostream &OS) const {
264354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "    AddString(SA->get" << getUpperName() << "(), Record);\n";
265bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    }
266354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    void writeValue(raw_ostream &OS) const {
267829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger      OS << "\\\"\" << get" << getUpperName() << "() << \"\\\"";
268bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    }
269354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    void writeDump(raw_ostream &OS) const {
270bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      OS << "    OS << \" \\\"\" << SA->get" << getUpperName()
271354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao         << "() << \"\\\"\";\n";
272829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger    }
273bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew  };
274354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
275bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew  class AlignedArgument : public Argument {
276354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao  public:
277bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    AlignedArgument(Record &Arg, StringRef Attr)
2784b264476cb3f10b994b39e4b61cca0594ea79279robbiew      : Argument(Arg, Attr)
2794b264476cb3f10b994b39e4b61cca0594ea79279robbiew    {}
280bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew
281829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger    void writeAccessors(raw_ostream &OS) const {
282bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      OS << "  bool is" << getUpperName() << "Dependent() const;\n";
2834b264476cb3f10b994b39e4b61cca0594ea79279robbiew
2844b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "  unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";
2854b264476cb3f10b994b39e4b61cca0594ea79279robbiew
2869e78ade7d6c596a709d0228909bd5d37a85cf4a5vapier      OS << "  bool is" << getUpperName() << "Expr() const {\n";
2874b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "    return is" << getLowerName() << "Expr;\n";
2884b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "  }\n";
2894b264476cb3f10b994b39e4b61cca0594ea79279robbiew
2904b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "  Expr *get" << getUpperName() << "Expr() const {\n";
291354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "    assert(is" << getLowerName() << "Expr);\n";
292354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "    return " << getLowerName() << "Expr;\n";
2934b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "  }\n";
2944b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper
2954b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "  TypeSourceInfo *get" << getUpperName() << "Type() const {\n";
2964b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "    assert(!is" << getLowerName() << "Expr);\n";
2974b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "    return " << getLowerName() << "Type;\n";
298354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "  }";
299354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    }
3004b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper    void writeAccessorDefinitions(raw_ostream &OS) const {
3014b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
3024b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper         << "Dependent() const {\n";
303354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "  if (is" << getLowerName() << "Expr)\n";
304354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "    return " << getLowerName() << "Expr && (" << getLowerName()
305354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao         << "Expr->isValueDependent() || " << getLowerName()
306354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao         << "Expr->isTypeDependent());\n";
3074b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "  else\n";
3084b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "    return " << getLowerName()
3094b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper         << "Type->getType()->isDependentType();\n";
3104b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "}\n";
311354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
312354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      // FIXME: Do not do the calculation here
313354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      // FIXME: Handle types correctly
314354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      // A null pointer means maximum alignment
315354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      // FIXME: Load the platform-specific maximum alignment, rather than
3164b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      //        16, the x86 max.
317354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName()
3184b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper         << "(ASTContext &Ctx) const {\n";
3194b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "  assert(!is" << getUpperName() << "Dependent());\n";
3204b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "  if (is" << getLowerName() << "Expr)\n";
3214b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "    return (" << getLowerName() << "Expr ? " << getLowerName()
322354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao         << "Expr->EvaluateKnownConstInt(Ctx).getZExtValue() : 16)"
323354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao         << "* Ctx.getCharWidth();\n";
324354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "  else\n";
3254b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "    return 0; // FIXME\n";
3264b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "}\n";
327354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    }
3284b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper    void writeCloneArgs(raw_ostream &OS) const {
3294b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "is" << getLowerName() << "Expr, is" << getLowerName()
3304b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper         << "Expr ? static_cast<void*>(" << getLowerName()
3314b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper         << "Expr) : " << getLowerName()
3324b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper         << "Type";
333354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    }
334bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
335bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      // FIXME: move the definition in Sema::InstantiateAttrs to here.
336354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      // In the meantime, aligned attributes are cloned.
337bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    }
338bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    void writeCtorBody(raw_ostream &OS) const {
339354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "    if (is" << getLowerName() << "Expr)\n";
340bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      OS << "       " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
341bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew         << getUpperName() << ");\n";
342829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger      OS << "    else\n";
343bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew      OS << "       " << getLowerName()
344354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao         << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
345354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao         << ");";
346354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    }
3474b264476cb3f10b994b39e4b61cca0594ea79279robbiew    void writeCtorInitializers(raw_ostream &OS) const {
3484b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
349bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    }
3502c28215423293e443469a07ae7011135d058b671Garrett Cooper    void writeCtorParameters(raw_ostream &OS) const {
351829ac9d177bb1c713f1fe4266bdc44792b8c556dMike Frysinger      OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
352bd002493fe25b809dbf37e89c6ceb8fe90dc9d49robbiew    }
353354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    void writeDeclarations(raw_ostream &OS) const {
3544b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "bool is" << getLowerName() << "Expr;\n";
3554b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "union {\n";
3564b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "Expr *" << getLowerName() << "Expr;\n";
3574b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
3584b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "};";
3594b264476cb3f10b994b39e4b61cca0594ea79279robbiew    }
3604b264476cb3f10b994b39e4b61cca0594ea79279robbiew    void writePCHReadArgs(raw_ostream &OS) const {
3614b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
3624b264476cb3f10b994b39e4b61cca0594ea79279robbiew    }
3634b264476cb3f10b994b39e4b61cca0594ea79279robbiew    void writePCHReadDecls(raw_ostream &OS) const {
364354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "    bool is" << getLowerName() << "Expr = Record[Idx++];\n";
3654b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "    void *" << getLowerName() << "Ptr;\n";
366354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "    if (is" << getLowerName() << "Expr)\n";
367354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao      OS << "      " << getLowerName() << "Ptr = ReadExpr(F);\n";
3684b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper      OS << "    else\n";
3694b264476cb3f10b994b39e4b61cca0594ea79279robbiew      OS << "      " << getLowerName()
370354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao         << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n";
371354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao    }
3724b20b1d51ab9293abe408289e9096fbf3fa9b080Garrett Cooper    void writePCHWrite(raw_ostream &OS) const {
373ec6edca7aa42b6affd989ef91b5897f96795e40fChris Dearman      OS << "    Record.push_back(SA->is" << getUpperName() << "Expr());\n";
374      OS << "    if (SA->is" << getUpperName() << "Expr())\n";
375      OS << "      AddStmt(SA->get" << getUpperName() << "Expr());\n";
376      OS << "    else\n";
377      OS << "      AddTypeSourceInfo(SA->get" << getUpperName()
378         << "Type(), Record);\n";
379    }
380    void writeValue(raw_ostream &OS) const {
381      OS << "\";\n"
382         << "  " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n"
383         << "  OS << \"";
384    }
385    void writeDump(raw_ostream &OS) const {
386    }
387    void writeDumpChildren(raw_ostream &OS) const {
388      OS << "    if (SA->is" << getUpperName() << "Expr()) {\n";
389      OS << "      lastChild();\n";
390      OS << "      dumpStmt(SA->get" << getUpperName() << "Expr());\n";
391      OS << "    } else\n";
392      OS << "      dumpType(SA->get" << getUpperName()
393         << "Type()->getType());\n";
394    }
395    void writeHasChildren(raw_ostream &OS) const {
396      OS << "SA->is" << getUpperName() << "Expr()";
397    }
398  };
399
400  class VariadicArgument : public Argument {
401    std::string type;
402
403  public:
404    VariadicArgument(Record &Arg, StringRef Attr, std::string T)
405      : Argument(Arg, Attr), type(T)
406    {}
407
408    std::string getType() const { return type; }
409
410    void writeAccessors(raw_ostream &OS) const {
411      OS << "  typedef " << type << "* " << getLowerName() << "_iterator;\n";
412      OS << "  " << getLowerName() << "_iterator " << getLowerName()
413         << "_begin() const {\n";
414      OS << "    return " << getLowerName() << ";\n";
415      OS << "  }\n";
416      OS << "  " << getLowerName() << "_iterator " << getLowerName()
417         << "_end() const {\n";
418      OS << "    return " << getLowerName() << " + " << getLowerName()
419         << "Size;\n";
420      OS << "  }\n";
421      OS << "  unsigned " << getLowerName() << "_size() const {\n"
422         << "    return " << getLowerName() << "Size;\n";
423      OS << "  }";
424    }
425    void writeCloneArgs(raw_ostream &OS) const {
426      OS << getLowerName() << ", " << getLowerName() << "Size";
427    }
428    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
429      // This isn't elegant, but we have to go through public methods...
430      OS << "A->" << getLowerName() << "_begin(), "
431         << "A->" << getLowerName() << "_size()";
432    }
433    void writeCtorBody(raw_ostream &OS) const {
434      // FIXME: memcpy is not safe on non-trivial types.
435      OS << "    std::memcpy(" << getLowerName() << ", " << getUpperName()
436         << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n";
437    }
438    void writeCtorInitializers(raw_ostream &OS) const {
439      OS << getLowerName() << "Size(" << getUpperName() << "Size), "
440         << getLowerName() << "(new (Ctx, 16) " << getType() << "["
441         << getLowerName() << "Size])";
442    }
443    void writeCtorParameters(raw_ostream &OS) const {
444      OS << getType() << " *" << getUpperName() << ", unsigned "
445         << getUpperName() << "Size";
446    }
447    void writeDeclarations(raw_ostream &OS) const {
448      OS << "  unsigned " << getLowerName() << "Size;\n";
449      OS << "  " << getType() << " *" << getLowerName() << ";";
450    }
451    void writePCHReadDecls(raw_ostream &OS) const {
452      OS << "  unsigned " << getLowerName() << "Size = Record[Idx++];\n";
453      OS << "  SmallVector<" << type << ", 4> " << getLowerName()
454         << ";\n";
455      OS << "  " << getLowerName() << ".reserve(" << getLowerName()
456         << "Size);\n";
457      OS << "  for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
458
459      std::string read = ReadPCHRecord(type);
460      OS << "    " << getLowerName() << ".push_back(" << read << ");\n";
461    }
462    void writePCHReadArgs(raw_ostream &OS) const {
463      OS << getLowerName() << ".data(), " << getLowerName() << "Size";
464    }
465    void writePCHWrite(raw_ostream &OS) const{
466      OS << "    Record.push_back(SA->" << getLowerName() << "_size());\n";
467      OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
468         << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
469         << getLowerName() << "_end(); i != e; ++i)\n";
470      OS << "      " << WritePCHRecord(type, "(*i)");
471    }
472    void writeValue(raw_ostream &OS) const {
473      OS << "\";\n";
474      OS << "  bool isFirst = true;\n"
475         << "  for (" << getAttrName() << "Attr::" << getLowerName()
476         << "_iterator i = " << getLowerName() << "_begin(), e = "
477         << getLowerName() << "_end(); i != e; ++i) {\n"
478         << "    if (isFirst) isFirst = false;\n"
479         << "    else OS << \", \";\n"
480         << "    OS << *i;\n"
481         << "  }\n";
482      OS << "  OS << \"";
483    }
484    void writeDump(raw_ostream &OS) const {
485      OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
486         << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
487         << getLowerName() << "_end(); I != E; ++I)\n";
488      OS << "      OS << \" \" << *I;\n";
489    }
490  };
491
492  class EnumArgument : public Argument {
493    std::string type;
494    std::vector<StringRef> values, enums, uniques;
495  public:
496    EnumArgument(Record &Arg, StringRef Attr)
497      : Argument(Arg, Attr), type(Arg.getValueAsString("Type")),
498        values(getValueAsListOfStrings(Arg, "Values")),
499        enums(getValueAsListOfStrings(Arg, "Enums")),
500        uniques(enums)
501    {
502      // Calculate the various enum values
503      std::sort(uniques.begin(), uniques.end());
504      uniques.erase(std::unique(uniques.begin(), uniques.end()), uniques.end());
505      // FIXME: Emit a proper error
506      assert(!uniques.empty());
507    }
508
509    void writeAccessors(raw_ostream &OS) const {
510      OS << "  " << type << " get" << getUpperName() << "() const {\n";
511      OS << "    return " << getLowerName() << ";\n";
512      OS << "  }";
513    }
514    void writeCloneArgs(raw_ostream &OS) const {
515      OS << getLowerName();
516    }
517    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
518      OS << "A->get" << getUpperName() << "()";
519    }
520    void writeCtorInitializers(raw_ostream &OS) const {
521      OS << getLowerName() << "(" << getUpperName() << ")";
522    }
523    void writeCtorParameters(raw_ostream &OS) const {
524      OS << type << " " << getUpperName();
525    }
526    void writeDeclarations(raw_ostream &OS) const {
527      std::vector<StringRef>::const_iterator i = uniques.begin(),
528                                             e = uniques.end();
529      // The last one needs to not have a comma.
530      --e;
531
532      OS << "public:\n";
533      OS << "  enum " << type << " {\n";
534      for (; i != e; ++i)
535        OS << "    " << *i << ",\n";
536      OS << "    " << *e << "\n";
537      OS << "  };\n";
538      OS << "private:\n";
539      OS << "  " << type << " " << getLowerName() << ";";
540    }
541    void writePCHReadDecls(raw_ostream &OS) const {
542      OS << "    " << getAttrName() << "Attr::" << type << " " << getLowerName()
543         << "(static_cast<" << getAttrName() << "Attr::" << type
544         << ">(Record[Idx++]));\n";
545    }
546    void writePCHReadArgs(raw_ostream &OS) const {
547      OS << getLowerName();
548    }
549    void writePCHWrite(raw_ostream &OS) const {
550      OS << "Record.push_back(SA->get" << getUpperName() << "());\n";
551    }
552    void writeValue(raw_ostream &OS) const {
553      OS << "\" << get" << getUpperName() << "() << \"";
554    }
555    void writeDump(raw_ostream &OS) const {
556      OS << "    switch(SA->get" << getUpperName() << "()) {\n";
557      for (std::vector<StringRef>::const_iterator I = uniques.begin(),
558           E = uniques.end(); I != E; ++I) {
559        OS << "    case " << getAttrName() << "Attr::" << *I << ":\n";
560        OS << "      OS << \" " << *I << "\";\n";
561        OS << "      break;\n";
562      }
563      OS << "    }\n";
564    }
565  };
566
567  class VersionArgument : public Argument {
568  public:
569    VersionArgument(Record &Arg, StringRef Attr)
570      : Argument(Arg, Attr)
571    {}
572
573    void writeAccessors(raw_ostream &OS) const {
574      OS << "  VersionTuple get" << getUpperName() << "() const {\n";
575      OS << "    return " << getLowerName() << ";\n";
576      OS << "  }\n";
577      OS << "  void set" << getUpperName()
578         << "(ASTContext &C, VersionTuple V) {\n";
579      OS << "    " << getLowerName() << " = V;\n";
580      OS << "  }";
581    }
582    void writeCloneArgs(raw_ostream &OS) const {
583      OS << "get" << getUpperName() << "()";
584    }
585    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
586      OS << "A->get" << getUpperName() << "()";
587    }
588    void writeCtorBody(raw_ostream &OS) const {
589    }
590    void writeCtorInitializers(raw_ostream &OS) const {
591      OS << getLowerName() << "(" << getUpperName() << ")";
592    }
593    void writeCtorParameters(raw_ostream &OS) const {
594      OS << "VersionTuple " << getUpperName();
595    }
596    void writeDeclarations(raw_ostream &OS) const {
597      OS << "VersionTuple " << getLowerName() << ";\n";
598    }
599    void writePCHReadDecls(raw_ostream &OS) const {
600      OS << "    VersionTuple " << getLowerName()
601         << "= ReadVersionTuple(Record, Idx);\n";
602    }
603    void writePCHReadArgs(raw_ostream &OS) const {
604      OS << getLowerName();
605    }
606    void writePCHWrite(raw_ostream &OS) const {
607      OS << "    AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n";
608    }
609    void writeValue(raw_ostream &OS) const {
610      OS << getLowerName() << "=\" << get" << getUpperName() << "() << \"";
611    }
612    void writeDump(raw_ostream &OS) const {
613      OS << "    OS << \" \" << SA->get" << getUpperName() << "();\n";
614    }
615  };
616
617  class ExprArgument : public SimpleArgument {
618  public:
619    ExprArgument(Record &Arg, StringRef Attr)
620      : SimpleArgument(Arg, Attr, "Expr *")
621    {}
622
623    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
624      OS << "tempInst" << getUpperName();
625    }
626
627    void writeTemplateInstantiation(raw_ostream &OS) const {
628      OS << "      " << getType() << " tempInst" << getUpperName() << ";\n";
629      OS << "      {\n";
630      OS << "        EnterExpressionEvaluationContext "
631         << "Unevaluated(S, Sema::Unevaluated);\n";
632      OS << "        ExprResult " << "Result = S.SubstExpr("
633         << "A->get" << getUpperName() << "(), TemplateArgs);\n";
634      OS << "        tempInst" << getUpperName() << " = "
635         << "Result.takeAs<Expr>();\n";
636      OS << "      }\n";
637    }
638
639    void writeDump(raw_ostream &OS) const {
640    }
641
642    void writeDumpChildren(raw_ostream &OS) const {
643      OS << "    lastChild();\n";
644      OS << "    dumpStmt(SA->get" << getUpperName() << "());\n";
645    }
646    void writeHasChildren(raw_ostream &OS) const { OS << "true"; }
647  };
648
649  class VariadicExprArgument : public VariadicArgument {
650  public:
651    VariadicExprArgument(Record &Arg, StringRef Attr)
652      : VariadicArgument(Arg, Attr, "Expr *")
653    {}
654
655    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
656      OS << "tempInst" << getUpperName() << ", "
657         << "A->" << getLowerName() << "_size()";
658    }
659
660    void writeTemplateInstantiation(raw_ostream &OS) const {
661      OS << "      " << getType() << " *tempInst" << getUpperName()
662         << " = new (C, 16) " << getType()
663         << "[A->" << getLowerName() << "_size()];\n";
664      OS << "      {\n";
665      OS << "        EnterExpressionEvaluationContext "
666         << "Unevaluated(S, Sema::Unevaluated);\n";
667      OS << "        " << getType() << " *TI = tempInst" << getUpperName()
668         << ";\n";
669      OS << "        " << getType() << " *I = A->" << getLowerName()
670         << "_begin();\n";
671      OS << "        " << getType() << " *E = A->" << getLowerName()
672         << "_end();\n";
673      OS << "        for (; I != E; ++I, ++TI) {\n";
674      OS << "          ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n";
675      OS << "          *TI = Result.takeAs<Expr>();\n";
676      OS << "        }\n";
677      OS << "      }\n";
678    }
679
680    void writeDump(raw_ostream &OS) const {
681    }
682
683    void writeDumpChildren(raw_ostream &OS) const {
684      OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
685         << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
686         << getLowerName() << "_end(); I != E; ++I) {\n";
687      OS << "      if (I + 1 == E)\n";
688      OS << "        lastChild();\n";
689      OS << "      dumpStmt(*I);\n";
690      OS << "    }\n";
691    }
692
693    void writeHasChildren(raw_ostream &OS) const {
694      OS << "SA->" << getLowerName() << "_begin() != "
695         << "SA->" << getLowerName() << "_end()";
696    }
697  };
698}
699
700static Argument *createArgument(Record &Arg, StringRef Attr,
701                                Record *Search = 0) {
702  if (!Search)
703    Search = &Arg;
704
705  Argument *Ptr = 0;
706  llvm::StringRef ArgName = Search->getName();
707
708  if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr);
709  else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr);
710  else if (ArgName == "ExprArgument") Ptr = new ExprArgument(Arg, Attr);
711  else if (ArgName == "FunctionArgument")
712    Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *");
713  else if (ArgName == "IdentifierArgument")
714    Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
715  else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr,
716                                                               "bool");
717  else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
718  else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
719  else if (ArgName == "TypeArgument")
720    Ptr = new SimpleArgument(Arg, Attr, "QualType");
721  else if (ArgName == "UnsignedArgument")
722    Ptr = new SimpleArgument(Arg, Attr, "unsigned");
723  else if (ArgName == "SourceLocArgument")
724    Ptr = new SimpleArgument(Arg, Attr, "SourceLocation");
725  else if (ArgName == "VariadicUnsignedArgument")
726    Ptr = new VariadicArgument(Arg, Attr, "unsigned");
727  else if (ArgName == "VariadicExprArgument")
728    Ptr = new VariadicExprArgument(Arg, Attr);
729  else if (ArgName == "VersionArgument")
730    Ptr = new VersionArgument(Arg, Attr);
731
732  if (!Ptr) {
733    std::vector<Record*> Bases = Search->getSuperClasses();
734    for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end();
735         i != e; ++i) {
736      Ptr = createArgument(Arg, Attr, *i);
737      if (Ptr)
738        break;
739    }
740  }
741  return Ptr;
742}
743
744static void writeAvailabilityValue(raw_ostream &OS) {
745  OS << "\" << getPlatform()->getName();\n"
746     << "  if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n"
747     << "  if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n"
748     << "  if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n"
749     << "  if (getUnavailable()) OS << \", unavailable\";\n"
750     << "  OS << \"";
751}
752
753static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args,
754                                     raw_ostream &OS) {
755  std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
756
757  OS << "void " << R.getName() << "Attr::printPretty("
758    << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n";
759
760  if (Spellings.size() == 0) {
761    OS << "}\n\n";
762    return;
763  }
764
765  OS <<
766    "  switch (SpellingListIndex) {\n"
767    "  default:\n"
768    "    llvm_unreachable(\"Unknown attribute spelling!\");\n"
769    "    break;\n";
770
771  for (unsigned I = 0; I < Spellings.size(); ++ I) {
772    llvm::SmallString<16> Prefix;
773    llvm::SmallString<8> Suffix;
774    // The actual spelling of the name and namespace (if applicable)
775    // of an attribute without considering prefix and suffix.
776    llvm::SmallString<64> Spelling;
777    std::string Name = Spellings[I]->getValueAsString("Name");
778    std::string Variety = Spellings[I]->getValueAsString("Variety");
779
780    if (Variety == "GNU") {
781      Prefix = " __attribute__((";
782      Suffix = "))";
783    } else if (Variety == "CXX11") {
784      Prefix = " [[";
785      Suffix = "]]";
786      std::string Namespace = Spellings[I]->getValueAsString("Namespace");
787      if (Namespace != "") {
788        Spelling += Namespace;
789        Spelling += "::";
790      }
791    } else if (Variety == "Declspec") {
792      Prefix = " __declspec(";
793      Suffix = ")";
794    } else if (Variety == "Keyword") {
795      Prefix = " ";
796      Suffix = "";
797    } else {
798      llvm_unreachable("Unknown attribute syntax variety!");
799    }
800
801    Spelling += Name;
802
803    OS <<
804      "  case " << I << " : {\n"
805      "    OS << \"" + Prefix.str() + Spelling.str();
806
807    if (Args.size()) OS << "(";
808    if (Spelling == "availability") {
809      writeAvailabilityValue(OS);
810    } else {
811      for (std::vector<Argument*>::const_iterator I = Args.begin(),
812           E = Args.end(); I != E; ++ I) {
813        if (I != Args.begin()) OS << ", ";
814        (*I)->writeValue(OS);
815      }
816    }
817
818    if (Args.size()) OS << ")";
819    OS << Suffix.str() + "\";\n";
820
821    OS <<
822      "    break;\n"
823      "  }\n";
824  }
825
826  // End of the switch statement.
827  OS << "}\n";
828  // End of the print function.
829  OS << "}\n\n";
830}
831
832/// \brief Return the index of a spelling in a spelling list.
833static unsigned getSpellingListIndex(const std::vector<Record*> &SpellingList,
834                                     const Record &Spelling) {
835  assert(SpellingList.size() && "Spelling list is empty!");
836
837  for (unsigned Index = 0; Index < SpellingList.size(); ++Index) {
838    Record *S = SpellingList[Index];
839    if (S->getValueAsString("Variety") != Spelling.getValueAsString("Variety"))
840      continue;
841    if (S->getValueAsString("Variety") == "CXX11" &&
842        S->getValueAsString("Namespace") !=
843        Spelling.getValueAsString("Namespace"))
844      continue;
845    if (S->getValueAsString("Name") != Spelling.getValueAsString("Name"))
846      continue;
847
848    return Index;
849  }
850
851  llvm_unreachable("Unknown spelling!");
852}
853
854static void writeAttrAccessorDefinition(Record &R, raw_ostream &OS) {
855  std::vector<Record*> Accessors = R.getValueAsListOfDefs("Accessors");
856  for (std::vector<Record*>::const_iterator I = Accessors.begin(),
857       E = Accessors.end(); I != E; ++I) {
858    Record *Accessor = *I;
859    std::string Name = Accessor->getValueAsString("Name");
860    std::vector<Record*> Spellings = Accessor->getValueAsListOfDefs(
861      "Spellings");
862    std::vector<Record*> SpellingList = R.getValueAsListOfDefs("Spellings");
863    assert(SpellingList.size() &&
864           "Attribute with empty spelling list can't have accessors!");
865
866    OS << "  bool " << Name << "() const { return SpellingListIndex == ";
867    for (unsigned Index = 0; Index < Spellings.size(); ++Index) {
868      OS << getSpellingListIndex(SpellingList, *Spellings[Index]);
869      if (Index != Spellings.size() -1)
870        OS << " ||\n    SpellingListIndex == ";
871      else
872        OS << "; }\n";
873    }
874  }
875}
876
877namespace clang {
878
879// Emits the class definitions for attributes.
880void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
881  emitSourceFileHeader("Attribute classes' definitions", OS);
882
883  OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
884  OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n";
885
886  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
887
888  for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
889       i != e; ++i) {
890    Record &R = **i;
891
892    if (!R.getValueAsBit("ASTNode"))
893      continue;
894
895    const std::string &SuperName = R.getSuperClasses().back()->getName();
896
897    OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n";
898
899    std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
900    std::vector<Argument*> Args;
901    std::vector<Argument*>::iterator ai, ae;
902    Args.reserve(ArgRecords.size());
903
904    for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
905                                        re = ArgRecords.end();
906         ri != re; ++ri) {
907      Record &ArgRecord = **ri;
908      Argument *Arg = createArgument(ArgRecord, R.getName());
909      assert(Arg);
910      Args.push_back(Arg);
911
912      Arg->writeDeclarations(OS);
913      OS << "\n\n";
914    }
915
916    ae = Args.end();
917
918    OS << "\n public:\n";
919    OS << "  " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n";
920
921    for (ai = Args.begin(); ai != ae; ++ai) {
922      OS << "              , ";
923      (*ai)->writeCtorParameters(OS);
924      OS << "\n";
925    }
926
927    OS << "              , ";
928    OS << "unsigned SI = 0\n";
929
930    OS << "             )\n";
931    OS << "    : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n";
932
933    for (ai = Args.begin(); ai != ae; ++ai) {
934      OS << "              , ";
935      (*ai)->writeCtorInitializers(OS);
936      OS << "\n";
937    }
938
939    OS << "  {\n";
940
941    for (ai = Args.begin(); ai != ae; ++ai) {
942      (*ai)->writeCtorBody(OS);
943      OS << "\n";
944    }
945    OS << "  }\n\n";
946
947    OS << "  virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n";
948    OS << "  virtual void printPretty(raw_ostream &OS,\n"
949       << "                           const PrintingPolicy &Policy) const;\n";
950
951    writeAttrAccessorDefinition(R, OS);
952
953    for (ai = Args.begin(); ai != ae; ++ai) {
954      (*ai)->writeAccessors(OS);
955      OS << "\n\n";
956    }
957
958    OS << R.getValueAsString("AdditionalMembers");
959    OS << "\n\n";
960
961    OS << "  static bool classof(const Attr *A) { return A->getKind() == "
962       << "attr::" << R.getName() << "; }\n";
963
964    bool LateParsed = R.getValueAsBit("LateParsed");
965    OS << "  virtual bool isLateParsed() const { return "
966       << LateParsed << "; }\n";
967
968    OS << "};\n\n";
969  }
970
971  OS << "#endif\n";
972}
973
974// Emits the class method definitions for attributes.
975void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
976  emitSourceFileHeader("Attribute classes' member function definitions", OS);
977
978  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
979  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re;
980  std::vector<Argument*>::iterator ai, ae;
981
982  for (; i != e; ++i) {
983    Record &R = **i;
984
985    if (!R.getValueAsBit("ASTNode"))
986      continue;
987
988    std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
989    std::vector<Argument*> Args;
990    for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri)
991      Args.push_back(createArgument(**ri, R.getName()));
992
993    for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
994      (*ai)->writeAccessorDefinitions(OS);
995
996    OS << R.getName() << "Attr *" << R.getName()
997       << "Attr::clone(ASTContext &C) const {\n";
998    OS << "  return new (C) " << R.getName() << "Attr(getLocation(), C";
999    for (ai = Args.begin(); ai != ae; ++ai) {
1000      OS << ", ";
1001      (*ai)->writeCloneArgs(OS);
1002    }
1003    OS << ", getSpellingListIndex());\n}\n\n";
1004
1005    writePrettyPrintFunction(R, Args, OS);
1006  }
1007}
1008
1009} // end namespace clang
1010
1011static void EmitAttrList(raw_ostream &OS, StringRef Class,
1012                         const std::vector<Record*> &AttrList) {
1013  std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end();
1014
1015  if (i != e) {
1016    // Move the end iterator back to emit the last attribute.
1017    for(--e; i != e; ++i) {
1018      if (!(*i)->getValueAsBit("ASTNode"))
1019        continue;
1020
1021      OS << Class << "(" << (*i)->getName() << ")\n";
1022    }
1023
1024    OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n";
1025  }
1026}
1027
1028namespace clang {
1029
1030// Emits the enumeration list for attributes.
1031void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
1032  emitSourceFileHeader("List of all attributes that Clang recognizes", OS);
1033
1034  OS << "#ifndef LAST_ATTR\n";
1035  OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n";
1036  OS << "#endif\n\n";
1037
1038  OS << "#ifndef INHERITABLE_ATTR\n";
1039  OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n";
1040  OS << "#endif\n\n";
1041
1042  OS << "#ifndef LAST_INHERITABLE_ATTR\n";
1043  OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
1044  OS << "#endif\n\n";
1045
1046  OS << "#ifndef INHERITABLE_PARAM_ATTR\n";
1047  OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n";
1048  OS << "#endif\n\n";
1049
1050  OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n";
1051  OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)"
1052        " INHERITABLE_PARAM_ATTR(NAME)\n";
1053  OS << "#endif\n\n";
1054
1055  Record *InhClass = Records.getClass("InheritableAttr");
1056  Record *InhParamClass = Records.getClass("InheritableParamAttr");
1057  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
1058                       NonInhAttrs, InhAttrs, InhParamAttrs;
1059  for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
1060       i != e; ++i) {
1061    if (!(*i)->getValueAsBit("ASTNode"))
1062      continue;
1063
1064    if ((*i)->isSubClassOf(InhParamClass))
1065      InhParamAttrs.push_back(*i);
1066    else if ((*i)->isSubClassOf(InhClass))
1067      InhAttrs.push_back(*i);
1068    else
1069      NonInhAttrs.push_back(*i);
1070  }
1071
1072  EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
1073  EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
1074  EmitAttrList(OS, "ATTR", NonInhAttrs);
1075
1076  OS << "#undef LAST_ATTR\n";
1077  OS << "#undef INHERITABLE_ATTR\n";
1078  OS << "#undef LAST_INHERITABLE_ATTR\n";
1079  OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
1080  OS << "#undef ATTR\n";
1081}
1082
1083// Emits the code to read an attribute from a precompiled header.
1084void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
1085  emitSourceFileHeader("Attribute deserialization code", OS);
1086
1087  Record *InhClass = Records.getClass("InheritableAttr");
1088  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
1089                       ArgRecords;
1090  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
1091  std::vector<Argument*> Args;
1092  std::vector<Argument*>::iterator ri, re;
1093
1094  OS << "  switch (Kind) {\n";
1095  OS << "  default:\n";
1096  OS << "    assert(0 && \"Unknown attribute!\");\n";
1097  OS << "    break;\n";
1098  for (; i != e; ++i) {
1099    Record &R = **i;
1100    if (!R.getValueAsBit("ASTNode"))
1101      continue;
1102
1103    OS << "  case attr::" << R.getName() << ": {\n";
1104    if (R.isSubClassOf(InhClass))
1105      OS << "    bool isInherited = Record[Idx++];\n";
1106    ArgRecords = R.getValueAsListOfDefs("Args");
1107    Args.clear();
1108    for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) {
1109      Argument *A = createArgument(**ai, R.getName());
1110      Args.push_back(A);
1111      A->writePCHReadDecls(OS);
1112    }
1113    OS << "    New = new (Context) " << R.getName() << "Attr(Range, Context";
1114    for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) {
1115      OS << ", ";
1116      (*ri)->writePCHReadArgs(OS);
1117    }
1118    OS << ");\n";
1119    if (R.isSubClassOf(InhClass))
1120      OS << "    cast<InheritableAttr>(New)->setInherited(isInherited);\n";
1121    OS << "    break;\n";
1122    OS << "  }\n";
1123  }
1124  OS << "  }\n";
1125}
1126
1127// Emits the code to write an attribute to a precompiled header.
1128void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
1129  emitSourceFileHeader("Attribute serialization code", OS);
1130
1131  Record *InhClass = Records.getClass("InheritableAttr");
1132  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
1133  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
1134
1135  OS << "  switch (A->getKind()) {\n";
1136  OS << "  default:\n";
1137  OS << "    llvm_unreachable(\"Unknown attribute kind!\");\n";
1138  OS << "    break;\n";
1139  for (; i != e; ++i) {
1140    Record &R = **i;
1141    if (!R.getValueAsBit("ASTNode"))
1142      continue;
1143    OS << "  case attr::" << R.getName() << ": {\n";
1144    Args = R.getValueAsListOfDefs("Args");
1145    if (R.isSubClassOf(InhClass) || !Args.empty())
1146      OS << "    const " << R.getName() << "Attr *SA = cast<" << R.getName()
1147         << "Attr>(A);\n";
1148    if (R.isSubClassOf(InhClass))
1149      OS << "    Record.push_back(SA->isInherited());\n";
1150    for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
1151      createArgument(**ai, R.getName())->writePCHWrite(OS);
1152    OS << "    break;\n";
1153    OS << "  }\n";
1154  }
1155  OS << "  }\n";
1156}
1157
1158// Emits the list of spellings for attributes.
1159void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) {
1160  emitSourceFileHeader("llvm::StringSwitch code to match all known attributes",
1161                       OS);
1162
1163  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1164
1165  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
1166    Record &Attr = **I;
1167
1168    std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1169
1170    for (std::vector<Record*>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) {
1171      OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", true)\n";
1172    }
1173  }
1174
1175}
1176
1177void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) {
1178  emitSourceFileHeader("Code to translate different attribute spellings "
1179                       "into internal identifiers", OS);
1180
1181  OS <<
1182    "  unsigned Index = 0;\n"
1183    "  switch (AttrKind) {\n"
1184    "  default:\n"
1185    "    llvm_unreachable(\"Unknown attribute kind!\");\n"
1186    "    break;\n";
1187
1188  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1189  for (std::vector<Record*>::const_iterator I = Attrs.begin(), E = Attrs.end();
1190       I != E; ++I) {
1191    Record &R = **I;
1192    // We only care about attributes that participate in Sema checking, so
1193    // skip those attributes that are not able to make their way to Sema.
1194    if (!R.getValueAsBit("SemaHandler"))
1195      continue;
1196
1197    std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
1198    // Each distinct spelling yields an attribute kind.
1199    if (R.getValueAsBit("DistinctSpellings")) {
1200      for (unsigned I = 0; I < Spellings.size(); ++ I) {
1201        OS <<
1202          "  case AT_" << Spellings[I]->getValueAsString("Name") << ": \n"
1203          "    Index = " << I << ";\n"
1204          "  break;\n";
1205      }
1206    } else {
1207      OS << "  case AT_" << R.getName() << " : {\n";
1208      for (unsigned I = 0; I < Spellings.size(); ++ I) {
1209        SmallString<16> Namespace;
1210        if (Spellings[I]->getValueAsString("Variety") == "CXX11")
1211          Namespace = Spellings[I]->getValueAsString("Namespace");
1212        else
1213          Namespace = "";
1214
1215        OS << "    if (Name == \""
1216          << Spellings[I]->getValueAsString("Name") << "\" && "
1217          << "SyntaxUsed == "
1218          << StringSwitch<unsigned>(Spellings[I]->getValueAsString("Variety"))
1219            .Case("GNU", 0)
1220            .Case("CXX11", 1)
1221            .Case("Declspec", 2)
1222            .Case("Keyword", 3)
1223            .Default(0)
1224          << " && Scope == \"" << Namespace << "\")\n"
1225          << "        return " << I << ";\n";
1226      }
1227
1228      OS << "    break;\n";
1229      OS << "  }\n";
1230    }
1231  }
1232
1233  OS << "  }\n";
1234  OS << "  return Index;\n";
1235}
1236
1237// Emits the LateParsed property for attributes.
1238void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) {
1239  emitSourceFileHeader("llvm::StringSwitch code to match late parsed "
1240                       "attributes", OS);
1241
1242  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1243
1244  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1245       I != E; ++I) {
1246    Record &Attr = **I;
1247
1248    bool LateParsed = Attr.getValueAsBit("LateParsed");
1249
1250    if (LateParsed) {
1251      std::vector<Record*> Spellings =
1252        Attr.getValueAsListOfDefs("Spellings");
1253
1254      // FIXME: Handle non-GNU attributes
1255      for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1256           E = Spellings.end(); I != E; ++I) {
1257        if ((*I)->getValueAsString("Variety") != "GNU")
1258          continue;
1259        OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", "
1260           << LateParsed << ")\n";
1261      }
1262    }
1263  }
1264}
1265
1266// Emits code to instantiate dependent attributes on templates.
1267void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) {
1268  emitSourceFileHeader("Template instantiation code for attributes", OS);
1269
1270  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1271
1272  OS << "namespace clang {\n"
1273     << "namespace sema {\n\n"
1274     << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
1275     << "Sema &S,\n"
1276     << "        const MultiLevelTemplateArgumentList &TemplateArgs) {\n"
1277     << "  switch (At->getKind()) {\n"
1278     << "    default:\n"
1279     << "      break;\n";
1280
1281  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1282       I != E; ++I) {
1283    Record &R = **I;
1284    if (!R.getValueAsBit("ASTNode"))
1285      continue;
1286
1287    OS << "    case attr::" << R.getName() << ": {\n";
1288    bool ShouldClone = R.getValueAsBit("Clone");
1289
1290    if (!ShouldClone) {
1291      OS << "      return NULL;\n";
1292      OS << "    }\n";
1293      continue;
1294    }
1295
1296    OS << "      const " << R.getName() << "Attr *A = cast<"
1297       << R.getName() << "Attr>(At);\n";
1298    bool TDependent = R.getValueAsBit("TemplateDependent");
1299
1300    if (!TDependent) {
1301      OS << "      return A->clone(C);\n";
1302      OS << "    }\n";
1303      continue;
1304    }
1305
1306    std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
1307    std::vector<Argument*> Args;
1308    std::vector<Argument*>::iterator ai, ae;
1309    Args.reserve(ArgRecords.size());
1310
1311    for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
1312                                        re = ArgRecords.end();
1313         ri != re; ++ri) {
1314      Record &ArgRecord = **ri;
1315      Argument *Arg = createArgument(ArgRecord, R.getName());
1316      assert(Arg);
1317      Args.push_back(Arg);
1318    }
1319    ae = Args.end();
1320
1321    for (ai = Args.begin(); ai != ae; ++ai) {
1322      (*ai)->writeTemplateInstantiation(OS);
1323    }
1324    OS << "      return new (C) " << R.getName() << "Attr(A->getLocation(), C";
1325    for (ai = Args.begin(); ai != ae; ++ai) {
1326      OS << ", ";
1327      (*ai)->writeTemplateInstantiationArgs(OS);
1328    }
1329    OS << ");\n    }\n";
1330  }
1331  OS << "  } // end switch\n"
1332     << "  llvm_unreachable(\"Unknown attribute!\");\n"
1333     << "  return 0;\n"
1334     << "}\n\n"
1335     << "} // end namespace sema\n"
1336     << "} // end namespace clang\n";
1337}
1338
1339// Emits the list of parsed attributes.
1340void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) {
1341  emitSourceFileHeader("List of all attributes that Clang recognizes", OS);
1342
1343  OS << "#ifndef PARSED_ATTR\n";
1344  OS << "#define PARSED_ATTR(NAME) NAME\n";
1345  OS << "#endif\n\n";
1346
1347  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1348
1349  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1350       I != E; ++I) {
1351    Record &Attr = **I;
1352
1353    bool SemaHandler = Attr.getValueAsBit("SemaHandler");
1354    bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings");
1355
1356    if (SemaHandler) {
1357      if (DistinctSpellings) {
1358        std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1359
1360        for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1361             E = Spellings.end(); I != E; ++I) {
1362          std::string AttrName = (*I)->getValueAsString("Name");
1363
1364          StringRef Spelling = NormalizeAttrName(AttrName);
1365
1366          OS << "PARSED_ATTR(" << Spelling << ")\n";
1367        }
1368      } else {
1369        StringRef AttrName = Attr.getName();
1370        AttrName = NormalizeAttrName(AttrName);
1371        OS << "PARSED_ATTR(" << AttrName << ")\n";
1372      }
1373    }
1374  }
1375}
1376
1377// Emits the kind list of parsed attributes
1378void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
1379  emitSourceFileHeader("Attribute name matcher", OS);
1380
1381  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
1382
1383  std::vector<StringMatcher::StringPair> Matches;
1384  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1385       I != E; ++I) {
1386    Record &Attr = **I;
1387
1388    bool SemaHandler = Attr.getValueAsBit("SemaHandler");
1389    bool Ignored = Attr.getValueAsBit("Ignored");
1390    bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings");
1391    if (SemaHandler || Ignored) {
1392      std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
1393
1394      for (std::vector<Record*>::const_iterator I = Spellings.begin(),
1395           E = Spellings.end(); I != E; ++I) {
1396        std::string RawSpelling = (*I)->getValueAsString("Name");
1397        StringRef AttrName = NormalizeAttrName(DistinctSpellings
1398                                                 ? StringRef(RawSpelling)
1399                                                 : StringRef(Attr.getName()));
1400
1401        SmallString<64> Spelling;
1402        if ((*I)->getValueAsString("Variety") == "CXX11") {
1403          Spelling += (*I)->getValueAsString("Namespace");
1404          Spelling += "::";
1405        }
1406        Spelling += NormalizeAttrSpelling(RawSpelling);
1407
1408        if (SemaHandler)
1409          Matches.push_back(
1410            StringMatcher::StringPair(
1411              StringRef(Spelling),
1412              "return AttributeList::AT_" + AttrName.str() + ";"));
1413        else
1414          Matches.push_back(
1415            StringMatcher::StringPair(
1416              StringRef(Spelling),
1417              "return AttributeList::IgnoredAttribute;"));
1418      }
1419    }
1420  }
1421
1422  OS << "static AttributeList::Kind getAttrKind(StringRef Name) {\n";
1423  StringMatcher("Name", Matches, OS).Emit();
1424  OS << "return AttributeList::UnknownAttribute;\n"
1425     << "}\n";
1426}
1427
1428// Emits the code to dump an attribute.
1429void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) {
1430  emitSourceFileHeader("Attribute dumper", OS);
1431
1432  OS <<
1433    "  switch (A->getKind()) {\n"
1434    "  default:\n"
1435    "    llvm_unreachable(\"Unknown attribute kind!\");\n"
1436    "    break;\n";
1437  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
1438  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
1439       I != E; ++I) {
1440    Record &R = **I;
1441    if (!R.getValueAsBit("ASTNode"))
1442      continue;
1443    OS << "  case attr::" << R.getName() << ": {\n";
1444    Args = R.getValueAsListOfDefs("Args");
1445    if (!Args.empty()) {
1446      OS << "    const " << R.getName() << "Attr *SA = cast<" << R.getName()
1447         << "Attr>(A);\n";
1448      for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end();
1449           I != E; ++I)
1450        createArgument(**I, R.getName())->writeDump(OS);
1451
1452      // Code for detecting the last child.
1453      OS << "    bool OldMoreChildren = hasMoreChildren();\n";
1454      OS << "    bool MoreChildren = OldMoreChildren;\n";
1455
1456      for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end();
1457           I != E; ++I) {
1458        // More code for detecting the last child.
1459        OS << "    MoreChildren = OldMoreChildren";
1460        for (std::vector<Record*>::iterator Next = I + 1; Next != E; ++Next) {
1461          OS << " || ";
1462          createArgument(**Next, R.getName())->writeHasChildren(OS);
1463        }
1464        OS << ";\n";
1465        OS << "    setMoreChildren(MoreChildren);\n";
1466
1467        createArgument(**I, R.getName())->writeDumpChildren(OS);
1468      }
1469
1470      // Reset the last child.
1471      OS << "    setMoreChildren(OldMoreChildren);\n";
1472    }
1473    OS <<
1474      "    break;\n"
1475      "  }\n";
1476  }
1477  OS << "  }\n";
1478}
1479
1480} // end namespace clang
1481