зеркало из https://github.com/microsoft/clang.git
Semantics of @protocol attributes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61114 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
cb73530987
Коммит
bc1c877fe2
|
@ -45,6 +45,7 @@ public:
|
|||
Packed,
|
||||
StdCall,
|
||||
TransparentUnion,
|
||||
Unavailable,
|
||||
Unused,
|
||||
Visibility,
|
||||
Weak,
|
||||
|
@ -65,6 +66,10 @@ public:
|
|||
}
|
||||
|
||||
Kind getKind() const { return AttrKind; }
|
||||
|
||||
bool hasKind(Kind kind) const {
|
||||
return AttrKind == kind;
|
||||
}
|
||||
|
||||
Attr *getNext() { return Next; }
|
||||
const Attr *getNext() const { return Next; }
|
||||
|
@ -219,6 +224,16 @@ public:
|
|||
static bool classof(const DeprecatedAttr *A) { return true; }
|
||||
};
|
||||
|
||||
class UnavailableAttr : public Attr {
|
||||
public:
|
||||
UnavailableAttr() : Attr(Unavailable) {}
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
|
||||
static bool classof(const Attr *A) { return A->getKind() == Unavailable; }
|
||||
static bool classof(const UnavailableAttr *A) { return true; }
|
||||
};
|
||||
|
||||
class UnusedAttr : public Attr {
|
||||
public:
|
||||
UnusedAttr() : Attr(Unused) {}
|
||||
|
|
|
@ -974,6 +974,8 @@ DIAG(err_undeclared_use, ERROR,
|
|||
"use of undeclared '%0'")
|
||||
DIAG(warn_deprecated, WARNING,
|
||||
"%0 is deprecated")
|
||||
DIAG(warn_unavailable, WARNING,
|
||||
"%0 is unavailable")
|
||||
DIAG(err_redefinition, ERROR,
|
||||
"redefinition of %0")
|
||||
DIAG(err_static_non_static, ERROR,
|
||||
|
|
|
@ -1072,7 +1072,8 @@ public:
|
|||
virtual DeclTy *ActOnForwardProtocolDeclaration(
|
||||
SourceLocation AtProtocolLoc,
|
||||
const IdentifierLocPair*IdentList,
|
||||
unsigned NumElts) {
|
||||
unsigned NumElts,
|
||||
AttributeList *AttrList) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ public:
|
|||
AT_pure,
|
||||
AT_stdcall,
|
||||
AT_transparent_union,
|
||||
AT_unavailable,
|
||||
AT_unused,
|
||||
AT_vector_size,
|
||||
AT_visibility,
|
||||
|
|
|
@ -94,6 +94,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
|
|||
case 11:
|
||||
if (!memcmp(Str, "vector_size", 11)) return AT_vector_size;
|
||||
if (!memcmp(Str, "constructor", 11)) return AT_constructor;
|
||||
if (!memcmp(Str, "unavailable", 11)) return AT_unavailable;
|
||||
break;
|
||||
case 13:
|
||||
if (!memcmp(Str, "address_space", 13)) return AT_address_space;
|
||||
|
|
|
@ -936,7 +936,8 @@ Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
|
|||
if (Tok.is(tok::semi)) { // forward declaration of one protocol.
|
||||
IdentifierLocPair ProtoInfo(protocolName, nameLoc);
|
||||
ConsumeToken();
|
||||
return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1);
|
||||
return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
|
||||
attrList);
|
||||
}
|
||||
|
||||
if (Tok.is(tok::comma)) { // list of forward declarations.
|
||||
|
@ -964,7 +965,8 @@ Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
|
|||
|
||||
return Actions.ActOnForwardProtocolDeclaration(AtLoc,
|
||||
&ProtocolRefs[0],
|
||||
ProtocolRefs.size());
|
||||
ProtocolRefs.size(),
|
||||
attrList);
|
||||
}
|
||||
|
||||
// Last, and definitely not least, parse a protocol declaration.
|
||||
|
|
|
@ -1063,7 +1063,8 @@ public:
|
|||
|
||||
virtual DeclTy *ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
|
||||
const IdentifierLocPair *IdentList,
|
||||
unsigned NumElts);
|
||||
unsigned NumElts,
|
||||
AttributeList *attrList);
|
||||
|
||||
virtual void FindProtocolDeclaration(bool WarnOnDeclarations,
|
||||
const IdentifierLocPair *ProtocolId,
|
||||
|
|
|
@ -501,6 +501,16 @@ static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
|||
d->addAttr(new DeprecatedAttr());
|
||||
}
|
||||
|
||||
static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
||||
// check the attribute arguments.
|
||||
if (Attr.getNumArgs() != 0) {
|
||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
d->addAttr(new UnavailableAttr());
|
||||
}
|
||||
|
||||
static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
||||
// check the attribute arguments.
|
||||
if (Attr.getNumArgs() != 1) {
|
||||
|
@ -1126,6 +1136,7 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
|
|||
case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
|
||||
case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
|
||||
case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break;
|
||||
|
|
|
@ -207,7 +207,8 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
|
|||
PDecl->setForwardDecl(false);
|
||||
ObjCProtocols[ProtocolName] = PDecl;
|
||||
}
|
||||
|
||||
if (AttrList)
|
||||
ProcessDeclAttributeList(PDecl, AttrList);
|
||||
if (NumProtoRefs) {
|
||||
/// Check then save referenced protocols.
|
||||
PDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
|
||||
|
@ -233,6 +234,14 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
|
|||
<< ProtocolId[i].first;
|
||||
continue;
|
||||
}
|
||||
for (const Attr *attr = PDecl->getAttrs(); attr; attr = attr->getNext()) {
|
||||
if (attr->hasKind(Attr::Unavailable))
|
||||
Diag(ProtocolId[i].second, diag::warn_unavailable) <<
|
||||
PDecl->getDeclName();
|
||||
if (attr->hasKind(Attr::Deprecated))
|
||||
Diag(ProtocolId[i].second, diag::warn_deprecated) <<
|
||||
PDecl->getDeclName();
|
||||
}
|
||||
|
||||
// If this is a forward declaration and we are supposed to warn in this
|
||||
// case, do it.
|
||||
|
@ -417,7 +426,8 @@ Sema::MergeProtocolPropertiesIntoClass(Decl *CDecl,
|
|||
Action::DeclTy *
|
||||
Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
|
||||
const IdentifierLocPair *IdentList,
|
||||
unsigned NumElts) {
|
||||
unsigned NumElts,
|
||||
AttributeList *attrList) {
|
||||
llvm::SmallVector<ObjCProtocolDecl*, 32> Protocols;
|
||||
|
||||
for (unsigned i = 0; i != NumElts; ++i) {
|
||||
|
@ -425,7 +435,8 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
|
|||
ObjCProtocolDecl *&PDecl = ObjCProtocols[Ident];
|
||||
if (PDecl == 0) // Not already seen?
|
||||
PDecl = ObjCProtocolDecl::Create(Context, IdentList[i].second, Ident);
|
||||
|
||||
if (attrList)
|
||||
ProcessDeclAttributeList(PDecl, attrList);
|
||||
Protocols.push_back(PDecl);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// RUN: clang -fsyntax-only -verify %s
|
||||
|
||||
__attribute ((unavailable))
|
||||
@protocol FwProto;
|
||||
|
||||
Class <FwProto> cFw = 0; // expected-warning {{'FwProto' is unavailable}}
|
||||
|
||||
|
||||
__attribute ((deprecated)) @protocol MyProto1
|
||||
@end
|
||||
|
||||
@protocol Proto2 <MyProto1> // expected-warning {{'MyProto1' is deprecated}}
|
||||
+method2;
|
||||
@end
|
||||
|
||||
|
||||
@interface MyClass1 <MyProto1> // expected-warning {{'MyProto1' is deprecated}}
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface Derived : MyClass1 <MyProto1> // expected-warning {{'MyProto1' is deprecated}}
|
||||
{
|
||||
id <MyProto1> ivar; // expected-warning {{'MyProto1' is deprecated}}
|
||||
}
|
||||
@end
|
||||
|
||||
@interface MyClass1 (Category) <MyProto1, Proto2> // expected-warning {{'MyProto1' is deprecated}}
|
||||
@end
|
||||
|
||||
|
||||
|
||||
Class <MyProto1> clsP1 = 0; // expected-warning {{'MyProto1' is deprecated}}
|
||||
|
||||
@protocol FwProto @end
|
||||
|
||||
@interface MyClass2 <FwProto> // expected-warning {{'FwProto' is unavailable}}
|
||||
@end
|
||||
|
||||
__attribute ((unavailable)) __attribute ((deprecated)) @protocol XProto;
|
||||
|
||||
id <XProto> idX = 0; // expected-warning {{'XProto' is unavailable}} expected-warning {{'XProto' is deprecated}}
|
||||
|
||||
int main ()
|
||||
{
|
||||
MyClass1 <MyProto1> *p1; // expected-warning {{'MyProto1' is deprecated}}
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче