aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/all_types.hpp4
-rw-r--r--src/analyze.cpp3
-rw-r--r--src/ir.cpp3
-rw-r--r--src/parser.cpp35
4 files changed, 34 insertions, 11 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 74f25fc32b..15082b62aa 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -598,6 +598,7 @@ struct AstNodeContainerDecl {
ContainerKind kind;
ZigList<AstNode *> fields;
ZigList<AstNode *> decls;
+ bool is_extern;
};
struct AstNodeStructField {
@@ -801,6 +802,7 @@ struct TypeStructField {
};
struct TypeTableEntryStruct {
AstNode *decl_node;
+ bool is_extern;
bool is_packed;
uint32_t src_field_count;
uint32_t gen_field_count;
@@ -827,6 +829,7 @@ struct TypeTableEntryError {
struct TypeTableEntryEnum {
AstNode *decl_node;
+ bool is_extern;
uint32_t src_field_count;
uint32_t gen_field_count;
TypeEnumField *fields;
@@ -845,6 +848,7 @@ struct TypeTableEntryEnum {
struct TypeTableEntryUnion {
AstNode *decl_node;
+ bool is_extern;
uint32_t src_field_count;
uint32_t gen_field_count;
TypeStructField *fields;
diff --git a/src/analyze.cpp b/src/analyze.cpp
index ea3ba4aa7f..7651742986 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -838,12 +838,15 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKi
switch (kind) {
case ContainerKindStruct:
entry->data.structure.decl_node = decl_node;
+ entry->data.structure.is_extern = decl_node->data.container_decl.is_extern;
break;
case ContainerKindEnum:
entry->data.enumeration.decl_node = decl_node;
+ entry->data.enumeration.is_extern = decl_node->data.container_decl.is_extern;
break;
case ContainerKindUnion:
entry->data.unionation.decl_node = decl_node;
+ entry->data.unionation.is_extern = decl_node->data.container_decl.is_extern;
break;
}
diff --git a/src/ir.cpp b/src/ir.cpp
index d2729d8ed1..ae6fd78d1f 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -8007,6 +8007,9 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
TypeTableEntry *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields,
bool depends_on_compile_var)
{
+ if (!type_is_complete(container_type))
+ resolve_container_type(ira->codegen, container_type);
+
size_t actual_field_count = container_type->data.structure.src_field_count;
IrInstruction *first_non_const_instruction = nullptr;
diff --git a/src/parser.cpp b/src/parser.cpp
index 0ee984d7fa..54994034f9 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -684,11 +684,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
AstNode *node = ast_create_node(pc, NodeTypeErrorType, token);
*token_index += 1;
return node;
- } else if (token->id == TokenIdKeywordExtern) {
- *token_index += 1;
- AstNode *node = ast_parse_fn_proto(pc, token_index, true, VisibModPrivate);
- node->data.fn_proto.is_extern = true;
- return node;
} else if (token->id == TokenIdAtSign) {
*token_index += 1;
Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
@@ -742,6 +737,13 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
if (container_decl)
return container_decl;
+ if (token->id == TokenIdKeywordExtern) {
+ *token_index += 1;
+ AstNode *node = ast_parse_fn_proto(pc, token_index, true, VisibModPrivate);
+ node->data.fn_proto.is_extern = true;
+ return node;
+ }
+
if (!mandatory)
return nullptr;
@@ -2224,28 +2226,39 @@ static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index, VisibMod vi
}
/*
-ContainerDecl = ("struct" | "enum" | "union") "{" many(StructMember) "}"
+ContainerDecl = option("extern") ("struct" | "enum" | "union") "{" many(StructMember) "}"
StructMember = (StructField | FnDef | GlobalVarDecl)
StructField = Symbol option(":" Expression) ",")
*/
static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory) {
Token *first_token = &pc->tokens->at(*token_index);
+ Token *container_kind_token;
+
+ bool is_extern;
+ if (first_token->id == TokenIdKeywordExtern) {
+ container_kind_token = &pc->tokens->at(*token_index + 1);
+ is_extern = true;
+ } else {
+ container_kind_token = first_token;
+ is_extern = false;
+ }
ContainerKind kind;
- if (first_token->id == TokenIdKeywordStruct) {
+ if (container_kind_token->id == TokenIdKeywordStruct) {
kind = ContainerKindStruct;
- } else if (first_token->id == TokenIdKeywordEnum) {
+ } else if (container_kind_token->id == TokenIdKeywordEnum) {
kind = ContainerKindEnum;
- } else if (first_token->id == TokenIdKeywordUnion) {
+ } else if (container_kind_token->id == TokenIdKeywordUnion) {
kind = ContainerKindUnion;
} else if (mandatory) {
- ast_invalid_token_error(pc, first_token);
+ ast_invalid_token_error(pc, container_kind_token);
} else {
return nullptr;
}
- *token_index += 1;
+ *token_index += is_extern ? 2 : 1;
AstNode *node = ast_create_node(pc, NodeTypeContainerDecl, first_token);
+ node->data.container_decl.is_extern = is_extern;
node->data.container_decl.kind = kind;
ast_eat_token(pc, token_index, TokenIdLBrace);