Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions c2rust-transpile/src/c_ast/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,28 @@ impl ConversionContext {
self.visit_node(untyped_context, node_id, new_id, expected_ty)
}

// Check what primitive kinds were emitted by the compiler.
let mut found_kinds: HashMap<_, _> = CTypeKind::PRIMITIVE_KINDS
.into_iter()
.map(|kind| (kind, false))
.collect();

for Located { kind, .. } in self.typed_context.c_types.values() {
if let Some(is_found) = found_kinds.get_mut(kind) {
*is_found = true;
}
}

// If any primitives are missing, add them ourselves.
for (kind, is_found) in found_kinds {
if !is_found {
let new_id = self.id_mapper.fresh_id();
self.add_type(new_id, not_located(kind));
self.processed_nodes
.insert(new_id, self::node_types::OTHER_TYPE);
}
}

// Function declarations' types look through typedefs, but we want to use the types with
// typedefs intact in some cases during translation. To ensure that these types exist in the
// `TypedAstContext`, iterate over all function decls, compute their adjusted type using
Expand Down
44 changes: 41 additions & 3 deletions c2rust-transpile/src/c_ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1375,6 +1375,33 @@ impl TypedAstContext {
self.ast_context,
self.ast_context.c_exprs[&e].kind.get_qual_type().unwrap(),
),
CExprKind::Call(result_type_id, callee_id, _) => {
let CExprKind::ImplicitCast(_, callee_id, CastKind::BuiltinFnToFnPtr, _, _) =
self.ast_context.index_unwrap_parens(callee_id).kind
else {
return;
};
let CExprKind::DeclRef(_, decl_id, _) =
self.ast_context.index_unwrap_parens(callee_id).kind
else {
return;
};
let CDeclKind::Function { ref name, .. } = self.ast_context[decl_id].kind
else {
return;
};

match name.as_str() {
"__builtin_object_size" => {
let type_id = self
.ast_context
.type_for_kind(&CTypeKind::Size)
.expect("CTypeKind::Size should be size_t");
Some(result_type_id.with_ctype(type_id))
}
_ => None,
}
}
CExprKind::Paren(_ty, e) => self.ast_context.c_exprs[&e].kind.get_qual_type(),
CExprKind::UnaryType(_, op, _, _) => {
// All of these `CUnTypeOp`s should return `size_t`.
Expand Down Expand Up @@ -2483,7 +2510,7 @@ pub struct AsmOperand {
}

/// Type qualifiers (6.7.3)
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Hash)]
pub struct Qualifiers {
/// The `const` qualifier, which marks lvalues as non-assignable.
///
Expand Down Expand Up @@ -2519,7 +2546,7 @@ impl Qualifiers {
}

/// Qualified type
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct CQualTypeId {
pub qualifiers: Qualifiers,
pub ctype: CTypeId,
Expand All @@ -2546,7 +2573,7 @@ impl CQualTypeId {
/// Represents a type in C (6.2.5 Types)
///
/// Reflects the types in <http://clang.llvm.org/doxygen/classclang_1_1Type.html>
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum CTypeKind {
Void,

Expand Down Expand Up @@ -2670,6 +2697,17 @@ pub enum CTypeKind {
}

impl CTypeKind {
/// Kinds for C primitive types. These are emitted by the compiler, but possibly only if
/// they are actually used in the code.
pub const PRIMITIVE_KINDS: [CTypeKind; 16] = {
use CTypeKind::*;
[
Void, Bool, Char, SChar, Short, Int, Long, LongLong, UChar, UShort, UInt, ULong,
ULongLong, Float, Double, LongDouble,
]
};

/// Kinds for Rust types that are pulled back into C, for more fine-grained translation.
pub const PULLBACK_KINDS: [CTypeKind; 16] = {
use CTypeKind::*;
[
Expand Down
Loading
Loading