]> granicus.if.org Git - clang/commitdiff
[modules] Build a DAG of module macros for each identifier.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 22 Apr 2015 00:26:11 +0000 (00:26 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 22 Apr 2015 00:26:11 +0000 (00:26 +0000)
This graph will be used to determine the current set of active macros. This is
foundation work for getting macro visibility correct across submodules of the
current module. No functionality change for now.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235461 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/MacroInfo.h
include/clang/Lex/Preprocessor.h
include/clang/Serialization/ASTReader.h
lib/Lex/MacroInfo.cpp
lib/Lex/PPMacroExpansion.cpp
lib/Serialization/ASTReader.cpp

index 253e6625866f3004f6cffd73e6f5f97e8e5e162f..0dde8f2fdff66eb8d334f56a25738b00922a4530 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "clang/Lex/Token.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Allocator.h"
 #include <cassert>
@@ -577,6 +578,72 @@ MacroDirective::DefInfo::getPreviousDefinition() {
   return DefDirective->getPrevious()->getDefinition();
 }
 
+/// \brief Represents a macro directive exported by a module.
+///
+/// There's an instance of this class for every macro #define or #undef that is
+/// the final directive for a macro name within a module. These entities also
+/// represent the macro override graph.
+///
+/// These are stored in a FoldingSet in the preprocessor.
+class ModuleMacro : public llvm::FoldingSetNode {
+  /// The name defined by the macro.
+  IdentifierInfo *II;
+  /// The body of the #define, or nullptr if this is a #undef.
+  MacroInfo *Macro;
+  /// The ID of the module that exports this macro.
+  unsigned OwningModuleID;
+  /// The number of module macros that override this one.
+  unsigned NumOverriddenBy;
+  /// The number of modules whose macros are directly overridden by this one.
+  unsigned NumOverrides;
+  //ModuleMacro *OverriddenMacros[NumOverrides];
+
+  friend class Preprocessor;
+
+  ModuleMacro(unsigned OwningModuleID, IdentifierInfo *II, MacroInfo *Macro,
+              ArrayRef<ModuleMacro *> Overrides)
+      : II(II), Macro(Macro), OwningModuleID(OwningModuleID),
+        NumOverriddenBy(0), NumOverrides(Overrides.size()) {
+    std::copy(Overrides.begin(), Overrides.end(),
+              reinterpret_cast<ModuleMacro **>(this + 1));
+  }
+
+public:
+  static ModuleMacro *create(Preprocessor &PP, unsigned OwningModuleID,
+                             IdentifierInfo *II, MacroInfo *Macro,
+                             ArrayRef<ModuleMacro *> Overrides);
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    return Profile(ID, OwningModuleID, II);
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, unsigned OwningModuleID,
+                      IdentifierInfo *II) {
+    ID.AddInteger(OwningModuleID);
+    ID.AddPointer(II);
+  }
+
+  /// Get the ID of the module that exports this macro.
+  unsigned getOwningModuleID() const { return OwningModuleID; }
+
+  /// Get definition for this exported #define, or nullptr if this
+  /// represents a #undef.
+  MacroInfo *getMacroInfo() const { return Macro; }
+
+  /// Iterators over the overridden module IDs.
+  /// \{
+  typedef ModuleMacro *const *overrides_iterator;
+  overrides_iterator overrides_begin() const {
+    return reinterpret_cast<overrides_iterator>(this + 1);
+  }
+  overrides_iterator overrides_end() const {
+    return overrides_begin() + NumOverrides;
+  }
+  llvm::iterator_range<overrides_iterator> overrides() const {
+    return llvm::make_range(overrides_begin(), overrides_end());
+  }
+  /// \}
+};
+
 }  // end namespace clang
 
 #endif
index 326f519e914e12e4ec8a88331b44cfc5fbacdd4f..496f2791b35c8f425da1d4b9397df86d10ae7796 100644 (file)
@@ -31,6 +31,7 @@
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Support/Allocator.h"
 #include <memory>
 #include <vector>
@@ -368,7 +369,15 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
   /// the reverse order (the latest one is in the head of the list).
   llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros;
   friend class ASTReader;
-  
+
+  /// The set of known macros exported from modules.
+  llvm::FoldingSet<ModuleMacro> ModuleMacros;
+
+  /// The list of module macros, for each identifier, that are not overridden by
+  /// any other module macro.
+  llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro*>>
+      LeafModuleMacros;
+
   /// \brief Macros that we want to warn because they are not used at the end
   /// of the translation unit.
   ///
@@ -427,7 +436,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
   /// \c createPreprocessingRecord() prior to preprocessing.
   PreprocessingRecord *Record;
 
-private:  // Cached tokens state.
+  /// Cached tokens state.
   typedef SmallVector<Token, 1> CachedTokensTy;
 
   /// \brief Cached tokens are stored here when we do backtracking or
@@ -646,6 +655,11 @@ public:
   /// \brief Set a MacroDirective that was loaded from a PCH file.
   void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
 
+  /// \brief Register an exported macro for a module and identifier.
+  ModuleMacro *addModuleMacro(unsigned ModuleID, IdentifierInfo *II,
+                              MacroInfo *Macro,
+                              ArrayRef<ModuleMacro *> Overrides, bool &IsNew);
+
   /// \{
   /// Iterators for the macro history table. Currently defined macros have
   /// IdentifierInfo::hasMacroDefinition() set and an empty
index 3c30717716c77bba553bd9809ddb33243ea52527..330fc5b294d20fc00fa69a8b31689605ce09da8b 100644 (file)
@@ -1850,7 +1850,7 @@ public:
 
   void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
 
-  void installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
+  void installImportedMacro(IdentifierInfo *II, ModuleMacroInfo &MMI,
                             Module *Owner);
 
   typedef llvm::TinyPtrVector<DefMacroDirective *> AmbiguousMacros;
index 5416886cc9f79b30529fbe42e940871b0aba8b71..046948397fdd37ee40d4b30098afdc569625a446 100644 (file)
@@ -234,3 +234,10 @@ void MacroDirective::dump() const {
   }
   Out << "\n";
 }
+
+ModuleMacro *ModuleMacro::create(Preprocessor &PP, unsigned OwningModuleID,
+                                 IdentifierInfo *II, MacroInfo *Macro,
+                                 ArrayRef<ModuleMacro*> Overrides) {
+  return new (PP.getPreprocessorAllocator())
+      ModuleMacro(OwningModuleID, II, Macro, Overrides);
+}
index 3ceba05401a1d49a7242198f386733cabfdb8c03..4c6aa4e45ac199103a39d60e53f8515e19c51cc2 100644 (file)
@@ -72,6 +72,46 @@ void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,
     II->setHasMacroDefinition(false);
 }
 
+ModuleMacro *Preprocessor::addModuleMacro(unsigned ModuleID, IdentifierInfo *II,
+                                          MacroInfo *Macro,
+                                          ArrayRef<ModuleMacro *> Overrides,
+                                          bool &New) {
+  llvm::FoldingSetNodeID ID;
+  ModuleMacro::Profile(ID, ModuleID, II);
+
+  void *InsertPos;
+  if (auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) {
+    New = false;
+    return MM;
+  }
+
+  auto *MM = ModuleMacro::create(*this, ModuleID, II, Macro, Overrides);
+  ModuleMacros.InsertNode(MM, InsertPos);
+
+  // Each overridden macro is now overridden by one more macro.
+  bool HidAny = false;
+  for (auto *O : Overrides) {
+    HidAny |= (O->NumOverriddenBy == 0);
+    ++O->NumOverriddenBy;
+  }
+
+  // If we were the first overrider for any macro, it's no longer a leaf.
+  auto &LeafMacros = LeafModuleMacros[II];
+  if (HidAny) {
+    LeafMacros.erase(std::remove_if(LeafMacros.begin(), LeafMacros.end(),
+                                    [](ModuleMacro *MM) {
+                                      return MM->NumOverriddenBy != 0;
+                                    }),
+                     LeafMacros.end());
+  }
+
+  // The new macro is always a leaf macro.
+  LeafMacros.push_back(MM);
+
+  New = true;
+  return MM;
+}
+
 /// RegisterBuiltinMacro - Register the specified identifier in the identifier
 /// table and mark it as a builtin macro to be expanded.
 static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){
index 248e10d598b9c3f6cc72fbfef6020a43eebc2570..0e45a2f6fa78d68a7650dd94d0f0566509d40ae1 100644 (file)
@@ -1753,7 +1753,7 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,
   SavedStreamPosition SavedPosition(Cursor);
   Cursor.JumpToBit(PMInfo.MacroDirectivesOffset);
 
-  llvm::SmallVector<ModuleMacroInfo *, 8> ModuleMacros;
+  llvm::SmallVector<ModuleMacroInfo, 8> ModuleMacros;
 
   // We expect to see a sequence of PP_MODULE_MACRO records listing exported
   // macros, followed by a PP_MACRO_DIRECTIVE_HISTORY record with the complete
@@ -1774,19 +1774,9 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,
       break;
 
     case PP_MODULE_MACRO: {
-      auto SubModID = getGlobalSubmoduleID(M, Record[0]);
-      auto MacID = getGlobalMacroID(M, Record[1]);
-
-      // Check whether we've already loaded this module macro.
-      // FIXME: The MacrosLoaded check is wrong: multiple macro definitions can
-      // have the same MacroInfo (and the same MacID) due to #pragma pop_macro.
-      if (MacID ? (bool)MacrosLoaded[MacID - NUM_PREDEF_MACRO_IDS]
-                : !LoadedUndefs.insert(std::make_pair(II, SubModID)).second)
-        continue;
-
       ModuleMacroInfo Info;
-      Info.SubModID = SubModID;
-      Info.MI = getMacro(MacID);
+      Info.SubModID = getGlobalSubmoduleID(M, Record[0]);
+      Info.MI = getMacro(getGlobalMacroID(M, Record[1]));
       Info.F = &M;
 
       if (Record.size() > 2) {
@@ -1797,7 +1787,7 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,
             llvm::makeArrayRef(Overrides, Overrides + Record.size() - 2);
       }
 
-      ModuleMacros.push_back(new (Context) ModuleMacroInfo(Info));
+      ModuleMacros.push_back(Info);
       continue;
     }
 
@@ -1812,15 +1802,33 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,
   }
 
   // Module macros are listed in reverse dependency order.
-  std::reverse(ModuleMacros.begin(), ModuleMacros.end());
-  for (auto *MMI : ModuleMacros) {
-    Module *Owner = getSubmodule(MMI->getSubmoduleID());
-    if (Owner && Owner->NameVisibility == Module::Hidden) {
-      // Macros in the owning module are hidden. Just remember this macro to
-      // install if we make this module visible.
-      HiddenNamesMap[Owner].HiddenMacros.insert(std::make_pair(II, MMI));
-    } else {
-      installImportedMacro(II, MMI, Owner);
+  {
+    std::reverse(ModuleMacros.begin(), ModuleMacros.end());
+    llvm::SmallDenseMap<unsigned, ModuleMacro*> Macros;
+    llvm::SmallVector<ModuleMacro*, 8> Overrides;
+    for (auto &MMI : ModuleMacros) {
+      Overrides.clear();
+      for (unsigned ModID : MMI.Overrides) {
+        auto *Macro = Macros.lookup(ModID);
+        assert(Macro && "missing definition for overridden macro");
+        Overrides.push_back(Macros.lookup(ModID));
+      }
+
+      bool Inserted = false;
+      Macros[MMI.SubModID] =
+          PP.addModuleMacro(MMI.SubModID, II, MMI.MI, Overrides, Inserted);
+      if (!Inserted)
+        continue;
+
+      Module *Owner = getSubmodule(MMI.getSubmoduleID());
+      if (Owner->NameVisibility == Module::Hidden) {
+        // Macros in the owning module are hidden. Just remember this macro to
+        // install if we make this module visible.
+        HiddenNamesMap[Owner].HiddenMacros.insert(
+            std::make_pair(II, new ModuleMacroInfo(MMI)));
+      } else {
+        installImportedMacro(II, MMI, Owner);
+      }
     }
   }
 
@@ -1976,7 +1984,7 @@ ASTReader::removeOverriddenMacros(IdentifierInfo *II,
   return nullptr;
 }
 
-void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
+void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo &MMI,
                                      Module *Owner) {
   assert(II && Owner);
 
@@ -1986,16 +1994,16 @@ void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
     // source location for the import, we don't have a location for the macro.
     // Use the location at which the containing module file was first imported
     // for now.
-    ImportLoc = MMI->F->DirectImportLoc;
+    ImportLoc = MMI.F->DirectImportLoc;
     assert(ImportLoc.isValid() && "no import location for a visible macro?");
   }
 
   AmbiguousMacros *Prev =
-      removeOverriddenMacros(II, ImportLoc, MMI->getOverriddenSubmodules());
+      removeOverriddenMacros(II, ImportLoc, MMI.getOverriddenSubmodules());
 
   // Create a synthetic macro definition corresponding to the import (or null
   // if this was an undefinition of the macro).
-  MacroDirective *Imported = MMI->import(PP, ImportLoc);
+  MacroDirective *Imported = MMI.import(PP, ImportLoc);
   DefMacroDirective *MD = dyn_cast<DefMacroDirective>(Imported);
 
   // If there's no ambiguity, just install the macro.
@@ -3463,7 +3471,7 @@ void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner,
       PP.appendMacroDirective(Macro.first,
                               Macro.second->import(PP, SourceLocation()));
     else
-      installImportedMacro(Macro.first, Macro.second, Owner);
+      installImportedMacro(Macro.first, *Macro.second, Owner);
   }
 }