//===-- 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) {
  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) {
  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 llvm::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) {
  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);
    }

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