diff options
author | Steve Naroff <snaroff@apple.com> | 2007-11-11 17:19:15 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2007-11-11 17:19:15 +0000 |
commit | 0416fb9f379b49abb3eb0c1cb2ca75107e5a71d1 (patch) | |
tree | bb9c9236a7ba43f551a2e19a7ba7652d905e3f84 /Sema/SemaDecl.cpp | |
parent | d848a3867794f4a9297bced70178834936e59d3d (diff) |
This is the last 5% of the solution to teaching Sema::ActOnInstanceMessage() about private methods (r43989).
While the diff is large, the idea is very simple. When we parse method definitions (in an @implementation), we need to add them incrementally (rather than wait until the @end).
Other details...
- Renamed Sema::ActOnAddMethodsToObjcDecl() to Sema::ActOnAtEnd(). The methods are now optional arguments.
- Removed Parser::AllImplMethods (a nice cleanup).
- Added location info to ObjcImplementationDecl (since we will need it very soon:-)
- Modified message.m test to no longer allow the bogus diagnostic.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43995 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Sema/SemaDecl.cpp')
-rw-r--r-- | Sema/SemaDecl.cpp | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index e9c438ffc5..e043fa19f6 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1576,7 +1576,7 @@ void Sema::ImplMethodsVsClassMethods(ObjcImplementationDecl* IMPDecl, llvm::DenseSet<Selector> InsMap; // Check and see if instance methods in class interface have been // implemented in the implementation class. - ObjcMethodDecl **methods = IMPDecl->getInstanceMethods(); + ObjcMethodDecl *const*methods = IMPDecl->getInstanceMethods(); for (int i=0; i < IMPDecl->getNumInstanceMethods(); i++) InsMap.insert(methods[i]->getSelector()); @@ -2079,10 +2079,9 @@ void Sema::AddFactoryMethodToGlobalPool(ObjcMethodDecl *Method) { } } -void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl, - DeclTy **allMethods, unsigned allNum, - DeclTy **allProperties, unsigned pNum, - SourceLocation AtEndLoc) { +void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl, + DeclTy **allMethods, unsigned allNum, + DeclTy **allProperties, unsigned pNum) { Decl *ClassDecl = static_cast<Decl *>(classDecl); // FIXME: If we don't have a ClassDecl, we have an error. I (snaroff) would @@ -2164,8 +2163,7 @@ void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl, } else if (ObjcImplementationDecl *IC = dyn_cast<ObjcImplementationDecl>(ClassDecl)) { - IC->addMethods(&insMethods[0], insMethods.size(), - &clsMethods[0], clsMethods.size(), AtEndLoc); + IC->setLocEnd(AtEndLoc); if (ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(IC->getIdentifier())) ImplMethodsVsClassMethods(IC, IDecl); } else { @@ -2242,14 +2240,15 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( Decl *CDecl = static_cast<Decl*>(ClassDecl); ObjcInterfaceDecl *IDecl = 0; + ObjcImplementationDecl *ImpDecl = 0; if (isa<ObjcInterfaceDecl>(CDecl)) IDecl = cast<ObjcInterfaceDecl>(CDecl); else if (isa<ObjcCategoryDecl>(CDecl)) - IDecl = cast<ObjcCategoryDecl>(CDecl)->getClassInterface(); - else if (isa<ObjcImplementationDecl>(CDecl)) - IDecl = cast<ObjcImplementationDecl>(CDecl)->getClassInterface(); + IDecl = cast<ObjcCategoryDecl>(CDecl)->getClassInterface(); // FIXME: what is this? (talk to fariborz) + else if ((ImpDecl = dyn_cast<ObjcImplementationDecl>(CDecl))) + IDecl = ImpDecl->getClassInterface(); // FIXME: what is this? (talk to fariborz) else if (isa<ObjcCategoryImplDecl>(CDecl)) - IDecl = cast<ObjcCategoryImplDecl>(CDecl)->getClassInterface(); + IDecl = cast<ObjcCategoryImplDecl>(CDecl)->getClassInterface(); // FIXME: what is this? (talk to fariborz) ObjcMethodDecl* ObjcMethod = new ObjcMethodDecl(MethodLoc, EndLoc, Sel, resultDeclType, @@ -2262,6 +2261,27 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( ObjcMethod->setMethodParams(&Params[0], Sel.getNumArgs()); ObjcMethod->setObjcDeclQualifier( CvtQTToAstBitMask(ReturnQT.getObjcDeclQualifier())); + if (ImpDecl) { + // For implementations (which can be very "coarse grain"), we add the + // method now. This allows the AST to implement lookup methods that work + // incrementally (without waiting until we parse the @end). It also allows + // us to flag multiple declaration errors as they occur. + // FIXME: still need to do this for ObjcCategoryImplDecl. + const ObjcMethodDecl *PrevMethod = 0; + if (MethodType == tok::minus) { + PrevMethod = ImpDecl->lookupInstanceMethod(Sel); + ImpDecl->addInstanceMethod(ObjcMethod); + } else { + PrevMethod = ImpDecl->lookupClassMethod(Sel); + ImpDecl->addClassMethod(ObjcMethod); + } + if (PrevMethod) { + // You can never have two method definitions with the same name. + Diag(ObjcMethod->getLocation(), diag::error_duplicate_method_decl, + ObjcMethod->getSelector().getName()); + Diag(PrevMethod->getLocation(), diag::err_previous_declaration); + } + } return ObjcMethod; } |