From 3daade9020b55e5369256b6536e6c2f6f7a15060 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 19 Nov 2013 01:23:07 +0000 Subject: [PATCH] ObjectiveC 'objc_bridging'. Assorment of improvements per Doug/Jordan comments. // rdar://15454846. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195066 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticGroups.td | 2 +- include/clang/Basic/DiagnosticSemaKinds.td | 4 +--- lib/Sema/SemaDecl.cpp | 27 ---------------------- lib/Sema/SemaDeclAttr.cpp | 3 ++- lib/Sema/SemaExprObjC.cpp | 6 ++--- test/SemaObjC/objcbridge-attribute.m | 20 ++++++++-------- 6 files changed, 17 insertions(+), 45 deletions(-) diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 2643ee9dbf..38a939faae 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -382,7 +382,7 @@ def AutomaticReferenceCounting : DiagGroup<"arc", def ARCRepeatedUseOfWeakMaybe : DiagGroup<"arc-maybe-repeated-use-of-weak">; def ARCRepeatedUseOfWeak : DiagGroup<"arc-repeated-use-of-weak", [ARCRepeatedUseOfWeakMaybe]>; -def ObjCBridge : DiagGroup<"arc-bridge-cast">; +def ObjCBridge : DiagGroup<"bridge-cast">; def SelectorTypeMismatch : DiagGroup<"selector-type-mismatch">; def Selector : DiagGroup<"selector", [SelectorTypeMismatch]>; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 3b80df844a..2c89d13865 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2442,9 +2442,7 @@ 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 applied to a struct, C++ class, or union">; -def err_objc_bridge_not_cftype : Error< - "'objc_bridge' attribute must be applied to definition of CF types">; + "'objc_bridge' attribute must be applied to a struct%select{|, C++ class}0 or union">; 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< diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 6a5d608c7b..1892809bce 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -10072,31 +10072,6 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { } } -static inline bool isTollFreeBridgeCFRefType(TypedefDecl *TD) { - TypedefNameDecl * TDefNameDecl = TD; - const Type *TP = TDefNameDecl->getUnderlyingType().getTypePtr(); - while (const TypedefType *TDef = dyn_cast(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; - T = T->getPointeeType(); - if (T->isStructureType() || T->isUnionType() || T->isClassType()) - if (RecordDecl *RD = T->getAs()->getDecl()) - if (RD->hasAttr() && !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"); @@ -10119,8 +10094,6 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, NewTD->setInvalidDecl(); return NewTD; } - - CheckObjCBridgeAttribute(*this, NewTD); if (D.getDeclSpec().isModulePrivateSpecified()) { if (CurContext->isFunctionOrMethod()) diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 77f7905302..a1f385688e 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -4392,7 +4392,8 @@ static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D, static void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D, const AttributeList &Attr) { if (!isa(D)) { - S.Diag(D->getLocStart(), diag::err_objc_bridge_attribute); + S.Diag(D->getLocStart(), diag::err_objc_bridge_attribute) + << S.getLangOpts().CPlusPlus; return; } diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 69d7b9e07e..a2399b7ec4 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -3199,11 +3199,11 @@ static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) { if ((CastClass == ExprClass) || (CastClass && ExprClass->isSuperClassOf(CastClass))) return true; S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge) - << TDNDecl->getName() << Target->getName() << CastClass->getName(); + << T << Target->getName() << castType->getPointeeType(); return true; } else { S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge) - << TDNDecl->getName() << Target->getName() << castType; + << T << Target->getName() << castType; return true; } } @@ -3243,7 +3243,7 @@ static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr) { if ((CastClass == ExprClass) || (ExprClass && CastClass->isSuperClassOf(ExprClass))) return true; S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf) - << ExprClass->getName() << TDNDecl->getName(); + << castExpr->getType()->getPointeeType() << T; S.Diag(TDNDecl->getLocStart(), diag::note_declared_at); return true; } else { diff --git a/test/SemaObjC/objcbridge-attribute.m b/test/SemaObjC/objcbridge-attribute.m index 2ab21016cb..cc5eb21d3d 100644 --- a/test/SemaObjC/objcbridge-attribute.m +++ b/test/SemaObjC/objcbridge-attribute.m @@ -7,28 +7,28 @@ typedef struct __attribute__((objc_bridge(12))) __CFMyColor *CFMyColorRef; // e 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 struct, C++ class, or union}} +typedef void * __attribute__ ((objc_bridge(NSURL))) CFURLRef; // expected-error {{'objc_bridge' attribute must be applied to a struct or union}} -typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // 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 struct or union}} 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 struct, C++ class, or union}} +typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{'objc_bridge' attribute must be applied to a struct or union}} typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef; -typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{'objc_bridge' attribute must be applied to a struct, C++ class, or union}}; +typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{'objc_bridge' attribute must be applied to a struct or union}}; -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))) * CFUColorRef; // expected-error {{'objc_bridge' attribute must be applied to a struct 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 __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{'objc_bridge' attribute must be applied to a struct 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 applied to a struct, C++ class, or union}}; + __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute must be applied to a struct or union}}; } @end @@ -55,12 +55,12 @@ typedef CFErrorRef1 CFErrorRef2; @class 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)(NSString *)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') 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 {{CFErrorRef2 bridges to NSError, not 'Class'}} + (void)(CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} + (void)(Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}} (void)(CFErrorRef)c; // expected-warning {{'Class' cannot bridge to 'CFErrorRef'}} } -- 2.40.0