Skip to content

Commit 6a307b6

Browse files
committed
codegen: Move type mangling to its own module
This enables sharing the type mangling with the variable generator
1 parent a6b4f68 commit 6a307b6

File tree

3 files changed

+45
-37
lines changed

3 files changed

+45
-37
lines changed

src/codegen/generators.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ pub mod data_type_generator;
22
pub mod expression_generator;
33
pub mod llvm;
44
pub mod pou_generator;
5+
pub mod section_names;
56
pub mod statement_generator;
67
pub mod variable_generator;
78

src/codegen/generators/pou_generator.rs

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use super::{
44
data_type_generator::get_default_for,
55
expression_generator::ExpressionCodeGenerator,
66
llvm::{GlobalValueExt, Llvm},
7+
section_names,
78
statement_generator::{FunctionContext, StatementCodeGenerator},
89
ADDRESS_SPACE_GENERIC,
910
};
@@ -14,7 +15,7 @@ use crate::{
1415
},
1516
index::{self, ImplementationType},
1617
resolver::{AstAnnotations, Dependency},
17-
typesystem::{self, DataType, DataTypeInformation, StringEncoding, TypeSize, VarArgs},
18+
typesystem::{self, DataType, VarArgs},
1819
};
1920
use std::collections::HashMap;
2021

@@ -40,7 +41,7 @@ use inkwell::{
4041
use plc_ast::ast::{AstNode, Implementation, PouType};
4142
use plc_diagnostics::diagnostics::{Diagnostic, INTERNAL_LLVM_ERROR};
4243
use plc_source::source_location::SourceLocation;
43-
use section_mangler::{FunctionArgument, SectionMangler, StringEncoding as SectionStringEncoding, Type};
44+
use section_mangler::{FunctionArgument, SectionMangler};
4445

4546
pub struct PouGenerator<'ink, 'cg> {
4647
llvm: Llvm<'ink>,
@@ -158,7 +159,10 @@ impl<'ink, 'cg> PouGenerator<'ink, 'cg> {
158159

159160
let ctx = params.into_iter().fold(ctx, |ctx, param| {
160161
// FIXME: Can we unwrap here?
161-
let ty = self.mangle_type(self.index.get_effective_type_by_name(&param.data_type_name).unwrap());
162+
let ty = section_names::mangle_type(
163+
self.index,
164+
self.index.get_effective_type_by_name(&param.data_type_name).unwrap(),
165+
);
162166
let parameter = match param.argument_type {
163167
// TODO: We need to handle the `VariableType` enum as well - this describes the mode of
164168
// argument passing, e.g. inout
@@ -169,44 +173,14 @@ impl<'ink, 'cg> PouGenerator<'ink, 'cg> {
169173
ctx.with_parameter(parameter)
170174
});
171175

172-
let return_ty =
173-
self.index.find_return_type(implementation.get_type_name()).map(|ty| self.mangle_type(ty));
176+
let return_ty = self
177+
.index
178+
.find_return_type(implementation.get_type_name())
179+
.map(|ty| section_names::mangle_type(self.index, ty));
174180

175181
ctx.with_return_type(return_ty).mangle()
176182
}
177183

178-
fn mangle_type(&self, ty: &typesystem::DataType) -> Type {
179-
// TODO: This is a bit ugly because we keep dereferencing references to Copy types like
180-
// bool, u32, etc, because `DataTypeInformation::Pointer` keeps a `String` which is not
181-
// Copy. the alternative is for section_mangle::Type to keep references everywhere, and
182-
// have a lifetime generic parameter, e.g. `section_mangler::Type<'a>` - which is also
183-
// annoying.
184-
match ty.get_type_information() {
185-
DataTypeInformation::Void => Type::Void,
186-
DataTypeInformation::Integer { signed, size, semantic_size, .. } => {
187-
Type::Integer { signed: *signed, size: *size, semantic_size: *semantic_size }
188-
}
189-
DataTypeInformation::Float { size, .. } => Type::Float { size: *size },
190-
DataTypeInformation::String { size: TypeSize::LiteralInteger(size), encoding } => {
191-
let encoding = match encoding {
192-
StringEncoding::Utf8 => SectionStringEncoding::Utf8,
193-
StringEncoding::Utf16 => SectionStringEncoding::Utf16,
194-
};
195-
196-
Type::String { size: *size as usize, encoding }
197-
}
198-
DataTypeInformation::Pointer { inner_type_name, .. } => Type::Pointer {
199-
inner: Box::new(
200-
self.mangle_type(self.index.get_effective_type_by_name(inner_type_name).unwrap()),
201-
),
202-
},
203-
// FIXME: For now, encode all unknown types as "void" since this is not required for
204-
// execution. Not doing so (and doing an `unreachable!()` for example) obviously causes
205-
// failures, because complex types are already implemented in the compiler.
206-
_ => Type::Void,
207-
}
208-
}
209-
210184
/// generates an empty llvm function for the given implementation, including all parameters and the return type
211185
pub fn generate_implementation_stub(
212186
&self,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use crate::index::Index;
2+
use crate::typesystem::{self, DataTypeInformation, StringEncoding, TypeSize};
3+
use section_mangler::{StringEncoding as SectionStringEncoding, Type};
4+
5+
pub fn mangle_type(index: &Index, ty: &typesystem::DataType) -> section_mangler::Type {
6+
// TODO: This is a bit ugly because we keep dereferencing references to Copy types like
7+
// bool, u32, etc, because `DataTypeInformation::Pointer` keeps a `String` which is not
8+
// Copy. the alternative is for section_mangle::Type to keep references everywhere, and
9+
// have a lifetime generic parameter, e.g. `section_mangler::Type<'a>` - which is also
10+
// annoying.
11+
match ty.get_type_information() {
12+
DataTypeInformation::Void => Type::Void,
13+
DataTypeInformation::Integer { signed, size, semantic_size, .. } => {
14+
Type::Integer { signed: *signed, size: *size, semantic_size: *semantic_size }
15+
}
16+
DataTypeInformation::Float { size, .. } => Type::Float { size: *size },
17+
DataTypeInformation::String { size: TypeSize::LiteralInteger(size), encoding } => {
18+
let encoding = match encoding {
19+
StringEncoding::Utf8 => SectionStringEncoding::Utf8,
20+
StringEncoding::Utf16 => SectionStringEncoding::Utf16,
21+
};
22+
23+
Type::String { size: *size as usize, encoding }
24+
}
25+
DataTypeInformation::Pointer { inner_type_name, .. } => Type::Pointer {
26+
inner: Box::new(mangle_type(index, index.get_effective_type_by_name(inner_type_name).unwrap())),
27+
},
28+
// FIXME: For now, encode all unknown types as "void" since this is not required for
29+
// execution. Not doing so (and doing an `unreachable!()` for example) obviously causes
30+
// failures, because complex types are already implemented in the compiler.
31+
_ => Type::Void,
32+
}
33+
}

0 commit comments

Comments
 (0)