//===-- IRForTarget.cpp -----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "IRForTarget.h"

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

#include "clang/AST/ASTContext.h"

#include "lldb/Core/dwarf.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/StreamString.h"

#include <map>

using namespace llvm;

static char ID;

typedef SmallVector<Instruction *, 2> InstrList;

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

  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(nullptr), m_decl_map(decl_map),
      m_CFStringCreateWithBytes(nullptr), m_sel_registerName(nullptr),
      m_objc_getClass(nullptr), m_intptr_ty(nullptr),
      m_error_stream(error_stream), m_execution_unit(execution_unit),
      m_result_store(nullptr), m_result_is_pointer(false),
      m_reloc_placeholder(nullptr),
      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 nullptr;

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

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

    uintptr_t ptr = constant_int->getZExtValue();

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

  return nullptr;
}

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

/// Returns true iff the mangled symbol is for a static guard variable.
static bool isGuardVariableSymbol(llvm::StringRef mangled_symbol,
                                  bool check_ms_abi = true) {
  bool result = mangled_symbol.startswith("_ZGV"); // Itanium ABI guard variable
  if (check_ms_abi)
    result |= mangled_symbol.endswith("@4IA"); // Microsoft ABI
  return result;
}

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();

  llvm::StringRef result_name;
  bool found_result = false;

  for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
    result_name = value_symbol.first();

    // Check if this is a guard variable. It seems this causes some hiccups
    // on Windows, so let's only check for Itanium guard variables.
    bool is_guard_var = isGuardVariableSymbol(result_name, /*MS ABI*/ false);

    if (result_name.contains("$__lldb_expr_result_ptr") && !is_guard_var) {
      found_result = true;
      m_result_is_pointer = true;
      break;
    }

    if (result_name.contains("$__lldb_expr_result") && !is_guard_var) {
      found_result = true;
      m_result_is_pointer = false;
      break;
    }
  }

  if (!found_result) {
    LLDB_LOG(log, "Couldn't find result variable");

    return true;
  }

  LLDB_LOG(log, "Result name: \"{0}\"", result_name);

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

  if (!result_value) {
    LLDB_LOG(log, "Result variable had no data");

    m_error_stream.Format("Internal error [IRForTarget]: Result variable's "
                          "name ({0}) exists, but not its definition\n",
                          result_name);

    return false;
  }

  LLDB_LOG(log, "Found result in the IR: \"{0}\"",
           PrintValue(result_value, false));

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

  if (!result_global) {
    LLDB_LOG(log, "Result variable isn't a GlobalVariable");

    m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
                          "is defined, but is not a global variable\n",
                          result_name);

    return false;
  }

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

    m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
                          "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();

    LLDB_LOG(log, "Found result decl: \"{0}\"", decl_desc_str);
  }

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

    m_error_stream.Format("Internal error [IRForTarget]: Result variable "
                          "({0})'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 {
      LLDB_LOG(log, "Expected result to have pointer type, but it did not");

      m_error_stream.Format("Internal error [IRForTarget]: Lvalue result ({0}) "
                            "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);
  llvm::Optional<uint64_t> bit_size =
      m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope());
  if (!bit_size) {
    lldb_private::StreamString type_desc_stream;
    m_result_type.DumpTypeDescription(&type_desc_stream);

    LLDB_LOG(log, "Result type has unknown size");

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

    LLDB_LOG(log, "Result decl type: \"{0}\"", type_desc_stream.GetData());
  }

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

  LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}",
           m_result_name, m_result_type.GetByteSize(nullptr).getValueOr(0));

  // 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, nullptr, /* 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);

  LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(result_global),
           PrintValue(new_result_global));

  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()) {
      LLDB_LOG(log, "Couldn't find initializer for unused variable");

      m_error_stream.Format("Internal error [IRForTarget]: Result variable "
                            "({0}) 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);

    LLDB_LOG(log, "Synthesized result store \"{0}\"\n",
             PrintValue(synthesized_store));
  } 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");

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

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

      return false;
    }

    LLDB_LOG(log, "Found CFStringCreateWithBytes at {0}",
             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::FunctionType *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 = {
        CFSCWB_ty, ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty)};
  }

  ConstantDataSequential *string_array = nullptr;

  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) * string_array->getElementByteSize() : 0, false);
 int encoding_flags = 0;
 switch (cstr ? string_array->getElementByteSize() : 1) {
 case 1:
   encoding_flags = 0x08000100; /* 0x08000100 is kCFStringEncodingUTF8 */
   break;
 case 2:
   encoding_flags = 0x0100; /* 0x0100 is kCFStringEncodingUTF16 */
   break;
 case 4:
   encoding_flags = 0x0c000100; /* 0x0c000100 is kCFStringEncodingUTF32 */
   break;
 default:
   encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */
   LLDB_LOG(log, "Encountered an Objective-C constant string with unusual "
                 "element size {0}",
            string_array->getElementByteSize());
 }
 Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags, false);
 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, nullptr, CFSCWB_Caller, m_entry_instruction_finder,
                     m_error_stream)) {
   LLDB_LOG(log, "Couldn't replace the NSString with the result of the call");

   m_error_stream.Printf("error [IRForTarget internal]: 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 (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
    llvm::StringRef value_name = value_symbol.first();

    if (value_name.contains("_unnamed_cfstring_")) {
      Value *nsstring_value = value_symbol.second;

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

      if (!nsstring_global) {
        LLDB_LOG(log, "NSString variable is not a GlobalVariable");

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

        return false;
      }

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

        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) {
        LLDB_LOG(log,
                 "NSString variable's initializer is not a ConstantStruct");

        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) {

        LLDB_LOG(log,
                 "NSString variable's initializer structure has an "
                 "unexpected number of members.  Should be 4, is {0}",
                 nsstring_struct->getNumOperands());

        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) {
        LLDB_LOG(log, "NSString initializer's str element was empty");

        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) {
        LLDB_LOG(log,
                 "NSString initializer's str element is not a ConstantExpr");

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

        return false;
      }

      GlobalVariable *cstr_global = nullptr;

      if (nsstring_expr->getOpcode() == Instruction::GetElementPtr) {
        Constant *nsstring_cstr = nsstring_expr->getOperand(0);
        cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
      } else if (nsstring_expr->getOpcode() == Instruction::BitCast) {
        Constant *nsstring_cstr = nsstring_expr->getOperand(0);
        cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
      }

      if (!cstr_global) {
        LLDB_LOG(log,
                 "NSString initializer's str element is not a GlobalVariable");

        m_error_stream.Printf("Internal error [IRForTarget]: Unhandled"
                              "constant string initializer\n");

        return false;
      }

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

        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 (cstr_array)
        LLDB_LOG(log, "Found NSString constant {0}, which contains \"{1}\"",
                 value_name, cstr_array->getAsString());
      else
        LLDB_LOG(log, "Found NSString constant {0}, which contains \"\"",
                 value_name);

      if (!cstr_array)
        cstr_global = nullptr;

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

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

        return false;
      }
    }
  }

  for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
    llvm::StringRef value_name = value_symbol.first();

    if (value_name == "__CFConstantStringClassReference") {
      GlobalVariable *gv = dyn_cast<GlobalVariable>(value_symbol.second);

      if (!gv) {
        LLDB_LOG(log,
                 "__CFConstantStringClassReference is not a global variable");

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

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

// 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();

  LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"",
           omvn_initializer_string);

  // Construct a call to sel_registerName

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

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

    LLDB_LOG(log, "Found sel_registerName at {0}", 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::FunctionType *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 = {srN_type,
                          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));

  InstrList selector_loads;

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

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

      LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C selector");

      return false;
    }
  }

  return true;
}

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

  return !(!global_variable || !global_variable->hasName() ||
           !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_"));
}

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

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

  if (!load)
    return false;

  // Unpack the class name from the reference.  In LLVM IR, a reference to an
  // Objective-C class gets represented as
  //
  // %tmp     = load %struct._objc_class*,
  //            %struct._objc_class** @OBJC_CLASS_REFERENCES_, align 4
  //
  // @"OBJC_CLASS_REFERENCES_ is a bitcast of a character array called
  // @OBJC_CLASS_NAME_. @OBJC_CLASS_NAME contains the string.

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

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

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

  Constant *ocr_initializer = _objc_class_references_->getInitializer();

  ConstantExpr *ocr_initializer_expr = dyn_cast<ConstantExpr>(ocr_initializer);

  if (!ocr_initializer_expr ||
      ocr_initializer_expr->getOpcode() != Instruction::BitCast)
    return false;

  Value *ocr_initializer_base = ocr_initializer_expr->getOperand(0);

  if (!ocr_initializer_base)
    return false;

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

  GlobalVariable *_objc_class_name_ =
      dyn_cast<GlobalVariable>(ocr_initializer_base);

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

  Constant *ocn_initializer = _objc_class_name_->getInitializer();

  ConstantDataArray *ocn_initializer_array =
      dyn_cast<ConstantDataArray>(ocn_initializer);

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

  std::string ocn_initializer_string = ocn_initializer_array->getAsString();

  LLDB_LOG(log, "Found Objective-C class reference \"{0}\"",
           ocn_initializer_string);

  // Construct a call to objc_getClass

  if (!m_objc_getClass) {
    lldb::addr_t objc_getClass_addr;

    bool missing_weak = false;
    static lldb_private::ConstString g_objc_getClass_str("objc_getClass");
    objc_getClass_addr = m_execution_unit.FindSymbol(g_objc_getClass_str,
                                                     missing_weak);
    if (objc_getClass_addr == LLDB_INVALID_ADDRESS || missing_weak)
      return false;

    LLDB_LOG(log, "Found objc_getClass at {0}", objc_getClass_addr);

    // Build the function type: %struct._objc_class *objc_getClass(i8*)

    Type *class_type = load->getType();
    Type *type_array[1];
    type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());

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

    llvm::FunctionType *ogC_type =
        FunctionType::get(class_type, ogC_arg_types, false);

    // Build the constant containing the pointer to the function
    PointerType *ogC_ptr_ty = PointerType::getUnqual(ogC_type);
    Constant *ogC_addr_int =
        ConstantInt::get(m_intptr_ty, objc_getClass_addr, false);
    m_objc_getClass = {ogC_type,
                       ConstantExpr::getIntToPtr(ogC_addr_int, ogC_ptr_ty)};
  }

  Value *argument_array[1];

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

  argument_array[0] = ocn_pointer;

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

  CallInst *ogC_call = CallInst::Create(m_objc_getClass, ogC_arguments,
                                        "objc_getClass", class_load);

  // Replace the load with the call in all users

  class_load->replaceAllUsesWith(ogC_call);

  class_load->eraseFromParent();

  return true;
}

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

  InstrList class_loads;

  for (Instruction &inst : basic_block) {
    if (LoadInst *load = dyn_cast<LoadInst>(&inst))
      if (IsObjCClassReference(load->getPointerOperand()))
        class_loads.push_back(&inst);
  }

  for (Instruction *inst : class_loads) {
    if (!RewriteObjCClassReference(inst)) {
      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
                            "static reference to an Objective-C class to a "
                            "dynamic reference\n");

      LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C class");

      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, nullptr, /* no initializer */
      alloc->getName().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);

  LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc),
           PrintValue(persistent_load));

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

  InstrList pvar_allocs;

  for (Instruction &inst : basic_block) {

    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) {
          LLDB_LOG(log, "Rejecting a numeric persistent variable.");

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

  for (Instruction *inst : pvar_allocs) {
    if (!RewritePersistentAlloc(inst)) {
      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
                            "the creation of a persistent variable\n");

      LLDB_LOG(log, "Couldn't rewrite the creation of a persistent variable");

      return false;
    }
  }

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

  LLDB_LOG(log, "MaybeHandleVariable ({0})", PrintValue(llvm_value_ptr));

  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;

      LLDB_LOG(log, "Found global variable \"{0}\" without metadata",
               global_variable->getName());

      return false;
    }

    llvm::StringRef name(named_decl->getName());

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

    lldb_private::CompilerType compiler_type(
        lldb_private::ClangASTContext::GetASTContext(
            &value_decl->getASTContext()),
        value_decl->getType().getAsOpaquePtr());

    const Type *value_type = nullptr;

    if (name.startswith("$")) {
      // 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();
    }

    llvm::Optional<uint64_t> value_size = compiler_type.GetByteSize(nullptr);
    if (!value_size)
      return false;
    llvm::Optional<size_t> opt_alignment = compiler_type.GetTypeBitAlign(nullptr);
    if (!opt_alignment)
      return false;
    lldb::offset_t value_alignment = (*opt_alignment + 7ull) / 8ull;

    LLDB_LOG(log,
             "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, "
             "align {4}]",
             name,
             lldb_private::ClangUtil::GetQualType(compiler_type).getAsString(),
             PrintType(value_type), *value_size, value_alignment);

    if (named_decl)
      m_decl_map->AddValueToStruct(named_decl, lldb_private::ConstString(name),
                                   llvm_value_ptr, *value_size,
                                   value_alignment);
  } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
    LLDB_LOG(log, "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) {
    LLDB_LOG(log, "Symbol \"{0}\" had no address", name);

    return false;
  }

  LLDB_LOG(log, "Found \"{0}\" at {1}", name, 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);

  LLDB_LOG(log, "Replacing {0} with {1}", PrintValue(symbol),
           PrintValue(symbol_addr_ptr));

  symbol->replaceAllUsesWith(symbol_addr_ptr);

  return true;
}

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

  LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old));

  for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
       op_index < num_ops; ++op_index)
    // conservatively believe that this is a store
    if (!MaybeHandleVariable(Old->getArgOperand(op_index))) {
      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);

  LLDB_LOG(log, "Found reference to Objective-C class {0} ({1})", name,
           (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) {
  std::vector<CallInst *> calls_to_remove;

  for (Instruction &inst : basic_block) {
    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 (CallInst *ci : calls_to_remove)
    ci->eraseFromParent();

  return true;
}

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

  for (Instruction &inst : basic_block) {
    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()) {
    llvm::StringRef global_name = global_var.getName();

    LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}", global_name,
             static_cast<void *>(DeclForGlobal(&global_var)));

    if (global_name.startswith("OBJC_IVAR")) {
      if (!HandleSymbol(&global_var)) {
        m_error_stream.Format("Error [IRForTarget]: Couldn't find Objective-C "
                              "indirect ivar symbol {0}\n",
                              global_name);

        return false;
      }
    } else if (global_name.contains("OBJC_CLASSLIST_REFERENCES_$")) {
      if (!HandleObjCClass(&global_var)) {
        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.contains("OBJC_CLASSLIST_SUP_REFS_$")) {
      if (!HandleObjCClass(&global_var)) {
        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)) {
        m_error_stream.Format("Internal error [IRForTarget]: Couldn't rewrite "
                              "external variable {0}\n",
                              global_name);

        return false;
      }
    }
  }

  return true;
}

static bool isGuardVariableRef(Value *V) {
  Constant *Old = dyn_cast<Constant>(V);

  if (!Old)
    return false;

  if (auto 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() || !isGuardVariableSymbol(GV->getName()))
    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.

  InstrList guard_loads;
  InstrList guard_stores;

  for (Instruction &inst : basic_block) {

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

  for (Instruction *inst : guard_loads)
    TurnGuardLoadIntoZero(inst);

  for (Instruction *inst : guard_stores)
    ExciseGuardStore(inst);

  return true;
}

// This function does not report errors; its callers are responsible.
bool IRForTarget::UnfoldConstant(Constant *old_constant,
                                 llvm::Function *llvm_function,
                                 FunctionValueCache &value_maker,
                                 FunctionValueCache &entry_instruction_finder,
                                 lldb_private::Stream &error_stream) {
  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:
          error_stream.Printf("error [IRForTarget internal]: 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, llvm_function, bit_cast_maker,
                              entry_instruction_finder, error_stream))
            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, llvm_function,
                              get_element_pointer_maker,
                              entry_instruction_finder, error_stream))
            return false;
        } break;
        }
      } else {
        error_stream.Printf(
            "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
            PrintValue(constant).c_str());
        return false;
      }
    } else {
      if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {
        if (llvm_function && inst->getParent()->getParent() != llvm_function) {
          error_stream.PutCString("error: Capturing non-local variables in "
                                  "expressions is unsupported.\n");
          return false;
        }
        inst->replaceUsesOfWith(
            old_constant, value_maker.GetValue(inst->getParent()->getParent()));
      } else {
        error_stream.Printf(
            "error [IRForTarget internal]: 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();

  LLDB_LOG(log, "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.arg_begin());

  if (iter == llvm_function.arg_end()) {
    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.arg_end()) {
      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.arg_end()) {
      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")) {
      m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes '{0}' "
                            "after 'self' argument (should take '_cmd')",
                            iter->getName());

      return false;
    }

    ++iter;

    if (iter == llvm_function.arg_end()) {
      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")) {
    m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes an "
                          "argument named '{0}' instead of the struct pointer",
                          argument->getName());

    return false;
  }

  LLDB_LOG(log, "Arg: \"{0}\"", PrintValue(argument));

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

  if (!FirstEntryInstruction) {
    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) {
    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 = nullptr;
    Value *value = nullptr;
    lldb::offset_t offset;
    lldb_private::ConstString name;

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

      return false;
    }

    LLDB_LOG(log, "  \"{0}\" (\"{1}\") placed at {2}", name,
             decl->getNameAsString(), offset);

    if (value) {
      LLDB_LOG(log, "    Replacing [{0}]", PrintValue(value));

      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)) {
        if (!UnfoldConstant(constant, &llvm_function, body_result_maker,
                            m_entry_instruction_finder, m_error_stream)) {
          return false;
        }
      } else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
        if (instruction->getParent()->getParent() != &llvm_function) {
          m_error_stream.PutCString("error: Capturing non-local variables in "
                                    "expressions is unsupported.\n");
          return false;
        }
        value->replaceAllUsesWith(
            body_result_maker.GetValue(instruction->getParent()->getParent()));
      } else {
        LLDB_LOG(log, "Unhandled non-constant type: \"{0}\"",
                 PrintValue(value));
        return false;
      }

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

  LLDB_LOG(log, "Total structure [align {0}, size {1}]", (int64_t)alignment,
           (uint64_t)size);

  return true;
}

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

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

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

    m_module->print(oss, nullptr);

    oss.flush();

    LLDB_LOG(log, "Module as passed in to IRForTarget: \n\"{0}\"", s);
  }

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

  if (!m_func_name.IsEmpty() && !main_function) {
    LLDB_LOG(log, "Couldn't find \"{0}()\" in the module", m_func_name);

    m_error_stream.Format("Internal error [IRForTarget]: Couldn't find wrapper "
                          "'{0}' in the module",
                          m_func_name);

    return false;
  }

  if (main_function) {
    if (!FixFunctionLinkage(*main_function)) {
      LLDB_LOG(log, "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", nullptr /* InsertBefore */,
      GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */);

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

  if (main_function) {
    if (!CreateResultVariable(*main_function)) {
      LLDB_LOG(log, "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, nullptr);

    oss.flush();

    LLDB_LOG(log, "Module after creating the result variable: \n\"{0}\"", s);
  }

  for (llvm::Function &function : *m_module) {
    for (BasicBlock &bb : function) {
      if (!RemoveGuards(bb)) {
        LLDB_LOG(log, "RemoveGuards() failed");

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

        return false;
      }

      if (!RewritePersistentAllocs(bb)) {
        LLDB_LOG(log, "RewritePersistentAllocs() failed");

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

        return false;
      }

      if (!RemoveCXAAtExit(bb)) {
        LLDB_LOG(log, "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()) {
    LLDB_LOG(log, "RewriteObjCConstStrings() failed");

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

    return false;
  }

  for (llvm::Function &function : *m_module) {
    for (llvm::BasicBlock &bb : function) {
      if (!RewriteObjCSelectors(bb)) {
        LLDB_LOG(log, "RewriteObjCSelectors() failed");

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

        return false;
      }

      if (!RewriteObjCClassReferences(bb)) {
        LLDB_LOG(log, "RewriteObjCClassReferences() failed");

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

        return false;
      }
    }
  }

  for (llvm::Function &function : *m_module) {
    for (BasicBlock &bb : function) {
      if (!ResolveCalls(bb)) {
        LLDB_LOG(log, "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)) {
      LLDB_LOG(log, "ResolveExternals() failed");

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

      return false;
    }

    if (!ReplaceVariables(*main_function)) {
      LLDB_LOG(log, "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, nullptr);

    oss.flush();

    LLDB_LOG(log, "Module after preparing for execution: \n\"{0}\"", s);
  }

  return true;
}

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

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