Browse Source

Merge branch 'master' into fix-core-path-name-extension

jockus 5 years ago
parent
commit
914c99a15e
8 changed files with 88 additions and 12 deletions
  1. 4 7
      core/odin/parser/parser.odin
  2. 4 2
      core/time/time.odin
  3. 12 1
      src/check_type.cpp
  4. 28 0
      src/ir.cpp
  5. 31 1
      src/llvm_backend.cpp
  6. 4 0
      src/parser.cpp
  7. 2 1
      src/parser.hpp
  8. 3 0
      src/types.cpp

+ 4 - 7
core/odin/parser/parser.odin

@@ -1654,13 +1654,10 @@ parse_field_list :: proc(p: ^Parser, follow: tokenizer.Token_Kind, allowed_flags
 			names := make([]^ast.Expr, 1);
 			names[0] = ast.new(ast.Ident, tok.pos, end_pos(tok));
 			switch ident in &names[0].derived {
-				case ast.Ident: {
-					ident.name = tok.text;
-				}
-
-				case: {
-					unreachable();
-				}
+			case ast.Ident:
+				ident.name = tok.text;
+			case:
+				unreachable();
 			}
 
 			flags := check_field_flag_prefixes(p, len(list), allowed_flags, eaf.flags);

+ 4 - 2
core/time/time.odin

@@ -146,6 +146,7 @@ WALL_TO_INTERNAL :: i64((1884*365 + 1884/4 - 1884/100 + 1884/400) * SECONDS_PER_
 INTERNAL_TO_WALL :: i64(- WALL_TO_INTERNAL);
 
 UNIX_TO_ABSOLUTE :: i64(UNIX_TO_INTERNAL + INTERNAL_TO_ABSOLUTE);
+ABSOLUTE_TO_UNIX :: i64(-UNIX_TO_ABSOLUTE);
 
 _is_leap_year :: proc(year: int) -> bool {
 	return year%4 == 0 && (year%100 != 0 || year%400 == 0);
@@ -192,11 +193,12 @@ _abs_date :: proc(abs: u64, full: bool) -> (year: int, month: Month, day: int, y
 	}
 
 	day = yday;
+
 	if _is_leap_year(year) do switch {
-	case day < 31+29-1:
+	case day > 31+29-1:
 		day -= 1;
 	case day == 31+29-1:
-		month = Month.February;
+		month = .February;
 		day = 29;
 		return;
 	}

+ 12 - 1
src/check_type.cpp

@@ -1137,7 +1137,7 @@ void check_bit_set_type(CheckerContext *c, Type *type, Type *named_type, Ast *no
 	} else {
 		Type *elem = check_type_expr(c, bs->elem, nullptr);
 
-		#if 1
+		#if 0
 		if (named_type != nullptr && named_type->kind == Type_Named &&
 		    elem->kind == Type_Enum) {
 			// NOTE(bill): Anonymous enumeration
@@ -1662,6 +1662,10 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
 					error(name, "'auto_cast' can only be applied to variable fields");
 					p->flags &= ~FieldFlag_auto_cast;
 				}
+				if (p->flags&FieldFlag_const) {
+					error(name, "'#const' can only be applied to variable fields");
+					p->flags &= ~FieldFlag_const;
+				}
 
 				param = alloc_entity_type_name(scope, name->Ident.token, type, EntityState_Resolved);
 				param->TypeName.is_type_alias = true;
@@ -1726,6 +1730,10 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
 						error(name, "'auto_cast' can only be applied to variable fields");
 						p->flags &= ~FieldFlag_auto_cast;
 					}
+					if (p->flags&FieldFlag_const) {
+						error(name, "'#const' can only be applied to variable fields");
+						p->flags &= ~FieldFlag_const;
+					}
 
 					if (!is_type_constant_type(type) && !is_type_polymorphic(type)) {
 						gbString str = type_to_string(type);
@@ -1745,6 +1753,9 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
 			if (p->flags&FieldFlag_auto_cast) {
 				param->flags |= EntityFlag_AutoCast;
 			}
+			if (p->flags&FieldFlag_const) {
+				param->flags |= EntityFlag_ConstInput;
+			}
 
 			param->state = EntityState_Resolved; // NOTE(bill): This should have be resolved whilst determining it
 			add_entity(ctx->checker, scope, name, param);

+ 28 - 0
src/ir.cpp

@@ -4227,6 +4227,28 @@ irValue *ir_addr_get_ptr(irProcedure *proc, irAddr const &addr, bool allow_refer
 		}
 	}
 
+	case irAddr_RelativePointer: {
+		Type *rel_ptr = base_type(ir_addr_type(addr));
+		GB_ASSERT(rel_ptr->kind == Type_RelativePointer);
+
+		irValue *ptr = ir_emit_conv(proc, addr.addr, t_uintptr);
+		irValue *offset = ir_emit_conv(proc, ptr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
+		offset = ir_emit_load(proc, offset);
+
+		if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
+			offset = ir_emit_conv(proc, offset, t_i64);
+		}
+		offset = ir_emit_conv(proc, offset, t_uintptr);
+		irValue *absolute_ptr = ir_emit_arith(proc, Token_Add, ptr, offset, t_uintptr);
+		absolute_ptr = ir_emit_conv(proc, absolute_ptr, rel_ptr->RelativePointer.pointer_type);
+
+		irValue *cond = ir_emit_comp(proc, Token_CmpEq, offset, ir_value_nil(rel_ptr->RelativePointer.base_integer));
+
+		// NOTE(bill): nil check
+		irValue *nil_ptr = ir_value_nil(rel_ptr->RelativePointer.pointer_type);
+		irValue *final_ptr = ir_emit_select(proc, cond, nil_ptr, absolute_ptr);
+		return final_ptr;
+	}
 
 	case irAddr_BitField: {
 		irValue *v = ir_addr_load(proc, addr);
@@ -5101,6 +5123,10 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index) {
 		t = t->Opaque.elem;
 	}
 
+	if (is_type_relative_pointer(t)) {
+		s = ir_addr_get_ptr(proc, ir_addr(s));
+	}
+
 	if (is_type_struct(t)) {
 		result_type = alloc_type_pointer(t->Struct.fields[index]->type);
 	} else if (is_type_union(t)) {
@@ -5337,6 +5363,8 @@ irValue *ir_emit_deep_field_gep(irProcedure *proc, irValue *e, Selection sel) {
 			e = ir_emit_array_epi(proc, e, index);
 		} else if (type->kind == Type_Map) {
 			e = ir_emit_struct_ep(proc, e, index);
+		} else if (type->kind == Type_RelativePointer) {
+			e = ir_emit_struct_ep(proc, e, index);
 		} else {
 			GB_PANIC("un-gep-able type %s", type_to_string(type));
 		}

+ 31 - 1
src/llvm_backend.cpp

@@ -145,6 +145,30 @@ lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
 
 		return lb_emit_conv(p, ptr, alloc_type_pointer(map_type->Map.value));
 	}
+
+	case lbAddr_RelativePointer: {
+		Type *rel_ptr = base_type(lb_addr_type(addr));
+		GB_ASSERT(rel_ptr->kind == Type_RelativePointer);
+
+		lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr);
+		lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
+		offset = lb_emit_load(p, offset);
+
+		if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
+		offset = lb_emit_conv(p, offset, t_i64);
+		}
+		offset = lb_emit_conv(p, offset, t_uintptr);
+		lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr);
+		absolute_ptr = lb_emit_conv(p, absolute_ptr, rel_ptr->RelativePointer.pointer_type);
+
+		lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer));
+
+		// NOTE(bill): nil check
+		lbValue nil_ptr = lb_const_nil(p->module, rel_ptr->RelativePointer.pointer_type);
+		lbValue final_ptr = lb_emit_select(p, cond, nil_ptr, absolute_ptr);
+		return final_ptr;
+	}
+
 	case lbAddr_BitField: {
 		lbValue v = lb_addr_load(p, addr);
 		return lb_address_from_load_or_generate_local(p, v);
@@ -6562,6 +6586,10 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
 		t = t->Opaque.elem;
 	}
 
+	if (is_type_relative_pointer(t)) {
+		s = lb_addr_get_ptr(p, lb_addr(s));
+	}
+
 	if (is_type_struct(t)) {
 		result_type = get_struct_field_type(t, index);
 	} else if (is_type_union(t)) {
@@ -6809,7 +6837,7 @@ lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel) {
 				break;
 
 			default:
-				GB_PANIC("un-gep-able type");
+				GB_PANIC("un-gep-able type %s", type_to_string(type));
 				break;
 			}
 		} else if (type->kind == Type_Slice) {
@@ -6820,6 +6848,8 @@ lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel) {
 			e = lb_emit_array_epi(p, e, index);
 		} else if (type->kind == Type_Map) {
 			e = lb_emit_struct_ep(p, e, index);
+		} else if (type->kind == Type_RelativePointer) {
+			e = lb_emit_struct_ep(p, e, index);
 		} else {
 			GB_PANIC("un-gep-able type %s", type_to_string(type));
 		}

+ 4 - 0
src/parser.cpp

@@ -3127,6 +3127,7 @@ u32 parse_field_prefixes(AstFile *f) {
 	i32 no_alias_count  = 0;
 	i32 c_vararg_count  = 0;
 	i32 auto_cast_count = 0;
+	i32 const_count     = 0;
 
 	for (;;) {
 		FieldPrefixKind kind = is_token_field_prefix(f);
@@ -3144,12 +3145,14 @@ u32 parse_field_prefixes(AstFile *f) {
 		case FieldPrefix_no_alias:  no_alias_count  += 1; advance_token(f); break;
 		case FieldPrefix_c_var_arg: c_vararg_count  += 1; advance_token(f); break;
 		case FieldPrefix_auto_cast: auto_cast_count += 1; advance_token(f); break;
+		case FieldPrefix_const:     const_count += 1; advance_token(f); break;
 		}
 	}
 	if (using_count     > 1) syntax_error(f->curr_token, "Multiple 'using' in this field list");
 	if (no_alias_count  > 1) syntax_error(f->curr_token, "Multiple '#no_alias' in this field list");
 	if (c_vararg_count  > 1) syntax_error(f->curr_token, "Multiple '#c_vararg' in this field list");
 	if (auto_cast_count > 1) syntax_error(f->curr_token, "Multiple 'auto_cast' in this field list");
+	if (const_count > 1)     syntax_error(f->curr_token, "Multiple '#const' in this field list");
 
 
 	u32 field_flags = 0;
@@ -3157,6 +3160,7 @@ u32 parse_field_prefixes(AstFile *f) {
 	if (no_alias_count  > 0) field_flags |= FieldFlag_no_alias;
 	if (c_vararg_count  > 0) field_flags |= FieldFlag_c_vararg;
 	if (auto_cast_count > 0) field_flags |= FieldFlag_auto_cast;
+	if (const_count > 0)     field_flags |= FieldFlag_const;
 	return field_flags;
 }
 

+ 2 - 1
src/parser.hpp

@@ -212,12 +212,13 @@ enum FieldFlag {
 	FieldFlag_no_alias  = 1<<2,
 	FieldFlag_c_vararg  = 1<<3,
 	FieldFlag_auto_cast = 1<<4,
+	FieldFlag_const     = 1<<5,
 
 	FieldFlag_Tags = 1<<10,
 
 	FieldFlag_Results   = 1<<16,
 
-	FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_c_vararg|FieldFlag_auto_cast,
+	FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_c_vararg|FieldFlag_auto_cast|FieldFlag_const,
 	FieldFlag_Struct    = FieldFlag_using|FieldFlag_Tags,
 };
 

+ 3 - 0
src/types.cpp

@@ -877,6 +877,9 @@ Type *alloc_type_named(String name, Type *base, Entity *type_name) {
 	Type *t = alloc_type(Type_Named);
 	t->Named.name = name;
 	t->Named.base = base;
+	if (base != t) {
+		t->Named.base = base_type(base);
+	}
 	t->Named.type_name = type_name;
 	return t;
 }