summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2013-12-18 23:44:18 +0000
committerAaron Ballman <aaron@aaronballman.com>2013-12-18 23:44:18 +0000
commit6adb540cf817f23df9f232aaf4a96d1a6633fa4a (patch)
tree6be71f271aa19c04a26b6ae5bb6e84b6ef3ed8b1
parent264ee6dc5ca465e36180fe0d12e01feb6f07c79e (diff)
downloadclang-6adb540cf817f23df9f232aaf4a96d1a6633fa4a.tar.gz
Refactor the Microsoft inheritance attribute handling so that it no longer has special treatment. Also fixes a minor bug where the attributes were being parsed as though they were GNU-style attributes when they were in fact keyword attributes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@197629 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Attr.h15
-rw-r--r--include/clang/Basic/Attr.td33
-rw-r--r--include/clang/Basic/AttrKinds.h1
-rw-r--r--lib/AST/AttrImpl.cpp2
-rw-r--r--lib/AST/MicrosoftCXXABI.cpp22
-rw-r--r--lib/Parse/ParseDeclCXX.cpp2
-rw-r--r--lib/Sema/SemaDeclAttr.cpp8
-rw-r--r--lib/Sema/SemaType.cpp5
-rw-r--r--utils/TableGen/ClangAttrEmitter.cpp17
9 files changed, 33 insertions, 72 deletions
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 7dbf41350a..d5dc537baf 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -136,21 +136,6 @@ public:
}
};
-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_INHERITANCE &&
- 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 f8e4eeb222..b8a60fb10a 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -1271,26 +1271,21 @@ def UPtr : TypeAttr {
let ASTNode = 0;
}
-class MSInheritanceAttr : InheritableAttr {
+def MSInheritance : InheritableAttr {
let LangOpts = [MicrosoftExt];
-}
-
-def SingleInheritance : MSInheritanceAttr {
- let Spellings = [Keyword<"__single_inheritance">];
-}
-
-def MultipleInheritance : MSInheritanceAttr {
- let Spellings = [Keyword<"__multiple_inheritance">];
-}
-
-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 = [];
+ let Spellings = [Keyword<"__single_inheritance">,
+ Keyword<"__multiple_inheritance">,
+ Keyword<"__virtual_inheritance">,
+ // We use an empty string to denote an unspecified
+ // inheritance attribute.
+ Keyword<"">];
+ let Accessors = [Accessor<"IsSingle", [Keyword<"__single_inheritance">]>,
+ Accessor<"IsMultiple", [Keyword<"__multiple_inheritance">]>,
+ Accessor<"IsVirtual", [Keyword<"__virtual_inheritance">]>,
+ Accessor<"IsUnspecified", [Keyword<"">]>];
+ // This index is based off the Spellings list and corresponds to the empty
+ // keyword "spelling."
+ let AdditionalMembers = [{static const int UnspecifiedSpellingIndex = 3;}];
}
def Unaligned : IgnoredAttr {
diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h
index 7c4e2c75f0..150a30e73d 100644
--- a/include/clang/Basic/AttrKinds.h
+++ b/include/clang/Basic/AttrKinds.h
@@ -24,7 +24,6 @@ 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_INHERITANCE_ATTR(X) X, LAST_MS_INHERITANCE = X,
#include "clang/Basic/AttrList.inc"
NUM_ATTRS
};
diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp
index 7af3c8b162..0bf6bcd909 100644
--- a/lib/AST/AttrImpl.cpp
+++ b/lib/AST/AttrImpl.cpp
@@ -24,6 +24,4 @@ void InheritableAttr::anchor() { }
void InheritableParamAttr::anchor() { }
-void MSInheritanceAttr::anchor() { }
-
#include "clang/AST/AttrImpl.inc"
diff --git a/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp
index 4a93ea1f41..f4037abebb 100644
--- a/lib/AST/MicrosoftCXXABI.cpp
+++ b/lib/AST/MicrosoftCXXABI.cpp
@@ -92,19 +92,21 @@ static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
return false;
}
-static MSInheritanceModel MSInheritanceAttrToModel(attr::Kind Kind) {
- switch (Kind) {
- default: llvm_unreachable("expected MS inheritance attribute");
- case attr::SingleInheritance: return MSIM_Single;
- case attr::MultipleInheritance: return MSIM_Multiple;
- case attr::VirtualInheritance: return MSIM_Virtual;
- case attr::UnspecifiedInheritance: return MSIM_Unspecified;
- }
+static MSInheritanceModel MSInheritanceAttrToModel(MSInheritanceAttr *Attr) {
+ if (Attr->IsSingle())
+ return MSIM_Single;
+ else if (Attr->IsMultiple())
+ return MSIM_Multiple;
+ else if (Attr->IsVirtual())
+ return MSIM_Virtual;
+
+ assert(Attr->IsUnspecified() && "Expected unspecified inheritance attr");
+ return MSIM_Unspecified;
}
MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
- if (Attr *IA = this->getAttr<MSInheritanceAttr>())
- return MSInheritanceAttrToModel(IA->getKind());
+ if (MSInheritanceAttr *IA = this->getAttr<MSInheritanceAttr>())
+ return MSInheritanceAttrToModel(IA);
// If there was no explicit attribute, the record must be defined already, and
// we can figure out the inheritance model from its other properties.
if (this->getNumVBases() > 0)
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 2d6523cfe4..4f86ba42db 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -998,7 +998,7 @@ void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
SourceLocation AttrNameLoc = ConsumeToken();
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
- AttributeList::AS_GNU);
+ AttributeList::AS_Keyword);
}
}
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index b44506c0a3..01a1bed0d4 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -4091,12 +4091,8 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_Uuid:
handleUuidAttr(S, D, Attr);
break;
- case AttributeList::AT_SingleInheritance:
- handleSimpleAttribute<SingleInheritanceAttr>(S, D, Attr); break;
- case AttributeList::AT_MultipleInheritance:
- handleSimpleAttribute<MultipleInheritanceAttr>(S, D, Attr); break;
- case AttributeList::AT_VirtualInheritance:
- handleSimpleAttribute<VirtualInheritanceAttr>(S, D, Attr); break;
+ case AttributeList::AT_MSInheritance:
+ handleSimpleAttribute<MSInheritanceAttr>(S, D, Attr); break;
case AttributeList::AT_ForceInline:
handleSimpleAttribute<ForceInlineAttr>(S, D, Attr); break;
case AttributeList::AT_SelectAny:
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 59b965b38c..961d14f619 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1773,8 +1773,9 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
// figure out the inheritance model.
for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(),
E = RD->redecls_end(); I != E; ++I) {
- I->addAttr(::new (Context) UnspecifiedInheritanceAttr(
- RD->getSourceRange(), Context));
+ I->addAttr(::new (Context) MSInheritanceAttr(RD->getSourceRange(),
+ Context,
+ MSInheritanceAttr::UnspecifiedSpellingIndex));
}
}
}
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index 3b2b9cef76..9641480908 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -1387,20 +1387,10 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
" INHERITABLE_PARAM_ATTR(NAME)\n";
OS << "#endif\n\n";
- OS << "#ifndef MS_INHERITANCE_ATTR\n";
- OS << "#define MS_INHERITANCE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
- OS << "#endif\n\n";
-
- OS << "#ifndef LAST_MS_INHERITANCE_ATTR\n";
- OS << "#define LAST_MS_INHERITANCE_ATTR(NAME)"
- " MS_INHERITANCE_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, MSInhAttrs;
+ NonInhAttrs, InhAttrs, InhParamAttrs;
for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
i != e; ++i) {
if (!(*i)->getValueAsBit("ASTNode"))
@@ -1408,8 +1398,6 @@ 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
@@ -1417,16 +1405,13 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
}
EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
- EmitAttrList(OS, "MS_INHERITANCE_ATTR", MSInhAttrs);
EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
EmitAttrList(OS, "ATTR", NonInhAttrs);
OS << "#undef LAST_ATTR\n";
OS << "#undef INHERITABLE_ATTR\n";
- OS << "#undef MS_INHERITANCE_ATTR\n";
OS << "#undef LAST_INHERITABLE_ATTR\n";
OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
- OS << "#undef LAST_MS_INHERITANCE_ATTR\n";
OS << "#undef ATTR\n";
}