diff options
Diffstat (limited to 'lib/compilers')
-rw-r--r-- | lib/compilers/ada.js | 91 | ||||
-rw-r--r-- | lib/compilers/argument-parsers.js | 174 | ||||
-rw-r--r-- | lib/compilers/golang.js | 139 | ||||
-rw-r--r-- | lib/compilers/haskell.js | 7 | ||||
-rw-r--r-- | lib/compilers/ispc.js | 11 | ||||
-rw-r--r-- | lib/compilers/llc.js | 7 | ||||
-rw-r--r-- | lib/compilers/llvm-mca.js | 7 | ||||
-rw-r--r-- | lib/compilers/nvcc.js | 7 | ||||
-rw-r--r-- | lib/compilers/ocaml.js | 40 | ||||
-rw-r--r-- | lib/compilers/opt.js | 7 | ||||
-rw-r--r-- | lib/compilers/pascal.js | 2 | ||||
-rw-r--r-- | lib/compilers/rust.js | 11 | ||||
-rw-r--r-- | lib/compilers/swift.js | 10 | ||||
-rw-r--r-- | lib/compilers/win32-vc.js | 2 | ||||
-rw-r--r-- | lib/compilers/wine-vc.js | 12 | ||||
-rw-r--r-- | lib/compilers/zig.js | 29 |
16 files changed, 501 insertions, 55 deletions
diff --git a/lib/compilers/ada.js b/lib/compilers/ada.js new file mode 100644 index 000000000..26f4d7102 --- /dev/null +++ b/lib/compilers/ada.js @@ -0,0 +1,91 @@ +// Copyright (c) 2018, Mitch Kennedy +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +const BaseCompiler = require('../base-compiler'), + utils = require('../utils'), + path = require("path"); + +class AdaCompiler extends BaseCompiler { + constructor(info, env) { + super(info, env); + this.supportsOptOutput = false; + this.compiler.supportsIntel = true; + } + + optionsForFilter(filters, outputFilename) { + let options = ['compile', + '-g', // enable debugging + '-c', // Compile only + '-S', // Generate ASM + '-fdiagnostics-color=always', + '-fverbose-asm', // Geneate verbose ASM showing variables + '-cargs', // Compiler Switches for gcc. + '-o', // Set the output executable name + outputFilename + ]; + if (this.compiler.intelAsm && filters.intel && !filters.binary) { + options = options.concat(this.compiler.intelAsm.split(" ")); + } + return options; + } + + // I have left the overloaded preProcess method in case there is a + // need to any actual pre-processing of the input. + // As Ada expects the outermost function name to match the source file name. + // The initial solution was to wrap any input in a dummy example procedure, + // this however restricts users from including standard library packages, as + // Ada mandates that 'with' clauses are placed in the context clause, + // which in the case of a single subprogram is outside of its declaration and body. + preProcess(source) { + return source; + } + + runCompiler(compiler, options, inputFilename, execOptions) { + if (!execOptions) { + execOptions = this.getDefaultExecOptions(); + } + // Set the working directory to be the temp directory that has been created + execOptions.customCwd = path.dirname(inputFilename); + // As the file name is always appended to the end of the options array we need to + // find where the '-cargs' flag is in options. This is to allow us to set the + // output as 'output.s' and not end up with 'example.s'. If the output is left + // as 'example.s' CE can't find it and thus you get no output. + let inputFileName = options.pop(); + for (let i = 0; i < options.length; i++) { + if (options[i] === '-cargs') { + options.splice(i, 0, inputFileName); + break; + } + } + return this.exec(compiler, options, execOptions) + .then(result => { + result.inputFilename = inputFilename; + result.stdout = utils.parseOutput(result.stdout, inputFilename); + result.stderr = utils.parseOutput(result.stderr, inputFilename); + return result; + }); + } +} + +module.exports = AdaCompiler; diff --git a/lib/compilers/argument-parsers.js b/lib/compilers/argument-parsers.js index 56b5a40cc..0476ad827 100644 --- a/lib/compilers/argument-parsers.js +++ b/lib/compilers/argument-parsers.js @@ -27,18 +27,53 @@ const _ = require('underscore'), utils = require('../utils'); class BaseParser { + static hasSupport(options, forOption) { + return _.keys(options).find(option => option.includes(forOption)); + } + + static parseLines(stdout, optionRegex) { + let previousOption = false; + let options = {}; + + utils.eachLine(stdout, line => { + const match = line.match(optionRegex); + if (!match) { + if (previousOption && (line.trim().length !== 0)) { + if (options[previousOption].description.endsWith("-")) + options[previousOption].description += line.trim(); + else { + if (options[previousOption].description.length !== 0) + options[previousOption].description += " " + line.trim(); + else + options[previousOption].description = line.trim(); + } + } else { + previousOption = false; + } + return; + } + + if (match) previousOption = match[1]; + if (previousOption) { + options[previousOption] = { + description: match[2].trim(), + timesused: 0 + }; + } + }); + + return options; + } + static getOptions(compiler, helpArg) { return compiler.exec(compiler.compiler.exe, [helpArg]).then(result => { - const options = {}; + let options = {}; if (result.code === 0) { - const optionFinder = /^\s*(--?[-a-zA-Z]+)/; + const optionFinder = /^\s*(--?[a-z0-9=+,[\]<>|-]*)\s*(.*)/i; - utils.eachLine(result.stdout + result.stderr, line => { - const match = line.match(optionFinder); - if (!match) return; - options[match[1]] = true; - }); + options = BaseParser.parseLines(result.stdout + result.stderr, optionFinder); } + compiler.possibleArguments.populateOptions(options); return options; }); } @@ -52,16 +87,17 @@ class GCCParser extends BaseParser { static parse(compiler) { return Promise.all([ GCCParser.getOptions(compiler, "--target-help"), - GCCParser.getOptions(compiler, "--help=common") + GCCParser.getOptions(compiler, "--help=common"), + GCCParser.getOptions(compiler, "--help=optimizers") ]).then(results => { const options = _.extend.apply(_.extend, results); const keys = _.keys(options); logger.debug("gcc-like compiler options: ", keys.join(" ")); - if (options['-masm']) { + if (BaseParser.hasSupport(options, "-masm=")) { compiler.compiler.intelAsm = "-masm=intel"; compiler.compiler.supportsIntel = true; } - if (options['-fdiagnostics-color']) { + if (BaseParser.hasSupport(options, "-fdiagnostics-color")) { if (compiler.compiler.options) compiler.compiler.options += " "; compiler.compiler.options += "-fdiagnostics-color=always"; } @@ -78,25 +114,135 @@ class ClangParser extends BaseParser { static parse(compiler) { return ClangParser.getOptions(compiler, "--help").then(options => { logger.debug("clang-like compiler options: ", _.keys(options).join(" ")); - if (options['-fsave-optimization-record']) { + if (BaseParser.hasSupport(options, '-fsave-optimization-record')) { compiler.compiler.optArg = "-fsave-optimization-record"; compiler.compiler.supportsOptOutput = true; } - if (options['-fcolor-diagnostics']) { + if (BaseParser.hasSupport(options, "-fcolor-diagnostics")) { if (compiler.compiler.options) compiler.compiler.options += " "; compiler.compiler.options += "-fcolor-diagnostics"; } - if (options['-emit-llvm']) { + if (BaseParser.hasSupport(options, "-emit-llvm")) { compiler.compiler.supportsIrView = true; compiler.compiler.irArg = ['-Xclang', '-emit-llvm', '-fsyntax-only']; } + if (BaseParser.hasSupport(options, "-fno-crash-diagnostics")) { + if (compiler.compiler.options) compiler.compiler.options += " "; + compiler.compiler.options += "-fno-crash-diagnostics"; + } return compiler; }); } } +class PascalParser extends BaseParser { + static parse(compiler) { + return PascalParser.getOptions(compiler, "-help").then(() => compiler); + } +} + +class ISPCParser extends BaseParser { + static parse(compiler) { + return ISPCParser.getOptions(compiler, "--help").then(() => compiler); + } + + static getOptions(compiler, helpArg) { + return compiler.exec(compiler.compiler.exe, [helpArg]).then(result => { + let options = {}; + if (result.code === 0) { + const optionFinder = /^\s*\[(--?[a-z0-9=+,{}\s[\]<>|-]*)\]\s*(.*)/i; + + options = BaseParser.parseLines(result.stdout + result.stderr, optionFinder); + } + compiler.possibleArguments.populateOptions(options); + return options; + }); + } +} + +class VCParser extends BaseParser { + static parse(compiler) { + return Promise.all([ + VCParser.getOptions(compiler, "/help") + ]).then(() => { + return compiler; + }); + } + + static parseLines(stdout, optionRegex) { + let previousOption = false; + let options = {}; + + const matchLine = (line) => { + if (line.startsWith("/?")) return; + + const match = line.match(optionRegex); + if (!match) { + if (previousOption && (line.trim().length !== 0)) { + if (options[previousOption].description.endsWith(":")) + options[previousOption].description += " " + line.trim(); + else { + if (options[previousOption].description.length !== 0) + options[previousOption].description += ", " + line.trim(); + else + options[previousOption].description = line.trim(); + } + } else { + previousOption = false; + } + return; + } + + if (match) previousOption = match[1]; + if (previousOption) { + options[previousOption] = { + description: match[2].trim(), + timesused: 0 + }; + } + }; + + utils.eachLine(stdout, line => { + if (line.length === 0) return; + if (line.includes("C/C++ COMPILER OPTIONS")) return; + if (line.match(/^\s\s*-.*-$/)) return; + + let col1; + let col2; + if ((line.length > 39) && (line[40] === '/')) { + col1 = line.substr(0, 39); + col2 = line.substr(40); + } else { + col1 = line; + col2 = ""; + } + + if (col1) matchLine(col1); + if (col2) matchLine(col2); + }); + + return options; + } + + static getOptions(compiler, helpArg) { + return compiler.exec(compiler.compiler.exe, [helpArg]).then(result => { + let options = {}; + if (result.code === 0) { + const optionFinder = /^\s*(\/[a-z0-9=:+#.,[\]{}<>|_-]*)\s*(.*)/i; + + options = this.parseLines(result.stdout, optionFinder); + } + compiler.possibleArguments.populateOptions(options); + return options; + }); + } +} + module.exports = { Base: BaseParser, Clang: ClangParser, - GCC: GCCParser + GCC: GCCParser, + VC: VCParser, + Pascal: PascalParser, + ISPC: ISPCParser }; diff --git a/lib/compilers/golang.js b/lib/compilers/golang.js index bbf666576..8c298ad38 100644 --- a/lib/compilers/golang.js +++ b/lib/compilers/golang.js @@ -23,41 +23,144 @@ // POSSIBILITY OF SUCH DAMAGE. const BaseCompiler = require('../base-compiler'), + argumentParsers = require("./argument-parsers"), _ = require('underscore'), utils = require('../utils'); +// Each arch has a list of jump instructions in +// Go source src/cmd/asm/internal/arch. +const jumpPrefixes = [ + 'j', + 'b', + + // arm + 'cb', + 'tb', + + // s390x + 'cmpb', + 'cmpub' +]; + class GolangCompiler extends BaseCompiler { convertNewGoL(code) { - const re = /^\s+(0[xX]?[0-9A-Za-z]+)?\s?[0-9]+\s*\(([^:]+):([0-9]+)\)\s*([A-Z]+)(.*)/; - const reUnknown = /^\s+(0[xX]?[0-9A-Za-z]+)?\s?[0-9]+\s*\(<unknown line number>\)\s*([A-Z]+)(.*)/; + const re = /^\s+(0[xX]?[0-9A-Za-z]+)?\s?([0-9]+)\s*\(([^:]+):([0-9]+)\)\s*([A-Z]+)(.*)/; + const reUnknown = /^\s+(0[xX]?[0-9A-Za-z]+)?\s?([0-9]+)\s*\(<unknown line number>\)\s*([A-Z]+)(.*)/; + const reFunc = /TEXT\s+[".]*(\S+)\(SB\)/; let prevLine = null; let file = null; let fileCount = 0; - return _.compact(code.map(obj => { + let func = null; + let funcCollisions = {}; + let labels = {}; + let usedLabels = {}; + let lines = code.map(obj => { + let pcMatch = null; + let fileMatch = null; + let lineMatch = null; + let ins = null; + let args = null; + const line = obj.text; let match = line.match(re); if (match) { - let res = ""; - if (file !== match[2]) { - fileCount++; - res += "\t.file " + fileCount + ' "' + match[2] + '"\n'; - file = match[2]; - } - if (prevLine !== match[3]) { - res += "\t.loc " + fileCount + " " + match[3] + " 0\n"; - prevLine = match[3]; - } - return res + "\t" + match[4].toLowerCase() + match[5]; + pcMatch = match[2]; + fileMatch = match[3]; + lineMatch = match[4]; + ins = match[5]; + args = match[6]; } else { match = line.match(reUnknown); if (match) { - return "\t" + match[2].toLowerCase() + match[3]; + pcMatch = match[2]; + ins = match[3]; + args = match[4]; } else { return null; } } - })).join("\n"); + match = line.match(reFunc); + if (match) { + // Normalize function name. + func = match[1].replace(/[.()*]+/g, "_"); + + // It's possible for normalized function names to collide. + // Keep a count of collisions per function name. Labels get + // suffixed with _[collisions] when collisions > 0. + let collisions = funcCollisions[func]; + if (collisions == null) { + collisions = 0; + } else { + collisions++; + } + + funcCollisions[func] = collisions; + } + + let res = []; + if (pcMatch && !labels[pcMatch]) { + // Create pseudo-label. + let label = pcMatch.replace(/^0{0,4}/, ''); + let suffix = ''; + if (funcCollisions[func] > 0) { + suffix = `_${funcCollisions[func]}`; + } + + label = `${func}_pc${label}${suffix}:`; + if (!labels[label]) { + res.push(label); + labels[label] = true; + } + } + + if (fileMatch && file !== fileMatch) { + fileCount++; + res.push(`\t.file ${fileCount} "${fileMatch}"`); + file = fileMatch; + } + + if (lineMatch && prevLine !== lineMatch) { + res.push(`\t.loc ${fileCount} ${lineMatch} 0`); + prevLine = lineMatch; + } + + ins = ins.toLowerCase(); + args = this.replaceJump(func, funcCollisions[func], ins, args, usedLabels); + res.push(`\t${ins}${args}`); + return res; + }); + + // Find unused pseudo-labels so they can be filtered out. + let unusedLabels = _.mapObject(labels, (val, key) => { return !usedLabels[key]; }); + + return _.chain(lines) + .flatten() + .compact() + .filter((line) => { return !unusedLabels[line]; }) + .value() + .join("\n"); + } + + replaceJump(func, collisions, ins, args, usedLabels) { + // Check if last argument is a decimal number. + const re = /(\s+)([0-9]+)(\s?)$/; + let match = args.match(re); + if (!match) { + return args; + } + + // Check instruction has a jump prefix + if (_.any(jumpPrefixes, (prefix) => { return ins.startsWith(prefix); })) { + let label = `${func}_pc${match[2]}`; + if (collisions > 0) { + label += `_${collisions}`; + } + usedLabels[label + ":"] = true; // record label use for later filtering + return `${match[1]}${label}${match[3]}`; + } + + return args; } extractLogging(stdout) { @@ -90,6 +193,10 @@ class GolangCompiler extends BaseCompiler { } return execOptions; } + + getArgumentParser() { + return argumentParsers.Clang; + } } module.exports = GolangCompiler; diff --git a/lib/compilers/haskell.js b/lib/compilers/haskell.js index 04cc55266..63394b3e7 100644 --- a/lib/compilers/haskell.js +++ b/lib/compilers/haskell.js @@ -22,12 +22,17 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -const BaseCompiler = require('../base-compiler'); +const BaseCompiler = require('../base-compiler'), + argumentParsers = require("./argument-parsers"); class HaskellCompiler extends BaseCompiler { optionsForFilter(filters, outputFilename) { return ['-S', '-g', '-o', this.filename(outputFilename)]; } + + getArgumentParser() { + return argumentParsers.Clang; + } } module.exports = HaskellCompiler; diff --git a/lib/compilers/ispc.js b/lib/compilers/ispc.js index fc0373513..bb571dd8a 100644 --- a/lib/compilers/ispc.js +++ b/lib/compilers/ispc.js @@ -22,12 +22,21 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -const BaseCompiler = require('../base-compiler'); +const BaseCompiler = require('../base-compiler'), + argumentParsers = require("./argument-parsers"); class ISPCCompiler extends BaseCompiler { optionsForFilter(filters, outputFilename) { return ['--target=sse2-i32x4', '--emit-asm', '-g', '-o', this.filename(outputFilename)]; } + + getArgumentParser() { + return argumentParsers.ISPC; + } + + isCfgCompiler(/*compilerVersion*/) { + return true; + } } module.exports = ISPCCompiler; diff --git a/lib/compilers/llc.js b/lib/compilers/llc.js index 11eb7c855..65b9f58dc 100644 --- a/lib/compilers/llc.js +++ b/lib/compilers/llc.js @@ -22,7 +22,8 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -const BaseCompiler = require('../base-compiler'); +const BaseCompiler = require('../base-compiler'), + argumentParsers = require("./argument-parsers"); class LLCCompiler extends BaseCompiler { constructor(info, env) { @@ -36,6 +37,10 @@ class LLCCompiler extends BaseCompiler { if (filters.binary) options = options.concat('-filetype=obj'); return options; } + + getArgumentParser() { + return argumentParsers.Clang; + } } module.exports = LLCCompiler; diff --git a/lib/compilers/llvm-mca.js b/lib/compilers/llvm-mca.js index 47e0f91ef..fc8e84b4c 100644 --- a/lib/compilers/llvm-mca.js +++ b/lib/compilers/llvm-mca.js @@ -22,7 +22,8 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -const AnalysisTool = require('./analysis-tool'); +const AnalysisTool = require('./analysis-tool'), + argumentParsers = require("./argument-parsers"); // Plain compiler, which just runs the tool and returns whatever the output was class LLVMmcaTool extends AnalysisTool { @@ -39,6 +40,10 @@ class LLVMmcaTool extends AnalysisTool { if (filters.intel) options = options.concat(this.compiler.intelAsm.split(' ')); return options; } + + getArgumentParser() { + return argumentParsers.Clang; + } } diff --git a/lib/compilers/nvcc.js b/lib/compilers/nvcc.js index 73f556baf..c090cb419 100644 --- a/lib/compilers/nvcc.js +++ b/lib/compilers/nvcc.js @@ -22,7 +22,8 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -const BaseCompiler = require('../base-compiler'); +const BaseCompiler = require('../base-compiler'), + argumentParsers = require("./argument-parsers"); class NvccCompiler extends BaseCompiler { constructor(info, env) { @@ -38,6 +39,10 @@ class NvccCompiler extends BaseCompiler { optionsForFilter(filters, outputFilename) { return ['-o', this.filename(outputFilename), '--ptx', '--generate-line-info']; } + + getArgumentParser() { + return argumentParsers.Clang; + } } module.exports = NvccCompiler; diff --git a/lib/compilers/ocaml.js b/lib/compilers/ocaml.js new file mode 100644 index 000000000..9c1f12555 --- /dev/null +++ b/lib/compilers/ocaml.js @@ -0,0 +1,40 @@ +// Copyright (c) 2018, Eugen Bulavin +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +"use strict"; + +const BaseCompiler = require('../base-compiler'), + path = require("path"); + +class OCamlCompiler extends BaseCompiler { + optionsForFilter() { + return ['-S', '-g', '-c']; + } + + getOutputFilename(dirPath) { + return path.join(dirPath, `${path.basename(this.compileFilename, this.lang.extensions[0])}.s`); + } +} + +module.exports = OCamlCompiler; diff --git a/lib/compilers/opt.js b/lib/compilers/opt.js index c34a28a4c..7a833bad6 100644 --- a/lib/compilers/opt.js +++ b/lib/compilers/opt.js @@ -22,7 +22,8 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -const BaseCompiler = require('../base-compiler'); +const BaseCompiler = require('../base-compiler'), + argumentParsers = require("./argument-parsers"); class OptCompiler extends BaseCompiler { constructor(info, env) { @@ -32,6 +33,10 @@ class OptCompiler extends BaseCompiler { optionsForFilter(filters, outputFilename) { return ['-o', this.filename(outputFilename), '-S']; } + + getArgumentParser() { + return argumentParsers.Clang; + } } module.exports = OptCompiler; diff --git a/lib/compilers/pascal.js b/lib/compilers/pascal.js index 02e1a4ea5..d9f027749 100644 --- a/lib/compilers/pascal.js +++ b/lib/compilers/pascal.js @@ -156,7 +156,7 @@ class FPCCompiler extends BaseCompiler { } getArgumentParser() { - return argumentParsers.Base; + return argumentParsers.Pascal; } getExtraAsmHint(asm) { diff --git a/lib/compilers/rust.js b/lib/compilers/rust.js index 63eec2af7..b0e51635c 100644 --- a/lib/compilers/rust.js +++ b/lib/compilers/rust.js @@ -23,7 +23,8 @@ // POSSIBILITY OF SUCH DAMAGE. const BaseCompiler = require('../base-compiler'), - _ = require('underscore'); + _ = require('underscore'), + argumentParsers = require("./argument-parsers"); class RustCompiler extends BaseCompiler { constructor(info, env) { @@ -45,6 +46,14 @@ class RustCompiler extends BaseCompiler { options = options.concat(['--crate-type', 'rlib']); return options; } + + getArgumentParser() { + return argumentParsers.Clang; + } + + isCfgCompiler(/*compilerVersion*/) { + return true; + } } module.exports = RustCompiler; diff --git a/lib/compilers/swift.js b/lib/compilers/swift.js index ff43f76f2..71934d7e8 100644 --- a/lib/compilers/swift.js +++ b/lib/compilers/swift.js @@ -22,9 +22,17 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -const BaseCompiler = require('../base-compiler'); +const BaseCompiler = require('../base-compiler'), + argumentParsers = require("./argument-parsers"); class SwiftCompiler extends BaseCompiler { + getArgumentParser() { + return argumentParsers.Clang; + } + + isCfgCompiler(/*compilerVersion*/) { + return true; + } } module.exports = SwiftCompiler; diff --git a/lib/compilers/win32-vc.js b/lib/compilers/win32-vc.js index d26ef5778..1a109445f 100644 --- a/lib/compilers/win32-vc.js +++ b/lib/compilers/win32-vc.js @@ -33,7 +33,7 @@ class Win32VcCompiler extends Win32Compiler { } getArgumentParser() { - return argumentParsers.Base; + return argumentParsers.VC; } } diff --git a/lib/compilers/wine-vc.js b/lib/compilers/wine-vc.js index 6cd2a282a..640f27427 100644 --- a/lib/compilers/wine-vc.js +++ b/lib/compilers/wine-vc.js @@ -52,8 +52,18 @@ class WineVcCompiler extends BaseCompiler { return 'Z:' + fn; } + runCompiler(compiler, options, inputFilename, execOptions) { + if (!execOptions) { + execOptions = this.getDefaultExecOptions(); + } + + execOptions.customCwd = path.dirname(inputFilename).substr(2); + + return super.runCompiler(compiler, options, inputFilename, execOptions); + } + getArgumentParser() { - return argumentParsers.Base; + return argumentParsers.VC; } getExecutableFilename(dirPath, outputFilebase) { diff --git a/lib/compilers/zig.js b/lib/compilers/zig.js index 52e67c8b0..ff2b6f6e0 100644 --- a/lib/compilers/zig.js +++ b/lib/compilers/zig.js @@ -24,7 +24,8 @@ const BaseCompiler = require('../base-compiler'), _ = require('underscore'), - path = require('path'); + path = require('path'), + Semver = require('semver'); class ZigCompiler extends BaseCompiler { constructor(info, env) { @@ -53,21 +54,17 @@ class ZigCompiler extends BaseCompiler { } optionsForFilter(filters, outputFilename, userOptions) { - let options; - if (filters.execute) { - options = [ - 'build-exe', - '--cache-dir', path.dirname(outputFilename), - '--output', this.filename(outputFilename), - '--output-h', '/dev/null' - ]; + let options = [filters.execute ? 'build-exe' : 'build-obj']; + if (this.compiler.semver === 'trunk' || Semver.gt(this.compiler.semver, '0.3.0')) { + const outputDir = path.dirname(outputFilename); + options.push('--cache-dir', outputDir, + '--output-dir', outputDir, + '--name', path.basename(outputFilename, '.s')); } else { - options = [ - 'build-obj', - '--cache-dir', path.dirname(outputFilename), + // Older versions use a different command line interface (#1304) + options.push('--cache-dir', path.dirname(outputFilename), '--output', this.filename(outputFilename), - '--output-h', '/dev/null' - ]; + '--output-h', '/dev/null'); } if (!filters.binary) { @@ -84,6 +81,10 @@ class ZigCompiler extends BaseCompiler { const blacklist = /^(((--(cache-dir|name|output|verbose))|(-mllvm)).*)$/; return _.filter(userOptions, option => !blacklist.test(option)); } + + isCfgCompiler(/*compilerVersion*/) { + return true; + } } module.exports = ZigCompiler; |