Get pointee type from an opaque pointer type in function argument


I need to get pointee type for a function argument:

void test(int arr[], int n) {

Here, the first argument has an opaque pointer type, but how can I get pointee type for it (i.e. i32)? Opaque pointers have PointeeTy set to nullptr.

In this article Opaque Pointers — LLVM 16.0.0git documentation I didn’t find any hints about function arguments.


This is not possible. Can you please provide some more context on why you need this?

If this is for optimization purposes, then what you usually want to do instead is look at how the pointer is used, i.e. the type of the load/store/etc instructions using the pointer.

Thanks for your response, nikic. It is sad that I can’t do that. Then I guess, I can use -no-opaque-pointers option or CLANG_ENABLE_OPAQUE_POINTERS macro. But I also guess that it is bad practice, isn’t it? I mean that non-opaque pointers are deprecated.

I need it for emitting some extra metadata file about function signature. Specifically, it is EVM ABI file, which contains information about each function parameter: name and type.

In that case, @jcranmer may have some advice for you. I believe the way they are handling this for SPIR-V is to demangle the function name and take the type information from there.

you might be able to take type information from the DWARF too - not all functions are mangled, for instance - but if that covers your use case, it might be fine/the better option (more reliable/always available compared to DWARF).

If you can generate it from the frontend instead it might be more long-term reliable.

When it comes to getting the pointer element types, there’s a variety of techniques depending on how important it is that the pointer type information be precisely correct and whether or not type punning is acceptable.

If your goal is to precisely get C/C++ source information… well, trying to extract that information from LLVM IR is not a great idea at all :blush:.

As much as you can, it is generally best to get the type information from the actual use of pointer types (e.g., the types on load and store instructions), and be prepared to handle to the need to insert pointer cast instructions (i.e., what would be bitcasts in LLVM IR with typed pointers) as necessary. Scavenging types in this way is pretty straightforward, at least until you get to pointer-to-pointer types.

Function calls do present interesting complications, but in what I’ve done for SPIR-V, most of the relevant function calls are builtins to Itanium-mangled function names using a relatively limited set of mangled names, which means using the existing Itanium demangler is a workable solution. Even then, where the pointer types are truly important, I’m working on moving these types from being pointer-to-opaque-struct-types to target extension types which fixes some cases where the types get too horribly mangled by the optimizer. A lot of the approach I use still relies on giving up and saying a ptr is really an i8* if you don’t know any better is usually sufficient.

There are other ways to get type information other than demangling functions. @dblaikie suggested the use of DWARF debug information. Some metadata might prove able to scavenge type information (for example, TBAA metadata may have a garbled version of type information). Attacking from the frontend directly is going to be far more accurate in any case than recovering it from the LLVM IR.

But in general, if the question is “how do you get pointee type from LLVM IR?”, the best answer remains “try at all costs to find a way not to need to do this.”

Thank you guys! I’ll investigate these two approaches: DWARF and Frontend+metadata. The second one though looks more promising for me.