Parser: fully qualify the declarations mentioned in default arguments - #41
Open
Fedr wants to merge 1 commit into
Open
Parser: fully qualify the declarations mentioned in default arguments#41Fedr wants to merge 1 commit into
Fedr wants to merge 1 commit into
Conversation
Stmt::printPretty() prints DeclRefExprs only with the qualifiers written in the source (PrintingPolicy::FullyQualifiedName only affects types), so e.g. a default argument `= npos` written inside `class MR::BitSet` was emitted as bare `npos` into the generated bindings, which are outside of the original scope. The existing `using namespace` workaround can't help for class-scope members like this one. Now `DefaultArgument::as_cpp_expression` is printed with a PrinterHelper that replaces every DeclRefExpr with the fully qualified name of the referenced declaration (`::MR::BitSet::npos`), unless it's a template parameter, function-local, or enclosed in an unnamed scope, in which cases the old behavior is kept. `original_spelling` is unchanged (as written). Also fixes a bug in the newline-removal loop, which replaced the entire accumulated string with a single space (`new_str = ' '`) instead of appending it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.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.
Problem
Stmt::printPretty()prints aDeclRefExpronly with the qualifiers that were written in the source —PrintingPolicy::FullyQualifiedNameaffects types, not value references. Since the printed default argument is inserted into the generated bindings, which live outside of the original scope, any unqualified name breaks the build of the generated code.The existing workaround (
default_arguments_need_using_namespace+using namespacein the generated wrappers) rescues namespace-scope names, but cannot rescue class-scope names: ausing namespacecan't re-enter a class scope. Practical example from MeshLib (MeshLib#6507):generated
MRCMesh/MRBitSet.cppfailed witherror: 'npos' was not declared in this scopeon every platform, and the header had to spell the default asMR::BitSet::nposto work around it.Fix
DefaultArgument::as_cpp_expressionis now printed via aclang::PrinterHelperhook that prints everyDeclRefExpras the fully qualified name of the referenced declaration (with a leading::), plus its explicit template arguments if any. The default printing is kept for declarations that can't be named from the global scope:using namespaceworkaround still applies, so I leftdefault_arguments_need_using_namespaceuntouched.original_spellingis intentionally unchanged (still as-written) — it's used for comments and the nullptr-uselessness heuristics.Drive-by: fixed the newline-removal loop, which did
new_str = ' '(clobbering the accumulated string) instead ofnew_str += ' '.Effect on generated code
Tests
Added
DefaultArgsMentioningMemberstotest/input/MR/test_static_memberr.handtest/input_py/MR/1.h: a static constexpr member, a nested enum constant, and a compound expression (limit + 1 - A::x), all referenced without qualification from default arguments.Verified locally (Windows, MSYS2 CLANG64, clang 22.1.4):
make_c.shoutput between stock and patched parser shows only the intended qualification changes (intest_csharp,test_simple_types,test_static_memberr,test_std_optional,test_std_shared_ptr,test_std_unique_ptrsources, same for the fixed-typedefs variants);clang++ -fsyntax-only -pedantic-errors.Note: I did not commit regenerated
test/output_*goldens — on Windows they come out platform-flavored (e.g.std_vector_long/std_vector_unsigned_longare replaced bylong longvariants, and the final link oflibblehfails for pre-existing platform reasons), so they need the usual regeneration on Linux. Sorry for the extra step.Unrelated observation from testing: when the parse ends with a fatal error (e.g. standard headers not found), the parser still proceeds and then dies with
Too many template instantiation iterations!on the broken AST — bailing out early onDiags.hasErrorOccurred()would give a clearer failure. Happy to file/fix separately if useful.