r192951 - C++ modules: don't lose track of a 'namespace std' that is imported from a module.

Richard Smith richard-llvm at metafoo.co.uk
Thu Oct 17 23:54:39 PDT 2013


Author: rsmith
Date: Fri Oct 18 01:54:39 2013
New Revision: 192951

URL: http://llvm.org/viewvc/llvm-project?rev=192951&view=rev
Log:
C++ modules: don't lose track of a 'namespace std' that is imported from a module.

Added:
    cfe/trunk/test/Modules/Inputs/initializer_list
    cfe/trunk/test/Modules/initializer_list.cpp
Modified:
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/test/Modules/Inputs/module.map

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=192951&r1=192950&r2=192951&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Oct 18 01:54:39 2013
@@ -1268,6 +1268,9 @@ public:
   /// \brief Initializes the ASTContext
   void InitializeContext();
 
+  /// \brief Update the state of Sema after loading some additional modules.
+  void UpdateSema();
+
   /// \brief Add in-memory (virtual file) buffer.
   void addInMemoryBuffer(StringRef &FileName, llvm::MemoryBuffer *Buffer) {
     ModuleMgr.addInMemoryBuffer(FileName, Buffer);

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=192951&r1=192950&r2=192951&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Oct 18 01:54:39 2013
@@ -2524,9 +2524,10 @@ bool ASTReader::ReadASTBlock(ModuleFile
       break;
 
     case SEMA_DECL_REFS:
-      // Later tables overwrite earlier ones.
-      // FIXME: Modules will have some trouble with this.
-      SemaDeclRefs.clear();
+      if (Record.size() != 2) {
+        Error("Invalid SEMA_DECL_REFS block");
+        return true;
+      }
       for (unsigned I = 0, N = Record.size(); I != N; ++I)
         SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
       break;
@@ -3035,6 +3036,9 @@ ASTReader::ASTReadResult ASTReader::Read
   
   InitializeContext();
 
+  if (SemaObj)
+    UpdateSema();
+
   if (DeserializationListener)
     DeserializationListener->ReaderInitialized(this);
 
@@ -6136,21 +6140,13 @@ void ASTReader::InitializeSema(Sema &S)
   }
   PreloadedDecls.clear();
 
-  // Load the offsets of the declarations that Sema references.
-  // They will be lazily deserialized when needed.
-  if (!SemaDeclRefs.empty()) {
-    assert(SemaDeclRefs.size() == 2 && "More decl refs than expected!");
-    if (!SemaObj->StdNamespace)
-      SemaObj->StdNamespace = SemaDeclRefs[0];
-    if (!SemaObj->StdBadAlloc)
-      SemaObj->StdBadAlloc = SemaDeclRefs[1];
-  }
-
+  // FIXME: What happens if these are changed by a module import?
   if (!FPPragmaOptions.empty()) {
     assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS");
     SemaObj->FPFeatures.fp_contract = FPPragmaOptions[0];
   }
 
+  // FIXME: What happens if these are changed by a module import?
   if (!OpenCLExtensions.empty()) {
     unsigned I = 0;
 #define OPENCLEXT(nm)  SemaObj->OpenCLFeatures.nm = OpenCLExtensions[I++];
@@ -6158,6 +6154,25 @@ void ASTReader::InitializeSema(Sema &S)
 
     assert(OpenCLExtensions.size() == I && "Wrong number of OPENCL_EXTENSIONS");
   }
+
+  UpdateSema();
+}
+
+void ASTReader::UpdateSema() {
+  assert(SemaObj && "no Sema to update");
+
+  // Load the offsets of the declarations that Sema references.
+  // They will be lazily deserialized when needed.
+  if (!SemaDeclRefs.empty()) {
+    assert(SemaDeclRefs.size() % 2 == 0);
+    for (unsigned I = 0; I != SemaDeclRefs.size(); I += 2) {
+      if (!SemaObj->StdNamespace)
+        SemaObj->StdNamespace = SemaDeclRefs[I];
+      if (!SemaObj->StdBadAlloc)
+        SemaObj->StdBadAlloc = SemaDeclRefs[I+1];
+    }
+    SemaDeclRefs.clear();
+  }
 }
 
 IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {

Added: cfe/trunk/test/Modules/Inputs/initializer_list
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/initializer_list?rev=192951&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/initializer_list (added)
+++ cfe/trunk/test/Modules/Inputs/initializer_list Fri Oct 18 01:54:39 2013
@@ -0,0 +1,9 @@
+namespace std {
+  using size_t = decltype(sizeof(0));
+
+  template<typename T> struct initializer_list {
+    initializer_list(T*, size_t);
+  };
+
+  template<typename T> int min(initializer_list<T>);
+}

Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=192951&r1=192950&r2=192951&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Fri Oct 18 01:54:39 2013
@@ -254,3 +254,7 @@ module incomplete_mod {
 module warning {
   header "warning.h"
 }
+
+module initializer_list {
+  header "initializer_list"
+}

Added: cfe/trunk/test/Modules/initializer_list.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/initializer_list.cpp?rev=192951&view=auto
==============================================================================
--- cfe/trunk/test/Modules/initializer_list.cpp (added)
+++ cfe/trunk/test/Modules/initializer_list.cpp Fri Oct 18 01:54:39 2013
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11
+
+// expected-no-diagnostics
+ at import initializer_list;
+
+int n = std::min({1, 2, 3});





More information about the cfe-commits mailing list