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