r235461 - [modules] Build a DAG of module macros for each identifier.

Richard Smith richard-llvm at metafoo.co.uk
Tue Apr 21 17:26:11 PDT 2015


Author: rsmith
Date: Tue Apr 21 19:26:11 2015
New Revision: 235461

URL: http://llvm.org/viewvc/llvm-project?rev=235461&view=rev
Log:
[modules] Build a DAG of module macros for each identifier.

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.

Modified:
    cfe/trunk/include/clang/Lex/MacroInfo.h
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/Lex/MacroInfo.cpp
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp

Modified: cfe/trunk/include/clang/Lex/MacroInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroInfo.h?rev=235461&r1=235460&r2=235461&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/MacroInfo.h (original)
+++ cfe/trunk/include/clang/Lex/MacroInfo.h Tue Apr 21 19:26:11 2015
@@ -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::getPreviousDefi
   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

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=235461&r1=235460&r2=235461&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Tue Apr 21 19:26:11 2015
@@ -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 RefCountedBa
   /// 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 RefCountedBa
   /// \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

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=235461&r1=235460&r2=235461&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Tue Apr 21 19:26:11 2015
@@ -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;

Modified: cfe/trunk/lib/Lex/MacroInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/MacroInfo.cpp?rev=235461&r1=235460&r2=235461&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/MacroInfo.cpp (original)
+++ cfe/trunk/lib/Lex/MacroInfo.cpp Tue Apr 21 19:26:11 2015
@@ -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);
+}

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=235461&r1=235460&r2=235461&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Tue Apr 21 19:26:11 2015
@@ -72,6 +72,46 @@ void Preprocessor::setLoadedMacroDirecti
     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){

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=235461&r1=235460&r2=235461&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Apr 21 19:26:11 2015
@@ -1753,7 +1753,7 @@ void ASTReader::resolvePendingMacro(Iden
   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(Iden
       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(Iden
             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(Iden
   }
 
   // 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(Identi
   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(Ide
     // 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 H
       PP.appendMacroDirective(Macro.first,
                               Macro.second->import(PP, SourceLocation()));
     else
-      installImportedMacro(Macro.first, Macro.second, Owner);
+      installImportedMacro(Macro.first, *Macro.second, Owner);
   }
 }
 





More information about the cfe-commits mailing list