ソースを参照

Fix overloading bug due to `#import .`; Add sys/wgl.odin

Ginger Bill 8 年 前
コミット
758dd9ba16
7 ファイル変更114 行追加43 行削除
  1. 1 1
      code/demo.odin
  2. 2 1
      core/opengl.odin
  3. 72 0
      core/sys/wgl.odin
  4. 4 16
      core/sys/windows.odin
  5. 21 18
      src/check_expr.c
  6. 14 0
      src/checker.c
  7. 0 7
      src/ir.c

+ 1 - 1
code/demo.odin

@@ -13,7 +13,7 @@ main :: proc() {
 	Version 0.1.1
 
 	Added:
-	 * Dynamic Arrays [dynamic]Type`
+	 * Dynamic Arrays `[dynamic]Type`
 	 * Dynamic Maps   `map[Key]Value`
 	 * Dynamic array and map literals
 	 * Custom struct alignemnt `struct #align 8 { bar: i8 }`

+ 2 - 1
core/opengl.odin

@@ -1,5 +1,6 @@
 #foreign_system_library lib "opengl32.lib" when ODIN_OS == "windows";
 #import win32 "sys/windows.odin" when ODIN_OS == "windows";
+#import "sys/wgl.odin" when ODIN_OS == "windows";
 #load "opengl_constants.odin";
 
 Clear         :: proc(mask: u32)                                #foreign lib "glClear";
@@ -35,7 +36,7 @@ _libgl := win32.LoadLibraryA(string_data("opengl32.dll\x00"));
 
 GetProcAddress :: proc(name: string) -> proc() #cc_c {
 	assert(name[name.count-1] == 0);
-	res := win32.wglGetProcAddress(name.data);
+	res := wgl.GetProcAddress(name.data);
 	if res == nil {
 		res = win32.GetProcAddress(_libgl, name.data);
 	}

+ 72 - 0
core/sys/wgl.odin

@@ -0,0 +1,72 @@
+#foreign_system_library "opengl32.lib" when ODIN_OS == "windows";
+#import . "windows.odin";
+
+CONTEXT_MAJOR_VERSION_ARB          :: 0x2091;
+CONTEXT_MINOR_VERSION_ARB          :: 0x2092;
+CONTEXT_FLAGS_ARB                  :: 0x2094;
+CONTEXT_PROFILE_MASK_ARB           :: 0x9126;
+CONTEXT_FORWARD_COMPATIBLE_BIT_ARB :: 0x0002;
+CONTEXT_CORE_PROFILE_BIT_ARB       :: 0x00000001;
+
+HGLRC :: HANDLE;
+COLORREF :: u32;
+
+LAYERPLANEDESCRIPTOR :: struct #ordered {
+	size:             u16,
+	version:          u16,
+	flags:            u32,
+	pixel_type:       byte,
+	color_bits:       byte,
+	red_bits:         byte,
+	red_shift:        byte,
+	green_bits:       byte,
+	green_shift:      byte,
+	blue_bits:        byte,
+	blue_shift:       byte,
+	alpha_bits:       byte,
+	alpha_shift:      byte,
+	accum_bits:       byte,
+	accum_red_bits:   byte,
+	accum_green_bits: byte,
+	accum_blue_bits:  byte,
+	accum_alpha_bits: byte,
+	depth_bits:       byte,
+	stencil_bits:     byte,
+	aux_buffers:      byte,
+	layer_type:       byte,
+	reserved:         byte,
+	transparent:      COLORREF,
+}
+
+POINTFLOAT :: struct #ordered {
+	x, y: f32,
+}
+
+GLYPHMETRICSFLOAT :: struct #ordered {
+	black_box_x:  f32,
+	black_box_y:  f32,
+	glyph_origin: POINTFLOAT,
+	cell_inc_x:   f32,
+	cell_inc_y:   f32,
+}
+
+CreateContextAttribsARBType :: #type proc(hdc: HDC, hshareContext: rawptr, attribList: ^i32) -> HGLRC;
+ChoosePixelFormatARBType    :: #type proc(hdc: HDC, attrib_i_list: ^i32, attrib_f_list: ^f32, max_formats: u32, formats: ^i32, num_formats : ^u32) -> BOOL #cc_c;
+
+
+CreateContext           :: proc(hdc: HDC) -> HGLRC                                                                                               #foreign opengl32 "wglCreateContext";
+MakeCurrent             :: proc(hdc: HDC, hglrc: HGLRC) -> BOOL                                                                                  #foreign opengl32 "wglMakeCurrent";
+GetProcAddress          :: proc(c_str: ^u8) -> PROC                                                                                              #foreign opengl32 "wglGetProcAddress";
+DeleteContext           :: proc(hglrc: HGLRC) -> BOOL                                                                                            #foreign opengl32 "wglDeleteContext";
+CopyContext             :: proc(src, dst: HGLRC, mask: u32) -> BOOL                                                                              #foreign opengl32 "wglCopyContext";
+CreateLayerContext      :: proc(hdc: HDC, layer_plane: i32) -> HGLRC                                                                             #foreign opengl32 "wglCreateLayerContext";
+DescribeLayerPlane      :: proc(hdc: HDC, pixel_format, layer_plane: i32, bytes: u32, pd: ^LAYERPLANEDESCRIPTOR) -> BOOL                         #foreign opengl32 "wglDescribeLayerPlane";
+GetCurrentContext       :: proc() -> HGLRC                                                                                                       #foreign opengl32 "wglGetCurrentContext";
+GetCurrentDC            :: proc() -> HDC                                                                                                         #foreign opengl32 "wglGetCurrentDC";
+GetLayerPaletteEntries  :: proc(hdc: HDC, layer_plane, start, entries: i32, cr: ^COLORREF) -> i32                                                #foreign opengl32 "wglGetLayerPaletteEntries";
+RealizeLayerPalette     :: proc(hdc: HDC, layer_plane: i32, realize: BOOL) -> BOOL                                                               #foreign opengl32 "wglRealizeLayerPalette";
+SetLayerPaletteEntries  :: proc(hdc: HDC, layer_plane, start, entries: i32, cr: ^COLORREF) -> i32                                                #foreign opengl32 "wglSetLayerPaletteEntries";
+ShareLists              :: proc(hglrc1, hglrc2: HGLRC) -> BOOL                                                                                   #foreign opengl32 "wglShareLists";
+SwapLayerBuffers        :: proc(hdc: HDC, planes: u32) -> BOOL                                                                                   #foreign opengl32 "wglSwapLayerBuffers";
+UseFontBitmaps          :: proc(hdc: HDC, first, count, list_base: u32) -> BOOL                                                                  #foreign opengl32 "wglUseFontBitmaps";
+UseFontOutlines         :: proc(hdc: HDC, first, count, list_base: u32, deviation, extrusion: f32, format: i32, gmf: ^GLYPHMETRICSFLOAT) -> BOOL #foreign opengl32 "wglUseFontOutlines";

+ 4 - 16
core/sys/windows.odin

@@ -2,7 +2,6 @@
 #foreign_system_library "user32.lib"   when ODIN_OS == "windows";
 #foreign_system_library "gdi32.lib"    when ODIN_OS == "windows";
 #foreign_system_library "winmm.lib"    when ODIN_OS == "windows";
-#foreign_system_library "opengl32.lib" when ODIN_OS == "windows";
 
 HANDLE    :: rawptr;
 HWND      :: HANDLE;
@@ -168,6 +167,9 @@ DefWindowProcA :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) ->
 AdjustWindowRect :: proc(rect: ^RECT, style: u32, menu: BOOL) -> BOOL #foreign user32;
 GetActiveWindow  :: proc() -> HWND #foreign user32;
 
+DestroyWindow       :: proc(wnd: HWND) -> BOOL #foreign user32;
+DescribePixelFormat :: proc(dc: HDC, pixel_format: i32, bytes : u32, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign user32;
+
 
 GetQueryPerformanceFrequency :: proc() -> i64 {
 	r: i64;
@@ -360,10 +362,6 @@ PFD_DEPTH_DONTCARE        :: 0x20000000;
 PFD_DOUBLEBUFFER_DONTCARE :: 0x40000000;
 PFD_STEREO_DONTCARE       :: 0x80000000;
 
-HGLRC :: HANDLE;
-PROC  :: #type proc() #cc_c;
-wglCreateContextAttribsARBType :: #type proc(hdc: HDC, hshareContext: rawptr, attribList: ^i32) -> HGLRC;
-
 
 PIXELFORMATDESCRIPTOR :: struct #ordered {
 	size,
@@ -402,18 +400,8 @@ ChoosePixelFormat :: proc(hdc: HDC, pfd: ^PIXELFORMATDESCRIPTOR) -> i32 #foreign
 SwapBuffers       :: proc(hdc: HDC) -> BOOL #foreign gdi32;
 ReleaseDC         :: proc(wnd: HWND, hdc: HDC) -> i32 #foreign user32;
 
-WGL_CONTEXT_MAJOR_VERSION_ARB             :: 0x2091;
-WGL_CONTEXT_MINOR_VERSION_ARB             :: 0x2092;
-WGL_CONTEXT_PROFILE_MASK_ARB              :: 0x9126;
-WGL_CONTEXT_CORE_PROFILE_BIT_ARB          :: 0x0001;
-WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x0002;
-
-wglCreateContext  :: proc(hdc: HDC) -> HGLRC              #foreign opengl32;
-wglMakeCurrent    :: proc(hdc: HDC, hglrc: HGLRC) -> BOOL #foreign opengl32;
-wglGetProcAddress :: proc(c_str: ^u8) -> PROC             #foreign opengl32;
-wglDeleteContext  :: proc(hglrc: HGLRC) -> BOOL           #foreign opengl32;
-wglChoosePixelFormatARB :: proc(hdc: HDC, attribi_list: ^i32, attribf_list: ^f32, max_formats: u32, formats: ^i32, num_formats: u32) -> BOOL #foreign opengl32;
 
+PROC  :: #type proc() #cc_c;
 
 
 GetKeyState      :: proc(v_key: i32) -> i16 #foreign user32;

+ 21 - 18
src/check_expr.c

@@ -2564,6 +2564,17 @@ bool check_index_value(Checker *c, AstNode *index_value, i64 max_count, i64 *val
 	return true;
 }
 
+isize procedure_overload_count(Scope *s, String name) {
+	isize overload_count = 0;
+	Entity *e = scope_lookup_entity(s, name);
+	if (e->kind == Entity_Procedure) {
+		HashKey key = hash_string(e->token.string);
+		// NOTE(bill): Overloads are only allowed with the same scope
+		overload_count = map_entity_multi_count(&s->elements, key);
+	}
+	return overload_count;
+}
+
 Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_hint) {
 	ast_node(se, SelectorExpr, node);
 
@@ -2596,15 +2607,17 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
 			// It pretty much needs to be in this order and this way
 			// If you can clean this up, please do but be really careful
 
+			Scope *import_scope = e->ImportName.scope;
+
 			String sel_name = selector->Ident.string;
 
 			check_op_expr = false;
-			entity = scope_lookup_entity(e->ImportName.scope, sel_name);
+			entity = scope_lookup_entity(import_scope, sel_name);
 			bool is_declared = entity != NULL;
 			if (is_declared) {
 				if (entity->kind == Entity_Builtin) {
 					is_declared = false;
-				} else if (entity->scope->is_global && !e->ImportName.scope->is_global) {
+				} else if (entity->scope->is_global && !import_scope->is_global) {
 					is_declared = false;
 				}
 			}
@@ -2615,18 +2628,8 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
 			check_entity_decl(c, entity, NULL, NULL);
 			GB_ASSERT(entity->type != NULL);
 
-			bool is_overloaded = false;
-			isize overload_count = 0;
-			HashKey key = {0};
-			if (entity->kind == Entity_Procedure) {
-				key = hash_string(entity->token.string);
-				// NOTE(bill): Overloads are only allowed with the same scope
-				Scope *s = entity->scope;
-				overload_count = map_entity_multi_count(&s->elements, key);
-				if (overload_count > 1) {
-					is_overloaded = true;
-				}
-			}
+			isize overload_count = procedure_overload_count(import_scope, entity->token.string);
+			bool is_overloaded = overload_count > 1;
 
 			bool implicit_is_found = map_bool_get(&e->ImportName.scope->implicit, hash_pointer(entity)) != NULL;
 			bool is_not_exported = !is_entity_exported(entity);
@@ -2645,12 +2648,13 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
 			}
 
 			if (is_overloaded) {
-				Scope *s = entity->scope;
+				HashKey key = hash_string(entity->token.string);
+				Scope *s = import_scope;
 				bool skip = false;
 
 				Entity **procs = gb_alloc_array(heap_allocator(), Entity *, overload_count);
 				map_entity_multi_get_all(&s->elements, key, procs);
-				for (isize i = 0; i < overload_count; /**/) {
+				for (isize i = 0; i < overload_count; i++) {
 					Type *t = base_type(procs[i]->type);
 					if (t == t_invalid) {
 						continue;
@@ -2660,6 +2664,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
 					if (map_bool_get(&e->ImportName.scope->implicit, hash_pointer(procs[i]))) {
 						gb_swap(Entity *, procs[i], procs[overload_count-1]);
 						overload_count--;
+						i--; // NOTE(bill): Counteract the post event
 						continue;
 					}
 
@@ -2673,8 +2678,6 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
 							break;
 						}
 					}
-
-					i++;
 				}
 
 				if (overload_count > 0 && !skip) {

+ 14 - 0
src/checker.c

@@ -1715,6 +1715,12 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
 					continue;
 				}
 				if (id->is_import) {
+					// String gpa = str_lit("GetProcAddress");
+					// if (str_eq(e->token.string, gpa)) {
+					// 	Entity *f = scope_lookup_entity(parent_scope, gpa);
+					// 	gb_printf_err("%.*s %.*s %td\n", LIT(gpa), LIT(f->token.pos.file), entity_procedure_overload_count(f));
+					// }
+
 					if (is_entity_exported(e)) {
 						// TODO(bill): Should these entities be imported but cause an error when used?
 						bool ok = add_entity(c, parent_scope, NULL, e);
@@ -1722,6 +1728,12 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
 							map_bool_set(&parent_scope->implicit, hash_pointer(e), true);
 						}
 					}
+
+					// if (str_eq(e->token.string, gpa)) {
+					// 	Entity *f = scope_lookup_entity(parent_scope, gpa);
+					// 	gb_printf_err("%.*s %.*s %td\n", LIT(gpa), LIT(f->token.pos.file), entity_procedure_overload_count(f));
+					// }
+
 				} else {
 					add_entity(c, parent_scope, NULL, e);
 				}
@@ -1736,6 +1748,8 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
 				Entity *e = make_entity_import_name(c->allocator, parent_scope, id->import_name, t_invalid,
 				                                    id->fullpath, id->import_name.string,
 				                                    scope);
+
+
 				add_entity(c, parent_scope, NULL, e);
 			}
 		}

+ 0 - 7
src/ir.c

@@ -1102,13 +1102,6 @@ void ir_add_block_to_proc(irProcedure *proc, irBlock *b) {
 	b->index = proc->block_count++;
 }
 
-
-// irBlock *ir_add_block(irProcedure *proc, AstNode *node, char *label) {
-// 	irBlock *block = ir_new_block(proc, node, label);
-// 	ir_add_block_to_proc(proc, block);
-// 	return block;
-// }
-
 void ir_start_block(irProcedure *proc, irBlock *block) {
 	proc->curr_block = block;
 	if (block != NULL) {