//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
#include <stdio.h>
#if HAVE_SYS_TYPES_H
#  include <sys/types.h>
#endif

// C++ Includes

#include "lldb/Core/ConstString.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Expression/ExpressionSourceCode.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Host/Host.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"

using namespace lldb_private;
using namespace lldb;

//------------------------------------------------------------------
/// Constructor
///
/// @param[in] text
///     The text of the function.  Must be a full translation unit.
///
/// @param[in] name
///     The name of the function, as used in the text.
//------------------------------------------------------------------
UtilityFunction::UtilityFunction (ExecutionContextScope &exe_scope,
                                  const char *text,
                                  const char *name) :
    Expression (exe_scope),
    m_execution_unit_sp (),
    m_jit_module_wp (),
    m_function_text (ExpressionSourceCode::g_expression_prefix),
    m_function_name (name)
{
    if (text && text[0])
        m_function_text.append (text);
}

UtilityFunction::~UtilityFunction ()
{
    lldb::ProcessSP process_sp (m_jit_process_wp.lock());
    if (process_sp)
    {
        lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
        if (jit_module_sp)
            process_sp->GetTarget().GetImages().Remove(jit_module_sp);
    }
    
}

// FIXME: We should check that every time this is called it is called with the same return type & arguments...

FunctionCaller *
UtilityFunction::MakeFunctionCaller (const CompilerType &return_type, const ValueList &arg_value_list, Error &error)
{
    if (m_caller_up)
        return m_caller_up.get();
    
    ProcessSP process_sp = m_jit_process_wp.lock();
    if (!process_sp)
        return nullptr;
    
    Address impl_code_address;
    impl_code_address.SetOffset(StartAddress());
    std::string name(m_function_name);
    name.append("-caller");
    
    m_caller_up.reset (process_sp->GetTarget().GetFunctionCallerForLanguage (Language(),
                                                                             return_type,
                                                                             impl_code_address,
                                                                             arg_value_list,
                                                                             name.c_str(),
                                                                             error));
    if (error.Fail())
    {
        
        return nullptr;
    }
    if (m_caller_up)
    {
        StreamString errors;
        errors.Clear();
        unsigned num_errors = m_caller_up->CompileFunction(errors);
        if (num_errors)
        {
            error.SetErrorStringWithFormat ("Error compiling %s caller function: \"%s\".",
                                                m_function_name.c_str(),
                                                errors.GetData());
            m_caller_up.reset();
            return nullptr;
        }
        
        errors.Clear();
        ExecutionContext exe_ctx(process_sp);
        
        if (!m_caller_up->WriteFunctionWrapper(exe_ctx, errors))
        {
            error.SetErrorStringWithFormat ("Error inserting caller function for %s: \"%s\".",
                                                m_function_name.c_str(),
                                                errors.GetData());
            m_caller_up.reset();
            return nullptr;
        }
    }
    return m_caller_up.get();
}
