diff options
-rw-r--r-- | include/clang/AST/Attr.h | 17 | ||||
-rw-r--r-- | include/clang/Basic/Attr.td | 14 | ||||
-rw-r--r-- | include/clang/Basic/AttrKinds.h | 1 | ||||
-rw-r--r-- | lib/AST/AttrImpl.cpp | 2 | ||||
-rw-r--r-- | utils/TableGen/ClangAttrEmitter.cpp | 17 |
5 files changed, 47 insertions, 4 deletions
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 61c57f9928..27dcef2a1e 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -129,10 +129,27 @@ 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; } }; +class MSInheritanceAttr : public InheritableAttr { + virtual void anchor(); +protected: + MSInheritanceAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0) + : InheritableAttr(AK, R, SpellingListIndex) {} + +public: + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { + // Relies on relative order of enum emission with respect to param attrs. + return (A->getKind() <= attr::LAST_MS_INHERITABLE && + A->getKind() > attr::LAST_INHERITABLE_PARAM); + } +}; + #include "clang/AST/Attrs.inc" } // end namespace clang diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 47905bf8b1..37aa332b81 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -956,18 +956,26 @@ def Ptr64 : InheritableAttr { let Spellings = [Keyword<"__ptr64">]; } -def SingleInheritance : InheritableAttr { +class MSInheritanceAttr : InheritableAttr; + +def SingleInheritance : MSInheritanceAttr { let Spellings = [Keyword<"__single_inheritance">]; } -def MultipleInheritance : InheritableAttr { +def MultipleInheritance : MSInheritanceAttr { let Spellings = [Keyword<"__multiple_inheritance">]; } -def VirtualInheritance : InheritableAttr { +def VirtualInheritance : MSInheritanceAttr { let Spellings = [Keyword<"__virtual_inheritance">]; } +// This attribute doesn't have any spellings, but we can apply it implicitly to +// incomplete types that lack any of the other attributes. +def UnspecifiedInheritance : MSInheritanceAttr { + let Spellings = []; +} + def Unaligned : IgnoredAttr { let Spellings = [Keyword<"__unaligned">]; } diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h index 150a30e73d..bd090ecc0d 100644 --- a/include/clang/Basic/AttrKinds.h +++ b/include/clang/Basic/AttrKinds.h @@ -24,6 +24,7 @@ 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 LAST_MS_INHERITABLE_ATTR(X) X, LAST_MS_INHERITABLE = X, #include "clang/Basic/AttrList.inc" NUM_ATTRS }; diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp index 0a4f7ea556..daf65e56bd 100644 --- a/lib/AST/AttrImpl.cpp +++ b/lib/AST/AttrImpl.cpp @@ -23,4 +23,6 @@ void InheritableAttr::anchor() { } void InheritableParamAttr::anchor() { } +void MSInheritanceAttr::anchor() { } + #include "clang/AST/AttrImpl.inc" diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index 544ec29fab..7c8603fc6c 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -1052,10 +1052,20 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { " INHERITABLE_PARAM_ATTR(NAME)\n"; OS << "#endif\n\n"; + OS << "#ifndef MS_INHERITABLE_ATTR\n"; + OS << "#define MS_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n"; + OS << "#endif\n\n"; + + OS << "#ifndef LAST_MS_INHERITABLE_ATTR\n"; + OS << "#define LAST_MS_INHERITABLE_ATTR(NAME)" + " MS_INHERITABLE_ATTR(NAME)\n"; + OS << "#endif\n\n"; + Record *InhClass = Records.getClass("InheritableAttr"); Record *InhParamClass = Records.getClass("InheritableParamAttr"); + Record *MSInheritanceClass = Records.getClass("MSInheritanceAttr"); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), - NonInhAttrs, InhAttrs, InhParamAttrs; + NonInhAttrs, InhAttrs, InhParamAttrs, MSInhAttrs; for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i) { if (!(*i)->getValueAsBit("ASTNode")) @@ -1063,6 +1073,8 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { if ((*i)->isSubClassOf(InhParamClass)) InhParamAttrs.push_back(*i); + else if ((*i)->isSubClassOf(MSInheritanceClass)) + MSInhAttrs.push_back(*i); else if ((*i)->isSubClassOf(InhClass)) InhAttrs.push_back(*i); else @@ -1070,13 +1082,16 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { } EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs); + EmitAttrList(OS, "MS_INHERITABLE_ATTR", MSInhAttrs); EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs); EmitAttrList(OS, "ATTR", NonInhAttrs); OS << "#undef LAST_ATTR\n"; OS << "#undef INHERITABLE_ATTR\n"; + OS << "#undef MS_INHERITABLE_ATTR\n"; OS << "#undef LAST_INHERITABLE_ATTR\n"; OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n"; + OS << "#undef LAST_MS_INHERITABLE_ATTR\n"; OS << "#undef ATTR\n"; } |