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 <rjmcc...@apple.com> wrote: > On Feb 29, 2016, at 5:44 PM, Sean Silva <chisophu...@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@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@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > > >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits