Address more of Richard's comments.

Hi rsmith, doug.gregor, klimek,

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

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D2024?vs=5172&id=5290#toc

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
@@ -264,19 +264,27 @@
 .. parsed-literal::
 
   *module-id*:
-    *identifier* ('.' *identifier*)*
+    *module-name* ('.' *module-name*)*
+
+A module name can either be an identifier or a string literal. The quotes of the string literal do not become part of the module name. Thus, ``modulea`` and ``"modulea"`` are equivalent names.
+
+.. parsed-literal::
+
+  *module-name*:
+    *identifier*
+    *string-literal*
 
 Module declaration
 ------------------
 A module declaration describes a module, including the headers that contribute to that module, its submodules, and other aspects of the module.
 
 .. parsed-literal::
 
   *module-declaration*:
-    ``explicit``:sub:`opt` ``framework``:sub:`opt` ``module`` *module-id* *attributes*:sub:`opt` '{' *module-member** '}'
-    ``extern`` ``module`` *module-id* *string-literal*
+    ``explicit``:sub:`opt` ``framework``:sub:`opt` ``module`` *module-name* *attributes*:sub:`opt` '{' *module-member** '}'
+    ``extern`` ``module`` *module-name* *string-literal*
 
-The *module-id* should consist of only a single *identifier*, which provides the name of the module being defined. Each module shall have a single definition. 
+Each module shall have a single definition. 
 
 The ``explicit`` qualifier can only be applied to a submodule, i.e., a module that is nested within another module. The contents of explicit submodules are only made available when the submodule itself was explicitly named in an import declaration or was re-exported from an imported module.
 
@@ -499,9 +507,9 @@
     ``export`` *wildcard-module-id*
 
   *wildcard-module-id*:
-    *identifier*
+    *module-name*
     '*'
-    *identifier* '.' *wildcard-module-id*
+    *module-name* '.' *wildcard-module-id*
 
 The *export-declaration* names a module or a set of modules that will be re-exported to any translation unit that imports the enclosing module. Each imported module that matches the *wildcard-module-id* up to, but not including, the first ``*`` will be re-exported.
 
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
@@ -1066,7 +1066,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 {
@@ -1687,25 +1687,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
@@ -735,9 +735,23 @@
 void Preprocessor::LexAfterModuleImport(Token &Result) {
   // Figure out what kind of lexer we actually have.
   recomputeCurLexerKind();
-  
-  // Lex the next token.
-  Lex(Result);
+
+  // Lex the next token and convert (implicitly concatenated) strings to a
+  // single identifier token.
+  SmallVector<Token, 1> StrToks;
+  while (LookAhead(0).is(tok::string_literal)) {
+    Lex(Result);
+    if (Result.hasUDSuffix())
+      Diag(Result, diag::err_invalid_string_udl);
+    StrToks.push_back(Result);
+  }
+  if (StrToks.empty()) {
+    Lex(Result);
+  } else {
+    StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this);
+    Result.setIdentifierInfo(&Identifiers.get(Literal.GetString()));
+    Result.setKind(tok::identifier);
+  }
 
   // The token sequence 
   //
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 {{module XG does not depend on a module exporting 'f.h'}}
 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,12 @@
+// 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";
+@import "my/"
+        "module-a"."Sub";
+@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