Skip to content

Commit d6d097c

Browse files
author
bors-servo
authored
Auto merge of #1312 - emilio:constness-woes, r=fitzgen
ir: Handle *const T at the codegen level. Followup to #1311.
2 parents 74dcb20 + 716d53b commit d6d097c

File tree

8 files changed

+92
-23
lines changed

8 files changed

+92
-23
lines changed

src/codegen/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3054,7 +3054,7 @@ impl TryToRustTy for Type {
30543054
}
30553055
TypeKind::Pointer(inner) |
30563056
TypeKind::Reference(inner) => {
3057-
let is_const = self.is_const() || ctx.resolve_type(inner).is_const();
3057+
let is_const = ctx.resolve_type(inner).is_const();
30583058

30593059
let inner = inner.into_resolver().through_type_refs().resolve(ctx);
30603060
let inner_ty = inner.expect_type();

src/ir/context.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -1925,9 +1925,44 @@ impl BindgenContext {
19251925
wrapped_id: TypeId,
19261926
parent_id: Option<ItemId>,
19271927
ty: &clang::Type,
1928+
) -> TypeId {
1929+
self.build_wrapper(
1930+
with_id,
1931+
wrapped_id,
1932+
parent_id,
1933+
ty,
1934+
ty.is_const(),
1935+
)
1936+
}
1937+
1938+
/// A wrapper over a type that adds a const qualifier explicitly.
1939+
///
1940+
/// Needed to handle const methods in C++, wrapping the type .
1941+
pub fn build_const_wrapper(
1942+
&mut self,
1943+
with_id: ItemId,
1944+
wrapped_id: TypeId,
1945+
parent_id: Option<ItemId>,
1946+
ty: &clang::Type,
1947+
) -> TypeId {
1948+
self.build_wrapper(
1949+
with_id,
1950+
wrapped_id,
1951+
parent_id,
1952+
ty,
1953+
/* is_const = */ true,
1954+
)
1955+
}
1956+
1957+
fn build_wrapper(
1958+
&mut self,
1959+
with_id: ItemId,
1960+
wrapped_id: TypeId,
1961+
parent_id: Option<ItemId>,
1962+
ty: &clang::Type,
1963+
is_const: bool,
19281964
) -> TypeId {
19291965
let spelling = ty.spelling();
1930-
let is_const = ty.is_const();
19311966
let layout = ty.fallible_layout().ok();
19321967
let type_kind = TypeKind::ResolvedTypeRef(wrapped_id);
19331968
let ty = Type::new(Some(spelling), layout, type_kind, is_const);

src/ir/function.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -402,14 +402,27 @@ impl FunctionSig {
402402
let is_virtual = is_method && cursor.method_is_virtual();
403403
let is_static = is_method && cursor.method_is_static();
404404
if !is_static && !is_virtual {
405-
let class = Item::parse(cursor.semantic_parent(), None, ctx)
405+
let parent = cursor.semantic_parent();
406+
let class = Item::parse(parent, None, ctx)
406407
.expect("Expected to parse the class");
407408
// The `class` most likely is not finished parsing yet, so use
408409
// the unchecked variant.
409410
let class = class.as_type_id_unchecked();
410411

412+
let class = if is_const {
413+
let const_class_id = ctx.next_item_id();
414+
ctx.build_const_wrapper(
415+
const_class_id,
416+
class,
417+
None,
418+
&parent.cur_type(),
419+
)
420+
} else {
421+
class
422+
};
423+
411424
let ptr =
412-
Item::builtin_type(TypeKind::Pointer(class), is_const, ctx);
425+
Item::builtin_type(TypeKind::Pointer(class), false, ctx);
413426
args.insert(0, (Some("this".into()), ptr));
414427
} else if is_virtual {
415428
let void = Item::builtin_type(TypeKind::Void, false, ctx);

src/ir/item.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1449,8 +1449,8 @@ impl ClangItemParser for Item {
14491449
return Ok(Item::new_opaque_type(id, ty, ctx));
14501450
}
14511451

1452-
if let Some(id) = Item::type_param(Some(id), location, ctx) {
1453-
return Ok(id);
1452+
if let Some(param_id) = Item::type_param(None, location, ctx) {
1453+
return Ok(ctx.build_ty_wrapper(id, param_id, None, ty));
14541454
}
14551455
}
14561456

src/ir/layout.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ impl Opaque {
8888
pub fn from_clang_ty(ty: &clang::Type) -> Type {
8989
let layout = Layout::new(ty.size(), ty.align());
9090
let ty_kind = TypeKind::Opaque;
91-
Type::new(None, Some(layout), ty_kind, false)
91+
let is_const = ty.is_const();
92+
Type::new(None, Some(layout), ty_kind, is_const)
9293
}
9394

9495
/// Return the known rust type we should use to create a correctly-aligned

src/ir/ty.rs

+1-16
Original file line numberDiff line numberDiff line change
@@ -1195,22 +1195,7 @@ impl Type {
11951195

11961196
let name = if name.is_empty() { None } else { Some(name) };
11971197

1198-
// Just using ty.is_const() is wrong here, because when we declare an
1199-
// argument like 'int* const arg0', arg0 is considered
1200-
// const but the pointer itself points to mutable data.
1201-
//
1202-
// Without canonicalizing the type to the pointer type, we'll get the
1203-
// following mapping:
1204-
//
1205-
// arg0: *const c_int
1206-
//
1207-
// So by canonicalizing the type first, we can check constness by
1208-
// calling is_const() on the pointer type.
1209-
let is_const = if let Some(pty) = ty.pointee_type() {
1210-
pty.is_const()
1211-
} else {
1212-
ty.is_const()
1213-
};
1198+
let is_const = ty.is_const();
12141199

12151200
let ty = Type::new(name, layout, kind, is_const);
12161201
// TODO: maybe declaration.canonical()?
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
4+
5+
#[repr(C)]
6+
#[derive(Debug, Copy, Clone)]
7+
pub struct foo {
8+
pub bar: *const *const *mut *const ::std::os::raw::c_int,
9+
}
10+
#[test]
11+
fn bindgen_test_layout_foo() {
12+
assert_eq!(
13+
::std::mem::size_of::<foo>(),
14+
8usize,
15+
concat!("Size of: ", stringify!(foo))
16+
);
17+
assert_eq!(
18+
::std::mem::align_of::<foo>(),
19+
8usize,
20+
concat!("Alignment of ", stringify!(foo))
21+
);
22+
assert_eq!(
23+
unsafe { &(*(::std::ptr::null::<foo>())).bar as *const _ as usize },
24+
0usize,
25+
concat!("Offset of field: ", stringify!(foo), "::", stringify!(bar))
26+
);
27+
}
28+
impl Default for foo {
29+
fn default() -> Self {
30+
unsafe { ::std::mem::zeroed() }
31+
}
32+
}

tests/headers/const-const-mut-ptr.h

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct foo {
2+
const int** const* const* bar;
3+
};

0 commit comments

Comments
 (0)