Index: COFF/Config.h =================================================================== --- COFF/Config.h +++ COFF/Config.h @@ -94,7 +94,8 @@ bool DoICF = true; bool TailMerge; bool Relocatable = true; - bool Force = false; + bool ForceMultiple = false; + bool ForceUnresolved = false; bool Debug = false; bool DebugDwarf = false; bool DebugGHashes = false; Index: COFF/Driver.cpp =================================================================== --- COFF/Driver.cpp +++ COFF/Driver.cpp @@ -837,8 +837,12 @@ // Handle /force or /force:unresolved if (Args.hasArg(OPT_force, OPT_force_unresolved)) - Config->Force = true; + Config->ForceUnresolved = true; + // Handle /force or /force:multiple + if (Args.hasArg(OPT_force, OPT_force_multiple)) + Config->ForceMultiple = true; + // Handle /debug if (Args.hasArg(OPT_debug, OPT_debug_dwarf, OPT_debug_ghash)) { Config->Debug = true; Index: COFF/Options.td =================================================================== --- COFF/Options.td +++ COFF/Options.td @@ -99,8 +99,11 @@ def wholearchive_flag : F<"wholearchive">; def force : F<"force">, + HelpText<"Allow undefined and multiply defined symbols when creating executables">; +def force_unresolved : F<"force:unresolved">, HelpText<"Allow undefined symbols when creating executables">; -def force_unresolved : F<"force:unresolved">; +def force_multiple : F<"force:multiple">, + HelpText<"Allow multiply defined symbols when creating executables">; defm WX : B<"WX", "Treat warnings as errors", "Don't treat warnings as errors">; defm allowbind : B<"allowbind", "Enable DLL binding (default)", Index: COFF/SymbolTable.cpp =================================================================== --- COFF/SymbolTable.cpp +++ COFF/SymbolTable.cpp @@ -59,8 +59,15 @@ Driver->parseDirectives(S); } -static void errorOrWarn(const Twine &S) { - if (Config->Force) +static void errorOrWarnMultiple(const Twine &S) { + if (Config->ForceMultiple) + warn(S); + else + error(S); +} + +static void errorOrWarnUnresolved(const Twine &S) { + if (Config->ForceUnresolved) warn(S); else error(S); @@ -171,7 +178,7 @@ // Remaining undefined symbols are not fatal if /force is specified. // They are replaced with dummy defined symbols. - if (Config->Force) + if (Config->ForceUnresolved) replaceSymbol(Sym, Name, 0); Undefs.insert(Sym); } @@ -181,7 +188,7 @@ for (Symbol *B : Config->GCRoot) { if (Undefs.count(B)) - errorOrWarn(": undefined symbol: " + B->getName()); + errorOrWarnUnresolved(": undefined symbol: " + B->getName()); if (Config->WarnLocallyDefinedImported) if (Symbol *Imp = LocalImports.lookup(B)) warn(": locally defined symbol imported: " + Imp->getName() + @@ -195,7 +202,7 @@ if (!Sym) continue; if (Undefs.count(Sym)) - errorOrWarn("undefined symbol: " + Sym->getName() + + errorOrWarnUnresolved("undefined symbol: " + Sym->getName() + getSymbolLocations(File, SymIndex)); if (Config->WarnLocallyDefinedImported) if (Symbol *Imp = LocalImports.lookup(Sym)) @@ -255,8 +262,8 @@ } void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) { - error("duplicate symbol: " + toString(*Existing) + " in " + - toString(Existing->getFile()) + " and in " + toString(NewFile)); + errorOrWarnMultiple("duplicate symbol: " + toString(*Existing) + " in " + + toString(Existing->getFile()) + " and in " + toString(NewFile)); } Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {