aboutsummaryrefslogtreecommitdiffstats
path: root/COFF/DriverUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'COFF/DriverUtils.cpp')
-rw-r--r--COFF/DriverUtils.cpp59
1 files changed, 39 insertions, 20 deletions
diff --git a/COFF/DriverUtils.cpp b/COFF/DriverUtils.cpp
index 4360ac23b262..e08b855740a4 100644
--- a/COFF/DriverUtils.cpp
+++ b/COFF/DriverUtils.cpp
@@ -322,7 +322,7 @@ public:
if (!contents.empty()) {
std::error_code ec;
- raw_fd_ostream os(path, ec, sys::fs::F_None);
+ raw_fd_ostream os(path, ec, sys::fs::OF_None);
if (ec)
fatal("failed to open " + path + ": " + ec.message());
os << contents;
@@ -410,7 +410,7 @@ static std::string createManifestXmlWithExternalMt(StringRef defaultXml) {
// Create the default manifest file as a temporary file.
TemporaryFile Default("defaultxml", "manifest");
std::error_code ec;
- raw_fd_ostream os(Default.path, ec, sys::fs::F_Text);
+ raw_fd_ostream os(Default.path, ec, sys::fs::OF_Text);
if (ec)
fatal("failed to open " + Default.path + ": " + ec.message());
os << defaultXml;
@@ -511,7 +511,7 @@ void createSideBySideManifest() {
if (path == "")
path = config->outputFile + ".manifest";
std::error_code ec;
- raw_fd_ostream out(path, ec, sys::fs::F_Text);
+ raw_fd_ostream out(path, ec, sys::fs::OF_Text);
if (ec)
fatal("failed to create manifest: " + ec.message());
out << createManifestXml();
@@ -700,26 +700,42 @@ void checkFailIfMismatch(StringRef arg, InputFile *source) {
// Convert Windows resource files (.res files) to a .obj file.
// Does what cvtres.exe does, but in-process and cross-platform.
-MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs) {
- object::WindowsResourceParser parser;
+MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,
+ ArrayRef<ObjFile *> objs) {
+ object::WindowsResourceParser parser(/* MinGW */ config->mingw);
+ std::vector<std::string> duplicates;
for (MemoryBufferRef mb : mbs) {
std::unique_ptr<object::Binary> bin = check(object::createBinary(mb));
object::WindowsResource *rf = dyn_cast<object::WindowsResource>(bin.get());
if (!rf)
fatal("cannot compile non-resource file as resource");
- std::vector<std::string> duplicates;
if (auto ec = parser.parse(rf, duplicates))
fatal(toString(std::move(ec)));
+ }
+
+ // Note: This processes all .res files before all objs. Ideally they'd be
+ // handled in the same order they were linked (to keep the right one, if
+ // there are duplicates that are tolerated due to forceMultipleRes).
+ for (ObjFile *f : objs) {
+ object::ResourceSectionRef rsf;
+ if (auto ec = rsf.load(f->getCOFFObj()))
+ fatal(toString(f) + ": " + toString(std::move(ec)));
- for (const auto &dupeDiag : duplicates)
- if (config->forceMultipleRes)
- warn(dupeDiag);
- else
- error(dupeDiag);
+ if (auto ec = parser.parse(rsf, f->getName(), duplicates))
+ fatal(toString(std::move(ec)));
}
+ if (config->mingw)
+ parser.cleanUpManifests(duplicates);
+
+ for (const auto &dupeDiag : duplicates)
+ if (config->forceMultipleRes)
+ warn(dupeDiag);
+ else
+ error(dupeDiag);
+
Expected<std::unique_ptr<MemoryBuffer>> e =
llvm::object::writeWindowsResourceCOFF(config->machine, parser,
config->timestamp);
@@ -757,15 +773,15 @@ static void handleColorDiagnostics(opt::InputArgList &args) {
if (!arg)
return;
if (arg->getOption().getID() == OPT_color_diagnostics) {
- errorHandler().colorDiagnostics = true;
+ enableColors(true);
} else if (arg->getOption().getID() == OPT_no_color_diagnostics) {
- errorHandler().colorDiagnostics = false;
+ enableColors(false);
} else {
StringRef s = arg->getValue();
if (s == "always")
- errorHandler().colorDiagnostics = true;
+ enableColors(true);
else if (s == "never")
- errorHandler().colorDiagnostics = false;
+ enableColors(false);
else if (s != "auto")
error("unknown option: --color-diagnostics=" + s);
}
@@ -792,13 +808,17 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
// We need to get the quoting style for response files before parsing all
// options so we parse here before and ignore all the options but
- // --rsp-quoting.
+ // --rsp-quoting and /lldignoreenv.
+ // (This means --rsp-quoting can't be added through %LINK%.)
opt::InputArgList args = table.ParseArgs(argv, missingIndex, missingCount);
- // Expand response files (arguments in the form of @<filename>)
- // and then parse the argument again.
+
+ // Expand response files (arguments in the form of @<filename>) and insert
+ // flags from %LINK% and %_LINK_%, and then parse the argument again.
SmallVector<const char *, 256> expandedArgv(argv.data(),
argv.data() + argv.size());
+ if (!args.hasArg(OPT_lldignoreenv))
+ addLINK(expandedArgv);
cl::ExpandResponseFiles(saver, getQuotingStyle(args), expandedArgv);
args = table.ParseArgs(makeArrayRef(expandedArgv).drop_front(), missingIndex,
missingCount);
@@ -868,7 +888,7 @@ ArgParser::parseDirectives(StringRef s) {
// link.exe has an interesting feature. If LINK or _LINK_ environment
// variables exist, their contents are handled as command line strings.
// So you can pass extra arguments using them.
-opt::InputArgList ArgParser::parseLINK(std::vector<const char *> argv) {
+void ArgParser::addLINK(SmallVector<const char *, 256> &argv) {
// Concatenate LINK env and command line arguments, and then parse them.
if (Optional<std::string> s = Process::GetEnv("LINK")) {
std::vector<const char *> v = tokenize(*s);
@@ -878,7 +898,6 @@ opt::InputArgList ArgParser::parseLINK(std::vector<const char *> argv) {
std::vector<const char *> v = tokenize(*s);
argv.insert(std::next(argv.begin()), v.begin(), v.end());
}
- return parse(argv);
}
std::vector<const char *> ArgParser::tokenize(StringRef s) {