aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Attr.h17
-rw-r--r--include/clang/Basic/Attr.td14
-rw-r--r--include/clang/Basic/AttrKinds.h1
-rw-r--r--lib/AST/AttrImpl.cpp2
-rw-r--r--utils/TableGen/ClangAttrEmitter.cpp17
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";
}