Skip to content

Commit 6c4b552

Browse files
committed
Temporary fix for not yet indexed types in codgen
1 parent 9c032b0 commit 6c4b552

File tree

3 files changed

+59
-12
lines changed

3 files changed

+59
-12
lines changed

src/codegen/generators/data_type_generator.rs

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,22 +97,43 @@ pub fn generate_data_types<'ink>(
9797
}
9898
}
9999

100-
// now create all other types (enum's, arrays, etc.)
100+
// Separate function types from other types to process them later
101+
let mut function_types = vec![];
102+
let mut non_function_types = vec![];
103+
101104
for (name, user_type) in &types {
105+
if let DataTypeInformation::Struct { source: StructSource::Pou(PouType::Function | PouType::Method { .. }, ..), .. } = user_type.get_type_information() {
106+
function_types.push((*name, *user_type));
107+
} else {
108+
non_function_types.push((*name, *user_type));
109+
}
110+
}
111+
112+
// First create all POU types (excluding functions/methods) - this includes function blocks like ClassA, ClassB
113+
for (name, user_type) in &pou_types {
114+
let gen_type = generator.create_type(name, user_type)?;
115+
generator.types_index.associate_pou_type(name, gen_type)?
116+
}
117+
118+
// Then create function types now that all POU types are available
119+
for (name, user_type) in &function_types {
102120
let gen_type = generator.create_type(name, user_type)?;
103121
generator.types_index.associate_type(name, gen_type)?
104122
//Get and associate debug type
105123
}
106124

107-
for (name, user_type) in &pou_types {
125+
// Finally create all non-function types (enum's, arrays, VTable structs, etc.)
126+
for (name, user_type) in &non_function_types {
108127
let gen_type = generator.create_type(name, user_type)?;
109-
generator.types_index.associate_pou_type(name, gen_type)?
128+
generator.types_index.associate_type(name, gen_type)?
129+
//Get and associate debug type
110130
}
111131

112-
// Combine the types and pou_types into a single Vector
132+
// Combine all types in the order they were processed
113133
let mut types_to_init = VecDeque::new();
114-
types_to_init.extend(types);
115134
types_to_init.extend(pou_types);
135+
types_to_init.extend(function_types);
136+
types_to_init.extend(non_function_types);
116137
// now since all types should be available in the llvm index, we can think about constructing and associating
117138
for (_, user_type) in &types_to_init {
118139
//Expand all types
@@ -176,7 +197,7 @@ pub fn generate_data_types<'ink>(
176197
}
177198

178199
impl<'ink> DataTypeGenerator<'ink, '_> {
179-
fn create_function_type(&self, name: &str) -> Result<FunctionType<'ink>, Diagnostic> {
200+
fn create_function_type(&mut self, name: &str) -> Result<FunctionType<'ink>, Diagnostic> {
180201
let return_type_dt = self.index.find_return_type(name).unwrap_or(self.index.get_void_type());
181202

182203
let return_type = self
@@ -190,8 +211,20 @@ impl<'ink> DataTypeGenerator<'ink, '_> {
190211
// For methods, we need to add the 'this' parameter as the first parameter
191212
if let Some(PouIndexEntry::Method { parent_name, .. }) = self.index.find_pou(name) {
192213
// Get the owner class type and add it as the first parameter (this pointer)
193-
if let Ok(owner_type) = self.types_index.get_associated_type(parent_name) {
214+
// If the parent type is not available yet (e.g., during early type creation),
215+
// we'll create a properly named opaque struct as placeholder
216+
if let Ok(owner_type) = self.types_index.get_associated_pou_type(parent_name) {
194217
parameter_types.push(owner_type.ptr_type(AddressSpace::from(ADDRESS_SPACE_GENERIC)).into());
218+
} else {
219+
// Create an opaque struct type with the exact same name that will be used
220+
// when the full type is created. This ensures LLVM will treat them as the same type.
221+
let opaque_struct = self.llvm.context.opaque_struct_type(parent_name);
222+
let opaque_type: BasicTypeEnum = opaque_struct.into();
223+
224+
// Register it in the POU type index for this generation session
225+
let _ = self.types_index.associate_pou_type(parent_name, opaque_type.as_any_type_enum());
226+
227+
parameter_types.push(opaque_type.ptr_type(AddressSpace::from(ADDRESS_SPACE_GENERIC)).into());
195228
}
196229
}
197230

@@ -206,10 +239,11 @@ impl<'ink> DataTypeGenerator<'ink, '_> {
206239

207240
parameter_types.extend(declared_params);
208241

209-
let fn_type = match dbg!(return_type) {
242+
let fn_type = match return_type {
210243
AnyTypeEnum::IntType(value) => value.fn_type(parameter_types.as_slice(), false),
211244
AnyTypeEnum::VoidType(value) => value.fn_type(parameter_types.as_slice(), false),
212-
_ => unimplemented!(),
245+
AnyTypeEnum::FloatType(value) => value.fn_type(parameter_types.as_slice(), false),
246+
_ => unimplemented!("Unsupported function return type: {:?}", return_type),
213247
};
214248

215249
Ok(fn_type)
@@ -248,9 +282,11 @@ impl<'ink> DataTypeGenerator<'ink, '_> {
248282
StructSource::Pou(PouType::Function | PouType::Method { .. }, ..) => {
249283
let gen_type = self.create_function_type(name)?;
250284

251-
// TODO(vosa): Strictly speaking we don't need to register in LLVM index, i.e. `return Ok(gen_type.as_any_type_enum())` would suffice without breaking any tests; re-think approach with AnyType changes in API
285+
// Associate the function type in the POU index
252286
self.types_index.associate_pou_type(name, gen_type.as_any_type_enum())?;
253-
self.types_index.get_associated_function_type(name).map(|it| it.as_any_type_enum())
287+
288+
// Return the function type
289+
Ok(gen_type.as_any_type_enum())
254290
}
255291
StructSource::Pou(..) => self
256292
.types_index

src/codegen/generators/pou_generator.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,14 @@ impl<'ink, 'cg> PouGenerator<'ink, 'cg> {
389389
let class_name =
390390
implementation.get_associated_class_name().expect("Method needs to have a class-name");
391391
let instance_members_struct_type: StructType =
392-
self.llvm_index.get_associated_type(class_name).map(|it| it.into_struct_type())?;
392+
self.llvm_index.get_associated_pou_type(class_name)
393+
.or_else(|_| {
394+
// Fallback: create a placeholder opaque struct type
395+
eprintln!("Warning: POU type '{}' not found, creating placeholder", class_name);
396+
let placeholder_struct = self.llvm.context.opaque_struct_type(class_name);
397+
Ok::<BasicTypeEnum<'_>, Diagnostic>(placeholder_struct.into())
398+
})
399+
.map(|it| it.into_struct_type())?;
393400
parameters.insert(
394401
0,
395402
instance_members_struct_type.ptr_type(AddressSpace::from(ADDRESS_SPACE_GENERIC)).into(),

src/codegen/llvm_index.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ impl<'ink> LlvmTypedIndex<'ink> {
200200

201201
pub fn get_associated_pou_type(&self, type_name: &str) -> Result<BasicTypeEnum<'ink>, Diagnostic> {
202202
self.find_associated_pou_type(type_name)
203+
.or_else(|| {
204+
// Fallback: try to find it as a regular type if it's not found as a POU type
205+
self.find_associated_type(type_name)
206+
})
203207
.ok_or_else(|| Diagnostic::unknown_type(type_name, SourceLocation::undefined()))
204208
}
205209

0 commit comments

Comments
 (0)