diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-12-21 17:34:17 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-12-21 17:34:17 +0000 |
commit | bdb2d5056fd675c27307b34efd371bbba6839e92 (patch) | |
tree | 3198a99052139ee9f81add1f93941371e300988e /lib/Sema | |
parent | fbfd180495e7800975c6d9bdc6d24e706ef70e34 (diff) |
Fix a major inconsistency in the representation of Objective-C
classes, categories, protocols, and class extensions, where the
methods and properties of these entities would be inserted into the
DeclContext in an ordering that doesn't necessarily reflect source
order. The culprits were Sema::ActOnMethodDeclaration(), which did not
perform the insertion of the just-created method declaration into
the DeclContext for these Objective-C entities, and
Sema::ActOnAtEnd(), which inserted all method declarations at the
*end* of the DeclContext.
With this fix in hand, clean up the code-completion actions for
property setters/getters that worked around this brokenness in the AST.
Fixes <rdar://problem/8062781>, where this problem manifested as poor
token-annotation information, but this would have struck again in many
other places.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122347 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 34 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 13 |
2 files changed, 7 insertions, 40 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 76452a4516..b33f3fcb7c 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -4171,9 +4171,7 @@ static void AddObjCMethods(ObjCContainerDecl *Container, } -void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl, - Decl **Methods, - unsigned NumMethods) { +void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl) { typedef CodeCompletionResult Result; // Try to find the interface where getters might live. @@ -4191,19 +4189,6 @@ void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl, ResultBuilder Results(*this, CodeCompletionContext::CCC_Other); Results.EnterNewScope(); - // FIXME: We need to do this because Objective-C methods don't get - // pushed into DeclContexts early enough. Argh! - for (unsigned I = 0; I != NumMethods; ++I) { - if (ObjCMethodDecl *Method - = dyn_cast_or_null<ObjCMethodDecl>(Methods[I])) - if (Method->isInstanceMethod() && - isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) { - Result R = Result(Method, 0); - R.AllParametersAreInformative = true; - Results.MaybeAddResult(R, CurContext); - } - } - VisitedSelectorSet Selectors; AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Selectors, /*AllowSameLength=*/true, Results); @@ -4213,9 +4198,7 @@ void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl, Results.data(),Results.size()); } -void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl, - Decl **Methods, - unsigned NumMethods) { +void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl) { typedef CodeCompletionResult Result; // Try to find the interface where setters might live. @@ -4234,19 +4217,6 @@ void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl, ResultBuilder Results(*this, CodeCompletionContext::CCC_Other); Results.EnterNewScope(); - // FIXME: We need to do this because Objective-C methods don't get - // pushed into DeclContexts early enough. Argh! - for (unsigned I = 0; I != NumMethods; ++I) { - if (ObjCMethodDecl *Method - = dyn_cast_or_null<ObjCMethodDecl>(Methods[I])) - if (Method->isInstanceMethod() && - isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) { - Result R = Result(Method, 0); - R.AllParametersAreInformative = true; - Results.MaybeAddResult(R, CurContext); - } - } - VisitedSelectorSet Selectors; AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Selectors, /*AllowSameLength=*/true, Results); diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 5d9a924ed8..d19991138e 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1475,8 +1475,6 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, Diag(L, diag::warn_missing_atend); } - DeclContext *DC = dyn_cast<DeclContext>(ClassDecl); - // FIXME: Remove these and use the ObjCContainerDecl/DeclContext. llvm::DenseMap<Selector, const ObjCMethodDecl*> InsMap; llvm::DenseMap<Selector, const ObjCMethodDecl*> ClsMap; @@ -1496,8 +1494,8 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, Diag(Method->getLocation(), diag::err_duplicate_method_decl) << Method->getDeclName(); Diag(PrevMethod->getLocation(), diag::note_previous_declaration); + Method->setInvalidDecl(); } else { - DC->addDecl(Method); InsMap[Method->getSelector()] = Method; /// The following allows us to typecheck messages to "id". AddInstanceMethodToGlobalPool(Method); @@ -1515,8 +1513,8 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, Diag(Method->getLocation(), diag::err_duplicate_method_decl) << Method->getDeclName(); Diag(PrevMethod->getLocation(), diag::note_previous_declaration); + Method->setInvalidDecl(); } else { - DC->addDecl(Method); ClsMap[Method->getSelector()] = Method; /// The following allows us to typecheck messages to "Class". AddFactoryMethodToGlobalPool(Method); @@ -1773,10 +1771,7 @@ Decl *Sema::ActOnMethodDeclaration( const ObjCMethodDecl *InterfaceMD = 0; - // 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. + // Add the method now. if (ObjCImplementationDecl *ImpDecl = dyn_cast<ObjCImplementationDecl>(ClassDecl)) { if (MethodType == tok::minus) { @@ -1803,6 +1798,8 @@ Decl *Sema::ActOnMethodDeclaration( if (ObjCMethod->hasAttrs() && containsInvalidMethodImplAttribute(ObjCMethod->getAttrs())) Diag(EndLoc, diag::warn_attribute_method_def); + } else { + cast<DeclContext>(ClassDecl)->addDecl(ObjCMethod); } if (PrevMethod) { // You can never have two method definitions with the same name. |