Driver/Darwin: Model dsymutil properly, as a separate action/tool kind which is
added as the last output step, instead of just hacking it into the link step.
- Among other things, this fixes dSYM generation when using multiple -arch options.
llvm-svn: 105475
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index da83803..cae2243 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -504,7 +504,8 @@
ActionList SingleActions;
BuildActions(Args, SingleActions);
- // Add in arch binding and lipo (if necessary) for every top level action.
+ // Add in arch bindings for every top level action, as well as lipo and
+ // dsymutil steps if needed.
for (unsigned i = 0, e = SingleActions.size(); i != e; ++i) {
Action *Act = SingleActions[i];
@@ -531,6 +532,19 @@
Actions.append(Inputs.begin(), Inputs.end());
else
Actions.push_back(new LipoJobAction(Inputs, Act->getType()));
+
+ // Add a 'dsymutil' step if necessary.
+ if (Act->getType() == types::TY_Image) {
+ Arg *A = Args.getLastArg(options::OPT_g_Group);
+ if (A && !A->getOption().matches(options::OPT_g0) &&
+ !A->getOption().matches(options::OPT_gstabs)) {
+ ActionList Inputs;
+ Inputs.push_back(Actions.back());
+ Actions.pop_back();
+
+ Actions.push_back(new DsymutilJobAction(Inputs, types::TY_dSYM));
+ }
+ }
}
}
@@ -992,9 +1006,17 @@
InputInfoList InputInfos;
for (ActionList::const_iterator it = Inputs->begin(), ie = Inputs->end();
it != ie; ++it) {
+ // Treat dsymutil sub-jobs as being at the top-level too, they shouldn't get
+ // temporary output names.
+ //
+ // FIXME: Clean this up.
+ bool SubJobAtTopLevel = false;
+ if (AtTopLevel && isa<DsymutilJobAction>(A))
+ SubJobAtTopLevel = true;
+
InputInfo II;
BuildJobsForAction(C, *it, TC, BoundArch, TryToUsePipeInput,
- /*AtTopLevel*/false, LinkingOutput, II);
+ SubJobAtTopLevel, LinkingOutput, II);
InputInfos.push_back(II);
}
@@ -1023,6 +1045,11 @@
// Always use the first input as the base input.
const char *BaseInput = InputInfos[0].getBaseInput();
+ // ... except dsymutil actions, which use their actual input as the base
+ // input.
+ if (JA->getType() == types::TY_dSYM)
+ BaseInput = InputInfos[0].getFilename();
+
// Determine the place to write output to (nothing, pipe, or filename) and
// where to put the new job.
if (JA->getType() == types::TY_Nothing) {
@@ -1065,7 +1092,7 @@
bool AtTopLevel) const {
llvm::PrettyStackTraceString CrashInfo("Computing output path");
// Output to a user requested destination?
- if (AtTopLevel) {
+ if (AtTopLevel && !isa<DsymutilJobAction>(JA)) {
if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
return C.addResultFile(FinalOutput->getValue(C.getArgs()));
}