get function parameters (not arguments)

Hi Everyone,

Does anyone know to get function parameters? For example, I want to get e and f in the call to function foo in the following code:

foo(inr a , int b){

}

main() {

int e,f;

e=10;

f=22;

foo(e,f);
}

I use the following code:

for (auto& A : (cast(BI))->arg_operands ()) errs() << A.dump();

but I get a and b instead.

Thank you and best

This sounds really weird. If you're analyzing a CallInst in main, %a
and %b shouldn't even be available. Can you show us your actual IR and
output?

Cheers.

Tim.

Sorry i’m using the following code:

F = (cast(BI))->getCalledFunction();

for (auto& A : F->getArgumentList()) {

errs() << "------- " << A.getName() << " " << “11” << “\n”;
}

But how can I get the parameters (as e and f in the example)?

Thank you and best,

Mo

The code you originally posted (using
cast<CallInst>(BI)->arg_operands()) should iterate through the
arguments to the call.

Cheers.

Tim.

I tried the original posted code again:

for (auto& A : cast(BI)->arg_operands())

errs() << "— " << A->getName() << “\n”;

but it prints empty (only —)!

Thank you and best,

Mo

Ah, I see. You actually want "e" as a name. Unforuntately this isn't
possible in general for a few reasons.

First, release builds of LLVM drop most Value names for efficiency
reasons. Without optimization your IR would just have numbers in the
arg position: "call void @foo(i32 %3, i32 %4)". Even those numbers
don't exist in memory, but are constructed as needed.

Another confounding factor is that optimization will turn even that
into a plain "call void @foo(i32 10, i32 22)" with no record of what
the original arguments were.

It gets even worse at the C level. If you saw "foo(a + b)", that
argument doesn't really have a natural name. It's a temporary
expression.

So in general you shouldn't be relying on the name for any actual
transformation you do.

For debugging there are usually alternatives that might not be quite
so convenient but do the job: Just dumping the argument is usually
sufficient; with heroic effort you might be able to use any debug info
that's present.

Cheers.

Tim.

what about the memory address of e and f? can i get them?

Thank you and best,

Mo

Not in general, again. After optimizations they probably won't even
have a fixed memory address. For example on AArch64 that code might
become something like:

    main:
        mov w0, #10
        mov w1, #22
        bl foo
        ret

Where e and f only ever exist in registers.

In some cases you might get lucky and see that the Value used in the
call came from a load instruction, and then you could get its address
from that. But it's not something you can rely on for correctness.

Cheers.

Tim.

What if I use -O0? In this case, there should be a load for each parameter before the function call, yes?

Thank you and best,

Mo

You hit the "foo(e+f)" problem again. That parameter won't necessarily
have an address even at -O0.

There will be other mismatches between the C and IR too. For example
large structs might be passed by pointer directly.

Cheers.

Tim.