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