Exemple #1
0
static bool make_struct(compile_t* c, gentype_t* g)
{
  LLVMTypeRef type;
  int extra = 0;

  if(g->underlying != TK_TUPLETYPE)
  {
    type = g->structure;
    extra++;
  } else {
    type = g->primitive;
  }

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

  size_t buf_size = (g->field_count + extra) * sizeof(LLVMTypeRef);
  LLVMTypeRef* elements = (LLVMTypeRef*)pool_alloc_size(buf_size);

  // Create the type descriptor as element 0.
  if(g->underlying != TK_TUPLETYPE)
    elements[0] = LLVMPointerType(g->desc_type, 0);

  // Create the actor pad as element 1.
  if(g->underlying == TK_ACTOR)
    elements[1] = c->actor_pad;

  // Get a preliminary type for each field and set the struct body. This is
  // needed in case a struct for the type being generated here is required when
  // generating a field.
  for(int i = 0; i < g->field_count; i++)
  {
    gentype_t field_g;

    if(!gentype_prelim(c, g->fields[i], &field_g))
    {
      pool_free_size(buf_size, elements);
      return false;
    }

    elements[i + extra] = field_g.use_type;
  }

  LLVMStructSetBody(type, elements, g->field_count + extra, false);

  // Create a box type for tuples.
  if(g->underlying == TK_TUPLETYPE)
    make_box_type(c, g);

  pool_free_size(buf_size, elements);
  return true;
}
Exemple #2
0
static bool make_struct(compile_t* c, gentype_t* g)
{
  LLVMTypeRef type;
  int extra = 0;

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

    if(g->underlying != TK_STRUCT)
      extra++;
  } else {
    type = g->primitive;
  }

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

  size_t buf_size = (g->field_count + extra) * sizeof(LLVMTypeRef);
  LLVMTypeRef* elements = (LLVMTypeRef*)pool_alloc_size(buf_size);

  // Create the type descriptor as element 0.
  if(extra > 0)
    elements[0] = LLVMPointerType(g->desc_type, 0);

  // Create the actor pad as element 1.
  if(g->underlying == TK_ACTOR)
    elements[1] = c->actor_pad;

  // Get a preliminary type for each field and set the struct body. This is
  // needed in case a struct for the type being generated here is required when
  // generating a field.
  for(int i = 0; i < g->field_count; i++)
  {
    gentype_t field_g;
    bool ok;

    if((g->field_keys != NULL) && (g->field_keys[i] == TK_EMBED))
    {
      ok = gentype(c, g->fields[i], &field_g);
      elements[i + extra] = field_g.structure;
    } else {
      ok = gentype_prelim(c, g->fields[i], &field_g);
      elements[i + extra] = field_g.use_type;
    }

    if(!ok)
    {
      pool_free_size(buf_size, elements);
      return false;
    }
  }

  // An embedded field may have caused the current type to be fully generated
  // at this point. If so, finish gracefully.
  if(!LLVMIsOpaqueStruct(type))
  {
    g->done = true;
    return true;
  }

  LLVMStructSetBody(type, elements, g->field_count + extra, false);

  // Create a box type for tuples.
  if(g->underlying == TK_TUPLETYPE)
    make_box_type(c, g);

  pool_free_size(buf_size, elements);
  return true;
}