diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index db10d7906e2..f33cb50c760 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -462,8 +462,9 @@ void ClangAttrClassEmitter::run(raw_ostream &OS) { for (std::vector::iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i) { Record &R = **i; + const std::string &SuperName = R.getSuperClasses().back()->getName(); - OS << "class " << R.getName() << "Attr : public Attr {\n"; + OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n"; std::vector ArgRecords = R.getValueAsListOfDefs("Args"); std::vector Args; @@ -494,7 +495,7 @@ void ClangAttrClassEmitter::run(raw_ostream &OS) { } OS << " )\n"; - OS << " : Attr(attr::" << R.getName() << ", L)\n"; + OS << " : " << SuperName << "(attr::" << R.getName() << ", L)\n"; for (ai = Args.begin(); ai != ae; ++ai) { OS << " , "; @@ -558,31 +559,58 @@ void ClangAttrImplEmitter::run(raw_ostream &OS) { } } +static void EmitAttrList(raw_ostream &OS, StringRef Class, + const std::vector &AttrList) { + std::vector::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) + OS << Class << "(" << (*i)->getName() << ")\n"; + + OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n"; + } +} + void ClangAttrListEmitter::run(raw_ostream &OS) { OS << "// This file is generated by TableGen. Do not edit.\n\n"; OS << "#ifndef LAST_ATTR\n"; OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n"; OS << "#endif\n\n"; - - std::vector Attrs = Records.getAllDerivedDefinitions("Attr"); - std::vector::iterator i = Attrs.begin(), e = Attrs.end(); - if (i != e) { - // Move the end iterator back to emit the last attribute. - for(--e; i != e; ++i) - OS << "ATTR(" << (*i)->getName() << ")\n"; - - OS << "LAST_ATTR(" << (*i)->getName() << ")\n\n"; + OS << "#ifndef INHERITABLE_ATTR\n"; + OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n"; + OS << "#endif\n\n"; + + OS << "#ifndef LAST_INHERITABLE_ATTR\n"; + OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n"; + OS << "#endif\n\n"; + + Record *InhClass = Records.getClass("InheritableAttr"); + std::vector Attrs = Records.getAllDerivedDefinitions("Attr"), + NonInhAttrs, InhAttrs; + for (std::vector::iterator i = Attrs.begin(), e = Attrs.end(); + i != e; ++i) { + if ((*i)->isSubClassOf(InhClass)) + InhAttrs.push_back(*i); + else + NonInhAttrs.push_back(*i); } + EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs); + EmitAttrList(OS, "ATTR", NonInhAttrs); + OS << "#undef LAST_ATTR\n"; + OS << "#undef INHERITABLE_ATTR\n"; + OS << "#undef LAST_INHERITABLE_ATTR\n"; OS << "#undef ATTR\n"; } void ClangAttrPCHReadEmitter::run(raw_ostream &OS) { OS << "// This file is generated by TableGen. Do not edit.\n\n"; + Record *InhClass = Records.getClass("InheritableAttr"); std::vector Attrs = Records.getAllDerivedDefinitions("Attr"), ArgRecords; std::vector::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; @@ -596,6 +624,8 @@ void ClangAttrPCHReadEmitter::run(raw_ostream &OS) { for (; i != e; ++i) { Record &R = **i; OS << " case attr::" << R.getName() << ": {\n"; + if (R.isSubClassOf(InhClass)) + OS << " bool isInherited = Record[Idx++];\n"; ArgRecords = R.getValueAsListOfDefs("Args"); Args.clear(); for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) { @@ -609,6 +639,8 @@ void ClangAttrPCHReadEmitter::run(raw_ostream &OS) { (*ri)->writePCHReadArgs(OS); } OS << ");\n"; + if (R.isSubClassOf(InhClass)) + OS << " cast(New)->setInherited(isInherited);\n"; OS << " break;\n"; OS << " }\n"; } @@ -616,6 +648,7 @@ void ClangAttrPCHReadEmitter::run(raw_ostream &OS) { } void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) { + Record *InhClass = Records.getClass("InheritableAttr"); std::vector Attrs = Records.getAllDerivedDefinitions("Attr"), Args; std::vector::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; @@ -627,9 +660,11 @@ void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) { Record &R = **i; OS << " case attr::" << R.getName() << ": {\n"; Args = R.getValueAsListOfDefs("Args"); - if (!Args.empty()) + if (R.isSubClassOf(InhClass) || !Args.empty()) OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName() << "Attr>(A);\n"; + if (R.isSubClassOf(InhClass)) + OS << " Record.push_back(SA->isInherited());\n"; for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) createArgument(**ai, R.getName())->writePCHWrite(OS); OS << " break;\n";