forked from OSchip/llvm-project
Teach the preprocessor how to handle module import declarations that
involve submodules (e.g., importing std.vector), rather than always importing the top-level module. llvm-svn: 145478
This commit is contained in:
parent
5196bc6b39
commit
1805b8a42f
|
@ -109,6 +109,14 @@ class CompilerInstance : public ModuleLoader {
|
|||
/// along with the module map
|
||||
llvm::DenseMap<const IdentifierInfo *, KnownModule> KnownModules;
|
||||
|
||||
/// \brief The location of the module-import keyword for the last module
|
||||
/// import.
|
||||
SourceLocation LastModuleImportLoc;
|
||||
|
||||
/// \brief The result of the last module import.
|
||||
///
|
||||
KnownModule LastModuleImportResult;
|
||||
|
||||
/// \brief Holds information about the output file.
|
||||
///
|
||||
/// If TempFilename is not empty we must rename it to Filename at the end.
|
||||
|
|
|
@ -167,6 +167,14 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
|
|||
/// lexed, if any.
|
||||
SourceLocation ModuleImportLoc;
|
||||
|
||||
/// \brief The module import path that we're currently processing.
|
||||
llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2>
|
||||
ModuleImportPath;
|
||||
|
||||
/// \brief Whether the module import expectes an identifier next. Otherwise,
|
||||
/// it expects a '.' or ';'.
|
||||
bool ModuleImportExpectsIdentifier;
|
||||
|
||||
/// \brief The source location of the currently-active
|
||||
/// #pragma clang arc_cf_code_audited begin.
|
||||
SourceLocation PragmaARCCFCodeAuditedLoc;
|
||||
|
|
|
@ -1070,6 +1070,12 @@ static void compileModule(CompilerInstance &ImportingInstance,
|
|||
|
||||
ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,
|
||||
ModuleIdPath Path) {
|
||||
// If we've already handled this import, just return the cached result.
|
||||
// This one-element cache is important to eliminate redundant diagnostics
|
||||
// when both the preprocessor and parser see the same import declaration.
|
||||
if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc)
|
||||
return LastModuleImportResult.getOpaqueValue();
|
||||
|
||||
// Determine what file we're searching from.
|
||||
SourceManager &SourceMgr = getSourceManager();
|
||||
SourceLocation ExpandedImportLoc = SourceMgr.getExpansionLoc(ImportLoc);
|
||||
|
@ -1241,6 +1247,8 @@ ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,
|
|||
// FIXME: The module file's FileEntry makes a poor key indeed! Once we
|
||||
// eliminate the need for FileEntry here, the module itself will become the
|
||||
// key (which does make sense).
|
||||
LastModuleImportLoc = ImportLoc;
|
||||
LastModuleImportResult = Known;
|
||||
return Known.getOpaqueValue();
|
||||
}
|
||||
|
||||
|
|
|
@ -546,6 +546,8 @@ void Preprocessor::HandleIdentifier(Token &Identifier) {
|
|||
if (II.getTokenID() == tok::kw___import_module__ &&
|
||||
!InMacroArgs && !DisableMacroExpansion) {
|
||||
ModuleImportLoc = Identifier.getLocation();
|
||||
ModuleImportPath.clear();
|
||||
ModuleImportExpectsIdentifier = true;
|
||||
CurLexerKind = CLK_LexAfterModuleImport;
|
||||
}
|
||||
}
|
||||
|
@ -567,19 +569,31 @@ void Preprocessor::LexAfterModuleImport(Token &Result) {
|
|||
|
||||
// The token sequence
|
||||
//
|
||||
// __import_module__ identifier
|
||||
// __import_module__ identifier (. identifier)*
|
||||
//
|
||||
// indicates a module import directive. We already saw the __import_module__
|
||||
// keyword, so now we're looking for the identifier.
|
||||
if (Result.getKind() != tok::identifier)
|
||||
// keyword, so now we're looking for the identifiers.
|
||||
if (ModuleImportExpectsIdentifier && Result.getKind() == tok::identifier) {
|
||||
// We expected to see an identifier here, and we did; continue handling
|
||||
// identifiers.
|
||||
ModuleImportPath.push_back(std::make_pair(Result.getIdentifierInfo(),
|
||||
Result.getLocation()));
|
||||
ModuleImportExpectsIdentifier = false;
|
||||
CurLexerKind = CLK_LexAfterModuleImport;
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the module.
|
||||
llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
|
||||
Path.push_back(std::make_pair(Result.getIdentifierInfo(),
|
||||
Result.getLocation()));
|
||||
|
||||
(void)TheModuleLoader.loadModule(ModuleImportLoc, Path);
|
||||
// If we're expecting a '.' or a ';', and we got a '.', then wait until we
|
||||
// see the next identifier.
|
||||
if (!ModuleImportExpectsIdentifier && Result.getKind() == tok::period) {
|
||||
ModuleImportExpectsIdentifier = true;
|
||||
CurLexerKind = CLK_LexAfterModuleImport;
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have a non-empty module path, load the named module.
|
||||
if (!ModuleImportPath.empty())
|
||||
(void)TheModuleLoader.loadModule(ModuleImportLoc, ModuleImportPath);
|
||||
}
|
||||
|
||||
void Preprocessor::AddCommentHandler(CommentHandler *Handler) {
|
||||
|
|
Loading…
Reference in New Issue