LipoJobClass,
DsymutilJobClass,
VerifyJobClass,
- SplitDebugJobClass,
JobClassFirst=PreprocessJobClass,
- JobClassLast=SplitDebugJobClass
+ JobClassLast=VerifyJobClass
};
static const char *getClassName(ActionClass AC);
}
};
-class SplitDebugJobAction : public JobAction {
- virtual void anchor();
-public:
- SplitDebugJobAction(ActionList &Inputs, types::ID Type);
- static bool classof(const Action *A) {
- return A->getKind() == SplitDebugJobClass;
- }
-};
-
} // end namespace driver
} // end namespace clang
case LipoJobClass: return "lipo";
case DsymutilJobClass: return "dsymutil";
case VerifyJobClass: return "verify";
- case SplitDebugJobClass: return "split-debug";
}
llvm_unreachable("invalid class");
VerifyJobAction::VerifyJobAction(ActionList &Inputs, types::ID Type)
: JobAction(VerifyJobClass, Inputs, Type) {
}
-
-void SplitDebugJobAction::anchor() {}
-
-SplitDebugJobAction::SplitDebugJobAction(ActionList &Inputs, types::ID Type)
- : JobAction(SplitDebugJobClass, Inputs, Type) {
-}
Current.reset(ConstructPhaseAction(Args, Phase, Current.take()));
if (Current->getType() == types::TY_Nothing)
break;
- else if (Current->getType() == types::TY_Object &&
- Args.hasArg(options::OPT_gsplit_dwarf)) {
- ActionList Input;
- Input.push_back(Current.take());
- Current.reset(new SplitDebugJobAction(Input, types::TY_Object));
- }
}
// If we ended with something, add to the output list.
Actions.push_back(Current.take());
}
- if (!SplitInputs.empty()) {
- for (ActionList::iterator i = SplitInputs.begin(), e = SplitInputs.end();
- i != e; ++i) {
- Action *Act = *i;
- ActionList Inputs;
- Inputs.push_back(Act);
- Actions.push_back(new SplitDebugJobAction(Inputs, types::TY_Object));
- }
- }
-
// Add a link action if necessary.
if (!LinkerInputs.empty())
Actions.push_back(new LinkJobAction(LinkerInputs, types::TY_Image));
// Determine the place to write output to, if any.
if (JA->getType() == types::TY_Nothing)
Result = InputInfo(A->getType(), BaseInput);
- else if (isa<SplitDebugJobAction>(A))
- Result = InputInfos[0];
else
Result = InputInfo(GetNamedOutputPath(C, *JA, BaseInput, AtTopLevel),
A->getType(), BaseInput);
Tool *&T = Tools[Key];
if (!T) {
switch (Key) {
- case Action::SplitDebugJobClass:
case Action::InputClass:
case Action::BindArchClass:
llvm_unreachable("Invalid tool kind.");
Tool *&T = Tools[Key];
if (!T) {
switch (Key) {
- case Action::SplitDebugJobClass:
case Action::InputClass:
case Action::BindArchClass:
llvm_unreachable("Invalid tool kind.");
break;
case Action::LinkJobClass:
T = new tools::linuxtools::Link(*this); break;
- case Action::SplitDebugJobClass:
- T = new tools::linuxtools::SplitDebug(*this); break;
default:
T = &Generic_GCC::SelectTool(C, JA, Inputs);
}
}
}
+void Clang::SplitDebugInfo(Compilation &C, const JobAction &JA,
+ const ArgList &Args,
+ const InputInfoList &Inputs,
+ const InputInfo &Output,
+ const char *LinkingOutput) const {
+ ArgStringList ExtractArgs;
+ ExtractArgs.push_back("--extract-dwo");
+
+ ArgStringList StripArgs;
+ StripArgs.push_back("--strip-dwo");
+
+ // Grabbing the output of the earlier compile step.
+ StripArgs.push_back(Output.getFilename());
+ ExtractArgs.push_back(Output.getFilename());
+
+ // Add an output for the extract.
+ Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);
+ const char *OutFile;
+ if (FinalOutput) {
+ SmallString<128> T(FinalOutput->getValue());
+ llvm::sys::path::replace_extension(T, "dwo");
+ OutFile = Args.MakeArgString(T);
+ } else {
+ // Use the compilation dir.
+ SmallString<128> T(Args.getLastArgValue(options::OPT_fdebug_compilation_dir));
+ T += llvm::sys::path::stem(Inputs[0].getBaseInput());
+ llvm::sys::path::replace_extension(T, "dwo");
+ OutFile = Args.MakeArgString(T);
+ }
+ ExtractArgs.push_back(OutFile);
+
+ const char *Exec =
+ Args.MakeArgString(getToolChain().GetProgramPath("objcopy"));
+
+ // First extract the dwo sections.
+ C.addCommand(new Command(JA, *this, Exec, ExtractArgs));
+
+ // Then remove them from the original .o file.
+ C.addCommand(new Command(JA, *this, Exec, StripArgs));
+}
+
void Clang::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
// Finally add the command to the compilation.
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ // Handle the debug info splitting at object creation time.
+ // TODO: Currently only works on linux with newer objcopy.
+ if (Args.hasArg(options::OPT_gsplit_dwarf) &&
+ getToolChain().getTriple().getOS() == llvm::Triple::Linux &&
+ isa<AssembleJobAction>(JA))
+ SplitDebugInfo(C, JA, Args, Inputs, Output, LinkingOutput);
+
if (Arg *A = Args.getLastArg(options::OPT_pg))
if (Args.hasArg(options::OPT_fomit_frame_pointer))
D.Diag(diag::err_drv_argument_not_allowed_with)
if (getToolChain().getTriple().getArch() != llvm::Triple::x86_64 &&
(((Args.hasArg(options::OPT_mkernel) ||
- Args.hasArg(options::OPT_fapple_kext)) &&
+ Args.hasArg(options::OPT_fapple_kext)) &&
(!getDarwinToolChain().isTargetIPhoneOS() ||
getDarwinToolChain().isIPhoneOSVersionLT(6, 0))) ||
Args.hasArg(options::OPT_static)))
C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs));
}
-void linuxtools::SplitDebug::ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &Args,
- const char *LinkingOutput) const {
- // Assert some invariants.
- assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
- const InputInfo &Input = Inputs[0];
- assert(Input.isFilename() && "Unexpected verify input");
-
- ArgStringList ExtractArgs;
- ExtractArgs.push_back("--extract-dwo");
-
- ArgStringList StripArgs;
- StripArgs.push_back("--strip-dwo");
-
- // Grabbing the output of the earlier compile step.
- StripArgs.push_back(Input.getFilename());
- ExtractArgs.push_back(Input.getFilename());
-
- // Add an output for the extract.
- SmallString<128> T(Inputs[0].getBaseInput());
- llvm::sys::path::replace_extension(T, "dwo");
- const char *OutFile = Args.MakeArgString(T);
- ExtractArgs.push_back(OutFile);
-
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("objcopy"));
-
- // First extract the dwo sections.
- C.addCommand(new Command(JA, *this, Exec, ExtractArgs));
-
- // Then remove them from the original .o file.
- C.addCommand(new Command(JA, *this, Exec, StripArgs));
-}
-
void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
void AddSparcTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const;
void AddHexagonTargetArgs (const ArgList &Args, ArgStringList &CmdArgs) const;
+ void SplitDebugInfo(Compilation &C, const JobAction &JA,
+ const ArgList &Args, const InputInfoList &Inputs,
+ const InputInfo &Output,
+ const char *LinkingOutput) const;
enum RewriteKind { RK_None, RK_Fragile, RK_NonFragile };
const ArgList &TCArgs,
const char *LinkingOutput) const;
};
-
- class LLVM_LIBRARY_VISIBILITY SplitDebug : public Tool {
- public:
- SplitDebug(const ToolChain &TC) : Tool("linuxtools::SplitDebug",
- "objcopy", TC) {}
-
- virtual bool hasIntegratedCPP() const { return false; }
-
- virtual void ConstructJob(Compilation &C, const JobAction &JA,
- const InputInfo &Output,
- const InputInfoList &Inputs,
- const ArgList &TCArgs,
- const char *LinkingOutput) const;
- };
}
/// minix -- Directly call GNU Binutils assembler and linker
namespace minix {
case Action::LipoJobClass:
case Action::DsymutilJobClass:
case Action::VerifyJobClass:
- case Action::SplitDebugJobClass:
- llvm_unreachable("Invalid tool kind.");
case Action::PreprocessJobClass:
case Action::PrecompileJobClass:
case Action::AnalyzeJobClass:
// Check that we split debug output properly
//
// REQUIRES: asserts
-// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-phases \
-// RUN: -gsplit-dwarf -arch x86_64 %s 2> %t
+// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -c -### %s 2> %t
// RUN: FileCheck -check-prefix=CHECK-ACTIONS < %t %s
//
-// CHECK-ACTIONS: 0: input, "{{.*}}split-debug.c", c
-// CHECK-ACTIONS: 4: split-debug, {3}, object
+// CHECK-ACTIONS: objcopy{{.*}}--extract-dwo{{.*}}"split-debug.dwo"
+// CHECK-ACTIONS: objcopy{{.*}}--strip-dwo{{.*}}"split-debug.o"
-// Check output name derivation.
-//
-// RUN: %clang -target x86_64-unknown-linux-gnu -ccc-print-bindings \
-// RUN: -gsplit-dwarf -arch x86_64 -c %s 2> %t
-// RUN: FileCheck -check-prefix=CHECK-OUTPUT-NAME < %t %s
-//
-// CHECK-OUTPUT-NAME:# "x86_64-unknown-linux-gnu" - "clang", inputs: ["{{.*}}split-debug.c"], output: "{{.*}}split-debug{{.*}}.o"
-// CHECK-OUTPUT-NAME:# "x86_64-unknown-linux-gnu" - "linuxtools::SplitDebug", inputs: ["{{.*}}split-debug{{.*}}.o"], output: "{{.*}}split-debug{{.*}}.o"