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

#include "lldb/Expression/IRForTarget.h"

#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/ValueSymbolTable.h"

#include "clang/AST/ASTContext.h"

#include "lldb/Core/dwarf.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Expression/ClangExpressionDeclMap.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangASTType.h"

#include <map>

using namespace llvm;

static char ID;

IRForTarget::StaticDataAllocator::StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit) :
    m_execution_unit(execution_unit),
    m_stream_string(lldb_private::Stream::eBinary, execution_unit.GetAddressByteSize(), execution_unit.GetByteOrder()),
    m_allocation(LLDB_INVALID_ADDRESS)
{
}

IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker) :
    m_maker(maker),
    m_values()
{
}

IRForTarget::FunctionValueCache::~FunctionValueCache()
{
}

llvm::Value *IRForTarget::FunctionValueCache::GetValue(llvm::Function *function)
{
    if (!m_values.count(function))
    {
        llvm::Value *ret = m_maker(function);
        m_values[function] = ret;
        return ret;
    }
    return m_values[function];
}

lldb::addr_t IRForTarget::StaticDataAllocator::Allocate()
{
    lldb_private::Error err;

    if (m_allocation != LLDB_INVALID_ADDRESS)
    {
        m_execution_unit.FreeNow(m_allocation);
        m_allocation = LLDB_INVALID_ADDRESS;
    }

    m_allocation = m_execution_unit.WriteNow((const uint8_t*)m_stream_string.GetData(), m_stream_string.GetSize(), err);

    return m_allocation;
}

static llvm::Value *FindEntryInstruction (llvm::Function *function)
{
    if (function->empty())
        return NULL;

    return function->getEntryBlock().getFirstNonPHIOrDbg();
}

IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map,
                          bool resolve_vars,
                          lldb_private::IRExecutionUnit &execution_unit,
                          lldb_private::Stream *error_stream,
                          const char *func_name) :
    ModulePass(ID),
    m_resolve_vars(resolve_vars),
    m_func_name(func_name),
    m_module(NULL),
    m_decl_map(decl_map),
    m_data_allocator(execution_unit),
    m_CFStringCreateWithBytes(NULL),
    m_sel_registerName(NULL),
    m_intptr_ty(NULL),
    m_error_stream(error_stream),
    m_result_store(NULL),
    m_result_is_pointer(false),
    m_reloc_placeholder(NULL),
    m_entry_instruction_finder (FindEntryInstruction)
{
}

/* Handy utility functions used at several places in the code */

static std::string
PrintValue(const Value *value, bool truncate = false)
{
    std::string s;
    if (value)
    {
        raw_string_ostream rso(s);
        value->print(rso);
        rso.flush();
        if (truncate)
            s.resize(s.length() - 1);
    }
    return s;
}

static std::string
PrintType(const llvm::Type *type, bool truncate = false)
{
    std::string s;
    raw_string_ostream rso(s);
    type->print(rso);
    rso.flush();
    if (truncate)
        s.resize(s.length() - 1);
    return s;
}

IRForTarget::~IRForTarget()
{
}

bool
IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function)
{
    llvm_function.setLinkage(GlobalValue::ExternalLinkage);

    std::string name = llvm_function.getName().str();

    return true;
}

IRForTarget::LookupResult
IRForTarget::GetFunctionAddress (llvm::Function *fun,
                                 uint64_t &fun_addr,
                                 lldb_private::ConstString &name,
                                 Constant **&value_ptr)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    fun_addr = LLDB_INVALID_ADDRESS;
    name.Clear();
    value_ptr = NULL;

    if (fun->isIntrinsic())
    {
        Intrinsic::ID intrinsic_id = (Intrinsic::ID)fun->getIntrinsicID();

        switch (intrinsic_id)
        {
        default:
            if (log)
                log->Printf("Unresolved intrinsic \"%s\"", Intrinsic::getName(intrinsic_id).c_str());

            if (m_error_stream)
                m_error_stream->Printf("Internal error [IRForTarget]: Call to unhandled compiler intrinsic '%s'\n", Intrinsic::getName(intrinsic_id).c_str());

            return LookupResult::Fail;
        case Intrinsic::memcpy:
            {
                static lldb_private::ConstString g_memcpy_str ("memcpy");
                name = g_memcpy_str;
            }
            break;
        case Intrinsic::memset:
            {
                static lldb_private::ConstString g_memset_str ("memset");
                name = g_memset_str;
            }
            break;
        case Intrinsic::dbg_declare:
        case Intrinsic::dbg_value:
            return LookupResult::Ignore;
        }

        if (log && name)
            log->Printf("Resolved intrinsic name \"%s\"", name.GetCString());
    }
    else
    {
        name.SetCStringWithLength (fun->getName().data(), fun->getName().size());
    }

    // Find the address of the function.

    clang::NamedDecl *fun_decl = DeclForGlobal (fun);

    if (fun_decl)
    {
        if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr))
        {
            lldb_private::ConstString altnernate_name;
            bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr);
            if (!found_it)
            {
                // Check for an alternate mangling for "std::basic_string<char>"
                // that is part of the itanium C++ name mangling scheme
                const char *name_cstr = name.GetCString();
                if (name_cstr && strncmp(name_cstr, "_ZNKSbIcE", strlen("_ZNKSbIcE")) == 0)
                {
                    std::string alternate_mangling("_ZNKSs");
                    alternate_mangling.append (name_cstr + strlen("_ZNKSbIcE"));
                    altnernate_name.SetCString(alternate_mangling.c_str());
                    found_it = m_decl_map->GetFunctionAddress (altnernate_name, fun_addr);
                }
            }

            if (!found_it)
            {
                lldb_private::Mangled mangled_name(name);
                lldb_private::Mangled alt_mangled_name(altnernate_name);
                if (log)
                {
                    if (alt_mangled_name)
                        log->Printf("Function \"%s\" (alternate name \"%s\") has no address",
                                    mangled_name.GetName().GetCString(),
                                    alt_mangled_name.GetName().GetCString());
                    else
                        log->Printf("Function \"%s\" had no address",
                                    mangled_name.GetName().GetCString());
                }

                if (m_error_stream)
                {
                    if (alt_mangled_name)
                        m_error_stream->Printf("error: call to a function '%s' (alternate name '%s') that is not present in the target\n",
                                               mangled_name.GetName().GetCString(),
                                               alt_mangled_name.GetName().GetCString());
                    else if (mangled_name.GetMangledName())
                        m_error_stream->Printf("error: call to a function '%s' ('%s') that is not present in the target\n",
                                               mangled_name.GetName().GetCString(),
                                               mangled_name.GetMangledName().GetCString());
                    else
                        m_error_stream->Printf("error: call to a function '%s' that is not present in the target\n",
                                               mangled_name.GetName().GetCString());
                }
                return LookupResult::Fail;
            }
        }
    }
    else
    {
        if (!m_decl_map->GetFunctionAddress (name, fun_addr))
        {
            if (log)
                log->Printf ("Metadataless function \"%s\" had no address", name.GetCString());

            if (m_error_stream)
                m_error_stream->Printf("Error [IRForTarget]: Call to a symbol-only function '%s' that is not present in the target\n", name.GetCString());

            return LookupResult::Fail;
        }
    }

    if (log)
        log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), fun_addr);

    return LookupResult::Success;
}

llvm::Constant *
IRForTarget::BuildFunctionPointer (llvm::Type *type,
                                   uint64_t ptr)
{
    PointerType *fun_ptr_ty = PointerType::getUnqual(type);
    Constant *fun_addr_int = ConstantInt::get(m_intptr_ty, ptr, false);
    return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
}

void
IRForTarget::RegisterFunctionMetadata(LLVMContext &context,
                                      llvm::Value *function_ptr,
                                      const char *name)
{
    for (llvm::User *user : function_ptr->users())
    {
        if (Instruction *user_inst = dyn_cast<Instruction>(user))
        {
            MDString* md_name = MDString::get(context, StringRef(name));

            MDNode *metadata = MDNode::get(context, md_name);

            user_inst->setMetadata("lldb.call.realName", metadata);
        }
        else
        {
            RegisterFunctionMetadata (context, user, name);
        }
    }
}

bool
IRForTarget::ResolveFunctionPointers(llvm::Module &llvm_module)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    for (llvm::Module::iterator fi = llvm_module.begin();
         fi != llvm_module.end();
         ++fi)
    {
        Function *fun = fi;

        bool is_decl = fun->isDeclaration();

        if (log)
            log->Printf("Examining %s function %s", (is_decl ? "declaration" : "non-declaration"), fun->getName().str().c_str());

        if (!is_decl)
            continue;

        if (fun->use_empty())
            continue; // ignore

        uint64_t addr = LLDB_INVALID_ADDRESS;
        lldb_private::ConstString name;
        Constant **value_ptr = NULL;

        LookupResult result = GetFunctionAddress(fun,
                                                 addr,
                                                 name,
                                                 value_ptr);

        switch (result)
        {
        case LookupResult::Fail:
            return false; // GetFunctionAddress reports its own errors

        case LookupResult::Ignore:
            break; // Nothing to do

        case LookupResult::Success:
            {
                Constant *value = BuildFunctionPointer(fun->getFunctionType(), addr);

                RegisterFunctionMetadata (llvm_module.getContext(), fun, name.AsCString());

                if (value_ptr)
                    *value_ptr = value;

                // If we are replacing a function with the nobuiltin attribute, it may
                // be called with the builtin attribute on call sites. Remove any such
                // attributes since it's illegal to have a builtin call to something
                // other than a nobuiltin function.
                if (fun->hasFnAttribute(llvm::Attribute::NoBuiltin)) {
                    llvm::Attribute builtin = llvm::Attribute::get(fun->getContext(), llvm::Attribute::Builtin);

                    for (auto u : fun->users()) {
                        if (auto call = dyn_cast<CallInst>(u)) {
                            call->removeAttribute(AttributeSet::FunctionIndex, builtin);
                        }
                    }
                }

                fun->replaceAllUsesWith(value);
            }
            break;
        }
    }

    return true;
}


clang::NamedDecl *
IRForTarget::DeclForGlobal (const GlobalValue *global_val, Module *module)
{
    NamedMDNode *named_metadata = module->getNamedMetadata("clang.global.decl.ptrs");

    if (!named_metadata)
        return NULL;

    unsigned num_nodes = named_metadata->getNumOperands();
    unsigned node_index;

    for (node_index = 0;
         node_index < num_nodes;
         ++node_index)
    {
        llvm::MDNode *metadata_node = dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
        if (!metadata_node)
            return NULL;

        if (metadata_node->getNumOperands() != 2)
            continue;

        if (mdconst::dyn_extract_or_null<GlobalValue>(metadata_node->getOperand(0)) != global_val)
            continue;

        ConstantInt *constant_int = mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));

        if (!constant_int)
            return NULL;

        uintptr_t ptr = constant_int->getZExtValue();

        return reinterpret_cast<clang::NamedDecl *>(ptr);
    }

    return NULL;
}

clang::NamedDecl *
IRForTarget::DeclForGlobal (GlobalValue *global_val)
{
    return DeclForGlobal(global_val, m_module);
}

bool
IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    if (!m_resolve_vars)
        return true;

    // Find the result variable.  If it doesn't exist, we can give up right here.

    ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();

    std::string result_name_str;
    const char *result_name = NULL;

    for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
         vi != ve;
         ++vi)
    {
        result_name_str = vi->first().str();
        const char *value_name = result_name_str.c_str();

        if (strstr(value_name, "$__lldb_expr_result_ptr") &&
            strncmp(value_name, "_ZGV", 4))
        {
            result_name = value_name;
            m_result_is_pointer = true;
            break;
        }

        if (strstr(value_name, "$__lldb_expr_result") &&
            strncmp(value_name, "_ZGV", 4))
        {
            result_name = value_name;
            m_result_is_pointer = false;
            break;
        }
    }

    if (!result_name)
    {
        if (log)
            log->PutCString("Couldn't find result variable");

        return true;
    }

    if (log)
        log->Printf("Result name: \"%s\"", result_name);

    Value *result_value = m_module->getNamedValue(result_name);

    if (!result_value)
    {
        if (log)
            log->PutCString("Result variable had no data");

        if (m_error_stream)
            m_error_stream->Printf("Internal error [IRForTarget]: Result variable's name (%s) exists, but not its definition\n", result_name);

        return false;
    }

    if (log)
        log->Printf("Found result in the IR: \"%s\"", PrintValue(result_value, false).c_str());

    GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);

    if (!result_global)
    {
        if (log)
            log->PutCString("Result variable isn't a GlobalVariable");

        if (m_error_stream)
            m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) is defined, but is not a global variable\n", result_name);

        return false;
    }

    clang::NamedDecl *result_decl = DeclForGlobal (result_global);
    if (!result_decl)
    {
        if (log)
            log->PutCString("Result variable doesn't have a corresponding Decl");

        if (m_error_stream)
            m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) does not have a corresponding Clang entity\n", result_name);

        return false;
    }

    if (log)
    {
        std::string decl_desc_str;
        raw_string_ostream decl_desc_stream(decl_desc_str);
        result_decl->print(decl_desc_stream);
        decl_desc_stream.flush();

        log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str());
    }

    clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
    if (!result_var)
    {
        if (log)
            log->PutCString("Result variable Decl isn't a VarDecl");

        if (m_error_stream)
            m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s)'s corresponding Clang entity isn't a variable\n", result_name);

        return false;
    }

    // Get the next available result name from m_decl_map and create the persistent
    // variable for it

    // If the result is an Lvalue, it is emitted as a pointer; see
    // ASTResultSynthesizer::SynthesizeBodyResult.
    if (m_result_is_pointer)
    {
        clang::QualType pointer_qual_type = result_var->getType();
        const clang::Type *pointer_type = pointer_qual_type.getTypePtr();

        const clang::PointerType *pointer_pointertype = pointer_type->getAs<clang::PointerType>();
        const clang::ObjCObjectPointerType *pointer_objcobjpointertype = pointer_type->getAs<clang::ObjCObjectPointerType>();

        if (pointer_pointertype)
        {
            clang::QualType element_qual_type = pointer_pointertype->getPointeeType();

            m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
                                                         &result_decl->getASTContext());
        }
        else if (pointer_objcobjpointertype)
        {
            clang::QualType element_qual_type = clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);

            m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
                                                         &result_decl->getASTContext());
        }
        else
        {
            if (log)
                log->PutCString("Expected result to have pointer type, but it did not");

            if (m_error_stream)
                m_error_stream->Printf("Internal error [IRForTarget]: Lvalue result (%s) is not a pointer variable\n", result_name);

            return false;
        }
    }
    else
    {
        m_result_type = lldb_private::TypeFromParser(result_var->getType().getAsOpaquePtr(),
                                                     &result_decl->getASTContext());
    }

    if (m_result_type.GetBitSize(nullptr) == 0)
    {
        lldb_private::StreamString type_desc_stream;
        m_result_type.DumpTypeDescription(&type_desc_stream);

        if (log)
            log->Printf("Result type has size 0");

        if (m_error_stream)
            m_error_stream->Printf("Error [IRForTarget]: Size of result type '%s' couldn't be determined\n",
                                   type_desc_stream.GetData());
        return false;
    }

    if (log)
    {
        lldb_private::StreamString type_desc_stream;
        m_result_type.DumpTypeDescription(&type_desc_stream);

        log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
    }

    m_result_name = lldb_private::ConstString("$RESULT_NAME");

    if (log)
        log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
                    m_result_name.GetCString(),
                    m_result_type.GetByteSize(nullptr));

    // Construct a new result global and set up its metadata

    GlobalVariable *new_result_global = new GlobalVariable((*m_module),
                                                           result_global->getType()->getElementType(),
                                                           false, /* not constant */
                                                           GlobalValue::ExternalLinkage,
                                                           NULL, /* no initializer */
                                                           m_result_name.GetCString ());

    // It's too late in compilation to create a new VarDecl for this, but we don't
    // need to.  We point the metadata at the old VarDecl.  This creates an odd
    // anomaly: a variable with a Value whose name is something like $0 and a
    // Decl whose name is $__lldb_expr_result.  This condition is handled in
    // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
    // fixed up.

    ConstantInt *new_constant_int = ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
                                                     reinterpret_cast<uint64_t>(result_decl),
                                                     false);

    llvm::Metadata *values[2];
    values[0] = ConstantAsMetadata::get(new_result_global);
    values[1] = ConstantAsMetadata::get(new_constant_int);

    ArrayRef<Metadata *> value_ref(values, 2);

    MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
    NamedMDNode *named_metadata = m_module->getNamedMetadata("clang.global.decl.ptrs");
    named_metadata->addOperand(persistent_global_md);

    if (log)
        log->Printf("Replacing \"%s\" with \"%s\"",
                    PrintValue(result_global).c_str(),
                    PrintValue(new_result_global).c_str());

    if (result_global->use_empty())
    {
        // We need to synthesize a store for this variable, because otherwise
        // there's nothing to put into its equivalent persistent variable.

        BasicBlock &entry_block(llvm_function.getEntryBlock());
        Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());

        if (!first_entry_instruction)
            return false;

        if (!result_global->hasInitializer())
        {
            if (log)
                log->Printf("Couldn't find initializer for unused variable");

            if (m_error_stream)
                m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) has no writes and no initializer\n", result_name);

            return false;
        }

        Constant *initializer = result_global->getInitializer();

        StoreInst *synthesized_store = new StoreInst(initializer,
                                                     new_result_global,
                                                     first_entry_instruction);

        if (log)
            log->Printf("Synthesized result store \"%s\"\n", PrintValue(synthesized_store).c_str());
    }
    else
    {
        result_global->replaceAllUsesWith(new_result_global);
    }

    if (!m_decl_map->AddPersistentVariable(result_decl,
                                           m_result_name,
                                           m_result_type,
                                           true,
                                           m_result_is_pointer))
        return false;

    result_global->eraseFromParent();

    return true;
}

bool
IRForTarget::RewriteObjCConstString (llvm::GlobalVariable *ns_str,
                                     llvm::GlobalVariable *cstr)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    Type *ns_str_ty = ns_str->getType();

    Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
    Type *i32_ty = Type::getInt32Ty(m_module->getContext());
    Type *i8_ty = Type::getInt8Ty(m_module->getContext());

    if (!m_CFStringCreateWithBytes)
    {
        lldb::addr_t CFStringCreateWithBytes_addr;

        static lldb_private::ConstString g_CFStringCreateWithBytes_str ("CFStringCreateWithBytes");

        if (!m_decl_map->GetFunctionAddress (g_CFStringCreateWithBytes_str, CFStringCreateWithBytes_addr))
        {
            if (log)
                log->PutCString("Couldn't find CFStringCreateWithBytes in the target");

            if (m_error_stream)
                m_error_stream->Printf("Error [IRForTarget]: Rewriting an Objective-C constant string requires CFStringCreateWithBytes\n");

            return false;
        }

        if (log)
            log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64, CFStringCreateWithBytes_addr);

        // Build the function type:
        //
        // CFStringRef CFStringCreateWithBytes (
        //   CFAllocatorRef alloc,
        //   const UInt8 *bytes,
        //   CFIndex numBytes,
        //   CFStringEncoding encoding,
        //   Boolean isExternalRepresentation
        // );
        //
        // We make the following substitutions:
        //
        // CFStringRef -> i8*
        // CFAllocatorRef -> i8*
        // UInt8 * -> i8*
        // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its pointer size for now)
        // CFStringEncoding -> i32
        // Boolean -> i8

        Type *arg_type_array[5];

        arg_type_array[0] = i8_ptr_ty;
        arg_type_array[1] = i8_ptr_ty;
        arg_type_array[2] = m_intptr_ty;
        arg_type_array[3] = i32_ty;
        arg_type_array[4] = i8_ty;

        ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);

        llvm::Type *CFSCWB_ty = FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);

        // Build the constant containing the pointer to the function
        PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
        Constant *CFSCWB_addr_int = ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);
        m_CFStringCreateWithBytes = ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty);
    }

    ConstantDataSequential *string_array = NULL;

    if (cstr)
        string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());

    Constant *alloc_arg         = Constant::getNullValue(i8_ptr_ty);
    Constant *bytes_arg         = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty) : Constant::getNullValue(i8_ptr_ty);
    Constant *numBytes_arg      = ConstantInt::get(m_intptr_ty, cstr ? string_array->getNumElements() - 1 : 0, false);
    Constant *encoding_arg      = ConstantInt::get(i32_ty, 0x0600, false); /* 0x0600 is kCFStringEncodingASCII */
    Constant *isExternal_arg    = ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */

    Value *argument_array[5];

    argument_array[0] = alloc_arg;
    argument_array[1] = bytes_arg;
    argument_array[2] = numBytes_arg;
    argument_array[3] = encoding_arg;
    argument_array[4] = isExternal_arg;

    ArrayRef <Value *> CFSCWB_arguments(argument_array, 5);

    FunctionValueCache CFSCWB_Caller ([this, &CFSCWB_arguments] (llvm::Function *function)->llvm::Value * {
        return CallInst::Create(m_CFStringCreateWithBytes,
                                CFSCWB_arguments,
                                "CFStringCreateWithBytes",
                                llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function)));
    });

    if (!UnfoldConstant(ns_str, CFSCWB_Caller, m_entry_instruction_finder))
    {
        if (log)
            log->PutCString("Couldn't replace the NSString with the result of the call");

        if (m_error_stream)
            m_error_stream->Printf("Error [IRForTarget]: Couldn't replace an Objective-C constant string with a dynamic string\n");

        return false;
    }

    ns_str->eraseFromParent();

    return true;
}

bool
IRForTarget::RewriteObjCConstStrings()
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();

    for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
         vi != ve;
         ++vi)
    {
        std::string value_name = vi->first().str();
        const char *value_name_cstr = value_name.c_str();

        if (strstr(value_name_cstr, "_unnamed_cfstring_"))
        {
            Value *nsstring_value = vi->second;

            GlobalVariable *nsstring_global = dyn_cast<GlobalVariable>(nsstring_value);

            if (!nsstring_global)
            {
                if (log)
                    log->PutCString("NSString variable is not a GlobalVariable");

                if (m_error_stream)
                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string is not a global variable\n");

                return false;
            }

            if (!nsstring_global->hasInitializer())
            {
                if (log)
                    log->PutCString("NSString variable does not have an initializer");

                if (m_error_stream)
                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string does not have an initializer\n");

                return false;
            }

            ConstantStruct *nsstring_struct = dyn_cast<ConstantStruct>(nsstring_global->getInitializer());

            if (!nsstring_struct)
            {
                if (log)
                    log->PutCString("NSString variable's initializer is not a ConstantStruct");

                if (m_error_stream)
                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string is not a structure constant\n");

                return false;
            }

            // We expect the following structure:
            //
            // struct {
            //   int *isa;
            //   int flags;
            //   char *str;
            //   long length;
            // };

            if (nsstring_struct->getNumOperands() != 4)
            {
                if (log)
                    log->Printf("NSString variable's initializer structure has an unexpected number of members.  Should be 4, is %d", nsstring_struct->getNumOperands());

                if (m_error_stream)
                    m_error_stream->Printf("Internal error [IRForTarget]: The struct for an Objective-C constant string is not as expected\n");

                return false;
            }

            Constant *nsstring_member = nsstring_struct->getOperand(2);

            if (!nsstring_member)
            {
                if (log)
                    log->PutCString("NSString initializer's str element was empty");

                if (m_error_stream)
                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string does not have a string initializer\n");

                return false;
            }

            ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);

            if (!nsstring_expr)
            {
                if (log)
                    log->PutCString("NSString initializer's str element is not a ConstantExpr");

                if (m_error_stream)
                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not constant\n");

                return false;
            }

            if (nsstring_expr->getOpcode() != Instruction::GetElementPtr)
            {
                if (log)
                    log->Printf("NSString initializer's str element is not a GetElementPtr expression, it's a %s", nsstring_expr->getOpcodeName());

                if (m_error_stream)
                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not an array\n");

                return false;
            }

            Constant *nsstring_cstr = nsstring_expr->getOperand(0);

            GlobalVariable *cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);

            if (!cstr_global)
            {
                if (log)
                    log->PutCString("NSString initializer's str element is not a GlobalVariable");

                if (m_error_stream)
                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to a global\n");

                return false;
            }

            if (!cstr_global->hasInitializer())
            {
                if (log)
                    log->PutCString("NSString initializer's str element does not have an initializer");

                if (m_error_stream)
                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to initialized data\n");

                return false;
            }

            /*
            if (!cstr_array)
            {
                if (log)
                    log->PutCString("NSString initializer's str element is not a ConstantArray");

                if (m_error_stream)
                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to an array\n");

                return false;
            }

            if (!cstr_array->isCString())
            {
                if (log)
                    log->PutCString("NSString initializer's str element is not a C string array");

                if (m_error_stream)
                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to a C string\n");

                return false;
            }
            */

            ConstantDataArray *cstr_array = dyn_cast<ConstantDataArray>(cstr_global->getInitializer());

            if (log)
            {
                if (cstr_array)
                    log->Printf("Found NSString constant %s, which contains \"%s\"", value_name_cstr, cstr_array->getAsString().str().c_str());
                else
                    log->Printf("Found NSString constant %s, which contains \"\"", value_name_cstr);
            }

            if (!cstr_array)
                cstr_global = NULL;

            if (!RewriteObjCConstString(nsstring_global, cstr_global))
            {
                if (log)
                    log->PutCString("Error rewriting the constant string");

                // We don't print an error message here because RewriteObjCConstString has done so for us.

                return false;
            }
        }
    }

    for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
         vi != ve;
         ++vi)
    {
        std::string value_name = vi->first().str();
        const char *value_name_cstr = value_name.c_str();

        if (!strcmp(value_name_cstr, "__CFConstantStringClassReference"))
        {
            GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second);

            if (!gv)
            {
                if (log)
                    log->PutCString("__CFConstantStringClassReference is not a global variable");

                if (m_error_stream)
                    m_error_stream->Printf("Internal error [IRForTarget]: Found a CFConstantStringClassReference, but it is not a global object\n");

                return false;
            }

            gv->eraseFromParent();

            break;
        }
    }

    return true;
}

static bool IsObjCSelectorRef (Value *value)
{
    GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);

    if (!global_variable || !global_variable->hasName() || !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"))
        return false;

    return true;
}

// This function does not report errors; its callers are responsible.
bool
IRForTarget::RewriteObjCSelector (Instruction* selector_load)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    LoadInst *load = dyn_cast<LoadInst>(selector_load);

    if (!load)
        return false;

    // Unpack the message name from the selector.  In LLVM IR, an objc_msgSend gets represented as
    //
    // %tmp     = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*>
    // %call    = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*>
    //
    // where %obj is the object pointer and %tmp is the selector.
    //
    // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
    // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.

    // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) and get the string from its target

    GlobalVariable *_objc_selector_references_ = dyn_cast<GlobalVariable>(load->getPointerOperand());

    if (!_objc_selector_references_ || !_objc_selector_references_->hasInitializer())
        return false;

    Constant *osr_initializer = _objc_selector_references_->getInitializer();

    ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);

    if (!osr_initializer_expr || osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
        return false;

    Value *osr_initializer_base = osr_initializer_expr->getOperand(0);

    if (!osr_initializer_base)
        return false;

    // Find the string's initializer (a ConstantArray) and get the string from it

    GlobalVariable *_objc_meth_var_name_ = dyn_cast<GlobalVariable>(osr_initializer_base);

    if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
        return false;

    Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();

    ConstantDataArray *omvn_initializer_array = dyn_cast<ConstantDataArray>(omvn_initializer);

    if (!omvn_initializer_array->isString())
        return false;

    std::string omvn_initializer_string = omvn_initializer_array->getAsString();

    if (log)
        log->Printf("Found Objective-C selector reference \"%s\"", omvn_initializer_string.c_str());

    // Construct a call to sel_registerName

    if (!m_sel_registerName)
    {
        lldb::addr_t sel_registerName_addr;

        static lldb_private::ConstString g_sel_registerName_str ("sel_registerName");
        if (!m_decl_map->GetFunctionAddress (g_sel_registerName_str, sel_registerName_addr))
            return false;

        if (log)
            log->Printf("Found sel_registerName at 0x%" PRIx64, sel_registerName_addr);

        // Build the function type: struct objc_selector *sel_registerName(uint8_t*)

        // The below code would be "more correct," but in actuality what's required is uint8_t*
        //Type *sel_type = StructType::get(m_module->getContext());
        //Type *sel_ptr_type = PointerType::getUnqual(sel_type);
        Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());

        Type *type_array[1];

        type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());

        ArrayRef<Type *> srN_arg_types(type_array, 1);

        llvm::Type *srN_type = FunctionType::get(sel_ptr_type, srN_arg_types, false);

        // Build the constant containing the pointer to the function
        PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
        Constant *srN_addr_int = ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
        m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty);
    }

    Value *argument_array[1];

    Constant *omvn_pointer = ConstantExpr::getBitCast(_objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));

    argument_array[0] = omvn_pointer;

    ArrayRef<Value *> srN_arguments(argument_array, 1);

    CallInst *srN_call = CallInst::Create(m_sel_registerName,
                                          srN_arguments,
                                          "sel_registerName",
                                          selector_load);

    // Replace the load with the call in all users

    selector_load->replaceAllUsesWith(srN_call);

    selector_load->eraseFromParent();

    return true;
}

bool
IRForTarget::RewriteObjCSelectors (BasicBlock &basic_block)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    BasicBlock::iterator ii;

    typedef SmallVector <Instruction*, 2> InstrList;
    typedef InstrList::iterator InstrIterator;

    InstrList selector_loads;

    for (ii = basic_block.begin();
         ii != basic_block.end();
         ++ii)
    {
        Instruction &inst = *ii;

        if (LoadInst *load = dyn_cast<LoadInst>(&inst))
            if (IsObjCSelectorRef(load->getPointerOperand()))
                selector_loads.push_back(&inst);
    }

    InstrIterator iter;

    for (iter = selector_loads.begin();
         iter != selector_loads.end();
         ++iter)
    {
        if (!RewriteObjCSelector(*iter))
        {
            if (m_error_stream)
                m_error_stream->Printf("Internal error [IRForTarget]: Couldn't change a static reference to an Objective-C selector to a dynamic reference\n");

            if (log)
                log->PutCString("Couldn't rewrite a reference to an Objective-C selector");

            return false;
        }
    }

    return true;
}

// This function does not report errors; its callers are responsible.
bool
IRForTarget::RewritePersistentAlloc (llvm::Instruction *persistent_alloc)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);

    MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");

    if (!alloc_md || !alloc_md->getNumOperands())
        return false;

    ConstantInt *constant_int = mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));

    if (!constant_int)
        return false;

    // We attempt to register this as a new persistent variable with the DeclMap.

    uintptr_t ptr = constant_int->getZExtValue();

    clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);

    lldb_private::TypeFromParser result_decl_type (decl->getType().getAsOpaquePtr(),
                                                   &decl->getASTContext());

    StringRef decl_name (decl->getName());
    lldb_private::ConstString persistent_variable_name (decl_name.data(), decl_name.size());
    if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name, result_decl_type, false, false))
        return false;

    GlobalVariable *persistent_global = new GlobalVariable((*m_module),
                                                           alloc->getType(),
                                                           false, /* not constant */
                                                           GlobalValue::ExternalLinkage,
                                                           NULL, /* no initializer */
                                                           alloc->getName().str().c_str());

    // What we're going to do here is make believe this was a regular old external
    // variable.  That means we need to make the metadata valid.

    NamedMDNode *named_metadata = m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");

    llvm::Metadata *values[2];
    values[0] = ConstantAsMetadata::get(persistent_global);
    values[1] = ConstantAsMetadata::get(constant_int);

    ArrayRef<llvm::Metadata *> value_ref(values, 2);

    MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
    named_metadata->addOperand(persistent_global_md);

    // Now, since the variable is a pointer variable, we will drop in a load of that
    // pointer variable.

    LoadInst *persistent_load = new LoadInst (persistent_global, "", alloc);

    if (log)
        log->Printf("Replacing \"%s\" with \"%s\"",
                    PrintValue(alloc).c_str(),
                    PrintValue(persistent_load).c_str());

    alloc->replaceAllUsesWith(persistent_load);
    alloc->eraseFromParent();

    return true;
}

bool
IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block)
{
    if (!m_resolve_vars)
        return true;

    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    BasicBlock::iterator ii;

    typedef SmallVector <Instruction*, 2> InstrList;
    typedef InstrList::iterator InstrIterator;

    InstrList pvar_allocs;

    for (ii = basic_block.begin();
         ii != basic_block.end();
         ++ii)
    {
        Instruction &inst = *ii;

        if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst))
        {
            llvm::StringRef alloc_name = alloc->getName();

            if (alloc_name.startswith("$") &&
                !alloc_name.startswith("$__lldb"))
            {
                if (alloc_name.find_first_of("0123456789") == 1)
                {
                    if (log)
                        log->Printf("Rejecting a numeric persistent variable.");

                    if (m_error_stream)
                        m_error_stream->Printf("Error [IRForTarget]: Names starting with $0, $1, ... are reserved for use as result names\n");

                    return false;
                }

                pvar_allocs.push_back(alloc);
            }
        }
    }

    InstrIterator iter;

    for (iter = pvar_allocs.begin();
         iter != pvar_allocs.end();
         ++iter)
    {
        if (!RewritePersistentAlloc(*iter))
        {
            if (m_error_stream)
                m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite the creation of a persistent variable\n");

            if (log)
                log->PutCString("Couldn't rewrite the creation of a persistent variable");

            return false;
        }
    }

    return true;
}

bool
IRForTarget::MaterializeInitializer (uint8_t *data, Constant *initializer)
{
    if (!initializer)
        return true;

    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    if (log && log->GetVerbose())
        log->Printf("  MaterializeInitializer(%p, %s)", data, PrintValue(initializer).c_str());

    Type *initializer_type = initializer->getType();

    if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer))
    {
        memcpy (data, int_initializer->getValue().getRawData(), m_target_data->getTypeStoreSize(initializer_type));
        return true;
    }
    else if (ConstantDataArray *array_initializer = dyn_cast<ConstantDataArray>(initializer))
    {
        if (array_initializer->isString())
        {
            std::string array_initializer_string = array_initializer->getAsString();
            memcpy (data, array_initializer_string.c_str(), m_target_data->getTypeStoreSize(initializer_type));
        }
        else
        {
            ArrayType *array_initializer_type = array_initializer->getType();
            Type *array_element_type = array_initializer_type->getElementType();

            size_t element_size = m_target_data->getTypeAllocSize(array_element_type);

            for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i)
            {
                Value *operand_value = array_initializer->getOperand(i);
                Constant *operand_constant = dyn_cast<Constant>(operand_value);

                if (!operand_constant)
                    return false;

                if (!MaterializeInitializer(data + (i * element_size), operand_constant))
                    return false;
            }
        }
        return true;
    }
    else if (ConstantStruct *struct_initializer = dyn_cast<ConstantStruct>(initializer))
    {
        StructType *struct_initializer_type = struct_initializer->getType();
        const StructLayout *struct_layout = m_target_data->getStructLayout(struct_initializer_type);

        for (unsigned i = 0;
             i < struct_initializer->getNumOperands();
             ++i)
        {
            if (!MaterializeInitializer(data + struct_layout->getElementOffset(i), struct_initializer->getOperand(i)))
                return false;
        }
        return true;
    }
    else if (isa<ConstantAggregateZero>(initializer))
    {
        memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
        return true;
    }
    return false;
}

bool
IRForTarget::MaterializeInternalVariable (GlobalVariable *global_variable)
{
    if (GlobalVariable::isExternalLinkage(global_variable->getLinkage()))
        return false;

    if (global_variable == m_reloc_placeholder)
        return true;

    uint64_t offset = m_data_allocator.GetStream().GetSize();

    llvm::Type *variable_type = global_variable->getType();

    Constant *initializer = global_variable->getInitializer();

    llvm::Type *initializer_type = initializer->getType();

    size_t size = m_target_data->getTypeAllocSize(initializer_type);
    size_t align = m_target_data->getPrefTypeAlignment(initializer_type);

    const size_t mask = (align - 1);
    uint64_t aligned_offset = (offset + mask) & ~mask;
    m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);
    offset = aligned_offset;

    lldb_private::DataBufferHeap data(size, '\0');

    if (initializer)
        if (!MaterializeInitializer(data.GetBytes(), initializer))
            return false;

    m_data_allocator.GetStream().Write(data.GetBytes(), data.GetByteSize());

    Constant *new_pointer = BuildRelocation(variable_type, offset);

    global_variable->replaceAllUsesWith(new_pointer);

    global_variable->eraseFromParent();

    return true;
}

// This function does not report errors; its callers are responsible.
bool
IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    if (log)
        log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());

    if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr))
    {
        switch (constant_expr->getOpcode())
        {
        default:
            break;
        case Instruction::GetElementPtr:
        case Instruction::BitCast:
            Value *s = constant_expr->getOperand(0);
            if (!MaybeHandleVariable(s))
                return false;
        }
    }
    else if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(llvm_value_ptr))
    {
        if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
            return MaterializeInternalVariable(global_variable);

        clang::NamedDecl *named_decl = DeclForGlobal(global_variable);

        if (!named_decl)
        {
            if (IsObjCSelectorRef(llvm_value_ptr))
                return true;

            if (!global_variable->hasExternalLinkage())
                return true;

            if (log)
                log->Printf("Found global variable \"%s\" without metadata", global_variable->getName().str().c_str());

            return false;
        }

        std::string name (named_decl->getName().str());

        clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
        if (value_decl == NULL)
            return false;

        lldb_private::ClangASTType clang_type(&value_decl->getASTContext(), value_decl->getType());

        const Type *value_type = NULL;

        if (name[0] == '$')
        {
            // The $__lldb_expr_result name indicates the the return value has allocated as
            // a static variable.  Per the comment at ASTResultSynthesizer::SynthesizeBodyResult,
            // accesses to this static variable need to be redirected to the result of dereferencing
            // a pointer that is passed in as one of the arguments.
            //
            // Consequently, when reporting the size of the type, we report a pointer type pointing
            // to the type of $__lldb_expr_result, not the type itself.
            //
            // We also do this for any user-declared persistent variables.
            clang_type = clang_type.GetPointerType();
            value_type = PointerType::get(global_variable->getType(), 0);
        }
        else
        {
            value_type = global_variable->getType();
        }

        const uint64_t value_size = clang_type.GetByteSize(nullptr);
        lldb::offset_t value_alignment = (clang_type.GetTypeBitAlign() + 7ull) / 8ull;

        if (log)
        {
            log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRIu64 "]",
                        name.c_str(),
                        clang_type.GetQualType().getAsString().c_str(),
                        PrintType(value_type).c_str(),
                        value_size,
                        value_alignment);
        }


        if (named_decl && !m_decl_map->AddValueToStruct(named_decl,
                                                        lldb_private::ConstString (name.c_str()),
                                                        llvm_value_ptr,
                                                        value_size,
                                                        value_alignment))
        {
            if (!global_variable->hasExternalLinkage())
                return true;
            else if (HandleSymbol (global_variable))
                return true;
            else
                return false;
        }
    }
    else if (dyn_cast<llvm::Function>(llvm_value_ptr))
    {
        if (log)
            log->Printf("Function pointers aren't handled right now");

        return false;
    }

    return true;
}

// This function does not report errors; its callers are responsible.
bool
IRForTarget::HandleSymbol (Value *symbol)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    lldb_private::ConstString name(symbol->getName().str().c_str());

    lldb::addr_t symbol_addr = m_decl_map->GetSymbolAddress (name, lldb::eSymbolTypeAny);

    if (symbol_addr == LLDB_INVALID_ADDRESS)
    {
        if (log)
            log->Printf ("Symbol \"%s\" had no address", name.GetCString());

        return false;
    }

    if (log)
        log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);

    Type *symbol_type = symbol->getType();

    Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);

    Value *symbol_addr_ptr = ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);

    if (log)
        log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(), PrintValue(symbol_addr_ptr).c_str());

    symbol->replaceAllUsesWith(symbol_addr_ptr);

    return true;
}

bool
IRForTarget::MaybeHandleCallArguments (CallInst *Old)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    if (log)
        log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());

    for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
         op_index < num_ops;
         ++op_index)
        if (!MaybeHandleVariable(Old->getArgOperand(op_index))) // conservatively believe that this is a store
        {
            if (m_error_stream)
                m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite one of the arguments of a function call.\n");

            return false;
        }

    return true;
}

bool
IRForTarget::HandleObjCClass(Value *classlist_reference)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    GlobalVariable *global_variable = dyn_cast<GlobalVariable>(classlist_reference);

    if (!global_variable)
        return false;

    Constant *initializer = global_variable->getInitializer();

    if (!initializer)
        return false;

    if (!initializer->hasName())
        return false;

    StringRef name(initializer->getName());
    lldb_private::ConstString name_cstr(name.str().c_str());
    lldb::addr_t class_ptr = m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);

    if (log)
        log->Printf("Found reference to Objective-C class %s (0x%llx)", name_cstr.AsCString(), (unsigned long long)class_ptr);

    if (class_ptr == LLDB_INVALID_ADDRESS)
        return false;

    if (global_variable->use_empty())
        return false;

    SmallVector<LoadInst *, 2> load_instructions;

    for (llvm::User *u : global_variable->users())
    {
        if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
            load_instructions.push_back(load_instruction);
    }

    if (load_instructions.empty())
        return false;

    Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);

    for (LoadInst *load_instruction : load_instructions)
    {
        Constant *class_bitcast = ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());

        load_instruction->replaceAllUsesWith(class_bitcast);

        load_instruction->eraseFromParent();
    }

    return true;
}

bool
IRForTarget::RemoveCXAAtExit (BasicBlock &basic_block)
{
    BasicBlock::iterator ii;

    std::vector<CallInst *> calls_to_remove;

    for (ii = basic_block.begin();
         ii != basic_block.end();
         ++ii)
    {
        Instruction &inst = *ii;

        CallInst *call = dyn_cast<CallInst>(&inst);

        // MaybeHandleCallArguments handles error reporting; we are silent here
        if (!call)
            continue;

        bool remove = false;

        llvm::Function *func = call->getCalledFunction();

        if (func && func->getName() == "__cxa_atexit")
            remove = true;

        llvm::Value *val = call->getCalledValue();

        if (val && val->getName() == "__cxa_atexit")
            remove = true;

        if (remove)
            calls_to_remove.push_back(call);
    }

    for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(), ce = calls_to_remove.end();
         ci != ce;
         ++ci)
    {
        (*ci)->eraseFromParent();
    }

    return true;
}

bool
IRForTarget::ResolveCalls(BasicBlock &basic_block)
{
    /////////////////////////////////////////////////////////////////////////
    // Prepare the current basic block for execution in the remote process
    //

    BasicBlock::iterator ii;

    for (ii = basic_block.begin();
         ii != basic_block.end();
         ++ii)
    {
        Instruction &inst = *ii;

        CallInst *call = dyn_cast<CallInst>(&inst);

        // MaybeHandleCallArguments handles error reporting; we are silent here
        if (call && !MaybeHandleCallArguments(call))
            return false;
    }

    return true;
}

bool
IRForTarget::ResolveExternals (Function &llvm_function)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    for (GlobalVariable &global_var : m_module->globals())
    {
        std::string global_name = global_var.getName().str();

        if (log)
            log->Printf("Examining %s, DeclForGlobalValue returns %p",
                        global_name.c_str(),
                        static_cast<void*>(DeclForGlobal(&global_var)));

        if (global_name.find("OBJC_IVAR") == 0)
        {
            if (!HandleSymbol(&global_var))
            {
                if (m_error_stream)
                    m_error_stream->Printf("Error [IRForTarget]: Couldn't find Objective-C indirect ivar symbol %s\n", global_name.c_str());

                return false;
            }
        }
        else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") != global_name.npos)
        {
            if (!HandleObjCClass(&global_var))
            {
                if (m_error_stream)
                    m_error_stream->Printf("Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call\n");

                return false;
            }
        }
        else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") != global_name.npos)
        {
            if (!HandleObjCClass(&global_var))
            {
                if (m_error_stream)
                    m_error_stream->Printf("Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call\n");

                return false;
            }
        }
        else if (DeclForGlobal(&global_var))
        {
            if (!MaybeHandleVariable (&global_var))
            {
                if (m_error_stream)
                    m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite external variable %s\n", global_name.c_str());

                return false;
            }
        }
    }

    return true;
}

bool
IRForTarget::ReplaceStrings ()
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    typedef std::map <GlobalVariable *, size_t> OffsetsTy;

    OffsetsTy offsets;

    for (GlobalVariable &gv : m_module->globals())
    {
        if (!gv.hasInitializer())
            continue;

        Constant *gc = gv.getInitializer();

        std::string str;

        if (gc->isNullValue())
        {
            Type *gc_type = gc->getType();

            ArrayType *gc_array_type = dyn_cast<ArrayType>(gc_type);

            if (!gc_array_type)
                continue;

            Type *gc_element_type = gc_array_type->getElementType();

            IntegerType *gc_integer_type = dyn_cast<IntegerType>(gc_element_type);

            if (gc_integer_type->getBitWidth() != 8)
                continue;

            str = "";
        }
        else
        {
            ConstantDataArray *gc_array = dyn_cast<ConstantDataArray>(gc);

            if (!gc_array)
                continue;

            if (!gc_array->isCString())
                continue;

            if (log)
                log->Printf("Found a GlobalVariable with string initializer %s", PrintValue(gc).c_str());

            str = gc_array->getAsString();
        }

        offsets[&gv] = m_data_allocator.GetStream().GetSize();

        m_data_allocator.GetStream().Write(str.c_str(), str.length() + 1);
    }

    Type *char_ptr_ty = Type::getInt8PtrTy(m_module->getContext());

    for (OffsetsTy::iterator oi = offsets.begin(), oe = offsets.end();
         oi != oe;
         ++oi)
    {
        GlobalVariable *gv = oi->first;
        size_t offset = oi->second;

        Constant *new_initializer = BuildRelocation(char_ptr_ty, offset);

        if (log)
            log->Printf("Replacing GV %s with %s", PrintValue(gv).c_str(), PrintValue(new_initializer).c_str());

        for (llvm::User *u : gv->users())
        {
            if (log)
                log->Printf("Found use %s", PrintValue(u).c_str());

            ConstantExpr *const_expr = dyn_cast<ConstantExpr>(u);
            StoreInst *store_inst = dyn_cast<StoreInst>(u);

            if (const_expr)
            {
                if (const_expr->getOpcode() != Instruction::GetElementPtr)
                {
                    if (log)
                        log->Printf("Use (%s) of string variable is not a GetElementPtr constant", PrintValue(const_expr).c_str());

                    return false;
                }

                Constant *bit_cast = ConstantExpr::getBitCast(new_initializer, const_expr->getOperand(0)->getType());
                Constant *new_gep = const_expr->getWithOperandReplaced(0, bit_cast);

                const_expr->replaceAllUsesWith(new_gep);
            }
            else if (store_inst)
            {
                Constant *bit_cast = ConstantExpr::getBitCast(new_initializer, store_inst->getValueOperand()->getType());

                store_inst->setOperand(0, bit_cast);
            }
            else
            {
                if (log)
                    log->Printf("Use (%s) of string variable is neither a constant nor a store", PrintValue(const_expr).c_str());

                return false;
            }
        }

        gv->eraseFromParent();
    }

    return true;
}

bool
IRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    typedef SmallVector <Value*, 2> ConstantList;
    typedef SmallVector <llvm::Instruction*, 2> UserList;
    typedef ConstantList::iterator ConstantIterator;
    typedef UserList::iterator UserIterator;

    ConstantList static_constants;
    UserList static_users;

    for (BasicBlock::iterator ii = basic_block.begin(), ie = basic_block.end();
         ii != ie;
         ++ii)
    {
        llvm::Instruction &inst = *ii;

        for (Value *operand_val : inst.operand_values())
        {
            ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val);

            if (operand_constant_fp/* && operand_constant_fp->getType()->isX86_FP80Ty()*/)
            {
                static_constants.push_back(operand_val);
                static_users.push_back(ii);
            }
        }
    }

    ConstantIterator constant_iter;
    UserIterator user_iter;

    for (constant_iter = static_constants.begin(), user_iter = static_users.begin();
         constant_iter != static_constants.end();
         ++constant_iter, ++user_iter)
    {
        Value *operand_val = *constant_iter;
        llvm::Instruction *inst = *user_iter;

        ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val);

        if (operand_constant_fp)
        {
            Type *operand_type = operand_constant_fp->getType();

            APFloat operand_apfloat = operand_constant_fp->getValueAPF();
            APInt operand_apint = operand_apfloat.bitcastToAPInt();

            const uint8_t* operand_raw_data = (const uint8_t*)operand_apint.getRawData();
            size_t operand_data_size = operand_apint.getBitWidth() / 8;

            if (log)
            {
                std::string s;
                raw_string_ostream ss(s);
                for (size_t index = 0;
                     index < operand_data_size;
                     ++index)
                {
                    ss << (uint32_t)operand_raw_data[index];
                    ss << " ";
                }
                ss.flush();

                log->Printf("Found ConstantFP with size %" PRIu64 " and raw data %s", (uint64_t)operand_data_size, s.c_str());
            }

            lldb_private::DataBufferHeap data(operand_data_size, 0);

            if (lldb::endian::InlHostByteOrder() != m_data_allocator.GetStream().GetByteOrder())
            {
                uint8_t *data_bytes = data.GetBytes();

                for (size_t index = 0;
                     index < operand_data_size;
                     ++index)
                {
                    data_bytes[index] = operand_raw_data[operand_data_size - (1 + index)];
                }
            }
            else
            {
                memcpy(data.GetBytes(), operand_raw_data, operand_data_size);
            }

            uint64_t offset = m_data_allocator.GetStream().GetSize();

            size_t align = m_target_data->getPrefTypeAlignment(operand_type);

            const size_t mask = (align - 1);
            uint64_t aligned_offset = (offset + mask) & ~mask;
            m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);

            m_data_allocator.GetStream().Write(data.GetBytes(), operand_data_size);

            llvm::Type *fp_ptr_ty = operand_constant_fp->getType()->getPointerTo();

            Constant *new_pointer = BuildRelocation(fp_ptr_ty, aligned_offset);

            llvm::LoadInst *fp_load = new llvm::LoadInst(new_pointer, "fp_load", inst);

            operand_constant_fp->replaceAllUsesWith(fp_load);
        }
    }

    return true;
}

static bool isGuardVariableRef(Value *V)
{
    Constant *Old = NULL;

    if (!(Old = dyn_cast<Constant>(V)))
        return false;

    ConstantExpr *CE = NULL;

    if ((CE = dyn_cast<ConstantExpr>(V)))
    {
        if (CE->getOpcode() != Instruction::BitCast)
            return false;

        Old = CE->getOperand(0);
    }

    GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);

    if (!GV || !GV->hasName() ||
        (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable
         !GV->getName().endswith("@4IA")))    // Microsoft ABI guard variable
    {
        return false;
    }

    return true;
}

void
IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction* guard_load)
{
    Constant *zero(Constant::getNullValue(guard_load->getType()));
    guard_load->replaceAllUsesWith(zero);
    guard_load->eraseFromParent();
}

static void ExciseGuardStore(Instruction* guard_store)
{
    guard_store->eraseFromParent();
}

bool
IRForTarget::RemoveGuards(BasicBlock &basic_block)
{
    ///////////////////////////////////////////////////////
    // Eliminate any reference to guard variables found.
    //

    BasicBlock::iterator ii;

    typedef SmallVector <Instruction*, 2> InstrList;
    typedef InstrList::iterator InstrIterator;

    InstrList guard_loads;
    InstrList guard_stores;

    for (ii = basic_block.begin();
         ii != basic_block.end();
         ++ii)
    {
        Instruction &inst = *ii;

        if (LoadInst *load = dyn_cast<LoadInst>(&inst))
            if (isGuardVariableRef(load->getPointerOperand()))
                guard_loads.push_back(&inst);

        if (StoreInst *store = dyn_cast<StoreInst>(&inst))
            if (isGuardVariableRef(store->getPointerOperand()))
                guard_stores.push_back(&inst);
    }

    InstrIterator iter;

    for (iter = guard_loads.begin();
         iter != guard_loads.end();
         ++iter)
        TurnGuardLoadIntoZero(*iter);

    for (iter = guard_stores.begin();
         iter != guard_stores.end();
         ++iter)
        ExciseGuardStore(*iter);

    return true;
}

// This function does not report errors; its callers are responsible.
bool
IRForTarget::UnfoldConstant(Constant *old_constant,
                            FunctionValueCache &value_maker,
                            FunctionValueCache &entry_instruction_finder)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    SmallVector<User*, 16> users;

    // We do this because the use list might change, invalidating our iterator.
    // Much better to keep a work list ourselves.
    for (llvm::User *u : old_constant->users())
        users.push_back(u);

    for (size_t i = 0;
         i < users.size();
         ++i)
    {
        User *user = users[i];

        if (Constant *constant = dyn_cast<Constant>(user))
        {
            // synthesize a new non-constant equivalent of the constant

            if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
            {
                switch (constant_expr->getOpcode())
                {
                default:
                    if (log)
                        log->Printf("Unhandled constant expression type: \"%s\"", PrintValue(constant_expr).c_str());
                    return false;
                case Instruction::BitCast:
                    {
                        FunctionValueCache bit_cast_maker ([&value_maker, &entry_instruction_finder, old_constant, constant_expr] (llvm::Function *function)->llvm::Value* {
                            // UnaryExpr
                            //   OperandList[0] is value

                            if (constant_expr->getOperand(0) != old_constant)
                                return constant_expr;

                            return new BitCastInst(value_maker.GetValue(function),
                                                   constant_expr->getType(),
                                                   "",
                                                   llvm::cast<Instruction>(entry_instruction_finder.GetValue(function)));
                        });

                        if (!UnfoldConstant(constant_expr, bit_cast_maker, entry_instruction_finder))
                            return false;
                    }
                    break;
                case Instruction::GetElementPtr:
                    {
                        // GetElementPtrConstantExpr
                        //   OperandList[0] is base
                        //   OperandList[1]... are indices

                        FunctionValueCache get_element_pointer_maker ([&value_maker, &entry_instruction_finder, old_constant, constant_expr] (llvm::Function *function)->llvm::Value* {
                            Value *ptr = constant_expr->getOperand(0);

                            if (ptr == old_constant)
                                ptr = value_maker.GetValue(function);

                            std::vector<Value*> index_vector;

                            unsigned operand_index;
                            unsigned num_operands = constant_expr->getNumOperands();

                            for (operand_index = 1;
                                 operand_index < num_operands;
                                 ++operand_index)
                            {
                                Value *operand = constant_expr->getOperand(operand_index);

                                if (operand == old_constant)
                                    operand = value_maker.GetValue(function);

                                index_vector.push_back(operand);
                            }

                            ArrayRef <Value*> indices(index_vector);

                            return GetElementPtrInst::Create(ptr, indices, "", llvm::cast<Instruction>(entry_instruction_finder.GetValue(function)));
                        });

                        if (!UnfoldConstant(constant_expr, get_element_pointer_maker, entry_instruction_finder))
                            return false;
                    }
                    break;
                }
            }
            else
            {
                if (log)
                    log->Printf("Unhandled constant type: \"%s\"", PrintValue(constant).c_str());
                return false;
            }
        }
        else
        {
            if (Instruction *inst = llvm::dyn_cast<Instruction>(user))
            {
                inst->replaceUsesOfWith(old_constant, value_maker.GetValue(inst->getParent()->getParent()));
            }
            else
            {
                if (log)
                    log->Printf("Unhandled non-constant type: \"%s\"", PrintValue(user).c_str());
                return false;
            }
        }
    }

    if (!isa<GlobalValue>(old_constant))
    {
        old_constant->destroyConstant();
    }

    return true;
}

bool
IRForTarget::ReplaceVariables (Function &llvm_function)
{
    if (!m_resolve_vars)
        return true;

    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    m_decl_map->DoStructLayout();

    if (log)
        log->Printf("Element arrangement:");

    uint32_t num_elements;
    uint32_t element_index;

    size_t size;
    lldb::offset_t alignment;

    if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
        return false;

    Function::arg_iterator iter(llvm_function.getArgumentList().begin());

    if (iter == llvm_function.getArgumentList().end())
    {
        if (m_error_stream)
            m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes no arguments (should take at least a struct pointer)");

        return false;
    }

    Argument *argument = iter;

    if (argument->getName().equals("this"))
    {
        ++iter;

        if (iter == llvm_function.getArgumentList().end())
        {
            if (m_error_stream)
                m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'this' argument (should take a struct pointer too)");

            return false;
        }

        argument = iter;
    }
    else if (argument->getName().equals("self"))
    {
        ++iter;

        if (iter == llvm_function.getArgumentList().end())
        {
            if (m_error_stream)
                m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'self' argument (should take '_cmd' and a struct pointer too)");

            return false;
        }

        if (!iter->getName().equals("_cmd"))
        {
            if (m_error_stream)
                m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes '%s' after 'self' argument (should take '_cmd')", iter->getName().str().c_str());

            return false;
        }

        ++iter;

        if (iter == llvm_function.getArgumentList().end())
        {
            if (m_error_stream)
                m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'self' and '_cmd' arguments (should take a struct pointer too)");

            return false;
        }

        argument = iter;
    }

    if (!argument->getName().equals("$__lldb_arg"))
    {
        if (m_error_stream)
            m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes an argument named '%s' instead of the struct pointer", argument->getName().str().c_str());

        return false;
    }

    if (log)
        log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());

    BasicBlock &entry_block(llvm_function.getEntryBlock());
    Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());

    if (!FirstEntryInstruction)
    {
        if (m_error_stream)
            m_error_stream->Printf("Internal error [IRForTarget]: Couldn't find the first instruction in the wrapper for use in rewriting");

        return false;
    }

    LLVMContext &context(m_module->getContext());
    IntegerType *offset_type(Type::getInt32Ty(context));

    if (!offset_type)
    {
        if (m_error_stream)
            m_error_stream->Printf("Internal error [IRForTarget]: Couldn't produce an offset type");

        return false;
    }

    for (element_index = 0; element_index < num_elements; ++element_index)
    {
        const clang::NamedDecl *decl = NULL;
        Value *value = NULL;
        lldb::offset_t offset;
        lldb_private::ConstString name;

        if (!m_decl_map->GetStructElement (decl, value, offset, name, element_index))
        {
            if (m_error_stream)
                m_error_stream->Printf("Internal error [IRForTarget]: Structure information is incomplete");

            return false;
        }

        if (log)
            log->Printf("  \"%s\" (\"%s\") placed at %" PRIu64,
                        name.GetCString(),
                        decl->getNameAsString().c_str(),
                        offset);

        if (value)
        {
            if (log)
                log->Printf("    Replacing [%s]", PrintValue(value).c_str());

            FunctionValueCache body_result_maker ([this, name, offset_type, offset, argument, value] (llvm::Function *function)->llvm::Value * {
                // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in cases where the result
                // variable is an rvalue, we have to synthesize a dereference of the appropriate structure
                // entry in order to produce the static variable that the AST thinks it is accessing.

                llvm::Instruction *entry_instruction = llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function));

                ConstantInt *offset_int(ConstantInt::get(offset_type, offset, true));
                GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument,
                                                                               offset_int,
                                                                               "",
                                                                               entry_instruction);

                if (name == m_result_name && !m_result_is_pointer)
                {
                    BitCastInst *bit_cast = new BitCastInst(get_element_ptr,
                                                            value->getType()->getPointerTo(),
                                                            "",
                                                            entry_instruction);

                    LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);

                    return load;
                }
                else
                {
                    BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", entry_instruction);

                    return bit_cast;
                }
            });

            if (Constant *constant = dyn_cast<Constant>(value))
            {
                UnfoldConstant(constant, body_result_maker, m_entry_instruction_finder);
            }
            else if (Instruction *instruction = dyn_cast<Instruction>(value))
            {
                value->replaceAllUsesWith(body_result_maker.GetValue(instruction->getParent()->getParent()));
            }
            else
            {
                if (log)
                    log->Printf("Unhandled non-constant type: \"%s\"", PrintValue(value).c_str());
                return false;
            }

            if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
                var->eraseFromParent();
        }
    }

    if (log)
        log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]", (int64_t)alignment, (uint64_t)size);

    return true;
}

llvm::Constant *
IRForTarget::BuildRelocation(llvm::Type *type, uint64_t offset)
{
    llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset);

    llvm::Constant *offset_array[1];

    offset_array[0] = offset_int;

    llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);

    llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(m_reloc_placeholder, offsets);
    llvm::Constant *reloc_getbitcast = ConstantExpr::getBitCast(reloc_getelementptr, type);

    return reloc_getbitcast;
}

bool
IRForTarget::CompleteDataAllocation ()
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    if (!m_data_allocator.GetStream().GetSize())
        return true;

    lldb::addr_t allocation = m_data_allocator.Allocate();

    if (log)
    {
        if (allocation)
            log->Printf("Allocated static data at 0x%llx", (unsigned long long)allocation);
        else
            log->Printf("Failed to allocate static data");
    }

    if (!allocation || allocation == LLDB_INVALID_ADDRESS)
        return false;

    Constant *relocated_addr = ConstantInt::get(m_intptr_ty, (uint64_t)allocation);
    Constant *relocated_bitcast = ConstantExpr::getIntToPtr(relocated_addr, llvm::Type::getInt8PtrTy(m_module->getContext()));

    m_reloc_placeholder->replaceAllUsesWith(relocated_bitcast);

    m_reloc_placeholder->eraseFromParent();

    return true;
}

bool
IRForTarget::StripAllGVs (Module &llvm_module)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
    std::vector<GlobalVariable *> global_vars;
    std::set<GlobalVariable *>erased_vars;

    bool erased = true;

    while (erased)
    {
        erased = false;

        for (GlobalVariable &global_var : llvm_module.globals())
        {
            global_var.removeDeadConstantUsers();

            if (global_var.use_empty())
            {
                if (log)
                    log->Printf("Did remove %s",
                                PrintValue(&global_var).c_str());
                global_var.eraseFromParent();
                erased = true;
                break;
            }
        }
    }

    for (GlobalVariable &global_var : llvm_module.globals())
    {
        GlobalValue::user_iterator ui = global_var.user_begin();

        if (log)
            log->Printf("Couldn't remove %s because of %s",
                        PrintValue(&global_var).c_str(),
                        PrintValue(*ui).c_str());
    }

    return true;
}

bool
IRForTarget::runOnModule (Module &llvm_module)
{
    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    m_module = &llvm_module;
    m_target_data.reset(new DataLayout(m_module));
    m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(), m_target_data->getPointerSizeInBits());

    if (log)
    {
        std::string s;
        raw_string_ostream oss(s);

        m_module->print(oss, NULL);

        oss.flush();

        log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
    }

    Function* main_function = m_module->getFunction(StringRef(m_func_name.c_str()));

    if (!main_function)
    {
        if (log)
            log->Printf("Couldn't find \"%s()\" in the module", m_func_name.c_str());

        if (m_error_stream)
            m_error_stream->Printf("Internal error [IRForTarget]: Couldn't find wrapper '%s' in the module", m_func_name.c_str());

        return false;
    }

    if (!FixFunctionLinkage (*main_function))
    {
        if (log)
            log->Printf("Couldn't fix the linkage for the function");

        return false;
    }

    llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());

    m_reloc_placeholder = new llvm::GlobalVariable((*m_module),
                                                   int8_ty,
                                                   false /* IsConstant */,
                                                   GlobalVariable::InternalLinkage,
                                                   Constant::getNullValue(int8_ty),
                                                   "reloc_placeholder",
                                                   NULL /* InsertBefore */,
                                                   GlobalVariable::NotThreadLocal /* ThreadLocal */,
                                                   0 /* AddressSpace */);

    ////////////////////////////////////////////////////////////
    // Replace $__lldb_expr_result with a persistent variable
    //

    if (!CreateResultVariable(*main_function))
    {
        if (log)
            log->Printf("CreateResultVariable() failed");

        // CreateResultVariable() reports its own errors, so we don't do so here

        return false;
    }

    if (log && log->GetVerbose())
    {
        std::string s;
        raw_string_ostream oss(s);

        m_module->print(oss, NULL);

        oss.flush();

        log->Printf("Module after creating the result variable: \n\"%s\"", s.c_str());
    }

    for (Module::iterator fi = m_module->begin(), fe = m_module->end();
         fi != fe;
         ++fi)
    {
        llvm::Function *function = fi;

        if (function->begin() == function->end())
            continue;

        Function::iterator bbi;

        for (bbi = function->begin();
             bbi != function->end();
             ++bbi)
        {
            if (!RemoveGuards(*bbi))
            {
                if (log)
                    log->Printf("RemoveGuards() failed");

                // RemoveGuards() reports its own errors, so we don't do so here

                return false;
            }

            if (!RewritePersistentAllocs(*bbi))
            {
                if (log)
                    log->Printf("RewritePersistentAllocs() failed");

                // RewritePersistentAllocs() reports its own errors, so we don't do so here

                return false;
            }

            if (!RemoveCXAAtExit(*bbi))
            {
                if (log)
                    log->Printf("RemoveCXAAtExit() failed");

                // RemoveCXAAtExit() reports its own errors, so we don't do so here

                return false;
            }
        }
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
    //

    if (!RewriteObjCConstStrings())
    {
        if (log)
            log->Printf("RewriteObjCConstStrings() failed");

        // RewriteObjCConstStrings() reports its own errors, so we don't do so here

        return false;
    }

    ///////////////////////////////
    // Resolve function pointers
    //

    if (!ResolveFunctionPointers(llvm_module))
    {
        if (log)
            log->Printf("ResolveFunctionPointers() failed");

        // ResolveFunctionPointers() reports its own errors, so we don't do so here

        return false;
    }

    for (Module::iterator fi = m_module->begin(), fe = m_module->end();
         fi != fe;
         ++fi)
    {
        llvm::Function *function = fi;

        for (llvm::Function::iterator bbi = function->begin(), bbe = function->end();
             bbi != bbe;
             ++bbi)
        {
            if (!RewriteObjCSelectors(*bbi))
            {
                if (log)
                    log->Printf("RewriteObjCSelectors() failed");

                // RewriteObjCSelectors() reports its own errors, so we don't do so here

                return false;
            }
        }
    }

    for (Module::iterator fi = m_module->begin(), fe = m_module->end();
         fi != fe;
         ++fi)
    {
        llvm::Function *function = fi;

        for (llvm::Function::iterator bbi = function->begin(), bbe = function->end();
             bbi != bbe;
             ++bbi)
        {
            if (!ResolveCalls(*bbi))
            {
                if (log)
                    log->Printf("ResolveCalls() failed");

                // ResolveCalls() reports its own errors, so we don't do so here

                return false;
            }

            if (!ReplaceStaticLiterals(*bbi))
            {
                if (log)
                    log->Printf("ReplaceStaticLiterals() failed");

                return false;
            }
        }
    }

    ////////////////////////////////////////////////////////////////////////
    // Run function-level passes that only make sense on the main function
    //

    if (!ResolveExternals(*main_function))
    {
        if (log)
            log->Printf("ResolveExternals() failed");

        // ResolveExternals() reports its own errors, so we don't do so here

        return false;
    }

    if (!ReplaceVariables(*main_function))
    {
        if (log)
            log->Printf("ReplaceVariables() failed");

        // ReplaceVariables() reports its own errors, so we don't do so here

        return false;
    }

    if (!ReplaceStrings())
    {
        if (log)
            log->Printf("ReplaceStrings() failed");

        return false;
    }

    if (!CompleteDataAllocation())
    {
        if (log)
            log->Printf("CompleteDataAllocation() failed");

        return false;
    }

    if (!StripAllGVs(llvm_module))
    {
        if (log)
            log->Printf("StripAllGVs() failed");
    }

    if (log && log->GetVerbose())
    {
        std::string s;
        raw_string_ostream oss(s);

        m_module->print(oss, NULL);

        oss.flush();

        log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
    }

    return true;
}

void
IRForTarget::assignPassManager (PMStack &pass_mgr_stack, PassManagerType pass_mgr_type)
{
}

PassManagerType
IRForTarget::getPotentialPassManagerType() const
{
    return PMT_ModulePassManager;
}
