]> granicus.if.org Git - clang/commitdiff
[Objective-C Sema] patch to introduce IndependentClass
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 16 Apr 2015 18:38:44 +0000 (18:38 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 16 Apr 2015 18:38:44 +0000 (18:38 +0000)
attribute to be placed on Objective-C pointer typedef
to make them strong enough so on their "new" method
family no attempt is made to override these
types. rdar://20255473

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235128 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Type.h
include/clang/Basic/Attr.td
include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/AST/Type.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaDeclObjC.cpp
test/SemaObjC/psuedo-class-attribute.m [new file with mode: 0644]

index 5db43b4cfc43497d855e1e5cd2f8b123bf1746fd..6eb94405b95ce032765abefdefa425710c28126e 100644 (file)
@@ -1575,6 +1575,7 @@ public:
   bool isObjCLifetimeType() const;              // (array of)* retainable type
   bool isObjCIndirectLifetimeType() const;      // (pointer to)* lifetime type
   bool isObjCNSObjectType() const;              // __attribute__((NSObject))
+  bool isObjCIndependentClassType() const;      // __attribute__((IndependentClass))
   // FIXME: change this to 'raw' interface type, so we can used 'interface' type
   // for the common case.
   bool isObjCObjectType() const;                // NSString or typeof(*(id)0)
index 05a399afda93d7d26c33093f20ae948bae486d3e..423fdc67847b2e5fe1e70bb39a81f46466beff41 100644 (file)
@@ -1058,6 +1058,11 @@ def ObjCNSObject : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
+def ObjCIndependentClass : InheritableAttr {
+  let Spellings = [GNU<"IndependentClass">];
+  let Documentation = [Undocumented];
+}
+
 def ObjCPreciseLifetime : InheritableAttr {
   let Spellings = [GNU<"objc_precise_lifetime">];
   let Subjects = SubjectList<[Var], ErrorDiag>;
index 5e4d7efa982f660ab98ca93862d60febd02741bd..09c50a959cbf52c396e0125728579fdc06d3a79f 100644 (file)
@@ -394,6 +394,7 @@ def IgnoredPragmas : DiagGroup<"ignored-pragmas">;
 def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>;
 def UnknownWarningOption : DiagGroup<"unknown-warning-option">;
 def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
+def IndependentClassAttribute : DiagGroup<"IndependentClass-attribute">;
 def UnknownAttributes : DiagGroup<"unknown-attributes">;
 def IgnoredAttributes : DiagGroup<"ignored-attributes">;
 def Attributes : DiagGroup<"attributes", [UnknownAttributes,
index 89b439c7c317a7caeabd811a1e891683fd5637cc..6199aebc9522f94e333ad9c50d96dadaba4b6f9f 100644 (file)
@@ -2200,6 +2200,14 @@ def warn_gc_attribute_weak_on_local : Warning<
 def warn_nsobject_attribute : Warning<
   "'NSObject' attribute may be put on a typedef only; attribute is ignored">,
   InGroup<NSobjectAttribute>;
+def warn_independentclass_attribute : Warning<
+  "'IndependentClass' attribute may be put on a typedef only; "
+  "attribute is ignored">,
+  InGroup<IndependentClassAttribute>;
+def warn_ptr_independentclass_attribute : Warning<
+  "'IndependentClass' attribute may be put on Objective-C object "
+  "pointer type only; attribute is ignored">,
+  InGroup<IndependentClassAttribute>;
 def warn_attribute_weak_on_local : Warning<
   "__weak attribute cannot be specified on an automatic variable when ARC "
   "is not enabled">,
index 0e8b1e8119705f21f7553c9373b0a42b73e17cf6..0eb5d8c338ce6a462476a18e309caf8b32e7a4ec 100644 (file)
@@ -2371,6 +2371,11 @@ bool Type::isObjCNSObjectType() const {
     return typedefType->getDecl()->hasAttr<ObjCNSObjectAttr>();
   return false;
 }
+bool Type::isObjCIndependentClassType() const {
+  if (const TypedefType *typedefType = dyn_cast<TypedefType>(this))
+    return typedefType->getDecl()->hasAttr<ObjCIndependentClassAttr>();
+  return false;
+}
 bool Type::isObjCRetainableType() const {
   return isObjCObjectPointerType() ||
          isBlockPointerType() ||
index fa61b974e0401191f4bb3f8e4519baead2a1b499..756b2d68a558b80b95fd24cdf6e3ac2f144f7fd5 100644 (file)
@@ -2122,6 +2122,22 @@ static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
                               Attr.getAttributeSpellingListIndex()));
 }
 
+static void handleObjCIndependentClass(Sema &S, Decl *D, const AttributeList &Attr) {
+  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
+    QualType T = TD->getUnderlyingType();
+    if (!T->isObjCObjectPointerType()) {
+      S.Diag(TD->getLocation(), diag::warn_ptr_independentclass_attribute);
+      return;
+    }
+  } else {
+    S.Diag(D->getLocation(), diag::warn_independentclass_attribute);
+    return;
+  }
+  D->addAttr(::new (S.Context)
+             ObjCIndependentClassAttr(Attr.getRange(), S.Context,
+                              Attr.getAttributeSpellingListIndex()));
+}
+
 static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   if (!Attr.isArgIdent(0)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
@@ -4678,6 +4694,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
   case AttributeList::AT_ObjCNSObject:
     handleObjCNSObject(S, D, Attr);
     break;
+  case AttributeList::AT_ObjCIndependentClass:
+    handleObjCIndependentClass(S, D, Attr);
+    break;
   case AttributeList::AT_Blocks:
     handleBlocksAttr(S, D, Attr);
     break;
index 256419353c852718e415a865cff5a7e05c3e1fb3..dc47ce966f71a1426a906c6a5c91a89d85d07a4e 100644 (file)
@@ -3299,7 +3299,7 @@ Decl *Sema::ActOnMethodDeclaration(
       
     case OMF_alloc:
     case OMF_new:
-      InferRelatedResultType = ObjCMethod->isClassMethod();
+        InferRelatedResultType = ObjCMethod->isClassMethod();
       break;
         
     case OMF_init:
@@ -3310,7 +3310,8 @@ Decl *Sema::ActOnMethodDeclaration(
       break;
     }
     
-    if (InferRelatedResultType)
+    if (InferRelatedResultType &&
+        !ObjCMethod->getReturnType()->isObjCIndependentClassType())
       ObjCMethod->SetRelatedResultType();
   }
 
diff --git a/test/SemaObjC/psuedo-class-attribute.m b/test/SemaObjC/psuedo-class-attribute.m
new file mode 100644 (file)
index 0000000..c6ba077
--- /dev/null
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://20255473
+
+@interface NSObject @end
+
+typedef NSObject * __attribute__((IndependentClass))dispatch_queue_t;
+
+typedef struct S {int ii; } * __attribute__((IndependentClass))dispatch_queue_t_2; // expected-warning {{Objective-C object}}
+
+typedef struct { // expected-warning {{'IndependentClass' attribute may be put on a typedef only; attribute is ignored}}
+   NSObject *__attribute__((IndependentClass)) ns; // expected-warning {{'IndependentClass' attribute may be put on a typedef only; attribute is ignored}}
+} __attribute__((IndependentClass)) T;
+
+dispatch_queue_t dispatch_queue_create();
+
+@interface DispatchQPointerCastIssue : NSObject {
+  NSObject *__attribute__((IndependentClass)) Ivar; // expected-warning {{'IndependentClass' attribute may be put on a typedef only; attribute is ignored}}
+}
+
+@property (copy) NSObject *__attribute__((IndependentClass)) Prop; // expected-warning {{'IndependentClass' attribute may be put on a typedef only; attribute is ignored}}
+
+typedef NSObject * __attribute__((IndependentClass))dispatch_queue_t_1;
+
+@end
+
+@implementation DispatchQPointerCastIssue
++ (dispatch_queue_t) newDispatchQueue {
+    return dispatch_queue_create();
+}
+@end
+
+NSObject *get_nsobject() {
+  typedef NSObject * __attribute__((IndependentClass))dispatch_queue_t;
+  dispatch_queue_t dt;
+  return dt;
+}