MadCoder created this revision. MadCoder added reviewers: arphaman, rjmccall, dexonsmith. MadCoder added a project: clang. Herald added a subscriber: cfe-commits. MadCoder added a reviewer: liuliu.
ObjCMethodDecl::getCanonicalDecl() for re-declared readwrite properties, only looks in the ObjCInterface for the declaration of the setter method, which it won't find. When the method is a property accessor, we must look in extensions for a possible redeclaration. Extend the CG test to cover this issue. Radar-Id: rdar://problem/57991337 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D71588 Files: clang/lib/AST/DeclObjC.cpp clang/test/CodeGenObjC/direct-method.m Index: clang/test/CodeGenObjC/direct-method.m =================================================================== --- clang/test/CodeGenObjC/direct-method.m +++ clang/test/CodeGenObjC/direct-method.m @@ -191,6 +191,14 @@ return [r getInt] + [r intProperty] + [r intProperty2]; } +int useFoo(Foo *f) { + // CHECK-LABEL: define i32 @useFoo + // CHECK: call void bitcast {{.*}} @"\01-[Foo setGetDynamic_setDirect:]" + // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo getDirect_setDynamic]" + [f setGetDynamic_setDirect:1]; + return [f getDirect_setDynamic]; +} + __attribute__((objc_root_class)) @interface RootDeclOnly @property(direct, readonly) int intProperty; Index: clang/lib/AST/DeclObjC.cpp =================================================================== --- clang/lib/AST/DeclObjC.cpp +++ clang/lib/AST/DeclObjC.cpp @@ -958,10 +958,18 @@ auto *CtxD = cast<Decl>(getDeclContext()); if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) { - if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) + if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) { if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(), isInstanceMethod())) return MD; + // readwrite properties may have been re-declared in an extension. + // look harder. + if (isPropertyAccessor()) + for (auto *Ext : IFD->known_extensions()) + if (ObjCMethodDecl *MD = Ext->getMethod(getSelector(), + isInstanceMethod())) + return MD; + } } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) { if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl()) if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
Index: clang/test/CodeGenObjC/direct-method.m =================================================================== --- clang/test/CodeGenObjC/direct-method.m +++ clang/test/CodeGenObjC/direct-method.m @@ -191,6 +191,14 @@ return [r getInt] + [r intProperty] + [r intProperty2]; } +int useFoo(Foo *f) { + // CHECK-LABEL: define i32 @useFoo + // CHECK: call void bitcast {{.*}} @"\01-[Foo setGetDynamic_setDirect:]" + // CHECK: %{{[^ ]*}} = call i32 bitcast {{.*}} @"\01-[Foo getDirect_setDynamic]" + [f setGetDynamic_setDirect:1]; + return [f getDirect_setDynamic]; +} + __attribute__((objc_root_class)) @interface RootDeclOnly @property(direct, readonly) int intProperty; Index: clang/lib/AST/DeclObjC.cpp =================================================================== --- clang/lib/AST/DeclObjC.cpp +++ clang/lib/AST/DeclObjC.cpp @@ -958,10 +958,18 @@ auto *CtxD = cast<Decl>(getDeclContext()); if (auto *ImplD = dyn_cast<ObjCImplementationDecl>(CtxD)) { - if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) + if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) { if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(), isInstanceMethod())) return MD; + // readwrite properties may have been re-declared in an extension. + // look harder. + if (isPropertyAccessor()) + for (auto *Ext : IFD->known_extensions()) + if (ObjCMethodDecl *MD = Ext->getMethod(getSelector(), + isInstanceMethod())) + return MD; + } } else if (auto *CImplD = dyn_cast<ObjCCategoryImplDecl>(CtxD)) { if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl()) if (ObjCMethodDecl *MD = CatD->getMethod(getSelector(),
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits