mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
parent
51ab9b03ce
commit
97c61313da
@ -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");
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user