cbindgen/bindgen/ir/
typedef.rs1use std::collections::HashMap;
6
7use syn::ext::IdentExt;
8
9use crate::bindgen::config::Config;
10use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
11use crate::bindgen::dependencies::Dependencies;
12use crate::bindgen::ir::{
13 AnnotationSet, Cfg, Documentation, Field, GenericArgument, GenericParams, Item, ItemContainer,
14 Path, Struct, Type,
15};
16use crate::bindgen::library::Library;
17use crate::bindgen::mangle;
18use crate::bindgen::monomorph::Monomorphs;
19
20#[derive(Debug, Clone)]
22pub struct Typedef {
23 pub path: Path,
24 pub export_name: String,
25 pub generic_params: GenericParams,
26 pub aliased: Type,
27 pub cfg: Option<Cfg>,
28 pub annotations: AnnotationSet,
29 pub documentation: Documentation,
30}
31
32impl Typedef {
33 pub fn load(item: &syn::ItemType, mod_cfg: Option<&Cfg>) -> Result<Typedef, String> {
34 if let Some(x) = Type::load(&item.ty)? {
35 let path = Path::new(item.ident.unraw().to_string());
36 Ok(Typedef::new(
37 path,
38 GenericParams::load(&item.generics)?,
39 x,
40 Cfg::append(mod_cfg, Cfg::load(&item.attrs)),
41 AnnotationSet::load(&item.attrs)?,
42 Documentation::load(&item.attrs),
43 ))
44 } else {
45 Err("Cannot have a typedef of a zero sized type.".to_owned())
46 }
47 }
48
49 pub fn new(
50 path: Path,
51 generic_params: GenericParams,
52 aliased: Type,
53 cfg: Option<Cfg>,
54 annotations: AnnotationSet,
55 documentation: Documentation,
56 ) -> Self {
57 let export_name = path.name().to_owned();
58 Self {
59 path,
60 export_name,
61 generic_params,
62 aliased,
63 cfg,
64 annotations,
65 documentation,
66 }
67 }
68
69 pub fn simplify_standard_types(&mut self, config: &Config) {
70 self.aliased.simplify_standard_types(config);
71 }
72
73 pub fn new_from_struct_field(item: &Struct, field: &Field) -> Self {
75 Self {
76 path: item.path().clone(),
77 export_name: item.export_name().to_string(),
78 generic_params: item.generic_params.clone(),
79 aliased: field.ty.clone(),
80 cfg: item.cfg().cloned(),
81 annotations: item.annotations().clone(),
82 documentation: item.documentation().clone(),
83 }
84 }
85
86 pub fn transfer_annotations(&mut self, out: &mut HashMap<Path, AnnotationSet>) {
87 if self.annotations.is_empty() {
88 return;
89 }
90
91 if let Some(alias_path) = self.aliased.get_root_path() {
92 if out.contains_key(&alias_path) {
93 warn!(
94 "Multiple typedef's with annotations for {}. Ignoring annotations from {}.",
95 alias_path, self.path
96 );
97 return;
98 }
99
100 out.insert(alias_path, self.annotations.clone());
101 self.annotations = AnnotationSet::new();
102 }
103 }
104
105 pub fn add_monomorphs(&self, library: &Library, out: &mut Monomorphs) {
106 if !self.is_generic() {
109 self.aliased.add_monomorphs(library, out);
110 }
111 }
112
113 pub fn mangle_paths(&mut self, monomorphs: &Monomorphs) {
114 self.aliased.mangle_paths(monomorphs);
115 }
116}
117
118impl Item for Typedef {
119 fn path(&self) -> &Path {
120 &self.path
121 }
122
123 fn export_name(&self) -> &str {
124 &self.export_name
125 }
126
127 fn cfg(&self) -> Option<&Cfg> {
128 self.cfg.as_ref()
129 }
130
131 fn annotations(&self) -> &AnnotationSet {
132 &self.annotations
133 }
134
135 fn annotations_mut(&mut self) -> &mut AnnotationSet {
136 &mut self.annotations
137 }
138
139 fn documentation(&self) -> &Documentation {
140 &self.documentation
141 }
142
143 fn container(&self) -> ItemContainer {
144 ItemContainer::Typedef(self.clone())
145 }
146
147 fn collect_declaration_types(&self, resolver: &mut DeclarationTypeResolver) {
148 resolver.add_none(&self.path);
149 }
150
151 fn resolve_declaration_types(&mut self, resolver: &DeclarationTypeResolver) {
152 self.aliased.resolve_declaration_types(resolver);
153 }
154
155 fn generic_params(&self) -> &GenericParams {
156 &self.generic_params
157 }
158
159 fn rename_for_config(&mut self, config: &Config) {
160 config.export.rename(&mut self.export_name);
161 self.aliased.rename_for_config(config, &self.generic_params);
162 }
163
164 fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
165 self.aliased
166 .add_dependencies_ignoring_generics(&self.generic_params, library, out);
167 }
168
169 fn instantiate_monomorph(
170 &self,
171 generic_values: &[GenericArgument],
172 library: &Library,
173 out: &mut Monomorphs,
174 ) {
175 let mappings = self.generic_params.call(self.path.name(), generic_values);
176
177 let mangled_path = mangle::mangle_path(
178 &self.path,
179 generic_values,
180 &library.get_config().export.mangle,
181 );
182
183 let monomorph = Typedef::new(
184 mangled_path,
185 GenericParams::default(),
186 self.aliased.specialize(&mappings),
187 self.cfg.clone(),
188 self.annotations.clone(),
189 self.documentation.clone(),
190 );
191
192 out.insert_typedef(library, self, monomorph, generic_values.to_owned());
193 }
194}