diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-11-30 04:26:53 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-11-30 04:26:53 +0000 |
commit | b514c792821a8f053027d88444e13bfaa8efef76 (patch) | |
tree | 123cd461e4098e78e066dcef4281686d30674fa5 /lib | |
parent | 49009ec701feb3009450e57e40c656e2ad7c1f41 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145478 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Frontend/CompilerInstance.cpp | 8 | ||||
-rw-r--r-- | lib/Lex/Preprocessor.cpp | 32 |
2 files changed, 31 insertions, 9 deletions
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index dfc98e8bfb..66b381e522 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -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(); } diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index aeba32f96a..b01113041e 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -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) { |