Test case?<br><br><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>