Commit 509f31ef authored by Fariborz Jahanian's avatar Fariborz Jahanian
Browse files

ObjectiveC 'objc_bridging'. Assorment of improvements

per Doug/Jordan comments. // rdar://15454846.

llvm-svn: 195066
parent d12ccbd3
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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]>;
+1 −3
Original line number Diff line number Diff line
@@ -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<
+0 −27
Original line number Diff line number Diff line
@@ -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");
@@ -10120,8 +10095,6 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
    return NewTD;
  }
  
  CheckObjCBridgeAttribute(*this, NewTD);
  
  if (D.getDeclSpec().isModulePrivateSpecified()) {
    if (CurContext->isFunctionOrMethod())
      Diag(NewTD->getLocation(), diag::err_module_private_local)
+2 −1
Original line number Diff line number Diff line
@@ -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;
  }
  
+3 −3
Original line number Diff line number Diff line
@@ -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 {
Loading