aboutsummaryrefslogtreecommitdiff
path: root/lib/compilers/ada.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compilers/ada.js')
-rw-r--r--lib/compilers/ada.js127
1 files changed, 70 insertions, 57 deletions
diff --git a/lib/compilers/ada.js b/lib/compilers/ada.js
index 83ec0294a..11de78ea1 100644
--- a/lib/compilers/ada.js
+++ b/lib/compilers/ada.js
@@ -1,4 +1,5 @@
// Copyright (c) 2018, Mitch Kennedy
+// Copyright (c) 2022, Compiler Explorer Authors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -53,91 +54,103 @@ export class AdaCompiler extends BaseCompiler {
return path.join(dirPath, 'example.o');
}
- optionsForBackend(backendOptions, outputFilename) {
- // super is needed as it handles the GCC Dump files.
- const opts = super.optionsForBackend(backendOptions, outputFilename);
+ prepareArguments(userOptions, filters, backendOptions, inputFilename, outputFilename, libraries) {
+ backendOptions = backendOptions || {};
+
+ // super call is needed as it handles the GCC Dump files.
+ let backend_opts = super.optionsForBackend(backendOptions, outputFilename);
+
+ // gnatmake opts name {[-cargs opts] [-bargs opts] [-largs opts] [-margs opts]}
+ // ^ ^ ^ ^ ^
+ // | | | | |
+ // `- inputFilename | | | `-- for gnatmake
+ // | | `-- for linker
+ // | `-- for binder (unused here)
+ // `-- for compiler (gcc)
+
+ let gnatmake_opts = [];
+ let compiler_opts = [];
+ let binder_opts = [];
+ let linker_opts = [''];
+
+ if (this.compiler.adarts) {
+ gnatmake_opts.push(`--RTS=${this.compiler.adarts}`);
+ }
if (backendOptions.produceGnatDebug && this.compiler.supportsGnatDebugViews)
// This is using stdout
- opts.push('-gnatGL');
+ gnatmake_opts.push('-gnatGL');
if (backendOptions.produceGnatDebugTree && this.compiler.supportsGnatDebugViews)
// This is also using stdout
- opts.push('-gnatdt');
+ gnatmake_opts.push('-gnatdt');
- return opts;
- }
-
- optionsForFilter(filters, outputFilename) {
- let options = [];
-
- // Always add -cargs to the options. If not needed here, put it last.
- // It's used in runCompiler to insert the input filename at the correct
- // location in the command line.
- // input filename is inserted before -cargs.
+ gnatmake_opts.push(
+ '-g',
+ '-fdiagnostics-color=always',
+ '-eS', // output commands to stdout, they are not errors
+ inputFilename,
+ );
if (!filters.binary) {
- // produce assembly output in outputFilename
- options.push(
- 'compile',
- '-g', // enable debugging
+ gnatmake_opts.push(
'-S', // Generate ASM
- '-fdiagnostics-color=always',
- '-fverbose-asm', // Generate verbose ASM showing variables
'-c', // Compile only
- '-eS', // commands are not errors
- '-cargs', // Compiler Switches for gcc.
- '-o',
- outputFilename,
+ '-fverbose-asm', // Generate verbose ASM showing variables
);
+ // produce assembly output in outputFilename
+ compiler_opts.push('-o', outputFilename);
+
if (this.compiler.intelAsm && filters.intel) {
- options = options.concat(this.compiler.intelAsm.split(' '));
+ gnatmake_opts.push(this.compiler.intelAsm.split(' '));
}
} else {
- // produce an executable in the file specified in getExecutableFilename.
- // The output file is automatically decided by GNAT based on the Source_File_Name being used.
- // As we are for forcing 'example.adb', the output here will be 'example'.
- options.push(
- 'make',
- '-eS',
- '-g',
- '-cargs', // Compiler Switches for gcc.
- );
+ gnatmake_opts.push('-o', outputFilename);
+ }
+
+ // Spread the options coming from outside (user, backend or config options)
+ // in the correct list.
+
+ let part = 0; // 0: gnatmake, 1: compiler, 2: linker, 3: binder
+ for (const a of backend_opts.concat(utils.splitArguments(this.compiler.options), userOptions)) {
+ if (a === '-cargs') {
+ part = 1;
+ continue;
+ } else if (a === '-largs') {
+ part = 2;
+ continue;
+ } else if (a === '-bargs') {
+ part = 3;
+ continue;
+ } else if (a === '-margs') {
+ part = 0;
+ continue;
+ }
+
+ if (part === 0) {
+ gnatmake_opts.push(a);
+ } else if (part === 1) {
+ compiler_opts.push(a);
+ } else if (part === 2) {
+ linker_opts.push(a);
+ } else if (part === 3) {
+ binder_opts.push(a);
+ }
}
- return options;
+ return gnatmake_opts.concat('-cargs', compiler_opts, '-largs', linker_opts, '-bargs', binder_opts);
}
async 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.
- const inputFileName = options.pop();
- for (let i = 0; i < options.length; i++) {
- if (options[i] === '-cargs') {
- options.splice(i, 0, inputFileName);
-
- // If the compiler contains a RTS, add the extra --RTS=.
- // FIXME: should probably check the user did not use one.
- if (this.compiler.adarts) {
- options.splice(i, 0, `--RTS=${this.compiler.adarts}`);
- }
- break;
- }
- }
const result = await this.exec(compiler, options, execOptions);
result.inputFilename = inputFilename;
- const baseFilename = path.basename(inputFileName);
+ const baseFilename = path.basename(inputFilename);
result.stdout = utils.parseOutput(result.stdout, baseFilename, execOptions.customCwd);
result.stderr = utils.parseOutput(result.stderr, baseFilename, execOptions.customCwd);
return result;