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

#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
#include "ClangUtilityFunction.h"

// 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/ExpressionSourceCode.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Host/Host.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"

using namespace lldb_private;

//------------------------------------------------------------------
/// 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.
//------------------------------------------------------------------
ClangUtilityFunction::ClangUtilityFunction (ExecutionContextScope &exe_scope,
                                            const char *text,
                                            const char *name) :
    UtilityFunction (exe_scope, text, name)
{
}

ClangUtilityFunction::~ClangUtilityFunction ()
{
}

//------------------------------------------------------------------
/// Install the utility function into a process
///
/// @param[in] diagnostic_manager
///     A diagnostic manager to report errors and warnings to.
///
/// @param[in] exe_ctx
///     The execution context to install the utility function to.
///
/// @return
///     True on success (no errors); false otherwise.
//------------------------------------------------------------------
bool
ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx)
{
    if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
    {
        diagnostic_manager.PutCString(eDiagnosticSeverityWarning, "already installed");
        return false;
    }

    ////////////////////////////////////
    // Set up the target and compiler
    //
    
    Target *target = exe_ctx.GetTargetPtr();

    if (!target)
    {
        diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid target");
        return false;
    }

    Process *process = exe_ctx.GetProcessPtr();

    if (!process)
    {
        diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid process");
        return false;
    }

    //////////////////////////
    // Parse the expression
    //
    
    bool keep_result_in_memory = false;
    
    ResetDeclMap(exe_ctx, keep_result_in_memory);

    if (!DeclMap()->WillParse(exe_ctx, NULL))
    {
        diagnostic_manager.PutCString(eDiagnosticSeverityError,
                                      "current process state is unsuitable for expression parsing");
        return false;
    }

    const bool generate_debug_info = true;
    ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this, generate_debug_info);

    unsigned num_errors = parser.Parse(diagnostic_manager);

    if (num_errors)
    {
        ResetDeclMap();

        return false;
    }
    
    //////////////////////////////////
    // JIT the output of the parser
    //
        
    bool can_interpret = false; // should stay that way
    
    Error jit_error = parser.PrepareForExecution (m_jit_start_addr, 
                                                  m_jit_end_addr,
                                                  m_execution_unit_sp,
                                                  exe_ctx,
                                                  can_interpret,
                                                  eExecutionPolicyAlways);
    
    if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
    {
        m_jit_process_wp = process->shared_from_this();
        if (parser.GetGenerateDebugInfo())
        {
            lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
            
            if (jit_module_sp)
            {
                ConstString const_func_name(FunctionName());
                FileSpec jit_file;
                jit_file.GetFilename() = const_func_name;
                jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
                m_jit_module_wp = jit_module_sp;
                target->GetImages().Append(jit_module_sp);
            }
        }
    }
    
#if 0
	// jingham: look here
    StreamFile logfile ("/tmp/exprs.txt", "a");
    logfile.Printf ("0x%16.16" PRIx64 ": func = %s, source =\n%s\n",
                    m_jit_start_addr, 
                    m_function_name.c_str(), 
                    m_function_text.c_str());
#endif

    DeclMap()->DidParse();
    
    ResetDeclMap();
    
    if (jit_error.Success())
    {
        return true;
    }
    else
    {
        const char *error_cstr = jit_error.AsCString();
        if (error_cstr && error_cstr[0])
        {
            diagnostic_manager.Printf(eDiagnosticSeverityError, "%s", error_cstr);
        }
        else
        {
            diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
        }
        return false;
    }
}

void
ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory)
{
    m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx));
}
