authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-14 22:01:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-14 22:06:25-07:00
log52e19b4a9b6e6140bae3c20c6f1fef36dca20aa7
tree7f08300bbaedd657fc46ae816e0302470becfb1a
parent304941026013e6310c9362849610c32d98d1332a

analyze: BlockContext has concept of module scope


5 files changed, 47 insertions(+), 36 deletions(-)

doc/langref.md+3-1
......@@ -32,7 +32,9 @@ zig | C equivalent | Description
3232```
3333Root : many(TopLevelDecl) token(EOF)
3434
35TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl
35TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl | VariableDeclaration
36
37VariableDeclaration : (token(Var) | token(Const)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
3638
3739StructDecl : many(Directive) token(Struct) token(Symbol) token(LBrace) many(StructField) token(RBrace)
3840
src/analyze.cpp+24-27
......@@ -445,6 +445,7 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,
445445 break;
446446 }
447447 case NodeTypeUse:
448 case NodeTypeVariableDeclaration:
448449 // nothing to do here
449450 break;
450451 case NodeTypeDirective:
......@@ -453,7 +454,6 @@ static void preview_function_declarations(CodeGen *g, ImportTableEntry *import,
453454 case NodeTypeType:
454455 case NodeTypeFnDecl:
455456 case NodeTypeReturnExpr:
456 case NodeTypeVariableDeclaration:
457457 case NodeTypeRoot:
458458 case NodeTypeBlock:
459459 case NodeTypeBinOpExpr:
......@@ -505,6 +505,7 @@ static void preview_types(CodeGen *g, ImportTableEntry *import, AstNode *node) {
505505 case NodeTypeFnDef:
506506 case NodeTypeRootExportDecl:
507507 case NodeTypeUse:
508 case NodeTypeVariableDeclaration:
508509 // nothing to do
509510 break;
510511 case NodeTypeDirective:
......@@ -513,7 +514,6 @@ static void preview_types(CodeGen *g, ImportTableEntry *import, AstNode *node) {
513514 case NodeTypeType:
514515 case NodeTypeFnDecl:
515516 case NodeTypeReturnExpr:
516 case NodeTypeVariableDeclaration:
517517 case NodeTypeRoot:
518518 case NodeTypeBlock:
519519 case NodeTypeBinOpExpr:
......@@ -537,26 +537,20 @@ static void preview_types(CodeGen *g, ImportTableEntry *import, AstNode *node) {
537537 }
538538}
539539
540static TypeTableEntry * get_return_type(BlockContext *context) {
541 AstNode *fn_def_node = context->root->node;
542 assert(fn_def_node->type == NodeTypeFnDef);
543 AstNode *fn_proto_node = fn_def_node->data.fn_def.fn_proto;
540static FnTableEntry *get_context_fn_entry(BlockContext *context) {
541 assert(context->fn_entry);
542 return context->fn_entry;
543}
544
545static TypeTableEntry *get_return_type(BlockContext *context) {
546 FnTableEntry *fn_entry = get_context_fn_entry(context);
547 AstNode *fn_proto_node = fn_entry->proto_node;
544548 assert(fn_proto_node->type == NodeTypeFnProto);
545549 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
546550 assert(return_type_node->codegen_node);
547551 return return_type_node->codegen_node->data.type_node.entry;
548552}
549553
550static FnTableEntry *get_context_fn_entry(BlockContext *context) {
551 AstNode *fn_def_node = context->root->node;
552 assert(fn_def_node->type == NodeTypeFnDef);
553 AstNode *fn_proto_node = fn_def_node->data.fn_def.fn_proto;
554 assert(fn_proto_node->type == NodeTypeFnProto);
555 assert(fn_proto_node->codegen_node);
556 assert(fn_proto_node->codegen_node->data.fn_proto_node.fn_table_entry);
557 return fn_proto_node->codegen_node->data.fn_proto_node.fn_table_entry;
558}
559
560554static void check_type_compatibility(CodeGen *g, AstNode *node,
561555 TypeTableEntry *expected_type, TypeTableEntry *actual_type)
562556{
......@@ -575,21 +569,22 @@ static void check_type_compatibility(CodeGen *g, AstNode *node,
575569 buf_ptr(&actual_type->name)));
576570}
577571
578static BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
572BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
579573 BlockContext *context = allocate<BlockContext>(1);
580574 context->node = node;
581575 context->parent = parent;
582 if (parent != nullptr)
583 context->root = parent->root;
584 else
585 context->root = context;
586576 context->variable_table.init(8);
587577
588 AstNode *fn_def_node = context->root->node;
589 assert(fn_def_node->type == NodeTypeFnDef);
590 assert(fn_def_node->codegen_node);
591 FnDefNode *fn_def_info = &fn_def_node->codegen_node->data.fn_def_node;
592 fn_def_info->all_block_contexts.append(context);
578 if (parent) {
579 context->fn_entry = parent->fn_entry;
580 } else if (node && node->type == NodeTypeFnDef) {
581 AstNode *fn_proto_node = node->data.fn_def.fn_proto;
582 context->fn_entry = fn_proto_node->codegen_node->data.fn_proto_node.fn_table_entry;
583 }
584
585 if (context->fn_entry) {
586 context->fn_entry->all_block_contexts.append(context);
587 }
593588
594589 return context;
595590}
......@@ -1509,13 +1504,15 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import,
15091504 case NodeTypeStructDecl:
15101505 // nothing to do
15111506 break;
1507 case NodeTypeVariableDeclaration:
1508 analyze_variable_declaration(g, import, import->block_context, nullptr, node);
1509 break;
15121510 case NodeTypeDirective:
15131511 case NodeTypeParamDecl:
15141512 case NodeTypeFnProto:
15151513 case NodeTypeType:
15161514 case NodeTypeFnDecl:
15171515 case NodeTypeReturnExpr:
1518 case NodeTypeVariableDeclaration:
15191516 case NodeTypeRoot:
15201517 case NodeTypeBlock:
15211518 case NodeTypeBinOpExpr:
src/analyze.hpp+7-5
......@@ -90,6 +90,7 @@ struct ImportTableEntry {
9090 LLVMZigDIFile *di_file;
9191 Buf *source_code;
9292 ZigList<int> *line_offsets;
93 BlockContext *block_context;
9394
9495 // reminder: hash tables must be initialized before use
9596 HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table;
......@@ -116,6 +117,8 @@ struct FnTableEntry {
116117 unsigned calling_convention;
117118 ImportTableEntry *import_entry;
118119 ZigList<FnAttrId> fn_attr_list;
120 // Required to be a pre-order traversal of the AST. (parents must come before children)
121 ZigList<BlockContext *> all_block_contexts;
119122
120123 // reminder: hash tables must be initialized before use
121124 HashMap<Buf *, LabelTableEntry *, buf_hash, buf_eql_buf> label_table;
......@@ -201,9 +204,9 @@ struct LocalVariableTableEntry {
201204};
202205
203206struct BlockContext {
204 AstNode *node; // either NodeTypeFnDef or NodeTypeBlock
205 BlockContext *root; // always points to the BlockContext with the NodeTypeFnDef
206 BlockContext *parent; // nullptr when this is the root
207 AstNode *node; // either NodeTypeFnDef or NodeTypeBlock or null for module scope
208 FnTableEntry *fn_entry; // null at the module scope
209 BlockContext *parent; // null when this is the root
207210 HashMap<Buf *, LocalVariableTableEntry *, buf_hash, buf_eql_buf> variable_table;
208211 ZigList<AstNode *> cast_expr_alloca_list;
209212 LLVMZigDIScope *di_scope;
......@@ -221,8 +224,6 @@ struct FnDefNode {
221224 TypeTableEntry *implicit_return_type;
222225 BlockContext *block_context;
223226 bool skip;
224 // Required to be a pre-order traversal of the AST. (parents must come before children)
225 ZigList<BlockContext *> all_block_contexts;
226227};
227228
228229struct ExprNode {
......@@ -295,5 +296,6 @@ void add_node_error(CodeGen *g, AstNode *node, Buf *msg);
295296TypeTableEntry *new_type_table_entry(TypeTableEntryId id);
296297TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
297298LocalVariableTableEntry *find_local_variable(BlockContext *context, Buf *name);
299BlockContext *new_block_context(AstNode *node, BlockContext *parent);
298300
299301#endif
src/codegen.cpp+5-2
......@@ -1132,8 +1132,8 @@ static void do_code_gen(CodeGen *g) {
11321132
11331133 // Set up debug info for blocks and variables and
11341134 // allocate all local variables
1135 for (int bc_i = 0; bc_i < codegen_fn_def->all_block_contexts.length; bc_i += 1) {
1136 BlockContext *block_context = codegen_fn_def->all_block_contexts.at(bc_i);
1135 for (int bc_i = 0; bc_i < fn_table_entry->all_block_contexts.length; bc_i += 1) {
1136 BlockContext *block_context = fn_table_entry->all_block_contexts.at(bc_i);
11371137
11381138 if (block_context->parent) {
11391139 LLVMZigDILexicalBlock *di_block = LLVMZigCreateLexicalBlock(g->dbuilder,
......@@ -1530,6 +1530,9 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *src_dirname, Buf *src
15301530 import_entry->di_file = LLVMZigCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname));
15311531 g->import_table.put(full_path, import_entry);
15321532
1533 import_entry->block_context = new_block_context(nullptr, nullptr);
1534 import_entry->block_context->di_scope = LLVMZigFileToScope(import_entry->di_file);
1535
15331536
15341537 assert(import_entry->root->type == NodeTypeRoot);
15351538 for (int decl_i = 0; decl_i < import_entry->root->data.root.top_level_decls.length; decl_i += 1) {
src/parser.cpp+8-1
......@@ -2266,7 +2266,7 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) {
22662266}
22672267
22682268/*
2269TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl
2269TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use | StructDecl | VariableDeclaration
22702270*/
22712271static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigList<AstNode *> *top_level_decls) {
22722272 for (;;) {
......@@ -2310,6 +2310,13 @@ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigLis
23102310 }
23112311 pc->directive_list = nullptr;
23122312
2313 AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false);
2314 if (var_decl_node) {
2315 ast_eat_token(pc, token_index, TokenIdSemicolon);
2316 top_level_decls->append(var_decl_node);
2317 continue;
2318 }
2319
23132320 return;
23142321 }
23152322 zig_unreachable();