<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Dec 3, 2013, at 1:38 PM, Aaron Ballman <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">On Tue, Dec 3, 2013 at 4:11 PM, Argyrios Kyrtzidis <<a href="mailto:akyrtzi@gmail.com">akyrtzi@gmail.com</a>> wrote:<br><blockquote type="cite">Author: akirtzidis<br>Date: Tue Dec 3 15:11:25 2013<br>New Revision: 196314<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=196314&view=rev">http://llvm.org/viewvc/llvm-project?rev=196314&view=rev</a><br>Log:<br>[objc] Introduce attribute 'objc_designated_initializer'.<br><br>It only applies to methods of init family in an interface declaration.<br><br>Added:<br> cfe/trunk/test/SemaObjC/attr-designated-init.m<br>Modified:<br> cfe/trunk/include/clang/Basic/Attr.td<br> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br> cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br><br>Modified: cfe/trunk/include/clang/Basic/Attr.td<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=196314&r1=196313&r2=196314&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=196314&r1=196313&r2=196314&view=diff</a><br>==============================================================================<br>--- cfe/trunk/include/clang/Basic/Attr.td (original)<br>+++ cfe/trunk/include/clang/Basic/Attr.td Tue Dec 3 15:11:25 2013<br>@@ -684,6 +684,11 @@ def ObjCSuppressProtocol : InheritableAt<br> let Args = [IdentifierArgument<"Protocol">];<br>}<br><br>+def ObjCDesignatedInitializer : Attr {<br>+ let Spellings = [GNU<"objc_designated_initializer">];<br>+ let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;<br></blockquote><br>Considering how simple the semantic checks are, I think a<br>SubsetSubject is more appropriate. Something like:<br><br>def ObjCInitFamily : SubsetSubject<ObjCMethod, [{S->getMethodFamily()<br>== OMF_init}]>;<br><br>def ObjCInterfaceDeclContext : SubsetSubject<ObjCMethod,<br>[{isa<ObjCInterfaceDecl>(S->getDeclContext())}]>;<br></div></blockquote><div><br></div><div>AFAICT there's no way to combine two SubsetSubjects; I added one in r196644.</div><br><blockquote type="cite"><div style="font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br><blockquote type="cite">+}<br>+<br>def Overloadable : Attr {<br> let Spellings = [GNU<"overloadable">];<br> let Subjects = SubjectList<[Function], ErrorDiag>;<br><br>Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=196314&r1=196313&r2=196314&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=196314&r1=196313&r2=196314&view=diff</a><br>==============================================================================<br>--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Dec 3 15:11:25 2013<br>@@ -2427,6 +2427,12 @@ def warn_objc_requires_super_protocol :<br>def note_protocol_decl : Note<<br> "protocol is declared here">;<br><br>+// objc_designated_initializer attribute diagnostics.<br>+def err_attr_objc_designated_not_init_family : Error<<br>+ "'objc_designated_initializer' only applies to methods of the init family">;<br>+def err_attr_objc_designated_not_interface : Error<<br>+ "'objc_designated_initializer' only applies to methods of interface declarations">;<br></blockquote><br>Both of these should be attached to the existing diagnostics applying<br>to attribute subjects (warn_attribute_wrong_decl_type and<br>err_attribute_wrong_decl_type). When switching over to the subset<br>subjects, you need to supply a custom error diagnostic argument<br>anyway. Don't forget to update AttributeList.h with the new enumerant.<br><br><blockquote type="cite">+<br>def err_ns_bridged_not_interface : Error<<br> "parameter of 'ns_bridged' attribute does not name an Objective-C class">;<br><br><br>Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=196314&r1=196313&r2=196314&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=196314&r1=196313&r2=196314&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)<br>+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Dec 3 15:11:25 2013<br>@@ -3713,6 +3713,28 @@ static void handleObjCBridgeMutableAttr(<br> Attr.getAttributeSpellingListIndex()));<br>}<br><br>+static void handleObjCDesignatedInitializer(Sema &S, Decl *D,<br>+ const AttributeList &Attr) {<br>+ SourceLocation Loc = Attr.getLoc();<br>+ ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);<br>+<br>+ if (Method->getMethodFamily() != OMF_init) {<br>+ S.Diag(D->getLocStart(), diag::err_attr_objc_designated_not_init_family)<br>+ << SourceRange(Loc, Loc);<br>+ return;<br>+ }<br>+ DeclContext *DC = Method->getDeclContext();<br>+ if (!isa<ObjCInterfaceDecl>(DC)) {<br>+ S.Diag(D->getLocStart(), diag::err_attr_objc_designated_not_interface)<br>+ << SourceRange(Loc, Loc);<br>+ return;<br>+ }<br>+<br>+ Method->addAttr(::new (S.Context)<br>+ ObjCDesignatedInitializerAttr(Attr.getRange(), S.Context,<br>+ Attr.getAttributeSpellingListIndex()));<br></blockquote><br>Once you use the SubsetSubjects, this entire method can go away.<br><br><blockquote type="cite">+}<br>+<br>static void handleObjCOwnershipAttr(Sema &S, Decl *D,<br> const AttributeList &Attr) {<br> if (hasDeclarator(D)) return;<br>@@ -3963,6 +3985,9 @@ static void ProcessDeclAttribute(Sema &S<br> case AttributeList::AT_ObjCBridgeMutable:<br> handleObjCBridgeMutableAttr(S, scope, D, Attr); break;<br><br>+ case AttributeList::AT_ObjCDesignatedInitializer:<br>+ handleObjCDesignatedInitializer(S, D, Attr); break;<br></blockquote><br>Once the handler method goes away, this can be replaced with:<br><br>handleSimpleAttribute<ObjCDesignatedInitializerAttr>(S, D, Attr); break;<br><br><blockquote type="cite">+<br> case AttributeList::AT_CFAuditedTransfer:<br> handleCFAuditedTransferAttr(S, D, Attr); break;<br> case AttributeList::AT_CFUnknownTransfer:<br><br>Added: cfe/trunk/test/SemaObjC/attr-designated-init.m<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-designated-init.m?rev=196314&view=auto">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-designated-init.m?rev=196314&view=auto</a><br>==============================================================================<br>--- cfe/trunk/test/SemaObjC/attr-designated-init.m (added)<br>+++ cfe/trunk/test/SemaObjC/attr-designated-init.m Tue Dec 3 15:11:25 2013<br>@@ -0,0 +1,32 @@<br>+// RUN: %clang_cc1 -fsyntax-only -verify %s<br>+<br>+#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))<br>+<br>+void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods}}<br>+<br>+@protocol P1<br>+-(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of interface declarations}}<br>+@end<br>+<br>+__attribute__((objc_root_class))<br>+@interface I1<br>+-(void)meth NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of the init family}}<br>+-(id)init NS_DESIGNATED_INITIALIZER;<br>++(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of the init family}}<br>+@end<br>+<br>+@interface I1(cat)<br>+-(id)init2 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of interface declarations}}<br>+@end<br>+<br>+@interface I1()<br>+-(id)init3 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to methods of interface declarations}}<br>+@end<br>+<br>+@implementation I1<br>+-(void)meth {}<br>+-(id)init NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to methods of interface declarations}}<br>++(id)init { return 0; }<br>+-(id)init3 { return 0; }<br>+-(id)init4 NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to methods of interface declarations}}<br>+@end<br></blockquote><br>~Aaron</div></blockquote></div><br></body></html>