diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2016-01-03 19:38:36 -0700 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2016-01-03 19:38:36 -0700 |
| commit | e64c0941f9cff66311c969b85be5fe5575c4ce45 (patch) | |
| tree | a3417dd85241d55362433f41e00b72d4d2cba435 /src/codegen.cpp | |
| parent | fa6e3eec464227a2c20ca949e2fd12f3ab649960 (diff) | |
| download | zig-e64c0941f9cff66311c969b85be5fe5575c4ce45.tar.gz zig-e64c0941f9cff66311c969b85be5fe5575c4ce45.zip | |
implement #sizeof()
closes #8
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 82 |
1 files changed, 56 insertions, 26 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 1fe0226378..7985e55e96 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1191,6 +1191,58 @@ static LLVMValueRef gen_var_decl_expr(CodeGen *g, AstNode *node) { node->codegen_node->expr_node.block_context, false, &init_val); } +static LLVMValueRef gen_number_literal_raw(CodeGen *g, AstNode *source_node, + NumberLiteralNode *codegen_num_lit, AstNodeNumberLiteral *num_lit_node) +{ + TypeTableEntry *type_entry = codegen_num_lit->resolved_type; + assert(type_entry); + + // override the expression type for number literals + source_node->codegen_node->expr_node.type_entry = type_entry; + + if (type_entry->id == TypeTableEntryIdInt) { + // here the union has int64_t and uint64_t and we purposefully read + // the uint64_t value in either case, because we want the twos + // complement representation + + return LLVMConstInt(type_entry->type_ref, + num_lit_node->data.x_uint, + type_entry->data.integral.is_signed); + } else if (type_entry->id == TypeTableEntryIdFloat) { + + return LLVMConstReal(type_entry->type_ref, + num_lit_node->data.x_float); + } else { + zig_panic("bad number literal type"); + } +} + +static LLVMValueRef gen_compiler_fn_type(CodeGen *g, AstNode *node) { + assert(node->type == NodeTypeCompilerFnType); + + Buf *name = &node->data.compiler_fn_type.name; + if (buf_eql_str(name, "sizeof")) { + TypeTableEntry *type_entry = get_type_for_type_node(g, node->data.compiler_fn_type.type); + NumberLiteralNode *codegen_num_lit = &node->codegen_node->data.num_lit_node; + AstNodeNumberLiteral num_lit_node; + num_lit_node.kind = type_entry->data.num_lit.kind; + num_lit_node.overflow = false; + num_lit_node.data.x_uint = type_entry->size_in_bits / 8; + return gen_number_literal_raw(g, node, codegen_num_lit, &num_lit_node); + } else { + zig_unreachable(); + } +} + +static LLVMValueRef gen_number_literal(CodeGen *g, AstNode *node) { + assert(node->type == NodeTypeNumberLiteral); + + NumberLiteralNode *codegen_num_lit = &node->codegen_node->data.num_lit_node; + assert(codegen_num_lit); + + return gen_number_literal_raw(g, node, codegen_num_lit, &node->data.number_literal); +} + static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) { switch (node->type) { case NodeTypeBinOpExpr: @@ -1228,31 +1280,7 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) { case NodeTypeAsmExpr: return gen_asm_expr(g, node); case NodeTypeNumberLiteral: - { - NumberLiteralNode *codegen_num_lit = &node->codegen_node->data.num_lit_node; - assert(codegen_num_lit); - TypeTableEntry *type_entry = codegen_num_lit->resolved_type; - assert(type_entry); - - // override the expression type for number literals - node->codegen_node->expr_node.type_entry = type_entry; - - if (type_entry->id == TypeTableEntryIdInt) { - // here the union has int64_t and uint64_t and we purposefully read - // the uint64_t value in either case, because we want the twos - // complement representation - - return LLVMConstInt(type_entry->type_ref, - node->data.number_literal.data.x_uint, - type_entry->data.integral.is_signed); - } else if (type_entry->id == TypeTableEntryIdFloat) { - - return LLVMConstReal(type_entry->type_ref, - node->data.number_literal.data.x_float); - } else { - zig_panic("bad number literal type"); - } - } + return gen_number_literal(g, node); case NodeTypeStringLiteral: { Buf *str = &node->data.string_literal.buf; @@ -1313,6 +1341,8 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) { } case NodeTypeStructValueExpr: return gen_struct_val_expr(g, node); + case NodeTypeCompilerFnType: + return gen_compiler_fn_type(g, node); case NodeTypeRoot: case NodeTypeRootExportDecl: case NodeTypeFnProto: @@ -1326,7 +1356,7 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) { case NodeTypeStructDecl: case NodeTypeStructField: case NodeTypeStructValueField: - case NodeTypeCompilerFnCall: + case NodeTypeCompilerFnExpr: zig_unreachable(); } zig_unreachable(); |
