Index: clang/lib/AST/DeclObjC.cpp =================================================================== --- clang/lib/AST/DeclObjC.cpp +++ clang/lib/AST/DeclObjC.cpp @@ -1308,7 +1308,7 @@ const auto *Container = cast(getParent()); // For accessor stubs, go back to the interface. if (auto *ImplDecl = dyn_cast(Container)) - if (!getBody()) + if (isSynthesizedAccessorStub()) Container = ImplDecl->getClassInterface(); bool IsGetter = (NumArgs == 0); @@ -1363,7 +1363,7 @@ } } - assert(!getBody() && "expected an accessor stub"); + assert(isSynthesizedAccessorStub() && "expected an accessor stub"); for (const auto *Cat : ClassDecl->known_categories()) { if (Cat == Container) continue; Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -5114,11 +5114,11 @@ // property. What we want to know is if the method is defined in // this implementation. auto *Getter = PID->getGetterMethodDecl(); - if (!Getter || !Getter->getBody()) + if (!Getter || Getter->isSynthesizedAccessorStub()) CodeGenFunction(*this).GenerateObjCGetter( const_cast(D), PID); auto *Setter = PID->getSetterMethodDecl(); - if (!PD->isReadOnly() && (!Setter || !Setter->getBody())) + if (!PD->isReadOnly() && (!Setter || Setter->isSynthesizedAccessorStub())) CodeGenFunction(*this).GenerateObjCSetter( const_cast(D), PID); } Index: clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp =================================================================== --- clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -910,7 +910,7 @@ bool getter) { auto *OMD = IMP->getInstanceMethod(getter ? PD->getGetterName() : PD->getSetterName()); - return !OMD || !OMD->getBody(); + return !OMD || OMD->isSynthesizedAccessorStub(); } void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID, Index: clang/lib/Index/IndexDecl.cpp =================================================================== --- clang/lib/Index/IndexDecl.cpp +++ clang/lib/Index/IndexDecl.cpp @@ -69,6 +69,17 @@ } } + /// Returns true if the given method has been defined explicitly by the + /// user. + static bool hasUserDefined(const ObjCMethodDecl *D, + const ObjCImplDecl *Container) { + const ObjCMethodDecl *MD = Container->getMethod(D->getSelector(), + D->isInstanceMethod()); + return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition() && + !MD->isSynthesizedAccessorStub(); + } + + void handleDeclarator(const DeclaratorDecl *D, const NamedDecl *Parent = nullptr, bool isIBType = false) { @@ -525,16 +536,15 @@ SymbolRoleSet AccessorMethodRoles = SymbolRoleSet(SymbolRole::Dynamic) | SymbolRoleSet(SymbolRole::Implicit); if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) { - if (MD->isPropertyAccessor() && !D->getGetterMethodDecl()->hasBody()) + if (MD->isPropertyAccessor() && !hasUserDefined(MD, Container)) IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container); } if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) { - if (MD->isPropertyAccessor() && !D->getSetterMethodDecl()->hasBody()) + if (MD->isPropertyAccessor() && !hasUserDefined(MD, Container)) IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container); } if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) { if (IvarD->getSynthesize()) { - IvarD->dump(); // For synthesized ivars, use the location of its name in the // corresponding @synthesize. If there isn't one, use the containing // @implementation's location, rather than the property's location, Index: clang/lib/Sema/SemaDeclObjC.cpp =================================================================== --- clang/lib/Sema/SemaDeclObjC.cpp +++ clang/lib/Sema/SemaDeclObjC.cpp @@ -2829,7 +2829,7 @@ // ImpMethodDecl may be null as in a @dynamic property. if (ImpMethodDecl) { // Skip property accessor function stubs. - if (I->isPropertyAccessor() && !ImpMethodDecl->getBody()) + if (ImpMethodDecl->isSynthesizedAccessorStub()) continue; if (!WarnCategoryMethodImpl) WarnConflictingTypedMethods(ImpMethodDecl, I, @@ -2858,7 +2858,7 @@ // ImpMethodDecl may be null as in a @dynamic property. if (ImpMethodDecl) { // Skip property accessor function stubs. - if (I->isPropertyAccessor() && !ImpMethodDecl->getBody()) + if (ImpMethodDecl->isSynthesizedAccessorStub()) continue; if (!WarnCategoryMethodImpl) WarnConflictingTypedMethods(ImpMethodDecl, I, @@ -3914,18 +3914,18 @@ if (auto *OID = dyn_cast(CurContext)) { for (auto PropImpl : OID->property_impls()) { if (auto *Getter = PropImpl->getGetterMethodDecl()) - if (Getter->isImplicit() && !Getter->hasBody()) { + if (Getter->isSynthesizedAccessorStub()) { OID->makeDeclVisibleInContext(Getter); OID->addDecl(Getter); } if (auto *Setter = PropImpl->getSetterMethodDecl()) - if (Setter->isImplicit() && !Setter->hasBody()) { + if (Setter->isSynthesizedAccessorStub()) { OID->makeDeclVisibleInContext(Setter); OID->addDecl(Setter); } } } - + // FIXME: Remove these and use the ObjCContainerDecl/DeclContext. llvm::DenseMap InsMap; llvm::DenseMap ClsMap; @@ -4699,13 +4699,13 @@ if (auto *Setter = PropertyImpl->getSetterMethodDecl()) if (Setter->getSelector() == Sel && Setter->isInstanceMethod() == ObjCMethod->isInstanceMethod()) { - assert(!Setter->hasBody() && "autosynth stub expected"); + assert(Setter->isSynthesizedAccessorStub() && "autosynth stub expected"); PropertyImpl->setSetterMethodDecl(ObjCMethod); } if (auto *Getter = PropertyImpl->getGetterMethodDecl()) if (Getter->getSelector() == Sel && Getter->isInstanceMethod() == ObjCMethod->isInstanceMethod()) { - assert(!Getter->hasBody() && "autosynth stub expected"); + assert(Getter->isSynthesizedAccessorStub() && "autosynth stub expected"); PropertyImpl->setGetterMethodDecl(ObjCMethod); break; } @@ -5108,7 +5108,7 @@ if (!IV) continue; - if (!CurMethod->getBody()) + if (CurMethod->isSynthesizedAccessorStub()) continue; UnusedBackingIvarChecker Checker(*this, CurMethod, IV); Index: clang/lib/Sema/SemaObjCProperty.cpp =================================================================== --- clang/lib/Sema/SemaObjCProperty.cpp +++ clang/lib/Sema/SemaObjCProperty.cpp @@ -1043,7 +1043,6 @@ ObjCMethodDecl *AccessorDecl, SourceLocation AtLoc, SourceLocation PropertyLoc) { ObjCMethodDecl *Decl = AccessorDecl; - // llvm::errs()<<"redeclare: "; Decl->dump(); ObjCMethodDecl *ImplDecl = ObjCMethodDecl::Create( Context, AtLoc, PropertyLoc, Decl->getSelector(), Decl->getReturnType(), Decl->getReturnTypeSourceInfo(), Impl, Decl->isInstanceMethod(), @@ -2145,8 +2144,8 @@ property->getSetterMethodDecl()) { auto *getterImpl = propertyImpl->getGetterMethodDecl(); auto *setterImpl = propertyImpl->getSetterMethodDecl(); - if ((!getterImpl || !getterImpl->getBody()) && - (!setterImpl || !setterImpl->getBody())) { + if ((!getterImpl || getterImpl->isSynthesizedAccessorStub()) && + (!setterImpl || setterImpl->isSynthesizedAccessorStub())) { SourceLocation loc = propertyImpl->getLocation(); if (loc.isInvalid()) loc = impDecl->getBeginLoc(); @@ -2189,9 +2188,9 @@ SetterMethod = Property->isClassProperty() ? IMPDecl->getClassMethod(Property->getSetterName()) : IMPDecl->getInstanceMethod(Property->getSetterName()); - if (GetterMethod && !GetterMethod->getBody()) + if (GetterMethod && GetterMethod->isSynthesizedAccessorStub()) GetterMethod = nullptr; - if (SetterMethod && !SetterMethod->getBody()) + if (SetterMethod && SetterMethod->isSynthesizedAccessorStub()) SetterMethod = nullptr; LookedUpGetterSetter = true; if (GetterMethod) { @@ -2218,9 +2217,9 @@ continue; GetterMethod = PIDecl->getGetterMethodDecl(); SetterMethod = PIDecl->getSetterMethodDecl(); - if (GetterMethod && !GetterMethod->getBody()) + if (GetterMethod && !GetterMethod->isSynthesizedAccessorStub()) GetterMethod = nullptr; - if (SetterMethod && !SetterMethod->getBody()) + if (SetterMethod && !SetterMethod->isSynthesizedAccessorStub()) SetterMethod = nullptr; if ((bool)GetterMethod ^ (bool)SetterMethod) { SourceLocation MethodLoc = @@ -2265,7 +2264,7 @@ if (PD && !PD->hasAttr() && !PD->isClassProperty()) { ObjCMethodDecl *IM = PID->getGetterMethodDecl(); - if (IM && IM->getBody()) + if (IM && IM->isSynthesizedAccessorStub()) continue; ObjCMethodDecl *method = PD->getGetterMethodDecl(); if (!method) Index: clang/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp +++ clang/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp @@ -144,8 +144,9 @@ continue; const Stmt *Body = M->getBody(); - if (!Body) + if (M->isSynthesizedAccessorStub()) continue; + assert(Body); MethodCrawler MC(IvarToPropMap, M->getCanonicalDecl(), InterD, BR, this, DCtx); Index: clang/tools/libclang/CIndex.cpp =================================================================== --- clang/tools/libclang/CIndex.cpp +++ clang/tools/libclang/CIndex.cpp @@ -632,7 +632,7 @@ // Filter out synthesized property accessor redeclarations. if (isa(DC)) if (auto *OMD = dyn_cast(D)) - if (OMD->isImplicit() && !OMD->hasBody()) + if (OMD->isSynthesizedAccessorStub()) continue; const Optional V = handleDeclForVisitation(D); if (!V.hasValue())