Esempio n. 1
0
static LLVMMetadataRef make_debug_field(compile_t* c, reach_type_t* t,
  uint32_t i)
{
  const char* name;
  char buf[32];
  unsigned flags = 0;
  uint64_t offset = 0;
  ast_t* ast;

  if(t->underlying != TK_TUPLETYPE)
  {
    ast_t* def = (ast_t*)ast_data(t->ast);
    ast_t* members = ast_childidx(def, 4);
    ast = ast_childidx(members, i);
    name = ast_name(ast_child(ast));

    if(is_name_private(name))
      flags |= DW_FLAG_Private;

    uint32_t extra = 0;

    if(t->underlying != TK_STRUCT)
      extra++;

    if(t->underlying == TK_ACTOR)
      extra++;

    offset = LLVMOffsetOfElement(c->target_data, t->structure, i + extra);
  } else {
    snprintf(buf, 32, "_%d", i + 1);
    name = buf;
    ast = t->ast;
    offset = LLVMOffsetOfElement(c->target_data, t->primitive, i);
  }

  LLVMTypeRef type;
  LLVMMetadataRef di_type;

  if(t->fields[i].embed)
  {
    type = t->fields[i].type->structure;
    di_type = t->fields[i].type->di_type_embed;
  } else {
    type = t->fields[i].type->use_type;
    di_type = t->fields[i].type->di_type;
  }

  uint64_t size = LLVMABISizeOfType(c->target_data, type);
  uint64_t align = LLVMABIAlignmentOfType(c->target_data, type);

  return LLVMDIBuilderCreateMemberType(c->di, c->di_unit, name, t->di_file,
    (unsigned)ast_line(ast), 8 * size, 8 * align, 8 * offset, flags, di_type);
}
Esempio n. 2
0
static LLVMValueRef field_loc(compile_t* c, LLVMValueRef offset,
  LLVMTypeRef structure, LLVMTypeRef ftype, int index)
{
  LLVMValueRef f_offset = LLVMBuildAdd(c->builder, offset,
    LLVMConstInt(c->intptr,
      LLVMOffsetOfElement(c->target_data, structure, index), false), "");

  return LLVMBuildIntToPtr(c->builder, f_offset,
    LLVMPointerType(ftype, 0), "");
}
Esempio n. 3
0
static LLVMValueRef make_field_list(compile_t* c, gentype_t* g)
{
  // The list is an array of field descriptors.
  int count;

  if(g->underlying == TK_TUPLETYPE)
    count = g->field_count;
  else
    count = 0;

  LLVMTypeRef type = LLVMArrayType(c->field_descriptor, count);

  // If we aren't a tuple, return a null pointer to a list.
  if(count == 0)
    return LLVMConstNull(LLVMPointerType(type, 0));

  // Create a constant array of field descriptors.
  size_t buf_size = count *sizeof(LLVMValueRef);
  LLVMValueRef* list = (LLVMValueRef*)pool_alloc_size(buf_size);

  for(int i = 0; i < count; i++)
  {
    gentype_t fg;

    if(!gentype(c, g->fields[i], &fg))
      return NULL;

    LLVMValueRef fdesc[2];
    fdesc[0] = LLVMConstInt(c->i32,
      LLVMOffsetOfElement(c->target_data, g->primitive, i), false);

    if(fg.desc != NULL)
    {
      // We are a concrete type.
      fdesc[1] = LLVMConstBitCast(fg.desc, c->descriptor_ptr);
    } else {
      // We aren't a concrete type.
      fdesc[1] = LLVMConstNull(c->descriptor_ptr);
    }

    list[i] = LLVMConstStructInContext(c->context, fdesc, 2, false);
  }

  LLVMValueRef field_array = LLVMConstArray(c->field_descriptor, list, count);

  // Create a global to hold the array.
  const char* name = genname_fieldlist(g->type_name);
  LLVMValueRef global = LLVMAddGlobal(c->module, type, name);
  LLVMSetGlobalConstant(global, true);
  LLVMSetLinkage(global, LLVMInternalLinkage);
  LLVMSetInitializer(global, field_array);

  pool_free_size(buf_size, list);
  return global;
}
Esempio n. 4
0
static LLVMValueRef make_field_offset(compile_t* c, reach_type_t* t)
{
  if(t->field_count == 0)
    return LLVMConstInt(c->i32, 0, false);

  int index = 1;

  if(t->underlying == TK_ACTOR)
    index++;

  return LLVMConstInt(c->i32,
    LLVMOffsetOfElement(c->target_data, t->structure, index), false);
}
Esempio n. 5
0
void dwarf_field(dwarf_t* dwarf, gentype_t* composite, gentype_t* field,
  int index)
{
  char buf[32];
  memset(buf, 0, sizeof(buf));

  dwarf_meta_t meta;
  setup_dwarf(dwarf, &meta, field, false, true);

  meta.typearg = field->type_name;

  if(composite->underlying == TK_TUPLETYPE)
  {
    meta.flags |= DWARF_CONSTANT;
    snprintf(buf, sizeof(buf), "_%d", index + 1);
    meta.name = buf;
  }
  else
  {
    ast_t* def = (ast_t*)ast_data(composite->ast);
    ast_t* members = ast_childidx(def, 4);
    ast_t* fld = ast_childidx(members, index);
    meta.name = ast_name(ast_child(fld));

    if(ast_id(fld) == TK_FLET)
      meta.flags |= DWARF_CONSTANT;
  }

  if(meta.name[0] == '_')
    meta.flags |= DWARF_PRIVATE;

  LLVMTypeRef structure = composite->primitive;
  int offset = 0;

  if(composite->underlying != TK_TUPLETYPE)
  {
    structure = composite->structure;

    if(composite->underlying != TK_STRUCT)
      offset++;

    if(composite->underlying == TK_ACTOR)
      offset++;
  }

  meta.offset = 8 * LLVMOffsetOfElement(dwarf->target_data, structure,
    offset + index);

  symbols_field(dwarf->symbols, &meta);
}
/* TargetData.t -> Llvm.lltype -> int -> Int64.t */
CAMLprim value llvm_offset_of_element(LLVMTargetDataRef TD, LLVMTypeRef Ty,
                                      value Index) {
    return caml_copy_int64(LLVMOffsetOfElement(TD, Ty, Int_val(Index)));
}
Esempio n. 7
0
/* Llvm.lltype -> int -> DataLayout.t -> Int64.t */
CAMLprim value llvm_datalayout_offset_of_element(LLVMTypeRef Ty, value Index,
                                                 value DL) {
  return caml_copy_int64(LLVMOffsetOfElement(DataLayout_val(DL), Ty,
                                             Int_val(Index)));
}
Esempio n. 8
0
static void serialise(compile_t* c, reach_type_t* t, LLVMValueRef ctx,
  LLVMValueRef object, LLVMValueRef offset)
{
  LLVMTypeRef structure = t->structure;
  int extra = 0;

  switch(t->underlying)
  {
    case TK_PRIMITIVE:
    {
      genserialise_typeid(c, t, offset);

      if(t->primitive != NULL)
      {
        LLVMValueRef field = LLVMBuildStructGEP(c->builder, object, 1, "");
        LLVMValueRef f_size = LLVMConstInt(c->intptr,
          LLVMOffsetOfElement(c->target_data, structure, 1), false);
        LLVMValueRef f_offset = LLVMBuildInBoundsGEP(c->builder, offset,
                                                     &f_size, 1, "");

        genserialise_element(c, t, false, ctx, field, f_offset);
      }
      return;
    }

    case TK_CLASS:
    {
      genserialise_typeid(c, t, offset);
      extra++;
      break;
    }

    case TK_ACTOR:
    {
      // Skip the actor pad.
      genserialise_typeid(c, t, offset);
      extra += 2;
      break;
    }

    case TK_TUPLETYPE:
    {
      // Get the tuple primitive type.
      if(LLVMTypeOf(object) == t->structure_ptr)
      {
        genserialise_typeid(c, t, offset);
        object = LLVMBuildStructGEP(c->builder, object, 1, "");
        LLVMValueRef size = LLVMConstInt(c->intptr,
          LLVMOffsetOfElement(c->target_data, structure, 1), false);
        offset = LLVMBuildInBoundsGEP(c->builder, offset, &size, 1, "");
      }

      structure = t->primitive;
      break;
    }

    default: {}
  }

  for(uint32_t i = 0; i < t->field_count; i++)
  {
    LLVMValueRef field = LLVMBuildStructGEP(c->builder, object, i + extra, "");
    LLVMValueRef f_size = LLVMConstInt(c->intptr,
      LLVMOffsetOfElement(c->target_data, structure, i + extra), false);
    LLVMValueRef f_offset = LLVMBuildInBoundsGEP(c->builder, offset, &f_size,
      1, "");

    genserialise_element(c, t->fields[i].type, t->fields[i].embed,
      ctx, field, f_offset);
  }
}