diff options
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/Decl.cpp | 5 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 40 |
2 files changed, 36 insertions, 9 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 387f79a013..f7608529d4 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -13,6 +13,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Stmt.h" #include "clang/AST/Expr.h" @@ -194,6 +195,10 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const { // For function declarations, we keep track of redeclarations. return FD->getPreviousDeclaration() == OldD; + // For method declarations, we keep track of redeclarations. + if (isa<ObjCMethodDecl>(this)) + return false; + // For non-function declarations, if the declarations are of the // same kind then this must be a redeclaration, or semantic analysis // would not have given us the new declaration. diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 461bb9697f..a9f7922ed0 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -14,6 +14,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Stmt.h" +#include "llvm/ADT/STLExtras.h" using namespace clang; //===----------------------------------------------------------------------===// @@ -42,21 +43,42 @@ void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) { //===----------------------------------------------------------------------===// // Get the local instance method declared in this interface. -// FIXME: handle overloading, instance & class methods can have the same name. ObjCMethodDecl *ObjCContainerDecl::getInstanceMethod(Selector Sel) const { - lookup_const_result MethodResult = lookup(Sel); - if (MethodResult.first) - return const_cast<ObjCMethodDecl*>( - dyn_cast<ObjCMethodDecl>(*MethodResult.first)); + // Since instance & class methods can have the same name, the loop below + // ensures we get the correct method. + // + // @interface Whatever + // - (int) class_method; + // + (float) class_method; + // @end + // + lookup_const_iterator Meth, MethEnd; + for (llvm::tie(Meth, MethEnd) = lookup(Sel); + Meth != MethEnd; ++Meth) { + ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth); + if (MD && MD->isInstanceMethod()) + return MD; + } return 0; } // Get the local class method declared in this interface. ObjCMethodDecl *ObjCContainerDecl::getClassMethod(Selector Sel) const { - lookup_const_result MethodResult = lookup(Sel); - if (MethodResult.first) - return const_cast<ObjCMethodDecl*>( - dyn_cast<ObjCMethodDecl>(*MethodResult.first)); + // Since instance & class methods can have the same name, the loop below + // ensures we get the correct method. + // + // @interface Whatever + // - (int) class_method; + // + (float) class_method; + // @end + // + lookup_const_iterator Meth, MethEnd; + for (llvm::tie(Meth, MethEnd) = lookup(Sel); + Meth != MethEnd; ++Meth) { + ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth); + if (MD && MD->isClassMethod()) + return MD; + } return 0; } |