aboutsummaryrefslogtreecommitdiff
path: root/src/ssa.c
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-12-19 11:56:45 +0000
committerGinger Bill <bill@gingerbill.org>2016-12-19 11:56:45 +0000
commitf5eeecaca5842e4594ad2ed482c529a683bfb012 (patch)
tree25d9a45ca306f16f8bfc6af339c277ec8b163277 /src/ssa.c
parent77e219d442b54860979edeaa378d99b8e74d2ebd (diff)
Begin generic declarations for lists of specifications
Diffstat (limited to 'src/ssa.c')
-rw-r--r--src/ssa.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/src/ssa.c b/src/ssa.c
index f4100e9cf..bc5737676 100644
--- a/src/ssa.c
+++ b/src/ssa.c
@@ -3849,7 +3849,8 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
case_ast_node(us, UsingStmt, node);
AstNode *decl = unparen_expr(us->node);
- if (decl->kind == AstNode_VarDecl) {
+ if (decl->kind == AstNode_VarDecl &&
+ decl->kind == AstNode_GenericDecl) {
ssa_build_stmt(proc, decl);
}
case_end;
@@ -3858,6 +3859,75 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
ssa_build_when_stmt(proc, ws);
case_end;
+
+ case_ast_node(gd, GenericDecl, node);
+ for_array(spec_index, gd->specs) {
+ AstNode *spec = gd->specs.e[spec_index];
+ switch (spec->kind) {
+ case_ast_node(vs, ValueSpec, spec);
+ switch (vs->keyword) {
+ case Token_const:
+ break;
+ case Token_var: {
+ ssaModule *m = proc->module;
+ gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);
+
+ if (vs->values.count == 0) { // declared and zero-initialized
+ for_array(i, vs->names) {
+ AstNode *name = vs->names.e[i];
+ if (!ssa_is_blank_ident(name)) {
+ ssa_add_local_for_identifier(proc, name, true);
+ }
+ }
+ } else { // Tuple(s)
+ Array(ssaAddr) lvals;
+ ssaValueArray inits;
+ array_init_reserve(&lvals, m->tmp_allocator, vs->names.count);
+ array_init_reserve(&inits, m->tmp_allocator, vs->names.count);
+
+ for_array(i, vs->names) {
+ AstNode *name = vs->names.e[i];
+ ssaAddr lval = ssa_make_addr(NULL, NULL);
+ if (!ssa_is_blank_ident(name)) {
+ ssa_add_local_for_identifier(proc, name, false);
+ lval = ssa_build_addr(proc, name);
+ }
+
+ array_add(&lvals, lval);
+ }
+
+ for_array(i, vs->values) {
+ ssaValue *init = ssa_build_expr(proc, vs->values.e[i]);
+ Type *t = ssa_type(init);
+ if (t->kind == Type_Tuple) {
+ for (isize i = 0; i < t->Tuple.variable_count; i++) {
+ Entity *e = t->Tuple.variables[i];
+ ssaValue *v = ssa_emit_struct_ev(proc, init, i);
+ array_add(&inits, v);
+ }
+ } else {
+ array_add(&inits, init);
+ }
+ }
+
+
+ for_array(i, inits) {
+ if (lvals.e[i].addr == NULL) {
+ continue;
+ }
+ ssaValue *v = ssa_emit_conv(proc, inits.e[i], ssa_addr_type(lvals.e[i]));
+ ssa_addr_store(proc, lvals.e[i], v);
+ }
+ }
+
+ gb_temp_arena_memory_end(tmp);
+ } break;
+ }
+ case_end;
+ }
+ }
+ case_end;
+
case_ast_node(vd, VarDecl, node);
ssaModule *m = proc->module;
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);