diff options
author | Steve Naroff <snaroff@apple.com> | 2009-02-22 19:35:57 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2009-02-22 19:35:57 +0000 |
commit | c4173fa704860f3d7134e26b87ccd77e73e98163 (patch) | |
tree | ea10045b7c5c4824c06f06b2465d6e3c2e648d70 /clang/lib/AST | |
parent | e14282e274599a8de8921e7715a85c2c61d6f91c (diff) | |
download | bcm5719-llvm-c4173fa704860f3d7134e26b87ccd77e73e98163.tar.gz bcm5719-llvm-c4173fa704860f3d7134e26b87ccd77e73e98163.zip |
Contains the following (related to problems found while investigting <rdar://problem/6497631> Message lookup is sometimes different than gcc's).
- Implement instance/class overloading in ObjCContainerDecl (removing a FIXME). This involved hacking NamedDecl::declarationReplaces(), which took awhile to figure out (didn't realize replace was the default).
- Changed Sema::ActOnInstanceMessage() to remove redundant warnings when dealing with protocols. For now, I've omitted the "protocol" term in the diagnostic. It simplifies the code flow and wan't always 100% accurate (e.g. "Foo<Prot>" looks in the class interface, not just the protocol).
- Changed several test cases to jive with the above changes.
llvm-svn: 65292
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 5 | ||||
-rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 40 |
2 files changed, 36 insertions, 9 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 387f79a013f..f7608529d48 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/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/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 461bb9697fe..a9f7922ed04 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/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; } |