fix(tool): header parsing fails when prerequisite includes are supplied by the C consumer
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 64/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Área
- developer-experience, tooling
Línea de trabajo
Start with listHeaderFiles and ParseSources in tool/gen.go, which sort selected headers and invoke ParseTranslationUnit separately for each one. Reproduce with the two listed glibc headers and the documented llcppg command, then use the composed rose-entry.h control to compare field types and exit behavior. Done means prerequisite declarations are visible when parsing context-dependent headers, the generated fields retain their native types, and generation fails when the selected inputs still produce parse errors.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
The prerequisite #include can be supplied by the consuming .c file while being absent from the .h file itself. llcppg currently parses the .h independently, so it does not have the declarations that are already visible when that header is included by a correctly composed C source file.
The difference between compiling the C consumer and parsing its header
For glibc 2.24, this minimal consumer illustrates the required include context:
/* consumer.c — minimal reproduction, not an upstream source excerpt */
#include <netax25/ax25.h>
#include <netrose/rose.h>
The .c includes netax25/ax25.h first. This provides ax25_address, AX25_MAX_DIGIS, and, through bits/sockaddr.h, sa_family_t. When Clang then expands netrose/rose.h inside the same translation unit, those declarations are already visible.
The installed netrose/rose.h itself does not contain that prerequisite include. It uses these names and documents its requirement for ax25.h, relying on the includer to establish the context. The include sequence above passes the recorded C syntax check.
llcppg instead takes netrose/rose.h directly as a translation unit's main input. It does not parse a consuming .c file with the preceding include, nor does listing ax25.h separately in Files put its declarations into that translation unit. Consequently, a header that works when included by the C consumer reports unknown types when parsed in isolation.
The observed downstream result is also incorrect: llcppg returns success and emits sockaddr_rose fields as c.Int where the native declarations require sa_family_t and ax25_address.
Reproduction
Use the Bootlin glibc 2.24 Linux arm64 headers under source/linux-arm64/include, with a source Go module requiring github.com/goplus/lib v0.7.0. The relevant configuration is:
{
"Name": "libc",
"Language": "c",
"Dir": "$GOOS-$GOARCH/include",
"Files": [
"netax25/ax25.h",
"netrose/rose.h"
],
"FailFast": 0,
"IgnoreInline": true
}
Leave Stdlib unset. In the tested Linux container, Clang's builtin headers and the staged glibc headers were selected with:
GOOS=linux GOARCH=arm64 \
C_INCLUDE_PATH="/usr/lib/llvm-22/lib/clang/22/include:$PWD/source/linux-arm64/include" \
llcppg ./generated ./source
This two-header reproduction emits 13 Clang errors, including:
netrose/rose.h:71:3: error: unknown type name 'sa_family_t'
netrose/rose.h:73:3: error: unknown type name 'ax25_address'
netrose/rose.h:94:28: error: use of undeclared identifier 'AX25_MAX_DIGIS'
All definitions are present in the staged include tree. netax25/ax25.h defines ax25_address and AX25_MAX_DIGIS, and includes bits/sockaddr.h, which defines sa_family_t. netrose/rose.h does not include ax25.h; its comment explicitly states that it requires that header.
The command nevertheless exits 0 and emits recovered, incorrect fields:
type SockaddrRose struct {
SroseFamily c.Int
SroseAddr RoseAddress
SroseCall c.Int
SroseNdigis c.Int
SroseDigi c.Int
}
Why ordering Files does not help
At the tested revision, listHeaderFiles and ParseSources sort the input paths and call ParseTranslationUnit separately for each header. Even though ax25.h is parsed first, its declarations are not available when Clang independently parses rose.h.
Clang is correct to reject that standalone input. An include search path only locates files named by #include; it does not load declarations automatically or resolve unknown type names by searching sibling headers.
Verified workaround
Create a single input rose-entry.h containing:
#include <netax25/ax25.h>
#include <netrose/rose.h>
Select only rose-entry.h in Files. With the same native headers and toolchain, generation exits 0 with no diagnostics, and the resulting fields use the declared types:
type SockaddrRose struct {
SroseFamily SaFamilyT
SroseAddr RoseAddress
SroseCall Ax25Address
SroseNdigis c.Int
SroseDigi Ax25Address
}
Related C parsing controls also pass when rpcsvc/nislib.h is reached through rpcsvc/nis.h, and when stdint.h precedes scsi/scsi_bsg_fc.h, scsi/scsi_netlink.h, or scsi/scsi_netlink_fc.h. Only the ROSE example above was compared through full llcppg generation in this focused reproduction.
Expected behavior
- Parse prerequisite-dependent headers with the declarations required by their native include contract visible, and preserve the actual field types shown by the composed-input control.
- If the selected inputs do not establish a valid include context, report the original parse errors and fail generation. Do not return success or emit bindings from the erroneous recovered declarations.
- Preserve the native API; removing the affected declarations or changing the installed headers is not a fix.
The composed entry header above is a verified workaround for this bug. The report does not prescribe a new configuration field, public API, or automatic ordering algorithm.
Related issues
#997 covers recursive discovery of context-dependent implementation headers; this reproduction uses an explicit two-file list. #998 concerns preprocessing arguments and include roots; here the files are already reachable. #1137 covers failure handling for fatal parse diagnostics; this case demonstrates ordinary unknown-type errors followed by successful generation of incorrect field types.
Reproduced with llcppg 90bd72cfb16ac56750116353b76ee9e6bf2ae892, LLVM/libclang 22.1.8 and LLGo 1.0.8 on Linux arm64. These are parser/generator results; no LLGo build, runtime, or ABI validation is claimed.
- Lenguaje dominante
- Go
- Estrellas
- 40
- Forks
- 13
- Merge medio
- 2 h 4 min
- PR fusionados (30 d)
- 143
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de goplus/llcppg
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 6/100
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 70/100
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 38/100
goplus/llcppg#1136 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
Todos los issues de goplus/llcppg
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
riverqueue/river#1576 ·
Los mantenedores suelen responder en 1 día
-
NFS StorageProvider renders a missing nfsSubDir as "<no value>"Posiblemente ocupada @ldming la tomó hoy. Abiertokind/bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
apecloud/kubeblocks#11067 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
emersion/go-msgauth#87 ·
-
CLI: `describe <ns>.<table>` reports "namespace does not exist" when only the table is missingPosiblemente ocupada @Shruthirdy la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
apache/iceberg-go#2423 ·
Los mantenedores suelen responder en 2 días
-
Add tests for CSV email parsingAbiertogood first issue help wanted
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
mafzalkalwardev/mailforge#21 ·