Generate pointer-valued macro constants#3379
Conversation
|
cc @metaspace @ojeda |
ee2d27d to
dd174a8
Compare
|
r? @emilio |
|
It could be nice to split in two commits, to see how the test changes -- from a quick test against mainline I see: +pub const BEFORE_DECL: *mut later = 3u64 as usize as *mut later;
+pub const CONST_PTR: *const later = 4u64 as usize as *const later;
+pub const TYPEDEF_PTR: *mut later = 5u64 as usize as *mut later;
+pub const MAP_FAILED: *mut ::std::os::raw::c_void = 18446744073709551615u64 as usize
+ as *mut ::std::os::raw::c_void;
+pub const MAP_FAILED_ALIAS: *mut ::std::os::raw::c_void = 18446744073709551615u64
+ as usize as *mut ::std::os::raw::c_void;
pub const MAP_FAILED_EQUALS_ITSELF: u32 = 1;
pub const REDEFINED_FROM_INT: u32 = 1;
-pub const REDEFINED_ALIAS: u32 = 1;
+pub const REDEFINED_ALIAS: *mut ::std::os::raw::c_void = 2u64 as usize
+ as *mut ::std::os::raw::c_void;Is that the expected change here? I am surprised there was no other test that needed an update for the (A couple surprising but pre-existing issues discussed elsewhere IIRC are the value of |
| } | ||
| } | ||
|
|
||
| /// Defer materialization of a pointer-valued macro until parsing finishes. |
There was a problem hiding this comment.
Could you elaborate why we need this deferral thing?
There was a problem hiding this comment.
The deferral is about libclang cursor lifetimes, not just macro ordering.
The fallback translation unit is reparsed for each macro cexpr cannot evaluate. Materializing a pointer immediately can create an UnresolvedTypeRef holding a clang::Type and cursor from that translation unit. Those references are resolved only after parsing completes, but evaluating the next fallback macro invalidates them.
The regression fixture makes this concrete: BEFORE_DECL refers to struct later before its declaration has been visited, then CONST_PTR reparses the fallback translation unit. Without deferral, the first unresolved pointee would retain stale libclang handles.
Queueing pointer macros, preserving their item IDs, and materializing them together in one final reparse keeps those handles valid through type resolution. I do not see a simpler safe approach that preserves typed forward-declared pointees and the existing reusable fallback translation unit.
— tamirdex
|
Regarding the earlier review question: yes, that is the expected output change. A clean review split would be:
— tamirdex |
| /// The macro name. | ||
| name: String, | ||
| /// The original macro cursor in the primary translation unit. | ||
| cursor: clang::Cursor, |
There was a problem hiding this comment.
So I guess clang::Cursors are not invalidated when reparsing, but the types are? Is that documented anywhere?
There was a problem hiding this comment.
Yes, but the distinction is which translation unit is reparsed, not cursors versus types.
Clang explicitly documents that clang_reparseTranslationUnit invalidates all cursors and source locations referring into the translation unit being reparsed: https://github.com/llvm/llvm-project/blob/8e76c3f0d29a713c41f1b3d0f19d965a504481cf/clang/include/clang-c/Index.h#L1042-L1054.
The saved PendingPointerMacro cursor comes from bindgen’s original, primary translation unit, which is never reparsed:
rust-bindgen/bindgen/ir/var.rs
Lines 250 to 260 in dd174a8
rust-bindgen/bindgen/ir/var.rs
Lines 428 to 445 in dd174a8
rust-bindgen/bindgen/ir/var.rs
Lines 504 to 528 in dd174a8
So this does not depend on a guarantee that cursors from a reparsed translation unit survive; Clang explicitly says they do not.
— tamirdex
The Clang macro fallback can evaluate macro forms that cexpr cannot parse, but it discards pointer-valued expressions. Emit data pointer macros as raw Rust pointer constants. Keep dependent expressions eligible for fallback evaluation. Materialize pointer macro types from a final fallback parse so deferred type resolution does not retain cursors invalidated by a later reparse. Related to rust-lang#3347.
dd174a8 to
deb7c08
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
The Clang macro fallback can evaluate macro forms that cexpr cannot
parse, but it discards pointer-valued expressions. Emit data pointer
macros as raw Rust pointer constants. Keep dependent expressions
eligible for fallback evaluation.
Materialize pointer macro types from a final fallback parse so
deferred type resolution does not retain cursors invalidated by a
later reparse.
Related to #3347.