[cfe-commits] r165773 - in /cfe/trunk: include/clang/Serialization/ASTReader.h lib/Lex/PPMacroExpansion.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/Modules/Inputs/macros_left.h test/Modules/Inputs/macros_right.h test/Modules/Inputs/macros_right_undef.h test/Modules/Inputs/macros_top.h test/Modules/Inputs/module.map test/Modules/macros.c

Douglas Gregor dgregor at apple.com
Thu Oct 11 17:16:50 PDT 2012


Author: dgregor
Date: Thu Oct 11 19:16:50 2012
New Revision: 165773

URL: http://llvm.org/viewvc/llvm-project?rev=165773&view=rev
Log:
Track which particular submodule #undef's a macro, so that the actual
#undef only occurs if that submodule is imported.

Added:
    cfe/trunk/test/Modules/Inputs/macros_right_undef.h
Modified:
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/Modules/Inputs/macros_left.h
    cfe/trunk/test/Modules/Inputs/macros_right.h
    cfe/trunk/test/Modules/Inputs/macros_top.h
    cfe/trunk/test/Modules/Inputs/module.map
    cfe/trunk/test/Modules/macros.c

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=165773&r1=165772&r2=165773&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Thu Oct 11 19:16:50 2012
@@ -395,7 +395,10 @@
   /// global macro ID to produce a local ID.
   GlobalMacroMapType GlobalMacroMap;
 
-  typedef llvm::DenseMap<serialization::MacroID, MacroUpdate> MacroUpdatesMap;
+  typedef llvm::DenseMap<serialization::MacroID,
+            llvm::SmallVector<std::pair<serialization::SubmoduleID,
+                                        MacroUpdate>, 1> >
+    MacroUpdatesMap;
 
   /// \brief Mapping from (global) macro IDs to the set of updates to be
   /// performed to the corresponding macro.
@@ -417,30 +420,50 @@
 
   /// \brief An entity that has been hidden.
   class HiddenName {
-    /// \brief The hidden declaration or macro.
-    llvm::PointerUnion<Decl *, MacroInfo *> DeclOrMacro;
+  public:
+    enum NameKind {
+      Declaration,
+      MacroVisibility,
+      MacroUndef
+    } Kind;
+
+  private:
+    unsigned Loc;
+
+    union {
+      Decl *D;
+      MacroInfo *MI;
+    };
 
-    /// \brief The name being defined to a macro, for the macro case.
-    IdentifierInfo *Identifier;
+    IdentifierInfo *Id;
 
   public:
-    HiddenName(Decl *D) : DeclOrMacro(D), Identifier() { }
+    HiddenName(Decl *D) : Kind(Declaration), Loc(), D(D), Id() { }
+
     HiddenName(IdentifierInfo *II, MacroInfo *MI)
-      : DeclOrMacro(MI), Identifier(II) { }
+      : Kind(MacroVisibility), Loc(), MI(MI), Id(II) { }
 
-    bool isDecl() const { return DeclOrMacro.is<Decl*>(); }
-    bool isMacro() const { return !isDecl(); }
+    HiddenName(IdentifierInfo *II, MacroInfo *MI, SourceLocation Loc)
+      : Kind(MacroUndef), Loc(Loc.getRawEncoding()), MI(MI), Id(II) { }
+
+    NameKind getKind() const { return Kind; }
 
     Decl *getDecl() const {
-      assert(isDecl() && "Hidden name is not a declaration");
-      return DeclOrMacro.get<Decl *>();
+      assert(getKind() == Declaration && "Hidden name is not a declaration");
+      return D;
     }
 
     std::pair<IdentifierInfo *, MacroInfo *> getMacro() const {
-      assert(isMacro() && "Hidden name is not a macro!");
-      return std::make_pair(Identifier, DeclOrMacro.get<MacroInfo *>());
+      assert((getKind() == MacroUndef || getKind() == MacroVisibility)
+             && "Hidden name is not a macro!");
+      return std::make_pair(Id, MI);
     }
-  };
+
+    SourceLocation getMacroUndefLoc() const {
+      assert(getKind() == MacroUndef && "Hidden name is not an undef!");
+      return SourceLocation::getFromRawEncoding(Loc);
+    }
+};
 
   /// \brief A set of hidden declarations.
   typedef llvm::SmallVector<HiddenName, 2>

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=165773&r1=165772&r2=165773&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Thu Oct 11 19:16:50 2012
@@ -87,11 +87,13 @@
     }
 
     // Find the end of the definition chain.
-    MacroInfo *Prev = StoredMI;
-    MacroInfo *PrevPrev;
+    MacroInfo *Prev;
+    MacroInfo *PrevPrev = StoredMI;
     bool Ambiguous = StoredMI->isAmbiguous();
     bool MatchedOther = false;
     do {
+      Prev = PrevPrev;
+
       // If the macros are not identical, we have an ambiguity.
       if (!Prev->isIdenticalTo(*MI, *this)) {
         if (!Ambiguous) {
@@ -125,25 +127,29 @@
 void Preprocessor::makeLoadedMacroInfoVisible(IdentifierInfo *II,
                                               MacroInfo *MI) {
   assert(MI->isFromAST() && "Macro must be from the AST");
-  assert(MI->isDefined() && "Macro is not visible");
 
   MacroInfo *&StoredMI = Macros[II];
   if (StoredMI == MI) {
     // Easy case: this is the first macro anyway.
-    II->setHasMacroDefinition(true);
+    II->setHasMacroDefinition(MI->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 would be
-  // quadratic.
+  // FIXME: Yes, this is O(N), and making a pile of macros visible or hidden
+  // would be quadratic, but it's extremely rare.
   MacroInfo *Prev = StoredMI;
   while (Prev->getPreviousDefinition() != MI)
     Prev = Prev->getPreviousDefinition();
   Prev->setPreviousDefinition(MI->getPreviousDefinition());
+  MI->setPreviousDefinition(0);
 
   // Add the macro back to the list.
   addLoadedMacroInfo(II, MI);
+
+  II->setHasMacroDefinition(StoredMI->isDefined());
+  if (II->isFromAST())
+    II->setChangedSinceDeserialization();
 }
 
 /// \brief Undefine a macro for this identifier.

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=165773&r1=165772&r2=165773&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Oct 11 19:16:50 2012
@@ -1364,9 +1364,28 @@
       MacroUpdatesMap::iterator Update = MacroUpdates.find(GlobalID);
       if (Update != MacroUpdates.end()) {
         if (MI->getUndefLoc().isInvalid()) {
-          MI->setUndefLoc(Update->second.UndefLoc);
-          if (PPMutationListener *Listener = PP.getPPMutationListener())
-            Listener->UndefinedMacro(MI);
+          for (unsigned I = 0, N = Update->second.size(); I != N; ++I) {
+            bool Hidden = false;
+            if (unsigned SubmoduleID = Update->second[I].first) {
+              if (Module *Owner = getSubmodule(SubmoduleID)) {
+                if (Owner->NameVisibility == Module::Hidden) {
+                  // Note that this #undef is hidden.
+                  Hidden = true;
+
+                  // Record this hiding for later.
+                  HiddenNamesMap[Owner].push_back(
+                    HiddenName(II, MI, Update->second[I].second.UndefLoc));
+                }
+              }
+            }
+
+            if (!Hidden) {
+              MI->setUndefLoc(Update->second[I].second.UndefLoc);
+              if (PPMutationListener *Listener = PP.getPPMutationListener())
+                Listener->UndefinedMacro(MI);
+              break;
+            }
+          }
         }
         MacroUpdates.erase(Update);
       }
@@ -2517,7 +2536,11 @@
         if (I == N)
           break;
 
-        MacroUpdates[ID].UndefLoc = ReadSourceLocation(F, Record, I);
+        SourceLocation UndefLoc = ReadSourceLocation(F, Record, I);
+        SubmoduleID SubmoduleID = getGlobalSubmoduleID(F, Record[I++]);;
+        MacroUpdate Update;
+        Update.UndefLoc = UndefLoc;
+        MacroUpdates[ID].push_back(std::make_pair(SubmoduleID, Update));
       }
       break;
     }
@@ -2619,15 +2642,30 @@
 
 void ASTReader::makeNamesVisible(const HiddenNames &Names) {
   for (unsigned I = 0, N = Names.size(); I != N; ++I) {
-    if (Names[I].isDecl()) {
+    switch (Names[I].getKind()) {
+    case HiddenName::Declaration:
       Names[I].getDecl()->Hidden = false;
-      continue;
+      break;
+
+    case HiddenName::MacroVisibility: {
+      std::pair<IdentifierInfo *, MacroInfo *> Macro = Names[I].getMacro();
+      Macro.second->setHidden(!Macro.second->isPublic());
+      if (Macro.second->isDefined()) {
+        PP.makeLoadedMacroInfoVisible(Macro.first, Macro.second);
+      }
+      break;
     }
 
-    std::pair<IdentifierInfo *, MacroInfo *> Macro = Names[I].getMacro();
-    Macro.second->setHidden(!Macro.second->isPublic());
-    if (Macro.second->isDefined()) {
-      PP.makeLoadedMacroInfoVisible(Macro.first, Macro.second);
+    case HiddenName::MacroUndef: {
+      std::pair<IdentifierInfo *, MacroInfo *> 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);
+      }
+      break;
+    }
     }
   }
 }

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=165773&r1=165772&r2=165773&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu Oct 11 19:16:50 2012
@@ -3686,6 +3686,7 @@
        I != E; ++I) {
     addMacroRef(I->first, Record);
     AddSourceLocation(I->second.UndefLoc, Record);
+    Record.push_back(inferSubmoduleIDFromLocation(I->second.UndefLoc));
   }
   Stream.EmitRecord(MACRO_UPDATES, Record);
 }

Modified: cfe/trunk/test/Modules/Inputs/macros_left.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/macros_left.h?rev=165773&r1=165772&r2=165773&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/macros_left.h (original)
+++ cfe/trunk/test/Modules/Inputs/macros_left.h Thu Oct 11 19:16:50 2012
@@ -1,4 +1,4 @@
-#include "macros_top.h"
+ at __experimental_modules_import macros_top;
 #define LEFT unsigned long
 
 #undef TOP_LEFT_UNDEF

Modified: cfe/trunk/test/Modules/Inputs/macros_right.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/macros_right.h?rev=165773&r1=165772&r2=165773&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/macros_right.h (original)
+++ cfe/trunk/test/Modules/Inputs/macros_right.h Thu Oct 11 19:16:50 2012
@@ -1,4 +1,4 @@
-#include "macros_top.h"
+ at __experimental_modules_import macros_top;
 #define RIGHT unsigned short
 
 

Added: cfe/trunk/test/Modules/Inputs/macros_right_undef.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/macros_right_undef.h?rev=165773&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/macros_right_undef.h (added)
+++ cfe/trunk/test/Modules/Inputs/macros_right_undef.h Thu Oct 11 19:16:50 2012
@@ -0,0 +1 @@
+#undef TOP_RIGHT_UNDEF

Modified: cfe/trunk/test/Modules/Inputs/macros_top.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/macros_top.h?rev=165773&r1=165772&r2=165773&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/macros_top.h (original)
+++ cfe/trunk/test/Modules/Inputs/macros_top.h Thu Oct 11 19:16:50 2012
@@ -11,3 +11,6 @@
 
 
 #define TOP_RIGHT_REDEF int
+
+#define TOP_RIGHT_UNDEF int
+

Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=165773&r1=165772&r2=165773&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Thu Oct 11 19:16:50 2012
@@ -28,6 +28,9 @@
 module macros_right { 
   header "macros_right.h" 
   export *
+  explicit module undef {
+    header "macros_right_undef.h"
+  }
 }
 module macros { header "macros.h" }
 module category_top { header "category_top.h" }

Modified: cfe/trunk/test/Modules/macros.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/macros.c?rev=165773&r1=165772&r2=165773&view=diff
==============================================================================
--- cfe/trunk/test/Modules/macros.c (original)
+++ cfe/trunk/test/Modules/macros.c Thu Oct 11 19:16:50 2012
@@ -107,10 +107,6 @@
 #  error TOP should be visible
 #endif
 
-#ifndef TOP_LEFT_UNDEF
-#  error TOP_LEFT_UNDEF should be visible
-#endif
-
 void test2() {
   int i;
   float f;
@@ -129,3 +125,13 @@
   double d;
   LEFT_RIGHT_DIFFERENT *dp = &d; // okay
 }
+
+#ifndef TOP_RIGHT_UNDEF
+#  error TOP_RIGHT_UNDEF should still be defined
+#endif
+
+ at __experimental_modules_import macros_right.undef;
+
+#ifdef TOP_RIGHT_UNDEF
+# error TOP_RIGHT_UNDEF should not be defined
+#endif





More information about the cfe-commits mailing list