manmanren updated this revision to Diff 55638.
manmanren added a comment.

Addressing review comments from Doug and Adrian.

Manman


http://reviews.llvm.org/D19679

Files:
  include/clang/Sema/ExternalSemaSource.h
  include/clang/Sema/MultiplexExternalSemaSource.h
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTReader.h
  lib/Sema/MultiplexExternalSemaSource.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaDeclObjC.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/Modules/Inputs/MethodPoolCombined1.h
  test/Modules/Inputs/MethodPoolCombined2.h
  test/Modules/Inputs/MethodPoolString1.h
  test/Modules/Inputs/MethodPoolString2.h
  test/Modules/Inputs/module.map
  test/Modules/method_pool_write.m

Index: test/Modules/method_pool_write.m
===================================================================
--- /dev/null
+++ test/Modules/method_pool_write.m
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fsyntax-only -I %S/Inputs %s -verify
+// expected-no-diagnostics
+
+@import MethodPoolCombined;
+@import MethodPoolString2;
+
+void message_kindof_object(__kindof S2 *kindof_S2) {
+  [kindof_S2 stringValue];
+}
+
Index: test/Modules/Inputs/MethodPoolString2.h
===================================================================
--- /dev/null
+++ test/Modules/Inputs/MethodPoolString2.h
@@ -0,0 +1,4 @@
+
+@interface S2
+- (int)stringValue;
+@end
Index: test/Modules/Inputs/MethodPoolString1.h
===================================================================
--- /dev/null
+++ test/Modules/Inputs/MethodPoolString1.h
@@ -0,0 +1,4 @@
+
+@interface S1
+- (int)stringValue;
+@end
Index: test/Modules/Inputs/MethodPoolCombined2.h
===================================================================
--- /dev/null
+++ test/Modules/Inputs/MethodPoolCombined2.h
@@ -0,0 +1 @@
+@import MethodPoolString2;
Index: test/Modules/Inputs/MethodPoolCombined1.h
===================================================================
--- /dev/null
+++ test/Modules/Inputs/MethodPoolCombined1.h
@@ -0,0 +1,6 @@
+
+@import MethodPoolString1;
+@interface A
+- (int)stringValue;
+@end
+
Index: test/Modules/Inputs/module.map
===================================================================
--- test/Modules/Inputs/module.map
+++ test/Modules/Inputs/module.map
@@ -393,3 +393,20 @@
     header "elaborated-type-structs.h"
   }
 }
+
+// We import a module, then declare a method with selector stringValue in
+// MethodPoolCombined1.h. In MethodPoolCombined2.h, we import another module
+// that also contains a method for selector stringValue. We make sure that
+// the method pool entry for stringValue in this module is complete.
+module MethodPoolCombined {
+  header "MethodPoolCombined1.h"
+  header "MethodPoolCombined2.h"
+}
+
+module MethodPoolString1 {
+  header "MethodPoolString1.h"
+}
+
+module MethodPoolString2 {
+  header "MethodPoolString2.h"
+}
Index: lib/Serialization/ASTWriter.cpp
===================================================================
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -4387,6 +4387,19 @@
     }
   }
 
+  // For method pool in the module, if it contains an entry for a selector,
+  // the entry should be complete, containing everything introduced by that
+  // module and all modules it imports. It's possible that the entry is out of
+  // date, so we need to pull in the new content here.
+
+  // It's possible that updateOutOfDateSelector can update SelectorIDs. To be
+  // safe, we copy all selectors out.
+  llvm::SmallVector<Selector, 256> AllSelectors;
+  for (auto &SelectorAndID : SelectorIDs)
+    AllSelectors.push_back(SelectorAndID.first);
+  for (auto &Selector : AllSelectors)
+    SemaRef.updateOutOfDateSelector(Selector);
+
   // Form the record of special types.
   RecordData SpecialTypes;
   AddTypeRef(Context.getRawCFConstantStringType(), SpecialTypes);
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -3606,6 +3606,9 @@
          Id != IdEnd; ++Id)
       Id->second->setOutOfDate(true);
   }
+  // Mark selectors as out of date.
+  for (auto Sel : SelectorGeneration)
+    SelectorOutOfDate[Sel.first] = true;
   
   // Resolve any unresolved module exports.
   for (unsigned I = 0, N = UnresolvedModuleRefs.size(); I != N; ++I) {
@@ -7139,6 +7142,7 @@
   unsigned &Generation = SelectorGeneration[Sel];
   unsigned PriorGeneration = Generation;
   Generation = getGeneration();
+  SelectorOutOfDate[Sel] = false;
   
   // Search for methods defined with this selector.
   ++NumMethodPoolLookups;
@@ -7170,6 +7174,11 @@
   addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second);
 }
 
+void ASTReader::updateOutOfDateSelector(Selector Sel) {
+  if (SelectorOutOfDate[Sel])
+    ReadMethodPool(Sel);
+}
+
 void ASTReader::ReadKnownNamespaces(
                           SmallVectorImpl<NamespaceDecl *> &Namespaces) {
   Namespaces.clear();
Index: lib/Sema/SemaDeclObjC.cpp
===================================================================
--- lib/Sema/SemaDeclObjC.cpp
+++ lib/Sema/SemaDeclObjC.cpp
@@ -3305,6 +3305,12 @@
   ExternalSource->ReadMethodPool(Sel);
 }
 
+void Sema::updateOutOfDateSelector(Selector Sel) {
+  if (!ExternalSource)
+    return;
+  ExternalSource->updateOutOfDateSelector(Sel);
+}
+
 void Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,
                                  bool instance) {
   // Ignore methods of invalid containers.
Index: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -1237,6 +1237,7 @@
 ExternalSemaSource::~ExternalSemaSource() {}
 
 void ExternalSemaSource::ReadMethodPool(Selector Sel) { }
+void ExternalSemaSource::updateOutOfDateSelector(Selector Sel) { }
 
 void ExternalSemaSource::ReadKnownNamespaces(
                            SmallVectorImpl<NamespaceDecl *> &Namespaces) {
Index: lib/Sema/MultiplexExternalSemaSource.cpp
===================================================================
--- lib/Sema/MultiplexExternalSemaSource.cpp
+++ lib/Sema/MultiplexExternalSemaSource.cpp
@@ -197,6 +197,11 @@
     Sources[i]->ReadMethodPool(Sel);
 }
 
+void MultiplexExternalSemaSource::updateOutOfDateSelector(Selector Sel) {
+  for(size_t i = 0; i < Sources.size(); ++i)
+    Sources[i]->updateOutOfDateSelector(Sel);
+}
+
 void MultiplexExternalSemaSource::ReadKnownNamespaces(
                                    SmallVectorImpl<NamespaceDecl*> &Namespaces){
   for(size_t i = 0; i < Sources.size(); ++i)
Index: include/clang/Serialization/ASTReader.h
===================================================================
--- include/clang/Serialization/ASTReader.h
+++ include/clang/Serialization/ASTReader.h
@@ -653,6 +653,10 @@
   /// global method pool for this selector.
   llvm::DenseMap<Selector, unsigned> SelectorGeneration;
 
+  /// Whether a selector is out of date. We mark a selector as out of date
+  /// if we load another module after the method pool entry was pulled in.
+  llvm::DenseMap<Selector, bool> SelectorOutOfDate;
+
   struct PendingMacroInfo {
     ModuleFile *M;
     uint64_t MacroDirectivesOffset;
@@ -1781,6 +1785,10 @@
   /// selector.
   void ReadMethodPool(Selector Sel) override;
 
+  /// Load the contents of the global method pool for a given
+  /// selector if necessary.
+  void updateOutOfDateSelector(Selector Sel) override;
+
   /// \brief Load the set of namespaces that are known to the external source,
   /// which will be used during typo correction.
   void ReadKnownNamespaces(
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -987,6 +987,7 @@
   llvm::SmallSet<SpecialMemberDecl, 4> SpecialMembersBeingDeclared;
 
   void ReadMethodPool(Selector Sel);
+  void updateOutOfDateSelector(Selector Sel);
 
   /// Private Helper predicate to check for 'self'.
   bool isSelfExpr(Expr *RExpr);
Index: include/clang/Sema/MultiplexExternalSemaSource.h
===================================================================
--- include/clang/Sema/MultiplexExternalSemaSource.h
+++ include/clang/Sema/MultiplexExternalSemaSource.h
@@ -203,6 +203,10 @@
   /// selector.
   void ReadMethodPool(Selector Sel) override;
 
+  /// Load the contents of the global method pool for a given
+  /// selector if necessary.
+  void updateOutOfDateSelector(Selector Sel) override;
+
   /// \brief Load the set of namespaces that are known to the external source,
   /// which will be used during typo correction.
   void
Index: include/clang/Sema/ExternalSemaSource.h
===================================================================
--- include/clang/Sema/ExternalSemaSource.h
+++ include/clang/Sema/ExternalSemaSource.h
@@ -70,6 +70,10 @@
   /// selector.
   virtual void ReadMethodPool(Selector Sel);
 
+  /// Load the contents of the global method pool for a given
+  /// selector if necessary.
+  virtual void updateOutOfDateSelector(Selector Sel);
+
   /// \brief Load the set of namespaces that are known to the external source,
   /// which will be used during typo correction.
   virtual void ReadKnownNamespaces(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to