On Mon, Nov 18, 2013 at 7:09 PM, Fariborz Jahanian <[email protected]> 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. > 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 > > +@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 > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits ~Aaron _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
