]> granicus.if.org Git - clang/commitdiff
Implement name hiding for macro definitions within modules, such that
authorDouglas Gregor <dgregor@apple.com>
Fri, 2 Dec 2011 15:45:10 +0000 (15:45 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 2 Dec 2011 15:45:10 +0000 (15:45 +0000)
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

include/clang/Serialization/ASTReader.h
include/clang/Serialization/ASTWriter.h
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTWriter.cpp
test/Modules/Inputs/submodules/hash_map.h
test/Modules/Inputs/submodules/type_traits.h
test/Modules/Inputs/submodules/vector.h
test/Modules/submodules-preprocess.cpp

index bbcead091145e60c6d5d0448f6c92f90ff547660..04da346e63de23ad769564aaea2fb1a8d15c1387 100644 (file)
@@ -384,7 +384,8 @@ private:
   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 @@ public:
 
   /// \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();
index 27dccb0b72712dcaf6bf8813f82c0f3b9163a20e..1abce1869b70be8cc661db761cd9b9089aaa5700 100644 (file)
@@ -388,11 +388,7 @@ private:
   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 @@ public:
     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);
index a083e24e9e35eebfaf7abc2a4a4aa2280d6d8a0a..4594a393ddb2b57348f275c74c16da8d6d85c332 100644 (file)
@@ -562,8 +562,28 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
   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 @@ HeaderFileInfoTrait::ReadData(const internal_key_type, const unsigned char *d,
   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 @@ ASTReader::ASTReadResult ASTReader::validateFileEntries(ModuleFile &M) {
 }
 
 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, 
index 1b554ef3c45363f5ccc5ce9953873f5aa75a0bb1..5580f90b83bf5f0bee64b5714c337fe89d7c96c5 100644 (file)
@@ -2423,7 +2423,7 @@ public:
     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 @@ public:
     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
index 56f07497528514da938b83392d77794aa4f57f07..ce85984675790fd0829cefd5cd5306bddf983f8f 100644 (file)
@@ -1 +1,4 @@
 template<typename Key, typename Data> class hash_map { };
+
+#define HAVE_HASH_MAP
+
index 9ef9006fbc405ae20cb58380527488403ab580d3..4dad0901280971ff313e958f19e24135f97da674 100644 (file)
@@ -7,3 +7,6 @@ template<typename T>
 struct remove_reference<T&> {
   typedef T type;
 };
+
+#define HAVE_TYPE_TRAITS
+
index 2dcf3e57317ecbb0ae453c76cd1268522121aa3d..8e1cdc84f4bb55e429686f2f9b94f759ae740c03 100644 (file)
@@ -1 +1,3 @@
 template<typename T> class vector { };
+
+#define HAVE_VECTOR
index 1f0f37759c511aec4bc83cec67c658afa13f746e..ed51b4543f83f52e9be1447b978b8c5a84289944 100644 (file)
@@ -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