[Preprocessor/Modules] Separate the macro directives kinds into their own MacroDirective's subclasses.

For each macro directive (define, undefine, visibility) have a separate object that gets chained
to the macro directive history. This has several benefits:

-No need to mutate a MacroDirective when there is a undefine/visibility directive. Stuff like
 PPMutationListener become unnecessary.
-No need to keep extra source locations for the undef/visibility locations for the define directive object
 (which is the majority of the directives)
-Much easier to hide/unhide a section in the macro directive history.
-Easier to track the effects of the directives across different submodules.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178037 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 4c4d603..c6c850b 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -923,10 +923,11 @@
   // If this identifier does not currently have a macro definition,
   // check whether it had one on the command line.
   if (!Id->hasMacroDefinition()) {
-    MacroDirective *UndefMD = PP.getMacroDirectiveHistory(Id);
-    for (MacroDirective *MD = UndefMD; MD; MD = MD->getPrevious()) {
-
-      FileID FID = SourceMgr.getFileID(MD->getLocation());
+    MacroDirective::DefInfo LatestDef =
+        PP.getMacroDirectiveHistory(Id)->getDefinition();
+    for (MacroDirective::DefInfo Def = LatestDef; Def;
+           Def = Def.getPreviousDefinition()) {
+      FileID FID = SourceMgr.getFileID(Def.getLocation());
       if (FID.isInvalid())
         continue;
 
@@ -942,8 +943,8 @@
       // Complain.
       PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
         << true << ConfigMacro << Mod->getFullModuleName();
-      if (UndefMD->getUndefLoc().isValid())
-        PP.Diag(UndefMD->getUndefLoc(), diag::note_module_def_undef_here)
+      if (LatestDef.isUndefined())
+        PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
           << true;
       return;
     }
@@ -954,10 +955,12 @@
 
   // This identifier has a macro definition. Check whether we had a definition
   // on the command line.
-  MacroDirective *DefMD = PP.getMacroDirective(Id);
-  MacroDirective *PredefinedMD = 0;
-  for (MacroDirective *MD = DefMD; MD; MD = MD->getPrevious()) {
-    FileID FID = SourceMgr.getFileID(MD->getLocation());
+  MacroDirective::DefInfo LatestDef =
+      PP.getMacroDirectiveHistory(Id)->getDefinition();
+  MacroDirective::DefInfo PredefinedDef;
+  for (MacroDirective::DefInfo Def = LatestDef; Def;
+         Def = Def.getPreviousDefinition()) {
+    FileID FID = SourceMgr.getFileID(Def.getLocation());
     if (FID.isInvalid())
       continue;
 
@@ -969,32 +972,32 @@
     if (!StringRef(Buffer->getBufferIdentifier()).equals("<built-in>"))
       continue;
 
-    PredefinedMD = MD;
+    PredefinedDef = Def;
     break;
   }
 
   // If there was no definition for this macro in the predefines buffer,
   // complain.
-  if (!PredefinedMD ||
-      (!PredefinedMD->getLocation().isValid() &&
-       PredefinedMD->getUndefLoc().isValid())) {
+  if (!PredefinedDef ||
+      (!PredefinedDef.getLocation().isValid() &&
+       PredefinedDef.getUndefLocation().isValid())) {
     PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
       << false << ConfigMacro << Mod->getFullModuleName();
-    PP.Diag(DefMD->getLocation(), diag::note_module_def_undef_here)
+    PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here)
       << false;
     return;
   }
 
   // If the current macro definition is the same as the predefined macro
   // definition, it's okay.
-  if (DefMD == PredefinedMD ||
-      DefMD->getInfo()->isIdenticalTo(*PredefinedMD->getInfo(), PP))
+  if (LatestDef.getMacroInfo() == PredefinedDef.getMacroInfo() ||
+      LatestDef.getMacroInfo()->isIdenticalTo(*PredefinedDef.getMacroInfo(),PP))
     return;
 
   // The macro definitions differ.
   PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
     << false << ConfigMacro << Mod->getFullModuleName();
-  PP.Diag(DefMD->getLocation(), diag::note_module_def_undef_here)
+  PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here)
     << false;
 }
 
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index d894939..f70bd7c 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -318,7 +318,7 @@
 /// MacroDefined - This hook is called whenever a macro definition is seen.
 void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok,
                                             const MacroDirective *MD) {
-  const MacroInfo *MI = MD->getInfo();
+  const MacroInfo *MI = MD->getMacroInfo();
   // Only print out macro definitions in -dD mode.
   if (!DumpDefines ||
       // Ignore __FILE__ etc.
@@ -602,7 +602,7 @@
   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->getInfo()));
+      MacrosByID.push_back(id_macro_pair(I->first, I->second->getMacroInfo()));
   }
   llvm::array_pod_sort(MacrosByID.begin(), MacrosByID.end(), MacroIDCompare);
 
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
index 213e711..dc091f6 100644
--- a/lib/Lex/MacroInfo.cpp
+++ b/lib/Lex/MacroInfo.cpp
@@ -108,14 +108,40 @@
   return true;
 }
 
-const MacroDirective *
+MacroDirective::DefInfo MacroDirective::getDefinition(bool AllowHidden) {
+  MacroDirective *MD = this;
+  SourceLocation UndefLoc;
+  Optional<bool> isPublic;
+  for (; MD; MD = MD->getPrevious()) {
+    if (!AllowHidden && MD->isHidden())
+      continue;
+
+    if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
+      return DefInfo(DefMD, UndefLoc,
+                     !isPublic.hasValue() || isPublic.getValue());
+
+    if (UndefMacroDirective *UndefMD = dyn_cast<UndefMacroDirective>(MD)) {
+      UndefLoc = UndefMD->getLocation();
+      continue;
+    }
+
+    VisibilityMacroDirective *VisMD = cast<VisibilityMacroDirective>(MD);
+    if (!isPublic.hasValue())
+      isPublic = VisMD->isPublic();
+  }
+
+  return DefInfo();
+}
+
+const MacroDirective::DefInfo
 MacroDirective::findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const {
   assert(L.isValid() && "SourceLocation is invalid.");
-  for (const MacroDirective *MD = this; MD; MD = MD->Previous) {
-    if (MD->getLocation().isInvalid() ||  // For macros defined on the command line.
-        SM.isBeforeInTranslationUnit(MD->getLocation(), L))
-      return (MD->UndefLocation.isInvalid() ||
-              SM.isBeforeInTranslationUnit(L, MD->UndefLocation)) ? MD : NULL;
+  for (DefInfo Def = getDefinition(); Def; Def = Def.getPreviousDefinition()) {
+    if (Def.getLocation().isInvalid() ||  // For macros defined on the command line.
+        SM.isBeforeInTranslationUnit(Def.getLocation(), L))
+      return (!Def.isUndefined() ||
+              SM.isBeforeInTranslationUnit(L, Def.getUndefLocation()))
+                  ? Def : DefInfo();
   }
-  return NULL;
+  return DefInfo();
 }
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 7020da3..3fc19e4 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -70,11 +70,26 @@
   return MI;
 }
 
-MacroDirective *Preprocessor::AllocateMacroDirective(MacroInfo *MI,
-                                                     SourceLocation Loc,
-                                                     bool isImported) {
-  MacroDirective *MD = BP.Allocate<MacroDirective>();
-  new (MD) MacroDirective(MI, Loc, isImported);
+DefMacroDirective *
+Preprocessor::AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc,
+                                        bool isImported) {
+  DefMacroDirective *MD = BP.Allocate<DefMacroDirective>();
+  new (MD) DefMacroDirective(MI, Loc, isImported);
+  return MD;
+}
+
+UndefMacroDirective *
+Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc) {
+  UndefMacroDirective *MD = BP.Allocate<UndefMacroDirective>();
+  new (MD) UndefMacroDirective(UndefLoc);
+  return MD;
+}
+
+VisibilityMacroDirective *
+Preprocessor::AllocateVisibilityMacroDirective(SourceLocation Loc,
+                                               bool isPublic) {
+  VisibilityMacroDirective *MD = BP.Allocate<VisibilityMacroDirective>();
+  new (MD) VisibilityMacroDirective(Loc, isPublic);
   return MD;
 }
 
@@ -1130,15 +1145,8 @@
   }
   
   // Note that this macro has now been exported.
-  MD->setVisibility(/*IsPublic=*/true, MacroNameTok.getLocation());
-
-  // If this macro directive came from a PCH file, mark it as having changed
-  // since serialization.
-  if (MD->isFromPCH()) {
-    MD->setChangedAfterLoad();
-    assert(II->isFromAST());
-    II->setChangedSinceDeserialization();
-  }
+  appendMacroDirective(II, AllocateVisibilityMacroDirective(
+                                MacroNameTok.getLocation(), /*IsPublic=*/true));
 }
 
 /// \brief Handle a #private directive.
@@ -1164,15 +1172,8 @@
   }
   
   // Note that this macro has now been marked private.
-  MD->setVisibility(/*IsPublic=*/false, MacroNameTok.getLocation());
-
-  // If this macro directive came from a PCH file, mark it as having changed
-  // since serialization.
-  if (MD->isFromPCH()) {
-    MD->setChangedAfterLoad();
-    assert(II->isFromAST());
-    II->setChangedSinceDeserialization();
-  }
+  appendMacroDirective(II, AllocateVisibilityMacroDirective(
+                               MacroNameTok.getLocation(), /*IsPublic=*/false));
 }
 
 //===----------------------------------------------------------------------===//
@@ -1960,7 +1961,8 @@
       WarnUnusedMacroLocs.erase(OtherMI->getDefinitionLoc());
   }
 
-  MacroDirective *MD = setMacroDirective(MacroNameTok.getIdentifierInfo(), MI);
+  DefMacroDirective *MD =
+      appendDefMacroDirective(MacroNameTok.getIdentifierInfo(), MI);
 
   assert(!MI->isUsed());
   // If we need warning for not using the macro, add its location in the
@@ -1994,7 +1996,7 @@
 
   // Okay, we finally have a valid identifier to undef.
   MacroDirective *MD = getMacroDirective(MacroNameTok.getIdentifierInfo());
-  const MacroInfo *MI = MD ? MD->getInfo() : 0;
+  const MacroInfo *MI = MD ? MD->getMacroInfo() : 0;
 
   // If the callbacks want to know, tell them about the macro #undef.
   // Note: no matter if the macro was defined or not.
@@ -2010,20 +2012,8 @@
   if (MI->isWarnIfUnused())
     WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
 
-  UndefineMacro(MacroNameTok.getIdentifierInfo(), MD,
-                MacroNameTok.getLocation());
-}
-
-void Preprocessor::UndefineMacro(IdentifierInfo *II, MacroDirective *MD,
-                                 SourceLocation UndefLoc) {
-  MD->setUndefLoc(UndefLoc);
-  if (MD->isFromPCH()) {
-    MD->setChangedAfterLoad();
-    if (Listener)
-      Listener->UndefinedMacro(MD);
-  }
-
-  clearMacroInfo(II);
+  appendMacroDirective(MacroNameTok.getIdentifierInfo(),
+                       AllocateUndefMacroDirective(MacroNameTok.getLocation()));
 }
 
 
@@ -2058,7 +2048,7 @@
 
   IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
   MacroDirective *MD = getMacroDirective(MII);
-  MacroInfo *MI = MD ? MD->getInfo() : 0;
+  MacroInfo *MI = MD ? MD->getMacroInfo() : 0;
 
   if (CurPPLexer->getConditionalStackDepth() == 0) {
     // If the start of a top-level #ifdef and if the macro is not defined,
diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
index 27ad7b4..d9ce8bf 100644
--- a/lib/Lex/PPExpressions.cpp
+++ b/lib/Lex/PPExpressions.cpp
@@ -116,7 +116,7 @@
   // If there is a macro, mark it used.
   if (Result.Val != 0 && ValueLive) {
     Macro = PP.getMacroDirective(II);
-    PP.markMacroAsUsed(Macro->getInfo());
+    PP.markMacroAsUsed(Macro->getMacroInfo());
   }
 
   // Invoke the 'defined' callback.
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 868820b..bb2634f 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -41,15 +41,17 @@
   return Pos->second;
 }
 
-/// \brief Specify a macro for this identifier.
-void Preprocessor::setMacroDirective(IdentifierInfo *II, MacroDirective *MD) {
+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;
-  II->setHasMacroDefinition(true);
-  if (II->isFromAST())
+  II->setHasMacroDefinition(MD->isDefined());
+  bool isImportedMacro = isa<DefMacroDirective>(MD) &&
+                         cast<DefMacroDirective>(MD)->isImported();
+  if (II->isFromAST() && !isImportedMacro)
     II->setChangedSinceDeserialization();
 }
 
@@ -66,112 +68,6 @@
     II->setHasMacroDefinition(false);
 }
 
-void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroDirective *MD,
-                                      MacroDirective *Hint) {
-  assert(MD && "Missing macro?");
-  assert(MD->isImported() && "Macro is not from an AST?");
-  assert(!MD->getPrevious() && "Macro already in chain?");
-  
-  MacroDirective *&StoredMD = Macros[II];
-
-  // Easy case: this is the first macro definition for this macro.
-  if (!StoredMD) {
-    StoredMD = MD;
-
-    if (MD->isDefined())
-      II->setHasMacroDefinition(true);
-    return;
-  }
-
-  // If this macro is a definition and this identifier has been neither
-  // defined nor undef'd in the current translation unit, add this macro
-  // to the end of the chain of definitions.
-  if (MD->isDefined() && StoredMD->isImported()) {
-    // Simple case: if this is the first actual definition, just put it at
-    // th beginning.
-    if (!StoredMD->isDefined()) {
-      MD->setPrevious(StoredMD);
-      StoredMD = MD;
-
-      II->setHasMacroDefinition(true);
-      return;
-    }
-
-    // Find the end of the definition chain.
-    MacroDirective *Prev;
-    MacroDirective *PrevPrev = StoredMD;
-    bool Ambiguous = StoredMD->isAmbiguous();
-    bool MatchedOther = false;
-    do {
-      Prev = PrevPrev;
-
-      // If the macros are not identical, we have an ambiguity.
-      if (!Prev->getInfo()->isIdenticalTo(*MD->getInfo(), *this)) {
-        if (!Ambiguous) {
-          Ambiguous = true;
-          StoredMD->setAmbiguous(true);
-        }
-      } else {
-        MatchedOther = true;
-      }
-    } while ((PrevPrev = Prev->getPrevious()) &&
-             PrevPrev->isDefined());
-
-    // If there are ambiguous definitions, and we didn't match any other
-    // definition, then mark us as ambiguous.
-    if (Ambiguous && !MatchedOther)
-      MD->setAmbiguous(true);
-
-    // Wire this macro information into the chain.
-    MD->setPrevious(Prev->getPrevious());
-    Prev->setPrevious(MD);
-    return;
-  }
-
-  // The macro is not a definition; put it at the end of the list.
-  MacroDirective *Prev = Hint? Hint : StoredMD;
-  while (Prev->getPrevious())
-    Prev = Prev->getPrevious();
-  Prev->setPrevious(MD);
-}
-
-void Preprocessor::makeLoadedMacroInfoVisible(IdentifierInfo *II,
-                                              MacroDirective *MD) {
-  assert(MD->isImported() && "Macro must be from the AST");
-
-  MacroDirective *&StoredMD = Macros[II];
-  if (StoredMD == MD) {
-    // Easy case: this is the first macro anyway.
-    II->setHasMacroDefinition(MD->isDefined());
-    return;
-  }
-
-  // Go find the macro and pull it out of the list.
-  // FIXME: Yes, this is O(N), and making a pile of macros visible or hidden
-  // would be quadratic, but it's extremely rare.
-  MacroDirective *Prev = StoredMD;
-  while (Prev->getPrevious() != MD)
-    Prev = Prev->getPrevious();
-  Prev->setPrevious(MD->getPrevious());
-  MD->setPrevious(0);
-
-  // Add the macro back to the list.
-  addLoadedMacroInfo(II, MD);
-
-  II->setHasMacroDefinition(StoredMD->isDefined());
-  if (II->isFromAST())
-    II->setChangedSinceDeserialization();
-}
-
-/// \brief Undefine a macro for this identifier.
-void Preprocessor::clearMacroInfo(IdentifierInfo *II) {
-  assert(II->hasMacroDefinition() && "Macro is not defined!");
-  assert(Macros[II]->getUndefLoc().isValid() && "Macro is still defined!");
-  II->setHasMacroDefinition(false);
-  if (II->isFromAST())
-    II->setChangedSinceDeserialization();
-}
-
 /// 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){
@@ -181,7 +77,7 @@
   // Mark it as being a macro that is builtin.
   MacroInfo *MI = PP.AllocateMacroInfo(SourceLocation());
   MI->setIsBuiltinMacro();
-  PP.setMacroDirective(Id, MI);
+  PP.appendDefMacroDirective(Id, MI);
   return Id;
 }
 
@@ -315,7 +211,7 @@
 /// expanded as a macro, handle it and return the next token as 'Identifier'.
 bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
                                                  MacroDirective *MD) {
-  MacroInfo *MI = MD->getInfo();
+  MacroInfo *MI = MD->getMacroInfo();
 
   // If this is a macro expansion in the "#if !defined(x)" line for the file,
   // then the macro could expand to different things in other contexts, we need
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 2094dd1..95e8a8c 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -703,9 +703,10 @@
   if (iter != PragmaPushMacroInfo.end()) {
     // Forget the MacroInfo currently associated with IdentInfo.
     if (MacroDirective *CurrentMD = getMacroDirective(IdentInfo)) {
-      if (CurrentMD->getInfo()->isWarnIfUnused())
-        WarnUnusedMacroLocs.erase(CurrentMD->getInfo()->getDefinitionLoc());
-      UndefineMacro(IdentInfo, CurrentMD, MessageLoc);
+      MacroInfo *MI = CurrentMD->getMacroInfo();
+      if (MI->isWarnIfUnused())
+        WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
+      appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
     }
 
     // Get the MacroInfo we want to reinstall.
@@ -713,10 +714,8 @@
 
     if (MacroToReInstall) {
       // Reinstall the previously pushed macro.
-      setMacroDirective(IdentInfo, MacroToReInstall, MessageLoc,
-                        /*isImported=*/false);
-    } else if (IdentInfo->hasMacroDefinition()) {
-      clearMacroInfo(IdentInfo);
+      appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc,
+                              /*isImported=*/false);
     }
 
     // Pop PragmaPushMacroInfo stack.
diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp
index b834d6c..b10e7f7 100644
--- a/lib/Lex/PreprocessingRecord.cpp
+++ b/lib/Lex/PreprocessingRecord.cpp
@@ -385,31 +385,34 @@
                                 const MacroDirective *MD) {
   // This is not actually a macro expansion but record it as a macro reference.
   if (MD)
-    addMacroExpansion(MacroNameTok, MD->getInfo(), MacroNameTok.getLocation());
+    addMacroExpansion(MacroNameTok, MD->getMacroInfo(),
+                      MacroNameTok.getLocation());
 }
 
 void PreprocessingRecord::Ifndef(SourceLocation Loc, const Token &MacroNameTok,
                                  const MacroDirective *MD) {
   // This is not actually a macro expansion but record it as a macro reference.
   if (MD)
-    addMacroExpansion(MacroNameTok, MD->getInfo(), MacroNameTok.getLocation());
+    addMacroExpansion(MacroNameTok, MD->getMacroInfo(),
+                      MacroNameTok.getLocation());
 }
 
 void PreprocessingRecord::Defined(const Token &MacroNameTok,
                                   const MacroDirective *MD) {
   // This is not actually a macro expansion but record it as a macro reference.
   if (MD)
-    addMacroExpansion(MacroNameTok, MD->getInfo(), MacroNameTok.getLocation());
+    addMacroExpansion(MacroNameTok, MD->getMacroInfo(),
+                      MacroNameTok.getLocation());
 }
 
 void PreprocessingRecord::MacroExpands(const Token &Id,const MacroDirective *MD,
                                        SourceRange Range) {
-  addMacroExpansion(Id, MD->getInfo(), Range);
+  addMacroExpansion(Id, MD->getMacroInfo(), Range);
 }
 
 void PreprocessingRecord::MacroDefined(const Token &Id,
                                        const MacroDirective *MD) {
-  const MacroInfo *MI = MD->getInfo();
+  const MacroInfo *MI = MD->getMacroInfo();
   SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
   MacroDefinition *Def
       = new (*this) MacroDefinition(Id.getIdentifierInfo(), R);
@@ -421,7 +424,7 @@
                                          const MacroDirective *MD) {
   // Note: MI may be null (when #undef'ining an undefined macro).
   if (MD)
-    MacroDefinitions.erase(MD->getInfo());
+    MacroDefinitions.erase(MD->getMacroInfo());
 }
 
 void PreprocessingRecord::InclusionDirective(
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index af000ec..bda72be 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -306,15 +306,15 @@
   StringRef BestSpelling;
   for (Preprocessor::macro_iterator I = macro_begin(), E = macro_end();
        I != E; ++I) {
-    if (!I->second->getInfo()->isObjectLike())
+    if (!I->second->getMacroInfo()->isObjectLike())
       continue;
-    const MacroDirective *
-      MD = I->second->findDirectiveAtLoc(Loc, SourceMgr);
-    if (!MD)
+    const MacroDirective::DefInfo
+      Def = I->second->findDirectiveAtLoc(Loc, SourceMgr);
+    if (!Def)
       continue;
-    if (!MacroDefinitionEquals(MD->getInfo(), Tokens))
+    if (!MacroDefinitionEquals(Def.getMacroInfo(), Tokens))
       continue;
-    SourceLocation Location = I->second->getInfo()->getDefinitionLoc();
+    SourceLocation Location = Def.getLocation();
     // Choose the macro defined latest.
     if (BestLocation.isInvalid() ||
         (Location.isValid() &&
@@ -643,7 +643,7 @@
 
   // If this is a macro to be expanded, do it.
   if (MacroDirective *MD = getMacroDirective(&II)) {
-    MacroInfo *MI = MD->getInfo();
+    MacroInfo *MI = MD->getMacroInfo();
     if (!DisableMacroExpansion) {
       if (!Identifier.isExpandDisabled() && MI->isEnabled()) {
         if (!HandleMacroExpandedIdentifier(Identifier, MD))
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 34c83ed..2fa08fd 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -2575,7 +2575,7 @@
   if (Kind == RK_Macro) {
     const MacroDirective *MD = PP.getMacroDirectiveHistory(Macro);
     assert(MD && "Not a macro?");
-    const MacroInfo *MI = MD->getInfo();
+    const MacroInfo *MI = MD->getMacroInfo();
 
     Result.AddTypedTextChunk(
                             Result.getAllocator().CopyString(Macro->getName()));
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index c6dbfe1..837524d 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -1476,8 +1476,8 @@
 
   MacroInfo *MI = getMacro(GMacID);
   SubmoduleID SubModID = MI->getOwningModuleID();
-  MacroDirective *MD = PP.AllocateMacroDirective(MI, ImportLoc,
-                                                 /*isImported=*/true);
+  MacroDirective *MD = PP.AllocateDefMacroDirective(MI, ImportLoc,
+                                                    /*isImported=*/true);
 
   // Determine whether this macro definition is visible.
   bool Hidden = false;
@@ -1494,7 +1494,6 @@
       }
     }
   }
-  MD->setHidden(Hidden);
 
   if (!Hidden)
     installImportedMacro(II, MD);
@@ -1527,22 +1526,30 @@
   MacroDirective *Latest = 0, *Earliest = 0;
   unsigned Idx = 0, N = Record.size();
   while (Idx < N) {
-    GlobalMacroID GMacID = getGlobalMacroID(M, Record[Idx++]);
-    MacroInfo *MI = getMacro(GMacID);
+    MacroDirective *MD = 0;
     SourceLocation Loc = ReadSourceLocation(M, Record, Idx);
-    SourceLocation UndefLoc = ReadSourceLocation(M, Record, Idx);
-    SourceLocation VisibilityLoc = ReadSourceLocation(M, Record, Idx);
-    bool isImported = Record[Idx++];
-    bool isPublic = Record[Idx++];
-    bool isAmbiguous = Record[Idx++];
-
-    MacroDirective *MD = PP.AllocateMacroDirective(MI, Loc, isImported);
-    if (UndefLoc.isValid())
-      MD->setUndefLoc(UndefLoc);
-    if (VisibilityLoc.isValid())
-      MD->setVisibility(isPublic, VisibilityLoc);
-    MD->setAmbiguous(isAmbiguous);
-    MD->setIsFromPCH();
+    MacroDirective::Kind K = (MacroDirective::Kind)Record[Idx++];
+    switch (K) {
+    case MacroDirective::MD_Define: {
+      GlobalMacroID GMacID = getGlobalMacroID(M, Record[Idx++]);
+      MacroInfo *MI = getMacro(GMacID);
+      bool isImported = Record[Idx++];
+      bool isAmbiguous = Record[Idx++];
+      DefMacroDirective *DefMD =
+          PP.AllocateDefMacroDirective(MI, Loc, isImported);
+      DefMD->setAmbiguous(isAmbiguous);
+      MD = DefMD;
+      break;
+    }
+    case MacroDirective::MD_Undefine:
+      MD = PP.AllocateUndefMacroDirective(Loc);
+      break;
+    case MacroDirective::MD_Visibility: {
+      bool isPublic = Record[Idx++];
+      MD = PP.AllocateVisibilityMacroDirective(Loc, isPublic);
+      break;
+    }
+    }
 
     if (!Latest)
       Latest = MD;
@@ -1557,13 +1564,18 @@
 void ASTReader::installImportedMacro(IdentifierInfo *II, MacroDirective *MD) {
   assert(II && MD);
 
+  DefMacroDirective *DefMD = cast<DefMacroDirective>(MD);
   MacroDirective *Prev = PP.getMacroDirective(II);
-  if (Prev && !Prev->getInfo()->isIdenticalTo(*MD->getInfo(), PP)) {
-    Prev->setAmbiguous(true);
-    MD->setAmbiguous(true);
+  if (Prev) {
+    MacroDirective::DefInfo PrevDef = Prev->getDefinition();
+    if (DefMD->getInfo() != PrevDef.getMacroInfo() &&
+        !PrevDef.getMacroInfo()->isIdenticalTo(*DefMD->getInfo(), PP)) {
+      PrevDef.getDirective()->setAmbiguous(true);
+      DefMD->setAmbiguous(true);
+    }
   }
   
-  PP.setMacroDirective(II, MD);
+  PP.appendMacroDirective(II, MD);
 }
 
 InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
@@ -2723,21 +2735,12 @@
     }
     case HiddenName::MacroVisibility: {
       std::pair<IdentifierInfo *, MacroDirective *> Macro = Names[I].getMacro();
-      Macro.second->setHidden(!Macro.second->isPublic());
-      if (Macro.second->isDefined()) {
-        installImportedMacro(Macro.first, Macro.second);
-      }
+      installImportedMacro(Macro.first, Macro.second);
       break;
     }
 
     case HiddenName::MacroUndef: {
-      std::pair<IdentifierInfo *, MacroDirective *> Macro = Names[I].getMacro();
-      if (Macro.second->isDefined()) {
-        Macro.second->setUndefLoc(Names[I].getMacroUndefLoc());
-        if (PPMutationListener *Listener = PP.getPPMutationListener())
-          Listener->UndefinedMacro(Macro.second);
-        PP.makeLoadedMacroInfoVisible(Macro.first, Macro.second);
-      }
+      // FIXME: Remove HiddenName::MacroUndef and PPMutationListener.
       break;
     }
     }
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 7258963..95e32a3 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1833,8 +1833,9 @@
 
 static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule,
                               const Preprocessor &PP) {
-  if (MD->getInfo()->isBuiltinMacro())
-    return true;
+  if (MacroInfo *MI = MD->getMacroInfo())
+    if (MI->isBuiltinMacro())
+      return true;
 
   if (IsModule) {
     SourceLocation Loc = MD->getLocation();
@@ -1902,25 +1903,30 @@
 
     // If the macro or identifier need no updates, don't write the macro history
     // for this one.
-    if (MD->isFromPCH() && !MD->hasChangedAfterLoad() &&
+    // FIXME: Chain the macro history instead of re-writing it.
+    if (MD->isFromPCH() &&
         Name->isFromAST() && !Name->hasChangedSinceDeserialization())
       continue;
 
     // Emit the macro directives in reverse source order.
     for (; MD; MD = MD->getPrevious()) {
+      if (MD->isHidden())
+        continue;
       if (shouldIgnoreMacro(MD, IsModule, PP))
         continue;
-      MacroID InfoID = getMacroRef(MD->getInfo(), Name);
-      if (InfoID == 0)
-        continue;
 
-      Record.push_back(InfoID);
       AddSourceLocation(MD->getLocation(), Record);
-      AddSourceLocation(MD->getUndefLoc(), Record);
-      AddSourceLocation(MD->getVisibilityLocation(), Record);
-      Record.push_back(MD->isImported());
-      Record.push_back(MD->isPublic());
-      Record.push_back(MD->isAmbiguous());
+      Record.push_back(MD->getKind());
+      if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
+        MacroID InfoID = getMacroRef(DefMD->getInfo(), Name);
+        Record.push_back(InfoID);
+        Record.push_back(DefMD->isImported());
+        Record.push_back(DefMD->isAmbiguous());
+
+      } else if (VisibilityMacroDirective *
+                   VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
+        Record.push_back(VisMD->isPublic());
+      }
     }
     if (Record.empty())
       continue;
@@ -2898,48 +2904,78 @@
     return false;
   }
 
-  MacroDirective *getFirstPublicSubmoduleMacro(MacroDirective *MD,
-                                               SubmoduleID &ModID) {
-    if (shouldIgnoreMacro(MD, IsModule, PP))
-      return 0;
-    ModID = getSubmoduleID(MD);
-    if (ModID == 0)
-      return 0;
-    if (MD->isDefined() && MD->isPublic())
-      return MD;
-    return getNextPublicSubmoduleMacro(MD, ModID);
-  }
-
-  MacroDirective *getNextPublicSubmoduleMacro(MacroDirective *MD,
-                                              SubmoduleID &ModID) {
-    while (MD) {
-      MD = getNextSubmoduleMacro(MD, ModID);
-      if (MD && MD->isDefined() && MD->isPublic())
-        return MD;
-    }
+  DefMacroDirective *getFirstPublicSubmoduleMacro(MacroDirective *MD,
+                                                  SubmoduleID &ModID) {
+    ModID = 0;
+    if (DefMacroDirective *DefMD = getPublicSubmoduleMacro(MD, ModID))
+      if (!shouldIgnoreMacro(DefMD, IsModule, PP))
+        return DefMD;
     return 0;
   }
 
-  MacroDirective *getNextSubmoduleMacro(MacroDirective *CurrMD,
-                                        SubmoduleID &CurrModID) {
-    SubmoduleID OrigID = CurrModID;
-    while ((CurrMD = CurrMD->getPrevious())) {
-      if (shouldIgnoreMacro(CurrMD, IsModule, PP))
-        return 0;
-      CurrModID = getSubmoduleID(CurrMD);
-      if (CurrModID == 0)
-        return 0;
-      if (CurrModID != OrigID)
-        return CurrMD;
+  DefMacroDirective *getNextPublicSubmoduleMacro(DefMacroDirective *MD,
+                                                 SubmoduleID &ModID) {
+    if (DefMacroDirective *
+          DefMD = getPublicSubmoduleMacro(MD->getPrevious(), ModID))
+      if (!shouldIgnoreMacro(DefMD, IsModule, PP))
+        return DefMD;
+    return 0;
+  }
+
+  /// \brief Traverses the macro directives history and returns the latest
+  /// macro that is public and not undefined in the same submodule.
+  /// A macro that is defined in submodule A and undefined in submodule B,
+  /// will still be considered as defined/exported from submodule A.
+  DefMacroDirective *getPublicSubmoduleMacro(MacroDirective *MD,
+                                             SubmoduleID &ModID) {
+    if (!MD)
+      return 0;
+
+    bool isUndefined = false;
+    Optional<bool> isPublic;
+    for (; MD; MD = MD->getPrevious()) {
+      if (MD->isHidden())
+        continue;
+
+      SubmoduleID ThisModID = getSubmoduleID(MD);
+      if (ThisModID == 0) {
+        isUndefined = false;
+        isPublic = Optional<bool>();
+        continue;
+      }
+      if (ThisModID != ModID){
+        ModID = ThisModID;
+        isUndefined = false;
+        isPublic = Optional<bool>();
+      }
+
+      if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
+        if (!isUndefined && (!isPublic.hasValue() || isPublic.getValue()))
+          return DefMD;
+        continue;
+      }
+
+      if (isa<UndefMacroDirective>(MD)) {
+        isUndefined = true;
+        continue;
+      }
+
+      VisibilityMacroDirective *VisMD = cast<VisibilityMacroDirective>(MD);
+      if (!isPublic.hasValue())
+        isPublic = VisMD->isPublic();
     }
+
     return 0;
   }
 
   SubmoduleID getSubmoduleID(MacroDirective *MD) {
-    MacroInfo *MI = MD->getInfo();
-    if (unsigned ID = MI->getOwningModuleID())
-      return ID;
-    return Writer.inferSubmoduleIDFromLocation(MI->getDefinitionLoc());
+    if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
+      MacroInfo *MI = DefMD->getInfo();
+      if (unsigned ID = MI->getOwningModuleID())
+        return ID;
+      return Writer.inferSubmoduleIDFromLocation(MI->getDefinitionLoc());
+    }
+    return Writer.inferSubmoduleIDFromLocation(MD->getLocation());
   }
 
 public:
@@ -2969,8 +3005,9 @@
         DataLen += 4; // MacroDirectives offset.
         if (IsModule) {
           SubmoduleID ModID;
-          for (MacroDirective *MD = getFirstPublicSubmoduleMacro(Macro, ModID);
-                 MD; MD = getNextPublicSubmoduleMacro(MD, ModID)) {
+          for (DefMacroDirective *
+                 DefMD = getFirstPublicSubmoduleMacro(Macro, ModID);
+                 DefMD; DefMD = getNextPublicSubmoduleMacro(DefMD, ModID)) {
             DataLen += 4; // MacroInfo ID.
           }
           DataLen += 4;
@@ -3025,9 +3062,10 @@
       if (IsModule) {
         // Write the IDs of macros coming from different submodules.
         SubmoduleID ModID;
-        for (MacroDirective *MD = getFirstPublicSubmoduleMacro(Macro, ModID);
-               MD; MD = getNextPublicSubmoduleMacro(MD, ModID)) {
-          MacroID InfoID = Writer.getMacroID(MD->getInfo());
+        for (DefMacroDirective *
+               DefMD = getFirstPublicSubmoduleMacro(Macro, ModID);
+               DefMD; DefMD = getNextPublicSubmoduleMacro(DefMD, ModID)) {
+          MacroID InfoID = Writer.getMacroID(DefMD->getInfo());
           assert(InfoID);
           clang::io::Emit32(Out, InfoID);
         }