Skip to content

Commit 3c95378

Browse files
committed
feat: add a vtable type for every function block and interface
A new type is added for every function block, class or interface this represents a vtable with the methods declared in the class. If a class extends another class, the parent's class is also included. If a class extends an interface, the interface is also included.
1 parent f2f442e commit 3c95378

File tree

14 files changed

+1278
-18
lines changed

14 files changed

+1278
-18
lines changed

compiler/plc_driver/src/pipelines.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,15 @@ use plc::{
2424
codegen::{CodegenContext, GeneratedModule},
2525
index::{indexer, FxIndexSet, Index},
2626
linker::LinkerType,
27-
lowering::{
28-
property::PropertyLowerer,
29-
{calls::AggregateTypeLowerer, InitVisitor},
30-
},
27+
lowering::{calls::AggregateTypeLowerer, property::PropertyLowerer, InitVisitor},
3128
output::FormatOption,
3229
parser::parse_file,
3330
resolver::{
3431
const_evaluator::UnresolvableConstant, AnnotationMapImpl, AstAnnotations, Dependency, StringLiterals,
3532
TypeAnnotator,
3633
},
3734
validation::Validator,
35+
vtable::VTableIndexer,
3836
ConfigFormat, ErrorFormat, OnlineChange, Target, Threads,
3937
};
4038
use plc_diagnostics::{
@@ -263,6 +261,7 @@ impl<T: SourceContainer> BuildPipeline<T> {
263261
Box::new(InitParticipant::new(self.project.get_init_symbol_name(), self.context.provider())),
264262
Box::new(AggregateTypeLowerer::new(self.context.provider())),
265263
Box::new(InheritanceLowerer::new(self.context.provider())),
264+
Box::new(VTableIndexer::new(self.context.provider())),
266265
];
267266

268267
for participant in mut_participants {

compiler/plc_driver/src/pipelines/participant.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use std::{
1313

1414
use ast::provider::IdProvider;
1515
use plc::{
16-
codegen::GeneratedModule, lowering::calls::AggregateTypeLowerer, output::FormatOption, ConfigFormat,
17-
OnlineChange, Target,
16+
codegen::GeneratedModule, lowering::calls::AggregateTypeLowerer, output::FormatOption,
17+
vtable::VTableIndexer, ConfigFormat, OnlineChange, Target,
1818
};
1919
use plc_diagnostics::diagnostics::Diagnostic;
2020
use plc_lowering::inheritance::InheritanceLowerer;
@@ -281,3 +281,24 @@ impl PipelineParticipantMut for AggregateTypeLowerer {
281281
indexed_project.annotate(self.id_provider.clone())
282282
}
283283
}
284+
285+
impl PipelineParticipantMut for VTableIndexer {
286+
// TODO: Don't track overridden methods in vtable, as they're part of the parent instance (same for interfaces)
287+
fn post_index(&mut self, indexed_project: IndexedProject) -> IndexedProject {
288+
let IndexedProject { mut project, index, .. } = indexed_project;
289+
290+
let vtables_pou = VTableIndexer::create_vtables_for_pous(&index);
291+
let vtables_intf = VTableIndexer::create_vtables_for_interfaces(&index);
292+
let (internal, external) = VTableIndexer::create_global_variables_for_vtable(&index);
293+
294+
//FIXME: should we create the vtable in the unit of its pou?
295+
if let Some(unit) = project.units.first_mut() {
296+
unit.user_types.extend(vtables_pou);
297+
unit.user_types.extend(vtables_intf);
298+
unit.global_vars.push(internal);
299+
unit.global_vars.push(external);
300+
}
301+
302+
project.index(self.id_provider.clone())
303+
}
304+
}

compiler/plc_source/src/source_location.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,15 @@ impl SourceLocation {
289289
let SourceLocation { span, file } = self;
290290
SourceLocation { span, file: FileMarker::Internal(file.get_name().unwrap_or_default()) }
291291
}
292+
293+
pub fn into_internal_with_file(self) -> Self {
294+
let SourceLocation { file, .. } = self;
295+
SourceLocation {
296+
span: CodeSpan::None,
297+
file: FileMarker::Internal(file.get_name().unwrap_or_default()),
298+
}
299+
}
300+
292301
/// Constructs an undefined SourceRange with a 0..0 range and no filename
293302
pub fn undefined() -> SourceLocation {
294303
SourceLocation { span: CodeSpan::None, file: FileMarker::default() }

src/codegen/debug.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ use plc_source::source_location::SourceLocation;
2020

2121
use crate::{
2222
index::{Index, PouIndexEntry, VariableIndexEntry},
23-
typesystem::{DataType, DataTypeInformation, Dimension, StringEncoding, CHAR_TYPE, WCHAR_TYPE},
23+
typesystem::{
24+
DataType, DataTypeInformation, Dimension, StringEncoding, CHAR_TYPE, VOID_INTERNAL_NAME, WCHAR_TYPE,
25+
},
2426
DebugLevel, OptimizationLevel,
2527
};
2628

@@ -455,7 +457,21 @@ impl<'ink> DebugBuilder<'ink> {
455457
types_index: &LlvmTypedIndex,
456458
) -> Result<(), Diagnostic> {
457459
let inner_type = index.get_type(inner_type)?;
458-
let inner_type = self.get_or_create_debug_type(inner_type, index, types_index)?;
460+
//Skip void pointers debug info
461+
let inner_type = if inner_type.is_void() {
462+
DebugType::Basic(
463+
self.debug_info
464+
.create_basic_type(
465+
VOID_INTERNAL_NAME,
466+
0,
467+
DebugEncoding::DW_ATE_unsigned as u32,
468+
DIFlagsConstants::PUBLIC,
469+
)
470+
.map_err(|err| Diagnostic::codegen_error(err, SourceLocation::undefined()))?,
471+
)
472+
} else {
473+
self.get_or_create_debug_type(inner_type, index, types_index)?
474+
};
459475
let llvm_type = types_index.get_associated_type(name)?;
460476
let align_bits = self.target_data.get_preferred_alignment(&llvm_type) * 8;
461477
let pointer_type = self.debug_info.create_pointer_type(

src/codegen/tests/oop_tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use test_utils::codegen;
22

33
mod debug_tests;
44
mod super_tests;
5+
mod vtable_tests;
56

67
#[test]
78
fn members_from_base_class_are_available_in_subclasses() {

0 commit comments

Comments
 (0)