//===-LTOCodeGenerator.h - LLVM Link Time Optimizer -----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
//
// This file declares the LTOCodeGenerator class. 
//
//===----------------------------------------------------------------------===//


#ifndef LTO_CODE_GENERATOR_H
#define LTO_CODE_GENERATOR_H

#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/SmallVector.h"

#include <string>


//
// C++ class which implements the opaque lto_code_gen_t
//

struct LTOCodeGenerator {
    static const char*        getVersionString();
    
                            LTOCodeGenerator();
                            ~LTOCodeGenerator();
                            
    bool                addModule(struct LTOModule*, std::string& errMsg);
    bool                setDebugInfo(lto_debug_model, std::string& errMsg);
    bool                setCodePICModel(lto_codegen_model, std::string& errMsg);
    void                setCpu(const char *cpu);
    void                setAssemblerPath(const char* path);
    void                setAssemblerArgs(const char** args, int nargs);
    void                addMustPreserveSymbol(const char* sym);
    bool                writeMergedModules(const char* path, 
                                                           std::string& errMsg);
    const void*         compile(size_t* length, std::string& errMsg);
    void                setCodeGenDebugOptions(const char *opts); 
private:
    bool                generateAssemblyCode(llvm::raw_ostream& out, 
                                             std::string& errMsg);
    bool                assemble(const std::string& asmPath, 
                            const std::string& objPath, std::string& errMsg);
    void                applyScopeRestrictions();
    bool                determineTarget(std::string& errMsg);
    
    typedef llvm::StringMap<uint8_t> StringSet;

    llvm::LLVMContext&          _context;
    llvm::Linker                _linker;
    llvm::TargetMachine*        _target;
    bool                        _emitDwarfDebugInfo;
    bool                        _scopeRestrictionsDone;
    lto_codegen_model           _codeModel;
    StringSet                   _mustPreserveSymbols;
    llvm::MemoryBuffer*         _nativeObjectFile;
    std::vector<const char*>    _codegenOptions;
    llvm::sys::Path*            _assemblerPath;
    std::string                 _mCpu;
    std::vector<std::string>    _assemblerArgs;
};

#endif // LTO_CODE_GENERATOR_H