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

#include <mutex>
#include <utility>
#include <vector>

#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/GoASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"

#include "llvm/Support/Threading.h"

#include "Plugins/ExpressionParser/Go/GoUserExpression.h"
#include "Plugins/SymbolFile/DWARF/DWARFASTParserGo.h"

using namespace lldb;

namespace lldb_private {
class GoArray;
class GoFunction;
class GoStruct;

class GoType {
public:
  enum {
    KIND_BOOL = 1,
    KIND_INT = 2,
    KIND_INT8 = 3,
    KIND_INT16 = 4,
    KIND_INT32 = 5,
    KIND_INT64 = 6,
    KIND_UINT = 7,
    KIND_UINT8 = 8,
    KIND_UINT16 = 9,
    KIND_UINT32 = 10,
    KIND_UINT64 = 11,
    KIND_UINTPTR = 12,
    KIND_FLOAT32 = 13,
    KIND_FLOAT64 = 14,
    KIND_COMPLEX64 = 15,
    KIND_COMPLEX128 = 16,
    KIND_ARRAY = 17,
    KIND_CHAN = 18,
    KIND_FUNC = 19,
    KIND_INTERFACE = 20,
    KIND_MAP = 21,
    KIND_PTR = 22,
    KIND_SLICE = 23,
    KIND_STRING = 24,
    KIND_STRUCT = 25,
    KIND_UNSAFEPOINTER = 26,
    KIND_LLDB_VOID, // Extension for LLDB, not used by go runtime.
    KIND_MASK = (1 << 5) - 1,
    KIND_DIRECT_IFACE = 1 << 5
  };
  GoType(int kind, const ConstString &name)
      : m_kind(kind & KIND_MASK), m_name(name) {
    if (m_kind == KIND_FUNC)
      m_kind = KIND_FUNC;
  }
  virtual ~GoType() {}

  int GetGoKind() const { return m_kind; }
  const ConstString &GetName() const { return m_name; }
  virtual CompilerType GetElementType() const { return CompilerType(); }

  bool IsTypedef() const {
    switch (m_kind) {
    case KIND_CHAN:
    case KIND_MAP:
    case KIND_INTERFACE:
      return true;
    default:
      return false;
    }
  }

  GoArray *GetArray();
  GoFunction *GetFunction();
  GoStruct *GetStruct();

private:
  int m_kind;
  ConstString m_name;
  GoType(const GoType &) = delete;
  const GoType &operator=(const GoType &) = delete;
};

class GoElem : public GoType {
public:
  GoElem(int kind, const ConstString &name, const CompilerType &elem)
      : GoType(kind, name), m_elem(elem) {}
  virtual CompilerType GetElementType() const { return m_elem; }

private:
  // TODO: should we store this differently?
  CompilerType m_elem;

  GoElem(const GoElem &) = delete;
  const GoElem &operator=(const GoElem &) = delete;
};

class GoArray : public GoElem {
public:
  GoArray(const ConstString &name, uint64_t length, const CompilerType &elem)
      : GoElem(KIND_ARRAY, name, elem), m_length(length) {}

  uint64_t GetLength() const { return m_length; }

private:
  uint64_t m_length;
  GoArray(const GoArray &) = delete;
  const GoArray &operator=(const GoArray &) = delete;
};

class GoFunction : public GoType {
public:
  GoFunction(const ConstString &name, bool is_variadic)
      : GoType(KIND_FUNC, name), m_is_variadic(is_variadic) {}

  bool IsVariadic() const { return m_is_variadic; }

private:
  bool m_is_variadic;
  GoFunction(const GoFunction &) = delete;
  const GoFunction &operator=(const GoFunction &) = delete;
};

class GoStruct : public GoType {
public:
  struct Field {
    Field(const ConstString &name, const CompilerType &type, uint64_t offset)
        : m_name(name), m_type(type), m_byte_offset(offset) {}
    ConstString m_name;
    CompilerType m_type;
    uint64_t m_byte_offset;
  };

  GoStruct(int kind, const ConstString &name, int64_t byte_size)
      : GoType(kind == 0 ? KIND_STRUCT : kind, name), m_is_complete(false),
        m_byte_size(byte_size) {}

  uint32_t GetNumFields() const { return m_fields.size(); }

  const Field *GetField(uint32_t i) const {
    if (i < m_fields.size())
      return &m_fields[i];
    return nullptr;
  }

  void AddField(const ConstString &name, const CompilerType &type,
                uint64_t offset) {
    m_fields.push_back(Field(name, type, offset));
  }

  bool IsComplete() const { return m_is_complete; }

  void SetComplete() { m_is_complete = true; }

  int64_t GetByteSize() const { return m_byte_size; }

private:
  bool m_is_complete;
  int64_t m_byte_size;
  std::vector<Field> m_fields;

  GoStruct(const GoStruct &) = delete;
  const GoStruct &operator=(const GoStruct &) = delete;
};

GoArray *GoType::GetArray() {
  if (m_kind == KIND_ARRAY) {
    return static_cast<GoArray *>(this);
  }
  return nullptr;
}

GoFunction *GoType::GetFunction() {
  if (m_kind == KIND_FUNC) {
    return static_cast<GoFunction *>(this);
  }
  return nullptr;
}

GoStruct *GoType::GetStruct() {
  switch (m_kind) {
  case KIND_STRING:
  case KIND_STRUCT:
  case KIND_SLICE:
    return static_cast<GoStruct *>(this);
  }
  return nullptr;
}
} // namespace lldb_private
using namespace lldb_private;

GoASTContext::GoASTContext()
    : TypeSystem(eKindGo), m_pointer_byte_size(0), m_int_byte_size(0),
      m_types(new TypeMap) {}
GoASTContext::~GoASTContext() {}

//------------------------------------------------------------------
// PluginInterface functions
//------------------------------------------------------------------

ConstString GoASTContext::GetPluginNameStatic() { return ConstString("go"); }

ConstString GoASTContext::GetPluginName() {
  return GoASTContext::GetPluginNameStatic();
}

uint32_t GoASTContext::GetPluginVersion() { return 1; }

lldb::TypeSystemSP GoASTContext::CreateInstance(lldb::LanguageType language,
                                                Module *module, Target *target,
                                                const char *compiler_options) {
  if (language == eLanguageTypeGo) {
    ArchSpec arch;
    std::shared_ptr<GoASTContext> go_ast_sp;
    if (module) {
      arch = module->GetArchitecture();
      go_ast_sp = std::shared_ptr<GoASTContext>(new GoASTContext);
    } else if (target) {
      arch = target->GetArchitecture();
      go_ast_sp = std::shared_ptr<GoASTContextForExpr>(
          new GoASTContextForExpr(target->shared_from_this()));
    }

    if (arch.IsValid()) {
      go_ast_sp->SetAddressByteSize(arch.GetAddressByteSize());
      return go_ast_sp;
    }
  }
  return lldb::TypeSystemSP();
}

void GoASTContext::EnumerateSupportedLanguages(
    std::set<lldb::LanguageType> &languages_for_types,
    std::set<lldb::LanguageType> &languages_for_expressions) {
  static std::vector<lldb::LanguageType> s_supported_languages_for_types(
      {lldb::eLanguageTypeGo});

  static std::vector<lldb::LanguageType> s_supported_languages_for_expressions(
      {});

  languages_for_types.insert(s_supported_languages_for_types.begin(),
                             s_supported_languages_for_types.end());
  languages_for_expressions.insert(
      s_supported_languages_for_expressions.begin(),
      s_supported_languages_for_expressions.end());
}

void GoASTContext::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(), "AST context plug-in",
                                CreateInstance, EnumerateSupportedLanguages);
}

void GoASTContext::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

//----------------------------------------------------------------------
// Tests
//----------------------------------------------------------------------

bool GoASTContext::IsArrayType(lldb::opaque_compiler_type_t type,
                               CompilerType *element_type, uint64_t *size,
                               bool *is_incomplete) {
  if (element_type)
    element_type->Clear();
  if (size)
    *size = 0;
  if (is_incomplete)
    *is_incomplete = false;
  GoArray *array = static_cast<GoType *>(type)->GetArray();
  if (array) {
    if (size)
      *size = array->GetLength();
    if (element_type)
      *element_type = array->GetElementType();
    return true;
  }
  return false;
}

bool GoASTContext::IsVectorType(lldb::opaque_compiler_type_t type,
                                CompilerType *element_type, uint64_t *size) {
  if (element_type)
    element_type->Clear();
  if (size)
    *size = 0;
  return false;
}

bool GoASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) {
  int kind = static_cast<GoType *>(type)->GetGoKind();
  if (kind < GoType::KIND_ARRAY)
    return false;
  if (kind == GoType::KIND_PTR)
    return false;
  if (kind == GoType::KIND_CHAN)
    return false;
  if (kind == GoType::KIND_MAP)
    return false;
  if (kind == GoType::KIND_STRING)
    return false;
  if (kind == GoType::KIND_UNSAFEPOINTER)
    return false;
  return true;
}

bool GoASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) {
  return false;
}

bool GoASTContext::IsCharType(lldb::opaque_compiler_type_t type) {
  // Go's DWARF doesn't distinguish between rune and int32.
  return false;
}

bool GoASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) {
  if (!type)
    return false;
  GoType *t = static_cast<GoType *>(type);
  if (GoStruct *s = t->GetStruct())
    return s->IsComplete();
  if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR)
    return t->GetElementType().IsCompleteType();
  return true;
}

bool GoASTContext::IsConst(lldb::opaque_compiler_type_t type) { return false; }

bool GoASTContext::IsCStringType(lldb::opaque_compiler_type_t type,
                                 uint32_t &length) {
  return false;
}

bool GoASTContext::IsDefined(lldb::opaque_compiler_type_t type) {
  return type != nullptr;
}

bool GoASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type,
                                       uint32_t &count, bool &is_complex) {
  int kind = static_cast<GoType *>(type)->GetGoKind();
  if (kind >= GoType::KIND_FLOAT32 && kind <= GoType::KIND_COMPLEX128) {
    if (kind >= GoType::KIND_COMPLEX64) {
      is_complex = true;
      count = 2;
    } else {
      is_complex = false;
      count = 1;
    }
    return true;
  }
  count = 0;
  is_complex = false;
  return false;
}

bool GoASTContext::IsFunctionType(lldb::opaque_compiler_type_t type,
                                  bool *is_variadic_ptr) {
  GoFunction *func = static_cast<GoType *>(type)->GetFunction();
  if (func) {
    if (is_variadic_ptr)
      *is_variadic_ptr = func->IsVariadic();
    return true;
  }
  if (is_variadic_ptr)
    *is_variadic_ptr = false;
  return false;
}

uint32_t GoASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
                                              CompilerType *base_type_ptr) {
  return false;
}

size_t
GoASTContext::GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) {
  return 0;
}

CompilerType
GoASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
                                         const size_t index) {
  return CompilerType();
}

bool GoASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) {
  return IsFunctionType(type);
}

bool GoASTContext::IsBlockPointerType(lldb::opaque_compiler_type_t type,
                                      CompilerType *function_pointer_type_ptr) {
  return false;
}

bool GoASTContext::IsIntegerType(lldb::opaque_compiler_type_t type,
                                 bool &is_signed) {
  is_signed = false;
  // TODO: Is bool an integer?
  if (type) {
    int kind = static_cast<GoType *>(type)->GetGoKind();
    if (kind <= GoType::KIND_UINTPTR) {
      is_signed = (kind != GoType::KIND_BOOL) & (kind <= GoType::KIND_INT64);
      return true;
    }
  }
  return false;
}

bool GoASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) {
  return false;
}

bool GoASTContext::IsPossibleDynamicType(
    lldb::opaque_compiler_type_t type,
    CompilerType *target_type, // Can pass NULL
    bool check_cplusplus, bool check_objc, bool check_swift) {
  if (target_type)
    target_type->Clear();
  if (type)
    return static_cast<GoType *>(type)->GetGoKind() == GoType::KIND_INTERFACE;
  return false;
}

bool GoASTContext::IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) {
  return false;
}

bool GoASTContext::IsPointerType(lldb::opaque_compiler_type_t type,
                                 CompilerType *pointee_type) {
  if (!type)
    return false;
  GoType *t = static_cast<GoType *>(type);
  if (pointee_type) {
    *pointee_type = t->GetElementType();
  }
  switch (t->GetGoKind()) {
  case GoType::KIND_PTR:
  case GoType::KIND_UNSAFEPOINTER:
  case GoType::KIND_CHAN:
  case GoType::KIND_MAP:
    // TODO: is function a pointer?
    return true;
  default:
    return false;
  }
}

bool GoASTContext::IsPointerOrReferenceType(lldb::opaque_compiler_type_t type,
                                            CompilerType *pointee_type) {
  return IsPointerType(type, pointee_type);
}

bool GoASTContext::IsReferenceType(lldb::opaque_compiler_type_t type,
                                   CompilerType *pointee_type,
                                   bool *is_rvalue) {
  return false;
}

bool GoASTContext::IsScalarType(lldb::opaque_compiler_type_t type) {
  return !IsAggregateType(type);
}

bool GoASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) {
  if (type)
    return static_cast<GoType *>(type)->IsTypedef();
  return false;
}

bool GoASTContext::IsVoidType(lldb::opaque_compiler_type_t type) {
  if (!type)
    return false;
  return static_cast<GoType *>(type)->GetGoKind() == GoType::KIND_LLDB_VOID;
}

bool GoASTContext::SupportsLanguage(lldb::LanguageType language) {
  return language == eLanguageTypeGo;
}

//----------------------------------------------------------------------
// Type Completion
//----------------------------------------------------------------------

bool GoASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) {
  if (!type)
    return false;
  GoType *t = static_cast<GoType *>(type);
  if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR || t->GetArray())
    return t->GetElementType().GetCompleteType();
  if (GoStruct *s = t->GetStruct()) {
    if (s->IsComplete())
      return true;
    CompilerType compiler_type(this, s);
    SymbolFile *symbols = GetSymbolFile();
    return symbols && symbols->CompleteType(compiler_type);
  }
  return true;
}

//----------------------------------------------------------------------
// AST related queries
//----------------------------------------------------------------------

uint32_t GoASTContext::GetPointerByteSize() { return m_pointer_byte_size; }

//----------------------------------------------------------------------
// Accessors
//----------------------------------------------------------------------

ConstString GoASTContext::GetTypeName(lldb::opaque_compiler_type_t type) {
  if (type)
    return static_cast<GoType *>(type)->GetName();
  return ConstString();
}

uint32_t
GoASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type,
                          CompilerType *pointee_or_element_compiler_type) {
  if (pointee_or_element_compiler_type)
    pointee_or_element_compiler_type->Clear();
  if (!type)
    return 0;
  GoType *t = static_cast<GoType *>(type);
  if (pointee_or_element_compiler_type)
    *pointee_or_element_compiler_type = t->GetElementType();
  int kind = t->GetGoKind();
  if (kind == GoType::KIND_ARRAY)
    return eTypeHasChildren | eTypeIsArray;
  if (kind < GoType::KIND_ARRAY) {
    uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue;
    if (kind < GoType::KIND_FLOAT32) {
      builtin_type_flags |= eTypeIsInteger | eTypeIsScalar;
      if (kind >= GoType::KIND_INT && kind <= GoType::KIND_INT64)
        builtin_type_flags |= eTypeIsSigned;
    } else {
      builtin_type_flags |= eTypeIsFloat;
      if (kind < GoType::KIND_COMPLEX64)
        builtin_type_flags |= eTypeIsComplex;
      else
        builtin_type_flags |= eTypeIsScalar;
    }
    return builtin_type_flags;
  }
  if (kind == GoType::KIND_STRING)
    return eTypeHasValue | eTypeIsBuiltIn;
  if (kind == GoType::KIND_FUNC)
    return eTypeIsFuncPrototype | eTypeHasValue;
  if (IsPointerType(type))
    return eTypeIsPointer | eTypeHasValue | eTypeHasChildren;
  if (kind == GoType::KIND_LLDB_VOID)
    return 0;
  return eTypeHasChildren | eTypeIsStructUnion;
}

lldb::TypeClass GoASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) {
  if (!type)
    return eTypeClassInvalid;
  int kind = static_cast<GoType *>(type)->GetGoKind();
  if (kind == GoType::KIND_FUNC)
    return eTypeClassFunction;
  if (IsPointerType(type))
    return eTypeClassPointer;
  if (kind < GoType::KIND_COMPLEX64)
    return eTypeClassBuiltin;
  if (kind <= GoType::KIND_COMPLEX128)
    return eTypeClassComplexFloat;
  if (kind == GoType::KIND_LLDB_VOID)
    return eTypeClassInvalid;
  return eTypeClassStruct;
}

lldb::BasicType
GoASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
  ConstString name = GetTypeName(type);
  if (name) {
    typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
    static TypeNameToBasicTypeMap g_type_map;
    static std::once_flag g_once_flag;
    llvm::call_once(g_once_flag, []() {
      // "void"
      g_type_map.Append(ConstString("void"), eBasicTypeVoid);
      // "int"
      g_type_map.Append(ConstString("int"), eBasicTypeInt);
      g_type_map.Append(ConstString("uint"), eBasicTypeUnsignedInt);

      // Miscellaneous
      g_type_map.Append(ConstString("bool"), eBasicTypeBool);

      // Others. Should these map to C types?
      g_type_map.Append(ConstString("byte"), eBasicTypeOther);
      g_type_map.Append(ConstString("uint8"), eBasicTypeOther);
      g_type_map.Append(ConstString("uint16"), eBasicTypeOther);
      g_type_map.Append(ConstString("uint32"), eBasicTypeOther);
      g_type_map.Append(ConstString("uint64"), eBasicTypeOther);
      g_type_map.Append(ConstString("int8"), eBasicTypeOther);
      g_type_map.Append(ConstString("int16"), eBasicTypeOther);
      g_type_map.Append(ConstString("int32"), eBasicTypeOther);
      g_type_map.Append(ConstString("int64"), eBasicTypeOther);
      g_type_map.Append(ConstString("float32"), eBasicTypeOther);
      g_type_map.Append(ConstString("float64"), eBasicTypeOther);
      g_type_map.Append(ConstString("uintptr"), eBasicTypeOther);

      g_type_map.Sort();
    });

    return g_type_map.Find(name, eBasicTypeInvalid);
  }
  return eBasicTypeInvalid;
}

lldb::LanguageType
GoASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) {
  return lldb::eLanguageTypeGo;
}

unsigned GoASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) {
  return 0;
}

//----------------------------------------------------------------------
// Creating related types
//----------------------------------------------------------------------

CompilerType
GoASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type,
                                  uint64_t *stride) {
  GoArray *array = static_cast<GoType *>(type)->GetArray();
  if (array) {
    if (stride) {
      *stride = array->GetElementType().GetByteSize(nullptr);
    }
    return array->GetElementType();
  }
  return CompilerType();
}

CompilerType GoASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) {
  GoType *t = static_cast<GoType *>(type);
  if (t->IsTypedef())
    return t->GetElementType();
  return CompilerType(this, type);
}

CompilerType
GoASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) {
  return CompilerType(this, type);
}

// Returns -1 if this isn't a function of if the function doesn't have a
// prototype
// Returns a value >= 0 if there is a prototype.
int GoASTContext::GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) {
  return GetNumberOfFunctionArguments(type);
}

CompilerType
GoASTContext::GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type,
                                             size_t idx) {
  return GetFunctionArgumentAtIndex(type, idx);
}

CompilerType
GoASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) {
  CompilerType result;
  if (type) {
    GoType *t = static_cast<GoType *>(type);
    if (t->GetGoKind() == GoType::KIND_FUNC)
      result = t->GetElementType();
  }
  return result;
}

size_t GoASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) {
  return 0;
}

TypeMemberFunctionImpl
GoASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
                                       size_t idx) {
  return TypeMemberFunctionImpl();
}

CompilerType
GoASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) {
  return CompilerType(this, type);
}

CompilerType GoASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) {
  if (!type)
    return CompilerType();
  return static_cast<GoType *>(type)->GetElementType();
}

CompilerType GoASTContext::GetPointerType(lldb::opaque_compiler_type_t type) {
  if (!type)
    return CompilerType();
  ConstString type_name = GetTypeName(type);
  ConstString pointer_name(std::string("*") + type_name.GetCString());
  GoType *pointer = (*m_types)[pointer_name].get();
  if (pointer == nullptr) {
    pointer =
        new GoElem(GoType::KIND_PTR, pointer_name, CompilerType(this, type));
    (*m_types)[pointer_name].reset(pointer);
  }
  return CompilerType(this, pointer);
}

// If the current object represents a typedef type, get the underlying type
CompilerType GoASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) {
  if (IsTypedefType(type))
    return static_cast<GoType *>(type)->GetElementType();
  return CompilerType();
}

//----------------------------------------------------------------------
// Create related types using the current type's AST
//----------------------------------------------------------------------
CompilerType GoASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) {
  return CompilerType();
}

CompilerType
GoASTContext::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
                                                  size_t bit_size) {
  return CompilerType();
}

//----------------------------------------------------------------------
// Exploring the type
//----------------------------------------------------------------------

uint64_t GoASTContext::GetBitSize(lldb::opaque_compiler_type_t type,
                                  ExecutionContextScope *exe_scope) {
  if (!type)
    return 0;
  if (!GetCompleteType(type))
    return 0;
  GoType *t = static_cast<GoType *>(type);
  GoArray *array = nullptr;
  switch (t->GetGoKind()) {
  case GoType::KIND_BOOL:
  case GoType::KIND_INT8:
  case GoType::KIND_UINT8:
    return 8;
  case GoType::KIND_INT16:
  case GoType::KIND_UINT16:
    return 16;
  case GoType::KIND_INT32:
  case GoType::KIND_UINT32:
  case GoType::KIND_FLOAT32:
    return 32;
  case GoType::KIND_INT64:
  case GoType::KIND_UINT64:
  case GoType::KIND_FLOAT64:
  case GoType::KIND_COMPLEX64:
    return 64;
  case GoType::KIND_COMPLEX128:
    return 128;
  case GoType::KIND_INT:
  case GoType::KIND_UINT:
    return m_int_byte_size * 8;
  case GoType::KIND_UINTPTR:
  case GoType::KIND_FUNC: // I assume this is a pointer?
  case GoType::KIND_CHAN:
  case GoType::KIND_PTR:
  case GoType::KIND_UNSAFEPOINTER:
  case GoType::KIND_MAP:
    return m_pointer_byte_size * 8;
  case GoType::KIND_ARRAY:
    array = t->GetArray();
    return array->GetLength() * array->GetElementType().GetBitSize(exe_scope);
  case GoType::KIND_INTERFACE:
    return t->GetElementType().GetBitSize(exe_scope);
  case GoType::KIND_SLICE:
  case GoType::KIND_STRING:
  case GoType::KIND_STRUCT:
    return t->GetStruct()->GetByteSize() * 8;
  default:
    assert(false);
  }
  return 0;
}

lldb::Encoding GoASTContext::GetEncoding(lldb::opaque_compiler_type_t type,
                                         uint64_t &count) {
  count = 1;
  bool is_signed;
  if (IsIntegerType(type, is_signed))
    return is_signed ? lldb::eEncodingSint : eEncodingUint;
  bool is_complex;
  uint32_t complex_count;
  if (IsFloatingPointType(type, complex_count, is_complex)) {
    count = complex_count;
    return eEncodingIEEE754;
  }
  if (IsPointerType(type))
    return eEncodingUint;
  return eEncodingInvalid;
}

lldb::Format GoASTContext::GetFormat(lldb::opaque_compiler_type_t type) {
  if (!type)
    return eFormatDefault;
  switch (static_cast<GoType *>(type)->GetGoKind()) {
  case GoType::KIND_BOOL:
    return eFormatBoolean;
  case GoType::KIND_INT:
  case GoType::KIND_INT8:
  case GoType::KIND_INT16:
  case GoType::KIND_INT32:
  case GoType::KIND_INT64:
    return eFormatDecimal;
  case GoType::KIND_UINT:
  case GoType::KIND_UINT8:
  case GoType::KIND_UINT16:
  case GoType::KIND_UINT32:
  case GoType::KIND_UINT64:
    return eFormatUnsigned;
  case GoType::KIND_FLOAT32:
  case GoType::KIND_FLOAT64:
    return eFormatFloat;
  case GoType::KIND_COMPLEX64:
  case GoType::KIND_COMPLEX128:
    return eFormatComplexFloat;
  case GoType::KIND_UINTPTR:
  case GoType::KIND_CHAN:
  case GoType::KIND_PTR:
  case GoType::KIND_MAP:
  case GoType::KIND_UNSAFEPOINTER:
    return eFormatHex;
  case GoType::KIND_STRING:
    return eFormatCString;
  case GoType::KIND_ARRAY:
  case GoType::KIND_INTERFACE:
  case GoType::KIND_SLICE:
  case GoType::KIND_STRUCT:
  default:
    // Don't know how to display this.
    return eFormatBytes;
  }
}

size_t GoASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) {
  return 0;
}

uint32_t GoASTContext::GetNumChildren(lldb::opaque_compiler_type_t type,
                                      bool omit_empty_base_classes) {
  if (!type || !GetCompleteType(type))
    return 0;
  GoType *t = static_cast<GoType *>(type);
  if (t->GetGoKind() == GoType::KIND_PTR) {
    CompilerType elem = t->GetElementType();
    if (elem.IsAggregateType())
      return elem.GetNumChildren(omit_empty_base_classes);
    return 1;
  } else if (GoArray *array = t->GetArray()) {
    return array->GetLength();
  } else if (t->IsTypedef()) {
    return t->GetElementType().GetNumChildren(omit_empty_base_classes);
  }

  return GetNumFields(type);
}

uint32_t GoASTContext::GetNumFields(lldb::opaque_compiler_type_t type) {
  if (!type || !GetCompleteType(type))
    return 0;
  GoType *t = static_cast<GoType *>(type);
  if (t->IsTypedef())
    return t->GetElementType().GetNumFields();
  GoStruct *s = t->GetStruct();
  if (s)
    return s->GetNumFields();
  return 0;
}

CompilerType GoASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
                                           size_t idx, std::string &name,
                                           uint64_t *bit_offset_ptr,
                                           uint32_t *bitfield_bit_size_ptr,
                                           bool *is_bitfield_ptr) {
  if (bit_offset_ptr)
    *bit_offset_ptr = 0;
  if (bitfield_bit_size_ptr)
    *bitfield_bit_size_ptr = 0;
  if (is_bitfield_ptr)
    *is_bitfield_ptr = false;

  if (!type || !GetCompleteType(type))
    return CompilerType();

  GoType *t = static_cast<GoType *>(type);
  if (t->IsTypedef())
    return t->GetElementType().GetFieldAtIndex(
        idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr);

  GoStruct *s = t->GetStruct();
  if (s) {
    const auto *field = s->GetField(idx);
    if (field) {
      name = field->m_name.GetStringRef();
      if (bit_offset_ptr)
        *bit_offset_ptr = field->m_byte_offset * 8;
      return field->m_type;
    }
  }
  return CompilerType();
}

CompilerType GoASTContext::GetChildCompilerTypeAtIndex(
    lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
    bool transparent_pointers, bool omit_empty_base_classes,
    bool ignore_array_bounds, std::string &child_name,
    uint32_t &child_byte_size, int32_t &child_byte_offset,
    uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
    bool &child_is_base_class, bool &child_is_deref_of_parent,
    ValueObject *valobj, uint64_t &language_flags) {
  child_name.clear();
  child_byte_size = 0;
  child_byte_offset = 0;
  child_bitfield_bit_size = 0;
  child_bitfield_bit_offset = 0;
  child_is_base_class = false;
  child_is_deref_of_parent = false;
  language_flags = 0;

  if (!type || !GetCompleteType(type))
    return CompilerType();

  GoType *t = static_cast<GoType *>(type);
  if (t->GetStruct()) {
    uint64_t bit_offset;
    CompilerType ret =
        GetFieldAtIndex(type, idx, child_name, &bit_offset, nullptr, nullptr);
    child_byte_size = ret.GetByteSize(
        exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
    child_byte_offset = bit_offset / 8;
    return ret;
  } else if (t->GetGoKind() == GoType::KIND_PTR) {
    CompilerType pointee = t->GetElementType();
    if (!pointee.IsValid() || pointee.IsVoidType())
      return CompilerType();
    if (transparent_pointers && pointee.IsAggregateType()) {
      bool tmp_child_is_deref_of_parent = false;
      return pointee.GetChildCompilerTypeAtIndex(
          exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
          ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
          child_bitfield_bit_size, child_bitfield_bit_offset,
          child_is_base_class, tmp_child_is_deref_of_parent, valobj,
          language_flags);
    } else {
      child_is_deref_of_parent = true;
      const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
      if (parent_name) {
        child_name.assign(1, '*');
        child_name += parent_name;
      }

      // We have a pointer to an simple type
      if (idx == 0 && pointee.GetCompleteType()) {
        child_byte_size = pointee.GetByteSize(
            exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
        child_byte_offset = 0;
        return pointee;
      }
    }
  } else if (GoArray *a = t->GetArray()) {
    if (ignore_array_bounds || idx < a->GetLength()) {
      CompilerType element_type = a->GetElementType();
      if (element_type.GetCompleteType()) {
        char element_name[64];
        ::snprintf(element_name, sizeof(element_name), "[%zu]", idx);
        child_name.assign(element_name);
        child_byte_size = element_type.GetByteSize(
            exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
        child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
        return element_type;
      }
    }
  } else if (t->IsTypedef()) {
    return t->GetElementType().GetChildCompilerTypeAtIndex(
        exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
        ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
        child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
        child_is_deref_of_parent, valobj, language_flags);
  }
  return CompilerType();
}

// Lookup a child given a name. This function will match base class names
// and member member names in "clang_type" only, not descendants.
uint32_t
GoASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
                                      const char *name,
                                      bool omit_empty_base_classes) {
  if (!type || !GetCompleteType(type))
    return UINT_MAX;

  GoType *t = static_cast<GoType *>(type);
  GoStruct *s = t->GetStruct();
  if (s) {
    for (uint32_t i = 0; i < s->GetNumFields(); ++i) {
      const GoStruct::Field *f = s->GetField(i);
      if (f->m_name.GetStringRef() == name)
        return i;
    }
  } else if (t->GetGoKind() == GoType::KIND_PTR || t->IsTypedef()) {
    return t->GetElementType().GetIndexOfChildWithName(name,
                                                       omit_empty_base_classes);
  }
  return UINT_MAX;
}

// Lookup a child member given a name. This function will match member names
// only and will descend into "clang_type" children in search for the first
// member in this class, or any base class that matches "name".
// TODO: Return all matches for a given name by returning a
// vector<vector<uint32_t>>
// so we catch all names that match a given child name, not just the first.
size_t GoASTContext::GetIndexOfChildMemberWithName(
    lldb::opaque_compiler_type_t type, const char *name,
    bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) {
  uint32_t index = GetIndexOfChildWithName(type, name, omit_empty_base_classes);
  if (index == UINT_MAX)
    return 0;
  child_indexes.push_back(index);
  return 1;
}

// Converts "s" to a floating point value and place resulting floating
// point bytes in the "dst" buffer.
size_t
GoASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
                                        const char *s, uint8_t *dst,
                                        size_t dst_size) {
  assert(false);
  return 0;
}
//----------------------------------------------------------------------
// Dumping types
//----------------------------------------------------------------------
#define DEPTH_INCREMENT 2

void GoASTContext::DumpValue(lldb::opaque_compiler_type_t type,
                             ExecutionContext *exe_ctx, Stream *s,
                             lldb::Format format, const DataExtractor &data,
                             lldb::offset_t data_byte_offset,
                             size_t data_byte_size, uint32_t bitfield_bit_size,
                             uint32_t bitfield_bit_offset, bool show_types,
                             bool show_summary, bool verbose, uint32_t depth) {
  if (IsTypedefType(type))
    type = GetTypedefedType(type).GetOpaqueQualType();
  if (!type)
    return;
  GoType *t = static_cast<GoType *>(type);

  if (GoStruct *st = t->GetStruct()) {
    if (GetCompleteType(type)) {
      uint32_t field_idx = 0;
      for (auto *field = st->GetField(field_idx); field != nullptr;
           field_idx++) {
        // Print the starting squiggly bracket (if this is the
        // first member) or comma (for member 2 and beyond) for
        // the struct/union/class member.
        if (field_idx == 0)
          s->PutChar('{');
        else
          s->PutChar(',');

        // Indent
        s->Printf("\n%*s", depth + DEPTH_INCREMENT, "");

        // Print the member type if requested
        if (show_types) {
          ConstString field_type_name = field->m_type.GetTypeName();
          s->Printf("(%s) ", field_type_name.AsCString());
        }
        // Print the member name and equal sign
        s->Printf("%s = ", field->m_name.AsCString());

        // Dump the value of the member
        CompilerType field_type = field->m_type;
        field_type.DumpValue(
            exe_ctx,
            s, // Stream to dump to
            field_type
                .GetFormat(), // The format with which to display the member
            data,             // Data buffer containing all bytes for this type
            data_byte_offset + field->m_byte_offset, // Offset into "data" where
                                                     // to grab value from
            field->m_type.GetByteSize(
                exe_ctx->GetBestExecutionContextScope()), // Size of this type
                                                          // in bytes
            0,                                            // Bitfield bit size
            0,                                            // Bitfield bit offset
            show_types,   // Boolean indicating if we should show the variable
                          // types
            show_summary, // Boolean indicating if we should show a summary for
                          // the current type
            verbose,      // Verbose output?
            depth + DEPTH_INCREMENT); // Scope depth for any types that have
                                      // children
      }

      // Indent the trailing squiggly bracket
      if (field_idx > 0)
        s->Printf("\n%*s}", depth, "");
    }
  }

  if (GoArray *a = t->GetArray()) {
    CompilerType element_clang_type = a->GetElementType();
    lldb::Format element_format = element_clang_type.GetFormat();
    uint32_t element_byte_size =
        element_clang_type.GetByteSize(exe_ctx->GetBestExecutionContextScope());

    uint64_t element_idx;
    for (element_idx = 0; element_idx < a->GetLength(); ++element_idx) {
      // Print the starting squiggly bracket (if this is the
      // first member) or comman (for member 2 and beyong) for
      // the struct/union/class member.
      if (element_idx == 0)
        s->PutChar('{');
      else
        s->PutChar(',');

      // Indent and print the index
      s->Printf("\n%*s[%" PRIu64 "] ", depth + DEPTH_INCREMENT, "",
                element_idx);

      // Figure out the field offset within the current struct/union/class type
      uint64_t element_offset = element_idx * element_byte_size;

      // Dump the value of the member
      element_clang_type.DumpValue(
          exe_ctx,
          s,              // Stream to dump to
          element_format, // The format with which to display the element
          data,           // Data buffer containing all bytes for this type
          data_byte_offset +
              element_offset, // Offset into "data" where to grab value from
          element_byte_size,  // Size of this type in bytes
          0,                  // Bitfield bit size
          0,                  // Bitfield bit offset
          show_types, // Boolean indicating if we should show the variable types
          show_summary, // Boolean indicating if we should show a summary for
                        // the current type
          verbose,      // Verbose output?
          depth +
              DEPTH_INCREMENT); // Scope depth for any types that have children
    }

    // Indent the trailing squiggly bracket
    if (element_idx > 0)
      s->Printf("\n%*s}", depth, "");
  }

  if (show_summary)
    DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size);
}

bool GoASTContext::DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s,
                                 lldb::Format format, const DataExtractor &data,
                                 lldb::offset_t byte_offset, size_t byte_size,
                                 uint32_t bitfield_bit_size,
                                 uint32_t bitfield_bit_offset,
                                 ExecutionContextScope *exe_scope,
                                 bool is_base_class) {
  if (!type)
    return false;
  if (IsAggregateType(type)) {
    return false;
  } else {
    GoType *t = static_cast<GoType *>(type);
    if (t->IsTypedef()) {
      CompilerType typedef_compiler_type = t->GetElementType();
      if (format == eFormatDefault)
        format = typedef_compiler_type.GetFormat();
      uint64_t typedef_byte_size = typedef_compiler_type.GetByteSize(exe_scope);

      return typedef_compiler_type.DumpTypeValue(
          s,
          format,            // The format with which to display the element
          data,              // Data buffer containing all bytes for this type
          byte_offset,       // Offset into "data" where to grab value from
          typedef_byte_size, // Size of this type in bytes
          bitfield_bit_size, // Size in bits of a bitfield value, if zero don't
                             // treat as a bitfield
          bitfield_bit_offset, // Offset in bits of a bitfield value if
                               // bitfield_bit_size != 0
          exe_scope, is_base_class);
    }

    uint32_t item_count = 1;
    // A few formats, we might need to modify our size and count for depending
    // on how we are trying to display the value...
    switch (format) {
    default:
    case eFormatBoolean:
    case eFormatBinary:
    case eFormatComplex:
    case eFormatCString: // NULL terminated C strings
    case eFormatDecimal:
    case eFormatEnum:
    case eFormatHex:
    case eFormatHexUppercase:
    case eFormatFloat:
    case eFormatOctal:
    case eFormatOSType:
    case eFormatUnsigned:
    case eFormatPointer:
    case eFormatVectorOfChar:
    case eFormatVectorOfSInt8:
    case eFormatVectorOfUInt8:
    case eFormatVectorOfSInt16:
    case eFormatVectorOfUInt16:
    case eFormatVectorOfSInt32:
    case eFormatVectorOfUInt32:
    case eFormatVectorOfSInt64:
    case eFormatVectorOfUInt64:
    case eFormatVectorOfFloat32:
    case eFormatVectorOfFloat64:
    case eFormatVectorOfUInt128:
      break;

    case eFormatChar:
    case eFormatCharPrintable:
    case eFormatCharArray:
    case eFormatBytes:
    case eFormatBytesWithASCII:
      item_count = byte_size;
      byte_size = 1;
      break;

    case eFormatUnicode16:
      item_count = byte_size / 2;
      byte_size = 2;
      break;

    case eFormatUnicode32:
      item_count = byte_size / 4;
      byte_size = 4;
      break;
    }
    return DumpDataExtractor(data, s, byte_offset, format, byte_size,
                             item_count, UINT32_MAX, LLDB_INVALID_ADDRESS,
                             bitfield_bit_size, bitfield_bit_offset, exe_scope);
  }
  return 0;
}

void GoASTContext::DumpSummary(lldb::opaque_compiler_type_t type,
                               ExecutionContext *exe_ctx, Stream *s,
                               const DataExtractor &data,
                               lldb::offset_t data_offset,
                               size_t data_byte_size) {
  if (type && GoType::KIND_STRING == static_cast<GoType *>(type)->GetGoKind()) {
    // TODO(ribrdb): read length and data
  }
}

void GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) {
  // Dump to stdout
  StreamFile s(stdout, false);
  DumpTypeDescription(type, &s);
}

void GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type,
                                       Stream *s) {
  if (!type)
    return;
  ConstString name = GetTypeName(type);
  GoType *t = static_cast<GoType *>(type);

  if (GoStruct *st = t->GetStruct()) {
    if (GetCompleteType(type)) {
      if (NULL == strchr(name.AsCString(), '{'))
        s->Printf("type %s ", name.AsCString());
      s->PutCString("struct {");
      if (st->GetNumFields() == 0) {
        s->PutChar('}');
        return;
      }
      s->IndentMore();
      uint32_t field_idx = 0;
      for (auto *field = st->GetField(field_idx); field != nullptr;
           field_idx++) {
        s->PutChar('\n');
        s->Indent();
        s->Printf("%s %s", field->m_name.AsCString(),
                  field->m_type.GetTypeName().AsCString());
      }
      s->IndentLess();
      s->PutChar('\n');
      s->Indent("}");
      return;
    }
  }

  s->PutCString(name.AsCString());
}

CompilerType GoASTContext::CreateArrayType(const ConstString &name,
                                           const CompilerType &element_type,
                                           uint64_t length) {
  GoType *type = new GoArray(name, length, element_type);
  (*m_types)[name].reset(type);
  return CompilerType(this, type);
}

CompilerType GoASTContext::CreateBaseType(int go_kind,
                                          const lldb_private::ConstString &name,
                                          uint64_t byte_size) {
  if (go_kind == GoType::KIND_UINT || go_kind == GoType::KIND_INT)
    m_int_byte_size = byte_size;
  GoType *type = new GoType(go_kind, name);
  (*m_types)[name].reset(type);
  return CompilerType(this, type);
}

CompilerType GoASTContext::CreateTypedefType(int kind, const ConstString &name,
                                             CompilerType impl) {
  GoType *type = new GoElem(kind, name, impl);
  (*m_types)[name].reset(type);
  return CompilerType(this, type);
}

CompilerType
GoASTContext::CreateVoidType(const lldb_private::ConstString &name) {
  GoType *type = new GoType(GoType::KIND_LLDB_VOID, name);
  (*m_types)[name].reset(type);
  return CompilerType(this, type);
}

CompilerType
GoASTContext::CreateStructType(int kind, const lldb_private::ConstString &name,
                               uint32_t byte_size) {
  GoType *type = new GoStruct(kind, name, byte_size);
  (*m_types)[name].reset(type);
  return CompilerType(this, type);
}

void GoASTContext::AddFieldToStruct(
    const lldb_private::CompilerType &struct_type,
    const lldb_private::ConstString &name,
    const lldb_private::CompilerType &field_type, uint32_t byte_offset) {
  if (!struct_type)
    return;
  GoASTContext *ast =
      llvm::dyn_cast_or_null<GoASTContext>(struct_type.GetTypeSystem());
  if (!ast)
    return;
  GoType *type = static_cast<GoType *>(struct_type.GetOpaqueQualType());
  if (GoStruct *s = type->GetStruct())
    s->AddField(name, field_type, byte_offset);
}

void GoASTContext::CompleteStructType(
    const lldb_private::CompilerType &struct_type) {
  if (!struct_type)
    return;
  GoASTContext *ast =
      llvm::dyn_cast_or_null<GoASTContext>(struct_type.GetTypeSystem());
  if (!ast)
    return;
  GoType *type = static_cast<GoType *>(struct_type.GetOpaqueQualType());
  if (GoStruct *s = type->GetStruct())
    s->SetComplete();
}

CompilerType
GoASTContext::CreateFunctionType(const lldb_private::ConstString &name,
                                 CompilerType *params, size_t params_count,
                                 bool is_variadic) {
  GoType *type = new GoFunction(name, is_variadic);
  (*m_types)[name].reset(type);
  return CompilerType(this, type);
}

bool GoASTContext::IsGoString(const lldb_private::CompilerType &type) {
  if (!type.IsValid() ||
      !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
    return false;
  return GoType::KIND_STRING ==
         static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
}

bool GoASTContext::IsGoSlice(const lldb_private::CompilerType &type) {
  if (!type.IsValid() ||
      !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
    return false;
  return GoType::KIND_SLICE ==
         static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
}

bool GoASTContext::IsGoInterface(const lldb_private::CompilerType &type) {
  if (!type.IsValid() ||
      !llvm::dyn_cast_or_null<GoASTContext>(type.GetTypeSystem()))
    return false;
  return GoType::KIND_INTERFACE ==
         static_cast<GoType *>(type.GetOpaqueQualType())->GetGoKind();
}

bool GoASTContext::IsPointerKind(uint8_t kind) {
  return (kind & GoType::KIND_MASK) == GoType::KIND_PTR;
}

bool GoASTContext::IsDirectIface(uint8_t kind) {
  return (kind & GoType::KIND_DIRECT_IFACE) == GoType::KIND_DIRECT_IFACE;
}

DWARFASTParser *GoASTContext::GetDWARFParser() {
  if (!m_dwarf_ast_parser_ap)
    m_dwarf_ast_parser_ap.reset(new DWARFASTParserGo(*this));
  return m_dwarf_ast_parser_ap.get();
}

UserExpression *GoASTContextForExpr::GetUserExpression(
    llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
    Expression::ResultType desired_type,
    const EvaluateExpressionOptions &options) {
  TargetSP target = m_target_wp.lock();
  if (target)
    return new GoUserExpression(*target, expr, prefix, language, desired_type,
                                options);
  return nullptr;
}
