Commit 37b13bf151

Andrew Kelley <superjoe30@gmail.com>
2016-12-18 23:24:52
hello.zig working with all structs anonymous
1 parent e50ced4
doc/langref.md
@@ -151,7 +151,7 @@ GroupedExpression = "(" Expression ")"
 
 KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this"
 
-ContainerDecl = ("struct" | "enum" | "union") "{" many(StructMember) "}"
+ContainerDecl = option("extern") ("struct" | "enum" | "union") "{" many(StructMember) "}"
 
 ```
 
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;
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;
     }
 
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;
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);
std/cstr.zig
@@ -34,7 +34,7 @@ pub fn toSlice(str: &u8) -> []u8 {
 
 
 /// A buffer that allocates memory and maintains a null byte at the end.
-pub struct CBuf {
+pub const CBuf = struct {
     list: List(u8),
 
     /// Must deinitialize with deinit.
@@ -124,7 +124,7 @@ pub struct CBuf {
     pub fn startsWithCStr(self: &const CBuf, s: &const u8) -> bool {
         self.startsWithMem(s[0...strlen(s)])
     }
-}
+};
 
 fn testSimpleCBuf() {
     @setFnTest(this, true);
std/io.zig
@@ -69,7 +69,7 @@ pub const OpenWrite    = 0b0010;
 pub const OpenCreate   = 0b0100;
 pub const OpenTruncate = 0b1000;
 
-pub struct OutStream {
+pub const OutStream = struct {
     fd: i32,
     buffer: [buffer_size]u8,
     index: usize,
@@ -153,11 +153,11 @@ pub struct OutStream {
             return;
         }
     }
-}
+};
 
 // TODO created a BufferedInStream struct and move some of this code there
 // BufferedInStream API goes on top of minimal InStream API.
-pub struct InStream {
+pub const InStream = struct {
     fd: i32,
 
     /// Call close to clean up.
@@ -360,7 +360,7 @@ pub struct InStream {
 
         return usize(stat.size);
     }
-}
+};
 
 pub fn parseUnsigned(inline T: type, buf: []u8, radix: u8) -> %T {
     var x: T = 0;
std/linux.zig
@@ -342,31 +342,31 @@ pub const socklen_t = u32;
 pub const in_addr = u32;
 pub const in6_addr = [16]u8;
 
-export struct sockaddr {
+pub const sockaddr = extern struct {
     family: sa_family_t,
     port: u16,
     data: [12]u8,
-}
+};
 
-export struct sockaddr_in {
+pub const sockaddr_in = extern struct {
     family: sa_family_t,
     port: u16,
     addr: in_addr,
     zero: [8]u8,
-}
+};
 
-export struct sockaddr_in6 {
+pub const sockaddr_in6 = extern struct {
     family: sa_family_t,
     port: u16,
     flowinfo: u32,
     addr: in6_addr,
     scope_id: u32,
-}
+};
 
-export struct iovec {
+pub const iovec = extern struct {
     iov_base: &u8,
     iov_len: usize,
-}
+};
 
 //
 //const IF_NAMESIZE = 16;
std/linux_x86_64.zig
@@ -442,7 +442,7 @@ pub inline fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg
         : "rcx", "r11")
 }
 
-export struct msghdr {
+pub const msghdr = extern struct {
     msg_name: &u8,
     msg_namelen: socklen_t,
     msg_iov: &iovec,
@@ -452,9 +452,9 @@ export struct msghdr {
     msg_controllen: socklen_t,
     __pad2: socklen_t,
     msg_flags: i32,
-}
+};
 
-export struct stat {
+pub const stat = extern struct {
     dev: u64,
     ino: u64,
     nlink: usize,
@@ -472,9 +472,9 @@ export struct stat {
     mtim: timespec,
     ctim: timespec,
     __unused: [3]isize,
-}
+};
 
-export struct timespec {
+pub const timespec = extern struct {
     tv_sec: isize,
     tv_nsec: isize,
-}
+};
std/math.zig
@@ -1,8 +1,8 @@
-pub enum Cmp {
+pub const Cmp = enum {
     Equal,
     Greater,
     Less,
-}
+};
 
 pub fn min(x: var, y: var) -> @typeOf(x + y) {
     if (x < y) x else y