<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/144337>144337</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
libclang: clang_getPointeeType dereferences typedefs to functions with calling convention attribute
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Alcaro
</td>
</tr>
</table>
<pre>
```c
// gcc -I/usr/lib/llvm-14/include/ test.c -L/usr/lib/llvm-14/lib/ -lLLVM-14 -lclang && ./a.out
#include <clang-c/Index.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
static enum CXChildVisitResult libclang_bug_inner(CXCursor cursor, CXCursor parent, CXClientData client_data)
{
enum CXCursorKind kind = clang_getCursorKind(cursor);
if (cursor.kind == CXCursor_VarDecl)
{
CXType ty = clang_getCursorType(cursor);
CXType ty_inner = clang_getPointeeType(ty);
CXString varname = clang_getCursorSpelling(cursor);
CXString tyname = clang_getTypeSpelling(ty);
CXString ty_inner_name = clang_getTypeSpelling(ty_inner);
printf("var [%s] type [%s] innertype [%s]\n",
clang_getCString(varname), clang_getCString(tyname), clang_getCString(ty_inner_name));
clang_disposeString(varname);
clang_disposeString(tyname);
clang_disposeString(ty_inner_name);
}
return CXChildVisit_Continue;
}
static void test_the_libclang_bug()
{
const char * src =
"typedef void fn1_t(void);\n"
"fn1_t* fn1;\n"
"typedef void (__attribute__((__noreturn__)) fn2_t)(void);\n"
"fn2_t* fn2;\n"
"typedef void (__attribute__((__cdecl__)) fn3_t)(void);\n"
"fn3_t* fn3;\n"
;
const char * argv[] = { "-x","c", "-target","i386-pc-windows-gnu" };
struct CXUnsavedFile input = { "input.c", src, strlen(src) };
CXIndex index = clang_createIndex(false, false);
CXTranslationUnit unit = clang_parseTranslationUnit(index, "input.c", argv, sizeof(argv)/sizeof(*argv),
&input, 1, CXTranslationUnit_None);
clang_visitChildren(clang_getTranslationUnitCursor(unit), libclang_bug_inner, NULL);
clang_disposeTranslationUnit(unit);
clang_disposeIndex(index);
}
int main() { test_the_libclang_bug(); }
```
Expected:
```
var [fn1] type [fn1_t *] innertype [fn1_t]
var [fn2] type [fn2_t *] innertype [fn2_t]
var [fn3] type [fn3_t *] innertype [fn3_t]
```
Actual:
```
var [fn1] type [fn1_t *] innertype [fn1_t]
var [fn2] type [fn2_t *] innertype [fn2_t]
var [fn3] type [fn3_t *] innertype [void (void)]
```
Tested by me on Clang/LLVM 14.0.6 (Debian), and by a friend on commit 756e7cfd86c7 (five days ago).
Context: I'm trying to parse <windows.h>, and acquire the types and names of everything. Argument names disappear if typedefs are resolved, so I need fn3_t, not void(void).
I have a functional workaround (calling clang_visitChildren, expecting a CXCursor_TypeRef, and calling clang_getCursorReferenced on that), so this isn't a blocker, but it is kinda irritating.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzUV1-P4jgS_zTmpQQKDpDkgQcmLFLr-lan2ZlRv0XGqQTfBJuzK3Rzn_5kJ-FPA7sj3dNKKCSu-lWVy66fy8I5VWvEJZt_YfP1SLS0M3a5aqSwZrQ15WnJFlH3kyxaMb5hfAO1lDB-YXzTOsv4plFb_2yO-_F0xvhGadm0JXpNQkcTCePXp8rdN4yb19cf_xxPZzBuZCN0DYwvGF_AhPGNmJiWvHsfQdybBxbnQXMsGd-86BI_JjsW_3an5KhU5pnIKl0_hW2Nac7CaOVIkJKAut1D_pbvVFP-UE7RV3RtQ9CobYin2LZ1obRGy3iav-WtdcaCDH-M53AeOgiLmvqhRqGmtSABMrwWpSDBeOZdJ19CANngOcD_oXQJP_2DxWvoPNdIFyHj6eA0Y3FvonuqCs7SyWDDmxmMFz-EXaNs-gCi7BwDi7L87dvpgECnR5696InnC7BLzy38X0ZpQuzxdLrD_hEWC47CarHHR77_OGDTKF0_99_boNO9Ce_4ysDzAIbwi1-wMeyDG0sHqzRVjKeM86Ow4IuPzx2br4F8fq6-A_zTIJvnmnHOeH62yKIM4CobXaSMp32yfAA8f6TQZeLP5FeTDWo3U-kQpXIH4_CR17_UvQTwC6qfYjkjkvX17rZIrdU3JVrkRpPSLfaYAOjr-WhUGYiqoB0W11UcluimAqXRjkDu_KrxFTgrQ-Wc14Fzv1glVp3VSk8L8gkxquwD7hfvCtErrbz2Y40bm4ynRSGIrNq2hEURgkyLQptu3n7ELxNUmnu72V_754N__n_4lyXK5sp5_IvO48F5_Egjfpx4Yetjd2aFAmTJF2Ccjz_6uuBcdm9hlIStkc4iFaeL8UGO35Uuzbsb17plnIPfE4M3R7aVBPnbd-3EEcuNahCUPrR07S4MTAZPzsrwR7ZBzXgavrMbs_lbOKZAheeFOaRFQRhkjKeVaBx6U_1LdoX_ZoV2jSBl9HetCFr_uBg6COvwkw7jqeos5_dBhzz6qNV_0XhK6gYyxjfnIcZX59GecvzhHAx57LQ7wT65LX43-ib4LsKjr8ZQlzZk6UKdt_C85--0DVMI9PTogM3h9--vr_d-eu64z8Vg76H6sAR9wrJrtmDRSmmCvVC644WwDf6MN-Iv0EOHHqoz89vHASVhyeLVJ2F_GngiuDoMAkH4bX93InTUMV9fQ_ktlD-F8jtofAuNn0LjAXod_EpSK5q_66QGbhvY6m5639ARlrA9wR7BaMj9ajO-8X0rTGeTaLLw-DVuldD9jhU6AARUVqEuPUya_V4RJPMFJrIq04VMPKxSR4RSnByI2jCeTbqt4o8t_CAWr-CF8WQPZE-hBzEQat03qj2PdY1q71TI_7TKItAOw9xdGPXnpgNTAR7Rnmjne19Y2brdo6ZeWionDgcUFlQFPfE7EBbBojPNEcvAFwZeQCOWA9HnoA1Bl7whh_0cXmAnjuiT0GrpK1E08G7sT2FNq0POpQgdEzykiBww1ItXEJcG1bdaX7EaJnxr4twRfsUKLWqJIfe0EwOXOAO0Uw6U04wnBAK2jZE_O0rZtgSKQLnQXwtQ1irfK-h6MiqXcZnFmRjhcprMoyiZxVE62i0Xks-TuYiihcR0xlNecV5hlJXz2SyL5ulILXnE59FiuphOZ_MomeA8SaIqTitZJdNZydkswr1QzcRfjibG1iPlXIvL6WwWx8moEVtsXLipca7xHYLU8_h8PbLLcKPatrVjs6hRjtzFDClqcDkQlN9Lj5puKNEO2XKXlSdzXjcH74p2l1QbfUTtBXBuB0atbZY7ooPzPBBui7WiXbudSLPv733D9e9gzb9Rkr8w-pk4xjf9VI9L_r8AAAD__wm1hcc">