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

Argyrios Kyrtzidis akyrtzi at gmail.com
Tue Mar 26 10:17:01 PDT 2013


Author: akirtzidis
Date: Tue Mar 26 12:17:01 2013
New Revision: 178037

URL: http://llvm.org/viewvc/llvm-project?rev=178037&view=rev
Log:
[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.

Modified:
    cfe/trunk/include/clang/Lex/MacroInfo.h
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/lib/Frontend/CompilerInstance.cpp
    cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
    cfe/trunk/lib/Lex/MacroInfo.cpp
    cfe/trunk/lib/Lex/PPDirectives.cpp
    cfe/trunk/lib/Lex/PPExpressions.cpp
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
    cfe/trunk/lib/Lex/Pragma.cpp
    cfe/trunk/lib/Lex/PreprocessingRecord.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
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/Lex/MacroInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroInfo.h?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/MacroInfo.h (original)
+++ cfe/trunk/include/clang/Lex/MacroInfo.h Tue Mar 26 12:17:01 2013
@@ -299,6 +299,8 @@ private:
   friend class Preprocessor;
 };
 
+class DefMacroDirective;
+
 /// \brief Encapsulates changes to the "macros namespace" (the location where
 /// the macro name became active, the location where it was undefined, etc.).
 ///
@@ -314,76 +316,56 @@ private:
 /// will point to the same MacroInfo object.
 ///
 class MacroDirective {
-  MacroInfo *Info;
+public:
+  enum Kind {
+    MD_Define,
+    MD_Undefine,
+    MD_Visibility
+  };
 
-  /// \brief Previous definition, the identifier of this macro was defined to,
-  /// or NULL.
+protected:
+  /// \brief Previous macro directive for the same identifier, or NULL.
   MacroDirective *Previous;
 
   SourceLocation Loc;
 
-  /// \brief The location where the macro was #undef'd, or an invalid location
-  /// for macros that haven't been undefined.
-  SourceLocation UndefLocation;
-
-  /// \brief The location at which this macro was either explicitly exported
-  /// from its module or marked as private.
-  ///
-  /// If invalid, this macro has not been explicitly given any visibility.
-  SourceLocation VisibilityLocation;
+  /// \brief MacroDirective kind.
+  unsigned MDKind : 2;
 
   /// \brief True if the macro directive was loaded from a PCH file.
   bool IsFromPCH : 1;
 
-  /// \brief True if this macro was imported from a module.
-  bool IsImported : 1;
-
-  /// \brief Whether the macro has public (when described in a module).
-  bool IsPublic : 1;
-
-  /// \brief Whether the macro definition is currently "hidden".
+  /// \brief Whether the macro directive is currently "hidden".
   ///
   /// Note that this is transient state that is never serialized to the AST
   /// file.
   bool IsHidden : 1;
 
+  // Used by DefMacroDirective -----------------------------------------------//
+
+  /// \brief True if this macro was imported from a module.
+  bool IsImported : 1;
+
   /// \brief Whether the definition of this macro is ambiguous, due to
   /// multiple definitions coming in from multiple modules.
   bool IsAmbiguous : 1;
 
-  /// \brief Whether this macro changed after it was loaded from an AST file.
-  bool ChangedAfterLoad : 1;
+  // Used by VisibilityMacroDirective ----------------------------------------//
 
-public:
-  explicit MacroDirective(MacroInfo *MI)
-    : Info(MI), Previous(0), Loc(MI->getDefinitionLoc()),
-      IsFromPCH(false), IsImported(false), IsPublic(true), IsHidden(false),
-      IsAmbiguous(false), ChangedAfterLoad(false) {
-    assert(MI && "MacroInfo is null");
-  }
+  /// \brief Whether the macro has public visibility (when described in a
+  /// module).
+  bool IsPublic : 1;
 
-  MacroDirective(MacroInfo *MI, SourceLocation Loc, bool isImported)
-    : Info(MI), Previous(0), Loc(Loc),
-      IsFromPCH(false), IsImported(isImported), IsPublic(true), IsHidden(false),
-      IsAmbiguous(false), ChangedAfterLoad(false) {
-    assert(MI && "MacroInfo is null");
+  MacroDirective(Kind K, SourceLocation Loc)
+    : Previous(0), Loc(Loc), MDKind(K), IsFromPCH(false), IsHidden(false),
+      IsImported(false), IsAmbiguous(false),
+      IsPublic(true) {
   }
 
-  SourceLocation getLocation() const { return Loc; }
-
-  /// \brief Set the location where macro was undefined. Can only be set once.
-  void setUndefLoc(SourceLocation UndefLoc) {
-    assert(UndefLocation.isInvalid() && "UndefLocation is already set!");
-    assert(UndefLoc.isValid() && "Invalid UndefLoc!");
-    UndefLocation = UndefLoc;
-  }
-
-  /// \brief The data for the macro definition.
-  const MacroInfo *getInfo() const { return Info; }
-  MacroInfo *getInfo() { return Info; }
+public:
+  Kind getKind() const { return Kind(MDKind); }
 
-  /// \brief Get the location where macro was undefined.
-  SourceLocation getUndefLoc() const { return UndefLocation; }
+  SourceLocation getLocation() const { return Loc; }
 
   /// \brief Set previous definition of the macro with the same name.
   void setPrevious(MacroDirective *Prev) {
@@ -396,42 +378,104 @@ public:
   /// \brief Get previous definition of the macro with the same name.
   MacroDirective *getPrevious() { return Previous; }
 
-  /// \brief Find macro definition active in the specified source location. If
-  /// this macro was not defined there, return NULL.
-  const MacroDirective *findDirectiveAtLoc(SourceLocation L,
-                                           SourceManager &SM) const;
+  /// \brief Return true if the macro directive was loaded from a PCH file.
+  bool isFromPCH() const { return IsFromPCH; }
 
-  /// \brief Set the export location for this macro.
-  void setVisibility(bool Public, SourceLocation Loc) {
-    VisibilityLocation = Loc;
-    IsPublic = Public;
+  void setIsFromPCH() { IsFromPCH = true; }
+
+  /// \brief Determine whether this macro directive is hidden.
+  bool isHidden() const { return IsHidden; }
+
+  /// \brief Set whether this macro directive is hidden.
+  void setHidden(bool Val) { IsHidden = Val; }
+
+  class DefInfo {
+    DefMacroDirective *DefDirective;
+    SourceLocation UndefLoc;
+    bool IsPublic;
+
+  public:
+    DefInfo() : DefDirective(0) { }
+
+    DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
+            bool isPublic)
+      : DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) { }
+
+    const DefMacroDirective *getDirective() const { return DefDirective; }
+          DefMacroDirective *getDirective()       { return DefDirective; }
+
+    inline SourceLocation getLocation() const;
+    inline MacroInfo *getMacroInfo();
+    const MacroInfo *getMacroInfo() const {
+      return const_cast<DefInfo*>(this)->getMacroInfo();
+    }
+
+    SourceLocation getUndefLocation() const { return UndefLoc; }
+    bool isUndefined() const { return UndefLoc.isValid(); }
+
+    bool isPublic() const { return IsPublic; }
+
+    bool isValid() const { return DefDirective != 0; }
+    bool isInvalid() const { return !isValid(); }
+
+    operator bool() const { return isValid(); }
+
+    inline DefInfo getPreviousDefinition(bool AllowHidden = false);
+    const DefInfo getPreviousDefinition(bool AllowHidden = false) const {
+      return const_cast<DefInfo*>(this)->getPreviousDefinition(AllowHidden);
+    }
+  };
+
+  /// \brief Traverses the macro directives history and returns the next
+  /// macro definition directive along with info about its undefined location
+  /// (if there is one) and if it is public or private.
+  DefInfo getDefinition(bool AllowHidden = false);
+  const DefInfo getDefinition(bool AllowHidden = false) const {
+    return const_cast<MacroDirective*>(this)->getDefinition(AllowHidden);
   }
 
-  /// \brief Determine whether this macro is part of the public API of its
-  /// module.
-  bool isPublic() const { return IsPublic; }
-  
-  /// \brief Determine the location where this macro was explicitly made
-  /// public or private within its module.
-  SourceLocation getVisibilityLocation() const { return VisibilityLocation; }
+  bool isDefined(bool AllowHidden = false) const {
+    if (const DefInfo Def = getDefinition(AllowHidden))
+      return !Def.isUndefined();
+    return false;
+  }
 
-  /// \brief Return true if the macro directive was loaded from a PCH file.
-  bool isFromPCH() const { return IsFromPCH; }
+  const MacroInfo *getMacroInfo(bool AllowHidden = false) const {
+    return getDefinition(AllowHidden).getMacroInfo();
+  }
+  MacroInfo *getMacroInfo(bool AllowHidden = false) {
+    return getDefinition(AllowHidden).getMacroInfo();
+  }
 
-  void setIsFromPCH() { IsFromPCH = true; }
+  /// \brief Find macro definition active in the specified source location. If
+  /// this macro was not defined there, return NULL.
+  const DefInfo findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const;
 
-  /// \brief True if this macro was imported from a module.
-  bool isImported() const { return IsImported; }
+  static bool classof(const MacroDirective *) { return true; }
+};
 
-  /// \brief Determine whether this macro is currently defined (and has not
-  /// been #undef'd) or has been hidden.
-  bool isDefined() const { return UndefLocation.isInvalid() && !IsHidden; }
+/// \brief A directive for a defined macro or a macro imported from a module.
+class DefMacroDirective : public MacroDirective {
+  MacroInfo *Info;
 
-  /// \brief Determine whether this macro definition is hidden.
-  bool isHidden() const { return IsHidden; }
+public:
+  explicit DefMacroDirective(MacroInfo *MI)
+    : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) {
+    assert(MI && "MacroInfo is null");
+  }
 
-  /// \brief Set whether this macro definition is hidden.
-  void setHidden(bool Val) { IsHidden = Val; }
+  DefMacroDirective(MacroInfo *MI, SourceLocation Loc, bool isImported)
+    : MacroDirective(MD_Define, Loc), Info(MI) {
+    assert(MI && "MacroInfo is null");
+    IsImported = isImported;
+  }
+
+  /// \brief The data for the macro definition.
+  const MacroInfo *getInfo() const { return Info; }
+  MacroInfo *getInfo() { return Info; }
+
+  /// \brief True if this macro was imported from a module.
+  bool isImported() const { return IsImported; }
 
   /// \brief Determine whether this macro definition is ambiguous with
   /// other macro definitions.
@@ -440,15 +484,63 @@ public:
   /// \brief Set whether this macro definition is ambiguous.
   void setAmbiguous(bool Val) { IsAmbiguous = Val; }
 
-  /// \brief Determine whether this macro has changed since it was loaded from
-  /// an AST file.
-  bool hasChangedAfterLoad() const { return ChangedAfterLoad; }
-
-  /// \brief Note whether this macro has changed after it was loaded from an
-  /// AST file.
-  void setChangedAfterLoad(bool CAL = true) { ChangedAfterLoad = CAL; }
+  static bool classof(const MacroDirective *MD) {
+    return MD->getKind() == MD_Define;
+  }
+  static bool classof(const DefMacroDirective *) { return true; }
+};
+
+/// \brief A directive for an undefined macro.
+class UndefMacroDirective : public MacroDirective  {
+public:
+  explicit UndefMacroDirective(SourceLocation UndefLoc)
+    : MacroDirective(MD_Undefine, UndefLoc) {
+    assert(UndefLoc.isValid() && "Invalid UndefLoc!");
+  }
+
+  static bool classof(const MacroDirective *MD) {
+    return MD->getKind() == MD_Undefine;
+  }
+  static bool classof(const UndefMacroDirective *) { return true; }
+};
+
+/// \brief A directive for setting the module visibility of a macro.
+class VisibilityMacroDirective : public MacroDirective  {
+public:
+  explicit VisibilityMacroDirective(SourceLocation Loc, bool Public)
+    : MacroDirective(MD_Visibility, Loc) {
+    IsPublic = Public;
+  }
+
+  /// \brief Determine whether this macro is part of the public API of its
+  /// module.
+  bool isPublic() const { return IsPublic; }
+
+  static bool classof(const MacroDirective *MD) {
+    return MD->getKind() == MD_Visibility;
+  }
+  static bool classof(const VisibilityMacroDirective *) { return true; }
 };
 
+inline SourceLocation MacroDirective::DefInfo::getLocation() const {
+  if (isInvalid())
+    return SourceLocation();
+  return DefDirective->getLocation();
+}
+
+inline MacroInfo *MacroDirective::DefInfo::getMacroInfo() {
+  if (isInvalid())
+    return 0;
+  return DefDirective->getInfo();
+}
+
+inline MacroDirective::DefInfo
+MacroDirective::DefInfo::getPreviousDefinition(bool AllowHidden) {
+  if (isInvalid() || DefDirective->getPrevious() == 0)
+    return DefInfo();
+  return DefDirective->getPrevious()->getDefinition(AllowHidden);
+}
+
 }  // 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=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Tue Mar 26 12:17:01 2013
@@ -532,14 +532,14 @@ public:
   /// associated with this preprocessor, if any.
   PPMutationListener *getPPMutationListener() const { return Listener; }
 
-  /// \brief Given an identifier, return the MacroInfo it is \#defined to
-  /// or null if it isn't \#define'd.
+  /// \brief Given an identifier, return its latest MacroDirective if it is
+  // \#defined or null if it isn't \#define'd.
   MacroDirective *getMacroDirective(IdentifierInfo *II) const {
     if (!II->hasMacroDefinition())
       return 0;
 
     MacroDirective *MD = getMacroDirectiveHistory(II);
-    assert(MD->getUndefLoc().isInvalid() && "Macro is undefined!");
+    assert(MD->isDefined() && "Macro is undefined!");
     return MD;
   }
 
@@ -549,7 +549,7 @@ public:
 
   MacroInfo *getMacroInfo(IdentifierInfo *II) {
     if (MacroDirective *MD = getMacroDirective(II))
-      return MD->getInfo();
+      return MD->getMacroInfo();
     return 0;
   }
 
@@ -559,27 +559,20 @@ public:
   /// identifiers that hadMacroDefinition().
   MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const;
 
-  /// \brief Specify a macro for this identifier.
-  void setMacroDirective(IdentifierInfo *II, MacroDirective *MD);
-  MacroDirective *setMacroDirective(IdentifierInfo *II, MacroInfo *MI,
-                                    SourceLocation Loc, bool isImported) {
-    MacroDirective *MD = AllocateMacroDirective(MI, Loc, isImported);
-    setMacroDirective(II, MD);
+  /// \brief Add a directive to the macro directive history for this identifier.
+  void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD);
+  DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI,
+                                             SourceLocation Loc,
+                                             bool isImported) {
+    DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc, isImported);
+    appendMacroDirective(II, MD);
     return MD;
   }
-  MacroDirective *setMacroDirective(IdentifierInfo *II, MacroInfo *MI) {
-    return setMacroDirective(II, MI, MI->getDefinitionLoc(), false);
+  DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI){
+    return appendDefMacroDirective(II, MI, MI->getDefinitionLoc(), false);
   }
   /// \brief Set a MacroDirective that was loaded from a PCH file.
   void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
-  /// \brief Add a MacroInfo that was loaded from an AST file.
-  void addLoadedMacroInfo(IdentifierInfo *II, MacroDirective *MD,
-                          MacroDirective *Hint = 0);
-  /// \brief Make the given MacroInfo, that was loaded from an AST file and
-  /// previously hidden, visible.
-  void makeLoadedMacroInfoVisible(IdentifierInfo *II, MacroDirective *MD);
-  /// \brief Undefine a macro for this identifier.
-  void clearMacroInfo(IdentifierInfo *II);
 
   /// macro_iterator/macro_begin/macro_end - This allows you to walk the macro
   /// history table. Currently defined macros have
@@ -1294,8 +1287,12 @@ private:
   /// \brief Allocate a new MacroInfo object.
   MacroInfo *AllocateMacroInfo();
 
-  MacroDirective *AllocateMacroDirective(MacroInfo *MI, SourceLocation Loc,
-                                         bool isImported);
+  DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI,
+                                               SourceLocation Loc,
+                                               bool isImported);
+  UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc);
+  VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc,
+                                                             bool isPublic);
 
   /// \brief Release the specified MacroInfo for re-use.
   ///
@@ -1449,8 +1446,6 @@ private:
   // Macro handling.
   void HandleDefineDirective(Token &Tok);
   void HandleUndefDirective(Token &Tok);
-  void UndefineMacro(IdentifierInfo *II, MacroDirective *MD,
-                     SourceLocation UndefLoc);
 
   // Conditional Inclusion.
   void HandleIfdefDirective(Token &Tok, bool isIfndef,

Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Tue Mar 26 12:17:01 2013
@@ -923,10 +923,11 @@ static void checkConfigMacro(Preprocesso
   // 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 @@ static void checkConfigMacro(Preprocesso
       // 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 @@ static void checkConfigMacro(Preprocesso
 
   // 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 @@ static void checkConfigMacro(Preprocesso
     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;
 }
 

Modified: cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp (original)
+++ cfe/trunk/lib/Frontend/PrintPreprocessedOutput.cpp Tue Mar 26 12:17:01 2013
@@ -318,7 +318,7 @@ void PrintPPOutputPPCallbacks::Ident(Sou
 /// 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 @@ 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->getInfo()));
+      MacrosByID.push_back(id_macro_pair(I->first, I->second->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=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/MacroInfo.cpp (original)
+++ cfe/trunk/lib/Lex/MacroInfo.cpp Tue Mar 26 12:17:01 2013
@@ -108,14 +108,40 @@ bool MacroInfo::isIdenticalTo(const Macr
   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();
 }

Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Tue Mar 26 12:17:01 2013
@@ -70,11 +70,26 @@ MacroInfo *Preprocessor::AllocateDeseria
   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 @@ void Preprocessor::HandleMacroPublicDire
   }
   
   // 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 @@ void Preprocessor::HandleMacroPrivateDir
   }
   
   // 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 @@ void Preprocessor::HandleDefineDirective
       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 @@ void Preprocessor::HandleUndefDirective(
 
   // 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 @@ void Preprocessor::HandleUndefDirective(
   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 @@ void Preprocessor::HandleIfdefDirective(
 
   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,

Modified: cfe/trunk/lib/Lex/PPExpressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPExpressions.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPExpressions.cpp (original)
+++ cfe/trunk/lib/Lex/PPExpressions.cpp Tue Mar 26 12:17:01 2013
@@ -116,7 +116,7 @@ static bool EvaluateDefined(PPValue &Res
   // 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.

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Tue Mar 26 12:17:01 2013
@@ -41,15 +41,17 @@ Preprocessor::getMacroDirectiveHistory(c
   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 @@ void Preprocessor::setLoadedMacroDirecti
     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 @@ static IdentifierInfo *RegisterBuiltinMa
   // 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 @@ bool Preprocessor::isNextPPTokenLParen()
 /// 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

Modified: cfe/trunk/lib/Lex/Pragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Pragma.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Pragma.cpp (original)
+++ cfe/trunk/lib/Lex/Pragma.cpp Tue Mar 26 12:17:01 2013
@@ -703,9 +703,10 @@ void Preprocessor::HandlePragmaPopMacro(
   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 @@ void Preprocessor::HandlePragmaPopMacro(
 
     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.

Modified: cfe/trunk/lib/Lex/PreprocessingRecord.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PreprocessingRecord.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PreprocessingRecord.cpp (original)
+++ cfe/trunk/lib/Lex/PreprocessingRecord.cpp Tue Mar 26 12:17:01 2013
@@ -385,31 +385,34 @@ void PreprocessingRecord::Ifdef(SourceLo
                                 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 @@ void PreprocessingRecord::MacroUndefined
                                          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(

Modified: cfe/trunk/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Tue Mar 26 12:17:01 2013
@@ -306,15 +306,15 @@ StringRef Preprocessor::getLastMacroWith
   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 @@ void Preprocessor::HandleIdentifier(Toke
 
   // 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))

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Tue Mar 26 12:17:01 2013
@@ -2575,7 +2575,7 @@ CodeCompletionResult::CreateCodeCompleti
   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()));

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Mar 26 12:17:01 2013
@@ -1476,8 +1476,8 @@ void ASTReader::resolvePendingMacro(Iden
 
   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 @@ void ASTReader::resolvePendingMacro(Iden
       }
     }
   }
-  MD->setHidden(Hidden);
 
   if (!Hidden)
     installImportedMacro(II, MD);
@@ -1527,22 +1526,30 @@ void ASTReader::installPCHMacroDirective
   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::installPCHMacroDirective
 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 @@ void ASTReader::makeNamesVisible(const H
     }
     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;
     }
     }

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Mar 26 12:17:01 2013
@@ -1833,8 +1833,9 @@ static int compareMacroDirectives(const
 
 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 @@ void ASTWriter::WritePreprocessor(const
 
     // 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 (shouldIgnoreMacro(MD, IsModule, PP))
+      if (MD->isHidden())
         continue;
-      MacroID InfoID = getMacroRef(MD->getInfo(), Name);
-      if (InfoID == 0)
+      if (shouldIgnoreMacro(MD, IsModule, PP))
         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 @@ class ASTIdentifierTableTrait {
     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);
+  DefMacroDirective *getFirstPublicSubmoduleMacro(MacroDirective *MD,
+                                                  SubmoduleID &ModID) {
+    ModID = 0;
+    if (DefMacroDirective *DefMD = getPublicSubmoduleMacro(MD, ModID))
+      if (!shouldIgnoreMacro(DefMD, IsModule, PP))
+        return DefMD;
+    return 0;
   }
 
-  MacroDirective *getNextPublicSubmoduleMacro(MacroDirective *MD,
-                                              SubmoduleID &ModID) {
-    while (MD) {
-      MD = getNextSubmoduleMacro(MD, ModID);
-      if (MD && MD->isDefined() && MD->isPublic())
-        return MD;
-    }
+  DefMacroDirective *getNextPublicSubmoduleMacro(DefMacroDirective *MD,
+                                                 SubmoduleID &ModID) {
+    if (DefMacroDirective *
+          DefMD = getPublicSubmoduleMacro(MD->getPrevious(), 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;
+  /// \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 @@ public:
         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 @@ public:
       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);
         }

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=178037&r1=178036&r2=178037&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Mar 26 12:17:01 2013
@@ -6305,10 +6305,12 @@ MacroInfo *cxindex::getMacroInfo(const I
   ASTUnit *Unit = cxtu::getASTUnit(TU);
   Preprocessor &PP = Unit->getPreprocessor();
   MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
-  while (MD) {
-    if (MacroDefLoc == MD->getInfo()->getDefinitionLoc())
-      return MD->getInfo();
-    MD = MD->getPrevious();
+  if (MD) {
+    for (MacroDirective::DefInfo
+           Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
+      if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
+        return Def.getMacroInfo();
+    }
   }
 
   return 0;
@@ -6364,7 +6366,7 @@ MacroDefinition *cxindex::checkForMacroI
   if (!InnerMD)
     return 0;
 
-  return PPRec->findMacroDefinition(InnerMD->getInfo());
+  return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
 }
 
 MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,





More information about the cfe-commits mailing list