Hi rsmith, doug.gregor, klimek,

In order to make the migration to modules easier, it seems to be helpful to 
allow a 1:1 mapping between target names of a current build system and the 
corresponding C++ modules. As  such targets commonly contain characters like 
"-". ":" and "/", allowing arbitrary quote-escaped strings seems to be a 
straightforward option.

Also improve the error message on missing use-declarations.

http://llvm-reviews.chandlerc.com/D2024

Files:
  docs/Modules.rst
  include/clang/Basic/DiagnosticLexKinds.td
  lib/Lex/ModuleMap.cpp
  lib/Lex/PPDirectives.cpp
  lib/Lex/Preprocessor.cpp
  test/Modules/Inputs/declare-use/h.h
  test/Modules/Inputs/string_names/a.h
  test/Modules/Inputs/string_names/b.h
  test/Modules/Inputs/string_names/c.h
  test/Modules/Inputs/string_names/module.map
  test/Modules/Inputs/string_names/sub.h
  test/Modules/declare-use1.cpp
  test/Modules/declare-use2.cpp
  test/Modules/string_names.cpp
  test/Modules/string_names.m
Index: docs/Modules.rst
===================================================================
--- docs/Modules.rst
+++ docs/Modules.rst
@@ -240,7 +240,7 @@
 
 Lexical structure
 -----------------
-Module map files use a simplified form of the C99 lexer, with the same rules for identifiers, tokens, string literals, ``/* */`` and ``//`` comments. The module map language has the following reserved words; all other C identifiers are valid identifiers.
+Module map files use a simplified form of the C99 lexer, with the same rules for identifiers, tokens, string literals, ``/* */`` and ``//`` comments. The module map language has the following reserved words; all other C identifiers are valid identifiers. Additionally, string literals can also be used to specify module names.
 
 .. parsed-literal::
 
Index: include/clang/Basic/DiagnosticLexKinds.td
===================================================================
--- include/clang/Basic/DiagnosticLexKinds.td
+++ include/clang/Basic/DiagnosticLexKinds.td
@@ -614,7 +614,7 @@
 def error_use_of_private_header_outside_module : Error<
   "use of private header from outside its module: '%0'">;
 def error_undeclared_use_of_module : Error<
-  "use of a module not declared used: '%0'">;
+  "module %0 does not depend on a module exporting: '%1'">;
 
 def warn_header_guard : Warning<
   "%0 is used as a header guard here, followed by #define of a different macro">,
Index: lib/Lex/ModuleMap.cpp
===================================================================
--- lib/Lex/ModuleMap.cpp
+++ lib/Lex/ModuleMap.cpp
@@ -1061,7 +1061,7 @@
 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
   Id.clear();
   do {
-    if (Tok.is(MMToken::Identifier)) {
+    if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
       consumeToken();
     } else {
@@ -1672,25 +1672,7 @@
   consumeToken();
   // Parse the module-id.
   ModuleId ParsedModuleId;
-
-  do {
-    if (Tok.is(MMToken::Identifier)) {
-      ParsedModuleId.push_back(
-          std::make_pair(Tok.getString(), Tok.getLocation()));
-      consumeToken();
-
-      if (Tok.is(MMToken::Period)) {
-        consumeToken();
-        continue;
-      }
-
-      break;
-    }
-
-    Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
-    HadError = true;
-    return;
-  } while (true);
+  parseModuleId(ParsedModuleId);
 
   ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
 }
Index: lib/Lex/PPDirectives.cpp
===================================================================
--- lib/Lex/PPDirectives.cpp
+++ lib/Lex/PPDirectives.cpp
@@ -611,7 +611,7 @@
   if (RequestingModule && getLangOpts().ModulesDeclUse &&
       violatesUseDeclarations(RequestingModule, RequestedModule.getModule()))
     Diag(FilenameLoc, diag::error_undeclared_use_of_module)
-        << Filename;
+        << RequestingModule->getFullModuleName() << Filename;
 }
 
 const FileEntry *Preprocessor::LookupFile(
Index: lib/Lex/Preprocessor.cpp
===================================================================
--- lib/Lex/Preprocessor.cpp
+++ lib/Lex/Preprocessor.cpp
@@ -745,11 +745,21 @@
   //
   // indicates a module import directive. We already saw the 'import' 
   // contextual 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.
+  if (ModuleImportExpectsIdentifier &&
+      (Result.is(tok::identifier) || Result.is(tok::string_literal))) {
+    if (Result.is(tok::string_literal)) {
+      // String literals are valid module identifiers. Set token kind and
+      // identifier information appropriately.
+      StringRef WithoutQuotes(Result.getLiteralData(), Result.getLength());
+      WithoutQuotes = WithoutQuotes.substr(1, WithoutQuotes.size() - 2);
+      Result.setIdentifierInfo(&Identifiers.get(WithoutQuotes));
+      Result.setKind(tok::identifier);
+    }
     ModuleImportPath.push_back(std::make_pair(Result.getIdentifierInfo(),
                                               Result.getLocation()));
+
+    // We expected to see an identifier here, and we did; continue handling
+    // identifiers.
     ModuleImportExpectsIdentifier = false;
     CurLexerKind = CLK_LexAfterModuleImport;
     return;
Index: test/Modules/Inputs/declare-use/h.h
===================================================================
--- test/Modules/Inputs/declare-use/h.h
+++ test/Modules/Inputs/declare-use/h.h
@@ -1,7 +1,7 @@
 #ifndef H_H
 #define H_H
 #include "c.h"
-#include "d.h" // expected-error {{use of a module not declared used}}
+#include "d.h" // expected-error {{does not depend on a module exporting:}}
 #include "h1.h"
 const int h1 = aux_h*c*7*d;
 #endif
Index: test/Modules/Inputs/string_names/a.h
===================================================================
--- /dev/null
+++ test/Modules/Inputs/string_names/a.h
@@ -0,0 +1,4 @@
+#ifndef A_H
+#define A_H
+const int a = 2;
+#endif
Index: test/Modules/Inputs/string_names/b.h
===================================================================
--- /dev/null
+++ test/Modules/Inputs/string_names/b.h
@@ -0,0 +1,4 @@
+#ifndef B_H
+#define B_H
+const int b = 3;
+#endif
Index: test/Modules/Inputs/string_names/c.h
===================================================================
--- /dev/null
+++ test/Modules/Inputs/string_names/c.h
@@ -0,0 +1,4 @@
+#ifndef C_H
+#define C_H
+const int c = 2;
+#endif
Index: test/Modules/Inputs/string_names/module.map
===================================================================
--- /dev/null
+++ test/Modules/Inputs/string_names/module.map
@@ -0,0 +1,16 @@
+module "my/module-a" {
+  header "a.h"
+  use "my/module-c"
+
+  module "Sub" {
+    header "sub.h"
+  }
+}
+
+module "my/module-b" {
+  header "b.h"
+}
+
+module "my/module-c" {
+  header "c.h"
+}
Index: test/Modules/Inputs/string_names/sub.h
===================================================================
--- /dev/null
+++ test/Modules/Inputs/string_names/sub.h
@@ -0,0 +1,4 @@
+#ifndef SUB_H
+#define SUB_H
+const int sub = 2;
+#endif
Index: test/Modules/declare-use1.cpp
===================================================================
--- test/Modules/declare-use1.cpp
+++ test/Modules/declare-use1.cpp
@@ -3,5 +3,5 @@
 
 #include "g.h"
 #include "e.h"
-#include "f.h" // expected-error {{use of a module not declared used}}
+#include "f.h" // expected-error {{does not depend on a module exporting:}}
 const int g2 = g1+e+f;
Index: test/Modules/declare-use2.cpp
===================================================================
--- test/Modules/declare-use2.cpp
+++ test/Modules/declare-use2.cpp
@@ -3,5 +3,5 @@
 
 #include "h.h"
 #include "e.h"
-#include "f.h" // expected-error {{use of a module not declared used}}
+#include "f.h" // expected-error {{does not depend on a module exporting:}}
 const int h2 = h1+e+f;
Index: test/Modules/string_names.cpp
===================================================================
--- /dev/null
+++ test/Modules/string_names.cpp
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fmodules-decluse -I %S/Inputs/string_names %s -fmodule-name="my/module-a" -verify
+
+#include "a.h"
+#include "b.h" // expected-error {{does not depend on a module exporting:}}
+#include "c.h"
Index: test/Modules/string_names.m
===================================================================
--- /dev/null
+++ test/Modules/string_names.m
@@ -0,0 +1,11 @@
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -Wauto-import -fmodules-cache-path=%t -fmodules -I %S/Inputs/string_names %s -verify
+// expected-no-diagnostics
+
+@import "my/module-a"."Sub";
+
+int getValue() {
+  return sub;
+}
+
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to