[objc] Introduce attribute 'objc_designated_initializer'.
It only applies to methods of init family in an interface declaration. llvm-svn: 196314
This commit is contained in:
parent
fd9acf6a48
commit
d1438b446e
|
@ -684,6 +684,11 @@ def ObjCSuppressProtocol : InheritableAttr {
|
|||
let Args = [IdentifierArgument<"Protocol">];
|
||||
}
|
||||
|
||||
def ObjCDesignatedInitializer : Attr {
|
||||
let Spellings = [GNU<"objc_designated_initializer">];
|
||||
let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
|
||||
}
|
||||
|
||||
def Overloadable : Attr {
|
||||
let Spellings = [GNU<"overloadable">];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
|
|
|
@ -2427,6 +2427,12 @@ def warn_objc_requires_super_protocol : Warning<
|
|||
def note_protocol_decl : Note<
|
||||
"protocol is declared here">;
|
||||
|
||||
// objc_designated_initializer attribute diagnostics.
|
||||
def err_attr_objc_designated_not_init_family : Error<
|
||||
"'objc_designated_initializer' only applies to methods of the init family">;
|
||||
def err_attr_objc_designated_not_interface : Error<
|
||||
"'objc_designated_initializer' only applies to methods of interface declarations">;
|
||||
|
||||
def err_ns_bridged_not_interface : Error<
|
||||
"parameter of 'ns_bridged' attribute does not name an Objective-C class">;
|
||||
|
||||
|
|
|
@ -3713,6 +3713,28 @@ static void handleObjCBridgeMutableAttr(Sema &S, Scope *Sc, Decl *D,
|
|||
Attr.getAttributeSpellingListIndex()));
|
||||
}
|
||||
|
||||
static void handleObjCDesignatedInitializer(Sema &S, Decl *D,
|
||||
const AttributeList &Attr) {
|
||||
SourceLocation Loc = Attr.getLoc();
|
||||
ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
|
||||
|
||||
if (Method->getMethodFamily() != OMF_init) {
|
||||
S.Diag(D->getLocStart(), diag::err_attr_objc_designated_not_init_family)
|
||||
<< SourceRange(Loc, Loc);
|
||||
return;
|
||||
}
|
||||
DeclContext *DC = Method->getDeclContext();
|
||||
if (!isa<ObjCInterfaceDecl>(DC)) {
|
||||
S.Diag(D->getLocStart(), diag::err_attr_objc_designated_not_interface)
|
||||
<< SourceRange(Loc, Loc);
|
||||
return;
|
||||
}
|
||||
|
||||
Method->addAttr(::new (S.Context)
|
||||
ObjCDesignatedInitializerAttr(Attr.getRange(), S.Context,
|
||||
Attr.getAttributeSpellingListIndex()));
|
||||
}
|
||||
|
||||
static void handleObjCOwnershipAttr(Sema &S, Decl *D,
|
||||
const AttributeList &Attr) {
|
||||
if (hasDeclarator(D)) return;
|
||||
|
@ -3963,6 +3985,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
|||
case AttributeList::AT_ObjCBridgeMutable:
|
||||
handleObjCBridgeMutableAttr(S, scope, D, Attr); break;
|
||||
|
||||
case AttributeList::AT_ObjCDesignatedInitializer:
|
||||
handleObjCDesignatedInitializer(S, D, Attr); break;
|
||||
|
||||
case AttributeList::AT_CFAuditedTransfer:
|
||||
handleCFAuditedTransferAttr(S, D, Attr); break;
|
||||
case AttributeList::AT_CFUnknownTransfer:
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
|
||||
|
||||
void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods}}
|
||||
|
||||
@protocol P1
|
||||
-(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of interface declarations}}
|
||||
@end
|
||||
|
||||
__attribute__((objc_root_class))
|
||||
@interface I1
|
||||
-(void)meth NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of the init family}}
|
||||
-(id)init NS_DESIGNATED_INITIALIZER;
|
||||
+(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of the init family}}
|
||||
@end
|
||||
|
||||
@interface I1(cat)
|
||||
-(id)init2 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of interface declarations}}
|
||||
@end
|
||||
|
||||
@interface I1()
|
||||
-(id)init3 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of interface declarations}}
|
||||
@end
|
||||
|
||||
@implementation I1
|
||||
-(void)meth {}
|
||||
-(id)init NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to methods of interface declarations}}
|
||||
+(id)init { return 0; }
|
||||
-(id)init3 { return 0; }
|
||||
-(id)init4 NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to methods of interface declarations}}
|
||||
@end
|
Loading…
Reference in New Issue