diff options
-rw-r--r-- | include/clang/AST/DeclObjC.h | 7 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 24 |
2 files changed, 30 insertions, 1 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 4242d8d8d0..91c5c87269 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -154,7 +154,12 @@ private: EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {} virtual ~ObjCMethodDecl() {} - + + /// \brief A definition will return its interface declaration. + /// An interface declaration will return its definition. + /// Otherwise it will return itself. + virtual ObjCMethodDecl *getNextRedeclaration(); + public: /// Destroy - Call destructors and release memory. diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 7b86bfd195..cd4c5c072e 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -272,6 +272,30 @@ void ObjCMethodDecl::Destroy(ASTContext &C) { Decl::Destroy(C); } +/// \brief A definition will return its interface declaration. +/// An interface declaration will return its definition. +/// Otherwise it will return itself. +ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() { + ASTContext &Ctx = getASTContext(); + ObjCMethodDecl *Redecl = 0; + Decl *CtxD = cast<Decl>(getDeclContext()); + + if (ObjCInterfaceDecl *IFD = dyn_cast<ObjCInterfaceDecl>(CtxD)) { + if (ObjCImplementationDecl *ImplD = Ctx.getObjCImplementation(IFD)) + Redecl = ImplD->getMethod(getSelector(), isInstanceMethod()); + + } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(CtxD)) { + if (ObjCCategoryImplDecl *ImplD = Ctx.getObjCImplementation(CD)) + Redecl = ImplD->getMethod(getSelector(), isInstanceMethod()); + + } else if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(CtxD)) { + if (ObjCInterfaceDecl *IFD = ImplD->getClassInterface()) + Redecl = IFD->getMethod(getSelector(), isInstanceMethod()); + } + + return Redecl ? Redecl : this; +} + void ObjCMethodDecl::createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *OID) { QualType selfTy; |