From: Fariborz Jahanian Date: Wed, 16 Jul 2014 19:44:34 +0000 (+0000) Subject: Objective-C. Changes per A. Ballman's comment X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d818762dc6eeaebd4ce5c7cdfe049ad49205d2da;p=clang Objective-C. Changes per A. Ballman's comment for my last patch. // rdar://17631257 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213185 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index de5252601a..db3b084938 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -955,6 +955,9 @@ public: void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, unsigned Num, ASTContext &C); + + /// Produce a name to be used for class's metadata. It comes either via + /// objc_runtime_name attribute or class name. StringRef getObjCRuntimeNameAsString() const; /// Returns the designated initializers for the interface. @@ -1654,6 +1657,8 @@ public: /// \brief Starts the definition of this Objective-C protocol. void startDefinition(); + /// Produce a name to be used for protocol's metadata. It comes either via + /// objc_runtime_name attribute or protocol name. StringRef getObjCRuntimeNameAsString() const; SourceRange getSourceRange() const override LLVM_READONLY { @@ -2104,6 +2109,8 @@ public: return getName(); } + /// Produce a name to be used for class's metadata. It comes either via + /// class's objc_runtime_name attribute or class name. StringRef getObjCRuntimeNameAsString() const; const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 964e502716..11ad93a06b 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -993,8 +993,8 @@ def ObjCRuntimeName : Attr { let Spellings = [GNU<"objc_runtime_name">]; let Subjects = SubjectList<[ObjCInterface, ObjCProtocol], ErrorDiag, "ExpectedObjectiveCInterfaceOrProtocol">; - let Args = [StringArgument<"MetadataName", 1>]; - let Documentation = [Undocumented]; + let Args = [StringArgument<"MetadataName">]; + let Documentation = [ObjCRuntimeNameDocs]; } def OptimizeNone : InheritableAttr { diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td index 947c9ba014..18c49eefba 100644 --- a/include/clang/Basic/AttrDocs.td +++ b/include/clang/Basic/AttrDocs.td @@ -426,6 +426,25 @@ implementation of an override in a subclass does not call super. For example: }]; } +def ObjCRuntimeNameDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ + Annotation of Objective-C classes and protocols with this attribute allow to + use an alternative name for metadata names which normally use class or protocol + names as part of their names. + + **Usage**: ``__attribute__((objc_runtime_name("MyLocalName")))``. This attribute + can only be placed before an @protocol or @interface declaration: + + .. code-block:: objc + + __attribute__((objc_runtime_name("MyLocalName"))) + @interface Message + @end + + }]; +} + def AvailabilityDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index f01383a083..2204dff137 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -1201,18 +1201,19 @@ bool ObjCInterfaceDecl::hasDesignatedInitializers() const { StringRef ObjCInterfaceDecl::getObjCRuntimeNameAsString() const { - if (ObjCRuntimeNameAttr *ObjCRTName = getAttr()) - return ObjCRTName->getMetadataName(); - return getName(); + if (ObjCRuntimeNameAttr *ObjCRTName = getAttr()) + return ObjCRTName->getMetadataName(); + + return getName(); } StringRef ObjCImplementationDecl::getObjCRuntimeNameAsString() const { - if (ObjCInterfaceDecl *ID = - const_cast(this)->getClassInterface()) - return ID->getObjCRuntimeNameAsString(); + if (ObjCInterfaceDecl *ID = + const_cast(this)->getClassInterface()) + return ID->getObjCRuntimeNameAsString(); - return getName(); + return getName(); } ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const { @@ -1621,9 +1622,10 @@ void ObjCProtocolDecl::collectInheritedProtocolProperties( StringRef ObjCProtocolDecl::getObjCRuntimeNameAsString() const { - if (ObjCRuntimeNameAttr *ObjCRTName = getAttr()) - return ObjCRTName->getMetadataName(); - return getName(); + if (ObjCRuntimeNameAttr *ObjCRTName = getAttr()) + return ObjCRTName->getMetadataName(); + + return getName(); } //===----------------------------------------------------------------------===// diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 29be703320..61683cd875 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -3599,12 +3599,13 @@ static void handleObjCDesignatedInitializer(Sema &S, Decl *D, static void handleObjCRuntimeName(Sema &S, Decl *D, const AttributeList &Attr) { - StringRef MetaDataName; - if (!S.checkStringLiteralArgumentAttr(Attr, 0, MetaDataName)) - return; - D->addAttr(::new (S.Context) - ObjCRuntimeNameAttr(Attr.getRange(), S.Context, - MetaDataName, 0)); + StringRef MetaDataName; + if (!S.checkStringLiteralArgumentAttr(Attr, 0, MetaDataName)) + return; + D->addAttr(::new (S.Context) + ObjCRuntimeNameAttr(Attr.getRange(), S.Context, + MetaDataName, + Attr.getAttributeSpellingListIndex())); } static void handleObjCOwnershipAttr(Sema &S, Decl *D, diff --git a/test/SemaObjC/objc-asm-attribute-neg-test.m b/test/SemaObjC/objc-asm-attribute-neg-test.m new file mode 100644 index 0000000000..2fb6643add --- /dev/null +++ b/test/SemaObjC/objc-asm-attribute-neg-test.m @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// rdar://16462586 + +__attribute__((objc_runtime_name)) // expected-error {{'objc_runtime_name' attribute takes one argument}} +@interface BInterface +@end + +__attribute__((objc_runtime_name(123))) // expected-error {{'objc_runtime_name' attribute requires a string}} +@protocol BProtocol1 +@end + +__attribute__((objc_runtime_name("MySecretNamespace.Protocol"))) +@protocol Protocol +@end + +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) +@interface Message { +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}} + id MyIVAR; +} +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) +@property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}} + +- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}} + +- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}} + +@end + +__attribute__((objc_runtime_name("MySecretNamespace.ForwardClass"))) +@class ForwardClass; // expected-error {{prefix attribute must be followed by an interface or protocol}} + +__attribute__((objc_runtime_name("MySecretNamespace.ForwardProtocol"))) +@protocol ForwardProtocol; + +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) +@implementation Message // expected-error {{prefix attribute must be followed by an interface or protocol}} +__attribute__((objc_runtime_name("MySecretNamespace.Message"))) +- (id) MyMethod { + return MyIVAR; +} +@end