ClangAttrEmitter.cpp revision 93f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6
151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===- ClangAttrEmitter.cpp - Generate Clang attribute handling =-*- C++ -*--=// 251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// The LLVM Compiler Infrastructure 451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// This file is distributed under the University of Illinois Open Source 651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// License. See LICENSE.TXT for details. 751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 1051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// These tablegen backends emit Clang attribute processing code 1151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 1251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 1351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 1493f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt#include "llvm/ADT/SmallString.h" 1551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include "llvm/ADT/StringSwitch.h" 1651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include "llvm/TableGen/Record.h" 170c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor#include "llvm/TableGen/StringMatcher.h" 183cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h" 1951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include <algorithm> 2051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include <cctype> 21e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han#include <set> 2251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourneusing namespace llvm; 2451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic const std::vector<StringRef> 2651d7777a21b9706d503496c650af06f80d278c1aPeter CollingbournegetValueAsListOfStrings(Record &R, StringRef FieldName) { 2751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ListInit *List = R.getValueAsListInit(FieldName); 2851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne assert (List && "Got a null ListInit"); 2951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 3051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<StringRef> Strings; 3151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Strings.reserve(List->getSize()); 3251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 3351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (ListInit::const_iterator i = List->begin(), e = List->end(); 3451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne i != e; 3551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ++i) { 3651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne assert(*i && "Got a null element in a ListInit"); 3751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (StringInit *S = dynamic_cast<StringInit *>(*i)) 3851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Strings.push_back(S->getValue()); 3951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 4051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne assert(false && "Got a non-string, non-code element in a ListInit"); 4151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 4251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 4351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return Strings; 4451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 4551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 4651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string ReadPCHRecord(StringRef type) { 4751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return StringSwitch<std::string>(type) 4851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne .EndsWith("Decl *", "GetLocalDeclAs<" 4951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne + std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])") 5051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne .Case("QualType", "getLocalType(F, Record[Idx++])") 5151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne .Case("Expr *", "ReadSubExpr()") 5251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)") 5351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne .Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)") 5451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne .Default("Record[Idx++]"); 5551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 5651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 5751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Assumes that the way to get the value is SA->getname() 5851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string WritePCHRecord(StringRef type, StringRef name) { 5951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return StringSwitch<std::string>(type) 6051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne .EndsWith("Decl *", "AddDeclRef(" + std::string(name) + 6151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ", Record);\n") 6251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne .Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n") 6351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne .Case("Expr *", "AddStmt(" + std::string(name) + ");\n") 6451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne .Case("IdentifierInfo *", 6551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "AddIdentifierRef(" + std::string(name) + ", Record);\n") 6651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne .Case("SourceLocation", 6751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "AddSourceLocation(" + std::string(name) + ", Record);\n") 6851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne .Default("Record.push_back(" + std::string(name) + ");\n"); 6951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 7051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 71e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han// Normalize attribute name by removing leading and trailing 72e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han// underscores. For example, __foo, foo__, __foo__ would 73e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han// become foo. 74e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Hanstatic StringRef NormalizeAttrName(StringRef AttrName) { 75e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han if (AttrName.startswith("__")) 76e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han AttrName = AttrName.substr(2, AttrName.size()); 77e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 78e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han if (AttrName.endswith("__")) 79e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han AttrName = AttrName.substr(0, AttrName.size() - 2); 80e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 81e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han return AttrName; 82e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han} 83e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 84e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han// Normalize attribute spelling only if the spelling has both leading 85e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han// and trailing underscores. For example, __ms_struct__ will be 86e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han// normalized to "ms_struct"; __cdecl will remain intact. 87e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Hanstatic StringRef NormalizeAttrSpelling(StringRef AttrSpelling) { 88e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han if (AttrSpelling.startswith("__") && AttrSpelling.endswith("__")) { 89e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han AttrSpelling = AttrSpelling.substr(2, AttrSpelling.size() - 4); 90e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han } 91e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 92e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han return AttrSpelling; 93e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han} 94e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 9551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournenamespace { 9651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne class Argument { 9751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string lowerName, upperName; 9851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringRef attrName; 9951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 10051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne public: 10151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Argument(Record &Arg, StringRef Attr) 10251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne : lowerName(Arg.getValueAsString("Name")), upperName(lowerName), 10351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne attrName(Attr) { 10451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!lowerName.empty()) { 10551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne lowerName[0] = std::tolower(lowerName[0]); 10651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne upperName[0] = std::toupper(upperName[0]); 10751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 10851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 10951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne virtual ~Argument() {} 11051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 11151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringRef getLowerName() const { return lowerName; } 11251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringRef getUpperName() const { return upperName; } 11351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringRef getAttrName() const { return attrName; } 11451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 11551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // These functions print the argument contents formatted in different ways. 11651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne virtual void writeAccessors(raw_ostream &OS) const = 0; 11751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne virtual void writeAccessorDefinitions(raw_ostream &OS) const {} 11851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne virtual void writeCloneArgs(raw_ostream &OS) const = 0; 1197b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0; 120b880609697b3db5ae3df77387532f8b0cec89274Daniel Dunbar virtual void writeTemplateInstantiation(raw_ostream &OS) const {} 12151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne virtual void writeCtorBody(raw_ostream &OS) const {} 12251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne virtual void writeCtorInitializers(raw_ostream &OS) const = 0; 12351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne virtual void writeCtorParameters(raw_ostream &OS) const = 0; 12451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne virtual void writeDeclarations(raw_ostream &OS) const = 0; 12551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne virtual void writePCHReadArgs(raw_ostream &OS) const = 0; 12651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne virtual void writePCHReadDecls(raw_ostream &OS) const = 0; 12751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne virtual void writePCHWrite(raw_ostream &OS) const = 0; 1281bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor virtual void writeValue(raw_ostream &OS) const = 0; 12951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne }; 13051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 13151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne class SimpleArgument : public Argument { 13251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string type; 13351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 13451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne public: 13551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SimpleArgument(Record &Arg, StringRef Attr, std::string T) 13651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne : Argument(Arg, Attr), type(T) 13751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne {} 13851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 1397b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins std::string getType() const { return type; } 1407b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 14151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeAccessors(raw_ostream &OS) const { 14251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << type << " get" << getUpperName() << "() const {\n"; 14351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return " << getLowerName() << ";\n"; 14451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }"; 14551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 14651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCloneArgs(raw_ostream &OS) const { 14751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getLowerName(); 14851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 1497b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins void writeTemplateInstantiationArgs(raw_ostream &OS) const { 1507b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << "A->get" << getUpperName() << "()"; 1517b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 15251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorInitializers(raw_ostream &OS) const { 15351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getLowerName() << "(" << getUpperName() << ")"; 15451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 15551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorParameters(raw_ostream &OS) const { 15651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << type << " " << getUpperName(); 15751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 15851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeDeclarations(raw_ostream &OS) const { 15951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << type << " " << getLowerName() << ";"; 16051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 16151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHReadDecls(raw_ostream &OS) const { 16251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string read = ReadPCHRecord(type); 16351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << type << " " << getLowerName() << " = " << read << ";\n"; 16451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 16551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHReadArgs(raw_ostream &OS) const { 16651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getLowerName(); 16751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 16851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHWrite(raw_ostream &OS) const { 16951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << WritePCHRecord(type, "SA->get" + 17051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string(getUpperName()) + "()"); 17151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 1721bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor void writeValue(raw_ostream &OS) const { 1731bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor if (type == "FunctionDecl *") { 1741bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << "\" << get" << getUpperName() << "()->getNameInfo().getAsString() << \""; 1751bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } else if (type == "IdentifierInfo *") { 1761bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << "\" << get" << getUpperName() << "()->getName() << \""; 1771bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } else if (type == "QualType") { 1781bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << "\" << get" << getUpperName() << "().getAsString() << \""; 1791bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } else if (type == "SourceLocation") { 1801bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << "\" << get" << getUpperName() << "().getRawEncoding() << \""; 1811bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } else { 1821bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << "\" << get" << getUpperName() << "() << \""; 1831bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } 1841bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } 18551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne }; 18651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 18751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne class StringArgument : public Argument { 18851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne public: 18951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringArgument(Record &Arg, StringRef Attr) 19051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne : Argument(Arg, Attr) 19151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne {} 19251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 19351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeAccessors(raw_ostream &OS) const { 19451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " llvm::StringRef get" << getUpperName() << "() const {\n"; 19551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return llvm::StringRef(" << getLowerName() << ", " 19651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << getLowerName() << "Length);\n"; 19751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }\n"; 19851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " unsigned get" << getUpperName() << "Length() const {\n"; 19951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return " << getLowerName() << "Length;\n"; 20051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }\n"; 20151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " void set" << getUpperName() 20251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "(ASTContext &C, llvm::StringRef S) {\n"; 20351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << getLowerName() << "Length = S.size();\n"; 20451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " this->" << getLowerName() << " = new (C, 1) char [" 20551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << getLowerName() << "Length];\n"; 20651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " std::memcpy(this->" << getLowerName() << ", S.data(), " 20751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << getLowerName() << "Length);\n"; 20851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }"; 20951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 21051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCloneArgs(raw_ostream &OS) const { 21151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "get" << getUpperName() << "()"; 21251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 2137b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins void writeTemplateInstantiationArgs(raw_ostream &OS) const { 2147b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << "A->get" << getUpperName() << "()"; 2157b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 21651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorBody(raw_ostream &OS) const { 21751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " std::memcpy(" << getLowerName() << ", " << getUpperName() 21851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << ".data(), " << getLowerName() << "Length);"; 21951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 22051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorInitializers(raw_ostream &OS) const { 22151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getLowerName() << "Length(" << getUpperName() << ".size())," 22251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << getLowerName() << "(new (Ctx, 1) char[" << getLowerName() 22351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Length])"; 22451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 22551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorParameters(raw_ostream &OS) const { 22651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "llvm::StringRef " << getUpperName(); 22751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 22851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeDeclarations(raw_ostream &OS) const { 22951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "unsigned " << getLowerName() << "Length;\n"; 23051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "char *" << getLowerName() << ";"; 23151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 23251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHReadDecls(raw_ostream &OS) const { 23351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " std::string " << getLowerName() 23451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "= ReadString(Record, Idx);\n"; 23551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 23651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHReadArgs(raw_ostream &OS) const { 23751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getLowerName(); 23851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 23951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHWrite(raw_ostream &OS) const { 24051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " AddString(SA->get" << getUpperName() << "(), Record);\n"; 24151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 2421bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor void writeValue(raw_ostream &OS) const { 2431bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << "\\\"\" << get" << getUpperName() << "() << \"\\\""; 2441bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } 24551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne }; 24651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 24751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne class AlignedArgument : public Argument { 24851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne public: 24951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne AlignedArgument(Record &Arg, StringRef Attr) 25051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne : Argument(Arg, Attr) 25151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne {} 25251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 25351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeAccessors(raw_ostream &OS) const { 25451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " bool is" << getUpperName() << "Dependent() const;\n"; 25551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 25651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n"; 25751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 25851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " bool is" << getUpperName() << "Expr() const {\n"; 25951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return is" << getLowerName() << "Expr;\n"; 26051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }\n"; 26151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 26251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " Expr *get" << getUpperName() << "Expr() const {\n"; 26351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " assert(is" << getLowerName() << "Expr);\n"; 26451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return " << getLowerName() << "Expr;\n"; 26551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }\n"; 26651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 26751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " TypeSourceInfo *get" << getUpperName() << "Type() const {\n"; 26851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " assert(!is" << getLowerName() << "Expr);\n"; 26951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return " << getLowerName() << "Type;\n"; 27051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }"; 27151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 27251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeAccessorDefinitions(raw_ostream &OS) const { 27351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "bool " << getAttrName() << "Attr::is" << getUpperName() 27451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Dependent() const {\n"; 27551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " if (is" << getLowerName() << "Expr)\n"; 27651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return " << getLowerName() << "Expr && (" << getLowerName() 27751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Expr->isValueDependent() || " << getLowerName() 27851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Expr->isTypeDependent());\n"; 27951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " else\n"; 28051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return " << getLowerName() 28151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Type->getType()->isDependentType();\n"; 28251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "}\n"; 28351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 28451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // FIXME: Do not do the calculation here 28551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // FIXME: Handle types correctly 28651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // A null pointer means maximum alignment 28751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // FIXME: Load the platform-specific maximum alignment, rather than 28851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // 16, the x86 max. 28951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName() 29051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "(ASTContext &Ctx) const {\n"; 29151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " assert(!is" << getUpperName() << "Dependent());\n"; 29251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " if (is" << getLowerName() << "Expr)\n"; 29351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return (" << getLowerName() << "Expr ? " << getLowerName() 294a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith << "Expr->EvaluateKnownConstInt(Ctx).getZExtValue() : 16)" 29551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "* Ctx.getCharWidth();\n"; 29651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " else\n"; 29751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return 0; // FIXME\n"; 29851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "}\n"; 29951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 30051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCloneArgs(raw_ostream &OS) const { 30151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "is" << getLowerName() << "Expr, is" << getLowerName() 30251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Expr ? static_cast<void*>(" << getLowerName() 30351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Expr) : " << getLowerName() 30451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Type"; 30551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 3067b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins void writeTemplateInstantiationArgs(raw_ostream &OS) const { 3077b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins // FIXME: move the definition in Sema::InstantiateAttrs to here. 3087b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins // In the meantime, aligned attributes are cloned. 3097b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 31051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorBody(raw_ostream &OS) const { 31151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " if (is" << getLowerName() << "Expr)\n"; 31251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << getLowerName() << "Expr = reinterpret_cast<Expr *>(" 31351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << getUpperName() << ");\n"; 31451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " else\n"; 31551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << getLowerName() 31651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName() 31751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << ");"; 31851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 31951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorInitializers(raw_ostream &OS) const { 32051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)"; 32151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 32251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorParameters(raw_ostream &OS) const { 32351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName(); 32451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 32551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeDeclarations(raw_ostream &OS) const { 32651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "bool is" << getLowerName() << "Expr;\n"; 32751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "union {\n"; 32851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "Expr *" << getLowerName() << "Expr;\n"; 32951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "TypeSourceInfo *" << getLowerName() << "Type;\n"; 33051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "};"; 33151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 33251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHReadArgs(raw_ostream &OS) const { 33351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr"; 33451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 33551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHReadDecls(raw_ostream &OS) const { 33651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " bool is" << getLowerName() << "Expr = Record[Idx++];\n"; 33751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " void *" << getLowerName() << "Ptr;\n"; 33851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " if (is" << getLowerName() << "Expr)\n"; 33951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << getLowerName() << "Ptr = ReadExpr(F);\n"; 34051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " else\n"; 34151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << getLowerName() 34251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n"; 34351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 34451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHWrite(raw_ostream &OS) const { 34551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n"; 34651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " if (SA->is" << getUpperName() << "Expr())\n"; 34751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " AddStmt(SA->get" << getUpperName() << "Expr());\n"; 34851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " else\n"; 34951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " AddTypeSourceInfo(SA->get" << getUpperName() 35051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Type(), Record);\n"; 35151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 3521bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor void writeValue(raw_ostream &OS) const { 3531bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << "\" << get" << getUpperName() << "(Ctx) << \""; 3541bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } 35551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne }; 35651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 35751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne class VariadicArgument : public Argument { 35851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string type; 35951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 36051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne public: 36151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne VariadicArgument(Record &Arg, StringRef Attr, std::string T) 36251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne : Argument(Arg, Attr), type(T) 36351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne {} 36451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 36551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string getType() const { return type; } 36651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 36751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeAccessors(raw_ostream &OS) const { 36851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " typedef " << type << "* " << getLowerName() << "_iterator;\n"; 36951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << getLowerName() << "_iterator " << getLowerName() 37051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "_begin() const {\n"; 37151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return " << getLowerName() << ";\n"; 37251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }\n"; 37351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << getLowerName() << "_iterator " << getLowerName() 37451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "_end() const {\n"; 37551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return " << getLowerName() << " + " << getLowerName() 37651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Size;\n"; 37751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }\n"; 37851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " unsigned " << getLowerName() << "_size() const {\n" 37923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins << " return " << getLowerName() << "Size;\n"; 38051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }"; 38151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 38251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCloneArgs(raw_ostream &OS) const { 38351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getLowerName() << ", " << getLowerName() << "Size"; 38451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 3857b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins void writeTemplateInstantiationArgs(raw_ostream &OS) const { 3867b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins // This isn't elegant, but we have to go through public methods... 3877b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << "A->" << getLowerName() << "_begin(), " 3887b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << "A->" << getLowerName() << "_size()"; 3897b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 39051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorBody(raw_ostream &OS) const { 39151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // FIXME: memcpy is not safe on non-trivial types. 39251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " std::memcpy(" << getLowerName() << ", " << getUpperName() 39351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n"; 39451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 39551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorInitializers(raw_ostream &OS) const { 39651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getLowerName() << "Size(" << getUpperName() << "Size), " 39751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << getLowerName() << "(new (Ctx, 16) " << getType() << "[" 39851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << getLowerName() << "Size])"; 39951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 40051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorParameters(raw_ostream &OS) const { 40151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getType() << " *" << getUpperName() << ", unsigned " 40251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << getUpperName() << "Size"; 40351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 40451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeDeclarations(raw_ostream &OS) const { 40551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " unsigned " << getLowerName() << "Size;\n"; 40651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << getType() << " *" << getLowerName() << ";"; 40751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 40851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHReadDecls(raw_ostream &OS) const { 40951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n"; 41051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " llvm::SmallVector<" << type << ", 4> " << getLowerName() 41151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << ";\n"; 41251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << getLowerName() << ".reserve(" << getLowerName() 41351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Size);\n"; 41451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n"; 41551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 41651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string read = ReadPCHRecord(type); 41751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << getLowerName() << ".push_back(" << read << ");\n"; 41851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 41951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHReadArgs(raw_ostream &OS) const { 42051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getLowerName() << ".data(), " << getLowerName() << "Size"; 42151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 42251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHWrite(raw_ostream &OS) const{ 42351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " Record.push_back(SA->" << getLowerName() << "_size());\n"; 42451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " for (" << getAttrName() << "Attr::" << getLowerName() 42551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->" 42651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << getLowerName() << "_end(); i != e; ++i)\n"; 42751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << WritePCHRecord(type, "(*i)"); 42851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 4291bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor void writeValue(raw_ostream &OS) const { 4301bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << "\";\n"; 4311bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << " bool isFirst = true;\n" 4321bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor << " for (" << getAttrName() << "Attr::" << getLowerName() 4331bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor << "_iterator i = " << getLowerName() << "_begin(), e = " 4341bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor << getLowerName() << "_end(); i != e; ++i) {\n" 4351bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor << " if (isFirst) isFirst = false;\n" 4361bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor << " else OS << \", \";\n" 4371bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor << " OS << *i;\n" 4381bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor << " }\n"; 4391bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << " OS << \""; 4401bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } 44151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne }; 44251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 44351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne class EnumArgument : public Argument { 44451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string type; 44551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<StringRef> values, enums; 44651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne public: 44751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne EnumArgument(Record &Arg, StringRef Attr) 44851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne : Argument(Arg, Attr), type(Arg.getValueAsString("Type")), 44951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne values(getValueAsListOfStrings(Arg, "Values")), 45051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne enums(getValueAsListOfStrings(Arg, "Enums")) 45151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne {} 45251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 45351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeAccessors(raw_ostream &OS) const { 45451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << type << " get" << getUpperName() << "() const {\n"; 45551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return " << getLowerName() << ";\n"; 45651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }"; 45751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 45851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCloneArgs(raw_ostream &OS) const { 45951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getLowerName(); 46051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 4617b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins void writeTemplateInstantiationArgs(raw_ostream &OS) const { 4627b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << "A->get" << getUpperName() << "()"; 4637b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 46451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorInitializers(raw_ostream &OS) const { 46551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getLowerName() << "(" << getUpperName() << ")"; 46651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 46751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorParameters(raw_ostream &OS) const { 46851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << type << " " << getUpperName(); 46951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 47051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeDeclarations(raw_ostream &OS) const { 47151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Calculate the various enum values 47251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<StringRef> uniques(enums); 47351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::sort(uniques.begin(), uniques.end()); 47451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne uniques.erase(std::unique(uniques.begin(), uniques.end()), 47551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne uniques.end()); 47651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // FIXME: Emit a proper error 47751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne assert(!uniques.empty()); 47851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 47951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<StringRef>::iterator i = uniques.begin(), 48051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne e = uniques.end(); 48151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // The last one needs to not have a comma. 48251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne --e; 48351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 48451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "public:\n"; 48551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " enum " << type << " {\n"; 48651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (; i != e; ++i) 48751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << *i << ",\n"; 48851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << *e << "\n"; 48951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " };\n"; 49051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "private:\n"; 49151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << type << " " << getLowerName() << ";"; 49251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 49351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHReadDecls(raw_ostream &OS) const { 49451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << getAttrName() << "Attr::" << type << " " << getLowerName() 49551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "(static_cast<" << getAttrName() << "Attr::" << type 49651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << ">(Record[Idx++]));\n"; 49751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 49851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHReadArgs(raw_ostream &OS) const { 49951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getLowerName(); 50051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 50151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHWrite(raw_ostream &OS) const { 50251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "Record.push_back(SA->get" << getUpperName() << "());\n"; 50351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 5041bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor void writeValue(raw_ostream &OS) const { 5051bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << "\" << get" << getUpperName() << "() << \""; 5061bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } 50751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne }; 50851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 50951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne class VersionArgument : public Argument { 51051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne public: 51151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne VersionArgument(Record &Arg, StringRef Attr) 51251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne : Argument(Arg, Attr) 51351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne {} 51451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 51551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeAccessors(raw_ostream &OS) const { 51651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " VersionTuple get" << getUpperName() << "() const {\n"; 51751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return " << getLowerName() << ";\n"; 51851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }\n"; 51951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " void set" << getUpperName() 52051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "(ASTContext &C, VersionTuple V) {\n"; 52151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << getLowerName() << " = V;\n"; 52251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }"; 52351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 52451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCloneArgs(raw_ostream &OS) const { 52551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "get" << getUpperName() << "()"; 52651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 5277b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins void writeTemplateInstantiationArgs(raw_ostream &OS) const { 5287b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << "A->get" << getUpperName() << "()"; 5297b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 53051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorBody(raw_ostream &OS) const { 53151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 53251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorInitializers(raw_ostream &OS) const { 53351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getLowerName() << "(" << getUpperName() << ")"; 53451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 53551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeCtorParameters(raw_ostream &OS) const { 53651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "VersionTuple " << getUpperName(); 53751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 53851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writeDeclarations(raw_ostream &OS) const { 53951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "VersionTuple " << getLowerName() << ";\n"; 54051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 54151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHReadDecls(raw_ostream &OS) const { 54251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " VersionTuple " << getLowerName() 54351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "= ReadVersionTuple(Record, Idx);\n"; 54451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 54551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHReadArgs(raw_ostream &OS) const { 54651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << getLowerName(); 54751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 54851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne void writePCHWrite(raw_ostream &OS) const { 54951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n"; 55051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 5511bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor void writeValue(raw_ostream &OS) const { 5521bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << getLowerName() << "=\" << get" << getUpperName() << "() << \""; 5531bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } 55451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne }; 5557b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 5567b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins class ExprArgument : public SimpleArgument { 5577b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins public: 5587b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins ExprArgument(Record &Arg, StringRef Attr) 5597b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins : SimpleArgument(Arg, Attr, "Expr *") 5607b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins {} 5617b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 5627b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins void writeTemplateInstantiationArgs(raw_ostream &OS) const { 5637b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << "tempInst" << getUpperName(); 5647b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 5657b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 5667b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins void writeTemplateInstantiation(raw_ostream &OS) const { 5677b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " " << getType() << " tempInst" << getUpperName() << ";\n"; 5687b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " {\n"; 5697b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " EnterExpressionEvaluationContext " 5707b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << "Unevaluated(S, Sema::Unevaluated);\n"; 5717b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " ExprResult " << "Result = S.SubstExpr(" 5727b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << "A->get" << getUpperName() << "(), TemplateArgs);\n"; 5737b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " tempInst" << getUpperName() << " = " 5747b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << "Result.takeAs<Expr>();\n"; 5757b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " }\n"; 5767b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 5777b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins }; 5787b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 5797b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins class VariadicExprArgument : public VariadicArgument { 5807b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins public: 5817b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins VariadicExprArgument(Record &Arg, StringRef Attr) 5827b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins : VariadicArgument(Arg, Attr, "Expr *") 5837b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins {} 5847b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 5857b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins void writeTemplateInstantiationArgs(raw_ostream &OS) const { 5867b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << "tempInst" << getUpperName() << ", " 5877b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << "A->" << getLowerName() << "_size()"; 5887b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 5897b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 5907b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins void writeTemplateInstantiation(raw_ostream &OS) const { 5917b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " " << getType() << " *tempInst" << getUpperName() 5927b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << " = new (C, 16) " << getType() 5937b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << "[A->" << getLowerName() << "_size()];\n"; 5947b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " {\n"; 5957b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " EnterExpressionEvaluationContext " 5967b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << "Unevaluated(S, Sema::Unevaluated);\n"; 5977b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " " << getType() << " *TI = tempInst" << getUpperName() 5987b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << ";\n"; 5997b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " " << getType() << " *I = A->" << getLowerName() 6007b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << "_begin();\n"; 6017b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " " << getType() << " *E = A->" << getLowerName() 6027b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << "_end();\n"; 6037b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " for (; I != E; ++I, ++TI) {\n"; 6047b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n"; 6057b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " *TI = Result.takeAs<Expr>();\n"; 6067b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " }\n"; 6077b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " }\n"; 6087b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 6097b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins }; 61051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 61151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 61251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic Argument *createArgument(Record &Arg, StringRef Attr, 61351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *Search = 0) { 61451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!Search) 61551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Search = &Arg; 61651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 61751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Argument *Ptr = 0; 61851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne llvm::StringRef ArgName = Search->getName(); 61951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 62051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr); 62151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr); 6227b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins else if (ArgName == "ExprArgument") Ptr = new ExprArgument(Arg, Attr); 62351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if (ArgName == "FunctionArgument") 62451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *"); 62551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if (ArgName == "IdentifierArgument") 62651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *"); 62751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr, 62851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "bool"); 62951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int"); 63051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr); 63151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if (ArgName == "TypeArgument") 63251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Ptr = new SimpleArgument(Arg, Attr, "QualType"); 63351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if (ArgName == "UnsignedArgument") 63451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Ptr = new SimpleArgument(Arg, Attr, "unsigned"); 63551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if (ArgName == "SourceLocArgument") 63651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Ptr = new SimpleArgument(Arg, Attr, "SourceLocation"); 63751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if (ArgName == "VariadicUnsignedArgument") 63851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Ptr = new VariadicArgument(Arg, Attr, "unsigned"); 63951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if (ArgName == "VariadicExprArgument") 6407b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins Ptr = new VariadicExprArgument(Arg, Attr); 64151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if (ArgName == "VersionArgument") 64251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Ptr = new VersionArgument(Arg, Attr); 64351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 64451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!Ptr) { 64551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> Bases = Search->getSuperClasses(); 64651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end(); 64751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne i != e; ++i) { 64851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Ptr = createArgument(Arg, Attr, *i); 64951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (Ptr) 65051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 65151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 65251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 65351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return Ptr; 65451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 65551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 6561bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregorstatic void writeAvailabilityValue(raw_ostream &OS) { 6571bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << "\" << getPlatform()->getName();\n" 6581bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor << " if (!getIntroduced().empty()) OS << \", introduced=\" << getIntroduced();\n" 6591bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor << " if (!getDeprecated().empty()) OS << \", deprecated=\" << getDeprecated();\n" 6601bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor << " if (!getObsoleted().empty()) OS << \", obsoleted=\" << getObsoleted();\n" 6611bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor << " if (getUnavailable()) OS << \", unavailable\";\n" 6621bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor << " OS << \""; 6631bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor} 6641bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor 6653cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesennamespace clang { 6663cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 6673cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen// Emits the class definitions for attributes. 6683cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { 66951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "// This file is generated by TableGen. Do not edit.\n\n"; 67051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n"; 67151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n"; 67251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 67351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 67451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 67551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); 67651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne i != e; ++i) { 67751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record &R = **i; 6783e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor 6793e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor if (!R.getValueAsBit("ASTNode")) 6803e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor continue; 6813e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor 68251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::string &SuperName = R.getSuperClasses().back()->getName(); 68351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 68451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n"; 68551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 68651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 68751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Argument*> Args; 68851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Argument*>::iterator ai, ae; 68951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Args.reserve(ArgRecords.size()); 69051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 69151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::vector<Record*>::iterator ri = ArgRecords.begin(), 69251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne re = ArgRecords.end(); 69351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ri != re; ++ri) { 69451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record &ArgRecord = **ri; 69551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Argument *Arg = createArgument(ArgRecord, R.getName()); 69651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne assert(Arg); 69751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Args.push_back(Arg); 69851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 69951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Arg->writeDeclarations(OS); 70051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n\n"; 70151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 70251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 70351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ae = Args.end(); 70451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 70551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n public:\n"; 70651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n"; 70751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 70851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (ai = Args.begin(); ai != ae; ++ai) { 70951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " , "; 71051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne (*ai)->writeCtorParameters(OS); 71151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n"; 71251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 71351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 71451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " )\n"; 71551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " : " << SuperName << "(attr::" << R.getName() << ", R)\n"; 71651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 71751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (ai = Args.begin(); ai != ae; ++ai) { 71851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " , "; 71951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne (*ai)->writeCtorInitializers(OS); 72051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n"; 72151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 72251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 72351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " {\n"; 72451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 72551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (ai = Args.begin(); ai != ae; ++ai) { 72651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne (*ai)->writeCtorBody(OS); 72751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n"; 72851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 72951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }\n\n"; 73051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 73151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n"; 7321bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << " virtual void printPretty(llvm::raw_ostream &OS, ASTContext &Ctx) const;\n"; 73351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 73451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (ai = Args.begin(); ai != ae; ++ai) { 73551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne (*ai)->writeAccessors(OS); 73651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n\n"; 73751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 73851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 739eb666737bae8a5af8fb6b485cd15e2e62caa5cafJakob Stoklund Olesen OS << R.getValueAsString("AdditionalMembers"); 74051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n\n"; 74151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 74251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " static bool classof(const Attr *A) { return A->getKind() == " 74351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "attr::" << R.getName() << "; }\n"; 74451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " static bool classof(const " << R.getName() 74551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Attr *) { return true; }\n"; 74623323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins 74723323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins bool LateParsed = R.getValueAsBit("LateParsed"); 74823323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins OS << " virtual bool isLateParsed() const { return " 74923323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins << LateParsed << "; }\n"; 75023323e0253716ff03c95a00fb6903019daafe3aaDeLesley Hutchins 75151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "};\n\n"; 75251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 75351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 75451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n"; 75551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 75651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 7573cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen// Emits the class method definitions for attributes. 7583cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) { 75951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "// This file is generated by TableGen. Do not edit.\n\n"; 76051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 76151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 76251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re; 76351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Argument*>::iterator ai, ae; 76451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 76551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (; i != e; ++i) { 76651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record &R = **i; 7673e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor 7683e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor if (!R.getValueAsBit("ASTNode")) 7693e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor continue; 7703e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor 77151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 7721bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor std::vector<StringRef> Spellings = getValueAsListOfStrings(R, "Spellings"); 77351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Argument*> Args; 77451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri) 77551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Args.push_back(createArgument(**ri, R.getName())); 77651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 77751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) 77851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne (*ai)->writeAccessorDefinitions(OS); 77951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 78051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << R.getName() << "Attr *" << R.getName() 78151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Attr::clone(ASTContext &C) const {\n"; 78251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " return new (C) " << R.getName() << "Attr(getLocation(), C"; 78351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (ai = Args.begin(); ai != ae; ++ai) { 78451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ", "; 78551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne (*ai)->writeCloneArgs(OS); 78651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 78751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ");\n}\n\n"; 7881bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor 7891bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << "void " << R.getName() << "Attr::printPretty(" 7901bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor << "llvm::raw_ostream &OS, ASTContext &Ctx) const {\n"; 7911bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor if (Spellings.begin() != Spellings.end()) { 7921bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << " OS << \" __attribute__((" << *Spellings.begin(); 7931bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor if (Args.size()) OS << "("; 7941bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor if (*Spellings.begin()=="availability") { 7951bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor writeAvailabilityValue(OS); 7961bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } else { 7971bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor for (ai = Args.begin(); ai != ae; ++ai) { 7981bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor if (ai!=Args.begin()) OS <<", "; 7991bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor (*ai)->writeValue(OS); 8001bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } 8011bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } 8021bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor if (Args.size()) OS << ")"; 8031bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << "))\";\n"; 8041bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor } 8051bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor OS << "}\n\n"; 80651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 80751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 80851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 8093cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} // end namespace clang 8103cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 81151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic void EmitAttrList(raw_ostream &OS, StringRef Class, 81251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::vector<Record*> &AttrList) { 81351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end(); 81451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 81551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (i != e) { 81651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Move the end iterator back to emit the last attribute. 8173e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor for(--e; i != e; ++i) { 8183e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor if (!(*i)->getValueAsBit("ASTNode")) 8193e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor continue; 8203e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor 82151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << Class << "(" << (*i)->getName() << ")\n"; 8223e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor } 82351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 82451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n"; 82551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 82651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 82751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 8283cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesennamespace clang { 8293cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 8303cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen// Emits the enumeration list for attributes. 8313cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { 83251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "// This file is generated by TableGen. Do not edit.\n\n"; 83351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 83451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifndef LAST_ATTR\n"; 83551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n"; 83651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n\n"; 83751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 83851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifndef INHERITABLE_ATTR\n"; 83951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n"; 84051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n\n"; 84151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 84251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifndef LAST_INHERITABLE_ATTR\n"; 84351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n"; 84451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n\n"; 84551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 84651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifndef INHERITABLE_PARAM_ATTR\n"; 84751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n"; 84851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n\n"; 84951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 85051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n"; 85151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)" 85251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " INHERITABLE_PARAM_ATTR(NAME)\n"; 85351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n\n"; 85451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 85551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *InhClass = Records.getClass("InheritableAttr"); 85651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *InhParamClass = Records.getClass("InheritableParamAttr"); 85751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), 85851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne NonInhAttrs, InhAttrs, InhParamAttrs; 85951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); 86051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne i != e; ++i) { 8613e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor if (!(*i)->getValueAsBit("ASTNode")) 8623e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor continue; 8633e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor 86451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if ((*i)->isSubClassOf(InhParamClass)) 86551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne InhParamAttrs.push_back(*i); 86651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if ((*i)->isSubClassOf(InhClass)) 86751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne InhAttrs.push_back(*i); 86851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 86951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne NonInhAttrs.push_back(*i); 87051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 87151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 87251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs); 87351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs); 87451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne EmitAttrList(OS, "ATTR", NonInhAttrs); 87551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 87651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef LAST_ATTR\n"; 87751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef INHERITABLE_ATTR\n"; 87851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef LAST_INHERITABLE_ATTR\n"; 87951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n"; 88051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef ATTR\n"; 88151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 88251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 8833cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen// Emits the code to read an attribute from a precompiled header. 8843cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) { 88551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "// This file is generated by TableGen. Do not edit.\n\n"; 88651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 88751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *InhClass = Records.getClass("InheritableAttr"); 88851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), 88951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ArgRecords; 89051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; 89151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Argument*> Args; 89251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Argument*>::iterator ri, re; 89351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 89451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " switch (Kind) {\n"; 89551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " default:\n"; 89651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " assert(0 && \"Unknown attribute!\");\n"; 89751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " break;\n"; 89851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (; i != e; ++i) { 89951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record &R = **i; 9003e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor if (!R.getValueAsBit("ASTNode")) 9013e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor continue; 9023e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor 90351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " case attr::" << R.getName() << ": {\n"; 90451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R.isSubClassOf(InhClass)) 90551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " bool isInherited = Record[Idx++];\n"; 90651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ArgRecords = R.getValueAsListOfDefs("Args"); 90751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Args.clear(); 90851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) { 90951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Argument *A = createArgument(**ai, R.getName()); 91051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Args.push_back(A); 91151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne A->writePCHReadDecls(OS); 91251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 91351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " New = new (Context) " << R.getName() << "Attr(Range, Context"; 91451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) { 91551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ", "; 91651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne (*ri)->writePCHReadArgs(OS); 91751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 91851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ");\n"; 91951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R.isSubClassOf(InhClass)) 92051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " cast<InheritableAttr>(New)->setInherited(isInherited);\n"; 92151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " break;\n"; 92251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }\n"; 92351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 92451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }\n"; 92551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 92651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 9273cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen// Emits the code to write an attribute to a precompiled header. 9283cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) { 92951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *InhClass = Records.getClass("InheritableAttr"); 93051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args; 93151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; 93251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 93351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " switch (A->getKind()) {\n"; 93451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " default:\n"; 93551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " llvm_unreachable(\"Unknown attribute kind!\");\n"; 93651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " break;\n"; 93751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (; i != e; ++i) { 93851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record &R = **i; 9393e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor if (!R.getValueAsBit("ASTNode")) 9403e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor continue; 94151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " case attr::" << R.getName() << ": {\n"; 94251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Args = R.getValueAsListOfDefs("Args"); 94351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R.isSubClassOf(InhClass) || !Args.empty()) 94451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName() 94551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne << "Attr>(A);\n"; 94651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R.isSubClassOf(InhClass)) 94751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " Record.push_back(SA->isInherited());\n"; 94851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) 94951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne createArgument(**ai, R.getName())->writePCHWrite(OS); 95051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " break;\n"; 95151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }\n"; 95251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 95351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " }\n"; 95451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 95551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 9563cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen// Emits the list of spellings for attributes. 9573cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) { 95851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "// This file is generated by TableGen. Do not edit.\n\n"; 95951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 96051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 96151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 96251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { 96351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record &Attr = **I; 96451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 96551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<StringRef> Spellings = getValueAsListOfStrings(Attr, "Spellings"); 96651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 96751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::vector<StringRef>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) { 96851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringRef Spelling = *I; 96951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ".Case(\"" << Spelling << "\", true)\n"; 97051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 97151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 97251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 97351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 97451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 9753cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen// Emits the LateParsed property for attributes. 9763cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) { 97751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "// This file is generated by TableGen. Do not edit.\n\n"; 97851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 97951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 98051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 98151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 98251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne I != E; ++I) { 98351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record &Attr = **I; 98451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 98551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool LateParsed = Attr.getValueAsBit("LateParsed"); 98651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 98751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (LateParsed) { 98851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<StringRef> Spellings = 98951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne getValueAsListOfStrings(Attr, "Spellings"); 99051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 99151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (std::vector<StringRef>::const_iterator I = Spellings.begin(), 99251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne E = Spellings.end(); I != E; ++I) { 99351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ".Case(\"" << (*I) << "\", " << LateParsed << ")\n"; 99451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 99551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 99651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 99751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 9987b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 9993cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen// Emits code to instantiate dependent attributes on templates. 10003cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) { 10017b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << "// This file is generated by TableGen. Do not edit.\n\n"; 10027b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 10037b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 10047b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 10055bbc385ad2d8e487edfbc2756eaf4fb0b920cfe4Benjamin Kramer OS << "namespace clang {\n" 10065bbc385ad2d8e487edfbc2756eaf4fb0b920cfe4Benjamin Kramer << "namespace sema {\n\n" 10075bbc385ad2d8e487edfbc2756eaf4fb0b920cfe4Benjamin Kramer << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, " 10087b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << "Sema &S,\n" 10097b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << " const MultiLevelTemplateArgumentList &TemplateArgs) {\n" 10107b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << " switch (At->getKind()) {\n" 10117b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << " default:\n" 10127b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << " break;\n"; 10137b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 10147b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 10157b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins I != E; ++I) { 10167b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins Record &R = **I; 10173e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor if (!R.getValueAsBit("ASTNode")) 10183e7d31aa6050a2fb6cb35912793eb3f1b3a22030Douglas Gregor continue; 10197b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 10207b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " case attr::" << R.getName() << ": {\n"; 102131c195ac0f3869e742d42f9d02b6cd33442fb630Rafael Espindola bool ShouldClone = R.getValueAsBit("Clone"); 102231c195ac0f3869e742d42f9d02b6cd33442fb630Rafael Espindola 102331c195ac0f3869e742d42f9d02b6cd33442fb630Rafael Espindola if (!ShouldClone) { 102431c195ac0f3869e742d42f9d02b6cd33442fb630Rafael Espindola OS << " return NULL;\n"; 102531c195ac0f3869e742d42f9d02b6cd33442fb630Rafael Espindola OS << " }\n"; 102631c195ac0f3869e742d42f9d02b6cd33442fb630Rafael Espindola continue; 102731c195ac0f3869e742d42f9d02b6cd33442fb630Rafael Espindola } 102831c195ac0f3869e742d42f9d02b6cd33442fb630Rafael Espindola 10297b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " const " << R.getName() << "Attr *A = cast<" 10307b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << R.getName() << "Attr>(At);\n"; 10317b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins bool TDependent = R.getValueAsBit("TemplateDependent"); 10327b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 10337b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins if (!TDependent) { 10347b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " return A->clone(C);\n"; 10357b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " }\n"; 10367b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins continue; 10377b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 10387b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 10397b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); 10407b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins std::vector<Argument*> Args; 10417b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins std::vector<Argument*>::iterator ai, ae; 10427b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins Args.reserve(ArgRecords.size()); 10437b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 10447b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins for (std::vector<Record*>::iterator ri = ArgRecords.begin(), 10457b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins re = ArgRecords.end(); 10467b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins ri != re; ++ri) { 10477b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins Record &ArgRecord = **ri; 10487b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins Argument *Arg = createArgument(ArgRecord, R.getName()); 10497b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins assert(Arg); 10507b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins Args.push_back(Arg); 10517b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 10527b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins ae = Args.end(); 10537b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 10547b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins for (ai = Args.begin(); ai != ae; ++ai) { 10557b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins (*ai)->writeTemplateInstantiation(OS); 10567b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 10577b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " return new (C) " << R.getName() << "Attr(A->getLocation(), C"; 10587b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins for (ai = Args.begin(); ai != ae; ++ai) { 10597b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << ", "; 10607b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins (*ai)->writeTemplateInstantiationArgs(OS); 10617b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 10627b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << ");\n }\n"; 10637b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins } 10647b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins OS << " } // end switch\n" 10657b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << " llvm_unreachable(\"Unknown attribute!\");\n" 10667b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins << " return 0;\n" 10675bbc385ad2d8e487edfbc2756eaf4fb0b920cfe4Benjamin Kramer << "}\n\n" 10685bbc385ad2d8e487edfbc2756eaf4fb0b920cfe4Benjamin Kramer << "} // end namespace sema\n" 10695bbc385ad2d8e487edfbc2756eaf4fb0b920cfe4Benjamin Kramer << "} // end namespace clang\n"; 10707b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins} 10717b9ff0c09025dcbe48ec7db71330e2066d1e1863DeLesley Hutchins 10723cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen// Emits the list of parsed attributes. 10733cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) { 1074e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han OS << "// This file is generated by TableGen. Do not edit.\n\n"; 1075e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 1076e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han OS << "#ifndef PARSED_ATTR\n"; 1077e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han OS << "#define PARSED_ATTR(NAME) NAME\n"; 1078e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han OS << "#endif\n\n"; 1079e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 1080e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 1081e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han std::set<StringRef> ProcessedAttrs; 1082e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 1083e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 1084e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han I != E; ++I) { 1085e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han Record &Attr = **I; 1086e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 1087e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han bool SemaHandler = Attr.getValueAsBit("SemaHandler"); 1088703d412d192397b6fa17c5d99a4c1389aa2be2f3Douglas Gregor bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings"); 1089703d412d192397b6fa17c5d99a4c1389aa2be2f3Douglas Gregor 1090e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han if (SemaHandler) { 1091e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han std::vector<StringRef> Spellings = 1092e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han getValueAsListOfStrings(Attr, "Spellings"); 1093e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 1094e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han for (std::vector<StringRef>::const_iterator I = Spellings.begin(), 1095e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han E = Spellings.end(); I != E; ++I) { 1096e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han StringRef AttrName = *I; 1097e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 1098e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han AttrName = NormalizeAttrName(AttrName); 1099e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han // skip if a normalized version has been processed. 1100e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han if (ProcessedAttrs.find(AttrName) != ProcessedAttrs.end()) 1101e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han continue; 1102e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han else 1103e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han ProcessedAttrs.insert(AttrName); 1104e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 1105e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han OS << "PARSED_ATTR(" << AttrName << ")\n"; 1106703d412d192397b6fa17c5d99a4c1389aa2be2f3Douglas Gregor 1107703d412d192397b6fa17c5d99a4c1389aa2be2f3Douglas Gregor if (!DistinctSpellings) 1108703d412d192397b6fa17c5d99a4c1389aa2be2f3Douglas Gregor break; 1109e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han } 1110e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han } 1111e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han } 1112e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han} 1113e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 11143cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen// Emits the kind list of parsed attributes 11153cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { 1116e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han OS << "// This file is generated by TableGen. Do not edit.\n\n"; 11170c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor OS << "\n"; 11180c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor 1119e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); 1120e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 11210c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor std::vector<StringMatcher::StringPair> Matches; 1122e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); 1123e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han I != E; ++I) { 1124e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han Record &Attr = **I; 1125e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 1126e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han bool SemaHandler = Attr.getValueAsBit("SemaHandler"); 1127331d2ec7cd4c6b5e29cc61fcdc617bf708223cd4Douglas Gregor bool Ignored = Attr.getValueAsBit("Ignored"); 1128703d412d192397b6fa17c5d99a4c1389aa2be2f3Douglas Gregor bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings"); 1129331d2ec7cd4c6b5e29cc61fcdc617bf708223cd4Douglas Gregor if (SemaHandler || Ignored) { 1130e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han std::vector<StringRef> Spellings = 1131e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han getValueAsListOfStrings(Attr, "Spellings"); 113293f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt std::vector<StringRef> Namespaces = 113393f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt getValueAsListOfStrings(Attr, "Namespaces"); 1134e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 1135e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han for (std::vector<StringRef>::const_iterator I = Spellings.begin(), 1136e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han E = Spellings.end(); I != E; ++I) { 1137703d412d192397b6fa17c5d99a4c1389aa2be2f3Douglas Gregor StringRef AttrName = NormalizeAttrName(DistinctSpellings 1138703d412d192397b6fa17c5d99a4c1389aa2be2f3Douglas Gregor ? *I 1139703d412d192397b6fa17c5d99a4c1389aa2be2f3Douglas Gregor : Spellings.front()); 1140703d412d192397b6fa17c5d99a4c1389aa2be2f3Douglas Gregor StringRef Spelling = NormalizeAttrSpelling(*I); 1141e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 114293f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt for (std::vector<StringRef>::const_iterator NI = Namespaces.begin(), 114393f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt NE = Namespaces.end(); NI != NE; ++NI) { 114493f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt SmallString<64> Buf; 114593f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt Buf += *NI; 114693f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt Buf += "::"; 114793f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt Buf += Spelling; 114893f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt 114993f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt if (SemaHandler) 115093f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt Matches.push_back( 115193f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt StringMatcher::StringPair( 115293f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt Buf.str(), 115393f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt "return AttributeList::AT_" + AttrName.str() + ";")); 115493f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt else 115593f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt Matches.push_back( 115693f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt StringMatcher::StringPair( 115793f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt Buf.str(), 115893f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt "return AttributeList::IgnoredAttribute;")); 115993f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt } 116093f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt 1161331d2ec7cd4c6b5e29cc61fcdc617bf708223cd4Douglas Gregor if (SemaHandler) 11620c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor Matches.push_back( 1163703d412d192397b6fa17c5d99a4c1389aa2be2f3Douglas Gregor StringMatcher::StringPair( 1164703d412d192397b6fa17c5d99a4c1389aa2be2f3Douglas Gregor Spelling, 116593f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt "return AttributeList::AT_" + AttrName.str() + ";")); 1166331d2ec7cd4c6b5e29cc61fcdc617bf708223cd4Douglas Gregor else 11670c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor Matches.push_back( 11680c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor StringMatcher::StringPair( 11690c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor Spelling, 117093f95f2a2cbb6bb3d17bfb5fc74ce1cccea751b6Sean Hunt "return AttributeList::IgnoredAttribute;")); 1171e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han } 1172e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han } 1173e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han } 11740c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor 11750c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor OS << "static AttributeList::Kind getAttrKind(StringRef Name) {\n"; 11760c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor StringMatcher("Name", Matches, OS).Emit(); 11770c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor OS << "return AttributeList::UnknownAttribute;\n" 11780c19b3c38e356058aeb2424d175eae232bf014d9Douglas Gregor << "}\n"; 1179e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han} 1180e53ac8aea2d9e8bbb11191398ea3cc2edb2d171aMichael Han 11813cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} // end namespace clang 1182