clang-cl: Add support for asm listings (/FA and /Fa)
This adds support for outputing the assembly to a file during compilation. It does this by changing the compilation pipeling to not use the integrated assembler, and keep the intermediate assembler file. Differential Revision: http://llvm-reviews.chandlerc.com/D1946 llvm-svn: 192902
This commit is contained in:
parent
1f5573cca2
commit
2c21f74f02
|
@ -1456,6 +1456,8 @@ Execute ``clang-cl /?`` to see a list of supported options:
|
||||||
/c Compile only
|
/c Compile only
|
||||||
/D <macro[=value]> Define macro
|
/D <macro[=value]> Define macro
|
||||||
/fallback Fall back to cl.exe if clang-cl fails to compile
|
/fallback Fall back to cl.exe if clang-cl fails to compile
|
||||||
|
/FA Output assembly code file during compilation
|
||||||
|
/Fa<file or directory> Output assembly code to this file during compilation
|
||||||
/Fe<file or directory> Set output executable file or directory (ends in / or \)
|
/Fe<file or directory> Set output executable file or directory (ends in / or \)
|
||||||
/FI<value> Include file before parsing
|
/FI<value> Include file before parsing
|
||||||
/Fo<file or directory> Set output object file, or directory (ends in / or \)
|
/Fo<file or directory> Set output object file, or directory (ends in / or \)
|
||||||
|
|
|
@ -112,6 +112,11 @@ def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">,
|
||||||
|
|
||||||
def _SLASH_M_Group : OptionGroup<"</M group>">, Group<cl_compile_Group>;
|
def _SLASH_M_Group : OptionGroup<"</M group>">, Group<cl_compile_Group>;
|
||||||
|
|
||||||
|
def _SLASH_FA : CLFlag<"FA">,
|
||||||
|
HelpText<"Output assembly code file during compilation">;
|
||||||
|
def _SLASH_Fa : CLJoined<"Fa">,
|
||||||
|
HelpText<"Output assembly code to this file during compilation">,
|
||||||
|
MetaVarName<"<file or directory>">;
|
||||||
def _SLASH_fallback : CLCompileFlag<"fallback">,
|
def _SLASH_fallback : CLCompileFlag<"fallback">,
|
||||||
HelpText<"Fall back to cl.exe if clang-cl fails to compile">;
|
HelpText<"Fall back to cl.exe if clang-cl fails to compile">;
|
||||||
def _SLASH_FI : CLJoined<"FI">,
|
def _SLASH_FI : CLJoined<"FI">,
|
||||||
|
@ -165,8 +170,7 @@ def _SLASH_Zm : CLIgnoredJoined<"Zm">;
|
||||||
|
|
||||||
def _SLASH_bigobj : CLFlag<"bigobj">;
|
def _SLASH_bigobj : CLFlag<"bigobj">;
|
||||||
def _SLASH_EH : CLJoined<"EH">;
|
def _SLASH_EH : CLJoined<"EH">;
|
||||||
def _SLASH_FA : CLJoined<"FA">;
|
def _SLASH_FA_joined : CLJoined<"FA">;
|
||||||
def _SLASH_Fa : CLJoined<"Fa">;
|
|
||||||
def _SLASH_Fd : CLJoined<"Fd">;
|
def _SLASH_Fd : CLJoined<"Fd">;
|
||||||
def _SLASH_fp : CLJoined<"fp">;
|
def _SLASH_fp : CLJoined<"fp">;
|
||||||
def _SLASH_Gd : CLFlag<"Gd">;
|
def _SLASH_Gd : CLFlag<"Gd">;
|
||||||
|
|
|
@ -1446,6 +1446,8 @@ static const Tool *SelectToolForJob(Compilation &C, const ToolChain *TC,
|
||||||
|
|
||||||
if (TC->useIntegratedAs() &&
|
if (TC->useIntegratedAs() &&
|
||||||
!C.getArgs().hasArg(options::OPT_save_temps) &&
|
!C.getArgs().hasArg(options::OPT_save_temps) &&
|
||||||
|
!C.getArgs().hasArg(options::OPT__SLASH_FA) &&
|
||||||
|
!C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
|
||||||
isa<AssembleJobAction>(JA) &&
|
isa<AssembleJobAction>(JA) &&
|
||||||
Inputs->size() == 1 && isa<CompileJobAction>(*Inputs->begin())) {
|
Inputs->size() == 1 && isa<CompileJobAction>(*Inputs->begin())) {
|
||||||
const Tool *Compiler =
|
const Tool *Compiler =
|
||||||
|
@ -1569,7 +1571,9 @@ void Driver::BuildJobsForAction(Compilation &C,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Create output filename based on ArgValue, which could either be a
|
/// \brief Create output filename based on ArgValue, which could either be a
|
||||||
/// full filename, filename without extension, or a directory.
|
/// full filename, filename without extension, or a directory. If ArgValue
|
||||||
|
/// does not provide a filename, then use BaseName, and use the extension
|
||||||
|
/// suitable for FileType.
|
||||||
static const char *MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue,
|
static const char *MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue,
|
||||||
StringRef BaseName, types::ID FileType) {
|
StringRef BaseName, types::ID FileType) {
|
||||||
SmallString<128> Filename = ArgValue;
|
SmallString<128> Filename = ArgValue;
|
||||||
|
@ -1617,6 +1621,17 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
|
||||||
(isa<PreprocessJobAction>(JA) || JA.getType() == types::TY_ModuleFile))
|
(isa<PreprocessJobAction>(JA) || JA.getType() == types::TY_ModuleFile))
|
||||||
return "-";
|
return "-";
|
||||||
|
|
||||||
|
// Is this the assembly listing for /FA?
|
||||||
|
if (JA.getType() == types::TY_PP_Asm &&
|
||||||
|
(C.getArgs().hasArg(options::OPT__SLASH_FA) ||
|
||||||
|
C.getArgs().hasArg(options::OPT__SLASH_Fa))) {
|
||||||
|
// Use /Fa and the input filename to determine the asm file name.
|
||||||
|
StringRef BaseName = llvm::sys::path::filename(BaseInput);
|
||||||
|
StringRef FaValue = C.getArgs().getLastArgValue(options::OPT__SLASH_Fa);
|
||||||
|
return C.addResultFile(MakeCLOutputFilename(C.getArgs(), FaValue, BaseName,
|
||||||
|
JA.getType()), &JA);
|
||||||
|
}
|
||||||
|
|
||||||
// Output to a temporary file?
|
// Output to a temporary file?
|
||||||
if ((!AtTopLevel && !C.getArgs().hasArg(options::OPT_save_temps) &&
|
if ((!AtTopLevel && !C.getArgs().hasArg(options::OPT_save_temps) &&
|
||||||
!C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
|
!C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
|
||||||
|
|
|
@ -49,6 +49,8 @@ const char *types::getTypeTempSuffix(ID Id, bool CLMode) {
|
||||||
return "obj";
|
return "obj";
|
||||||
if (Id == TY_Image && CLMode)
|
if (Id == TY_Image && CLMode)
|
||||||
return "exe";
|
return "exe";
|
||||||
|
if (Id == TY_PP_Asm && CLMode)
|
||||||
|
return "asm";
|
||||||
return getInfo(Id).TempSuffix;
|
return getInfo(Id).TempSuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,3 +88,18 @@
|
||||||
|
|
||||||
// RUN: %clang_cl /Fefoo /Febar -### -- %s 2>&1 | FileCheck -check-prefix=FeOVERRIDE %s
|
// RUN: %clang_cl /Fefoo /Febar -### -- %s 2>&1 | FileCheck -check-prefix=FeOVERRIDE %s
|
||||||
// FeOVERRIDE: "-out:bar.exe"
|
// FeOVERRIDE: "-out:bar.exe"
|
||||||
|
|
||||||
|
|
||||||
|
// RUN: %clang_cl /FA -### -- %s 2>&1 | FileCheck -check-prefix=FA %s
|
||||||
|
// FA: "-o" "cl-outputs.asm"
|
||||||
|
// RUN: %clang_cl /FA /Fafoo -### -- %s 2>&1 | FileCheck -check-prefix=FaNAME %s
|
||||||
|
// RUN: %clang_cl /Fafoo -### -- %s 2>&1 | FileCheck -check-prefix=FaNAME %s
|
||||||
|
// FaNAME: "-o" "foo.asm"
|
||||||
|
// RUN: %clang_cl /FA /Faa.ext /Fab.ext -### -- %s 2>&1 | FileCheck -check-prefix=FaNAMEEXT %s
|
||||||
|
// FaNAMEEXT: "-o" "b.ext"
|
||||||
|
// RUN: %clang_cl /FA /Fafoo.dir/ -### -- %s 2>&1 | FileCheck -check-prefix=FaDIR %s
|
||||||
|
// FaDIR: "-o" "foo.dir{{[/\\]+}}cl-outputs.asm"
|
||||||
|
// RUN: %clang_cl /FA /Fafoo.dir/a -### -- %s 2>&1 | FileCheck -check-prefix=FaDIRNAME %s
|
||||||
|
// FaDIRNAME: "-o" "foo.dir{{[/\\]+}}a.asm"
|
||||||
|
// RUN: %clang_cl /FA /Fafoo.dir/a.ext -### -- %s 2>&1 | FileCheck -check-prefix=FaDIRNAMEEXT %s
|
||||||
|
// FaDIRNAMEEXT: "-o" "foo.dir{{[/\\]+}}a.ext"
|
||||||
|
|
Loading…
Reference in New Issue