]> granicus.if.org Git - clang/commitdiff
ObjectiveC 'objc_bridging'. Assorment of improvements
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 19 Nov 2013 01:23:07 +0000 (01:23 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 19 Nov 2013 01:23:07 +0000 (01:23 +0000)
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
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaExprObjC.cpp
test/SemaObjC/objcbridge-attribute.m

index 2643ee9dbf9d2ec230937e5a5f40dbc1640a835b..38a939faae3ad46bd7d4a8d0475f72e020e88581 100644 (file)
@@ -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]>;
index 3b80df844a59a902bb4a9a2e57f363f250aa58c2..2c89d13865fa82cd8a3d5a955c5e34d0b0d7b92d 100644 (file)
@@ -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<
index 6a5d608c7b2e87d493267f3a8d89079f28c2f703..1892809bcedcec1080644e99e6c034f540a07b03 100644 (file)
@@ -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<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;
-  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");
@@ -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())
index 77f7905302d0568f7467d39e6a499c6b4ad08736..a1f385688e1c7627a7d451aba3928a55d30a180a 100644 (file)
@@ -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<RecordDecl>(D)) {
-    S.Diag(D->getLocStart(), diag::err_objc_bridge_attribute);
+    S.Diag(D->getLocStart(), diag::err_objc_bridge_attribute)
+      << S.getLangOpts().CPlusPlus;
     return;
   }
   
index 69d7b9e07e9c5e93375a9e46aa7ac3a09083bd7e..a2399b7ec42ca7f216d614e730a5457ab4d5d887 100644 (file)
@@ -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 {
index 2ab21016cbf97b26fd8988c7558a0d0e70069506..cc5eb21d3dc221529506ff4fe3ad70ab1358fd6d 100644 (file)
@@ -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'}}
 }