r195061 - ObjectiveC ARC. Adopt objc_bridge attribute
jahanian
fjahanian at apple.com
Tue Nov 19 09:50:40 PST 2013
On Nov 18, 2013, at 5:24 PM, Aaron Ballman <aaron at aaronballman.com> wrote:
> On Mon, Nov 18, 2013 at 7:09 PM, Fariborz Jahanian <fjahanian at apple.com> wrote:
>> Author: fjahanian
>> Date: Mon Nov 18 18:09:48 2013
>> New Revision: 195061
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=195061&view=rev
>> Log:
>> ObjectiveC ARC. Adopt objc_bridge attribute
>> on struct/union/class instead of typedef of
>> such types. // rdar://15454846
>>
>> Modified:
>> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> cfe/trunk/lib/Sema/SemaDecl.cpp
>> cfe/trunk/lib/Sema/SemaDeclAttr.cpp
>> cfe/trunk/lib/Sema/SemaExprObjC.cpp
>> cfe/trunk/test/SemaObjC/objcbridge-attribute.m
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=195061&r1=195060&r2=195061&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Nov 18 18:09:48 2013
>> @@ -2442,11 +2442,9 @@ def err_ns_bridged_not_interface : Error
>> def err_objc_bridge_not_id : Error<
>> "parameter of 'objc_bridge' attribute must be a single name of an Objective-C class">;
>> def err_objc_bridge_attribute : Error<
>> - "'objc_bridge' attribute must be put on a typedef only">;
>> + "'objc_bridge' attribute must be applied to a struct, C++ class, or union">;
>
> Please use err_attribute_wrong_decl_type instead of a custom error message.
In r195135. Also, per Doug’s comment earlier, I removed the two routines you had
comments on.
- Thanks, Fariborz
>
>> def err_objc_bridge_not_cftype : Error<
>> "'objc_bridge' attribute must be applied to definition of CF types">;
>> -def err_objc_bridge_not_pointert_to_struct : Error<
>> - "'objc_bridge' attribute must be applied to a pointer to struct type">;
>> def err_objc_cf_bridged_not_interface : Error<
>> "CF object of type %0 is bridged to '%1', which is not an Objective-C class">;
>> def err_objc_ns_bridged_invalid_cfobject : Error<
>>
>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=195061&r1=195060&r2=195061&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Nov 18 18:09:48 2013
>> @@ -10072,6 +10072,31 @@ void Sema::AddKnownFunctionAttributes(Fu
>> }
>> }
>>
>> +static inline bool isTollFreeBridgeCFRefType(TypedefDecl *TD) {
>> + TypedefNameDecl * TDefNameDecl = TD;
>
> Extra space surrounding the asterisk.
>
>> + const Type *TP = TDefNameDecl->getUnderlyingType().getTypePtr();
>> + while (const TypedefType *TDef = dyn_cast<TypedefType>(TP)) {
>> + TDefNameDecl = TDef->getDecl();
>> + TP = TDefNameDecl->getUnderlyingType().getTypePtr();
>> + }
>> +
>> + StringRef TDName = TDefNameDecl->getIdentifier()->getName();
>> + return (TDName.startswith("CF") && TDName.endswith("Ref"));
>> +}
>> +
>> +/// CheckObjCBridgeAttribute - Checks that objc_bridge attribute is
>> +/// properly applied to a typedef of a pointer to struct/union/class
>> +static void CheckObjCBridgeAttribute(Sema &S, TypedefDecl *TD) {
>> + QualType T = TD->getUnderlyingType();
>> + if (!T->isPointerType())
>> + return;
>
> This behavior doesn't match the comments -- if it's not a pointer
> type, should it not have a diagnostic?
>
>> + T = T->getPointeeType();
>> + if (T->isStructureType() || T->isUnionType() || T->isClassType())
>> + if (RecordDecl *RD = T->getAs<RecordType>()->getDecl())
>> + if (RD->hasAttr<ObjCBridgeAttr>() && !isTollFreeBridgeCFRefType(TD))
>> + S.Diag(TD->getLocStart(), diag::err_objc_bridge_not_cftype);
>> +}
>> +
>> TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
>> TypeSourceInfo *TInfo) {
>> assert(D.getIdentifier() && "Wrong callback for declspec without declarator");
>> @@ -10095,6 +10120,8 @@ TypedefDecl *Sema::ParseTypedefDecl(Scop
>> return NewTD;
>> }
>>
>> + CheckObjCBridgeAttribute(*this, NewTD);
>
> Why did this functionality move out of SemaDeclAttr.cpp and into SemaDecl.cpp?
>
>> +
>> if (D.getDeclSpec().isModulePrivateSpecified()) {
>> if (CurContext->isFunctionOrMethod())
>> Diag(NewTD->getLocation(), diag::err_module_private_local)
>>
>> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=195061&r1=195060&r2=195061&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Nov 18 18:09:48 2013
>> @@ -207,11 +207,6 @@ static inline bool isCFStringType(QualTy
>> return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
>> }
>>
>> -static inline bool isTollFreeBridgeCFRefType(TypedefNameDecl *TD, ASTContext &Ctx) {
>> - StringRef TDName = TD->getIdentifier()->getName();
>> - return (TDName.startswith("CF") && TDName.endswith("Ref"));
>> -}
>> -
>> static unsigned getNumAttributeArgs(const AttributeList &Attr) {
>> // FIXME: Include the type in the argument list.
>> return Attr.getNumArgs() + Attr.hasParsedType();
>> @@ -4396,34 +4391,7 @@ static void handleNSBridgedAttr(Sema &S,
>>
>> static void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D,
>> const AttributeList &Attr) {
>> - if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
>> - QualType T = TD->getUnderlyingType();
>> - if (T->isPointerType()) {
>> - T = T->getPointeeType();
>> - if (T->isRecordType()) {
>> - RecordDecl *RD = T->getAs<RecordType>()->getDecl();
>> - if (!RD || RD->isUnion()) {
>> - S.Diag(D->getLocStart(), diag::err_objc_bridge_not_pointert_to_struct)
>> - << Attr.getRange();
>> - return;
>> - }
>> - } else {
>> - S.Diag(TD->getLocStart(), diag::err_objc_bridge_not_pointert_to_struct)
>> - << Attr.getRange();
>> - return;
>> - }
>> - } else {
>> - S.Diag(TD->getLocStart(), diag::err_objc_bridge_not_pointert_to_struct)
>> - << Attr.getRange();
>> - return;
>> - }
>> - // Check for T being a CFType goes here.
>> - if (!isTollFreeBridgeCFRefType(TD, S.Context)) {
>> - S.Diag(TD->getLocStart(), diag::err_objc_bridge_not_cftype);
>> - return;
>> - }
>> - }
>> - else {
>> + if (!isa<RecordDecl>(D)) {
>> S.Diag(D->getLocStart(), diag::err_objc_bridge_attribute);
>> return;
>> }
>>
>> Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=195061&r1=195060&r2=195061&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Mon Nov 18 18:09:48 2013
>> @@ -3165,15 +3165,26 @@ diagnoseObjCARCConversion(Sema &S, Sourc
>> << castRange << castExpr->getSourceRange();
>> }
>>
>> +static inline ObjCBridgeAttr *getObjCBridgeAttr(const TypedefType *TD) {
>> + TypedefNameDecl *TDNDecl = TD->getDecl();
>> + QualType QT = TDNDecl->getUnderlyingType();
>> + if (QT->isPointerType()) {
>> + QT = QT->getPointeeType();
>> + if (QT->isStructureType() || QT->isUnionType() || QT->isClassType())
>> + if (RecordDecl *RD = QT->getAs<RecordType>()->getDecl())
>> + if (RD->hasAttr<ObjCBridgeAttr>())
>> + return RD->getAttr<ObjCBridgeAttr>();
>> + }
>> + return 0;
>> +}
>> +
>> static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) {
>> QualType T = castExpr->getType();
>> while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
>> TypedefNameDecl *TDNDecl = TD->getDecl();
>> - if (TDNDecl->hasAttr<ObjCBridgeAttr>()) {
>> - ObjCBridgeAttr *ObjCBAttr = TDNDecl->getAttr<ObjCBridgeAttr>();
>> - IdentifierInfo *Parm = ObjCBAttr->getBridgedType();
>> - NamedDecl *Target = 0;
>> - if (Parm && S.getLangOpts().ObjC1) {
>> + if (ObjCBridgeAttr *ObjCBAttr = getObjCBridgeAttr(TD)) {
>> + if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
>> + NamedDecl *Target = 0;
>> // Check for an existing type with this name.
>> LookupResult R(S, DeclarationName(Parm), SourceLocation(),
>> Sema::LookupOrdinaryName);
>> @@ -3215,11 +3226,9 @@ static bool CheckObjCBridgeCFCast(Sema &
>> QualType T = castType;
>> while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
>> TypedefNameDecl *TDNDecl = TD->getDecl();
>> - if (TDNDecl->hasAttr<ObjCBridgeAttr>()) {
>> - ObjCBridgeAttr *ObjCBAttr = TDNDecl->getAttr<ObjCBridgeAttr>();
>> - IdentifierInfo *Parm = ObjCBAttr->getBridgedType();
>> - NamedDecl *Target = 0;
>> - if (Parm && S.getLangOpts().ObjC1) {
>> + if (ObjCBridgeAttr *ObjCBAttr = getObjCBridgeAttr(TD)) {
>> + if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
>> + NamedDecl *Target = 0;
>> // Check for an existing type with this name.
>> LookupResult R(S, DeclarationName(Parm), SourceLocation(),
>> Sema::LookupOrdinaryName);
>>
>> Modified: cfe/trunk/test/SemaObjC/objcbridge-attribute.m
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objcbridge-attribute.m?rev=195061&r1=195060&r2=195061&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/SemaObjC/objcbridge-attribute.m (original)
>> +++ cfe/trunk/test/SemaObjC/objcbridge-attribute.m Mon Nov 18 18:09:48 2013
>> @@ -1,37 +1,41 @@
>> // RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s
>> // rdar://15454846
>>
>> -typedef struct __CFErrorRef * __attribute__ ((objc_bridge(NSError))) CFErrorRef; // expected-note 2 {{declared here}}
>> +typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 2 {{declared here}}
>>
>> -typedef struct __CFMyColor * __attribute__((objc_bridge(12))) CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
>> +typedef struct __attribute__((objc_bridge(12))) __CFMyColor *CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
>>
>> -typedef struct __CFArray * __attribute__ ((objc_bridge)) CFArrayRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
>> +typedef struct __attribute__ ((objc_bridge)) __CFArray *CFArrayRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
>>
>> -typedef void * __attribute__ ((objc_bridge(NSURL))) CFURLRef; // expected-error {{'objc_bridge' attribute must be applied to a pointer to struct type}}
>> +typedef void * __attribute__ ((objc_bridge(NSURL))) CFURLRef; // expected-error {{'objc_bridge' attribute must be applied to a struct, C++ class, or union}}
>>
>> -typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{'objc_bridge' attribute must be applied to a pointer to struct type}}
>> +typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{'objc_bridge' attribute must be applied to a struct, C++ class, or union}}
>>
>> -typedef struct __CFLocale * __attribute__((objc_bridge(NSLocale, NSError))) CFLocaleRef;// expected-error {{use of undeclared identifier 'NSError'}}
>> +typedef struct __attribute__((objc_bridge(NSLocale, NSError))) __CFLocale *CFLocaleRef;// expected-error {{use of undeclared identifier 'NSError'}}
>>
>> -typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{'objc_bridge' attribute must be applied to a pointer to struct type}}
>> +typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{'objc_bridge' attribute must be applied to a struct, C++ class, or union}}
>>
>> -typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef; // expected-error {{'objc_bridge' attribute must be put on a typedef only}}
>> +typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef;
>>
>> -typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet)));
>> +typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{'objc_bridge' attribute must be applied to a struct, C++ class, or union}};
>>
>> -typedef union __CFUColor * __attribute__((objc_bridge(NSUColor))) CFUColorRef; // expected-error {{'objc_bridge' attribute must be applied to a pointer to struct type}}
>> +typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{'objc_bridge' attribute must be applied to a struct, C++ class, or union}};
>> +
>> +typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{'objc_bridge' attribute must be applied to a struct, C++ class, or union}};
>> +
>> +typedef union __attribute__((objc_bridge(NSUColor))) __CFUPrimeColor XXX;
>> +typedef XXX *CFUColor2Ref;
>>
>> @interface I
>> {
>> - __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute must be put on a typedef only}}
>> -
>> + __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute must be applied to a struct, C++ class, or union}};
>> }
>> @end
>>
>> @protocol NSTesting @end
>> @class NSString;
>>
>> -typedef struct __CFError * __attribute__((objc_bridge(NSTesting))) CFTestingRef; // expected-note {{declared here}}
>> +typedef struct __attribute__((objc_bridge(NSTesting))) __CFError *CFTestingRef; // expected-note {{declared here}}
>>
>> id Test1(CFTestingRef cf) {
>> return (NSString *)cf; // expected-error {{CF object of type 'CFTestingRef' (aka 'struct __CFError *') is bridged to 'NSTesting', which is not an Objective-C class}}
>> @@ -46,14 +50,17 @@ typedef CFErrorRef1 CFErrorRef2;
>> @interface MyError : NSError
>> @end
>>
>> + at interface NSUColor @end
>> +
>> @class NSString;
>>
>> -void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c) {
>> - (void)(NSString *)cf; // expected-warning {{CFErrorRef bridges to NSError, not NSString}}
>> +void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
>> + (void)(NSString *)cf; // expected-warning {{CFErrorRef2 bridges to NSError, not NSString}}
>> (void)(NSError *)cf; // okay
>> (void)(MyError*)cf; // okay,
>> + (void)(NSUColor *)cf2; // okay
>> (void)(CFErrorRef)ns; // okay
>> (void)(CFErrorRef)str; // expected-warning {{NSString cannot bridge to CFErrorRef}}
>> - (void)(Class)cf; // expected-warning {{CFErrorRef bridges to NSError, not 'Class'}}
>> + (void)(Class)cf; // expected-warning {{CFErrorRef2 bridges to NSError, not 'Class'}}
>> (void)(CFErrorRef)c; // expected-warning {{'Class' cannot bridge to 'CFErrorRef'}}
>> }
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
> ~Aaron
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131119/e0589e3d/attachment.html>
More information about the cfe-commits
mailing list