//===-- 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/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_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;
}

bool 
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 false;
        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;
        }
        
        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 false;
            }
        }
    }
    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 false;
        }
    }
    
    if (log)
        log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), fun_addr);
    
    return true;
}

llvm::Constant *
IRForTarget::BuildFunctionPointer (llvm::Type *type,
                                   uint64_t ptr)
{
    IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
                                             (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
    PointerType *fun_ptr_ty = PointerType::getUnqual(type);
    Constant *fun_addr_int = ConstantInt::get(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 (Value::use_iterator i = function_ptr->use_begin(), e = function_ptr->use_end();
         i != e;
         ++i)
    {
        Value *user = *i;
                
        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->hasNUses(0))
            continue; // ignore
        
        uint64_t addr = LLDB_INVALID_ADDRESS;
        lldb_private::ConstString name;
        Constant **value_ptr = NULL;
        
        if (!GetFunctionAddress(fun,
                                addr,
                                name,
                                value_ptr))
            return false; // GetFunctionAddress reports its own errors
        
        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->use_begin(), e = fun->use_end(); u != e; ++u) {
                if (auto call = dyn_cast<CallInst>(*u)) {
                    call->removeAttribute(AttributeSet::FunctionIndex, builtin);
                }
            }
        }
        
        fun->replaceAllUsesWith(value);
    }
    
    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)
    {
        MDNode *metadata_node = named_metadata->getOperand(node_index);
        
        if (!metadata_node)
            return NULL;
        
        if (metadata_node->getNumOperands() != 2)
            continue;
        
        if (metadata_node->getOperand(0) != global_val)
            continue;
        
        ConstantInt *constant_int = dyn_cast<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() == 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());
        
    // 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::Value* values[2];
    values[0] = new_result_global;
    values[1] = new_constant_int;
    
    ArrayRef<Value*> 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->hasNUses(0))
    {
        // 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;
}

#if 0
static void DebugUsers(Log *log, Value *value, uint8_t depth)
{    
    if (!depth)
        return;
    
    depth--;
    
    if (log)
        log->Printf("  <Begin %d users>", value->getNumUses());
    
    for (Value::use_iterator ui = value->use_begin(), ue = value->use_end();
         ui != ue;
         ++ui)
    {
        if (log)
            log->Printf("  <Use %p> %s", *ui, PrintValue(*ui).c_str());
        DebugUsers(log, *ui, depth);
    }
    
    if (log)
        log->Printf("  <End uses>");
}
#endif

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());
    IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
                                                   (m_module->getPointerSize()
                                                    == Module::Pointer64) ? 64 : 32);
    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] = 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(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(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("\01L_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** @"\01L_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.
    // 
    // @"\01L_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
        IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
                                                 (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
        PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
        Constant *srN_addr_int = ConstantInt::get(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 = dyn_cast<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::Value* values[2];
    values[0] = persistent_global;
    values[1] = constant_int;
    
    ArrayRef<llvm::Value*> 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();
        off_t value_alignment = (clang_type.GetTypeBitAlign() + 7ull) / 8ull;
        
        if (log)
        {
            log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRId64 "]",
                        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();
    IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
                                             (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
    
    Constant *symbol_addr_int = ConstantInt::get(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_begin() == global_variable->use_end())
        return false;
    
    SmallVector<LoadInst *, 2> load_instructions;
        
    for (Value::use_iterator i = global_variable->use_begin(), e = global_variable->use_end();
         i != e;
         ++i)
    {
        if (LoadInst *load_instruction = dyn_cast<LoadInst>(*i))
            load_instructions.push_back(load_instruction);
    }
    
    if (load_instructions.empty())
        return false;
    
    IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
                                             (m_module->getPointerSize()
                                              == Module::Pointer64) ? 64 : 32);
    
    Constant *class_addr = ConstantInt::get(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 (Module::global_iterator global = m_module->global_begin(), end = m_module->global_end();
         global != end;
         ++global)
    {
        if (!global)
        {
            if (m_error_stream)
                m_error_stream->Printf("Internal error [IRForTarget]: global variable is NULL");
            
            return false;
        }
        
        std::string global_name = (*global).getName().str();
        
        if (log)
            log->Printf("Examining %s, DeclForGlobalValue returns %p", 
                        global_name.c_str(),
                        DeclForGlobal(global));
        
        if (global_name.find("OBJC_IVAR") == 0)
        {
            if (!HandleSymbol(global))
            {
                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))
            {
                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))
            {
                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))
        {
            if (!MaybeHandleVariable (global))
            {
                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 (Module::global_iterator gi = m_module->global_begin(), ge = m_module->global_end();
         gi != ge;
         ++gi)
    {
        GlobalVariable *gv = gi;
        
        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 (GlobalVariable::use_iterator ui = gv->use_begin(), ue = gv->use_end();
             ui != ue;
             ++ui)
        {
            if (log)
                log->Printf("Found use %s", PrintValue(*ui).c_str());
            
            ConstantExpr *const_expr = dyn_cast<ConstantExpr>(*ui);
            StoreInst *store_inst = dyn_cast<StoreInst>(*ui);
            
            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 (Instruction::op_iterator oi = inst.op_begin(), oe = inst.op_end();
             oi != oe;
             ++oi)
        {
            Value *operand_val = oi->get();
            
            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 %zu and raw data %s", 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);
            offset = aligned_offset;
            
            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"))
        return false;
    
    return true;
}

void 
IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction* guard_load)
{
    Constant* zero(ConstantInt::get(Type::getInt8Ty(m_module->getContext()), 0, true));

    Value::use_iterator ui;
    
    for (ui = guard_load->use_begin();
         ui != guard_load->use_end();
         ++ui)
    {
        if (isa<Constant>(*ui))
        {
            // do nothing for the moment
        }
        else
        {
            ui->replaceUsesOfWith(guard_load, 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));

    Value::use_iterator ui;
    
    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 (ui = old_constant->use_begin();
         ui != old_constant->use_end();
         ++ui)
        users.push_back(*ui);
        
    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;
    off_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;
        off_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 %" PRId64,
                        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 %zu]", alignment, size);
    
    return true;
}

llvm::Constant *
IRForTarget::BuildRelocation(llvm::Type *type, uint64_t offset)
{
    IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
                                             (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
    
    llvm::Constant *offset_int = ConstantInt::get(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;
    
    IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
                                             (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
    
    Constant *relocated_addr = ConstantInt::get(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 (Module::global_iterator gi = llvm_module.global_begin(), ge = llvm_module.global_end();
             gi != ge;
             ++gi)
        {
            GlobalVariable *global_var = dyn_cast<GlobalVariable>(gi);
        
            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 (Module::global_iterator gi = llvm_module.global_begin(), ge = llvm_module.global_end();
         gi != ge;
         ++gi)
    {
        GlobalVariable *global_var = dyn_cast<GlobalVariable>(gi);

        GlobalValue::use_iterator ui = global_var->use_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));
   
    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 *intptr_ty = Type::getInt8Ty(m_module->getContext());
    
    m_reloc_placeholder = new llvm::GlobalVariable((*m_module),
                                                   intptr_ty,
                                                   false /* IsConstant */,
                                                   GlobalVariable::InternalLinkage,
                                                   Constant::getNullValue(intptr_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;
}
