LLVMValueRef gen_fieldptr(compile_t* c, ast_t* ast) { AST_GET_CHILDREN(ast, left, right); LLVMValueRef l_value = gen_expr(c, left); if(l_value == NULL) return NULL; ast_t* l_type = ast_type(left); return make_fieldptr(c, l_value, l_type, right); }
LLVMValueRef gen_fieldptr(compile_t* c, ast_t* ast) { AST_GET_CHILDREN(ast, left, right); LLVMValueRef l_value = gen_expr(c, left); if(l_value == NULL) return NULL; ast_t* l_type = deferred_reify(c->frame->reify, ast_type(left), c->opt); LLVMValueRef ret = make_fieldptr(c, l_value, l_type, right); ast_free_unattached(l_type); return ret; }
static LLVMValueRef make_fieldptr(compile_t* c, LLVMValueRef l_value, ast_t* l_type, ast_t* right) { switch(ast_id(l_type)) { case TK_NOMINAL: { assert(ast_id(right) == TK_ID); ast_t* def = (ast_t*)ast_data(l_type); ast_t* field = ast_get(def, ast_name(right), NULL); int index = (int)ast_index(field); if(ast_id(def) != TK_STRUCT) index++; if(ast_id(def) == TK_ACTOR) index++; return LLVMBuildStructGEP(c->builder, l_value, index, ""); } case TK_TUPLETYPE: { assert(ast_id(right) == TK_INT); int index = (int)ast_int(right)->low; return LLVMBuildExtractValue(c->builder, l_value, index, ""); } case TK_ARROW: return make_fieldptr(c, l_value, ast_childidx(l_type, 1), right); default: {} } assert(0); return NULL; }