Eliminate Sema::ObjCImplementations, relying instead on name lookup. What's good for uniformity is good for PCH (or is it the other way around?). 

As part of this, make ObjCImplDecl inherit from NamedDecl (since
ObjCImplementationDecls now need to have names so that they can be
found). This brings ObjCImplDecl very, very close to
ObjCContainerDecl; we may be able to merge them soon.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69941 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 62783b1..010dc67 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -165,14 +165,19 @@
     case ObjCContainer:
     case ObjCCategory:
     case ObjCInterface:
-    case ObjCCategoryImpl:
     case ObjCProperty:
     case ObjCCompatibleAlias:
       return IDNS_Ordinary;
       
     case ObjCProtocol:
-      return IDNS_Protocol;
+      return IDNS_ObjCProtocol;
       
+    case ObjCImplementation:
+      return IDNS_ObjCImplementation;
+
+    case ObjCCategoryImpl:
+      return IDNS_ObjCCategoryImpl;
+
     case Field:
     case ObjCAtDefsField:
     case ObjCIvar:
@@ -197,7 +202,6 @@
     case FileScopeAsm:
     case StaticAssert:
     case ObjCClass:
-    case ObjCImplementation:
     case ObjCPropertyImpl:
     case ObjCForwardProtocol:
     case Block:
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index eef1029..06a7258 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -327,7 +327,7 @@
 }
 
 void PCHDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
-  VisitDecl(D);
+  VisitNamedDecl(D);
   D->setClassInterface(
               cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
   D->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 985d297..1af093a 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -498,7 +498,7 @@
 }
 
 void PCHDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
-  VisitDecl(D);
+  VisitNamedDecl(D);
   Writer.AddDeclRef(D->getClassInterface(), Record);
   Writer.AddSourceLocation(D->getLocEnd(), Record);
   // Abstract class (no need to define a stable pch::DECL code).
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 8cf2af0..b5f4e0b 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -168,10 +168,6 @@
   /// This is only necessary for issuing pretty diagnostics.
   llvm::SmallVector<TypedefDecl*, 24> ExtVectorDecls;
 
-  /// ObjCImplementations - Keep track of all class @implementations
-  /// so we can emit errors on duplicates.
-  llvm::DenseMap<IdentifierInfo*, ObjCImplementationDecl*> ObjCImplementations;
-  
   /// ObjCCategoryImpls - Maintain a list of category implementations so 
   /// we can check for duplicates and find local method declarations.
   llvm::SmallVector<ObjCCategoryImplDecl*, 8> ObjCCategoryImpls;
@@ -770,7 +766,11 @@
     /// C99 6.2.2p4-5 and C++ [basic.link]p6.
     LookupRedeclarationWithLinkage,
     /// Look up the name of an Objective-C protocol.
-    LookupProtocolName
+    LookupObjCProtocolName,
+    /// Look up the name of an Objective-C implementation
+    LookupObjCImplementationName,
+    /// Look up the name of an Objective-C category implementation
+    LookupObjCCategoryImplName
   };
 
   /// @brief Represents the results of name lookup.
@@ -1022,7 +1022,9 @@
     case Sema::LookupTagName:
     case Sema::LookupMemberName:
     case Sema::LookupRedeclarationWithLinkage: // FIXME: check linkage, scoping
-    case Sema::LookupProtocolName:
+    case Sema::LookupObjCProtocolName:
+    case Sema::LookupObjCImplementationName:
+    case Sema::LookupObjCCategoryImplName:
       return D->isInIdentifierNamespace(IDNS);
       
     case Sema::LookupOperatorName:
@@ -1057,6 +1059,8 @@
                                 SourceLocation Loc = SourceLocation());
 
   ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II);
+  ObjCImplementationDecl *LookupObjCImplementation(IdentifierInfo *II);
+  ObjCCategoryImplDecl *LookupObjCCategoryImpl(IdentifierInfo *II);
 
   void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
                                     QualType T1, QualType T2, 
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 7badaa3..e0cbdce 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -677,18 +677,15 @@
     ObjCImplementationDecl::Create(Context, CurContext, AtClassImplLoc, 
                                    IDecl, SDecl);
   
-  // FIXME: PushOnScopeChains?
-  CurContext->addDecl(Context, IMPDecl);
-
   if (CheckObjCDeclScope(IMPDecl))
     return DeclPtrTy::make(IMPDecl);
   
   // Check that there is no duplicate implementation of this class.
-  if (ObjCImplementations[ClassName])
+  if (LookupObjCImplementation(ClassName))
     // FIXME: Don't leak everything!
     Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
   else // add it to the list.
-    ObjCImplementations[ClassName] = IMPDecl;
+    PushOnScopeChains(IMPDecl, TUScope);
   return DeclPtrTy::make(IMPDecl);
 }
 
@@ -832,8 +829,8 @@
     }
   }
   // Lastly, look through the implementation (if one is in scope).
-  if (ObjCImplementationDecl *ImpDecl = 
-        ObjCImplementations[IDecl->getIdentifier()])
+  if (ObjCImplementationDecl *ImpDecl 
+      = LookupObjCImplementation(IDecl->getIdentifier()))
     if (ImpDecl->getInstanceMethod(Context, PDecl->getSetterName()))
       return false;
   // If all fails, look at the super class.
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 8490672..89f834c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1807,8 +1807,8 @@
                                               const ObjCInterfaceDecl *IFace,
                                               const Selector &Sel) {
   ObjCMethodDecl *Method = 0;
-  if (ObjCImplementationDecl *ImpDecl =
-      Sema::ObjCImplementations[IFace->getIdentifier()])
+  if (ObjCImplementationDecl *ImpDecl 
+        = LookupObjCImplementation(IFace->getIdentifier()))
     Method = ImpDecl->getInstanceMethod(Context, Sel);
   
   if (!Method && IFace->getSuperClass())
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 1df7f3d..d48ba44 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -222,8 +222,8 @@
   ObjCMethodDecl *Method = 0;
   // lookup in class and all superclasses
   while (ClassDecl && !Method) {
-    if (ObjCImplementationDecl *ImpDecl = 
-        ObjCImplementations[ClassDecl->getIdentifier()])
+    if (ObjCImplementationDecl *ImpDecl 
+          = LookupObjCImplementation(ClassDecl->getIdentifier()))
       Method = ImpDecl->getClassMethod(Context, Sel);
     
     // Look through local category implementations associated with the class.
@@ -255,8 +255,8 @@
   ObjCMethodDecl *Method = 0;
   while (ClassDecl && !Method) {
     // If we have implementations in scope, check "private" methods.
-    if (ObjCImplementationDecl *ImpDecl = 
-        ObjCImplementations[ClassDecl->getIdentifier()])
+    if (ObjCImplementationDecl *ImpDecl
+          = LookupObjCImplementation(ClassDecl->getIdentifier()))
       Method = ImpDecl->getInstanceMethod(Context, Sel);
     
     // Look through local category implementations associated with the class.
@@ -288,8 +288,8 @@
   if (!Getter)
     if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
       if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
-        if (ObjCImplementationDecl *ImpDecl =
-            ObjCImplementations[ClassDecl->getIdentifier()])
+        if (ObjCImplementationDecl *ImpDecl
+              = LookupObjCImplementation(ClassDecl->getIdentifier()))
           Getter = ImpDecl->getClassMethod(Context, Sel);
 
   if (Getter) {
@@ -310,8 +310,8 @@
     // methods.
     if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
       if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
-        if (ObjCImplementationDecl *ImpDecl =
-              ObjCImplementations[ClassDecl->getIdentifier()])
+        if (ObjCImplementationDecl *ImpDecl 
+              = LookupObjCImplementation(ClassDecl->getIdentifier()))
           Setter = ImpDecl->getClassMethod(Context, SetterSel);
   }
   // Look through local category implementations associated with the class.
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 613c30b..4b5a04b 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -294,8 +294,16 @@
     IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member;
     break;
 
-  case Sema::LookupProtocolName:
-    IDNS = Decl::IDNS_Protocol;
+  case Sema::LookupObjCProtocolName:
+    IDNS = Decl::IDNS_ObjCProtocol;
+    break;
+
+  case Sema::LookupObjCImplementationName:
+    IDNS = Decl::IDNS_ObjCImplementation;
+    break;
+
+  case Sema::LookupObjCCategoryImplName:
+    IDNS = Decl::IDNS_ObjCCategoryImpl;
     break;
   }
   return IDNS;
@@ -836,8 +844,16 @@
       IDNS = Decl::IDNS_Ordinary;
       break;
 
-    case Sema::LookupProtocolName:
-      IDNS = Decl::IDNS_Protocol;
+    case Sema::LookupObjCProtocolName:
+      IDNS = Decl::IDNS_ObjCProtocol;
+      break;
+
+    case Sema::LookupObjCImplementationName:
+      IDNS = Decl::IDNS_ObjCImplementation;
+      break;
+      
+    case Sema::LookupObjCCategoryImplName:
+      IDNS = Decl::IDNS_ObjCCategoryImpl;
       break;
     }
 
@@ -1490,10 +1506,24 @@
 
 /// \brief Find the protocol with the given name, if any.
 ObjCProtocolDecl *Sema::LookupProtocol(IdentifierInfo *II) {
-  Decl *D = LookupName(TUScope, II, LookupProtocolName).getAsDecl();
+  Decl *D = LookupName(TUScope, II, LookupObjCProtocolName).getAsDecl();
   return cast_or_null<ObjCProtocolDecl>(D);
 }
 
+/// \brief Find the Objective-C implementation with the given name, if
+/// any.
+ObjCImplementationDecl *Sema::LookupObjCImplementation(IdentifierInfo *II) {
+  Decl *D = LookupName(TUScope, II, LookupObjCImplementationName).getAsDecl();
+  return cast_or_null<ObjCImplementationDecl>(D);
+}
+
+/// \brief Find the Objective-C category implementation with the given
+/// name, if any.
+ObjCCategoryImplDecl *Sema::LookupObjCCategoryImpl(IdentifierInfo *II) {
+  Decl *D = LookupName(TUScope, II, LookupObjCCategoryImplName).getAsDecl();
+  return cast_or_null<ObjCCategoryImplDecl>(D);
+}
+
 void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
                                         QualType T1, QualType T2, 
                                         FunctionSet &Functions) {