Fix: emit extern "C" fn for functions declared in extern "C" blocks#4210
Merged
Fix: emit extern "C" fn for functions declared in extern "C" blocks#4210
extern "C" fn for functions declared in extern "C" blocks#4210Conversation
Functions declared inside `extern "C" { }` blocks in C++ headers were
being collected but emitted with `extern fn` (defaulting to the
`system`/PlatformApi calling convention) instead of the correct
`extern "C" fn` (C/cdecl calling convention).
Fix:
- Add `extern_c: bool` field to `RdlFn`
- Detect C language linkage via `Entity::get_language() == Some(Language::C)`
when in C++ mode
- Pass the flag through `collect_function()` and emit `extern \"C\" fn`
in `emit_fn()` when the flag is set
Add a new test case (`fn_extern_c.h` + golden `.rdl`) that exercises
`extern \"C\" { }` blocks.
Update `webview2.rdl` golden file since WebView2 functions are also
declared inside `extern \"C\"` blocks and now correctly emit `extern \"C\" fn`.
Agent-Logs-Url: https://github.com/microsoft/windows-rs/sessions/ec069672-f3b6-4b00-8f4c-bcc4140be864
Co-authored-by: riverar <475132+riverar@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix extern "C" functions handling in RDL generation
Fix: emit Apr 18, 2026
extern "C" fn for functions declared in extern "C" blocks
riverar
requested changes
Apr 18, 2026
Collaborator
riverar
left a comment
There was a problem hiding this comment.
Do not change the header2rdl crate. Focus on crates/libs/rdl instead. Start over.
…ates/libs/rdl)
Functions declared inside `extern "C" { }` blocks were being ignored
entirely because `process_tu` in `crates/libs/rdl/src/clang/mod.rs`
did not handle `CXCursor_LinkageSpec` nodes.
Fix in `crates/libs/rdl/src/clang/`:
- `cx.rs`: Add `Cursor::language()` wrapping `clang_getCursorLanguage`
- `fn.rs`: Add `extern_c: bool` to `Fn`; pass flag through `parse()`;
emit `extern \"C\" fn` in `write()` when set (using conditional quote)
- `mod.rs`: Pass `extern_c = false` for top-level `FunctionDecl`;
add `CXCursor_LinkageSpec` arm that recurses into children and
sets `extern_c = (language == CXLanguage_C)` for each `FunctionDecl`
Also reverts the previous (incorrect) changes to `crates/tools/header2rdl/`.
New test: `crates/tests/libs/clang/roundtrip/fn_extern_c.h` / `.rdl`
Agent-Logs-Url: https://github.com/microsoft/windows-rs/sessions/57f06e7c-6509-4233-97cc-bd5ad23a4b08
Co-authored-by: riverar <475132+riverar@users.noreply.github.com>
Contributor
Author
Done. Rewrote the fix in
Reverted all |
riverar
requested changes
Apr 18, 2026
Agent-Logs-Url: https://github.com/microsoft/windows-rs/sessions/344f46c0-760b-4525-9d44-0c2824482ddb Co-authored-by: riverar <475132+riverar@users.noreply.github.com>
riverar
approved these changes
Apr 18, 2026
Collaborator
|
@copilot Address the build failure here. |
Agent-Logs-Url: https://github.com/microsoft/windows-rs/sessions/006f8c3b-a872-4fe5-b70a-413e3219119e Co-authored-by: riverar <475132+riverar@users.noreply.github.com>
Contributor
Author
riverar
requested changes
Apr 18, 2026
Co-authored-by: riverar <475132+riverar@users.noreply.github.com>
riverar
approved these changes
Apr 18, 2026
kennykerr
approved these changes
Apr 18, 2026
Copilot AI
added a commit
that referenced
this pull request
Apr 20, 2026
…4210) Co-authored-by: kennykerr <9845234+kennykerr@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Functions declared inside
extern "C" { }blocks in C++ headers were being entirely ignored — not collected at all — becauseprocess_tuincrates/libs/rdl/src/clang/mod.rsdid not handleCXCursor_LinkageSpecnodes. Additionally, when such functions are collected, they must be emitted withextern "C" fn(cdecl) rather thanextern fn(system/stdcall ABI) to correctly represent their calling convention.All changes are scoped to
crates/libs/rdl.Changes
crates/libs/rdl/src/clang/cx.rsCursor::language()wrappingclang_getCursorLanguagefrom clang-syscrates/libs/rdl/src/clang/fn.rsextern_c: booltoFnto track C-linkage originparse()to accept theextern_cflagwrite()to emitextern "C" fn(via conditionalquote!) whenextern_cis setcrates/libs/rdl/src/clang/mod.rsextern_c = falsefor top-levelCXCursor_FunctionDeclitemsCXCursor_LinkageSpecarm that recurses into the block's children and collects any containedFunctionDeclwithextern_c = (language == CXLanguage_C)New test:
crates/tests/libs/clang/roundtrip/fn_extern_c.h/.rdl— round-trip coverage forextern "C" { }blocksExample
Input header (C++ mode):
Before:
After: