Commit cc621cdee3
Changed files (5)
src/ast_render.cpp
@@ -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);
src/errmsg.cpp
@@ -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;
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));
}
}
src/parser.cpp
@@ -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;
test/parseh.zig
@@ -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);
,