mirror of https://github.com/microsoft/clang.git
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
This commit is contained in:
parent
264ee6dc5c
commit
6adb540cf8
|
@ -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"
|
#include "clang/AST/Attrs.inc"
|
||||||
|
|
||||||
} // end namespace clang
|
} // end namespace clang
|
||||||
|
|
|
@ -1271,26 +1271,21 @@ def UPtr : TypeAttr {
|
||||||
let ASTNode = 0;
|
let ASTNode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MSInheritanceAttr : InheritableAttr {
|
def MSInheritance : InheritableAttr {
|
||||||
let LangOpts = [MicrosoftExt];
|
let LangOpts = [MicrosoftExt];
|
||||||
}
|
let Spellings = [Keyword<"__single_inheritance">,
|
||||||
|
Keyword<"__multiple_inheritance">,
|
||||||
def SingleInheritance : MSInheritanceAttr {
|
Keyword<"__virtual_inheritance">,
|
||||||
let Spellings = [Keyword<"__single_inheritance">];
|
// We use an empty string to denote an unspecified
|
||||||
}
|
// inheritance attribute.
|
||||||
|
Keyword<"">];
|
||||||
def MultipleInheritance : MSInheritanceAttr {
|
let Accessors = [Accessor<"IsSingle", [Keyword<"__single_inheritance">]>,
|
||||||
let Spellings = [Keyword<"__multiple_inheritance">];
|
Accessor<"IsMultiple", [Keyword<"__multiple_inheritance">]>,
|
||||||
}
|
Accessor<"IsVirtual", [Keyword<"__virtual_inheritance">]>,
|
||||||
|
Accessor<"IsUnspecified", [Keyword<"">]>];
|
||||||
def VirtualInheritance : MSInheritanceAttr {
|
// This index is based off the Spellings list and corresponds to the empty
|
||||||
let Spellings = [Keyword<"__virtual_inheritance">];
|
// keyword "spelling."
|
||||||
}
|
let AdditionalMembers = [{static const int UnspecifiedSpellingIndex = 3;}];
|
||||||
|
|
||||||
// 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 {
|
def Unaligned : IgnoredAttr {
|
||||||
|
|
|
@ -24,7 +24,6 @@ enum Kind {
|
||||||
#define ATTR(X) X,
|
#define ATTR(X) X,
|
||||||
#define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X,
|
#define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X,
|
||||||
#define LAST_INHERITABLE_PARAM_ATTR(X) X, LAST_INHERITABLE_PARAM = 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"
|
#include "clang/Basic/AttrList.inc"
|
||||||
NUM_ATTRS
|
NUM_ATTRS
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,6 +24,4 @@ void InheritableAttr::anchor() { }
|
||||||
|
|
||||||
void InheritableParamAttr::anchor() { }
|
void InheritableParamAttr::anchor() { }
|
||||||
|
|
||||||
void MSInheritanceAttr::anchor() { }
|
|
||||||
|
|
||||||
#include "clang/AST/AttrImpl.inc"
|
#include "clang/AST/AttrImpl.inc"
|
||||||
|
|
|
@ -92,19 +92,21 @@ static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MSInheritanceModel MSInheritanceAttrToModel(attr::Kind Kind) {
|
static MSInheritanceModel MSInheritanceAttrToModel(MSInheritanceAttr *Attr) {
|
||||||
switch (Kind) {
|
if (Attr->IsSingle())
|
||||||
default: llvm_unreachable("expected MS inheritance attribute");
|
return MSIM_Single;
|
||||||
case attr::SingleInheritance: return MSIM_Single;
|
else if (Attr->IsMultiple())
|
||||||
case attr::MultipleInheritance: return MSIM_Multiple;
|
return MSIM_Multiple;
|
||||||
case attr::VirtualInheritance: return MSIM_Virtual;
|
else if (Attr->IsVirtual())
|
||||||
case attr::UnspecifiedInheritance: return MSIM_Unspecified;
|
return MSIM_Virtual;
|
||||||
}
|
|
||||||
|
assert(Attr->IsUnspecified() && "Expected unspecified inheritance attr");
|
||||||
|
return MSIM_Unspecified;
|
||||||
}
|
}
|
||||||
|
|
||||||
MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
|
MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
|
||||||
if (Attr *IA = this->getAttr<MSInheritanceAttr>())
|
if (MSInheritanceAttr *IA = this->getAttr<MSInheritanceAttr>())
|
||||||
return MSInheritanceAttrToModel(IA->getKind());
|
return MSInheritanceAttrToModel(IA);
|
||||||
// If there was no explicit attribute, the record must be defined already, and
|
// If there was no explicit attribute, the record must be defined already, and
|
||||||
// we can figure out the inheritance model from its other properties.
|
// we can figure out the inheritance model from its other properties.
|
||||||
if (this->getNumVBases() > 0)
|
if (this->getNumVBases() > 0)
|
||||||
|
|
|
@ -998,7 +998,7 @@ void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {
|
||||||
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
|
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
|
||||||
SourceLocation AttrNameLoc = ConsumeToken();
|
SourceLocation AttrNameLoc = ConsumeToken();
|
||||||
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
|
attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
|
||||||
AttributeList::AS_GNU);
|
AttributeList::AS_Keyword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4091,12 +4091,8 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
||||||
case AttributeList::AT_Uuid:
|
case AttributeList::AT_Uuid:
|
||||||
handleUuidAttr(S, D, Attr);
|
handleUuidAttr(S, D, Attr);
|
||||||
break;
|
break;
|
||||||
case AttributeList::AT_SingleInheritance:
|
case AttributeList::AT_MSInheritance:
|
||||||
handleSimpleAttribute<SingleInheritanceAttr>(S, D, Attr); break;
|
handleSimpleAttribute<MSInheritanceAttr>(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_ForceInline:
|
case AttributeList::AT_ForceInline:
|
||||||
handleSimpleAttribute<ForceInlineAttr>(S, D, Attr); break;
|
handleSimpleAttribute<ForceInlineAttr>(S, D, Attr); break;
|
||||||
case AttributeList::AT_SelectAny:
|
case AttributeList::AT_SelectAny:
|
||||||
|
|
|
@ -1773,8 +1773,9 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
|
||||||
// figure out the inheritance model.
|
// figure out the inheritance model.
|
||||||
for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(),
|
for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(),
|
||||||
E = RD->redecls_end(); I != E; ++I) {
|
E = RD->redecls_end(); I != E; ++I) {
|
||||||
I->addAttr(::new (Context) UnspecifiedInheritanceAttr(
|
I->addAttr(::new (Context) MSInheritanceAttr(RD->getSourceRange(),
|
||||||
RD->getSourceRange(), Context));
|
Context,
|
||||||
|
MSInheritanceAttr::UnspecifiedSpellingIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1387,20 +1387,10 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
|
||||||
" INHERITABLE_PARAM_ATTR(NAME)\n";
|
" INHERITABLE_PARAM_ATTR(NAME)\n";
|
||||||
OS << "#endif\n\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 *InhClass = Records.getClass("InheritableAttr");
|
||||||
Record *InhParamClass = Records.getClass("InheritableParamAttr");
|
Record *InhParamClass = Records.getClass("InheritableParamAttr");
|
||||||
Record *MSInheritanceClass = Records.getClass("MSInheritanceAttr");
|
|
||||||
std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
|
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();
|
for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
|
||||||
i != e; ++i) {
|
i != e; ++i) {
|
||||||
if (!(*i)->getValueAsBit("ASTNode"))
|
if (!(*i)->getValueAsBit("ASTNode"))
|
||||||
|
@ -1408,8 +1398,6 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
|
||||||
|
|
||||||
if ((*i)->isSubClassOf(InhParamClass))
|
if ((*i)->isSubClassOf(InhParamClass))
|
||||||
InhParamAttrs.push_back(*i);
|
InhParamAttrs.push_back(*i);
|
||||||
else if ((*i)->isSubClassOf(MSInheritanceClass))
|
|
||||||
MSInhAttrs.push_back(*i);
|
|
||||||
else if ((*i)->isSubClassOf(InhClass))
|
else if ((*i)->isSubClassOf(InhClass))
|
||||||
InhAttrs.push_back(*i);
|
InhAttrs.push_back(*i);
|
||||||
else
|
else
|
||||||
|
@ -1417,16 +1405,13 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
|
EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
|
||||||
EmitAttrList(OS, "MS_INHERITANCE_ATTR", MSInhAttrs);
|
|
||||||
EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
|
EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
|
||||||
EmitAttrList(OS, "ATTR", NonInhAttrs);
|
EmitAttrList(OS, "ATTR", NonInhAttrs);
|
||||||
|
|
||||||
OS << "#undef LAST_ATTR\n";
|
OS << "#undef LAST_ATTR\n";
|
||||||
OS << "#undef INHERITABLE_ATTR\n";
|
OS << "#undef INHERITABLE_ATTR\n";
|
||||||
OS << "#undef MS_INHERITANCE_ATTR\n";
|
|
||||||
OS << "#undef LAST_INHERITABLE_ATTR\n";
|
OS << "#undef LAST_INHERITABLE_ATTR\n";
|
||||||
OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
|
OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
|
||||||
OS << "#undef LAST_MS_INHERITANCE_ATTR\n";
|
|
||||||
OS << "#undef ATTR\n";
|
OS << "#undef ATTR\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue