llvm / llvm/llvm-project

libclang types resolved as int when calling LibTooling-based shared library via Python ctypes

Open
#186,739 0 comments 0 reactions 0 assignees View on GitHub
clang:as-a-library clang:tooling
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.