Browse Source

Custom thread local models

gingerBill 7 years ago
parent
commit
121f0185d6
5 changed files with 25 additions and 13 deletions
  1. 0 1
      core/sys/wgl.odin
  2. 14 7
      src/check_decl.cpp
  3. 1 1
      src/entity.cpp
  4. 2 2
      src/ir.cpp
  5. 8 2
      src/ir_print.cpp

+ 0 - 1
core/sys/wgl.odin

@@ -64,7 +64,6 @@ Get_Extensions_String_ARB_Type  :: #type proc "c" (Hdc) -> ^u8;
 	get_extensions_string_arb:  Get_Extensions_String_ARB_Type;
 
 
-
 foreign opengl32 {
 	@(link_name="wglCreateContext")
 	create_context :: proc(hdc: Hdc) -> Hglrc ---;

+ 14 - 7
src/check_decl.cpp

@@ -761,16 +761,23 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
 						error(elem, "Expected a string value for `%.*s`", LIT(name));
 					}
 				} else if (name == "thread_local") {
-					if (ev.kind == ExactValue_Invalid) {
-						if (!e->scope->is_file) {
-							error(elem, "Only a variable at file scope can be thread local");
-						} else if (init_expr_list.count > 0) {
-							error(elem, "A thread local variable declaration cannot have initialization values");
+					if (!e->scope->is_file) {
+						error(elem, "Only a variable at file scope can be thread local");
+					} else if (init_expr_list.count > 0) {
+						error(elem, "A thread local variable declaration cannot have initialization values");
+					} else if (ev.kind == ExactValue_Invalid) {
+						e->Variable.thread_local_model = str_lit("default");
+					} else if (ev.kind == ExactValue_String) {
+						String model = ev.value_string;
+						if (model == "localdynamic" ||
+						    model == "initialexec" ||
+						    model == "localexec") {
+							e->Variable.thread_local_model = model;
 						} else {
-							e->Variable.is_thread_local = true;
+							error(elem, "Invalid thread local model `%.*s`", LIT(model));
 						}
 					} else {
-						error(elem, "Expected no value for `%.*s`", LIT(name));
+						error(elem, "Expected either no value or a string for `%.*s`", LIT(name));
 					}
 				} else if (name == "link_prefix") {
 					if (ev.kind == ExactValue_String) {

+ 1 - 1
src/entity.cpp

@@ -84,7 +84,7 @@ struct Entity {
 			bool       default_is_undef;
 			bool       default_is_location;
 			bool       is_immutable;
-			bool       is_thread_local;
+			String     thread_local_model;
 			bool       is_foreign;
 			bool       is_export;
 			Entity *   foreign_library;

+ 2 - 2
src/ir.cpp

@@ -363,7 +363,7 @@ struct irValueGlobal {
 	bool          is_constant;
 	bool          is_export;
 	bool          is_private;
-	bool          is_thread_local;
+	String        thread_local_model;
 	bool          is_foreign;
 	bool          is_unnamed_addr;
 };
@@ -8191,7 +8191,7 @@ void ir_gen_tree(irGen *s) {
 
 			irValue *g = ir_value_global(a, e, nullptr);
 			g->Global.name = name;
-			g->Global.is_thread_local = e->Variable.is_thread_local;
+			g->Global.thread_local_model = e->Variable.thread_local_model;
 			g->Global.is_foreign = is_foreign;
 			g->Global.is_export  = is_export;
 

+ 8 - 2
src/ir_print.cpp

@@ -1934,8 +1934,14 @@ void print_llvm_ir(irGen *ir) {
 				ir_write_string(f, str_lit("dllexport "));
 			}
 		}
-		if (g->is_thread_local) {
-			ir_write_string(f, str_lit("thread_local "));
+		if (g->thread_local_model.len > 0) {
+			String model = g->thread_local_model;
+			if (model == "default") {
+				ir_write_string(f, str_lit("thread_local "));
+			} else {
+				ir_fprintf(f, "thread_local(%.*s) ", LIT(model));
+
+			}
 		}
 
 		if (g->is_private) {