/// \brief Information about a submodule that we're currently building.
struct BuildingSubmoduleInfo {
- BuildingSubmoduleInfo(Module *M) : M(M) {}
+ BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc)
+ : M(M), ImportLoc(ImportLoc) {}
- // The module that we are building.
+ /// The module that we are building.
Module *M;
- // The macros that were visible before we entered the module.
+ /// The location at which the module was included.
+ SourceLocation ImportLoc;
+ /// The macros that were visible before we entered the module.
MacroMap Macros;
// FIXME: VisibleModules?
};
SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
- void EnterSubmodule(Module *M);
+ void EnterSubmodule(Module *M, SourceLocation ImportLoc);
void LeaveSubmodule();
/// The set of known macros exported from modules.
/// \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,
- ModuleMacro *MM = nullptr) {
- DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc, MM);
+ SourceLocation Loc) {
+ DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc);
appendMacroDirective(II, MD);
return MD;
}
MacroInfo *AllocateMacroInfo();
DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI,
- SourceLocation Loc,
- ModuleMacro *MM = nullptr);
- UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc,
- ModuleMacro *MM = nullptr);
+ SourceLocation Loc);
+ UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc);
VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc,
bool isPublic);
+ MacroDirective *AllocateImportedMacroDirective(ModuleMacro *MM,
+ SourceLocation Loc);
+
/// \brief Lex and validate a macro name, which occurs after a
/// \#define or \#undef.
///
return MI;
}
-DefMacroDirective *
-Preprocessor::AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc,
- ModuleMacro *MM) {
- if (MM) return DefMacroDirective::createImported(*this, MI, Loc, MM);
+DefMacroDirective *Preprocessor::AllocateDefMacroDirective(MacroInfo *MI,
+ SourceLocation Loc) {
return new (BP) DefMacroDirective(MI, Loc);
}
UndefMacroDirective *
-Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc,
- ModuleMacro *MM) {
- if (MM) return UndefMacroDirective::createImported(*this, UndefLoc, MM);
+Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc) {
return new (BP) UndefMacroDirective(UndefLoc);
}
return new (BP) VisibilityMacroDirective(Loc, isPublic);
}
+MacroDirective *
+Preprocessor::AllocateImportedMacroDirective(ModuleMacro *MM,
+ SourceLocation Loc) {
+ if (auto *MI = MM->getMacroInfo())
+ return DefMacroDirective::createImported(*this, MI, Loc, MM);
+ else
+ return UndefMacroDirective::createImported(*this, Loc, MM);
+}
+
/// \brief Read and discard all tokens remaining on the current line until
/// the tok::eod token is found.
void Preprocessor::DiscardUntilEndOfDirective() {
assert(!CurSubmodule && "should not have marked this as a module yet");
CurSubmodule = BuildingModule.getModule();
- EnterSubmodule(CurSubmodule);
+ EnterSubmodule(CurSubmodule, HashLoc);
EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_begin,
CurSubmodule);
assert(!FoundLexer && "Lexer should return EOD before EOF in PP mode");
}
-void Preprocessor::EnterSubmodule(Module *M) {
+void Preprocessor::EnterSubmodule(Module *M, SourceLocation ImportLoc) {
// Save the current state for future imports.
- BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo(M));
+ BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo(M, ImportLoc));
auto &Info = BuildingSubmoduleStack.back();
// Copy across our macros and start the submodule with the current state.
// This module may have exported a new macro. If so, create a ModuleMacro
// representing that fact.
bool ExplicitlyPublic = false;
+ ModuleMacro *MM = nullptr;
for (auto *MD = Macro.second.getLatest(); MD != State.getLatest();
MD = MD->getPrevious()) {
// Skip macros defined in other submodules we #included along the way.
// FIXME: Issue a warning if multiple headers for the same submodule
// define a macro, rather than silently ignoring all but the first.
bool IsNew;
- addModuleMacro(Info.M, II, Def, Macro.second.getOverriddenMacros(),
- IsNew);
+ MM = addModuleMacro(Info.M, II, Def, Macro.second.getOverriddenMacros(),
+ IsNew);
break;
}
}
// Restore the old macro state.
Macro.second = State;
+
+ // If our submodule defined a macro, import it.
+ // FIXME: Do this lazily.
+ if (MM)
+ appendMacroDirective(II,
+ AllocateImportedMacroDirective(MM, Info.ImportLoc));
}
BuildingSubmoduleStack.pop_back();
}
MacroDirective *import(Preprocessor &PP, SourceLocation ImportLoc) const {
- if (auto *MI = MM->getMacroInfo())
- return PP.AllocateDefMacroDirective(MI, ImportLoc, MM);
- return PP.AllocateUndefMacroDirective(ImportLoc, MM);
+ return PP.AllocateImportedMacroDirective(MM, ImportLoc);
}
};
ModuleMacro *MM = nullptr;
if (SubmoduleID ImportedFrom = getGlobalSubmoduleID(M, Record[Idx++]))
MM = PP.getModuleMacro(getSubmodule(ImportedFrom), II);
- DefMacroDirective *DefMD = PP.AllocateDefMacroDirective(MI, Loc, MM);
- DefMD->setAmbiguous(IsAmbiguous);
- MD = DefMD;
+ MD = MM ? PP.AllocateImportedMacroDirective(MM, Loc)
+ : PP.AllocateDefMacroDirective(MI, Loc);
+ cast<DefMacroDirective>(MD)->setAmbiguous(IsAmbiguous);
break;
}
case MacroDirective::MD_Undefine: {
ModuleMacro *MM = nullptr;
if (SubmoduleID ImportedFrom = getGlobalSubmoduleID(M, Record[Idx++]))
MM = PP.getModuleMacro(getSubmodule(ImportedFrom), II);
- MD = PP.AllocateUndefMacroDirective(Loc, MM);
+ MD = MM ? PP.AllocateImportedMacroDirective(MM, Loc)
+ : PP.AllocateUndefMacroDirective(Loc);
break;
}
case MacroDirective::MD_Visibility: