diff options
Diffstat (limited to 'contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp | 184 |
1 files changed, 130 insertions, 54 deletions
diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp index 7951fc4..ef1ad3e 100644 --- a/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// -#include "ClangAttrEmitter.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/TableGen/Record.h" +#include "llvm/TableGen/StringMatcher.h" +#include "llvm/TableGen/TableGenBackend.h" #include <algorithm> #include <cctype> -#include <set> using namespace llvm; @@ -348,7 +349,9 @@ namespace { << "Type(), Record);\n"; } void writeValue(raw_ostream &OS) const { - OS << "\" << get" << getUpperName() << "(Ctx) << \""; + OS << "\";\n" + << " " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n" + << " OS << \""; } }; @@ -660,7 +663,10 @@ static void writeAvailabilityValue(raw_ostream &OS) { << " OS << \""; } -void ClangAttrClassEmitter::run(raw_ostream &OS) { +namespace clang { + +// Emits the class definitions for attributes. +void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { OS << "// This file is generated by TableGen. Do not edit.\n\n"; OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n"; OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n"; @@ -670,6 +676,10 @@ void ClangAttrClassEmitter::run(raw_ostream &OS) { for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i) { Record &R = **i; + + if (!R.getValueAsBit("ASTNode")) + continue; + const std::string &SuperName = R.getSuperClasses().back()->getName(); OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n"; @@ -720,7 +730,8 @@ void ClangAttrClassEmitter::run(raw_ostream &OS) { OS << " }\n\n"; OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n"; - OS << " virtual void printPretty(llvm::raw_ostream &OS, ASTContext &Ctx) const;\n"; + OS << " virtual void printPretty(llvm::raw_ostream &OS," + << " const PrintingPolicy &Policy) const;\n"; for (ai = Args.begin(); ai != ae; ++ai) { (*ai)->writeAccessors(OS); @@ -745,7 +756,8 @@ void ClangAttrClassEmitter::run(raw_ostream &OS) { OS << "#endif\n"; } -void ClangAttrImplEmitter::run(raw_ostream &OS) { +// Emits the class method definitions for attributes. +void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) { OS << "// This file is generated by TableGen. Do not edit.\n\n"; std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -754,8 +766,12 @@ void ClangAttrImplEmitter::run(raw_ostream &OS) { for (; i != e; ++i) { Record &R = **i; + + if (!R.getValueAsBit("ASTNode")) + continue; + std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); - std::vector<StringRef> Spellings = getValueAsListOfStrings(R, "Spellings"); + std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings"); std::vector<Argument*> Args; for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri) Args.push_back(createArgument(**ri, R.getName())); @@ -773,11 +789,12 @@ void ClangAttrImplEmitter::run(raw_ostream &OS) { OS << ");\n}\n\n"; OS << "void " << R.getName() << "Attr::printPretty(" - << "llvm::raw_ostream &OS, ASTContext &Ctx) const {\n"; + << "llvm::raw_ostream &OS, const PrintingPolicy &Policy) const {\n"; if (Spellings.begin() != Spellings.end()) { - OS << " OS << \" __attribute__((" << *Spellings.begin(); + std::string Spelling = (*Spellings.begin())->getValueAsString("Name"); + OS << " OS << \" __attribute__((" << Spelling; if (Args.size()) OS << "("; - if (*Spellings.begin()=="availability") { + if (Spelling == "availability") { writeAvailabilityValue(OS); } else { for (ai = Args.begin(); ai != ae; ++ai) { @@ -792,20 +809,29 @@ void ClangAttrImplEmitter::run(raw_ostream &OS) { } } +} // end namespace clang + static void EmitAttrList(raw_ostream &OS, StringRef Class, const std::vector<Record*> &AttrList) { std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end(); if (i != e) { // Move the end iterator back to emit the last attribute. - for(--e; i != e; ++i) + for(--e; i != e; ++i) { + if (!(*i)->getValueAsBit("ASTNode")) + continue; + OS << Class << "(" << (*i)->getName() << ")\n"; + } OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n"; } } -void ClangAttrListEmitter::run(raw_ostream &OS) { +namespace clang { + +// Emits the enumeration list for attributes. +void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { OS << "// This file is generated by TableGen. Do not edit.\n\n"; OS << "#ifndef LAST_ATTR\n"; @@ -835,6 +861,9 @@ void ClangAttrListEmitter::run(raw_ostream &OS) { NonInhAttrs, InhAttrs, InhParamAttrs; for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i) { + if (!(*i)->getValueAsBit("ASTNode")) + continue; + if ((*i)->isSubClassOf(InhParamClass)) InhParamAttrs.push_back(*i); else if ((*i)->isSubClassOf(InhClass)) @@ -854,7 +883,8 @@ void ClangAttrListEmitter::run(raw_ostream &OS) { OS << "#undef ATTR\n"; } -void ClangAttrPCHReadEmitter::run(raw_ostream &OS) { +// Emits the code to read an attribute from a precompiled header. +void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) { OS << "// This file is generated by TableGen. Do not edit.\n\n"; Record *InhClass = Records.getClass("InheritableAttr"); @@ -870,6 +900,9 @@ void ClangAttrPCHReadEmitter::run(raw_ostream &OS) { OS << " break;\n"; for (; i != e; ++i) { Record &R = **i; + if (!R.getValueAsBit("ASTNode")) + continue; + OS << " case attr::" << R.getName() << ": {\n"; if (R.isSubClassOf(InhClass)) OS << " bool isInherited = Record[Idx++];\n"; @@ -894,7 +927,8 @@ void ClangAttrPCHReadEmitter::run(raw_ostream &OS) { OS << " }\n"; } -void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) { +// Emits the code to write an attribute to a precompiled header. +void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) { Record *InhClass = Records.getClass("InheritableAttr"); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args; std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; @@ -905,6 +939,8 @@ void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) { OS << " break;\n"; for (; i != e; ++i) { Record &R = **i; + if (!R.getValueAsBit("ASTNode")) + continue; OS << " case attr::" << R.getName() << ": {\n"; Args = R.getValueAsListOfDefs("Args"); if (R.isSubClassOf(InhClass) || !Args.empty()) @@ -920,7 +956,8 @@ void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) { OS << " }\n"; } -void ClangAttrSpellingListEmitter::run(raw_ostream &OS) { +// Emits the list of spellings for attributes. +void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) { OS << "// This file is generated by TableGen. Do not edit.\n\n"; std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -928,17 +965,17 @@ void ClangAttrSpellingListEmitter::run(raw_ostream &OS) { for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { Record &Attr = **I; - std::vector<StringRef> Spellings = getValueAsListOfStrings(Attr, "Spellings"); + std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings"); - for (std::vector<StringRef>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) { - StringRef Spelling = *I; - OS << ".Case(\"" << Spelling << "\", true)\n"; + for (std::vector<Record*>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) { + OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", true)\n"; } } } -void ClangAttrLateParsedListEmitter::run(raw_ostream &OS) { +// Emits the LateParsed property for attributes. +void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) { OS << "// This file is generated by TableGen. Do not edit.\n\n"; std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -950,19 +987,23 @@ void ClangAttrLateParsedListEmitter::run(raw_ostream &OS) { bool LateParsed = Attr.getValueAsBit("LateParsed"); if (LateParsed) { - std::vector<StringRef> Spellings = - getValueAsListOfStrings(Attr, "Spellings"); + std::vector<Record*> Spellings = + Attr.getValueAsListOfDefs("Spellings"); - for (std::vector<StringRef>::const_iterator I = Spellings.begin(), + // FIXME: Handle non-GNU attributes + for (std::vector<Record*>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) { - OS << ".Case(\"" << (*I) << "\", " << LateParsed << ")\n"; + if ((*I)->getValueAsString("Variety") != "GNU") + continue; + OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", " + << LateParsed << ")\n"; } } } } - -void ClangAttrTemplateInstantiateEmitter::run(raw_ostream &OS) { +// Emits code to instantiate dependent attributes on templates. +void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) { OS << "// This file is generated by TableGen. Do not edit.\n\n"; std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -979,8 +1020,18 @@ void ClangAttrTemplateInstantiateEmitter::run(raw_ostream &OS) { for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { Record &R = **I; + if (!R.getValueAsBit("ASTNode")) + continue; OS << " case attr::" << R.getName() << ": {\n"; + bool ShouldClone = R.getValueAsBit("Clone"); + + if (!ShouldClone) { + OS << " return NULL;\n"; + OS << " }\n"; + continue; + } + OS << " const " << R.getName() << "Attr *A = cast<" << R.getName() << "Attr>(At);\n"; bool TDependent = R.getValueAsBit("TemplateDependent"); @@ -1024,7 +1075,8 @@ void ClangAttrTemplateInstantiateEmitter::run(raw_ostream &OS) { << "} // end namespace clang\n"; } -void ClangAttrParsedAttrListEmitter::run(raw_ostream &OS) { +// Emits the list of parsed attributes. +void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) { OS << "// This file is generated by TableGen. Do not edit.\n\n"; OS << "#ifndef PARSED_ATTR\n"; @@ -1032,61 +1084,85 @@ void ClangAttrParsedAttrListEmitter::run(raw_ostream &OS) { OS << "#endif\n\n"; std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); - std::set<StringRef> ProcessedAttrs; for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { Record &Attr = **I; bool SemaHandler = Attr.getValueAsBit("SemaHandler"); - + bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings"); + if (SemaHandler) { - std::vector<StringRef> Spellings = - getValueAsListOfStrings(Attr, "Spellings"); - - for (std::vector<StringRef>::const_iterator I = Spellings.begin(), - E = Spellings.end(); I != E; ++I) { - StringRef AttrName = *I; + if (DistinctSpellings) { + std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings"); + + for (std::vector<Record*>::const_iterator I = Spellings.begin(), + E = Spellings.end(); I != E; ++I) { + std::string AttrName = (*I)->getValueAsString("Name"); - AttrName = NormalizeAttrName(AttrName); - // skip if a normalized version has been processed. - if (ProcessedAttrs.find(AttrName) != ProcessedAttrs.end()) - continue; - else - ProcessedAttrs.insert(AttrName); + StringRef Spelling = NormalizeAttrName(AttrName); + OS << "PARSED_ATTR(" << Spelling << ")\n"; + } + } else { + StringRef AttrName = Attr.getName(); + AttrName = NormalizeAttrName(AttrName); OS << "PARSED_ATTR(" << AttrName << ")\n"; } } } } -void ClangAttrParsedAttrKindsEmitter::run(raw_ostream &OS) { +// Emits the kind list of parsed attributes +void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { OS << "// This file is generated by TableGen. Do not edit.\n\n"; - + OS << "\n"; + std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); + std::vector<StringMatcher::StringPair> Matches; for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { Record &Attr = **I; bool SemaHandler = Attr.getValueAsBit("SemaHandler"); - - if (SemaHandler) { - std::vector<StringRef> Spellings = - getValueAsListOfStrings(Attr, "Spellings"); + bool Ignored = Attr.getValueAsBit("Ignored"); + bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings"); + if (SemaHandler || Ignored) { + std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings"); - for (std::vector<StringRef>::const_iterator I = Spellings.begin(), + for (std::vector<Record*>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) { - StringRef AttrName = *I, Spelling = *I; - - AttrName = NormalizeAttrName(AttrName); - Spelling = NormalizeAttrSpelling(Spelling); + std::string RawSpelling = (*I)->getValueAsString("Name"); + StringRef AttrName = NormalizeAttrName(DistinctSpellings + ? StringRef(RawSpelling) + : StringRef(Attr.getName())); + + SmallString<64> Spelling; + if ((*I)->getValueAsString("Variety") == "CXX11") { + Spelling += (*I)->getValueAsString("Namespace"); + Spelling += "::"; + } + Spelling += NormalizeAttrSpelling(RawSpelling); - OS << ".Case(\"" << Spelling << "\", " << "AT_" << AttrName << ")\n"; + if (SemaHandler) + Matches.push_back( + StringMatcher::StringPair( + StringRef(Spelling), + "return AttributeList::AT_" + AttrName.str() + ";")); + else + Matches.push_back( + StringMatcher::StringPair( + StringRef(Spelling), + "return AttributeList::IgnoredAttribute;")); } } } + + OS << "static AttributeList::Kind getAttrKind(StringRef Name) {\n"; + StringMatcher("Name", Matches, OS).Emit(); + OS << "return AttributeList::UnknownAttribute;\n" + << "}\n"; } - +} // end namespace clang |