Issue 144337
Summary libclang: clang_getPointeeType dereferences typedefs to functions with calling convention attribute
Labels new issue
Assignees
Reporter Alcaro
    ```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 =
		"" 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.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to