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
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index f1c48a6..cd1321e 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -426,8 +426,7 @@
       ObjCDeclSpec OCDS;
       // Parse property attribute list, if any.
       if (Tok.is(tok::l_paren))
-        ParseObjCPropertyAttribute(OCDS, interfaceDecl,
-                                   allMethods.data(), allMethods.size());
+        ParseObjCPropertyAttribute(OCDS, interfaceDecl);
 
       ObjCPropertyCallback Callback(*this, interfaceDecl, allProperties,
                                     OCDS, AtLoc, MethodImplKind);
@@ -476,9 +475,7 @@
 ///     copy
 ///     nonatomic
 ///
-void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl,
-                                        Decl **Methods, 
-                                        unsigned NumMethods) {
+void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl) {
   assert(Tok.getKind() == tok::l_paren);
   SourceLocation LHSLoc = ConsumeParen(); // consume '('
 
@@ -523,11 +520,9 @@
 
       if (Tok.is(tok::code_completion)) {
         if (IsSetter)
-          Actions.CodeCompleteObjCPropertySetter(getCurScope(), ClassDecl,
-                                                 Methods, NumMethods);
+          Actions.CodeCompleteObjCPropertySetter(getCurScope(), ClassDecl);
         else
-          Actions.CodeCompleteObjCPropertyGetter(getCurScope(), ClassDecl,
-                                                 Methods, NumMethods);
+          Actions.CodeCompleteObjCPropertyGetter(getCurScope(), ClassDecl);
         ConsumeCodeCompletionToken();
       }
 
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 76452a4..b33f3fc 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -4171,9 +4171,7 @@
 }
 
 
-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 @@
   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 @@
                             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 @@
   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 5d9a924..d199911 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1475,8 +1475,6 @@
     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 @@
           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 @@
         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 @@
 
   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 @@
     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.