[modules] Make sure macros get made visible in the top-level file if we've got

local submodule visibility enabled; that top-level file might not actually be
the module includes buffer if use of prebuilt modules is disabled.

llvm-svn: 241120
This commit is contained in:
Richard Smith
2015-06-30 21:29:55 +00:00
parent b41e87c534
commit 4df6093ca3
5 changed files with 38 additions and 3 deletions

View 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;

View 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);
}

View File

@@ -1 +1,7 @@
int n;
#ifdef B
#error B is defined
#endif
#define A

View File

@@ -1 +1,7 @@
int m = n;
#if defined(A) && !defined(ALLOW_NAME_LEAKAGE)
#error A is defined
#endif
#define B

View File

@@ -20,3 +20,11 @@
#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