Commit 97c61313da
Changed files (6)
example
hello_world
test
example/hello_world/hello_libc.zig
@@ -1,7 +1,9 @@
#link("c")
export executable "hello";
-extern fn printf(__format: &const u8, ...) -> c_int;
+c_import {
+ @c_include("stdio.h");
+}
export fn main(argc: c_int, argv: &&u8) -> c_int {
printf(c"Hello, world!\n");
src/all_types.hpp
@@ -894,7 +894,7 @@ struct ImportTableEntry {
ZigList<int> *line_offsets;
BlockContext *block_context;
ZigList<ImporterInfo> importers;
- bool is_c_import;
+ AstNode *c_import_node;
// reminder: hash tables must be initialized before use
HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table;
src/analyze.cpp
@@ -12,6 +12,7 @@
#include "os.hpp"
#include "parseh.hpp"
#include "config.h"
+#include "ast_render.hpp"
static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import, BlockContext *context,
TypeTableEntry *expected_type, AstNode *node);
@@ -26,6 +27,7 @@ static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *
static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
TypeTableEntry *expected_type, AstNode *node);
static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node);
+static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *node);
static AstNode *first_executing_node(AstNode *node) {
switch (node->type) {
@@ -87,6 +89,8 @@ static AstNode *first_executing_node(AstNode *node) {
}
ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
+ assert(!node->owner->c_import_node);
+
ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column,
node->owner->source_code, node->owner->line_offsets, msg);
@@ -1056,11 +1060,15 @@ static void resolve_c_import_decl(CodeGen *g, ImportTableEntry *parent_import, A
find_libc_path(g);
- ImportTableEntry child_import = {0};
+ ImportTableEntry *child_import = allocate<ImportTableEntry>(1);
+ child_import->fn_table.init(32);
+ child_import->fn_type_table.init(32);
+ child_import->c_import_node = node;
+
ZigList<ErrorMsg *> errors = {0};
int err;
- if ((err = parse_h_buf(&child_import, &errors, child_context->c_import_buf, g->clang_argv, g->clang_argv_len,
+ if ((err = parse_h_buf(child_import, &errors, child_context->c_import_buf, g->clang_argv, g->clang_argv_len,
buf_ptr(g->libc_include_path))))
{
zig_panic("unable to parse h file: %s\n", err_str(err));
@@ -1075,7 +1083,24 @@ static void resolve_c_import_decl(CodeGen *g, ImportTableEntry *parent_import, A
return;
}
- zig_panic("TODO integrate the AST");
+ if (g->verbose) {
+ fprintf(stderr, "\nc_import:\n");
+ fprintf(stderr, "-----------\n");
+ ast_render(stderr, child_import->root, 4);
+ }
+
+ child_import->di_file = parent_import->di_file;
+ child_import->block_context = new_block_context(child_import->root, nullptr);
+ child_import->importers.append({parent_import, node});
+
+ detect_top_level_decl_deps(g, child_import, child_import->root);
+}
+
+static void satisfy_dep(CodeGen *g, AstNode *node) {
+ Buf *name = get_resolved_top_level_decl(node)->name;
+ if (name) {
+ g->unresolved_top_level_decls.maybe_remove(name);
+ }
}
static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
@@ -1085,7 +1110,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
break;
case NodeTypeRootExportDecl:
// handled earlier
- break;
+ return;
case NodeTypeStructDecl:
{
TypeTableEntry *type_entry = node->data.struct_decl.type_entry;
@@ -1115,7 +1140,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
break;
case NodeTypeImport:
// nothing to do here
- break;
+ return;
case NodeTypeCImport:
resolve_c_import_decl(g, import, node);
break;
@@ -1159,6 +1184,9 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
case NodeTypeErrorType:
zig_unreachable();
}
+
+
+ satisfy_dep(g, node);
}
static FnTableEntry *get_context_fn_entry(BlockContext *context) {
@@ -4512,6 +4540,12 @@ static TypeTableEntryId container_to_type(ContainerKind kind) {
static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *node) {
switch (node->type) {
+ case NodeTypeRoot:
+ for (int i = 0; i < import->root->data.root.top_level_decls.length; i += 1) {
+ AstNode *child = import->root->data.root.top_level_decls.at(i);
+ detect_top_level_decl_deps(g, import, child);
+ }
+ break;
case NodeTypeStructDecl:
{
Buf *name = &node->data.struct_decl.name;
@@ -4664,7 +4698,6 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
case NodeTypeParamDecl:
case NodeTypeFnDecl:
case NodeTypeReturnExpr:
- case NodeTypeRoot:
case NodeTypeBlock:
case NodeTypeBinOpExpr:
case NodeTypeUnwrapErrorExpr:
@@ -4732,7 +4765,6 @@ static void recursive_resolve_decl(CodeGen *g, ImportTableEntry *import, AstNode
}
resolve_top_level_decl(g, import, node);
- g->unresolved_top_level_decls.remove(get_resolved_top_level_decl(node)->name);
}
static void resolve_top_level_declarations_root(CodeGen *g, ImportTableEntry *import, AstNode *node) {
@@ -4823,10 +4855,7 @@ void semantic_analyze(CodeGen *g) {
ImportTableEntry *import = entry->value;
- for (int i = 0; i < import->root->data.root.top_level_decls.length; i += 1) {
- AstNode *child = import->root->data.root.top_level_decls.at(i);
- detect_top_level_decl_deps(g, import, child);
- }
+ detect_top_level_decl_deps(g, import, import->root);
}
}
src/hash_map.hpp
@@ -72,6 +72,12 @@ public:
return internal_get(key);
}
+ void maybe_remove(const K &key) {
+ if (maybe_get(key)) {
+ remove(key);
+ }
+ }
+
void remove(const K &key) {
_modification_count += 1;
int start_index = key_to_index(key);
src/parseh.cpp
@@ -27,6 +27,7 @@ struct Context {
AstNode *c_void_decl_node;
AstNode *root;
HashMap<Buf *, bool, buf_hash, buf_eql_buf> type_table;
+ HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table;
};
static AstNode *make_qual_type_node(Context *c, QualType qt);
@@ -107,8 +108,8 @@ static AstNode *make_type_node(Context *c, const Type *ty) {
return simple_type_node(c, "bool");
case BuiltinType::Char_U:
case BuiltinType::UChar:
- return simple_type_node(c, "u8");
case BuiltinType::Char_S:
+ return simple_type_node(c, "u8");
case BuiltinType::SChar:
return simple_type_node(c, "i8");
case BuiltinType::UShort:
@@ -266,11 +267,18 @@ static AstNode *make_qual_type_node(Context *c, QualType qt) {
static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
AstNode *node = create_node(c, NodeTypeFnProto);
+ buf_init_from_str(&node->data.fn_proto.name, decl_name(fn_decl));
+
+ auto fn_entry = c->fn_table.maybe_get(&node->data.fn_proto.name);
+ if (fn_entry) {
+ // we already saw this function
+ return;
+ }
+
node->data.fn_proto.is_extern = true;
node->data.fn_proto.visib_mod = c->visib_mod;
node->data.fn_proto.directives = create_empty_directives(c);
node->data.fn_proto.is_var_args = fn_decl->isVariadic();
- buf_init_from_str(&node->data.fn_proto.name, decl_name(fn_decl));
int arg_count = fn_decl->getNumParams();
bool all_ok = true;
@@ -313,6 +321,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
normalize_parent_ptrs(node);
+ c->fn_table.put(&node->data.fn_proto.name, true);
c->root->data.root.top_level_decls.append(node);
}
@@ -392,7 +401,9 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, ZigList<
Context *c = &context;
c->import = import;
c->errors = errors;
- c->type_table.init(64);
+ c->visib_mod = VisibModPub;
+ c->type_table.init(32);
+ c->fn_table.init(32);
char *ZIG_PARSEH_CFLAGS = getenv("ZIG_PARSEH_CFLAGS");
if (ZIG_PARSEH_CFLAGS) {
@@ -486,7 +497,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, ZigList<
normalize_parent_ptrs(c->root);
import->root = c->root;
- import->is_c_import = true;
return 0;
}
test/run_tests.cpp
@@ -98,7 +98,11 @@ static void add_compiling_test_cases(void) {
add_simple_case("hello world with libc", R"SOURCE(
#link("c")
export executable "test";
-extern fn puts(s: &const u8) -> c_int;
+
+c_import {
+ @c_include("stdio.h");
+}
+
export fn main(argc: c_int, argv: &&u8) -> c_int {
puts(c"Hello, world!");
return 0;
@@ -481,7 +485,10 @@ pub fn main(args: [][]u8) -> %void {
add_simple_case("number literals", R"SOURCE(
#link("c")
export executable "test";
-extern fn printf(__format: &const u8, ...) -> c_int;
+
+c_import {
+ @c_include("stdio.h");
+}
export fn main(argc: c_int, argv: &&u8) -> c_int {
printf(c"\n");