<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Nov 29, 2011, at 10:40 PM, Chandler Carruth wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Test case?<br></blockquote><div><br></div>r145490.</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>- Doug</div><div><br><blockquote type="cite"><div class="gmail_quote">On Tue, Nov 29, 2011 at 8:26 PM, Douglas Gregor <span dir="ltr"><<a href="mailto:dgregor@apple.com">dgregor@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Author: dgregor<br>
Date: Tue Nov 29 22:26:53 2011<br>
New Revision: 145478<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=145478&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=145478&view=rev</a><br>
Log:<br>
Teach the preprocessor how to handle module import declarations that<br>
involve submodules (e.g., importing std.vector), rather than always<br>
importing the top-level module.<br>
<br>
<br>
Modified:<br>
cfe/trunk/include/clang/Frontend/CompilerInstance.h<br>
cfe/trunk/include/clang/Lex/Preprocessor.h<br>
cfe/trunk/lib/Frontend/CompilerInstance.cpp<br>
cfe/trunk/lib/Lex/Preprocessor.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=145478&r1=145477&r2=145478&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=145478&r1=145477&r2=145478&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original)<br>
+++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Tue Nov 29 22:26:53 2011<br>
@@ -109,6 +109,14 @@<br>
/// along with the module map<br>
llvm::DenseMap<const IdentifierInfo *, KnownModule> KnownModules;<br>
<br>
+ /// \brief The location of the module-import keyword for the last module<br>
+ /// import.<br>
+ SourceLocation LastModuleImportLoc;<br>
+<br>
+ /// \brief The result of the last module import.<br>
+ ///<br>
+ KnownModule LastModuleImportResult;<br>
+<br>
/// \brief Holds information about the output file.<br>
///<br>
/// If TempFilename is not empty we must rename it to Filename at the end.<br>
<br>
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=145478&r1=145477&r2=145478&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=145478&r1=145477&r2=145478&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)<br>
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Tue Nov 29 22:26:53 2011<br>
@@ -167,6 +167,14 @@<br>
/// lexed, if any.<br>
SourceLocation ModuleImportLoc;<br>
<br>
+ /// \brief The module import path that we're currently processing.<br>
+ llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2><br>
+ ModuleImportPath;<br>
+<br>
+ /// \brief Whether the module import expectes an identifier next. Otherwise,<br>
+ /// it expects a '.' or ';'.<br>
+ bool ModuleImportExpectsIdentifier;<br>
+<br>
/// \brief The source location of the currently-active<br>
/// #pragma clang arc_cf_code_audited begin.<br>
SourceLocation PragmaARCCFCodeAuditedLoc;<br>
<br>
Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=145478&r1=145477&r2=145478&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=145478&r1=145477&r2=145478&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Tue Nov 29 22:26:53 2011<br>
@@ -1070,6 +1070,12 @@<br>
<br>
ModuleKey CompilerInstance::loadModule(SourceLocation ImportLoc,<br>
ModuleIdPath Path) {<br>
+ // If we've already handled this import, just return the cached result.<br>
+ // This one-element cache is important to eliminate redundant diagnostics<br>
+ // when both the preprocessor and parser see the same import declaration.<br>
+ if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc)<br>
+ return LastModuleImportResult.getOpaqueValue();<br>
+<br>
// Determine what file we're searching from.<br>
SourceManager &SourceMgr = getSourceManager();<br>
SourceLocation ExpandedImportLoc = SourceMgr.getExpansionLoc(ImportLoc);<br>
@@ -1241,6 +1247,8 @@<br>
// FIXME: The module file's FileEntry makes a poor key indeed! Once we<br>
// eliminate the need for FileEntry here, the module itself will become the<br>
// key (which does make sense).<br>
+ LastModuleImportLoc = ImportLoc;<br>
+ LastModuleImportResult = Known;<br>
return Known.getOpaqueValue();<br>
}<br>
<br>
<br>
Modified: cfe/trunk/lib/Lex/Preprocessor.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=145478&r1=145477&r2=145478&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Preprocessor.cpp?rev=145478&r1=145477&r2=145478&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Lex/Preprocessor.cpp (original)<br>
+++ cfe/trunk/lib/Lex/Preprocessor.cpp Tue Nov 29 22:26:53 2011<br>
@@ -546,6 +546,8 @@<br>
if (II.getTokenID() == tok::kw___import_module__ &&<br>
!InMacroArgs && !DisableMacroExpansion) {<br>
ModuleImportLoc = Identifier.getLocation();<br>
+ ModuleImportPath.clear();<br>
+ ModuleImportExpectsIdentifier = true;<br>
CurLexerKind = CLK_LexAfterModuleImport;<br>
}<br>
}<br>
@@ -567,19 +569,31 @@<br>
<br>
// The token sequence<br>
//<br>
- // __import_module__ identifier<br>
+ // __import_module__ identifier (. identifier)*<br>
//<br>
// indicates a module import directive. We already saw the __import_module__<br>
- // keyword, so now we're looking for the identifier.<br>
- if (Result.getKind() != tok::identifier)<br>
+ // keyword, so now we're looking for the identifiers.<br>
+ if (ModuleImportExpectsIdentifier && Result.getKind() == tok::identifier) {<br>
+ // We expected to see an identifier here, and we did; continue handling<br>
+ // identifiers.<br>
+ ModuleImportPath.push_back(std::make_pair(Result.getIdentifierInfo(),<br>
+ Result.getLocation()));<br>
+ ModuleImportExpectsIdentifier = false;<br>
+ CurLexerKind = CLK_LexAfterModuleImport;<br>
return;<br>
+ }<br>
<br>
- // Load the module.<br>
- llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;<br>
- Path.push_back(std::make_pair(Result.getIdentifierInfo(),<br>
- Result.getLocation()));<br>
-<br>
- (void)TheModuleLoader.loadModule(ModuleImportLoc, Path);<br>
+ // If we're expecting a '.' or a ';', and we got a '.', then wait until we<br>
+ // see the next identifier.<br>
+ if (!ModuleImportExpectsIdentifier && Result.getKind() == tok::period) {<br>
+ ModuleImportExpectsIdentifier = true;<br>
+ CurLexerKind = CLK_LexAfterModuleImport;<br>
+ return;<br>
+ }<br>
+<br>
+ // If we have a non-empty module path, load the named module.<br>
+ if (!ModuleImportPath.empty())<br>
+ (void)TheModuleLoader.loadModule(ModuleImportLoc, ModuleImportPath);<br>
}<br>
<br>
void Preprocessor::AddCommentHandler(CommentHandler *Handler) {<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br>
</blockquote></div><br></body></html>