From ceeb19cf189ecbea878df707d28d1780862ef2e5 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Tue, 28 Feb 2012 17:50:28 +0000 Subject: [PATCH] [AST] Associate the getter/setter methods to a property of a objc class extension. [libclang] Index the getter/setter methods of a property of a objc class extension. Fixes rdar://10907597 llvm-svn: 151633 --- clang/lib/Sema/SemaObjCProperty.cpp | 12 ++++++--- clang/tools/libclang/IndexDecl.cpp | 40 +++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index d47becc37567..fdd295ceff7c 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -263,7 +263,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, if (!PIDecl) { // No matching property found in the primary class. Just fall thru // and add property to continuation class's primary class. - ObjCPropertyDecl *PDecl = + ObjCPropertyDecl *PrimaryPDecl = CreatePropertyDecl(S, CCPrimary, AtLoc, FD, GetterSel, SetterSel, isAssign, isReadWrite, Attributes,AttributesAsWritten, T, MethodImplKind, DC); @@ -271,11 +271,13 @@ Sema::HandlePropertyInClassExtension(Scope *S, // A case of continuation class adding a new property in the class. This // is not what it was meant for. However, gcc supports it and so should we. // Make sure setter/getters are declared here. - ProcessPropertyDecl(PDecl, CCPrimary, /* redeclaredProperty = */ 0, + ProcessPropertyDecl(PrimaryPDecl, CCPrimary, /* redeclaredProperty = */ 0, /* lexicalDC = */ CDecl); + PDecl->setGetterMethodDecl(PrimaryPDecl->getGetterMethodDecl()); + PDecl->setSetterMethodDecl(PrimaryPDecl->getSetterMethodDecl()); if (ASTMutationListener *L = Context.getASTMutationListener()) - L->AddedObjCPropertyInClassExtension(PDecl, /*OrigProp=*/0, CDecl); - return PDecl; + L->AddedObjCPropertyInClassExtension(PrimaryPDecl, /*OrigProp=*/0, CDecl); + return PrimaryPDecl; } if (!Context.hasSameType(PIDecl->getType(), PDecl->getType())) { bool IncompatibleObjC = false; @@ -360,6 +362,8 @@ Sema::HandlePropertyInClassExtension(Scope *S, *isOverridingProperty = true; // Make sure setter decl is synthesized, and added to primary class's list. ProcessPropertyDecl(PIDecl, CCPrimary, PDecl, CDecl); + PDecl->setGetterMethodDecl(PIDecl->getGetterMethodDecl()); + PDecl->setSetterMethodDecl(PIDecl->getSetterMethodDecl()); if (ASTMutationListener *L = Context.getASTMutationListener()) L->AddedObjCPropertyInClassExtension(PDecl, PIDecl, CDecl); return 0; diff --git a/clang/tools/libclang/IndexDecl.cpp b/clang/tools/libclang/IndexDecl.cpp index dcc9a1dca3d8..2bd71295e6c6 100644 --- a/clang/tools/libclang/IndexDecl.cpp +++ b/clang/tools/libclang/IndexDecl.cpp @@ -41,6 +41,24 @@ public: } } + void handleObjCMethod(ObjCMethodDecl *D) { + IndexCtx.handleObjCMethod(D); + if (D->isImplicit()) + return; + + IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D); + for (ObjCMethodDecl::param_iterator + I = D->param_begin(), E = D->param_end(); I != E; ++I) + handleDeclarator(*I, D); + + if (D->isThisDeclarationADefinition()) { + const Stmt *Body = D->getBody(); + if (Body) { + IndexCtx.indexBody(Body, D, D); + } + } + } + bool VisitFunctionDecl(FunctionDecl *D) { IndexCtx.handleFunction(D); handleDeclarator(D); @@ -161,22 +179,22 @@ public: } bool VisitObjCMethodDecl(ObjCMethodDecl *D) { - IndexCtx.handleObjCMethod(D); - IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D); - for (ObjCMethodDecl::param_iterator - I = D->param_begin(), E = D->param_end(); I != E; ++I) - handleDeclarator(*I, D); + // Methods associated with a property, even user-declared ones, are + // handled when we handle the property. + if (D->isSynthesized()) + return true; - if (D->isThisDeclarationADefinition()) { - const Stmt *Body = D->getBody(); - if (Body) { - IndexCtx.indexBody(Body, D, D); - } - } + handleObjCMethod(D); return true; } bool VisitObjCPropertyDecl(ObjCPropertyDecl *D) { + if (ObjCMethodDecl *MD = D->getGetterMethodDecl()) + if (MD->getLexicalDeclContext() == D->getLexicalDeclContext()) + handleObjCMethod(MD); + if (ObjCMethodDecl *MD = D->getSetterMethodDecl()) + if (MD->getLexicalDeclContext() == D->getLexicalDeclContext()) + handleObjCMethod(MD); IndexCtx.handleObjCProperty(D); IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D); return true;