mirror of
https://github.com/ziglang/zig.git
synced 2026-01-06 21:43:25 +00:00
fix parseh bugs
This commit is contained in:
parent
e1d5da20a5
commit
cc621cdee3
@ -412,14 +412,17 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
|
||||
const char *pub_str = visib_mod_string(node->data.fn_proto.visib_mod);
|
||||
const char *extern_str = extern_string(node->data.fn_proto.is_extern);
|
||||
const char *inline_str = inline_string(node->data.fn_proto.is_inline);
|
||||
fprintf(ar->f, "%s%s%sfn ", pub_str, inline_str, extern_str);
|
||||
print_symbol(ar, node->data.fn_proto.name);
|
||||
fprintf(ar->f, "%s%s%sfn", pub_str, inline_str, extern_str);
|
||||
if (node->data.fn_proto.name != nullptr) {
|
||||
fprintf(ar->f, " ");
|
||||
print_symbol(ar, node->data.fn_proto.name);
|
||||
}
|
||||
fprintf(ar->f, "(");
|
||||
size_t arg_count = node->data.fn_proto.params.length;
|
||||
for (size_t arg_i = 0; arg_i < arg_count; arg_i += 1) {
|
||||
AstNode *param_decl = node->data.fn_proto.params.at(arg_i);
|
||||
assert(param_decl->type == NodeTypeParamDecl);
|
||||
if (buf_len(param_decl->data.param_decl.name) > 0) {
|
||||
if (param_decl->data.param_decl.name != nullptr) {
|
||||
const char *noalias_str = param_decl->data.param_decl.is_noalias ? "noalias " : "";
|
||||
const char *inline_str = param_decl->data.param_decl.is_inline ? "inline " : "";
|
||||
fprintf(ar->f, "%s%s", noalias_str, inline_str);
|
||||
|
||||
@ -79,11 +79,14 @@ ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size
|
||||
for (;;) {
|
||||
if (line_start_offset == 0) {
|
||||
break;
|
||||
} else if (source[line_start_offset] == '\n') {
|
||||
}
|
||||
|
||||
line_start_offset -= 1;
|
||||
|
||||
if (source[line_start_offset] == '\n') {
|
||||
line_start_offset += 1;
|
||||
break;
|
||||
}
|
||||
line_start_offset -= 1;
|
||||
}
|
||||
|
||||
size_t line_end_offset = offset;
|
||||
|
||||
148
src/parseh.cpp
148
src/parseh.cpp
@ -30,8 +30,8 @@ struct MacroSymbol {
|
||||
};
|
||||
|
||||
struct Alias {
|
||||
Buf *name;
|
||||
AstNode *node;
|
||||
Buf *new_name;
|
||||
Buf *canon_name;
|
||||
};
|
||||
|
||||
struct Context {
|
||||
@ -85,10 +85,10 @@ static void emit_warning(Context *c, const SourceLocation &sl, const char *forma
|
||||
fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg));
|
||||
}
|
||||
|
||||
static void add_global_weak_alias(Context *c, Buf *name, AstNode *node) {
|
||||
static void add_global_weak_alias(Context *c, Buf *new_name, Buf *canon_name) {
|
||||
Alias *alias = c->aliases.add_one();
|
||||
alias->name = name;
|
||||
alias->node = node;
|
||||
alias->new_name = new_name;
|
||||
alias->canon_name = canon_name;
|
||||
}
|
||||
|
||||
static AstNode * trans_create_node(Context *c, NodeType id) {
|
||||
@ -128,7 +128,7 @@ static AstNode *trans_create_node_builtin_fn_call_str(Context *c, const char *na
|
||||
}
|
||||
|
||||
static AstNode *trans_create_node_opaque(Context *c) {
|
||||
return trans_create_node_builtin_fn_call_str(c, "opaque");
|
||||
return trans_create_node_builtin_fn_call_str(c, "OpaqueType");
|
||||
}
|
||||
|
||||
static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) {
|
||||
@ -209,7 +209,7 @@ static AstNode *trans_create_node_var_decl(Context *c, bool is_const, Buf *var_n
|
||||
static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, Buf *var_name, AstNode *src_proto_node) {
|
||||
AstNode *fn_def = trans_create_node(c, NodeTypeFnDef);
|
||||
AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto);
|
||||
fn_proto->data.fn_proto.visib_mod = c->visib_mod;;
|
||||
fn_proto->data.fn_proto.visib_mod = c->visib_mod;
|
||||
fn_proto->data.fn_proto.name = fn_name;
|
||||
fn_proto->data.fn_proto.is_inline = true;
|
||||
fn_proto->data.fn_proto.return_type = src_proto_node->data.fn_proto.return_type; // TODO ok for these to alias?
|
||||
@ -559,6 +559,7 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo
|
||||
switch (fn_proto_ty->getCallConv()) {
|
||||
case CC_C: // __attribute__((cdecl))
|
||||
proto_node->data.fn_proto.cc = CallingConventionC;
|
||||
proto_node->data.fn_proto.is_extern = true;
|
||||
break;
|
||||
case CC_X86StdCall: // __attribute__((stdcall))
|
||||
proto_node->data.fn_proto.cc = CallingConventionStdcall;
|
||||
@ -646,9 +647,7 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo
|
||||
AstNode *param_node = trans_create_node(c, NodeTypeParamDecl);
|
||||
//emit_warning(c, source_loc, "TODO figure out fn prototype param name");
|
||||
const char *param_name = nullptr;
|
||||
if (param_name == nullptr) {
|
||||
param_node->data.param_decl.name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
|
||||
} else {
|
||||
if (param_name != nullptr) {
|
||||
param_node->data.param_decl.name = buf_create_from_str(param_name);
|
||||
}
|
||||
param_node->data.param_decl.is_noalias = qt.isRestrictQualified();
|
||||
@ -1662,7 +1661,14 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
|
||||
AstNode *param_node = proto_node->data.fn_proto.params.at(i);
|
||||
const ParmVarDecl *param = fn_decl->getParamDecl(i);
|
||||
const char *name = decl_name(param);
|
||||
if (strlen(name) != 0) {
|
||||
if (strlen(name) == 0) {
|
||||
Buf *proto_param_name = param_node->data.param_decl.name;
|
||||
if (proto_param_name == nullptr) {
|
||||
param_node->data.param_decl.name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
|
||||
} else {
|
||||
param_node->data.param_decl.name = proto_param_name;
|
||||
}
|
||||
} else {
|
||||
param_node->data.param_decl.name = buf_create_from_str(name);
|
||||
}
|
||||
}
|
||||
@ -1714,6 +1720,22 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)
|
||||
c->global_type_table.put(type_name, type_node);
|
||||
}
|
||||
|
||||
struct AstNode *demote_enum_to_opaque(Context *c, const EnumDecl *enum_decl,
|
||||
Buf *full_type_name, Buf *bare_name)
|
||||
{
|
||||
AstNode *opaque_node = trans_create_node_opaque(c);
|
||||
if (full_type_name == nullptr) {
|
||||
c->decl_table.put(enum_decl, opaque_node);
|
||||
return opaque_node;
|
||||
}
|
||||
AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
|
||||
c->enum_type_table.put(bare_name, symbol_node);
|
||||
add_global_weak_alias(c, bare_name, full_type_name);
|
||||
add_global_var(c, full_type_name, opaque_node);
|
||||
c->decl_table.put(enum_decl, symbol_node);
|
||||
return symbol_node;
|
||||
}
|
||||
|
||||
static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
|
||||
auto existing_entry = c->decl_table.maybe_get((void*)enum_decl);
|
||||
if (existing_entry) {
|
||||
@ -1727,14 +1749,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
|
||||
|
||||
const EnumDecl *enum_def = enum_decl->getDefinition();
|
||||
if (!enum_def) {
|
||||
AstNode *opaque_node = trans_create_node_opaque(c);
|
||||
if (!is_anonymous) {
|
||||
c->enum_type_table.put(bare_name, opaque_node);
|
||||
add_global_weak_alias(c, bare_name, opaque_node);
|
||||
add_global_var(c, full_type_name, opaque_node);
|
||||
}
|
||||
c->decl_table.put(enum_decl, opaque_node);
|
||||
return opaque_node;
|
||||
return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name);
|
||||
}
|
||||
|
||||
bool pure_enum = true;
|
||||
@ -1786,14 +1801,17 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
|
||||
add_global_var(c, enum_val_name, field_access_node);
|
||||
}
|
||||
|
||||
if (!is_anonymous) {
|
||||
c->enum_type_table.put(bare_name, enum_node);
|
||||
add_global_weak_alias(c, bare_name, enum_node);
|
||||
if (is_anonymous) {
|
||||
c->decl_table.put(enum_decl, enum_node);
|
||||
return enum_node;
|
||||
} else {
|
||||
AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
|
||||
c->enum_type_table.put(bare_name, symbol_node);
|
||||
add_global_weak_alias(c, bare_name, full_type_name);
|
||||
add_global_var(c, full_type_name, enum_node);
|
||||
c->decl_table.put(enum_decl, symbol_node);
|
||||
return enum_node;
|
||||
}
|
||||
c->decl_table.put(enum_decl, enum_node);
|
||||
|
||||
return enum_node;
|
||||
}
|
||||
|
||||
// TODO after issue #305 is solved, make this be an enum with tag_int_type
|
||||
@ -1814,14 +1832,32 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
|
||||
var_node->data.variable_declaration.type = tag_int_type;
|
||||
}
|
||||
|
||||
if (!is_anonymous) {
|
||||
c->enum_type_table.put(bare_name, enum_node);
|
||||
add_global_weak_alias(c, bare_name, enum_node);
|
||||
if (is_anonymous) {
|
||||
c->decl_table.put(enum_decl, enum_node);
|
||||
return enum_node;
|
||||
} else {
|
||||
AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
|
||||
c->enum_type_table.put(bare_name, symbol_node);
|
||||
add_global_weak_alias(c, bare_name, full_type_name);
|
||||
add_global_var(c, full_type_name, enum_node);
|
||||
return symbol_node;
|
||||
}
|
||||
c->decl_table.put(enum_decl, enum_node);
|
||||
}
|
||||
|
||||
return enum_node;
|
||||
static AstNode *demote_struct_to_opaque(Context *c, const RecordDecl *record_decl,
|
||||
Buf *full_type_name, Buf *bare_name)
|
||||
{
|
||||
AstNode *opaque_node = trans_create_node_opaque(c);
|
||||
if (full_type_name == nullptr) {
|
||||
c->decl_table.put(record_decl, opaque_node);
|
||||
return opaque_node;
|
||||
}
|
||||
AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
|
||||
c->struct_type_table.put(bare_name, symbol_node);
|
||||
add_global_weak_alias(c, bare_name, full_type_name);
|
||||
add_global_var(c, full_type_name, opaque_node);
|
||||
c->decl_table.put(record_decl, symbol_node);
|
||||
return symbol_node;
|
||||
}
|
||||
|
||||
static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
|
||||
@ -1834,7 +1870,6 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
|
||||
|
||||
if (!record_decl->isStruct()) {
|
||||
emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name);
|
||||
c->decl_table.put(record_decl, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -1844,14 +1879,7 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
|
||||
|
||||
RecordDecl *record_def = record_decl->getDefinition();
|
||||
if (record_def == nullptr) {
|
||||
AstNode *opaque_node = trans_create_node_opaque(c);
|
||||
if (!is_anonymous) {
|
||||
c->struct_type_table.put(bare_name, opaque_node);
|
||||
add_global_weak_alias(c, bare_name, opaque_node);
|
||||
add_global_var(c, full_type_name, opaque_node);
|
||||
}
|
||||
c->decl_table.put(record_decl, opaque_node);
|
||||
return opaque_node;
|
||||
return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
|
||||
}
|
||||
|
||||
// count fields and validate
|
||||
@ -1865,16 +1893,7 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
|
||||
if (field_decl->isBitField()) {
|
||||
emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield",
|
||||
is_anonymous ? "(anon)" : buf_ptr(bare_name));
|
||||
|
||||
AstNode *opaque_node = trans_create_node_opaque(c);
|
||||
|
||||
if (!is_anonymous) {
|
||||
c->struct_type_table.put(bare_name, opaque_node);
|
||||
add_global_weak_alias(c, bare_name, opaque_node);
|
||||
add_global_var(c, full_type_name, opaque_node);
|
||||
}
|
||||
c->decl_table.put(record_decl, opaque_node);
|
||||
return opaque_node;;
|
||||
return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1887,12 +1906,14 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
|
||||
struct_node->data.container_decl.fields.resize(field_count);
|
||||
|
||||
// must be before fields in case a circular reference happens
|
||||
if (!is_anonymous) {
|
||||
if (is_anonymous) {
|
||||
c->decl_table.put(record_decl, struct_node);
|
||||
} else {
|
||||
c->struct_type_table.put(bare_name, struct_node);
|
||||
add_global_weak_alias(c, bare_name, struct_node);
|
||||
add_global_weak_alias(c, bare_name, full_type_name);
|
||||
add_global_var(c, full_type_name, struct_node);
|
||||
c->decl_table.put(record_decl, trans_create_node_symbol(c, full_type_name));
|
||||
}
|
||||
c->decl_table.put(record_decl, struct_node);
|
||||
|
||||
uint32_t i = 0;
|
||||
for (auto it = record_def->field_begin(),
|
||||
@ -1910,22 +1931,17 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
|
||||
"struct %s demoted to opaque type - unresolved type",
|
||||
is_anonymous ? "(anon)" : buf_ptr(bare_name));
|
||||
|
||||
AstNode *opaque_node = trans_create_node_opaque(c);
|
||||
if (!is_anonymous) {
|
||||
c->struct_type_table.put(bare_name, opaque_node);
|
||||
add_global_weak_alias(c, bare_name, opaque_node);
|
||||
add_global_var(c, full_type_name, opaque_node);
|
||||
}
|
||||
c->decl_table.put(record_decl, opaque_node);
|
||||
|
||||
return opaque_node;
|
||||
return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
|
||||
}
|
||||
|
||||
struct_node->data.container_decl.fields.items[i] = field_node;
|
||||
}
|
||||
|
||||
|
||||
return struct_node;
|
||||
if (is_anonymous) {
|
||||
return struct_node;
|
||||
} else {
|
||||
return trans_create_node_symbol(c, full_type_name);
|
||||
}
|
||||
}
|
||||
|
||||
static void visit_var_decl(Context *c, const VarDecl *var_decl) {
|
||||
@ -2045,10 +2061,10 @@ static bool name_exists(Context *c, Buf *name) {
|
||||
static void render_aliases(Context *c) {
|
||||
for (size_t i = 0; i < c->aliases.length; i += 1) {
|
||||
Alias *alias = &c->aliases.at(i);
|
||||
if (name_exists(c, alias->name))
|
||||
if (name_exists(c, alias->new_name))
|
||||
continue;
|
||||
|
||||
add_global_var(c, alias->name, alias->node);
|
||||
add_global_var(c, alias->new_name, trans_create_node_symbol(c, alias->canon_name));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2174,7 +2190,7 @@ static void process_symbol_macros(Context *c) {
|
||||
}
|
||||
}
|
||||
|
||||
add_global_var(c, ms.name, existing_node);
|
||||
add_global_var(c, ms.name, trans_create_node_symbol(c, ms.value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,6 @@ struct ParseContext {
|
||||
ErrColor err_color;
|
||||
// These buffers are used freqently so we preallocate them once here.
|
||||
Buf *void_buf;
|
||||
Buf *empty_buf;
|
||||
};
|
||||
|
||||
__attribute__ ((format (printf, 4, 5)))
|
||||
@ -276,7 +275,7 @@ static AstNode *ast_parse_param_decl(ParseContext *pc, size_t *token_index) {
|
||||
token = &pc->tokens->at(*token_index);
|
||||
}
|
||||
|
||||
node->data.param_decl.name = pc->empty_buf;
|
||||
node->data.param_decl.name = nullptr;
|
||||
|
||||
if (token->id == TokenIdSymbol) {
|
||||
Token *next_token = &pc->tokens->at(*token_index + 1);
|
||||
@ -2246,7 +2245,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
|
||||
*token_index += 1;
|
||||
node->data.fn_proto.name = token_buf(fn_name);
|
||||
} else {
|
||||
node->data.fn_proto.name = pc->empty_buf;
|
||||
node->data.fn_proto.name = nullptr;
|
||||
}
|
||||
|
||||
ast_parse_param_decl_list(pc, token_index, &node->data.fn_proto.params, &node->data.fn_proto.is_var_args);
|
||||
@ -2612,7 +2611,6 @@ AstNode *ast_parse(Buf *buf, ZigList<Token> *tokens, ImportTableEntry *owner,
|
||||
{
|
||||
ParseContext pc = {0};
|
||||
pc.void_buf = buf_create_from_str("void");
|
||||
pc.empty_buf = buf_create_from_str("");
|
||||
pc.err_color = err_color;
|
||||
pc.owner = owner;
|
||||
pc.buf = buf;
|
||||
|
||||
@ -44,11 +44,11 @@ pub fn addCases(cases: &tests.ParseHContext) {
|
||||
\\ @"1",
|
||||
\\};
|
||||
,
|
||||
\\pub const FooA = Foo.A;
|
||||
\\pub const FooA = enum_Foo.A;
|
||||
,
|
||||
\\pub const FooB = Foo.B;
|
||||
\\pub const FooB = enum_Foo.B;
|
||||
,
|
||||
\\pub const Foo1 = Foo.1;
|
||||
\\pub const Foo1 = enum_Foo.@"1";
|
||||
,
|
||||
\\pub const Foo = enum_Foo;
|
||||
);
|
||||
@ -94,9 +94,9 @@ pub fn addCases(cases: &tests.ParseHContext) {
|
||||
\\ B,
|
||||
\\};
|
||||
,
|
||||
\\pub const BarA = 0;
|
||||
\\pub const BarA = enum_Bar.A;
|
||||
,
|
||||
\\pub const BarB = 1;
|
||||
\\pub const BarB = enum_Bar.B;
|
||||
,
|
||||
\\pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar);
|
||||
,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user