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>;
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">;
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;
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:
--- /dev/null
+// 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