Skip to content

Commit f0cee07

Browse files
committed
Use StringMap
More specific diag msgs Add tests
1 parent 7719a3d commit f0cee07

File tree

9 files changed

+85
-40
lines changed

9 files changed

+85
-40
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,14 @@ ERROR(error_stdlib_module_name,none,
150150
"module name \"%0\" is reserved for the standard library"
151151
"%select{|; use -module-name flag to specify an alternate name}1",
152152
(StringRef, bool))
153-
ERROR(error_bad_module_alias,none,
154-
"invalid module alias \"%0\" for an imported module; make sure the input format is correct (-module-alias alias=underlying_name), where the alias maps to an imported module, and the names do not contain special characters", (StringRef))
155153
ERROR(error_stdlib_not_found,Fatal,
156154
"unable to load standard library for target '%0'", (StringRef))
155+
ERROR(error_module_alias_invalid_format,none,
156+
"invalid module alias \"%0\"; make sure to use the format '-module-alias alias_name=underlying_name'", (StringRef))
157+
ERROR(error_module_alias_forbidden_name,none,
158+
"invalid module alias \"%0\"; make sure the alias differs from the module name, module ABI name, module link name, and a standard library name", (StringRef))
159+
ERROR(error_module_alias_duplicate,none,
160+
"duplicate module alias; the name \"%0\" is already used for a module alias or an underlying name", (StringRef))
157161

158162
ERROR(error_unable_to_load_supplementary_output_file_map, none,
159163
"unable to load supplementary output file map '%0': %1",

include/swift/Basic/LangOptions.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#include "llvm/Support/Regex.h"
3232
#include "llvm/Support/VersionTuple.h"
3333
#include "llvm/Support/raw_ostream.h"
34-
#include <map>
3534
#include <string>
3635
#include <vector>
3736

@@ -197,9 +196,6 @@ namespace swift {
197196
/// Enable features useful for running in the debugger.
198197
bool DebuggerSupport = false;
199198

200-
/// A map of aliases and underlying names of imported modules.
201-
std::map<StringRef, StringRef> ModuleAliasMap;
202-
203199
/// Enable the MemoryBufferSerializedModuleImporter.
204200
/// Only used by lldb-moduleimport-test.
205201
bool EnableMemoryBufferImporter = false;

include/swift/Frontend/Frontend.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -300,14 +300,6 @@ class CompilerInvocation {
300300
return FrontendOpts.ParseStdlib;
301301
}
302302

303-
void setModuleAliasMap(std::map<StringRef, StringRef> ModAliasMap) {
304-
FrontendOpts.ModuleAliasMap = ModAliasMap;
305-
}
306-
307-
std::map<StringRef, StringRef> getModuleAliasMap() const {
308-
return FrontendOpts.ModuleAliasMap;
309-
}
310-
311303
void setModuleName(StringRef Name) {
312304
FrontendOpts.ModuleName = Name.str();
313305
IRGenOpts.ModuleName = Name.str();

include/swift/Frontend/FrontendOptions.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
#include "swift/Frontend/FrontendInputsAndOutputs.h"
1919
#include "swift/Frontend/InputFile.h"
2020
#include "llvm/ADT/Hashing.h"
21+
#include "llvm/ADT/StringMap.h"
2122

22-
#include <map>
2323
#include <string>
2424
#include <vector>
2525

@@ -50,7 +50,7 @@ class FrontendOptions {
5050
std::string ImplicitObjCHeaderPath;
5151

5252
/// The map of aliases and underlying names of imported modules.
53-
std::map<StringRef, StringRef> ModuleAliasMap;
53+
llvm::StringMap<StringRef> ModuleAliasMap;
5454

5555
/// The name of the module that the frontend is building.
5656
std::string ModuleName;

include/swift/Option/Options.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,8 @@ def module_name_EQ : Joined<["-"], "module-name=">, Flags<[FrontendOption]>,
432432

433433
def module_alias : Separate<["-"], "module-alias">,
434434
Flags<[FrontendOption]>,
435-
HelpText<"Alias and underlying name 'alias=underlying_name' of the module to be imported">;
435+
MetaVarName<"<alias_name=underlying_name>">,
436+
HelpText<"If a source file imports or references module <alias_name>, the underlying name is used for the contents of the file">;
436437

437438
def module_link_name : Separate<["-"], "module-link-name">,
438439
Flags<[FrontendOption, ModuleInterfaceOption]>,

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -506,38 +506,63 @@ bool ArgsToFrontendOptionsConverter::setUpImmediateArgs() {
506506
bool ArgsToFrontendOptionsConverter::computeModuleAliases() {
507507
auto list = Args.getAllArgValues(options::OPT_module_alias);
508508
if (!list.empty()) {
509-
for (auto val: list) {
510-
auto i = val.find("=");
511-
if (i == std::string::npos) {
512-
Diags.diagnose(SourceLoc(), diag::error_bad_module_alias, val);
509+
auto validate = [this](StringRef value, bool allowModuleName) -> bool
510+
{
511+
if (!allowModuleName) {
512+
if (value == Opts.ModuleName ||
513+
value == Opts.ModuleABIName ||
514+
value == Opts.ModuleLinkName) {
515+
Diags.diagnose(SourceLoc(), diag::error_module_alias_forbidden_name, value);
516+
return false;
517+
}
518+
}
519+
if (value == STDLIB_NAME) {
520+
Diags.diagnose(SourceLoc(), diag::error_module_alias_forbidden_name, value);
521+
return false;
522+
}
523+
if (!Lexer::isIdentifier(value)) {
524+
Diags.diagnose(SourceLoc(), diag::error_bad_module_name, value, false);
525+
return false;
526+
}
527+
return true;
528+
};
529+
530+
for (auto item: list) {
531+
auto str = StringRef(item);
532+
// splits to an alias and the underlying name
533+
auto pair = str.split('=');
534+
auto lhs = pair.first;
535+
auto rhs = pair.second;
536+
537+
if (rhs.empty()) { // '=' is missing
538+
Diags.diagnose(SourceLoc(), diag::error_module_alias_invalid_format, str);
513539
return true;
514540
}
515-
516-
std::string *lhs = new std::string(val.substr(0, i));
517-
std::string *rhs = new std::string(val.substr(i+1, val.length()));
518-
auto modAlias = StringRef(*lhs);
519-
auto modValue = StringRef(*rhs);
520-
521-
if (modAlias.empty() ||
522-
modValue.empty() ||
523-
modAlias == Opts.ModuleName ||
524-
modAlias == Opts.ModuleABIName ||
525-
modAlias == Opts.ModuleLinkName ||
526-
modValue == Opts.ModuleName ||
527-
modValue == Opts.ModuleABIName ||
528-
modValue == Opts.ModuleLinkName ||
529-
!Lexer::isIdentifier(modAlias) ||
530-
!Lexer::isIdentifier(modValue)) {
531-
Diags.diagnose(SourceLoc(), diag::error_bad_module_alias, val);
541+
if (!validate(lhs, false) || !validate(rhs, true)) {
542+
return true;
543+
}
544+
545+
// First, add the underlying name as a key to prevent it from being
546+
// used as an alias
547+
if (!Opts.ModuleAliasMap.insert({rhs, StringRef()}).second) {
548+
Diags.diagnose(SourceLoc(), diag::error_module_alias_duplicate, rhs);
549+
return true;
550+
}
551+
// Next, add the alias as a key and the underlying name as a value to the map
552+
auto underlyingName = Opts.ModuleAliasMap.find(rhs)->first();
553+
if (!Opts.ModuleAliasMap.insert({lhs, underlyingName}).second) {
554+
Diags.diagnose(SourceLoc(), diag::error_module_alias_duplicate, lhs);
532555
return true;
533556
}
534-
Opts.ModuleAliasMap.insert({ modAlias, modValue });
535557
}
536558
}
537559
return false;
538560
}
539561

540562
bool ArgsToFrontendOptionsConverter::computeModuleName() {
563+
// Module alias (if any) should be computed after module name is computed
564+
assert(Opts.ModuleAliasMap.empty());
565+
541566
const Arg *A = Args.getLastArg(options::OPT_module_name);
542567
if (A) {
543568
Opts.ModuleName = A->getValue();

lib/Frontend/Frontend.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ bool CompilerInstance::setUpASTContextIfNeeded() {
211211
// and single file builds.
212212
Invocation.getLangOptions().RecordRequestReferences
213213
= !isWholeModuleCompilation();
214-
Invocation.getLangOptions().ModuleAliasMap = Invocation.getFrontendOptions().ModuleAliasMap;
215214

216215
Context.reset(ASTContext::get(
217216
Invocation.getLangOptions(), Invocation.getTypeCheckerOptions(),
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
func quip() {
2+
}
3+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Tests for invalid module alias format and values.
2+
3+
// RUN: not %target-swift-frontend -emit-silgen -parse-as-library %S/Inputs/invalid-module-alias.swift -module-name foo -module-alias foo=bar 2>&1 | %FileCheck -check-prefix=INVALID_MODULE_ALIAS %s
4+
// INVALID_MODULE_ALIAS: error: invalid module alias "foo"; make sure the alias differs from the module name, module ABI name, module link name, and a standard library name
5+
6+
// RUN: not %target-swift-frontend -emit-silgen -parse-as-library %S/Inputs/invalid-module-alias.swift -module-name foo -module-alias Swift=Bar 2>&1 | %FileCheck -check-prefix=INVALID_MODULE_ALIAS1 %s
7+
// INVALID_MODULE_ALIAS1: error: invalid module alias "Swift"; make sure the alias differs from the module name, module ABI name, module link name, and a standard library name
8+
9+
// RUN: not %target-swift-frontend -emit-silgen -parse-as-library %S/Inputs/invalid-module-alias.swift -module-name foo -module-alias bar=bar 2>&1 | %FileCheck -check-prefix=INVALID_MODULE_ALIAS2 %s
10+
// INVALID_MODULE_ALIAS2: error: duplicate module alias; the name "bar" is already used for a module alias or an underlying name
11+
12+
// RUN: not %target-swift-frontend -emit-silgen -parse-as-library %S/Inputs/invalid-module-alias.swift -module-name foo -module-alias bar=baz -module-alias baz=cat 2>&1 | %FileCheck -check-prefix=INVALID_MODULE_ALIAS3 %s
13+
// INVALID_MODULE_ALIAS3: error: duplicate module alias; the name "baz" is already used for a module alias or an underlying name
14+
15+
// RUN: not %target-swift-frontend -emit-silgen -parse-as-library %S/Inputs/invalid-module-alias.swift -module-name foo -module-alias bar 2>&1 | %FileCheck -check-prefix=INVALID_MODULE_ALIAS4 %s
16+
// INVALID_MODULE_ALIAS4: error: invalid module alias "bar"; make sure to use the format '-module-alias alias_name=underlying_name'
17+
18+
// RUN: not %target-swift-frontend -emit-silgen -parse-as-library %S/Inputs/invalid-module-alias.swift -module-name foo -module-alias bar=c-a.t 2>&1 | %FileCheck -check-prefix=INVALID_MODULE_NAME %s
19+
// INVALID_MODULE_NAME: error: module name "c-a.t" is not a valid identifier
20+
21+
// These should succeed.
22+
// RUN: %target-swift-frontend -emit-silgen %S/Inputs/invalid-module-alias.swift > /dev/null
23+
// RUN: %target-swift-frontend -emit-silgen -parse-as-library -module-name foo %S/Inputs/invalid-module-alias.swift -module-alias bar=cat > /dev/null
24+
// RUN: %target-swift-frontend -typecheck -parse-as-library -module-name foo %S/Inputs/invalid-module-alias.swift -module-alias bar=cat
25+

0 commit comments

Comments
 (0)