aboutsummaryrefslogtreecommitdiff
path: root/src/dump_analysis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dump_analysis.cpp')
-rw-r--r--src/dump_analysis.cpp393
1 files changed, 382 insertions, 11 deletions
diff --git a/src/dump_analysis.cpp b/src/dump_analysis.cpp
index 220019c184..168d86a21f 100644
--- a/src/dump_analysis.cpp
+++ b/src/dump_analysis.cpp
@@ -351,6 +351,15 @@ struct AnalDumpCtx {
ZigList<Tld *> decl_list;
HashMap<const Tld *, uint32_t, tld_ptr_hash, tld_ptr_eql> decl_map;
+
+ ZigList<ZigFn *> fn_list;
+ HashMap<const ZigFn *, uint32_t, fn_ptr_hash, fn_ptr_eql> fn_map;
+
+ ZigList<AstNode *> node_list;
+ HashMap<const AstNode *, uint32_t, node_ptr_hash, node_ptr_eql> node_map;
+
+ ZigList<ErrorTableEntry *> err_list;
+ HashMap<const ErrorTableEntry *, uint32_t, err_ptr_hash, err_ptr_eql> err_map;
};
static uint32_t anal_dump_get_type_id(AnalDumpCtx *ctx, ZigType *ty);
@@ -416,6 +425,39 @@ static uint32_t anal_dump_get_file_id(AnalDumpCtx *ctx, Buf *file) {
return file_id;
}
+static uint32_t anal_dump_get_node_id(AnalDumpCtx *ctx, AstNode *node) {
+ uint32_t node_id = ctx->node_list.length;
+ auto existing_entry = ctx->node_map.put_unique(node, node_id);
+ if (existing_entry == nullptr) {
+ ctx->node_list.append(node);
+ } else {
+ node_id = existing_entry->value;
+ }
+ return node_id;
+}
+
+static uint32_t anal_dump_get_fn_id(AnalDumpCtx *ctx, ZigFn *fn) {
+ uint32_t fn_id = ctx->fn_list.length;
+ auto existing_entry = ctx->fn_map.put_unique(fn, fn_id);
+ if (existing_entry == nullptr) {
+ ctx->fn_list.append(fn);
+ } else {
+ fn_id = existing_entry->value;
+ }
+ return fn_id;
+}
+
+static uint32_t anal_dump_get_err_id(AnalDumpCtx *ctx, ErrorTableEntry *err) {
+ uint32_t err_id = ctx->err_list.length;
+ auto existing_entry = ctx->err_map.put_unique(err, err_id);
+ if (existing_entry == nullptr) {
+ ctx->err_list.append(err);
+ } else {
+ err_id = existing_entry->value;
+ }
+ return err_id;
+}
+
static uint32_t anal_dump_get_decl_id(AnalDumpCtx *ctx, Tld *tld) {
uint32_t decl_id = ctx->decl_list.length;
auto existing_entry = ctx->decl_map.put_unique(tld, decl_id);
@@ -475,6 +517,21 @@ static void anal_dump_file_ref(AnalDumpCtx *ctx, Buf *file) {
jw_int(&ctx->jw, file_id);
}
+static void anal_dump_node_ref(AnalDumpCtx *ctx, AstNode *node) {
+ uint32_t node_id = anal_dump_get_node_id(ctx, node);
+ jw_int(&ctx->jw, node_id);
+}
+
+static void anal_dump_fn_ref(AnalDumpCtx *ctx, ZigFn *fn) {
+ uint32_t fn_id = anal_dump_get_fn_id(ctx, fn);
+ jw_int(&ctx->jw, fn_id);
+}
+
+static void anal_dump_err_ref(AnalDumpCtx *ctx, ErrorTableEntry *err) {
+ uint32_t err_id = anal_dump_get_err_id(ctx, err);
+ jw_int(&ctx->jw, err_id);
+}
+
static void anal_dump_decl_ref(AnalDumpCtx *ctx, Tld *tld) {
uint32_t decl_id = anal_dump_get_decl_id(ctx, tld);
jw_int(&ctx->jw, decl_id);
@@ -536,11 +593,8 @@ static void anal_dump_decl(AnalDumpCtx *ctx, Tld *tld) {
jw_object_field(jw, "import");
anal_dump_type_ref(ctx, tld->import);
- jw_object_field(jw, "line");
- jw_int(jw, tld->source_node->line);
-
- jw_object_field(jw, "col");
- jw_int(jw, tld->source_node->column);
+ jw_object_field(jw, "src");
+ anal_dump_node_ref(ctx, tld->source_node);
jw_object_field(jw, "name");
jw_string(jw, buf_ptr(tld->name));
@@ -584,8 +638,10 @@ static void anal_dump_decl(AnalDumpCtx *ctx, Tld *tld) {
jw_object_field(jw, "type");
anal_dump_type_ref(ctx, fn->type_entry);
- }
+ jw_object_field(jw, "value");
+ anal_dump_fn_ref(ctx, fn);
+ }
break;
}
default:
@@ -626,6 +682,19 @@ static void anal_dump_value(AnalDumpCtx *ctx, AstNode *source_node, ZigType *ty,
anal_dump_type_ref(ctx, val_ty);
return;
}
+ case ZigTypeIdFn: {
+ if (value->data.x_ptr.special == ConstPtrSpecialFunction) {
+ ZigFn *val_fn = value->data.x_ptr.data.fn.fn_entry;
+ if (val_fn->type_entry->data.fn.is_generic) {
+ anal_dump_node_ref(ctx, val_fn->proto_node);
+ } else {
+ anal_dump_fn_ref(ctx, val_fn);
+ }
+ } else {
+ jw_null(&ctx->jw);
+ }
+ return;
+ }
default:
jw_null(&ctx->jw);
return;
@@ -633,24 +702,75 @@ static void anal_dump_value(AnalDumpCtx *ctx, AstNode *source_node, ZigType *ty,
zig_unreachable();
}
-static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
+static void anal_dump_pointer_attrs(AnalDumpCtx *ctx, ZigType *ty) {
JsonWriter *jw = &ctx->jw;
- jw_array_elem(jw);
+ if (ty->data.pointer.explicit_alignment != 0) {
+ jw_object_field(jw, "align");
+ jw_int(jw, ty->data.pointer.explicit_alignment);
+ }
+ if (ty->data.pointer.is_const) {
+ jw_object_field(jw, "const");
+ jw_bool(jw, true);
+ }
+ if (ty->data.pointer.is_volatile) {
+ jw_object_field(jw, "volatile");
+ jw_bool(jw, true);
+ }
+ if (ty->data.pointer.allow_zero) {
+ jw_object_field(jw, "allowZero");
+ jw_bool(jw, true);
+ }
+ if (ty->data.pointer.host_int_bytes != 0) {
+ jw_object_field(jw, "hostIntBytes");
+ jw_int(jw, ty->data.pointer.host_int_bytes);
+
+ jw_object_field(jw, "bitOffsetInHost");
+ jw_int(jw, ty->data.pointer.bit_offset_in_host);
+ }
+
+ jw_object_field(jw, "elem");
+ anal_dump_type_ref(ctx, ty->data.pointer.child_type);
+}
+
+static void anal_dump_struct_field(AnalDumpCtx *ctx, const TypeStructField *struct_field) {
+ JsonWriter *jw = &ctx->jw;
+
jw_begin_object(jw);
jw_object_field(jw, "name");
- jw_string(jw, buf_ptr(&ty->name));
+ jw_string(jw, buf_ptr(struct_field->name));
+
+ jw_object_field(jw, "type");
+ anal_dump_type_ref(ctx, struct_field->type_entry);
+
+ jw_object_field(jw, "src");
+ anal_dump_node_ref(ctx, struct_field->decl_node);
+
+ jw_end_object(jw);
+}
+
+static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
+ JsonWriter *jw = &ctx->jw;
+ jw_array_elem(jw);
+ jw_begin_object(jw);
jw_object_field(jw, "kind");
jw_int(jw, type_id_index(ty));
switch (ty->id) {
+ case ZigTypeIdMetaType:
+ case ZigTypeIdBool:
+ break;
case ZigTypeIdStruct: {
if (ty->data.structure.is_slice) {
- // TODO
+ jw_object_field(jw, "len");
+ jw_int(jw, 2);
+ anal_dump_pointer_attrs(ctx, ty->data.structure.fields[slice_ptr_index].type_entry);
break;
}
+ jw_object_field(jw, "name");
+ jw_string(jw, buf_ptr(&ty->name));
{
jw_object_field(jw, "pubDecls");
jw_begin_array(jw);
@@ -691,6 +811,17 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
jw_end_array(jw);
}
+ {
+ jw_object_field(jw, "fields");
+ jw_begin_array(jw);
+
+ for(size_t i = 0; i < ty->data.structure.src_field_count; i += 1) {
+ jw_array_elem(jw);
+ anal_dump_struct_field(ctx, &ty->data.structure.fields[i]);
+ }
+ jw_end_array(jw);
+ }
+
if (ty->data.structure.root_struct != nullptr) {
Buf *path_buf = ty->data.structure.root_struct->path;
@@ -705,13 +836,167 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
jw_int(jw, ty->data.floating.bit_count);
break;
}
+ case ZigTypeIdInt: {
+ if (ty->data.integral.is_signed) {
+ jw_object_field(jw, "i");
+ } else {
+ jw_object_field(jw, "u");
+ }
+ jw_int(jw, ty->data.integral.bit_count);
+ break;
+ }
+ case ZigTypeIdFn: {
+ jw_object_field(jw, "name");
+ jw_string(jw, buf_ptr(&ty->name));
+
+ jw_object_field(jw, "generic");
+ jw_bool(jw, ty->data.fn.is_generic);
+
+ if (ty->data.fn.fn_type_id.return_type != nullptr) {
+ jw_object_field(jw, "ret");
+ anal_dump_type_ref(ctx, ty->data.fn.fn_type_id.return_type);
+ }
+
+ if (ty->data.fn.fn_type_id.param_count != 0) {
+ jw_object_field(jw, "args");
+ jw_begin_array(jw);
+ for (size_t i = 0; i < ty->data.fn.fn_type_id.param_count; i += 1) {
+ jw_array_elem(jw);
+ if (ty->data.fn.fn_type_id.param_info[i].type != nullptr) {
+ anal_dump_type_ref(ctx, ty->data.fn.fn_type_id.param_info[i].type);
+ } else {
+ jw_null(jw);
+ }
+ }
+ jw_end_array(jw);
+ }
+ break;
+ }
+ case ZigTypeIdPointer: {
+ switch (ty->data.pointer.ptr_len) {
+ case PtrLenSingle:
+ break;
+ case PtrLenUnknown:
+ jw_object_field(jw, "len");
+ jw_int(jw, 1);
+ break;
+ case PtrLenC:
+ jw_object_field(jw, "len");
+ jw_int(jw, 3);
+ break;
+ }
+ anal_dump_pointer_attrs(ctx, ty);
+ break;
+ }
+ case ZigTypeIdErrorSet: {
+ if (type_is_global_error_set(ty)) {
+ break;
+ }
+ jw_object_field(jw, "name");
+ jw_string(jw, buf_ptr(&ty->name));
+
+ if (ty->data.error_set.infer_fn != nullptr) {
+ jw_object_field(jw, "fn");
+ anal_dump_fn_ref(ctx, ty->data.error_set.infer_fn);
+ }
+ jw_object_field(jw, "errors");
+ jw_begin_array(jw);
+ for (uint32_t i = 0; i < ty->data.error_set.err_count; i += 1) {
+ jw_array_elem(jw);
+ ErrorTableEntry *err = ty->data.error_set.errors[i];
+ anal_dump_err_ref(ctx, err);
+ }
+ jw_end_array(jw);
+ break;
+ }
+ case ZigTypeIdErrorUnion: {
+ jw_object_field(jw, "err");
+ anal_dump_type_ref(ctx, ty->data.error_union.err_set_type);
+
+ jw_object_field(jw, "payload");
+ anal_dump_type_ref(ctx, ty->data.error_union.payload_type);
+
+ break;
+ }
default:
- // TODO
+ jw_object_field(jw, "name");
+ jw_string(jw, buf_ptr(&ty->name));
break;
}
jw_end_object(jw);
}
+static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {
+ JsonWriter *jw = &ctx->jw;
+
+ jw_begin_object(jw);
+
+ jw_object_field(jw, "file");
+ anal_dump_file_ref(ctx, node->owner->data.structure.root_struct->path);
+
+ jw_object_field(jw, "line");
+ jw_int(jw, node->line);
+
+ jw_object_field(jw, "col");
+ jw_int(jw, node->column);
+
+ const Buf *doc_comments_buf;
+ switch (node->type) {
+ case NodeTypeParamDecl:
+ doc_comments_buf = &node->data.param_decl.doc_comments;
+ break;
+ case NodeTypeFnProto:
+ doc_comments_buf = &node->data.fn_proto.doc_comments;
+ break;
+ case NodeTypeVariableDeclaration:
+ doc_comments_buf = &node->data.variable_declaration.doc_comments;
+ break;
+ case NodeTypeErrorSetField:
+ doc_comments_buf = &node->data.err_set_field.doc_comments;
+ break;
+ case NodeTypeStructField:
+ doc_comments_buf = &node->data.struct_field.doc_comments;
+ break;
+ default:
+ doc_comments_buf = nullptr;
+ break;
+ }
+ if (doc_comments_buf != nullptr && doc_comments_buf->list.length != 0) {
+ jw_object_field(jw, "docs");
+ jw_string(jw, buf_ptr(doc_comments_buf));
+ }
+
+ jw_end_object(jw);
+}
+
+static void anal_dump_err(AnalDumpCtx *ctx, const ErrorTableEntry *err) {
+ JsonWriter *jw = &ctx->jw;
+
+ jw_begin_object(jw);
+
+ jw_object_field(jw, "src");
+ anal_dump_node_ref(ctx, err->decl_node);
+
+ jw_object_field(jw, "name");
+ jw_string(jw, buf_ptr(&err->name));
+
+ jw_end_object(jw);
+}
+
+static void anal_dump_fn(AnalDumpCtx *ctx, ZigFn *fn) {
+ JsonWriter *jw = &ctx->jw;
+
+ jw_begin_object(jw);
+
+ jw_object_field(jw, "src");
+ anal_dump_node_ref(ctx, fn->proto_node);
+
+ jw_object_field(jw, "type");
+ anal_dump_type_ref(ctx, fn->type_entry);
+
+ jw_end_object(jw);
+}
+
void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const char *nl) {
Error err;
AnalDumpCtx ctx = {};
@@ -722,6 +1007,9 @@ void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const
ctx.pkg_map.init(16);
ctx.file_map.init(16);
ctx.decl_map.init(16);
+ ctx.node_map.init(16);
+ ctx.fn_map.init(16);
+ ctx.err_map.init(16);
jw_begin_object(jw);
@@ -761,6 +1049,71 @@ void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const
jw_object_field(jw, "rootPkg");
anal_dump_pkg_ref(&ctx, g->root_package);
+ // Poke the functions
+ for (size_t i = 0; i < g->fn_defs.length; i += 1) {
+ ZigFn *fn = g->fn_defs.at(i);
+ (void)anal_dump_get_fn_id(&ctx, fn);
+ }
+
+ jw_object_field(jw, "calls");
+ jw_begin_array(jw);
+ {
+ auto it = g->memoized_fn_eval_table.entry_iterator();
+ for (;;) {
+ auto *entry = it.next();
+ if (!entry)
+ break;
+
+ jw_array_elem(jw);
+ jw_begin_object(jw);
+
+ jw_object_field(jw, "args");
+ jw_begin_object(jw);
+
+ Scope *scope = entry->key;
+ while (scope != nullptr) {
+ if (scope->id == ScopeIdVarDecl) {
+ ZigVar *var = reinterpret_cast<ScopeVarDecl *>(scope)->var;
+ jw_object_field(jw, var->name);
+ jw_begin_object(jw);
+ jw_object_field(jw, "type");
+ anal_dump_type_ref(&ctx, var->var_type);
+ jw_object_field(jw, "value");
+ anal_dump_value(&ctx, scope->source_node, var->var_type, var->const_value);
+ jw_end_object(jw);
+ } else if (scope->id == ScopeIdFnDef) {
+ jw_end_object(jw);
+
+ jw_object_field(jw, "fn");
+ ZigFn *fn = reinterpret_cast<ScopeFnDef *>(scope)->fn_entry;
+ anal_dump_fn_ref(&ctx, fn);
+
+ ConstExprValue *result = entry->value;
+ jw_object_field(jw, "result");
+ jw_begin_object(jw);
+ jw_object_field(jw, "type");
+ anal_dump_type_ref(&ctx, result->type);
+ jw_object_field(jw, "value");
+ anal_dump_value(&ctx, scope->source_node, result->type, result);
+ jw_end_object(jw);
+ break;
+ }
+ scope = scope->parent;
+ }
+ jw_end_object(jw);
+ }
+ }
+ jw_end_array(jw);
+
+ jw_object_field(jw, "fns");
+ jw_begin_array(jw);
+ for (uint32_t i = 0; i < ctx.fn_list.length; i += 1) {
+ ZigFn *fn = ctx.fn_list.at(i);
+ jw_array_elem(jw);
+ anal_dump_fn(&ctx, fn);
+ }
+ jw_end_array(jw);
+
jw_object_field(jw, "packages");
jw_begin_array(jw);
for (uint32_t i = 0; i < ctx.pkg_list.length; i += 1) {
@@ -794,5 +1147,23 @@ void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const
}
jw_end_array(jw);
+ jw_object_field(jw, "errors");
+ jw_begin_array(jw);
+ for (uint32_t i = 0; i < ctx.err_list.length; i += 1) {
+ const ErrorTableEntry *err = ctx.err_list.at(i);
+ jw_array_elem(jw);
+ anal_dump_err(&ctx, err);
+ }
+ jw_end_array(jw);
+
+ jw_object_field(jw, "astNodes");
+ jw_begin_array(jw);
+ for (uint32_t i = 0; i < ctx.node_list.length; i += 1) {
+ const AstNode *node = ctx.node_list.at(i);
+ jw_array_elem(jw);
+ anal_dump_node(&ctx, node);
+ }
+ jw_end_array(jw);
+
jw_end_object(jw);
}