feat(extraction): universal recovery of macro-mangled C/C++ function names (#1102)

* feat(extraction): universal recovery of macro-mangled C/C++ function names

The curated inline-macro blank list (#1100/#1101) can't enumerate every
library's macro. Add a universal post-parse net so a function is findable by
name regardless of which macro decorates it, plus a batch of common libraries
to the curated list for full name+return-type recovery.

- recoverMangledCppName: after extraction, recover the real identifier from a
  name still mangled by an un-blanked macro (`MACRO Ret name(…)` misparses to
  "Ret name"). It's a new `recoverMangledName` extractor hook wired only onto
  C/C++, applied to every name they produce. Safe by construction: it only
  touches an already-mangled name (an internal space that isn't a legit
  `operator …`/destructor), so a clean name is returned unchanged; guarded
  against the `Ret (name)` parenthesized-name idiom and bare primitives. Scoped
  to C/C++ so Kotlin/Scala backtick identifiers (which legitimately contain
  spaces) are never touched.
- Curated list extended past UE/pugixml/Godot/Boost to Qt (Q_INVOKABLE, …),
  Folly, Abseil, LLVM, V8, Eigen, and rapidjson.

Validated on CARLA (large UE project, 1131 C++/h files) vs the pre-fix baseline:
function-name mangles 440 -> 6, 431 fixed, and — critically — 0 regressions
(the salvage also recovers names that the pre-parse's own non-local error-recovery
shifts would otherwise re-mangle, erasing the 7 shifts seen in #1101). The 6
residual are all the moodycamel `Ret (name)` idiom, correctly left alone. On a
made-up macro with no list entry (`WEBKIT_EXPORT WTFString compute()`), the name
`compute` is still recovered. Full suite green; eleven regression/safety tests added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* docs(changelog): note universal C++ macro-mangled name recovery (#1102)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Colby Mchenry
2026-07-01 09:29:20 -05:00
committed by GitHub
co-authored by Claude Opus 4.8
parent a164ceae8b
commit cb20a3bf7f
5 changed files with 122 additions and 1 deletions
+10
View File
@@ -133,6 +133,16 @@ export interface LanguageExtractor {
/** Override symbol name extraction (e.g. ObjC multi-part selectors). */
resolveName?: (node: SyntaxNode, source: string) => string | undefined;
/**
* Post-process an already-extracted name to recover a real identifier from a
* name still mangled by a macro the pre-parse didn't blank (C/C++:
* `MACRO Ret name(` misparses to the name "Ret name"). Applied to every name
* this extractor produces, so it MUST be a no-op on a well-formed name — only
* C/C++ set it, because a mangled name there is unambiguous (an internal space),
* whereas e.g. Kotlin/Scala backtick identifiers legitimately contain spaces.
*/
recoverMangledName?: (name: string) => string;
/** Extract property name when the generic name walk fails (e.g. ObjC @property). */
extractPropertyName?: (node: SyntaxNode, source: string) => string | null;