Forráskód Böngészése

Add string_set.cpp; Code clean up

gingerBill 7 éve
szülő
commit
414486829a
9 módosított fájl, 341 hozzáadás és 73 törlés
  1. 71 7
      src/check_decl.cpp
  2. 1 1
      src/check_stmt.cpp
  3. 4 8
      src/check_type.cpp
  4. 1 1
      src/checker.cpp
  5. 10 5
      src/ir.cpp
  6. 9 8
      src/ir_print.cpp
  7. 36 28
      src/parser.cpp
  8. 184 0
      src/string_set.cpp
  9. 25 15
      src/types.cpp

+ 71 - 7
src/check_decl.cpp

@@ -459,8 +459,6 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
 
 	bool is_foreign         = e->Procedure.is_foreign;
 	bool is_export          = e->Procedure.is_export;
-	bool is_inline          = (pl->tags & ProcTag_inline)    != 0;
-	bool is_no_inline       = (pl->tags & ProcTag_no_inline) != 0;
 	bool is_require_results = (pl->tags & ProcTag_require_results) != 0;
 
 	String link_name = {};
@@ -513,6 +511,9 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
 				if (name == "link_name") {
 					if (ev.kind == ExactValue_String) {
 						link_name = ev.value_string;
+						if (!is_foreign_name_valid(link_name)) {
+							error(elem, "Invalid link name: %.*s", LIT(link_name));
+						}
 					} else {
 						error(elem, "Expected a string value for `%.*s`", LIT(name));
 					}
@@ -548,10 +549,6 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
 		}
 	}
 
-	if (is_inline && is_no_inline) {
-		error(pl->type, "You cannot apply both `inline` and `no_inline` to a procedure");
-	}
-
 	if (is_foreign && is_export) {
 		error(pl->type, "A foreign procedure cannot have an `export` tag");
 	}
@@ -673,9 +670,69 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
 	}
 	e->flags |= EntityFlag_Visited;
 
+
+	String link_name = {};
+
 	DeclInfo *decl = decl_info_of_entity(&c->info, e);
 	if (decl != nullptr && decl->attributes.count > 0) {
-		error(decl->attributes[0], "Attributes are not allowed on variable declarations, yet");
+		StringSet set = {};
+		string_set_init(&set, heap_allocator());
+		defer (string_set_destroy(&set));
+
+		for_array(i, decl->attributes) {
+			AstNode *attr = decl->attributes[i];
+			if (attr->kind != AstNode_Attribute) continue;
+			for_array(j, attr->Attribute.elems) {
+				AstNode *elem = attr->Attribute.elems[j];
+				String name = {};
+				AstNode *value = nullptr;
+
+				switch (elem->kind) {
+				case_ast_node(i, Ident, elem);
+					name = i->token.string;
+				case_end;
+				case_ast_node(fv, FieldValue, elem);
+					GB_ASSERT(fv->field->kind == AstNode_Ident);
+					name = fv->field->Ident.token.string;
+					value = fv->value;
+				case_end;
+				default:
+					error(elem, "Invalid attribute element");
+					continue;
+				}
+
+				ExactValue ev = {};
+				if (value != nullptr) {
+					Operand op = {};
+					check_expr(c, &op, value);
+					if (op.mode != Addressing_Constant) {
+						error(value, "An attribute element must be constant");
+					} else {
+						ev = op.value;
+					}
+				}
+
+				if (string_set_exists(&set, name)) {
+					error(elem, "Previous declaration of `%.*s`", LIT(name));
+					continue;
+				} else {
+					string_set_add(&set, name);
+				}
+
+				if (name == "link_name") {
+					if (ev.kind == ExactValue_String) {
+						link_name = ev.value_string;
+						if (!is_foreign_name_valid(link_name)) {
+							error(elem, "Invalid link name: %.*s", LIT(link_name));
+						}
+					} else {
+						error(elem, "Expected a string value for `%.*s`", LIT(name));
+					}
+				} else {
+					error(elem, "Unknown attribute element name `%.*s`", LIT(name));
+				}
+			}
+		}
 	}
 
 	String context_name = str_lit("variable declaration");
@@ -704,8 +761,15 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
 		}
 		init_entity_foreign_library(c, e);
 	}
+	if (link_name.len > 0) {
+		e->Variable.link_name = link_name;
+	}
+
 	if (e->Variable.is_foreign || e->Variable.is_export) {
 		String name = e->token.string;
+		if (link_name.len > 0) {
+			name = link_name;
+		}
 		auto *fp = &c->info.foreigns;
 		HashKey key = hash_string(name);
 		Entity **found = map_get(fp, key);

+ 1 - 1
src/check_stmt.cpp

@@ -1670,7 +1670,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 		CheckerContext prev_context = c->context;
 		if (ok) {
 			c->context.curr_foreign_library = foreign_library;
-			c->context.default_foreign_cc = ProcCC_C;
+			c->context.default_foreign_cc = ProcCC_CDecl;
 		}
 
 		check_foreign_block_decl_attributes(c, fb);

+ 4 - 8
src/check_type.cpp

@@ -1890,7 +1890,7 @@ bool check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node, Array
 
 	ProcCallingConvention cc = pt->calling_convention;
 	if (cc == ProcCC_ForeignBlockDefault) {
-		cc = ProcCC_C;
+		cc = ProcCC_CDecl;
 		if (c->context.default_foreign_cc > 0) {
 			cc = c->context.default_foreign_cc;
 		}
@@ -1911,14 +1911,10 @@ bool check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node, Array
 	if (param_count > 0) {
 		Entity *end = params->Tuple.variables[param_count-1];
 		if (end->flags&EntityFlag_CVarArg) {
-			if (cc == ProcCC_Odin) {
-				error(end->token, "Odin calling convention does not support #c_vararg");
-			} else if (cc == ProcCC_Contextless) {
-				error(end->token, "Odin's contextless calling convention does not support #c_vararg");
-			} else if (cc == ProcCC_Fast) {
-				error(end->token, "Fast calling convention does not support #c_vararg");
-			} else {
+			if (cc == ProcCC_StdCall || cc == ProcCC_CDecl) {
 				type->Proc.c_vararg = true;
+			} else {
+				error(end->token, "Calling convention does not support #c_vararg");
 			}
 		}
 	}

+ 1 - 1
src/checker.cpp

@@ -2126,7 +2126,7 @@ void check_collect_value_decl(Checker *c, AstNode *decl) {
 					GB_ASSERT(pl->type->kind == AstNode_ProcType);
 					auto cc = pl->type->ProcType.calling_convention;
 					if (cc == ProcCC_ForeignBlockDefault) {
-						cc = ProcCC_C;
+						cc = ProcCC_CDecl;
 						if (c->context.default_foreign_cc > 0) {
 							cc = c->context.default_foreign_cc;
 						}

+ 10 - 5
src/ir.cpp

@@ -117,6 +117,7 @@ struct irProcedure {
 	AstNode *             type_expr;
 	AstNode *             body;
 	u64                   tags;
+	ProcInlining          inlining;
 	bool                  is_foreign;
 	bool                  is_export;
 	bool                  is_entry_point;
@@ -3695,6 +3696,7 @@ irValue *ir_gen_anonymous_proc_lit(irModule *m, String prefix_name, AstNode *exp
 	                                    m, nullptr, type, pl->type, pl->body, name);
 
 	value->Proc.tags = pl->tags;
+	value->Proc.inlining = pl->inlining;
 	value->Proc.parent = proc;
 
 	array_add(&m->procs_to_generate, value);
@@ -5902,6 +5904,7 @@ void ir_build_poly_proc(irProcedure *proc, AstNodeProcLit *pd, Entity *e) {
 	                                    proc->module, e, e->type, pd->type, pd->body, name);
 
 	value->Proc.tags = pd->tags;
+	value->Proc.inlining = pd->inlining;
 	value->Proc.parent = proc;
 
 	ir_module_add_value(proc->module, e, value);
@@ -5987,6 +5990,7 @@ void ir_build_constant_value_decl(irProcedure *proc, AstNodeValueDecl *vd) {
 				                                    proc->module, e, e->type, pl->type, pl->body, name);
 
 				value->Proc.tags = pl->tags;
+				value->Proc.inlining = pl->inlining;
 
 				ir_module_add_value(proc->module, e, value);
 				ir_build_proc(value, proc);
@@ -8295,6 +8299,7 @@ void ir_gen_tree(irGen *s) {
 
 			irValue *p = ir_value_procedure(a, m, e, e->type, type_expr, body, name);
 			p->Proc.tags = pl->tags;
+			p->Proc.inlining = pl->inlining;
 
 			ir_module_add_value(m, e, p);
 			HashKey hash_name = hash_string(name);
@@ -8363,7 +8368,7 @@ void ir_gen_tree(irGen *s) {
 
 		Type *proc_type = make_type_proc(a, proc_scope,
 		                                 proc_params, 3,
-		                                 proc_results, 1, false, ProcCC_Std);
+		                                 proc_results, 1, false, ProcCC_StdCall);
 
 		// TODO(bill): make this more robust
 		proc_type->Proc.abi_compat_params = gb_alloc_array(a, Type *, proc_params->Tuple.variables.count);
@@ -8380,7 +8385,7 @@ void ir_gen_tree(irGen *s) {
 		map_set(&m->members, hash_string(name), p);
 
 		irProcedure *proc = &p->Proc;
-		proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
+		proc->inlining = ProcInlining_no_inline; // TODO(bill): is no_inline a good idea?
 		proc->is_entry_point = true;
 		e->Procedure.link_name = name;
 
@@ -8434,7 +8439,7 @@ void ir_gen_tree(irGen *s) {
 
 		Type *proc_type = make_type_proc(a, proc_scope,
 		                                 proc_params, 2,
-		                                 proc_results, 1, false, ProcCC_C);
+		                                 proc_results, 1, false, ProcCC_CDecl);
 
 		// TODO(bill): make this more robust
 		proc_type->Proc.abi_compat_params = gb_alloc_array(a, Type *, proc_params->Tuple.variables.count);
@@ -8451,7 +8456,7 @@ void ir_gen_tree(irGen *s) {
 		map_set(&m->members, hash_string(name), p);
 
 		irProcedure *proc = &p->Proc;
-		proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
+		proc->inlining = ProcInlining_no_inline; // TODO(bill): is no_inline a good idea?
 		proc->is_entry_point = true;
 		e->Procedure.link_name = name;
 
@@ -8543,7 +8548,7 @@ void ir_gen_tree(irGen *s) {
 
 
 		irProcedure *proc = &p->Proc;
-		proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
+		proc->inlining = ProcInlining_no_inline; // TODO(bill): is no_inline a good idea?
 
 		ir_begin_procedure_body(proc);
 

+ 9 - 8
src/ir_print.cpp

@@ -882,9 +882,9 @@ void ir_print_calling_convention(irFileBuffer *f, irModule *m, ProcCallingConven
 	switch (cc) {
 	case ProcCC_Odin:        ir_write_string(f, "");       break;
 	case ProcCC_Contextless: ir_write_string(f, "");       break;
-	case ProcCC_C:           ir_write_string(f, "ccc ");   break;
-	case ProcCC_Std:         ir_write_string(f, "cc 64 "); break;
-	case ProcCC_Fast:        ir_write_string(f, "cc 65 "); break;
+	case ProcCC_CDecl:       ir_write_string(f, "ccc ");   break;
+	case ProcCC_StdCall:     ir_write_string(f, "cc 64 "); break;
+	case ProcCC_FastCall:    ir_write_string(f, "cc 65 "); break;
 	default: GB_PANIC("unknown calling convention: %d", cc);
 	}
 }
@@ -1751,14 +1751,15 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) {
 
 	ir_write_string(f, ") ");
 
-	if (proc->tags & ProcTag_inline) {
-		ir_write_string(f, "alwaysinline ");
-	}
-	if (proc->tags & ProcTag_no_inline) {
+	switch (proc->inlining) {
+	case ProcInlining_no_inline:
 		ir_write_string(f, "noinline ");
+		break;
+	case ProcInlining_inline:
+		ir_write_string(f, "alwaysinline ");
+		break;
 	}
 
-
 	if (proc->entity != nullptr) {
 		if (proc->body != nullptr) {
 			irDebugInfo **di_ = map_get(&proc->module->debug_info, hash_pointer(proc->entity));

+ 36 - 28
src/parser.cpp

@@ -88,28 +88,29 @@ struct Parser {
 	gbMutex             file_decl_mutex;
 };
 
+enum ProcInlining {
+	ProcInlining_none = 0,
+	ProcInlining_inline = 1,
+	ProcInlining_no_inline = 2,
+};
+
 enum ProcTag {
 	ProcTag_bounds_check    = 1<<0,
 	ProcTag_no_bounds_check = 1<<1,
-
-
 	ProcTag_require_results = 1<<4,
-
-	ProcTag_link_name       = 1<<11,
-	ProcTag_inline          = 1<<12,
-	ProcTag_no_inline       = 1<<13,
-
-	// ProcTag_dll_import      = 1<<15,
-	// ProcTag_dll_export      = 1<<16,
 };
 
 enum ProcCallingConvention {
-	ProcCC_Invalid     = 0,
-	ProcCC_Odin        = 1,
-	ProcCC_Contextless = 2,
-	ProcCC_C           = 3,
-	ProcCC_Std         = 4,
-	ProcCC_Fast        = 5,
+	ProcCC_Invalid = 0,
+	ProcCC_Odin,
+	ProcCC_Contextless,
+	ProcCC_CDecl,
+	ProcCC_StdCall,
+	ProcCC_FastCall,
+
+	// TODO(bill): Add extra calling conventions
+	// ProcCC_VectorCall,
+	// ProcCC_ClrCall,
 
 	ProcCC_ForeignBlockDefault = -1,
 };
@@ -172,6 +173,7 @@ Array<AstNode *> make_ast_node_array(AstFile *f, isize init_capacity = 8) {
 		AstNode *type; \
 		AstNode *body; \
 		u64      tags; \
+		ProcInlining inlining; \
 	}) \
 	AST_NODE_KIND(CompoundLit, "compound literal", struct { \
 		AstNode *type; \
@@ -2275,11 +2277,20 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
 			syntax_error(expr, "%.*s must be followed by a procedure literal, got %.*s", LIT(token.string), LIT(ast_node_strings[expr->kind]));
 			return ast_bad_expr(f, token, f->curr_token);
 		}
+		ProcInlining pi = ProcInlining_none;
 		if (token.kind == Token_inline) {
-			expr->ProcLit.tags |= ProcTag_inline;
+			pi = ProcInlining_inline;
 		} else if (token.kind == Token_no_inline) {
-			expr->ProcLit.tags |= ProcTag_no_inline;
+			pi = ProcInlining_no_inline;
+		}
+		if (pi != ProcInlining_none) {
+			if (expr->ProcLit.inlining != ProcInlining_none &&
+			    expr->ProcLit.inlining != pi) {
+				syntax_error(expr, "You cannot apply both `inline` and `no_inline` to a procedure literal");
+			}
+			expr->ProcLit.inlining = pi;
 		}
+
 		return expr;
 	} break;
 
@@ -3255,17 +3266,14 @@ AstNode *parse_results(AstFile *f) {
 
 
 ProcCallingConvention string_to_calling_convention(String s) {
-	if (s == "odin") {
-		return ProcCC_Odin;
-	} else if (s == "contextless") {
-		return ProcCC_Contextless;
-	} else if (s == "cdecl" || s == "c") {
-		return ProcCC_C;
-	} else if (s == "stdcall" || s == "std") {
-		return ProcCC_Std;
-	} else if (s == "fastcall" || s == "fast") {
-		return ProcCC_Fast;
-	}
+	if (s == "odin")        return ProcCC_Odin;
+	if (s == "contextless") return ProcCC_Contextless;
+	if (s == "cdecl")       return ProcCC_CDecl;
+	if (s == "c")           return ProcCC_CDecl;
+	if (s == "stdcall")     return ProcCC_StdCall;
+	if (s == "std")         return ProcCC_StdCall;
+	if (s == "fastcall")    return ProcCC_FastCall;
+	if (s == "fast")        return ProcCC_FastCall;
 	return ProcCC_Invalid;
 }
 

+ 184 - 0
src/string_set.cpp

@@ -0,0 +1,184 @@
+struct StringSetFindResult {
+	isize hash_index;
+	isize entry_prev;
+	isize entry_index;
+};
+
+struct StringSetEntry {
+	HashKey  key;
+	isize    next;
+	String   value;
+};
+
+struct StringSet {
+	Array<isize>          hashes;
+	Array<StringSetEntry> entries;
+};
+
+
+void string_set_init   (StringSet *s, gbAllocator a, isize capacity = 16);
+void string_set_destroy(StringSet *s);
+void string_set_add    (StringSet *s, String str);
+bool string_set_exists (StringSet *s, String str);
+void string_set_remove (StringSet *s, String str);
+void string_set_clear  (StringSet *s);
+void string_set_grow   (StringSet *s);
+void string_set_rehash (StringSet *s, isize new_count);
+
+
+gb_inline void string_set_init(StringSet *s, gbAllocator a, isize capacity) {
+	array_init(&s->hashes,  a);
+	array_init(&s->entries, a);
+}
+
+gb_inline void string_set_destroy(StringSet *s) {
+	array_free(&s->entries);
+	array_free(&s->hashes);
+}
+
+gb_internal isize string_set__add_entry(StringSet *s, HashKey key) {
+	StringSetEntry e = {};
+	e.key = key;
+	e.next = -1;
+	array_add(&s->entries, e);
+	return s->entries.count-1;
+}
+
+gb_internal StringSetFindResult string_set__find(StringSet *s, HashKey key) {
+	StringSetFindResult fr = {-1, -1, -1};
+	if (s->hashes.count > 0) {
+		// fr.hash_index  = u128_to_i64(key.key % u128_from_i64(s->hashes.count));
+		fr.hash_index = key.key % s->hashes.count;
+		fr.entry_index = s->hashes[fr.hash_index];
+		while (fr.entry_index >= 0) {
+			if (hash_key_equal(s->entries[fr.entry_index].key, key)) {
+				return fr;
+			}
+			fr.entry_prev = fr.entry_index;
+			fr.entry_index = s->entries[fr.entry_index].next;
+		}
+	}
+	return fr;
+}
+
+gb_internal StringSetFindResult string_set__find_from_entry(StringSet *s, StringSetEntry *e) {
+	StringSetFindResult fr = {-1, -1, -1};
+	if (s->hashes.count > 0) {
+		fr.hash_index  = e->key.key % s->hashes.count;
+		fr.entry_index = s->hashes[fr.hash_index];
+		while (fr.entry_index >= 0) {
+			if (&s->entries[fr.entry_index] == e) {
+				return fr;
+			}
+			fr.entry_prev = fr.entry_index;
+			fr.entry_index = s->entries[fr.entry_index].next;
+		}
+	}
+	return fr;
+}
+
+gb_internal b32 string_set__full(StringSet *s) {
+	return 0.75f * s->hashes.count <= s->entries.count;
+}
+
+gb_inline void string_set_grow(StringSet *s) {
+	isize new_count = ARRAY_GROW_FORMULA(s->entries.count);
+	string_set_rehash(s, new_count);
+}
+
+void string_set_rehash(StringSet *s, isize new_count) {
+	isize i, j;
+	StringSet ns = {};
+	string_set_init(&ns, s->hashes.allocator);
+	array_resize(&ns.hashes, new_count);
+	array_reserve(&ns.entries, s->entries.count);
+	for (i = 0; i < new_count; i++) {
+		ns.hashes[i] = -1;
+	}
+	for (i = 0; i < s->entries.count; i++) {
+		StringSetEntry *e = &s->entries[i];
+		StringSetFindResult fr;
+		if (ns.hashes.count == 0) {
+			string_set_grow(&ns);
+		}
+		fr = string_set__find(&ns, e->key);
+		j = string_set__add_entry(&ns, e->key);
+		if (fr.entry_prev < 0) {
+			ns.hashes[fr.hash_index] = j;
+		} else {
+			ns.entries[fr.entry_prev].next = j;
+		}
+		ns.entries[j].next = fr.entry_index;
+		ns.entries[j].value = e->value;
+		if (string_set__full(&ns)) {
+			string_set_grow(&ns);
+		}
+	}
+	string_set_destroy(s);
+	*s = ns;
+}
+
+gb_inline bool string_set_exists(StringSet *s, String str) {
+	HashKey key = hash_string(str);
+	isize index = string_set__find(s, key).entry_index;
+	return index >= 0;
+}
+
+void string_set_add(StringSet *s, String str) {
+	isize index;
+	StringSetFindResult fr;
+	HashKey key = hash_string(str);
+	if (s->hashes.count == 0) {
+		string_set_grow(s);
+	}
+	fr = string_set__find(s, key);
+	if (fr.entry_index >= 0) {
+		index = fr.entry_index;
+	} else {
+		index = string_set__add_entry(s, key);
+		if (fr.entry_prev >= 0) {
+			s->entries[fr.entry_prev].next = index;
+		} else {
+			s->hashes[fr.hash_index] = index;
+		}
+	}
+	s->entries[index].value = str;
+
+	if (string_set__full(s)) {
+		string_set_grow(s);
+	}
+}
+
+
+void string_set__erase(StringSet *s, StringSetFindResult fr) {
+	StringSetFindResult last;
+	if (fr.entry_prev < 0) {
+		s->hashes[fr.hash_index] = s->entries[fr.entry_index].next;
+	} else {
+		s->entries[fr.entry_prev].next = s->entries[fr.entry_index].next;
+	}
+	if (fr.entry_index == s->entries.count-1) {
+		array_pop(&s->entries);
+		return;
+	}
+	s->entries[fr.entry_index] = s->entries[s->entries.count-1];
+	last = string_set__find(s, s->entries[fr.entry_index].key);
+	if (last.entry_prev >= 0) {
+		s->entries[last.entry_prev].next = fr.entry_index;
+	} else {
+		s->hashes[last.hash_index] = fr.entry_index;
+	}
+}
+
+void string_set_remove(StringSet *s, String str) {
+	HashKey key = hash_string(str);
+	StringSetFindResult fr = string_set__find(s, key);
+	if (fr.entry_index >= 0) {
+		string_set__erase(s, fr);
+	}
+}
+
+gb_inline void string_set_clear(StringSet *s) {
+	array_clear(&s->hashes);
+	array_clear(&s->entries);
+}

+ 25 - 15
src/types.cpp

@@ -2436,7 +2436,31 @@ gbString write_type_to_string(gbString str, Type *type) {
 		break;
 
 	case Type_Proc:
-		str = gb_string_appendc(str, "proc(");
+		str = gb_string_appendc(str, "proc");
+
+		switch (type->Proc.calling_convention) {
+		case ProcCC_Odin:
+			break;
+		case ProcCC_Contextless:
+			str = gb_string_appendc(str, " \"contextless\" ");
+			break;
+		case ProcCC_CDecl:
+			str = gb_string_appendc(str, " \"cdecl\" ");
+			break;
+		case ProcCC_StdCall:
+			str = gb_string_appendc(str, " \"stdcall\" ");
+			break;
+		case ProcCC_FastCall:
+			str = gb_string_appendc(str, " \"fastcall\" ");
+			break;
+		// case ProcCC_VectorCall:
+		// 	str = gb_string_appendc(str, " \"vectorcall\" ");
+		// 	break;
+		// case ProcCC_ClrCall:
+		// 	str = gb_string_appendc(str, " \"clrcall\" ");
+		// 	break;
+		}
+		str = gb_string_appendc(str, "(");
 		if (type->Proc.params) {
 			str = write_type_to_string(str, type->Proc.params);
 		}
@@ -2445,20 +2469,6 @@ gbString write_type_to_string(gbString str, Type *type) {
 			str = gb_string_appendc(str, " -> ");
 			str = write_type_to_string(str, type->Proc.results);
 		}
-		switch (type->Proc.calling_convention) {
-		case ProcCC_Odin:
-			// str = gb_string_appendc(str, " #cc_odin");
-			break;
-		case ProcCC_C:
-			str = gb_string_appendc(str, " #cc_c");
-			break;
-		case ProcCC_Std:
-			str = gb_string_appendc(str, " #cc_std");
-			break;
-		case ProcCC_Fast:
-			str = gb_string_appendc(str, " #cc_fast");
-			break;
-		}
 		break;
 
 	case Type_BitField: