r235614 - [modules] Determine the set of macros exported by a submodule at the end of that submodule.

Richard Smith richard-llvm at metafoo.co.uk
Thu Apr 23 11:18:27 PDT 2015


Author: rsmith
Date: Thu Apr 23 13:18:26 2015
New Revision: 235614

URL: http://llvm.org/viewvc/llvm-project?rev=235614&view=rev
Log:
[modules] Determine the set of macros exported by a submodule at the end of that submodule.

Previously we'd defer this determination until writing the AST, which doesn't
allow us to use this information when building other submodules of the same
module. This change also allows us to use a uniform mechanism for writing
module macro records, independent of whether they are local or imported.

Modified:
    cfe/trunk/include/clang/Lex/ExternalPreprocessorSource.h
    cfe/trunk/include/clang/Lex/MacroInfo.h
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
    cfe/trunk/lib/Lex/MacroInfo.cpp
    cfe/trunk/lib/Lex/PPDirectives.cpp
    cfe/trunk/lib/Lex/PPLexerChange.cpp
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
    cfe/trunk/lib/Lex/Preprocessor.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/include/clang/Lex/ExternalPreprocessorSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ExternalPreprocessorSource.h?rev=235614&r1=235613&r2=235614&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/ExternalPreprocessorSource.h (original)
+++ cfe/trunk/include/clang/Lex/ExternalPreprocessorSource.h Thu Apr 23 13:18:26 2015
@@ -32,6 +32,9 @@ public:
   
   /// \brief Update an out-of-date identifier.
   virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0;
+
+  /// \brief Map a module ID to a module.
+  virtual Module *getModule(unsigned ModuleID) = 0;
 };
   
 }

Modified: cfe/trunk/include/clang/Lex/MacroInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroInfo.h?rev=235614&r1=235613&r2=235614&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/MacroInfo.h (original)
+++ cfe/trunk/include/clang/Lex/MacroInfo.h Thu Apr 23 13:18:26 2015
@@ -23,6 +23,7 @@
 #include <cassert>
 
 namespace clang {
+class Module;
 class Preprocessor;
 
 /// \brief Encapsulates the data about a macro definition (e.g. its tokens).
@@ -590,8 +591,8 @@ class ModuleMacro : public llvm::Folding
   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 module that exports this macro.
+  Module *OwningModule;
   /// The number of module macros that override this one.
   unsigned NumOverriddenBy;
   /// The number of modules whose macros are directly overridden by this one.
@@ -600,30 +601,30 @@ class ModuleMacro : public llvm::Folding
 
   friend class Preprocessor;
 
-  ModuleMacro(unsigned OwningModuleID, IdentifierInfo *II, MacroInfo *Macro,
+  ModuleMacro(Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro,
               ArrayRef<ModuleMacro *> Overrides)
-      : II(II), Macro(Macro), OwningModuleID(OwningModuleID),
+      : II(II), Macro(Macro), OwningModule(OwningModule),
         NumOverriddenBy(0), NumOverrides(Overrides.size()) {
     std::copy(Overrides.begin(), Overrides.end(),
               reinterpret_cast<ModuleMacro **>(this + 1));
   }
 
 public:
-  static ModuleMacro *create(Preprocessor &PP, unsigned OwningModuleID,
+  static ModuleMacro *create(Preprocessor &PP, Module *OwningModule,
                              IdentifierInfo *II, MacroInfo *Macro,
                              ArrayRef<ModuleMacro *> Overrides);
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
-    return Profile(ID, OwningModuleID, II);
+    return Profile(ID, OwningModule, II);
   }
-  static void Profile(llvm::FoldingSetNodeID &ID, unsigned OwningModuleID,
+  static void Profile(llvm::FoldingSetNodeID &ID, Module *OwningModule,
                       IdentifierInfo *II) {
-    ID.AddInteger(OwningModuleID);
+    ID.AddPointer(OwningModule);
     ID.AddPointer(II);
   }
 
   /// Get the ID of the module that exports this macro.
-  unsigned getOwningModuleID() const { return OwningModuleID; }
+  Module *getOwningModule() const { return OwningModule; }
 
   /// Get definition for this exported #define, or nullptr if this
   /// represents a #undef.
@@ -642,6 +643,10 @@ public:
     return llvm::make_range(overrides_begin(), overrides_end());
   }
   /// \}
+
+  /// Get the number of macros that override this one.
+  unsigned getNumOverridingMacros() const { return NumOverriddenBy; }
+
 };
 
 }  // end namespace clang

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=235614&r1=235613&r2=235614&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Thu Apr 23 13:18:26 2015
@@ -364,12 +364,86 @@ class Preprocessor : public RefCountedBa
   };
   SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
 
+  /// The state of a macro for an identifier.
+  class MacroState {
+    struct ExtInfo {
+      ExtInfo(MacroDirective *MD) : MD(MD) {}
+
+      // The most recent macro directive for this identifier.
+      MacroDirective *MD;
+      // The module macros that are overridden by this macro.
+      SmallVector<ModuleMacro*, 4> OverriddenMacros;
+    };
+
+    llvm::PointerUnion<MacroDirective *, ExtInfo *> State;
+
+    ExtInfo &getExtInfo(Preprocessor &PP) {
+      auto *Ext = State.dyn_cast<ExtInfo*>();
+      if (!Ext) {
+        Ext = new (PP.getPreprocessorAllocator())
+            ExtInfo(State.get<MacroDirective *>());
+        State = Ext;
+      }
+      return *Ext;
+    }
+
+  public:
+    MacroState() : MacroState(nullptr) {}
+    MacroState(MacroDirective *MD) : State(MD) {}
+    MacroDirective *getLatest() const {
+      if (auto *Ext = State.dyn_cast<ExtInfo*>())
+        return Ext->MD;
+      return State.get<MacroDirective*>();
+    }
+    void setLatest(MacroDirective *MD) {
+      if (auto *Ext = State.dyn_cast<ExtInfo*>())
+        Ext->MD = MD;
+      else
+        State = MD;
+    }
+
+    MacroDirective::DefInfo findDirectiveAtLoc(SourceLocation Loc,
+                                               SourceManager &SourceMgr) const {
+      return getLatest()->findDirectiveAtLoc(Loc, SourceMgr);
+    }
+
+    void addOverriddenMacro(Preprocessor &PP, ModuleMacro *MM) {
+      getExtInfo(PP).OverriddenMacros.push_back(MM);
+    }
+    ArrayRef<ModuleMacro*> getOverriddenMacros() const {
+      if (auto *Ext = State.dyn_cast<ExtInfo*>())
+        return Ext->OverriddenMacros;
+      return None;
+    }
+  };
+
+  typedef llvm::DenseMap<const IdentifierInfo *, MacroState> MacroMap;
+
   /// For each IdentifierInfo that was associated with a macro, we
   /// keep a mapping to the history of all macro definitions and #undefs in
   /// the reverse order (the latest one is in the head of the list).
-  llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros;
+  MacroMap Macros;
+
   friend class ASTReader;
 
+  /// \brief Information about a submodule that we're currently building.
+  struct BuildingSubmoduleInfo {
+    BuildingSubmoduleInfo(Module *M) : M(M) {}
+
+    // The module that we are building.
+    Module *M;
+    // The macros that were visible before we entered the module.
+    MacroMap Macros;
+
+    // FIXME: VisibleModules?
+    // FIXME: CounterValue?
+    // FIXME: PragmaPushMacroInfo?
+  };
+  SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
+
+  void EnterSubmodule(Module *M);
+  void LeaveSubmodule();
+
   /// The set of known macros exported from modules.
   llvm::FoldingSet<ModuleMacro> ModuleMacros;
 
@@ -656,19 +730,30 @@ public:
   void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
 
   /// \brief Register an exported macro for a module and identifier.
-  ModuleMacro *addModuleMacro(unsigned ModuleID, IdentifierInfo *II,
-                              MacroInfo *Macro,
+  ModuleMacro *addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro,
                               ArrayRef<ModuleMacro *> Overrides, bool &IsNew);
-  ModuleMacro *getModuleMacro(unsigned ModuleID, IdentifierInfo *II);
+  ModuleMacro *getModuleMacro(Module *Mod, IdentifierInfo *II);
+
+  /// \brief Get the list of leaf (non-overridden) module macros for a name.
+  ArrayRef<ModuleMacro*> getLeafModuleMacros(const IdentifierInfo *II) const {
+    auto I = LeafModuleMacros.find(II);
+    if (I != LeafModuleMacros.end())
+      return I->second;
+    return None;
+  }
 
   /// \{
   /// Iterators for the macro history table. Currently defined macros have
   /// IdentifierInfo::hasMacroDefinition() set and an empty
   /// MacroInfo::getUndefLoc() at the head of the list.
-  typedef llvm::DenseMap<const IdentifierInfo *,
-                         MacroDirective*>::const_iterator macro_iterator;
+  typedef MacroMap::const_iterator macro_iterator;
   macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
   macro_iterator macro_end(bool IncludeExternalMacros = true) const;
+  llvm::iterator_range<macro_iterator>
+  macros(bool IncludeExternalMacros = true) const {
+    return llvm::make_range(macro_begin(IncludeExternalMacros),
+                            macro_end(IncludeExternalMacros));
+  }
   /// \}
 
   /// \brief Return the name of the macro defined before \p Loc that has

Modified: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp?rev=235614&r1=235613&r2=235614&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp (original)
+++ cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp Thu Apr 23 13:18:26 2015
@@ -687,7 +687,8 @@ static void DoPrintMacros(Preprocessor &
   for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
        I != E; ++I) {
     if (I->first->hasMacroDefinition())
-      MacrosByID.push_back(id_macro_pair(I->first, I->second->getMacroInfo()));
+      MacrosByID.push_back(
+          id_macro_pair(I->first, I->second.getLatest()->getMacroInfo()));
   }
   llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
 

Modified: cfe/trunk/lib/Lex/MacroInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/MacroInfo.cpp?rev=235614&r1=235613&r2=235614&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/MacroInfo.cpp (original)
+++ cfe/trunk/lib/Lex/MacroInfo.cpp Thu Apr 23 13:18:26 2015
@@ -235,11 +235,11 @@ void MacroDirective::dump() const {
   Out << "\n";
 }
 
-ModuleMacro *ModuleMacro::create(Preprocessor &PP, unsigned OwningModuleID,
+ModuleMacro *ModuleMacro::create(Preprocessor &PP, Module *OwningModule,
                                  IdentifierInfo *II, MacroInfo *Macro,
                                  ArrayRef<ModuleMacro *> Overrides) {
   void *Mem = PP.getPreprocessorAllocator().Allocate(
       sizeof(ModuleMacro) + sizeof(ModuleMacro *) * Overrides.size(),
       llvm::alignOf<ModuleMacro>());
-  return new (Mem) ModuleMacro(OwningModuleID, II, Macro, Overrides);
+  return new (Mem) ModuleMacro(OwningModule, II, Macro, Overrides);
 }

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=235614&r1=235613&r2=235614&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Thu Apr 23 13:18:26 2015
@@ -1787,6 +1787,8 @@ void Preprocessor::HandleIncludeDirectiv
     assert(!CurSubmodule && "should not have marked this as a module yet");
     CurSubmodule = BuildingModule.getModule();
 
+    EnterSubmodule(CurSubmodule);
+
     EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_begin,
                          CurSubmodule);
   }

Modified: cfe/trunk/lib/Lex/PPLexerChange.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPLexerChange.cpp?rev=235614&r1=235613&r2=235614&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPLexerChange.cpp (original)
+++ cfe/trunk/lib/Lex/PPLexerChange.cpp Thu Apr 23 13:18:26 2015
@@ -400,6 +400,9 @@ bool Preprocessor::HandleEndOfFile(Token
       CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end);
       Result.setAnnotationEndLoc(Result.getLocation());
       Result.setAnnotationValue(CurSubmodule);
+
+      // We're done with this submodule.
+      LeaveSubmodule();
     }
 
     // We're done with the #included file.
@@ -605,3 +608,63 @@ void Preprocessor::HandleMicrosoftCommen
   // preprocessor directive mode), so just return EOF as our token.
   assert(!FoundLexer && "Lexer should return EOD before EOF in PP mode");
 }
+
+void Preprocessor::EnterSubmodule(Module *M) {
+  // Save the current state for future imports.
+  BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo(M));
+
+  auto &Info = BuildingSubmoduleStack.back();
+  // Copy across our macros and start the submodule with the current state.
+  // FIXME: We should start each submodule with just the predefined macros.
+  Info.Macros = Macros;
+}
+
+void Preprocessor::LeaveSubmodule() {
+  auto &Info = BuildingSubmoduleStack.back();
+
+  // Create ModuleMacros for any macros defined in this submodule.
+  for (auto &Macro : Macros) {
+    auto *II = const_cast<IdentifierInfo*>(Macro.first);
+    MacroState State = Info.Macros.lookup(II);
+
+    // This module may have exported a new macro. If so, create a ModuleMacro
+    // representing that fact.
+    bool ExplicitlyPublic = false;
+    for (auto *MD = Macro.second.getLatest(); MD != State.getLatest();
+         MD = MD->getPrevious()) {
+      // Skip macros defined in other submodules we #included along the way.
+      Module *Mod = getModuleForLocation(MD->getLocation());
+      if (Mod != Info.M)
+        continue;
+
+      if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
+        // The latest visibility directive for a name in a submodule affects
+        // all the directives that come before it.
+        if (VisMD->isPublic())
+          ExplicitlyPublic = true;
+        else if (!ExplicitlyPublic)
+          // Private with no following public directive: not exported.
+          break;
+      } else {
+        MacroInfo *Def = nullptr;
+        if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
+          Def = DefMD->getInfo();
+
+        // FIXME: Issue a warning if multiple headers for the same submodule
+        // define a macro, rather than silently ignoring all but the first.
+        bool IsNew;
+        addModuleMacro(Info.M, II, Def, Macro.second.getOverriddenMacros(),
+                       IsNew);
+        break;
+      }
+    }
+
+    // Update the macro to refer to the latest directive in the chain.
+    State.setLatest(Macro.second.getLatest());
+
+    // Restore the old macro state.
+    Macro.second = State;
+  }
+
+  BuildingSubmoduleStack.pop_back();
+}

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=235614&r1=235613&r2=235614&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Thu Apr 23 13:18:26 2015
@@ -37,33 +37,73 @@ MacroDirective *
 Preprocessor::getMacroDirectiveHistory(const IdentifierInfo *II) const {
   assert(II->hadMacroDefinition() && "Identifier has not been not a macro!");
 
-  macro_iterator Pos = Macros.find(II);
+  auto Pos = Macros.find(II);
   assert(Pos != Macros.end() && "Identifier macro info is missing!");
-  return Pos->second;
+  return Pos->second.getLatest();
 }
 
 void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){
   assert(MD && "MacroDirective should be non-zero!");
   assert(!MD->getPrevious() && "Already attached to a MacroDirective history.");
 
-  MacroDirective *&StoredMD = Macros[II];
-  MD->setPrevious(StoredMD);
-  StoredMD = MD;
-  // Setup the identifier as having associated macro history.
+  MacroState &StoredMD = Macros[II];
+  auto *OldMD = StoredMD.getLatest();
+  MD->setPrevious(OldMD);
+  StoredMD.setLatest(MD);
+
+  // Set up the identifier as having associated macro history.
   II->setHasMacroDefinition(true);
   if (!MD->isDefined())
     II->setHasMacroDefinition(false);
-  bool isImportedMacro = isa<DefMacroDirective>(MD) &&
-                         cast<DefMacroDirective>(MD)->isImported();
-  if (II->isFromAST() && !isImportedMacro)
+  if (II->isFromAST() && !MD->isImported())
     II->setChangedSinceDeserialization();
+
+  // Accumulate any overridden imported macros.
+  if (!MD->isImported() && getCurrentModule()) {
+    Module *OwningMod = getModuleForLocation(MD->getLocation());
+    if (!OwningMod)
+      return;
+
+    for (auto *PrevMD = OldMD; PrevMD; PrevMD = PrevMD->getPrevious()) {
+      // FIXME: Store a ModuleMacro * on an imported directive.
+      Module *DirectiveMod = getModuleForLocation(PrevMD->getLocation());
+      Module *PrevOwningMod =
+          PrevMD->isImported()
+              ? getExternalSource()->getModule(PrevMD->getOwningModuleID())
+              : DirectiveMod;
+      auto *MM = getModuleMacro(PrevOwningMod, II);
+      if (!MM) {
+        // We're still within the module defining the previous macro. We don't
+        // override it.
+        assert(!PrevMD->isImported() &&
+               "imported macro with no corresponding ModuleMacro");
+        break;
+      }
+      StoredMD.addOverriddenMacro(*this, MM);
+
+      // Stop once we leave the original macro's submodule.
+      //
+      // Either this submodule #included another submodule of the same
+      // module or it just happened to be built after the other module.
+      // In the former case, we override the submodule's macro.
+      //
+      // FIXME: In the latter case, we shouldn't do so, but we can't tell
+      // these cases apart.
+      //
+      // FIXME: We can leave this submodule and re-enter it if it #includes a
+      // header within a different submodule of the same module. In such cases
+      // the overrides list will be incomplete.
+      if (DirectiveMod != OwningMod || !PrevMD->isImported())
+        break;
+    }
+  }
 }
 
 void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,
                                            MacroDirective *MD) {
   assert(II && MD);
-  MacroDirective *&StoredMD = Macros[II];
-  assert(!StoredMD &&
+  MacroState &StoredMD = Macros[II];
+  assert(!StoredMD.getLatest() &&
          "the macro history was modified before initializing it from a pch");
   StoredMD = MD;
   // Setup the identifier as having associated macro history.
@@ -72,12 +112,12 @@ void Preprocessor::setLoadedMacroDirecti
     II->setHasMacroDefinition(false);
 }
 
-ModuleMacro *Preprocessor::addModuleMacro(unsigned ModuleID, IdentifierInfo *II,
+ModuleMacro *Preprocessor::addModuleMacro(Module *Mod, IdentifierInfo *II,
                                           MacroInfo *Macro,
                                           ArrayRef<ModuleMacro *> Overrides,
                                           bool &New) {
   llvm::FoldingSetNodeID ID;
-  ModuleMacro::Profile(ID, ModuleID, II);
+  ModuleMacro::Profile(ID, Mod, II);
 
   void *InsertPos;
   if (auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) {
@@ -85,7 +125,7 @@ ModuleMacro *Preprocessor::addModuleMacr
     return MM;
   }
 
-  auto *MM = ModuleMacro::create(*this, ModuleID, II, Macro, Overrides);
+  auto *MM = ModuleMacro::create(*this, Mod, II, Macro, Overrides);
   ModuleMacros.InsertNode(MM, InsertPos);
 
   // Each overridden macro is now overridden by one more macro.
@@ -112,10 +152,9 @@ ModuleMacro *Preprocessor::addModuleMacr
   return MM;
 }
 
-ModuleMacro *Preprocessor::getModuleMacro(unsigned ModuleID,
-                                          IdentifierInfo *II) {
+ModuleMacro *Preprocessor::getModuleMacro(Module *Mod, IdentifierInfo *II) {
   llvm::FoldingSetNodeID ID;
-  ModuleMacro::Profile(ID, ModuleID, II);
+  ModuleMacro::Profile(ID, Mod, II);
 
   void *InsertPos;
   return ModuleMacros.FindNodeOrInsertPos(ID, InsertPos);

Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=235614&r1=235613&r2=235614&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Thu Apr 23 13:18:26 2015
@@ -322,7 +322,7 @@ StringRef Preprocessor::getLastMacroWith
   for (Preprocessor::macro_iterator I = macro_begin(), E = macro_end();
        I != E; ++I) {
     const MacroDirective::DefInfo
-      Def = I->second->findDirectiveAtLoc(Loc, SourceMgr);
+      Def = I->second.findDirectiveAtLoc(Loc, SourceMgr);
     if (!Def || !Def.getMacroInfo())
       continue;
     if (!Def.getMacroInfo()->isObjectLike())

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=235614&r1=235613&r2=235614&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Thu Apr 23 13:18:26 2015
@@ -3037,7 +3037,7 @@ static void AddMacroResults(Preprocessor
                                  MEnd = PP.macro_end();
        M != MEnd; ++M) {
     if (IncludeUndefined || M->first->hasMacroDefinition()) {
-      if (MacroInfo *MI = M->second->getMacroInfo())
+      if (MacroInfo *MI = M->second.getLatest()->getMacroInfo())
         if (MI->isUsedForHeaderGuard())
           continue;
 

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=235614&r1=235613&r2=235614&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Apr 23 13:18:26 2015
@@ -1807,17 +1807,18 @@ void ASTReader::resolvePendingMacro(Iden
     for (auto &MMI : ModuleMacros) {
       Overrides.clear();
       for (unsigned ModID : MMI.Overrides) {
-        auto *Macro = PP.getModuleMacro(ModID, II);
+        Module *Mod = getSubmodule(ModID);
+        auto *Macro = PP.getModuleMacro(Mod, II);
         assert(Macro && "missing definition for overridden macro");
         Overrides.push_back(Macro);
       }
 
       bool Inserted = false;
-      PP.addModuleMacro(MMI.SubModID, II, MMI.MI, Overrides, Inserted);
+      Module *Owner = getSubmodule(MMI.getSubmoduleID());
+      PP.addModuleMacro(Owner, 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.

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=235614&r1=235613&r2=235614&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu Apr 23 13:18:26 2015
@@ -1993,69 +1993,6 @@ static bool shouldIgnoreMacro(MacroDirec
   return false;
 }
 
-static void addOverriddenSubmodules(ASTWriter &Writer, const Preprocessor &PP,
-                                    MacroDirective *MD,
-                                    SmallVectorImpl<uint64_t> &Result) {
-  assert(!isa<VisibilityMacroDirective>(MD) &&
-         "only #define and #undef can override");
-
-  if (MD->isImported()) {
-    auto ModIDs = MD->getOverriddenModules();
-    Result.insert(Result.end(), ModIDs.begin(), ModIDs.end());
-    return;
-  }
-
-  unsigned Start = Result.size();
-
-  SubmoduleID ModID = Writer.inferSubmoduleIDFromLocation(MD->getLocation());
-  for (MD = MD->getPrevious(); MD; MD = MD->getPrevious()) {
-    if (shouldIgnoreMacro(MD, /*IsModule*/true, PP))
-      break;
-
-    // If this is a definition from a submodule import, that submodule's
-    // definition is overridden by the definition or undefinition that we
-    // started with.
-    if (MD->isImported()) {
-      if (auto *DefMD = dyn_cast<DefMacroDirective>(MD)) {
-        SubmoduleID DefModuleID = DefMD->getInfo()->getOwningModuleID();
-        assert(DefModuleID && "imported macro has no owning module");
-        Result.push_back(DefModuleID);
-      } else if (auto *UndefMD = dyn_cast<UndefMacroDirective>(MD)) {
-        // If we override a #undef, we override anything that #undef overrides.
-        // We don't need to override it, since an active #undef doesn't affect
-        // the meaning of a macro.
-        // FIXME: Overriding the #undef directly might be simpler.
-        auto Overrides = UndefMD->getOverriddenModules();
-        Result.insert(Result.end(), Overrides.begin(), Overrides.end());
-      }
-    }
-
-    // Stop once we leave the original macro's submodule.
-    //
-    // Either this submodule #included another submodule of the same
-    // module or it just happened to be built after the other module.
-    // In the former case, we override the submodule's macro.
-    //
-    // FIXME: In the latter case, we shouldn't do so, but we can't tell
-    // these cases apart.
-    //
-    // FIXME: We can leave this submodule and re-enter it if it #includes a
-    // header within a different submodule of the same module. In such cases
-    // the overrides list will be incomplete.
-    SubmoduleID DirectiveModuleID =
-        Writer.inferSubmoduleIDFromLocation(MD->getLocation());
-    if (DirectiveModuleID != ModID) {
-      if (DirectiveModuleID && !MD->isImported())
-        Result.push_back(DirectiveModuleID);
-      break;
-    }
-  }
-
-  // Weed out any duplicate overrides.
-  std::sort(Result.begin() + Start, Result.end());
-  Result.erase(std::unique(Result.begin() + Start, Result.end()), Result.end());
-}
-
 /// \brief Writes the block containing the serialized form of the
 /// preprocessor.
 ///
@@ -2093,7 +2030,7 @@ void ASTWriter::WritePreprocessor(const
          I = PP.macro_begin(/*IncludeExternalMacros=*/false),
          E = PP.macro_end(/*IncludeExternalMacros=*/false);
        I != E; ++I) {
-    MacroDirectives.push_back(std::make_pair(I->first, I->second));
+    MacroDirectives.push_back(std::make_pair(I->first, I->second.getLatest()));
   }
 
   // Sort the set of macro definitions that need to be serialized by the
@@ -2117,18 +2054,6 @@ void ASTWriter::WritePreprocessor(const
         Name->isFromAST() && !Name->hasChangedSinceDeserialization())
       continue;
 
-    // State of this macro within each submodule.
-    enum class SubmoduleMacroState {
-      /// We've seen nothing about this macro.
-      None,
-      /// We've seen a public visibility directive.
-      Public,
-      /// We've either exported a macro for this module or found that the
-      /// module's definition of this macro is private.
-      Done
-    };
-    llvm::DenseMap<SubmoduleID, SubmoduleMacroState> State;
-
     auto StartOffset = Stream.GetCurrentBitNo();
 
     // Emit the macro directives in reverse source order.
@@ -2157,39 +2082,30 @@ void ASTWriter::WritePreprocessor(const
         Record.push_back(Overrides.size());
         Record.append(Overrides.begin(), Overrides.end());
       }
+    }
 
-      // If this is the final definition in some module, and it's not
-      // module-private, add a module macro record for it.
-      if (IsModule) {
-        SubmoduleID ModID =
-            MD->isImported() ? MD->getOwningModuleID()
-                             : inferSubmoduleIDFromLocation(MD->getLocation());
-        assert(ModID && "found macro in no submodule");
-
-        auto &S = State[ModID];
-        if (S == SubmoduleMacroState::Done) {
-          // We've already handled the final macro from this submodule, or seen
-          // a private visibility directive.
-        } else if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
-          // The latest visibility directive for a name in a submodule affects
-          // all the directives that come before it.
-          if (S == SubmoduleMacroState::None)
-            S = VisMD->isPublic() ? SubmoduleMacroState::Public
-                                  : SubmoduleMacroState::Done;
-        } else {
-          S = SubmoduleMacroState::Done;
-
-          // Emit a record indicating this submodule exports this macro.
-          ModuleMacroRecord.push_back(ModID);
-          if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
-            ModuleMacroRecord.push_back(getMacroID(DefMD->getInfo()));
-          else
-            ModuleMacroRecord.push_back(0);
-          addOverriddenSubmodules(*this, PP, MD, ModuleMacroRecord);
-
-          Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord);
-          ModuleMacroRecord.clear();
-        }
+    // Write out any exported module macros.
+    if (IsModule) {
+      auto Leafs = PP.getLeafModuleMacros(Name);
+      SmallVector<ModuleMacro*, 8> Worklist(Leafs.begin(), Leafs.end());
+      llvm::DenseMap<ModuleMacro*, unsigned> Visits;
+      while (!Worklist.empty()) {
+        auto *Macro = Worklist.pop_back_val();
+
+        // Emit a record indicating this submodule exports this macro.
+        ModuleMacroRecord.push_back(
+            getSubmoduleID(Macro->getOwningModule()));
+        ModuleMacroRecord.push_back(getMacroID(Macro->getMacroInfo()));
+        for (auto *M : Macro->overrides())
+          ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule()));
+
+        Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord);
+        ModuleMacroRecord.clear();
+
+        // Enqueue overridden macros once we've visited all their ancestors.
+        for (auto *M : Macro->overrides())
+          if (++Visits[M] == M->getNumOverridingMacros())
+            Worklist.push_back(M);
       }
     }
 





More information about the cfe-commits mailing list