Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 10 additions & 16 deletions analyser/module_analyser_struct.c2
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
module module_analyser;

import ast local;
import name_vector local;
import name_map local;
import size_analyser;
import value_type local;

Expand All @@ -25,15 +25,11 @@ fn void Analyser.analyseStructType(Analyser* ma, StructTypeDecl* d) {
ma.checkStack[ma.checkIndex-1].usedPublic = false;
ma.usedPublic = false;
}
u32 num_members = d.getNumMembers();
NameMap names.init(d.getNumMembers());

NameVector names.init(num_members);
NameVector locs.init(num_members);

ma.analyseStructNames(d, &names, &locs);
ma.analyseStructNames(d, &names);

names.free();
locs.free();

ma.analyseStructMembers(d);

Expand Down Expand Up @@ -176,7 +172,7 @@ fn void Analyser.analyseStructMember(Analyser* ma, VarDecl* v) {
// TODO check initValue
}

fn void Analyser.analyseStructNames(Analyser* ma, StructTypeDecl* d, NameVector* names, NameVector* locs) {
fn void Analyser.analyseStructNames(Analyser* ma, StructTypeDecl* d, NameMap* names) {
// note: already checked that struct doesn't have 0 members
u32 count = d.getNumMembers();
Decl** members = d.getMembers();
Expand All @@ -192,25 +188,23 @@ fn void Analyser.analyseStructNames(Analyser* ma, StructTypeDecl* d, NameVector*
if (name_idx == 0) {
// can be anonymous sub-struct/union or anonymous bit-field
if (member.isStructType()) {
ma.analyseStructNames(sub, names, locs);
ma.analyseStructNames(sub, names);
}
} else {
u32 old_index;
if (names.find(name_idx, &old_index)) {
ma.error(member.getLoc(), "duplicate struct/union member '%s'", member.getName());
ma.note(locs.get(old_index), "previous declaration is here");
ma.note(names.getLoc(old_index), "previous declaration is here");
return;
}
names.add(name_idx);
locs.add(member.getLoc());
names.add(name_idx, member.getLoc());

if (member.isStructType()) {
NameVector sub_names.init(sub.getNumMembers());
NameVector sub_locs.init(sub.getNumMembers());
ma.analyseStructNames(sub, &sub_names, &sub_locs);
NameMap sub_names.init(sub.getNumMembers());
ma.analyseStructNames(sub, &sub_names);
sub_names.free();
sub_locs.free();
}
}
}
}

98 changes: 98 additions & 0 deletions analyser/name_map.c2
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* Copyright 2022-2026 Bas van den Berg
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

module name_map;

import src_loc local;

import stdlib;
import string;

public const u32 Stash_len = 16;

public type NameMap struct {
u32 count;
u32 capacity;
u32* name_data;
SrcLoc* loc_data;
u32[Stash_len] name_stash;
SrcLoc[Stash_len] loc_stash;
}

public fn void NameMap.init(NameMap* v, u32 capacity) {
v.name_data = v.name_stash;
v.loc_data = v.loc_stash;
v.count = 0;
v.capacity = capacity;
if (capacity > Stash_len) {
v.name_data = stdlib.malloc(capacity * sizeof(*v.name_data));
v.loc_data = stdlib.malloc(capacity * sizeof(*v.loc_data));
}
}

public fn void NameMap.free(NameMap* v) {
if (v.name_data != v.name_stash) stdlib.free(v.name_data);
if (v.loc_data != v.loc_stash) stdlib.free(v.loc_data);
v.count = 0;
v.capacity = 0;
v.name_data = nil;
v.loc_data = nil;
}

public fn void NameMap.clear(NameMap* v) @(unused) {
v.count = 0;
}

fn void NameMap.resize(NameMap* v) {
if (v.capacity == 0) {
v.name_data = v.name_stash;
v.loc_data = v.loc_stash;
v.capacity = elemsof(v.name_stash);
} else {
v.capacity = v.capacity * 2;
u32* name_data2 = stdlib.malloc(v.capacity * sizeof(*v.name_data));
string.memcpy(name_data2, v.name_data, v.count * sizeof(*v.name_data));
if (v.loc_data != v.loc_stash) stdlib.free(v.name_data);
v.name_data = name_data2;
u32* loc_data2 = stdlib.malloc(v.capacity * sizeof(*v.loc_data));
string.memcpy(loc_data2, v.loc_data, v.count * sizeof(*v.loc_data));
if (v.loc_data != v.loc_stash) stdlib.free(v.loc_data);
v.loc_data = loc_data2;
}
}

public fn u32 NameMap.add(NameMap* v, u32 name_idx, SrcLoc loc) {
if (v.count == v.capacity) v.resize();

u32 index = v.count++;
v.name_data[index] = name_idx;
v.loc_data[index] = loc;
return index;
}

public fn bool NameMap.find(NameMap* v, u32 name_idx, u32* indexp) {
for (u32 i = 0; i < v.count; i++) {
if (v.name_data[i] == name_idx) {
*indexp = i;
return true;
}
}
return false;
}

public fn SrcLoc NameMap.getLoc(NameMap* v, u32 i) {
return v.loc_data[i];
}

2 changes: 1 addition & 1 deletion analyser/name_vector.c2
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public fn u32 NameVector.add(NameVector* v, u32 name_idx) {
return index;
}

public fn u32 NameVector.get(const NameVector* v, u32 idx) {
public fn u32 NameVector.get(const NameVector* v, u32 idx) @(unused) {
return v.data[idx];
}

Expand Down
1 change: 1 addition & 0 deletions recipe.txt
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ executable c2c
analyser/module_sorter.c2
analyser/struct_field_init_checker.c2
analyser/name_vector.c2
analyser/name_map.c2
analyser/label_vector.c2
analyser/printf_utils.c2
analyser/scope.c2
Expand Down
Loading