Repository navigation
[ffigen] Parse declarations inside extern "C" blocks - #3609
Conversation
liamappelbe
left a comment
There was a problem hiding this comment.
Looks good. The CI test failure looks legit tho. Also, you've got the same sync issues with verify_test_bindings as your other PRs (sorry about that). And v22 is published, so your changelog entry should go in v22.0.1-wip
eba47fb to
c29dd76
Compare
|
@liamappelbe The Linux job fails because it installs libclang-14. Before LLVM 18, libclang never reported There is a workaround but I think it's ugly: bool isLinkageSpec() {
switch (kind()) {
case clang_types.CXCursorKind.CXCursor_LinkageSpec:
return true;
case clang_types.CXCursorKind.CXCursor_UnexposedDecl:
return _firstToken() ==
(clang_types.CXTokenKind.CXToken_Keyword, 'extern');
default:
return false;
}
}
(int, String)? _firstToken() {
final tu = clang.clang_Cursor_getTranslationUnit(this);
// An empty range at the start of the extent lexes exactly one token.
final start = clang.clang_getRangeStart(extent);
final range = clang.clang_getRange(start, start);
final tokensPtr = calloc<Pointer<clang_types.CXToken>>();
final numTokensPtr = calloc<UnsignedInt>();
try {
clang.clang_tokenize(tu, range, tokensPtr, numTokensPtr);
final numTokens = numTokensPtr.value;
if (numTokens == 0) return null;
final token = tokensPtr.value.ref;
final result = (
clang.clang_getTokenKind(token),
clang.clang_getTokenSpelling(tu, token).toStringAndDispose(),
);
clang.clang_disposeTokens(tu, tokensPtr.value, numTokens);
return result;
} finally {
calloc.free(tokensPtr);
calloc.free(numTokensPtr);
}
}I'd bump the ubuntu version to |
Sounds good. You can update the |
|
There's also a line in the readme that says "LLVM (9+) must be installed...". That's a super old version. We should probably tell people to use v18+ if that's what we're testing. |
Most of this branch's C++ parsing work landed upstream as separate PRs (dart-lang#3591, dart-lang#3607, dart-lang#3608, dart-lang#3609, dart-lang#3644), so conflicts are resolved in favour of the upstream implementations. Branch-only features are kept on top: - constexpr variables and static data members: nested VarDecls are dispatched again, using qualifiedNameFromCursor, but only bound when they have a constant value (others would need a mangled-symbol lookup). - forward-declared / pointer-only classes are covered by upstream's class-as-struct fallback; the existing test still passes. - cpp_constexpr and cpp_opaque_class tests get per-test config files. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Description
In C++ mode, declarations inside an
extern "C" { ... }block are wrapped in aLinkageSpeccursor. Neither the root cursor visitor nor the USR definitionindex looked through it, so every declaration in such a block was silently
dropped, which is most of what a C++ header exposes to C. Recurse into
LinkageSpeccursors in both places. Tests cover the braced and bracelessforms and a nested linkage spec; the case inside a
namespaceneeds anamespace visitor and is left for that change.
Depends on #3607: the
verifyBindingsawait fix there is what makes thenew golden test actually compare anything. Please land that first.
Related Issues
PR Checklist
dart tool/ci.dart --alllocally and resolved all issues identified. This ensures the PR is formatted, has no lint errors, and ran all code generators. This applies to the packages part of the toplevelpubspec.yamlworkspace.CHANGELOG.mdfor the relevant packages. (Not needed for small changes such as doc typos).