Commits

Volodymyr Sapsai committed f7844de

Forward declare ObjC class as property type

Comments (0)

Files changed (4)

     return Base::VisitObjCClassDecl(fwdClassDecl);
   }
 
+  bool VisitObjCPropertyDecl(clang::ObjCPropertyDecl* propertyDecl) {
+    if (CanIgnoreCurrentASTNode())  return true;
+    if (const Type* propertyType = propertyDecl->getType().getTypePtrOrNull()) {
+      const clang::ObjCObjectPointerType* objCPointerType =
+          propertyType->getAsObjCInterfacePointerType();
+      if (objCPointerType) {
+        const clang::ObjCInterfaceDecl* interfaceDecl =
+            objCPointerType->getInterfaceDecl();
+        if (interfaceDecl) {
+          ReportDeclForwardDeclareUse(CurrentLoc(), interfaceDecl);
+        }
+      }
+    }
+    return Base::VisitObjCPropertyDecl(propertyDecl);
+  }
+
   // If you say 'typedef Foo Bar', then clients can use Bar however
   // they want without having to worry about #including anything
   // except you.  That puts you on the hook for all the #includes that
     //vsapsai: comment it out until know where other ObjCInterfaceType are
     // encountered
     //ReportDeclUse(CurrentLoc(), type->getDecl());
+    CHECK_(false && "Fail hard and early. VisitObjCInterfaceType");
     return Base::VisitObjCInterfaceType(type);
   }
 

tests/fwd_decl_class_as_property.h

+//===--- fwd_decl_class_as_property.h - test input file for iwyu ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Tests that ObjC class as property type is forward declared.
+
+#import <objc/Object.h>
+#import "tests/imported_class.h"
+
+
+@interface Foo : Object {
+}
+@property (retain, nonatomic) ImportedClass *fooProperty;
+// test non-class properties
+@property (assign, nonatomic) id idProperty;
+@property (assign, nonatomic) int intProperty;
+@end
+
+/**** IWYU_SUMMARY
+
+tests/fwd_decl_class_as_property.h should add these lines:
+@class ImportedClass;
+
+tests/fwd_decl_class_as_property.h should remove these lines:
+- #import "tests/imported_class.h"  // lines XX-XX
+
+The full include-list for tests/fwd_decl_class_as_property.h:
+#import <objc/Object.h>  // for Object
+@class ImportedClass;
+
+***** IWYU_SUMMARY */

tests/fwd_decl_class_as_property.m

+//===--- fwd_decl_class_as_property.m - test input file for iwyu ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import "tests/fwd_decl_class_as_property.h"
+
+@implementation Foo
+
+// We are lying here, nobody implements these properties. Don't implement
+// properties to keep test small and devoted to properties in .h file.
+@dynamic fooProperty;
+@dynamic idProperty;
+@dynamic intProperty;
+
+@end
+
+/**** IWYU_SUMMARY
+
+(tests/fwd_decl_class_as_property.m has correct #includes/fwd-decls)
+
+***** IWYU_SUMMARY */
 Investigate if IWYU produces forward declarations both in .h file and in .cc
+	if forward declaration in .h file is good enough to be used in .cc
 
 test that forward declaration in discarded file is ignored
 test that forward declaration in full-use file stays
 call protocol method
 call method declared in superclass
 call method declared in superclass category (need both class and category?)
+synthesize property (it implies retain, release, copy are called for property type. Still need to decide if need the entire class or only class which contains retain, release, copy i.e. NSObject)
+
+nil usage: "nil is defined in <objc/objc.h>, which isn't directly #included."
+TODO: test struct property, e.g. @property (assign) NSSize frame;
 
 Crude outline:
 	Class as superclass needs import