r262275 - Infrastructure improvements to Clang attribute TableGen.
Sean Silva via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 29 18:38:47 PST 2016
All green on the two latest commits. Thanks!
http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/961
-- Sean Silva
On Mon, Feb 29, 2016 at 6:14 PM, John McCall <rjmccall at apple.com> wrote:
> On Feb 29, 2016, at 5:44 PM, Sean Silva <chisophugis at gmail.com> wrote:
> This seems to be causing a substantial amount of warning spew from MSVC:
>
> http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/955
>
> I think our recommended "portable" method of using llvm_unreachable is
> outside the switch, instead of in the default case:
> http://llvm.org/docs/CodingStandards.html#don-t-use-default-labels-in-fully-covered-switches-over-enumerations
>
>
> Sorry, should be fixed in r262288. I’ll be back in a few hours, feel free
> to revert if it doesn’t clear up.
>
> John.
>
>
> -- Sean Silva
>
> On Mon, Feb 29, 2016 at 4:18 PM, John McCall via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
>
>> Author: rjmccall
>> Date: Mon Feb 29 18:18:05 2016
>> New Revision: 262275
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=262275&view=rev
>> Log:
>> Infrastructure improvements to Clang attribute TableGen.
>>
>> This should make it easier to add new Attr subclasses.
>>
>> Modified:
>> cfe/trunk/include/clang/AST/Attr.h
>> cfe/trunk/include/clang/Basic/AttrKinds.h
>> cfe/trunk/lib/AST/ASTDumper.cpp
>> cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
>>
>> Modified: cfe/trunk/include/clang/AST/Attr.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=262275&r1=262274&r2=262275&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/AST/Attr.h (original)
>> +++ cfe/trunk/include/clang/AST/Attr.h Mon Feb 29 18:18:05 2016
>> @@ -129,7 +129,8 @@ public:
>>
>> // Implement isa/cast/dyncast/etc.
>> static bool classof(const Attr *A) {
>> - return A->getKind() <= attr::LAST_INHERITABLE;
>> + return A->getKind() >= attr::FirstInheritableAttr &&
>> + A->getKind() <= attr::LastInheritableAttr;
>> }
>> };
>>
>> @@ -143,9 +144,8 @@ protected:
>> public:
>> // Implement isa/cast/dyncast/etc.
>> static bool classof(const Attr *A) {
>> - // Relies on relative order of enum emission with respect to MS
>> inheritance
>> - // attrs.
>> - return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
>> + return A->getKind() >= attr::FirstInheritableParamAttr &&
>> + A->getKind() <= attr::LastInheritableParamAttr;
>> }
>> };
>>
>>
>> Modified: cfe/trunk/include/clang/Basic/AttrKinds.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrKinds.h?rev=262275&r1=262274&r2=262275&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/AttrKinds.h (original)
>> +++ cfe/trunk/include/clang/Basic/AttrKinds.h Mon Feb 29 18:18:05 2016
>> @@ -22,10 +22,10 @@ namespace attr {
>> // \brief A list of all the recognized kinds of attributes.
>> enum Kind {
>> #define ATTR(X) X,
>> -#define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X,
>> -#define LAST_INHERITABLE_PARAM_ATTR(X) X, LAST_INHERITABLE_PARAM = X,
>> +#define ATTR_RANGE(CLASS, FIRST_NAME, LAST_NAME) \
>> + First##CLASS = FIRST_NAME, \
>> + Last##CLASS = LAST_NAME,
>> #include "clang/Basic/AttrList.inc"
>> - NUM_ATTRS
>> };
>>
>> } // end namespace attr
>>
>> Modified: cfe/trunk/lib/AST/ASTDumper.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=262275&r1=262274&r2=262275&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/AST/ASTDumper.cpp (original)
>> +++ cfe/trunk/lib/AST/ASTDumper.cpp Mon Feb 29 18:18:05 2016
>> @@ -819,8 +819,6 @@ void ASTDumper::dumpAttr(const Attr *A)
>> switch (A->getKind()) {
>> #define ATTR(X) case attr::X: OS << #X; break;
>> #include "clang/Basic/AttrList.inc"
>> - default:
>> - llvm_unreachable("unexpected attribute kind");
>> }
>> OS << "Attr";
>> }
>>
>> Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=262275&r1=262274&r2=262275&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
>> +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Mon Feb 29 18:18:05 2016
>> @@ -1718,8 +1718,6 @@ void EmitClangAttrImpl(RecordKeeper &Rec
>> OS << " return cast<" << R.getName() << "Attr>(this)->" <<
>> Method
>> << ";\n";
>> }
>> - OS << " case attr::NUM_ATTRS:\n";
>> - OS << " break;\n";
>> OS << " }\n";
>> OS << " llvm_unreachable(\"Unexpected attribute kind!\");\n";
>> OS << "}\n\n";
>> @@ -1738,20 +1736,10 @@ void EmitClangAttrImpl(RecordKeeper &Rec
>>
>> } // end namespace clang
>>
>> -static void EmitAttrList(raw_ostream &OS, StringRef Class,
>> +static void emitAttrList(raw_ostream &OS, StringRef Class,
>> const std::vector<Record*> &AttrList) {
>> - auto i = AttrList.cbegin(), e = AttrList.cend();
>> -
>> - if (i != e) {
>> - // Move the end iterator back to emit the last attribute.
>> - for(--e; i != e; ++i) {
>> - if (!(*i)->getValueAsBit("ASTNode"))
>> - continue;
>> -
>> - OS << Class << "(" << (*i)->getName() << ")\n";
>> - }
>> -
>> - OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n";
>> + for (auto Cur : AttrList) {
>> + OS << Class << "(" << Cur->getName() << ")\n";
>> }
>> }
>>
>> @@ -1764,71 +1752,216 @@ static bool AttrHasPragmaSpelling(const
>> }) != Spellings.end();
>> }
>>
>> -namespace clang {
>> -// Emits the enumeration list for attributes.
>> -void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
>> - emitSourceFileHeader("List of all attributes that Clang recognizes",
>> OS);
>> +namespace {
>> + struct AttrClassDescriptor {
>> + const char * const MacroName;
>> + const char * const TableGenName;
>> + };
>> +}
>>
>> - OS << "#ifndef LAST_ATTR\n";
>> - OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n";
>> - OS << "#endif\n\n";
>> +static const AttrClassDescriptor AttrClassDescriptors[] = {
>> + { "ATTR", "Attr" },
>> + { "INHERITABLE_ATTR", "InheritableAttr" },
>> + { "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" }
>> +};
>> +
>> +static void emitDefaultDefine(raw_ostream &OS, StringRef name,
>> + const char *superName) {
>> + OS << "#ifndef " << name << "\n";
>> + OS << "#define " << name << "(NAME) ";
>> + if (superName) OS << superName << "(NAME)";
>> + OS << "\n#endif\n\n";
>> +}
>> +
>> +namespace {
>> + /// A class of attributes.
>> + struct AttrClass {
>> + const AttrClassDescriptor &Descriptor;
>> + Record *TheRecord;
>> + AttrClass *SuperClass = nullptr;
>> + std::vector<AttrClass*> SubClasses;
>> + std::vector<Record*> Attrs;
>> +
>> + AttrClass(const AttrClassDescriptor &Descriptor, Record *R)
>> + : Descriptor(Descriptor), TheRecord(R) {}
>> +
>> + void emitDefaultDefines(raw_ostream &OS) const {
>> + // Default the macro unless this is a root class (i.e. Attr).
>> + if (SuperClass) {
>> + emitDefaultDefine(OS, Descriptor.MacroName,
>> + SuperClass->Descriptor.MacroName);
>> + }
>> + }
>>
>> - OS << "#ifndef INHERITABLE_ATTR\n";
>> - OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n";
>> - OS << "#endif\n\n";
>> + void emitUndefs(raw_ostream &OS) const {
>> + OS << "#undef " << Descriptor.MacroName << "\n";
>> + }
>>
>> - OS << "#ifndef LAST_INHERITABLE_ATTR\n";
>> - OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
>> - OS << "#endif\n\n";
>> + void emitAttrList(raw_ostream &OS) const {
>> + for (auto SubClass : SubClasses) {
>> + SubClass->emitAttrList(OS);
>> + }
>>
>> - OS << "#ifndef INHERITABLE_PARAM_ATTR\n";
>> - OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n";
>> - OS << "#endif\n\n";
>> + ::emitAttrList(OS, Descriptor.MacroName, Attrs);
>> + }
>>
>> - OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n";
>> - OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)"
>> - " INHERITABLE_PARAM_ATTR(NAME)\n";
>> - OS << "#endif\n\n";
>> + void classifyAttrOnRoot(Record *Attr) {
>> + bool result = classifyAttr(Attr);
>> + assert(result && "failed to classify on root"); (void) result;
>> + }
>>
>> - OS << "#ifndef PRAGMA_SPELLING_ATTR\n";
>> - OS << "#define PRAGMA_SPELLING_ATTR(NAME)\n";
>> - OS << "#endif\n\n";
>> + void emitAttrRange(raw_ostream &OS) const {
>> + OS << "ATTR_RANGE(" << Descriptor.TableGenName
>> + << ", " << getFirstAttr()->getName()
>> + << ", " << getLastAttr()->getName() << ")\n";
>> + }
>>
>> - OS << "#ifndef LAST_PRAGMA_SPELLING_ATTR\n";
>> - OS << "#define LAST_PRAGMA_SPELLING_ATTR(NAME)
>> PRAGMA_SPELLING_ATTR(NAME)\n";
>> - OS << "#endif\n\n";
>> + private:
>> + bool classifyAttr(Record *Attr) {
>> + // Check all the subclasses.
>> + for (auto SubClass : SubClasses) {
>> + if (SubClass->classifyAttr(Attr))
>> + return true;
>> + }
>>
>> - Record *InhClass = Records.getClass("InheritableAttr");
>> - Record *InhParamClass = Records.getClass("InheritableParamAttr");
>> - std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr"),
>> - NonInhAttrs, InhAttrs, InhParamAttrs,
>> PragmaAttrs;
>> + // It's not more specific than this class, but it might still
>> belong here.
>> + if (Attr->isSubClassOf(TheRecord)) {
>> + Attrs.push_back(Attr);
>> + return true;
>> + }
>> +
>> + return false;
>> + }
>> +
>> + Record *getFirstAttr() const {
>> + if (!SubClasses.empty())
>> + return SubClasses.front()->getFirstAttr();
>> + return Attrs.front();
>> + }
>> +
>> + Record *getLastAttr() const {
>> + if (!Attrs.empty())
>> + return Attrs.back();
>> + return SubClasses.back()->getLastAttr();
>> + }
>> + };
>> +
>> + /// The entire hierarchy of attribute classes.
>> + class AttrClassHierarchy {
>> + std::vector<std::unique_ptr<AttrClass>> Classes;
>> + public:
>> + AttrClassHierarchy(RecordKeeper &Records) {
>> + // Find records for all the classes.
>> + for (auto &Descriptor : AttrClassDescriptors) {
>> + Record *ClassRecord = Records.getClass(Descriptor.TableGenName);
>> + AttrClass *Class = new AttrClass(Descriptor, ClassRecord);
>> + Classes.emplace_back(Class);
>> + }
>> +
>> + // Link up the hierarchy.
>> + for (auto &Class : Classes) {
>> + if (AttrClass *SuperClass = findSuperClass(Class->TheRecord)) {
>> + Class->SuperClass = SuperClass;
>> + SuperClass->SubClasses.push_back(Class.get());
>> + }
>> + }
>> +
>> +#ifndef NDEBUG
>> + for (auto i = Classes.begin(), e = Classes.end(); i != e; ++i) {
>> + assert((i == Classes.begin()) == ((*i)->SuperClass == nullptr) &&
>> + "only the first class should be a root class!");
>> + }
>> +#endif
>> + }
>> +
>> + void emitDefaultDefines(raw_ostream &OS) const {
>> + for (auto &Class : Classes) {
>> + Class->emitDefaultDefines(OS);
>> + }
>> + }
>> +
>> + void emitUndefs(raw_ostream &OS) const {
>> + for (auto &Class : Classes) {
>> + Class->emitUndefs(OS);
>> + }
>> + }
>> +
>> + void emitAttrLists(raw_ostream &OS) const {
>> + // Just start from the root class.
>> + Classes[0]->emitAttrList(OS);
>> + }
>> +
>> + void emitAttrRanges(raw_ostream &OS) const {
>> + for (auto &Class : Classes)
>> + Class->emitAttrRange(OS);
>> + }
>> +
>> + void classifyAttr(Record *Attr) {
>> + // Add the attribute to the root class.
>> + Classes[0]->classifyAttrOnRoot(Attr);
>> + }
>> +
>> + private:
>> + AttrClass *findClassByRecord(Record *R) const {
>> + for (auto &Class : Classes) {
>> + if (Class->TheRecord == R)
>> + return Class.get();
>> + }
>> + return nullptr;
>> + }
>> +
>> + AttrClass *findSuperClass(Record *R) const {
>> + // TableGen flattens the superclass list, so we just need to walk
>> it
>> + // in reverse.
>> + auto SuperClasses = R->getSuperClasses();
>> + for (signed i = 0, e = SuperClasses.size(); i != e; ++i) {
>> + auto SuperClass = findClassByRecord(SuperClasses[e - i -
>> 1].first);
>> + if (SuperClass) return SuperClass;
>> + }
>> + return nullptr;
>> + }
>> + };
>> +}
>> +
>> +namespace clang {
>> +// Emits the enumeration list for attributes.
>> +void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
>> + emitSourceFileHeader("List of all attributes that Clang recognizes",
>> OS);
>> +
>> + AttrClassHierarchy Hierarchy(Records);
>> +
>> + // Add defaulting macro definitions.
>> + Hierarchy.emitDefaultDefines(OS);
>> + emitDefaultDefine(OS, "PRAGMA_SPELLING_ATTR", nullptr);
>> +
>> + std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
>> + std::vector<Record *> PragmaAttrs;
>> for (auto *Attr : Attrs) {
>> if (!Attr->getValueAsBit("ASTNode"))
>> continue;
>>
>> + // Add the attribute to the ad-hoc groups.
>> if (AttrHasPragmaSpelling(Attr))
>> PragmaAttrs.push_back(Attr);
>>
>> - if (Attr->isSubClassOf(InhParamClass))
>> - InhParamAttrs.push_back(Attr);
>> - else if (Attr->isSubClassOf(InhClass))
>> - InhAttrs.push_back(Attr);
>> - else
>> - NonInhAttrs.push_back(Attr);
>> + // Place it in the hierarchy.
>> + Hierarchy.classifyAttr(Attr);
>> }
>>
>> - EmitAttrList(OS, "PRAGMA_SPELLING_ATTR", PragmaAttrs);
>> - EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
>> - 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 LAST_INHERITABLE_PARAM_ATTR\n";
>> - OS << "#undef LAST_PRAGMA_ATTR\n";
>> + // Emit the main attribute list.
>> + Hierarchy.emitAttrLists(OS);
>> +
>> + // Emit the ad hoc groups.
>> + emitAttrList(OS, "PRAGMA_SPELLING_ATTR", PragmaAttrs);
>> +
>> + // Emit the attribute ranges.
>> + OS << "#ifdef ATTR_RANGE\n";
>> + Hierarchy.emitAttrRanges(OS);
>> + OS << "#undef ATTR_RANGE\n";
>> + OS << "#endif\n";
>> +
>> + Hierarchy.emitUndefs(OS);
>> OS << "#undef PRAGMA_SPELLING_ATTR\n";
>> - OS << "#undef ATTR\n";
>> }
>>
>> // Emits the code to read an attribute from a precompiled header.
>> @@ -1841,8 +1974,6 @@ void EmitClangAttrPCHRead(RecordKeeper &
>> std::vector<std::unique_ptr<Argument>> Args;
>>
>> OS << " switch (Kind) {\n";
>> - OS << " default:\n";
>> - OS << " llvm_unreachable(\"Unknown attribute!\");\n";
>> for (const auto *Attr : Attrs) {
>> const Record &R = *Attr;
>> if (!R.getValueAsBit("ASTNode"))
>> @@ -1882,9 +2013,6 @@ void EmitClangAttrPCHWrite(RecordKeeper
>> std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
>> Args;
>>
>> OS << " switch (A->getKind()) {\n";
>> - OS << " default:\n";
>> - OS << " llvm_unreachable(\"Unknown attribute kind!\");\n";
>> - OS << " break;\n";
>> for (const auto *Attr : Attrs) {
>> const Record &R = *Attr;
>> if (!R.getValueAsBit("ASTNode"))
>> @@ -2075,11 +2203,7 @@ void EmitClangAttrSpellingListIndex(Reco
>> emitSourceFileHeader("Code to translate different attribute spellings "
>> "into internal identifiers", OS);
>>
>> - OS <<
>> - " switch (AttrKind) {\n"
>> - " default:\n"
>> - " llvm_unreachable(\"Unknown attribute kind!\");\n"
>> - " break;\n";
>> + OS << " switch (AttrKind) {\n";
>>
>> ParsedAttrMap Attrs = getParsedAttrList(Records);
>> for (const auto &I : Attrs) {
>> @@ -2159,9 +2283,7 @@ void EmitClangAttrASTVisitor(RecordKeepe
>> << " if (!A)\n"
>> << " return true;\n"
>> << "\n"
>> - << " switch (A->getKind()) {\n"
>> - << " default:\n"
>> - << " return true;\n";
>> + << " switch (A->getKind()) {\n";
>>
>> for (const auto *Attr : Attrs) {
>> const Record &R = *Attr;
>> @@ -2188,9 +2310,7 @@ void EmitClangAttrTemplateInstantiate(Re
>> << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext
>> &C, "
>> << "Sema &S,\n"
>> << " const MultiLevelTemplateArgumentList &TemplateArgs) {\n"
>> - << " switch (At->getKind()) {\n"
>> - << " default:\n"
>> - << " break;\n";
>> + << " switch (At->getKind()) {\n";
>>
>> for (const auto *Attr : Attrs) {
>> const Record &R = *Attr;
>> @@ -2788,11 +2908,7 @@ void EmitClangAttrParsedAttrKinds(Record
>> void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) {
>> emitSourceFileHeader("Attribute dumper", OS);
>>
>> - OS <<
>> - " switch (A->getKind()) {\n"
>> - " default:\n"
>> - " llvm_unreachable(\"Unknown attribute kind!\");\n"
>> - " break;\n";
>> + OS << " switch (A->getKind()) {\n";
>> std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
>> Args;
>> for (const auto *Attr : Attrs) {
>> const Record &R = *Attr;
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160229/fc50b511/attachment-0001.html>
More information about the cfe-commits
mailing list