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