Implement name hiding for macro definitions within modules, such that
only the macro definitions from visible (sub)modules will actually be
visible. This provides the same behavior for macros that r145640
provided for declarations.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145683 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index bbcead0..04da346 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -384,7 +384,8 @@
   GlobalSubmoduleMapType GlobalSubmoduleMap;
 
   /// \brief A set of hidden declarations.
-  typedef llvm::SmallVector<Decl *, 2> HiddenNames;
+  typedef llvm::SmallVector<llvm::PointerUnion<Decl *, IdentifierInfo *>, 2>
+    HiddenNames;
   
   typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType;
 
@@ -1343,8 +1344,17 @@
 
   /// \brief Note that the identifier is a macro whose record will be loaded
   /// from the given AST file at the given (file-local) offset.
-  void SetIdentifierIsMacro(IdentifierInfo *II, ModuleFile &F,
-                            uint64_t Offset);
+  ///
+  /// \param II The name of the macro.
+  ///
+  /// \param F The module file from which the macro definition was deserialized.
+  ///
+  /// \param Offset The offset into the module file at which the macro 
+  /// definition is located.
+  ///
+  /// \param Visible Whether the macro should be made visible.
+  void setIdentifierIsMacro(IdentifierInfo *II, ModuleFile &F,
+                            uint64_t Offset, bool Visible);
 
   /// \brief Read the set of macros defined by this external macro source.
   virtual void ReadDefinedMacros();
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 27dccb0..1abce18 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -388,11 +388,7 @@
   void WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot);
   void WritePreprocessorDetail(PreprocessingRecord &PPRec);
   void WriteSubmodules(Module *WritingModule);
-                    
-  /// \brief Infer the submodule ID that contains an entity at the given
-  /// source location.
-  serialization::SubmoduleID inferSubmoduleIDFromLocation(SourceLocation Loc);
-                    
+                                        
   void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag);
   void WriteCXXBaseSpecifiersOffsets();
   void WriteType(QualType T);
@@ -607,6 +603,10 @@
     return DeclsToRewrite.count(D);
   }
 
+  /// \brief Infer the submodule ID that contains an entity at the given
+  /// source location.
+  serialization::SubmoduleID inferSubmoduleIDFromLocation(SourceLocation Loc);
+
   /// \brief Note that the identifier II occurs at the given offset
   /// within the identifier table.
   void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset);
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index a083e24..4594a39 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -562,8 +562,28 @@
   if (hasMacroDefinition) {
     // FIXME: Check for conflicts?
     uint32_t Offset = ReadUnalignedLE32(d);
-    Reader.SetIdentifierIsMacro(II, F, Offset);
-    DataLen -= 4;
+    unsigned LocalSubmoduleID = ReadUnalignedLE32(d);
+    
+    // Determine whether this macro definition should be visible now, or
+    // whether it is in a hidden submodule.
+    bool Visible = true;
+    if (SubmoduleID GlobalSubmoduleID
+          = Reader.getGlobalSubmoduleID(F, LocalSubmoduleID)) {
+      if (Module *Owner = Reader.getSubmodule(GlobalSubmoduleID)) {
+        if (Owner->NameVisibility == Module::Hidden) {
+          // The owning module is not visible, and this macro definition should
+          // not be, either.
+          Visible = false;
+          
+          // Note that this macro definition was hidden because its owning 
+          // module is not yet visible.
+          Reader.HiddenNamesMap[Owner].push_back(II);
+        }
+      } 
+    }
+    
+    Reader.setIdentifierIsMacro(II, F, Offset, Visible);
+    DataLen -= 8;
   }
 
   Reader.SetIdentifierInfo(ID, II);
@@ -1454,10 +1474,12 @@
   return HFI;
 }
 
-void ASTReader::SetIdentifierIsMacro(IdentifierInfo *II, ModuleFile &F,
-                                     uint64_t LocalOffset) {
-  // Note that this identifier has a macro definition.
-  II->setHasMacroDefinition(true);
+void ASTReader::setIdentifierIsMacro(IdentifierInfo *II, ModuleFile &F,
+                                     uint64_t LocalOffset, bool Visible) {
+  if (Visible) {
+    // Note that this identifier has a macro definition.
+    II->setHasMacroDefinition(true);
+  }
   
   // Adjust the offset to a global offset.
   UnreadMacroRecordOffsets[II] = F.GlobalBitOffset + LocalOffset;
@@ -2440,8 +2462,12 @@
 }
 
 void ASTReader::makeNamesVisible(const HiddenNames &Names) {
-  for (unsigned I = 0, N = Names.size(); I != N; ++I)
-    Names[I]->ModulePrivate = false;    
+  for (unsigned I = 0, N = Names.size(); I != N; ++I) {
+    if (Decl *D = Names[I].dyn_cast<Decl *>())
+      D->ModulePrivate = false;
+    else
+      Names[I].get<IdentifierInfo *>()->setHasMacroDefinition(true);
+  }
 }
 
 void ASTReader::makeModuleVisible(Module *Mod, 
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 1b554ef..5580f90 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -2423,7 +2423,7 @@
     if (isInterestingIdentifier(II, Macro)) {
       DataLen += 2; // 2 bytes for builtin ID, flags
       if (hasMacroDefinition(II, Macro))
-        DataLen += 4;
+        DataLen += 8;
       
       for (IdentifierResolver::iterator D = IdResolver.begin(II),
                                      DEnd = IdResolver.end();
@@ -2465,9 +2465,12 @@
     Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword());
     clang::io::Emit16(Out, Bits);
 
-    if (HasMacroDefinition)
+    if (HasMacroDefinition) {
       clang::io::Emit32(Out, Writer.getMacroOffset(II));
-
+      clang::io::Emit32(Out, 
+        Writer.inferSubmoduleIDFromLocation(Macro->getDefinitionLoc()));
+    }
+    
     // Emit the declaration IDs in reverse order, because the
     // IdentifierResolver provides the declarations as they would be
     // visible (e.g., the function "stat" would come before the struct
diff --git a/test/Modules/Inputs/submodules/hash_map.h b/test/Modules/Inputs/submodules/hash_map.h
index 56f0749..ce85984 100644
--- a/test/Modules/Inputs/submodules/hash_map.h
+++ b/test/Modules/Inputs/submodules/hash_map.h
@@ -1 +1,4 @@
 template<typename Key, typename Data> class hash_map { };
+
+#define HAVE_HASH_MAP
+
diff --git a/test/Modules/Inputs/submodules/type_traits.h b/test/Modules/Inputs/submodules/type_traits.h
index 9ef9006..4dad090 100644
--- a/test/Modules/Inputs/submodules/type_traits.h
+++ b/test/Modules/Inputs/submodules/type_traits.h
@@ -7,3 +7,6 @@
 struct remove_reference<T&> {
   typedef T type;
 };
+
+#define HAVE_TYPE_TRAITS
+
diff --git a/test/Modules/Inputs/submodules/vector.h b/test/Modules/Inputs/submodules/vector.h
index 2dcf3e5..8e1cdc8 100644
--- a/test/Modules/Inputs/submodules/vector.h
+++ b/test/Modules/Inputs/submodules/vector.h
@@ -1 +1,3 @@
 template<typename T> class vector { };
+
+#define HAVE_VECTOR
diff --git a/test/Modules/submodules-preprocess.cpp b/test/Modules/submodules-preprocess.cpp
index 1f0f3775..ed51b45 100644
--- a/test/Modules/submodules-preprocess.cpp
+++ b/test/Modules/submodules-preprocess.cpp
@@ -3,12 +3,58 @@
 
 __import_module__ std.vector;
 
-vector<int> vi;
-remove_reference<int&>::type *int_ptr = 0;
+#ifndef HAVE_VECTOR
+#  error HAVE_VECTOR macro is not available (but should be)
+#endif
+
+#ifdef HAVE_TYPE_TRAITS
+#  error HAVE_TYPE_TRAITS_MAP macro is available (but shouldn't be)
+#endif
+
+#ifdef HAVE_HASH_MAP
+#  error HAVE_HASH_MAP macro is available (but shouldn't be)
+#endif
 
 __import_module__ std.typetraits; // expected-error{{no submodule named 'typetraits' in module 'std'; did you mean 'type_traits'?}}
 
-vector<float> vf;
-remove_reference<int&>::type *int_ptr2 = 0;
+#ifndef HAVE_VECTOR
+#  error HAVE_VECTOR macro is not available (but should be)
+#endif
+
+#ifndef HAVE_TYPE_TRAITS
+#  error HAVE_TYPE_TRAITS_MAP macro is not available (but should be)
+#endif
+
+#ifdef HAVE_HASH_MAP
+#  error HAVE_HASH_MAP macro is available (but shouldn't be)
+#endif
 
 __import_module__ std.vector.compare; // expected-error{{no submodule named 'compare' in module 'std.vector'}}
+
+__import_module__ std; // import everything in 'std'
+
+#ifndef HAVE_VECTOR
+#  error HAVE_VECTOR macro is not available (but should be)
+#endif
+
+#ifndef HAVE_TYPE_TRAITS
+#  error HAVE_TYPE_TRAITS_MAP macro is not available (but should be)
+#endif
+
+#ifdef HAVE_HASH_MAP
+#  error HAVE_HASH_MAP macro is available (but shouldn't be)
+#endif
+
+__import_module__ std.hash_map;
+
+#ifndef HAVE_VECTOR
+#  error HAVE_VECTOR macro is not available (but should be)
+#endif
+
+#ifndef HAVE_TYPE_TRAITS
+#  error HAVE_TYPE_TRAITS_MAP macro is not available (but should be)
+#endif
+
+#ifndef HAVE_HASH_MAP
+#  error HAVE_HASH_MAP macro is not available (but should be)
+#endif