libclang types resolved as int when calling LibTooling-based shared library via Python ctypes
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
# Summary
When parsing C source code using Clang APIs, integer types are resolved correctly when using LibTooling directly in a C++ program. However, when the same LibTooling-based functionality is compiled into a shared library and invoked from Python via ctypes, all integer types are resolved as `int`.
This behavior occurs regardless of the libclang version used.
# Environment
* OS: Ubuntu 22.04
* Python version: 3.10.12
* libclang version(s) tested:
* 14.x
* 20.1.0
* LLVM/Clang: tested with LLVM 20.1.0
* Binding method: Python ctypes
# Background
Initially, I used the libclang Python API to parse C type definitions. I observed that all integer types (e.g., `short`, `long`, `unsigned long`, etc.) were reported as `int`.
I suspected this might be due to an older libclang version, so I upgraded from libclang-14 to libclang-20.1.0, but the behavior remained the same.
To further investigate, I rewrote the parsing logic using the LibTooling C++ API instead of libclang.
* When running the parsing code directly in a C++ test program, the integer types are reported correctly.
* However, when the same functionality is compiled into a shared library and invoked from Python using ctypes, the issue reappears and all integer types are reported as `int`.
# Steps to Reproduce
1. Write a C source file containing different integer type definitions, for example:
```c
typedef struct {
char field1;
short field2;
int field3;
long field4
} my_test_t;
```
2. Use a LibTooling-based C++ program to parse the types.
3. Verify that the program correctly reports the underlying types.
4. Compile the parsing logic into a shared library.
5. Call the exported functions from Python using ctypes.
6. Observe that all integer types are reported as `int`.
# Expected Behavior
The parsed types should preserve their original integer type information, such as:
* `short`
* `long`
* `unsigned long`
* `unsigned int`
# Actual Behavior
When invoked through Python ctypes, all integer types are reported as: `int`
regardless of their actual underlying type in the source code.
# Additional Notes
* The parsing logic itself appears correct since it works when executed directly in a C++ test program.
* The issue seems to appear only when the functionality is accessed via ctypes.
* The behavior is consistent across multiple libclang versions.
# Question
Could this be related to:
* ABI differences when calling from Python via ctypes
* Clang AST objects crossing shared library boundaries
* Incorrect type conversion at the FFI layer
Any guidance or suggestions for debugging this would be appreciated.
Contributor guide
Research direction
Start by reproducing the reported C type definitions with the LibTooling-based C++ program, then compare its results with the same logic compiled as a shared library and called through Python ctypes. Inspect the exported function signatures and the FFI boundary; done means short, long, and unsigned types remain distinct in the ctypes-invoked path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100