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