//===-- 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 "IRForTarget.h"

#include "ClangExpressionDeclMap.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/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/ValueSymbolTable.h"

#include "clang/AST/ASTContext.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/Core/dwarf.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompilerType.h"

#include <map>

using namespace llvm;

static char ID;

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];
}

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_CFStringCreateWithBytes(NULL),
    m_sel_registerName(NULL),
    m_intptr_ty(NULL),
    m_error_stream(error_stream),
    m_execution_unit(execution_unit),
    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);

    return true;
}

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

    if (!named_metadata)
        return NULL;

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

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

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

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

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

        if (!constant_int)
            return NULL;

        uintptr_t ptr = constant_int->getZExtValue();

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

    return NULL;
}

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

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

    if (!m_resolve_vars)
        return true;

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

    ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();

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

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

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

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

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

        return true;
    }

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

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

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

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

        return false;
    }

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

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

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

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

        return false;
    }

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

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

        return false;
    }

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

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

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

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

        return false;
    }

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

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

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

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

            m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
                                                         lldb_private::ClangASTContext::GetASTContext(&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(),
                                                         lldb_private::ClangASTContext::GetASTContext(&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(),
                                                     lldb_private::ClangASTContext::GetASTContext(&result_decl->getASTContext()));
    }


    lldb::TargetSP target_sp (m_execution_unit.GetTarget());
    lldb_private::ExecutionContext exe_ctx (target_sp, true);
    if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0)
    {
        lldb_private::StreamString type_desc_stream;
        m_result_type.DumpTypeDescription(&type_desc_stream);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        if (!first_entry_instruction)
            return false;

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

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

            return false;
        }

        Constant *initializer = result_global->getInitializer();

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

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

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

    result_global->eraseFromParent();

    return true;
}

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

    Type *ns_str_ty = ns_str->getType();

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

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

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

        CFStringCreateWithBytes_addr = m_execution_unit.FindSymbol (g_CFStringCreateWithBytes_str);
        if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS)
        {
            if (log)
                log->PutCString("Couldn't find CFStringCreateWithBytes in the target");

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

            return false;
        }

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

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

        Type *arg_type_array[5];

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

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

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

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

    ConstantDataSequential *string_array = NULL;

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

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

    Value *argument_array[5];

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

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

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

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

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

        return false;
    }

    ns_str->eraseFromParent();

    return true;
}

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

    ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();

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

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

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

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

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

                return false;
            }

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

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

                return false;
            }

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

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

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

                return false;
            }

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

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

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

                return false;
            }

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

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

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

                return false;
            }

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

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

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

                return false;
            }

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

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

                return false;
            }

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

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

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

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

                return false;
            }

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

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

                return false;
            }

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

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

                return false;
            }

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

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

                return false;
            }
            */

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

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

            if (!cstr_array)
                cstr_global = NULL;

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

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

                return false;
            }
        }
    }

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

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

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

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

                return false;
            }

            gv->eraseFromParent();

            break;
        }
    }

    return true;
}

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

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

    return true;
}

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

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

    if (!load)
        return false;

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

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

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

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

    Constant *osr_initializer = _objc_selector_references_->getInitializer();

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

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

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

    if (!osr_initializer_base)
        return false;

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

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

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

    Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();

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

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

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

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

    // Construct a call to sel_registerName

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

        static lldb_private::ConstString g_sel_registerName_str ("sel_registerName");
        sel_registerName_addr = m_execution_unit.FindSymbol (g_sel_registerName_str);
        if (sel_registerName_addr == LLDB_INVALID_ADDRESS)
            return false;

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

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

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

        Type *type_array[1];

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

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

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

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

    Value *argument_array[1];

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

    argument_array[0] = omvn_pointer;

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

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

    // Replace the load with the call in all users

    selector_load->replaceAllUsesWith(srN_call);

    selector_load->eraseFromParent();

    return true;
}

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

    BasicBlock::iterator ii;

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

    InstrList selector_loads;

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

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

    InstrIterator iter;

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

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

            return false;
        }
    }

    return true;
}

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

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

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

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

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

    if (!constant_int)
        return false;

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

    uintptr_t ptr = constant_int->getZExtValue();

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

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

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

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

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

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

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

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

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

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

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

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

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

    return true;
}

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

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

    BasicBlock::iterator ii;

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

    InstrList pvar_allocs;

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

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

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

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

                    return false;
                }

                pvar_allocs.push_back(alloc);
            }
        }
    }

    InstrIterator iter;

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

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

            return false;
        }
    }

    return true;
}

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

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

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

    Type *initializer_type = initializer->getType();

    if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer))
    {
        size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
        lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(llvm::NextPowerOf2(constant_size) * 8);

        lldb_private::Error get_data_error;
        if (!scalar.GetAsMemoryData(data, constant_size, lldb_private::endian::InlHostByteOrder(), get_data_error))
            return false;

        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;
}

// 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 true;

        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::CompilerType compiler_type(&value_decl->getASTContext(), value_decl->getType());

        const Type *value_type = NULL;

        if (name[0] == '$')
        {
            // The $__lldb_expr_result name indicates 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.
            compiler_type = compiler_type.GetPointerType();
            value_type = PointerType::get(global_variable->getType(), 0);
        }
        else
        {
            value_type = global_variable->getType();
        }

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

        if (log)
        {
            log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRIu64 "]",
                        name.c_str(), lldb_private::ClangUtil::GetQualType(compiler_type).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
                return true;
        }
    }
    else if (dyn_cast<llvm::Function>(llvm_value_ptr))
    {
        if (log)
            log->Printf("Function pointers aren't handled right now");

        return false;
    }

    return true;
}

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

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

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

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

        return false;
    }

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

    Type *symbol_type = symbol->getType();

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

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

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

    symbol->replaceAllUsesWith(symbol_addr_ptr);

    return true;
}

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

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

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

            return false;
        }

    return true;
}

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

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

    if (!global_variable)
        return false;

    Constant *initializer = global_variable->getInitializer();

    if (!initializer)
        return false;

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

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

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

    if (class_ptr == LLDB_INVALID_ADDRESS)
        return false;

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

    SmallVector<LoadInst *, 2> load_instructions;

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

    if (load_instructions.empty())
        return false;

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

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

        load_instruction->replaceAllUsesWith(class_bitcast);

        load_instruction->eraseFromParent();
    }

    return true;
}

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

    std::vector<CallInst *> calls_to_remove;

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

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

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

        bool remove = false;

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

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

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

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

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

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

    return true;
}

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

    BasicBlock::iterator ii;

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

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

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

    return true;
}

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

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

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

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

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

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

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

                return false;
            }
        }
    }

    return true;
}

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

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

    ConstantExpr *CE = NULL;

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

        Old = CE->getOperand(0);
    }

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

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

    return true;
}

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

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

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

    BasicBlock::iterator ii;

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

    InstrList guard_loads;
    InstrList guard_stores;

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

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

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

    InstrIterator iter;

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

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

    return true;
}

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

    SmallVector<User*, 16> users;

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

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

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

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

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

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

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

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

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

                            std::vector<Value*> index_vector;

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

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

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

                                index_vector.push_back(operand);
                            }

                            ArrayRef <Value*> indices(index_vector);

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

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

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

    return true;
}

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

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

    m_decl_map->DoStructLayout();

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

    uint32_t num_elements;
    uint32_t element_index;

    size_t size;
    lldb::offset_t alignment;

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

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

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

        return false;
    }

    Argument *argument = &*iter;

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

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

            return false;
        }

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

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

            return false;
        }

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

            return false;
        }

        ++iter;

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

            return false;
        }

        argument = &*iter;
    }

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

        return false;
    }

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

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

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

        return false;
    }

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

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

        return false;
    }

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

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

            return false;
        }

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

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

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

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

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

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

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

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

                    return bit_cast;
                }
            });

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

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

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

    return true;
}

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

    llvm::Constant *offset_array[1];

    offset_array[0] = offset_int;

    llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
    llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext());
    llvm::Type *char_pointer_type = char_type->getPointerTo();

    llvm::Constant *reloc_placeholder_bitcast = ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type);
    llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(char_type, reloc_placeholder_bitcast, offsets);
    llvm::Constant *reloc_bitcast = ConstantExpr::getBitCast(reloc_getelementptr, type);

    return reloc_bitcast;
}

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

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

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

        m_module->print(oss, NULL);

        oss.flush();

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

    Function *const main_function = m_func_name.IsEmpty() ? nullptr : m_module->getFunction(m_func_name.GetStringRef());

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

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

        return false;
    }

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

            return false;
        }
    }

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

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

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

    if (main_function)
    {
        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;
    }

    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;
            }
        }
    }

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

    if (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 (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;
}
