Skip to content

Commit

Permalink
ir: Tweak monomorphization to instantiate recursively after inserting…
Browse files Browse the repository at this point in the history
… to the replacements map.

That way the check to prevent double-instantiation also works to prevent
infinite recursion.
  • Loading branch information
emilio committed Apr 7, 2021
1 parent 52de917 commit a9af0ad
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 20 deletions.
4 changes: 1 addition & 3 deletions src/bindgen/ir/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,9 +633,7 @@ impl Item for Enum {
self.documentation.clone(),
);

monomorph.add_monomorphs(library, out);

out.insert_enum(self, monomorph, generic_values.to_owned());
out.insert_enum(library, self, monomorph, generic_values.to_owned());
}

fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
Expand Down
6 changes: 1 addition & 5 deletions src/bindgen/ir/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,7 @@ impl Item for Struct {
.collect::<Vec<_>>();

let monomorph = self.specialize(generic_values, &mappings, library.get_config());

// Instantiate any monomorphs for any generic paths we may have just created.
monomorph.add_monomorphs(library, out);

out.insert_struct(self, monomorph, generic_values.to_owned());
out.insert_struct(library, self, monomorph, generic_values.to_owned());
}
}

Expand Down
5 changes: 1 addition & 4 deletions src/bindgen/ir/typedef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,7 @@ impl Item for Typedef {
self.documentation.clone(),
);

// Instantiate any monomorphs for any generic paths we may have just created.
monomorph.add_monomorphs(library, out);

out.insert_typedef(self, monomorph, generic_values.to_owned());
out.insert_typedef(library, self, monomorph, generic_values.to_owned());
}
}

Expand Down
5 changes: 1 addition & 4 deletions src/bindgen/ir/union.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,7 @@ impl Item for Union {
self.documentation.clone(),
);

// Instantiate any monomorphs for any generic paths we may have just created.
monomorph.add_monomorphs(library, out);

out.insert_union(self, monomorph, generic_values.to_owned());
out.insert_union(library, self, monomorph, generic_values.to_owned());
}
}

Expand Down
45 changes: 41 additions & 4 deletions src/bindgen/monomorph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::collections::HashMap;
use std::mem;

use crate::bindgen::ir::{Enum, GenericPath, OpaqueItem, Path, Struct, Type, Typedef, Union};
use crate::bindgen::library::Library;

#[derive(Default, Clone, Debug)]
pub struct Monomorphs {
Expand All @@ -22,36 +23,63 @@ impl Monomorphs {
self.replacements.contains_key(path)
}

pub fn insert_struct(&mut self, generic: &Struct, monomorph: Struct, parameters: Vec<Type>) {
pub fn insert_struct(
&mut self,
library: &Library,
generic: &Struct,
monomorph: Struct,
parameters: Vec<Type>,
) {
let replacement_path = GenericPath::new(generic.path.clone(), parameters);

debug_assert!(generic.generic_params.len() > 0);
debug_assert!(!self.contains(&replacement_path));

self.replacements
.insert(replacement_path, monomorph.path.clone());

monomorph.add_monomorphs(library, self);

self.structs.push(monomorph);
}

pub fn insert_enum(&mut self, generic: &Enum, monomorph: Enum, parameters: Vec<Type>) {
pub fn insert_enum(
&mut self,
library: &Library,
generic: &Enum,
monomorph: Enum,
parameters: Vec<Type>,
) {
let replacement_path = GenericPath::new(generic.path.clone(), parameters);

debug_assert!(generic.generic_params.len() > 0);
debug_assert!(!self.contains(&replacement_path));

self.replacements
.insert(replacement_path, monomorph.path.clone());

monomorph.add_monomorphs(library, self);

self.enums.push(monomorph);
}

pub fn insert_union(&mut self, generic: &Union, monomorph: Union, parameters: Vec<Type>) {
pub fn insert_union(
&mut self,
library: &Library,
generic: &Union,
monomorph: Union,
parameters: Vec<Type>,
) {
let replacement_path = GenericPath::new(generic.path.clone(), parameters);

debug_assert!(generic.generic_params.len() > 0);
debug_assert!(!self.contains(&replacement_path));

self.replacements
.insert(replacement_path, monomorph.path.clone());

monomorph.add_monomorphs(library, self);

self.unions.push(monomorph);
}

Expand All @@ -71,14 +99,23 @@ impl Monomorphs {
self.opaques.push(monomorph);
}

pub fn insert_typedef(&mut self, generic: &Typedef, monomorph: Typedef, parameters: Vec<Type>) {
pub fn insert_typedef(
&mut self,
library: &Library,
generic: &Typedef,
monomorph: Typedef,
parameters: Vec<Type>,
) {
let replacement_path = GenericPath::new(generic.path.clone(), parameters);

debug_assert!(generic.generic_params.len() > 0);
debug_assert!(!self.contains(&replacement_path));

self.replacements
.insert(replacement_path, monomorph.path.clone());

monomorph.add_monomorphs(library, self);

self.typedefs.push(monomorph);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
5 changes: 5 additions & 0 deletions tests/expectations/infinite-recursion-typedef-monomorph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>
8 changes: 8 additions & 0 deletions tests/expectations/infinite-recursion-typedef-monomorph.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
cdef extern from *:
ctypedef bint bool
ctypedef struct va_list

cdef extern from *:
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
5 changes: 5 additions & 0 deletions tests/expectations/infinite_recursion_typedef_monomorph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>
8 changes: 8 additions & 0 deletions tests/expectations/infinite_recursion_typedef_monomorph.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
cdef extern from *:
ctypedef bint bool
ctypedef struct va_list

cdef extern from *:
pass
2 changes: 2 additions & 0 deletions tests/rust/infinite_recursion_typedef_monomorph.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub type TryVec<T> = fallible_collections::TryVec<T>;
pub type TryString = fallible_collections::TryVec<u8>;

0 comments on commit a9af0ad

Please sign in to comment.