]> granicus.if.org Git - clang/commitdiff
clang-cl: Add support for asm listings (/FA and /Fa)
authorHans Wennborg <hans@hanshq.net>
Thu, 17 Oct 2013 16:16:23 +0000 (16:16 +0000)
committerHans Wennborg <hans@hanshq.net>
Thu, 17 Oct 2013 16:16:23 +0000 (16:16 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192902 91177308-0d34-0410-b5e6-96231b3b80d8

docs/UsersManual.rst
include/clang/Driver/CLCompatOptions.td
lib/Driver/Driver.cpp
lib/Driver/Types.cpp
test/Driver/cl-outputs.c

index 37eb10c62112048d854b35eca7dd7261917dab00..36cd39f8b24e60f243f65a371431d7aa4e472dd3 100644 (file)
@@ -1456,6 +1456,8 @@ Execute ``clang-cl /?`` to see a list of supported options:
     /c                     Compile only
     /D <macro[=value]>     Define macro
     /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 \)
     /FI<value>             Include file before parsing
     /Fo<file or directory> Set output object file, or directory (ends in / or \)
index bdbda6e33514f75da3e8177b1a3528e88898fdc0..075e71e353c9f79a02e26df2a79966d6b018ac16 100644 (file)
@@ -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_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">,
   HelpText<"Fall back to cl.exe if clang-cl fails to compile">;
 def _SLASH_FI : CLJoined<"FI">,
@@ -165,8 +170,7 @@ def _SLASH_Zm : CLIgnoredJoined<"Zm">;
 
 def _SLASH_bigobj : CLFlag<"bigobj">;
 def _SLASH_EH : CLJoined<"EH">;
-def _SLASH_FA : CLJoined<"FA">;
-def _SLASH_Fa : CLJoined<"Fa">;
+def _SLASH_FA_joined : CLJoined<"FA">;
 def _SLASH_Fd : CLJoined<"Fd">;
 def _SLASH_fp : CLJoined<"fp">;
 def _SLASH_Gd : CLFlag<"Gd">;
index ae62993a2fb1cdab62ad343b9212c17dcb0abb8b..101b83c711fb92270fbae99bcd548d4320d69e59 100644 (file)
@@ -1446,6 +1446,8 @@ static const Tool *SelectToolForJob(Compilation &C, const ToolChain *TC,
 
   if (TC->useIntegratedAs() &&
       !C.getArgs().hasArg(options::OPT_save_temps) &&
+      !C.getArgs().hasArg(options::OPT__SLASH_FA) &&
+      !C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
       isa<AssembleJobAction>(JA) &&
       Inputs->size() == 1 && isa<CompileJobAction>(*Inputs->begin())) {
     const Tool *Compiler =
@@ -1568,8 +1570,10 @@ void Driver::BuildJobsForAction(Compilation &C,
   }
 }
 
-/// \brief Create output filename based on ArgValue, which could either be a 
-/// full filename, filename without extension, or a directory.
+/// \brief Create output filename based on ArgValue, which could either be a
+/// 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,
                                         StringRef BaseName, types::ID FileType) {
   SmallString<128> Filename = ArgValue;
@@ -1617,6 +1621,17 @@ const char *Driver::GetNamedOutputPath(Compilation &C,
       (isa<PreprocessJobAction>(JA) || JA.getType() == types::TY_ModuleFile))
     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?
   if ((!AtTopLevel && !C.getArgs().hasArg(options::OPT_save_temps) &&
         !C.getArgs().hasArg(options::OPT__SLASH_Fo)) ||
index e569a2bf825e35c1832e8f22d0378827c24e8abe..3b353041b25bc1f34865f59a813516c1f4ba946f 100644 (file)
@@ -49,6 +49,8 @@ const char *types::getTypeTempSuffix(ID Id, bool CLMode) {
     return "obj";
   if (Id == TY_Image && CLMode)
     return "exe";
+  if (Id == TY_PP_Asm && CLMode)
+    return "asm";
   return getInfo(Id).TempSuffix;
 }
 
index 82134b05626f9bb4a2a9514cb459af08751acc12..4f586ae7ef2ec23cbf09fad28a0281db7a6e6409 100644 (file)
 
 // RUN: %clang_cl /Fefoo /Febar -### -- %s 2>&1 | FileCheck -check-prefix=FeOVERRIDE %s
 // 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"