use super::{
BuildContext, ScoredMetadata, clang, function::build_function, interface::build_interface,
};
pub fn collect_sizeofs(cursor: clang::Entity<'_>, ctx: &mut BuildContext) {
match cursor.get_kind() {
clang::EntityKind::TranslationUnit
| clang::EntityKind::LinkageSpec
| clang::EntityKind::Namespace
| clang::EntityKind::UnexposedDecl => {
for child in cursor.get_children() {
collect_sizeofs(child, ctx);
}
}
clang::EntityKind::StructDecl
| clang::EntityKind::ClassDecl
| clang::EntityKind::UnionDecl
| clang::EntityKind::TypedefDecl
| clang::EntityKind::TypeAliasDecl => {
let name = match cursor.get_name() {
Some(name) => name,
None => return,
};
let ty = match cursor.get_type() {
Some(ty) => ty,
None => return,
};
let size = match ty.get_sizeof() {
Some(size) => size,
None => return,
};
if let Some(prev) = ctx.sizeofs.insert(name.clone(), size)
&& prev != size
{
tracing::debug!(name, prev, size, "sizeof conflict; last wins");
}
}
_ => {}
}
}
pub fn visit(cursor: clang::Entity<'_>, ctx: &BuildContext, out: &mut ScoredMetadata) {
match cursor.get_kind() {
clang::EntityKind::TranslationUnit
| clang::EntityKind::LinkageSpec
| clang::EntityKind::Namespace
| clang::EntityKind::UnexposedDecl => {
for child in cursor.get_children() {
visit(child, ctx, out);
}
}
clang::EntityKind::FunctionDecl => {
match build_function(cursor, ctx) {
Ok(scored) => out.functions.push(scored),
Err(err) => tracing::trace!(%err, "skipping non-function decl"),
}
}
clang::EntityKind::StructDecl | clang::EntityKind::ClassDecl => {
match build_interface(cursor, ctx) {
Ok(scored) => out.interfaces.push(scored),
Err(err) => tracing::trace!(%err, "skipping non-interface decl"),
}
}
_ => {}
}
}