[cfe-dev] Nested functions in Clang?

mats petersson via cfe-dev cfe-dev at lists.llvm.org
Sun Sep 13 14:41:24 PDT 2015


So, my code builds a closure structure, which contains pointers to the
variables shared between the nested function and the outer function.

As long as you don't need function pointers that are compatible with
function pointers without local variable usage, you don't need trampolines,
just the closure structure to pass the arguments. Or you can just pass
extra arguments with those local variables as references.

But if you want something that in C would look something like this:

void func1(void (*fptr)(int), int x)
{
    fptr(x);
}

void func2(int a)
{
    int y = a;

    void foo(int x)
    {
        printf("x=%d, y=%d\n", x, y);
    }

    func1(foo, 42);
}

void bar(int x);

int main()
{
    func1(bar);
    func2(17);
    return 0;
}

For the foo function to be compatible with bar, you need a trampoline. If
you don't have this use-case, then you just need some way to pass y into
foo.

[This is almost identical to the function in the Pascal conformance test
that I had to implement trampolines for]

--
Mats

On 13 September 2015 at 22:03, Rodney M. Bates via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> I want to avoid trampolines for two reasons.  They have to be built in
> memory that is
> both writable and executable, which has already been a problem on some
> targets.  Also,
> a debugger needs to both construct and interpret them, which creates
> difficult target
> dependencies and compiler code-generation dependencies.
>
> I intend to pass some kind of environment pointer, like a static link.
> The real question
> is, what does it point to?  As I understand, llvm locals can not be used
> outside the
> function they are created in, so using a static link from outside can't
> access the
> alloca values.  I am thinking the best way is to wrap at least up-level
> referenceable
> formals and locals  in a struct, and have the static link point to that.
> This would
> include the next outer static link.
>
> On 09/13/2015 04:39 AM, David Chisnall wrote:
>
>> On 13 Sep 2015, at 01:18, Rodney M. Bates via cfe-dev <
>> cfe-dev at lists.llvm.org> wrote:
>>
>>>
>>> Does Clang have an option that allows C nested functions, as in gcc?
>>> So far, I can't find it.  I just want to look at generated llvm IR, for
>>> ideas on the best way to produce it from another front end.
>>>
>>
>> Clang doesn’t support it, but llvm-gcc did (and DragonEgg, possibly?),
>> and this is what the trampoline intrinsics are for.  The way that GCC
>> implements it is very dangerous - it requires having an executable stack,
>> which makes various attacks significantly easier.
>>
>> The nested function approach is *only* required if you need the ability
>> for unmodified C code (or code using a C FFI) to be able to call the
>> generated functions.  If you do not have this requirement, then using an
>> explicit argument in the LLVM IR to contain the state for the closure (as
>> [Objective-]C blocks and C++ lambdas do) is probably a better option.
>>
>> David
>>
>>
>>
> --
> Rodney Bates
> rodney.m.bates at acm.org
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150913/a885a632/attachment.html>


More information about the cfe-dev mailing list