/*
 * Copyright (c) 2016, Oracle and/or its affiliates.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to
 * endorse or promote products derived from this software without specific prior written
 * permission.
 *
 * 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.
 */
package com.oracle.truffle.llvm.tools;

import java.io.File;

import com.oracle.truffle.llvm.runtime.options.LLVMBaseOptionFacade;
import com.oracle.truffle.llvm.tools.util.ProcessUtil;

public final class GCC extends CompilerBase {

    private static final File GPP_PATH = Mx.executeGetGCCProgramPath("g++");
    private static final File GFORTRAN_PATH = Mx.executeGetGCCProgramPath("gfortran");
    private static final File GCC_PATH = Mx.executeGetGCCProgramPath("gcc");

    private GCC() {
    }

    public static void compileObjectToMachineCode(File objectFile, File executable) {
        String linkCommand = GCC_PATH + " " + objectFile.getAbsolutePath() + " -o " + executable.getAbsolutePath() + " -lm -lgfortran -lgmp";
        ProcessUtil.executeNativeCommandZeroReturn(linkCommand);
        executable.setExecutable(true);
    }

    public static void compileToLLVMIR(File toBeCompiled, File destinationFile) {
        String tool;
        if (ProgrammingLanguage.C.isFile(toBeCompiled)) {
            tool = GCC_PATH + " -std=gnu99";
        } else if (ProgrammingLanguage.FORTRAN.isFile(toBeCompiled)) {
            tool = GFORTRAN_PATH.toString();
        } else if (ProgrammingLanguage.C_PLUS_PLUS.isFile(toBeCompiled)) {
            tool = GPP_PATH.toString();
        } else {
            throw new AssertionError(toBeCompiled);
        }
        String[] command = new String[]{tool, "-I " + LLVMBaseOptionFacade.getProjectRoot() + "/../include", "-S", dragonEggOption(), "-fplugin-arg-dragonegg-emit-ir", "-o " + destinationFile,
                        toBeCompiled.getAbsolutePath()};
        ProcessUtil.executeNativeCommandZeroReturn(command);
    }

    private static String dragonEggOption() {
        return "-fplugin=" + LLVMToolPaths.LLVM_DRAGONEGG;
    }

    public static ProgrammingLanguage[] getSupportedLanguages() {
        return new ProgrammingLanguage[]{ProgrammingLanguage.C, ProgrammingLanguage.C_PLUS_PLUS, ProgrammingLanguage.FORTRAN};
    }
}

@@ -2050,16 +2050,102 @@
 (%22gcc%22);
+%0A    private static final File LLVM_AS_PATH = Mx.executeGetLLVMProgramPath(%22llvm-as%22);
 %0A%0A    pr
@@ -3021,16 +3021,824 @@
       %7D%0A
+        if (destinationFile.getName().endsWith(%22.bc%22)) %7B%0A            // TODO: Check for more elegant way to generate .bc file for FORTRAN source file%0A%0A            // Creating .ll file for the FORTRAN source file%0A            String llFileGenerationcommand = tool + %22 -I %22 + LLVMBaseOptionFacade.getProjectRoot() + %22/../include -S %22 + dragonEggOption() + %22 -fplugin-arg-dragonegg-emit-ir  -o /tmp/temp.ll %22 +%0A                            toBeCompiled.getAbsolutePath();%0A            ProcessUtil.executeNativeCommandZeroReturn(llFileGenerationcommand);%0A%0A            // Converting .ll file to .bc file%0A            String llToBCConversionCommand = LLVM_AS_PATH.toString() + %22 /tmp/temp.ll -o %22 + destinationFile;%0A            ProcessUtil.executeNativeCommandZeroReturn(llToBCConversionCommand);%0A        %7D else %7B%0A    
         
@@ -4038,32 +4038,36 @@
                 
+    
 toBeCompiled.get
@@ -4083,16 +4083,20 @@
 ath()%7D;%0A
+    
         
@@ -4144,24 +4144,35 @@
 n(command);%0A
+        %7D%0A%0A
     %7D%0A%0A    p

Add functionality to generate .bc file for FORTRAN source files