Skip to content

Detect export-macro class/struct .h headers as C++, not C (#1159)#1175

Open
nftmago wants to merge 1 commit into
colbymchenry:mainfrom
nftmago:pr-cpp-macro-1159
Open

Detect export-macro class/struct .h headers as C++, not C (#1159)#1175
nftmago wants to merge 1 commit into
colbymchenry:mainfrom
nftmago:pr-cpp-macro-1159

Conversation

@nftmago

@nftmago nftmago commented Jul 5, 2026

Copy link
Copy Markdown

Fixes #1159.

Problem

A .h whose only C++ tell is an all-caps export/visibility macro between the keyword and the type name — the ubiquitous Unreal Engine / library form class ENGINE_API Foo : public Bar — was classified as C by looksLikeCpp. Parsed with the C grammar, the whole class definition (node, members, base clause) never materialized in the graph, breaking type-hierarchy, callers, and blast-radius queries through that type.

This sits one step upstream of the existing #1061 export-macro blanking: that recovery never runs, because detection has already routed the header to C.

Note the issue's minimal repro also has public:, which looksLikeCpp already catches via another branch — so the truly-failing case is a macro class carrying no other C++ tell in the first 8 KB. Confirmed empirically before/after:

class ENGINE_API Foo : public Bar { void Tick(); };   // before: c   after: cpp
struct CORE_API Widget : Base { int n; };             // before: c   after: cpp
struct Point { int x; int y; };                        // before: c   after: c  (guard)

Fix

looksLikeCpp's class/struct signal now tolerates an optional all-caps macro between the keyword and the name. struct is matched only in its base-clause form (struct X : Base) — that : is C++-exclusive, whereas a plain struct X { … } is valid C and must stay c.

Tests

Added to extraction.test.ts: detection for macro class (with/without base) and macro struct; regression guards (plain class:base stays cpp, plain C struct{} stays c); and an end-to-end case proving a macro-only header now recovers the class node and its extends edge (detection + #1061 blanking together).

Full suite green (124 files, 2121 passed).

…ry#1159)

A `.h` whose only C++ tell is an all-caps export macro between the
keyword and the type name — the ubiquitous UE / library form
`class ENGINE_API Foo : Base` — was misclassified as C by looksLikeCpp,
so the file fell back to the C grammar and its whole class definition
(node, members, base clause) vanished from the graph. The existing
colbymchenry#1061 macro-blanking never got a chance to run because detection had
already routed the header to C, one step upstream.

- looksLikeCpp: the class/struct signal now tolerates an optional
  all-caps macro between the keyword and the name. `struct` is matched
  only in its base-clause form (`struct X : Base`) — that `:` is
  C++-exclusive, whereas plain `struct X { … }` is valid C and stays C.
- Tests: detection for macro class (with/without base), macro struct,
  plus regression guards (plain class:base stays cpp, plain C struct{}
  stays c); and an end-to-end case proving a macro-only header now
  recovers the class node and its `extends` edge.

Verified: full vitest suite green (124 files, 2121 passed).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UE-style single-line export-macro class headers (class ENGINE_API Foo : public Bar) are misdetected as C and their class definitions are dropped

1 participant