aboutsummaryrefslogtreecommitdiff
path: root/src/stage1/analyze.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-10-07 16:58:50 -0400
committerGitHub <noreply@github.com>2020-10-07 16:58:50 -0400
commit95a37373e9f576854956c2909cc128b5b6388ec6 (patch)
tree647f62398f1afbc0546d223b05203e6c69372ba2 /src/stage1/analyze.cpp
parent3c43eeceab70f78939401b68811f152a7f29b191 (diff)
parentbf4bfe54ac13512d7553a7be83ae19e908e9c294 (diff)
downloadzig-95a37373e9f576854956c2909cc128b5b6388ec6.tar.gz
zig-95a37373e9f576854956c2909cc128b5b6388ec6.zip
Merge pull request #6421 from tadeokondrak/opaque-syntax
Add opaque syntax that allows declarations
Diffstat (limited to 'src/stage1/analyze.cpp')
-rw-r--r--src/stage1/analyze.cpp62
1 files changed, 52 insertions, 10 deletions
diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp
index 88bbf6b9ac..bc9d265bd1 100644
--- a/src/stage1/analyze.cpp
+++ b/src/stage1/analyze.cpp
@@ -86,14 +86,18 @@ ZigType *new_type_table_entry(ZigTypeId id) {
}
static ScopeDecls **get_container_scope_ptr(ZigType *type_entry) {
- if (type_entry->id == ZigTypeIdStruct) {
- return &type_entry->data.structure.decls_scope;
- } else if (type_entry->id == ZigTypeIdEnum) {
- return &type_entry->data.enumeration.decls_scope;
- } else if (type_entry->id == ZigTypeIdUnion) {
- return &type_entry->data.unionation.decls_scope;
+ switch (type_entry->id) {
+ case ZigTypeIdStruct:
+ return &type_entry->data.structure.decls_scope;
+ case ZigTypeIdEnum:
+ return &type_entry->data.enumeration.decls_scope;
+ case ZigTypeIdUnion:
+ return &type_entry->data.unionation.decls_scope;
+ case ZigTypeIdOpaque:
+ return &type_entry->data.opaque.decls_scope;
+ default:
+ zig_unreachable();
}
- zig_unreachable();
}
static ScopeExpr *find_expr_scope(Scope *scope) {
@@ -912,13 +916,17 @@ ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const c
ZigType *import = scope ? get_scope_import(scope) : nullptr;
unsigned line = source_node ? (unsigned)(source_node->line + 1) : 0;
+ // Note: duplicated in get_partial_container_type
entry->llvm_type = LLVMInt8Type();
entry->llvm_di_type = ZigLLVMCreateDebugForwardDeclType(g->dbuilder,
ZigLLVMTag_DW_structure_type(), full_name,
import ? ZigLLVMFileToScope(import->data.structure.root_struct->di_file) : nullptr,
import ? import->data.structure.root_struct->di_file : nullptr,
line);
+ entry->data.opaque.decl_node = source_node;
entry->data.opaque.bare_name = bare_name;
+ entry->data.opaque.decls_scope = create_decls_scope(
+ g, source_node, scope, entry, import, &entry->name);
// The actual size is unknown, but the value must not be 0 because that
// is how type_has_bits is determined.
@@ -1078,6 +1086,8 @@ static ZigTypeId container_to_type(ContainerKind kind) {
return ZigTypeIdEnum;
case ContainerKindUnion:
return ZigTypeIdUnion;
+ case ContainerKindOpaque:
+ return ZigTypeIdOpaque;
}
zig_unreachable();
}
@@ -1119,6 +1129,22 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind
entry->data.unionation.decl_node = decl_node;
entry->data.unionation.layout = layout;
break;
+ case ContainerKindOpaque: {
+ ZigType *import = scope ? get_scope_import(scope) : nullptr;
+ unsigned line = decl_node ? (unsigned)(decl_node->line + 1) : 0;
+ // Note: duplicated in get_opaque_type
+ entry->llvm_type = LLVMInt8Type();
+ entry->llvm_di_type = ZigLLVMCreateDebugForwardDeclType(g->dbuilder,
+ ZigLLVMTag_DW_structure_type(), full_name,
+ import ? ZigLLVMFileToScope(import->data.structure.root_struct->di_file) : nullptr,
+ import ? import->data.structure.root_struct->di_file : nullptr,
+ line);
+ entry->data.opaque.decl_node = decl_node;
+ entry->abi_size = SIZE_MAX;
+ entry->size_in_bits = SIZE_MAX;
+ entry->abi_align = 1;
+ break;
+ }
}
buf_init_from_str(&entry->name, full_name);
@@ -3428,6 +3454,21 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
return ErrorNone;
}
+static Error resolve_opaque_type(CodeGen *g, ZigType *opaque_type) {
+ Error err = ErrorNone;
+ AstNode *container_node = opaque_type->data.opaque.decl_node;
+ if (container_node != nullptr) {
+ assert(container_node->type == NodeTypeContainerDecl);
+ AstNodeContainerDecl *container_decl = &container_node->data.container_decl;
+ for (size_t i = 0; i < container_decl->fields.length; i++) {
+ AstNode *field_node = container_decl->fields.items[i];
+ add_node_error(g, field_node, buf_create_from_str("opaque types cannot have fields"));
+ err = ErrorSemanticAnalyzeFail;
+ }
+ }
+ return err;
+}
+
void append_namespace_qualification(CodeGen *g, Buf *buf, ZigType *container_type) {
if (g->root_import == container_type || buf_len(&container_type->name) == 0) return;
buf_append_buf(buf, &container_type->name);
@@ -3893,6 +3934,8 @@ static Error resolve_decl_container(CodeGen *g, TldContainer *tld_container) {
return resolve_enum_zero_bits(g, tld_container->type_entry);
case ZigTypeIdUnion:
return resolve_union_type(g, tld_container->type_entry);
+ case ZigTypeIdOpaque:
+ return resolve_opaque_type(g, tld_container->type_entry);
default:
zig_unreachable();
}
@@ -4459,6 +4502,7 @@ bool is_container(ZigType *type_entry) {
return type_entry->data.structure.special != StructSpecialSlice;
case ZigTypeIdEnum:
case ZigTypeIdUnion:
+ case ZigTypeIdOpaque:
return true;
case ZigTypeIdPointer:
case ZigTypeIdMetaType:
@@ -4478,7 +4522,6 @@ bool is_container(ZigType *type_entry) {
case ZigTypeIdErrorSet:
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
- case ZigTypeIdOpaque:
case ZigTypeIdVector:
case ZigTypeIdFnFrame:
case ZigTypeIdAnyFrame:
@@ -8165,6 +8208,7 @@ const char *container_string(ContainerKind kind) {
case ContainerKindEnum: return "enum";
case ContainerKindStruct: return "struct";
case ContainerKindUnion: return "union";
+ case ContainerKindOpaque: return "opaque";
}
zig_unreachable();
}
@@ -8183,8 +8227,6 @@ Buf *type_bare_name(ZigType *type_entry) {
return &type_entry->name;
} else if (is_container(type_entry)) {
return get_container_scope(type_entry)->bare_name;
- } else if (type_entry->id == ZigTypeIdOpaque) {
- return type_entry->data.opaque.bare_name;
} else {
return &type_entry->name;
}