[lld/mac] reject -undefined warning and -undefined suppress with -twolevel_namespace
See discussion on https://reviews.llvm.org/D93263 -flat_namespace isn't implemented yet, and neither is -undefined dynamic, so this makes -undefined pretty pointless in lld/MachO for now. But once we implement -flat_namespace (which we need to do anyways to get check-llvm to pass with lld as host linker), the code's already there. Follow-up to https://reviews.llvm.org/D93263#2491865 Differential Revision: https://reviews.llvm.org/D96963
This commit is contained in:
parent
559f372844
commit
28d9953af9
|
@ -30,6 +30,11 @@ struct PlatformInfo {
|
|||
llvm::VersionTuple sdk;
|
||||
};
|
||||
|
||||
enum class NamespaceKind {
|
||||
twolevel,
|
||||
flat,
|
||||
};
|
||||
|
||||
enum class UndefinedSymbolTreatment {
|
||||
unknown,
|
||||
error,
|
||||
|
@ -61,6 +66,7 @@ struct Configuration {
|
|||
bool demangle = false;
|
||||
llvm::MachO::Architecture arch;
|
||||
PlatformInfo platform;
|
||||
NamespaceKind namespaceKind = NamespaceKind::twolevel;
|
||||
UndefinedSymbolTreatment undefinedSymbolTreatment =
|
||||
UndefinedSymbolTreatment::error;
|
||||
llvm::MachO::HeaderFileType outputType;
|
||||
|
|
|
@ -582,18 +582,27 @@ static void handlePlatformVersion(const opt::Arg *arg) {
|
|||
|
||||
static void handleUndefined(const opt::Arg *arg) {
|
||||
StringRef treatmentStr = arg->getValue(0);
|
||||
config->undefinedSymbolTreatment =
|
||||
auto treatment =
|
||||
StringSwitch<UndefinedSymbolTreatment>(treatmentStr)
|
||||
.Case("error", UndefinedSymbolTreatment::error)
|
||||
.Case("warning", UndefinedSymbolTreatment::warning)
|
||||
.Case("suppress", UndefinedSymbolTreatment::suppress)
|
||||
.Case("dynamic_lookup", UndefinedSymbolTreatment::dynamic_lookup)
|
||||
.Default(UndefinedSymbolTreatment::unknown);
|
||||
if (config->undefinedSymbolTreatment == UndefinedSymbolTreatment::unknown) {
|
||||
if (treatment == UndefinedSymbolTreatment::unknown) {
|
||||
warn(Twine("unknown -undefined TREATMENT '") + treatmentStr +
|
||||
"', defaulting to 'error'");
|
||||
config->undefinedSymbolTreatment = UndefinedSymbolTreatment::error;
|
||||
treatment = UndefinedSymbolTreatment::error;
|
||||
} else if (config->namespaceKind == NamespaceKind::twolevel &&
|
||||
(treatment == UndefinedSymbolTreatment::warning ||
|
||||
treatment == UndefinedSymbolTreatment::suppress)) {
|
||||
if (treatment == UndefinedSymbolTreatment::warning)
|
||||
error("'-undefined warning' only valid with '-flat_namespace'");
|
||||
else
|
||||
error("'-undefined suppress' only valid with '-flat_namespace'");
|
||||
treatment = UndefinedSymbolTreatment::error;
|
||||
}
|
||||
config->undefinedSymbolTreatment = treatment;
|
||||
}
|
||||
|
||||
static void warnIfDeprecatedOption(const opt::Option &opt) {
|
||||
|
@ -760,6 +769,18 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
|
|||
if (const opt::Arg *arg = args.getLastArg(OPT_static, OPT_dynamic))
|
||||
config->staticLink = (arg->getOption().getID() == OPT_static);
|
||||
|
||||
if (const opt::Arg *arg =
|
||||
args.getLastArg(OPT_flat_namespace, OPT_twolevel_namespace)) {
|
||||
config->namespaceKind = arg->getOption().getID() == OPT_twolevel_namespace
|
||||
? NamespaceKind::twolevel
|
||||
: NamespaceKind::flat;
|
||||
if (config->namespaceKind == NamespaceKind::flat) {
|
||||
warn("Option '" + arg->getOption().getPrefixedName() +
|
||||
"' is not yet implemented. Stay tuned...");
|
||||
config->namespaceKind = NamespaceKind::twolevel;
|
||||
}
|
||||
}
|
||||
|
||||
config->systemLibraryRoots = getSystemLibraryRoots(args);
|
||||
config->librarySearchPaths =
|
||||
getLibrarySearchPaths(args, config->systemLibraryRoots);
|
||||
|
|
|
@ -448,9 +448,12 @@ def alias_list : Separate<["-"], "alias_list">,
|
|||
Flags<[HelpHidden]>,
|
||||
Group<grp_resolve>;
|
||||
def flat_namespace : Flag<["-"], "flat_namespace">,
|
||||
HelpText<"Resolve symbols from all dylibs, both direct & transitive. Do not record source libraries: dyld must re-search at runtime and use the first definition found">,
|
||||
HelpText<"Resolve symbols from all dylibs, both direct and transitive. Do not record source libraries: dyld must re-search at runtime and use the first definition found">,
|
||||
Flags<[HelpHidden]>,
|
||||
Group<grp_resolve>;
|
||||
def twolevel_namespace : Flag<["-"], "twolevel_namespace">,
|
||||
HelpText<"Make dyld look up symbols by (dylib,name) pairs (default)">,
|
||||
Group<grp_resolve>;
|
||||
def u : Separate<["-"], "u">,
|
||||
MetaVarName<"<symbol>">,
|
||||
HelpText<"Require that <symbol> be defined for the link to succeed">,
|
||||
|
@ -1302,10 +1305,6 @@ def threaded_starts_section : Flag<["-"], "threaded_starts_section">,
|
|||
HelpText<"This option is undocumented in ld64">,
|
||||
Flags<[HelpHidden]>,
|
||||
Group<grp_undocumented>;
|
||||
def twolevel_namespace : Flag<["-"], "twolevel_namespace">,
|
||||
HelpText<"This option is undocumented in ld64">,
|
||||
Flags<[HelpHidden]>,
|
||||
Group<grp_undocumented>;
|
||||
def verbose_optimization_hints : Flag<["-"], "verbose_optimization_hints">,
|
||||
HelpText<"This option is undocumented in ld64">,
|
||||
Flags<[HelpHidden]>,
|
||||
|
|
|
@ -5,14 +5,29 @@
|
|||
# RUN: FileCheck %s -check-prefix=UNKNOWN
|
||||
# RUN: not %lld -undefined error -o /dev/null %t.o 2>&1 | \
|
||||
# RUN: FileCheck %s -check-prefix=ERROR
|
||||
# RUN: %no_fatal_warnings_lld -undefined warning -o /dev/null %t.o 2>&1 | \
|
||||
# RUN: FileCheck %s -check-prefix=WARNING
|
||||
# RUN: %lld -undefined suppress -o /dev/null %t.o 2>&1 | \
|
||||
# RUN: FileCheck %s -check-prefix=SUPPRESS --allow-empty
|
||||
|
||||
# RUN: not %lld -undefined warning -o /dev/null %t.o 2>&1 | \
|
||||
# RUN: FileCheck %s -check-prefix=INVAL-WARNING
|
||||
# RUN: not %lld -undefined suppress -o /dev/null %t.o 2>&1 | \
|
||||
# RUN: FileCheck %s -check-prefix=INVAL-SUPPRESS
|
||||
|
||||
# FIXME: Enable these -undefined checks once -flat_namespace is implemented.
|
||||
# RN: %no_fatal_warnings_lld -flat_namespace -undefined warning \
|
||||
# RN: -o /dev/null %t.o 2>&1 | \
|
||||
# RN: FileCheck %s -check-prefix=WARNING
|
||||
# RN: %lld -flat_namespace -undefined suppress -o /dev/null %t.o 2>&1 | \
|
||||
# RN: FileCheck %s -check-prefix=SUPPRESS --allow-empty
|
||||
|
||||
# ERROR: error: undefined symbol: _bar
|
||||
# ERROR-NEXT: >>> referenced by
|
||||
|
||||
# INVAL-WARNING: error: '-undefined warning' only valid with '-flat_namespace'
|
||||
# INVAL-WARNING-NEXT: error: undefined symbol: _bar
|
||||
|
||||
# INVAL-SUPPRESS: error: '-undefined suppress' only valid with '-flat_namespace'
|
||||
# INVAL-SUPPRESS-NEXT: error: undefined symbol: _bar
|
||||
|
||||
|
||||
# WARNING: warning: undefined symbol: _bar
|
||||
# WARNING-NEXT: >>> referenced by
|
||||
|
||||
|
|
Loading…
Reference in a new issue