Index: lld/COFF/Config.h =================================================================== --- lld/COFF/Config.h +++ lld/COFF/Config.h @@ -10,6 +10,7 @@ #ifndef LLD_COFF_CONFIG_H #define LLD_COFF_CONFIG_H +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Object/COFF.h" #include "llvm/Support/CachePruning.h" @@ -103,6 +104,11 @@ // True if we are creating a DLL. bool DLL = false; StringRef Implib; + + // Export args in directive sections and command line, + // parsed after deduplication. + llvm::SetVector RawExports; + std::vector Exports; std::set DelayLoads; std::map DLLOrder; Index: lld/COFF/Driver.cpp =================================================================== --- lld/COFF/Driver.cpp +++ lld/COFF/Driver.cpp @@ -245,15 +245,7 @@ Config->Entry = addUndefined(mangle(Arg->getValue())); break; case OPT_export: { - Export E = parseExport(Arg->getValue()); - if (Config->Machine == I386 && Config->MinGW) { - if (!isDecorated(E.Name)) - E.Name = Saver.save("_" + E.Name); - if (!E.ExtName.empty() && !isDecorated(E.ExtName)) - E.ExtName = Saver.save("_" + E.ExtName); - } - E.Directives = true; - Config->Exports.push_back(E); + Config->RawExports.insert(Arg->getValue()); break; } case OPT_failifmismatch: @@ -1105,10 +1097,20 @@ } } + const size_t NumDirectiveExports = Config->RawExports.size(); + // Handle /export for (auto *Arg : Args.filtered(OPT_export)) { - Export E = parseExport(Arg->getValue()); - if (Config->Machine == I386) { + Config->RawExports.insert(Arg->getValue()); + } + + // Parse deduplicated Exports in directive sections and command line. + for (size_t I = 0, RE = Config->RawExports.size(); I != RE; ++I) { + Export E = parseExport(Config->RawExports[I]); + if (I < NumDirectiveExports) + E.Directives = true; + + if (Config->Machine == I386 && (!E.Directives || Config->MinGW)) { if (!isDecorated(E.Name)) E.Name = Saver.save("_" + E.Name); if (!E.ExtName.empty() && !isDecorated(E.ExtName))