1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/*
General Rules for canonical name mangling
* No spaces between any values
* normal declarations - pkg::name
* builtin names - just their normal name e.g. `i32` or `string`
* nested (zero level) - pkg::parent1::parent2::name
* nested (more scopes) - pkg::parent1::parent2::name[4]
* [4] indicates the 4th scope within a procedure numbered in depth-first order
* file private - pkg::[file_name]::name
* Example: `pkg::[file.odin]::Type`
* polymorphic procedure/type - pkg::foo:TYPE
* naming convention for parameters
* type
* $typeid_based_name
* $$constant_parameter
* Example: `foo::to_thing:proc(u64)->([]u8)`
* nested decl in polymorphic procedure - pkg::foo:TYPE::name
* anonymous procedures - pkg::foo::$anon[file.odin:123]
* 123 is the file offset in bytes
*/
#define CANONICAL_TYPE_SEPARATOR ":"
#define CANONICAL_NAME_SEPARATOR "::"
// #define CANONICAL_NAME_SEPARATOR "·"
#define CANONICAL_BIT_FIELD_SEPARATOR "|"
#define CANONICAL_PARAM_SEPARATOR ","
#define CANONICAL_PARAM_TYPEID "$"
#define CANONICAL_PARAM_CONST "$$"
#define CANONICAL_PARAM_C_VARARG "#c_vararg"
#define CANONICAL_PARAM_VARARG ".."
#define CANONICAL_FIELD_SEPARATOR ","
#define CANONICAL_ANON_PREFIX "$anon"
#define CANONICAL_NONE_TYPE "<>"
#define CANONICAL_RANGE_OPERATOR "..="
struct TypeWriter;
gb_internal void write_type_to_canonical_string(TypeWriter *w, Type *type);
gb_internal void write_canonical_entity_name(TypeWriter *w, Entity *e);
gb_internal u64 type_hash_canonical_type(Type *type);
gb_internal String type_to_canonical_string(gbAllocator allocator, Type *type);
gb_internal gbString temp_canonical_string(Type *type);
gb_internal GB_COMPARE_PROC(type_info_pair_cmp);
struct TypeInfoPair {
Type *type;
u64 hash; // see: type_hash_canonical_type
};
struct TypeSet {
TypeInfoPair *keys;
usize count;
usize capacity;
};
static constexpr u64 TYPE_SET_TOMBSTONE = ~(u64)(0ull);
struct TypeSetIterator {
TypeSet *set;
usize index;
TypeSetIterator &operator++() noexcept {
for (;;) {
++index;
if (set->capacity == index) {
return *this;
}
TypeInfoPair key = set->keys[index];
if (key.hash != 0 && key.hash != TYPE_SET_TOMBSTONE) {
return *this;
}
}
}
bool operator==(TypeSetIterator const &other) const noexcept {
return this->set == other.set && this->index == other.index;
}
operator TypeInfoPair *() const {
return &set->keys[index];
}
};
gb_internal void type_set_init (TypeSet *s, isize capacity = 16);
gb_internal void type_set_destroy(TypeSet *s);
gb_internal Type *type_set_add (TypeSet *s, Type *ptr);
gb_internal Type *type_set_add (TypeSet *s, TypeInfoPair pair);
gb_internal bool type_set_update (TypeSet *s, Type *ptr); // returns true if it previously existed
gb_internal bool type_set_update (TypeSet *s, TypeInfoPair pair); // returns true if it previously existed
gb_internal bool type_set_update_with_mutex(TypeSet *s, TypeInfoPair pair, RWSpinLock *m);
gb_internal bool type_set_update_with_mutex(TypeSet *s, Type *ptr, RWSpinLock *m);
gb_internal bool type_set_exists (TypeSet *s, Type *ptr);
gb_internal void type_set_remove (TypeSet *s, Type *ptr);
gb_internal void type_set_clear (TypeSet *s);
gb_internal TypeInfoPair *type_set_retrieve(TypeSet *s, Type *ptr);
gb_internal TypeSetIterator begin(TypeSet &set) noexcept;
gb_internal TypeSetIterator end(TypeSet &set) noexcept;
template <typename V>
gb_internal gb_inline V *map_get(PtrMap<u64, V> *h, Type *key) {
return map_get(h, type_hash_canonical_type(key));
}
template <typename V>
gb_internal gb_inline void map_set(PtrMap<u64, V> *h, Type *key, V const &value) {
map_set(h, type_hash_canonical_type(key), value);
}
template <typename V>
gb_internal gb_inline V &map_must_get(PtrMap<u64, V> *h, Type *key) {
V *ptr = map_get(h, type_hash_canonical_type(key));
GB_ASSERT(ptr != nullptr);
return *ptr;
}
|