forked from OSchip/llvm-project
Add support for a verifier to the driver. Currently only verifies debug
output on darwin so is hard coded there. As a note this will need a little bit of refactoring in the class hierarchy to separate it out for different verifiers based on input type. Fixes rdar://8256258. llvm-svn: 138343
This commit is contained in:
parent
7d3effa389
commit
551ef45e85
|
@ -44,9 +44,10 @@ public:
|
|||
LinkJobClass,
|
||||
LipoJobClass,
|
||||
DsymutilJobClass,
|
||||
VerifyJobClass,
|
||||
|
||||
JobClassFirst=PreprocessJobClass,
|
||||
JobClassLast=DsymutilJobClass
|
||||
JobClassLast=VerifyJobClass
|
||||
};
|
||||
|
||||
static const char *getClassName(ActionClass AC);
|
||||
|
@ -214,6 +215,15 @@ public:
|
|||
static bool classof(const DsymutilJobAction *) { return true; }
|
||||
};
|
||||
|
||||
class VerifyJobAction : public JobAction {
|
||||
public:
|
||||
VerifyJobAction(ActionList &Inputs, types::ID Type);
|
||||
static bool classof(const Action *A) {
|
||||
return A->getKind() == VerifyJobClass;
|
||||
}
|
||||
static bool classof(const VerifyJobAction *) { return true; }
|
||||
};
|
||||
|
||||
} // end namespace driver
|
||||
} // end namespace clang
|
||||
|
||||
|
|
|
@ -693,6 +693,8 @@ def u : JoinedOrSeparate<"-u">, Group<u_Group>;
|
|||
def use_gold_plugin : Flag<"-use-gold-plugin">;
|
||||
def v : Flag<"-v">,
|
||||
HelpText<"Show commands to run and use verbose output">;
|
||||
def verify : Flag<"-verify">, Flags<[DriverOption]>,
|
||||
HelpText<"Verify output using a verifier.">;
|
||||
def weak_l : Joined<"-weak-l">, Flags<[LinkerInput]>;
|
||||
def weak__framework : Separate<"-weak_framework">, Flags<[LinkerInput]>;
|
||||
def weak__library : Separate<"-weak_library">, Flags<[LinkerInput]>;
|
||||
|
|
|
@ -31,6 +31,7 @@ const char *Action::getClassName(ActionClass AC) {
|
|||
case LinkJobClass: return "linker";
|
||||
case LipoJobClass: return "lipo";
|
||||
case DsymutilJobClass: return "dsymutil";
|
||||
case VerifyJobClass: return "verify";
|
||||
}
|
||||
|
||||
assert(0 && "invalid class");
|
||||
|
@ -84,3 +85,7 @@ LipoJobAction::LipoJobAction(ActionList &Inputs, types::ID Type)
|
|||
DsymutilJobAction::DsymutilJobAction(ActionList &Inputs, types::ID Type)
|
||||
: JobAction(DsymutilJobClass, Inputs, Type) {
|
||||
}
|
||||
|
||||
VerifyJobAction::VerifyJobAction(ActionList &Inputs, types::ID Type)
|
||||
: JobAction(VerifyJobClass, Inputs, Type) {
|
||||
}
|
||||
|
|
|
@ -829,6 +829,19 @@ void Driver::BuildUniversalActions(const ToolChain &TC,
|
|||
Actions.pop_back();
|
||||
|
||||
Actions.push_back(new DsymutilJobAction(Inputs, types::TY_dSYM));
|
||||
|
||||
// Verify the debug output if we're in assert mode.
|
||||
// TODO: The verifier is noisy by default so put this under an
|
||||
// option for now.
|
||||
#ifndef NDEBUG
|
||||
if (Args.hasArg(options::OPT_verify)) {
|
||||
ActionList VerifyInputs;
|
||||
VerifyInputs.push_back(Actions.back());
|
||||
Actions.pop_back();
|
||||
Actions.push_back(new VerifyJobAction(VerifyInputs,
|
||||
types::TY_Nothing));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1297,6 +1310,11 @@ void Driver::BuildJobsForAction(Compilation &C,
|
|||
if (AtTopLevel && isa<DsymutilJobAction>(A))
|
||||
SubJobAtTopLevel = true;
|
||||
|
||||
// Also treat verify sub-jobs as being at the top-level. They don't
|
||||
// produce any output and so don't need temporary output names.
|
||||
if (AtTopLevel && isa<VerifyJobAction>(A))
|
||||
SubJobAtTopLevel = true;
|
||||
|
||||
InputInfo II;
|
||||
BuildJobsForAction(C, *it, TC, BoundArch,
|
||||
SubJobAtTopLevel, LinkingOutput, II);
|
||||
|
@ -1340,7 +1358,8 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
|
|||
bool AtTopLevel) const {
|
||||
llvm::PrettyStackTraceString CrashInfo("Computing output path");
|
||||
// Output to a user requested destination?
|
||||
if (AtTopLevel && !isa<DsymutilJobAction>(JA)) {
|
||||
if (AtTopLevel && !isa<DsymutilJobAction>(JA) &&
|
||||
!isa<VerifyJobAction>(JA)) {
|
||||
if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
|
||||
return C.addResultFile(FinalOutput->getValue(C.getArgs()));
|
||||
}
|
||||
|
@ -1361,7 +1380,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
|
|||
StringRef BaseName;
|
||||
|
||||
// Dsymutil actions should use the full path.
|
||||
if (isa<DsymutilJobAction>(JA))
|
||||
if (isa<DsymutilJobAction>(JA) || isa<VerifyJobAction>(JA))
|
||||
BaseName = BasePath;
|
||||
else
|
||||
BaseName = llvm::sys::path::filename(BasePath);
|
||||
|
|
|
@ -255,6 +255,8 @@ Tool &Darwin::SelectTool(const Compilation &C, const JobAction &JA,
|
|||
T = new tools::darwin::Lipo(*this); break;
|
||||
case Action::DsymutilJobClass:
|
||||
T = new tools::darwin::Dsymutil(*this); break;
|
||||
case Action::VerifyJobClass:
|
||||
T = new tools::darwin::VerifyDebug(*this); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,8 +364,8 @@ void DarwinClang::AddLinkSearchPathArgs(const ArgList &Args,
|
|||
|
||||
void DarwinClang::AddLinkARCArgs(const ArgList &Args,
|
||||
ArgStringList &CmdArgs) const {
|
||||
|
||||
CmdArgs.push_back("-force_load");
|
||||
|
||||
CmdArgs.push_back("-force_load");
|
||||
llvm::sys::Path P(getDriver().ClangExecutable);
|
||||
P.eraseComponent(); // 'clang'
|
||||
P.eraseComponent(); // 'bin'
|
||||
|
@ -385,13 +387,13 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args,
|
|||
}
|
||||
|
||||
void DarwinClang::AddLinkRuntimeLib(const ArgList &Args,
|
||||
ArgStringList &CmdArgs,
|
||||
ArgStringList &CmdArgs,
|
||||
const char *DarwinStaticLib) const {
|
||||
llvm::sys::Path P(getDriver().ResourceDir);
|
||||
P.appendComponent("lib");
|
||||
P.appendComponent("darwin");
|
||||
P.appendComponent(DarwinStaticLib);
|
||||
|
||||
|
||||
// For now, allow missing resource libraries to support developers who may
|
||||
// not have compiler-rt checked out or integrated into their build.
|
||||
bool Exists;
|
||||
|
@ -1008,6 +1010,8 @@ Tool &Generic_GCC::SelectTool(const Compilation &C,
|
|||
T = new tools::darwin::Lipo(*this); break;
|
||||
case Action::DsymutilJobClass:
|
||||
T = new tools::darwin::Dsymutil(*this); break;
|
||||
case Action::VerifyJobClass:
|
||||
T = new tools::darwin::VerifyDebug(*this); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1371,7 +1375,7 @@ static bool HasMultilib(llvm::Triple::ArchType Arch, enum LinuxDistro Distro) {
|
|||
}
|
||||
if (Arch == llvm::Triple::ppc64)
|
||||
return true;
|
||||
if ((Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc) &&
|
||||
if ((Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc) &&
|
||||
IsDebianBased(Distro))
|
||||
return true;
|
||||
return false;
|
||||
|
@ -1596,14 +1600,14 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
|
|||
Exists) && Exists)
|
||||
GccTriple = "powerpc64-unknown-linux-gnu";
|
||||
else if (!llvm::sys::fs::exists("/usr/lib64/gcc/"
|
||||
"powerpc64-unknown-linux-gnu", Exists) &&
|
||||
"powerpc64-unknown-linux-gnu", Exists) &&
|
||||
Exists)
|
||||
GccTriple = "powerpc64-unknown-linux-gnu";
|
||||
}
|
||||
|
||||
std::string Base = findGCCBaseLibDir(GccTriple);
|
||||
path_list &Paths = getFilePaths();
|
||||
bool Is32Bits = (getArch() == llvm::Triple::x86 ||
|
||||
bool Is32Bits = (getArch() == llvm::Triple::x86 ||
|
||||
getArch() == llvm::Triple::ppc);
|
||||
|
||||
std::string Suffix;
|
||||
|
@ -1776,6 +1780,7 @@ Tool &Windows::SelectTool(const Compilation &C, const JobAction &JA,
|
|||
case Action::BindArchClass:
|
||||
case Action::LipoJobClass:
|
||||
case Action::DsymutilJobClass:
|
||||
case Action::VerifyJobClass:
|
||||
assert(0 && "Invalid tool kind.");
|
||||
case Action::PreprocessJobClass:
|
||||
case Action::PrecompileJobClass:
|
||||
|
|
|
@ -3482,6 +3482,26 @@ void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
|
||||
}
|
||||
|
||||
void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
const InputInfo &Output,
|
||||
const InputInfoList &Inputs,
|
||||
const ArgList &Args,
|
||||
const char *LinkingOutput) const {
|
||||
ArgStringList CmdArgs;
|
||||
CmdArgs.push_back("--verify");
|
||||
|
||||
assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
|
||||
const InputInfo &Input = Inputs[0];
|
||||
assert(Input.isFilename() && "Unexpected verify input");
|
||||
|
||||
// Grabbing the output of the earlier dsymutil run.
|
||||
CmdArgs.push_back(Input.getFilename());
|
||||
|
||||
const char *Exec =
|
||||
Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));
|
||||
C.addCommand(new Command(JA, *this, Exec, CmdArgs));
|
||||
}
|
||||
|
||||
void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
const InputInfo &Output,
|
||||
const InputInfoList &Inputs,
|
||||
|
|
|
@ -277,6 +277,21 @@ namespace darwin {
|
|||
const ArgList &TCArgs,
|
||||
const char *LinkingOutput) const;
|
||||
};
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY VerifyDebug : public DarwinTool {
|
||||
public:
|
||||
VerifyDebug(const ToolChain &TC) : DarwinTool("darwin::VerifyDebug",
|
||||
"dwarfdump", 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// openbsd -- Directly call GNU Binutils assembler and linker
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// Check that we verify debug output properly with multiple -arch options.
|
||||
//
|
||||
// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -ccc-print-phases \
|
||||
// RUN: -verify -arch i386 -arch x86_64 %s -g 2> %t
|
||||
// RUN: FileCheck -check-prefix=CHECK-MULTIARCH-ACTIONS < %t %s
|
||||
//
|
||||
// CHECK-MULTIARCH-ACTIONS: 0: input, "{{.*}}darwin-verify-debug.c", c
|
||||
// CHECK-MULTIARCH-ACTIONS: 8: dsymutil, {7}, dSYM
|
||||
// CHECK-MULTIARCH-ACTIONS: 9: verify, {8}, none
|
||||
//
|
||||
// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -ccc-print-bindings \
|
||||
// RUN: -verify -arch i386 -arch x86_64 %s -g 2> %t
|
||||
// RUN: FileCheck -check-prefix=CHECK-MULTIARCH-BINDINGS < %t %s
|
||||
//
|
||||
// CHECK-MULTIARCH-BINDINGS: # "x86_64-apple-darwin10" - "darwin::Dsymutil", inputs: ["a.out"], output: "a.out.dSYM"
|
||||
// CHECK-MULTIARCH-BINDINGS: # "x86_64-apple-darwin10" - "darwin::VerifyDebug", inputs: ["a.out.dSYM"], output: (nothing)
|
||||
|
||||
// Check output name derivation.
|
||||
//
|
||||
// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -ccc-print-bindings \
|
||||
// RUN: -verify -o foo %s -g 2> %t
|
||||
// RUN: FileCheck -check-prefix=CHECK-OUTPUT-NAME < %t %s
|
||||
//
|
||||
// CHECK-OUTPUT-NAME: "x86_64-apple-darwin10" - "darwin::Link", inputs: [{{.*}}], output: "foo"
|
||||
// CHECK-OUTPUT-NAME: "x86_64-apple-darwin10" - "darwin::Dsymutil", inputs: ["foo"], output: "foo.dSYM"
|
||||
// CHECK-OUTPUT-NAME: "x86_64-apple-darwin10" - "darwin::VerifyDebug", inputs: ["foo.dSYM"], output: (nothing)
|
||||
|
||||
// Check that we only verify when needed.
|
||||
//
|
||||
// RUN: touch %t.o
|
||||
// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -ccc-print-bindings \
|
||||
// RUN: -verify -o foo %t.o -g 2> %t
|
||||
// RUN: grep "Verify" %t | count 0
|
Loading…
Reference in New Issue