]> granicus.if.org Git - clang/commitdiff
[modules] Make sure macros get made visible in the top-level file if we've got
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 30 Jun 2015 21:29:55 +0000 (21:29 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 30 Jun 2015 21:29:55 +0000 (21:29 +0000)
local submodule visibility enabled; that top-level file might not actually be
the module includes buffer if use of prebuilt modules is disabled.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@241120 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/Preprocessor.h
lib/Lex/PPLexerChange.cpp
test/Modules/Inputs/submodule-visibility/a.h
test/Modules/Inputs/submodule-visibility/b.h
test/Modules/submodule-visibility.cpp

index f02364a385ea7f4b847a89d9a4dd3bafd6b2f626..bba0c38cec777420ca21f31f00d96c0bc12ef30b 100644 (file)
@@ -394,7 +394,9 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
                                    const IdentifierInfo *II) const {
       // FIXME: Find a spare bit on IdentifierInfo and store a
       //        HasModuleMacros flag.
-      if (!II->hasMacroDefinition() || !PP.getLangOpts().Modules ||
+      if (!II->hasMacroDefinition() ||
+          (!PP.getLangOpts().Modules &&
+           !PP.getLangOpts().ModulesLocalVisibility) ||
           !PP.CurSubmoduleState->VisibleModules.getGeneration())
         return nullptr;
 
index 1a35d32dedb5d383440aeb706e7cd3bd850a42a9..c231e18eecc3ec63bc2f6f6d53720a44b5065cad 100644 (file)
@@ -644,11 +644,20 @@ void Preprocessor::EnterSubmodule(Module *M, SourceLocation ImportLoc) {
   if (FirstTime) {
     // Determine the set of starting macros for this submodule; take these
     // from the "null" module (the predefines buffer).
+    //
+    // FIXME: If we have local visibility but not modules enabled, the
+    // NullSubmoduleState is polluted by #defines in the top-level source
+    // file.
     auto &StartingMacros = NullSubmoduleState.Macros;
 
     // Restore to the starting state.
     // FIXME: Do this lazily, when each macro name is first referenced.
     for (auto &Macro : StartingMacros) {
+      // Skip uninteresting macros.
+      if (!Macro.second.getLatest() &&
+          Macro.second.getOverriddenMacros().empty())
+        continue;
+
       MacroState MS(Macro.second.getLatest());
       MS.setOverriddenMacros(*this, Macro.second.getOverriddenMacros());
       State.Macros.insert(std::make_pair(Macro.first, std::move(MS)));
@@ -732,6 +741,11 @@ void Preprocessor::LeaveSubmodule() {
     }
   }
 
+  // FIXME: Before we leave this submodule, we should parse all the other
+  // headers within it. Otherwise, we're left with an inconsistent state
+  // where we've made the module visible but don't yet have its complete
+  // contents.
+
   // Put back the outer module's state, if we're tracking it.
   if (getLangOpts().ModulesLocalVisibility)
     CurSubmoduleState = Info.OuterSubmoduleState;
@@ -739,6 +753,5 @@ void Preprocessor::LeaveSubmodule() {
   BuildingSubmoduleStack.pop_back();
 
   // A nested #include makes the included submodule visible.
-  if (!BuildingSubmoduleStack.empty() || !getLangOpts().ModulesLocalVisibility)
-    makeModuleVisible(LeavingMod, ImportLoc);
+  makeModuleVisible(LeavingMod, ImportLoc);
 }
index d8805c92f24d9461a93c9a318ab62da581e3988c..34ac6b2b2eabdecf4060157377eac4ec2dc2147f 100644 (file)
@@ -1 +1,7 @@
 int n;
+
+#ifdef B
+#error B is defined
+#endif
+
+#define A
index fa419c0c5c481065731c54c84822a080b4012be5..dae75bf3315b57ea7a449a23745f59548c79c15f 100644 (file)
@@ -1 +1,7 @@
 int m = n;
+
+#if defined(A) && !defined(ALLOW_NAME_LEAKAGE)
+#error A is defined
+#endif
+
+#define B
index 084f811f231f4e5c27ef2ebf81727ee52ca81b38..b2c5fc7ba198e4757df89ced84248fb9a3b1767f 100644 (file)
 #endif
 
 int k = n + m; // OK, a and b are visible here.
+
+#ifndef A
+#error A is not defined
+#endif
+
+#ifndef B
+#error B is not defined
+#endif