/**
 * D header file for C99.
 *
 * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stdarg.h.html, _stdarg.h)
 *
 * Copyright: Copyright Digital Mars 2000 - 2020.
 * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
 * Authors:   Walter Bright, Hauke Duden
 * Standards: ISO/IEC 9899:1999 (E)
 * Source: $(DRUNTIMESRC core/stdc/_stdarg.d)
 */

module core.stdc.stdarg;

@nogc:
nothrow:

version (GNU)
    public import core.internal.vararg.gnu;
else:

version (X86_64)
{
    version (Windows) { /* different ABI */ }
    else version = SysV_x64;
}

version (SysV_x64)
{
    static import core.internal.vararg.sysv_x64;
}

version (ARM)     version = ARM_Any;
version (AArch64) version = ARM_Any;
version (MIPS32)  version = MIPS_Any;
version (MIPS64)  version = MIPS_Any;
version (PPC)     version = PPC_Any;
version (PPC64)   version = PPC_Any;
version (RISCV32) version = RISCV_Any;
version (RISCV64) version = RISCV_Any;

version (ARM_Any)
{
    // Darwin uses a simpler varargs implementation
    version (OSX) {}
    else version (iOS) {}
    else version (TVOS) {}
    else version (WatchOS) {}
    else:

    version (ARM)
    {
        version = AAPCS32;
    }
    else version (AArch64)
    {
        version = AAPCS64;
        static import core.internal.vararg.aapcs64;
    }
}


T alignUp(size_t alignment = size_t.sizeof, T)(T base) pure
{
    enum mask = alignment - 1;
    static assert(alignment > 0 && (alignment & mask) == 0, "alignment must be a power of 2");
    auto b = cast(size_t) base;
    b = (b + mask) & ~mask;
    return cast(T) b;
}

unittest
{
    assert(1.alignUp == size_t.sizeof);
    assert(31.alignUp!16 == 32);
    assert(32.alignUp!16 == 32);
    assert(33.alignUp!16 == 48);
    assert((-9).alignUp!8 == -8);
}


version (BigEndian)
{
    // Adjusts a size_t-aligned pointer for types smaller than size_t.
    T* adjustForBigEndian(T)(T* p, size_t size) pure
    {
        return size >= size_t.sizeof ? p :
            cast(T*) ((cast(void*) p) + (size_t.sizeof - size));
    }
}


/**
 * The argument pointer type.
 */
version (SysV_x64)
{
    public import core.internal.vararg.sysv_x64 : va_list, __va_list, __va_list_tag;
}
else version (AAPCS32)
{
    alias va_list = __va_list;

    // need std::__va_list for C++ mangling compatibility (AAPCS32 section 8.1.4)
    extern (C++, std) struct __va_list
    {
        void* __ap;
    }
}
else version (AAPCS64)
{
    alias va_list = core.internal.vararg.aapcs64.va_list;
    version (DigitalMars)
        public import core.internal.vararg.aapcs64 : __va_list, __va_list_tag;
}
else version (RISCV_Any)
{
    // The va_list type is void*, according to RISCV Calling Convention
    // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc
    alias va_list = void*;
}
else
{
    alias va_list = char*; // incl. unknown platforms
}


/**
 * Initialize ap.
 * parmn should be the last named parameter.
 */
version (LDC)
{
    pragma(LDC_va_start)
    void va_start(T)(out va_list ap, ref T parmn) @nogc;
}
else version (DigitalMars)
{
    version (X86)
    {
        void va_start(T)(out va_list ap, ref T parmn)
        {
            ap = cast(va_list) ((cast(void*) &parmn) + T.sizeof.alignUp);
        }
    }
    else
    {
        void va_start(T)(out va_list ap, ref T parmn); // intrinsic; parmn should be __va_argsave for non-Windows x86_64 targets
    }
}


/**
 * Retrieve and return the next value that is of type T.
 */
T va_arg(T)(ref va_list ap)
{
    version (X86)
    {
        auto p = cast(T*) ap;
        ap += T.sizeof.alignUp;
        return *p;
    }
    else version (Win64)
    {
        // LDC passes slices as 2 separate 64-bit values, not as 128-bit struct
        version (LDC) enum isLDC = true;
        else          enum isLDC = false;
        static if (isLDC && is(T == E[], E))
        {
            auto p = cast(T*) ap;
            ap += T.sizeof;
            return *p;
        }
        else
        {
            // passed indirectly by value if > 64 bits or of a size that is not a power of 2
            static if (T.sizeof > size_t.sizeof || (T.sizeof & (T.sizeof - 1)) != 0)
                auto p = *cast(T**) ap;
            else
                auto p = cast(T*) ap;
            ap += size_t.sizeof;
            return *p;
        }
    }
    else version (SysV_x64)
    {
        return core.internal.vararg.sysv_x64.va_arg!T(ap);
    }
    else version (AAPCS32)
    {
        // AAPCS32 section 6.5 B.5: type with alignment >= 8 is 8-byte aligned
        // instead of normal 4-byte alignment (APCS doesn't do this).
        if (T.alignof >= 8)
            ap.__ap = ap.__ap.alignUp!8;
        auto p = cast(T*) ap.__ap;
        version (BigEndian)
            static if (T.sizeof < size_t.sizeof)
                p = adjustForBigEndian(p, T.sizeof);
        ap.__ap += T.sizeof.alignUp;
        return *p;
    }
    else version (AAPCS64)
    {
        return core.internal.vararg.aapcs64.va_arg!T(ap);
    }
    else version (ARM_Any)
    {
        auto p = cast(T*) ap;
        version (BigEndian)
            static if (T.sizeof < size_t.sizeof)
                p = adjustForBigEndian(p, T.sizeof);
        ap += T.sizeof.alignUp;
        return *p;
    }
    else version (PPC_Any)
    {
        /*
         * The rules are described in the 64bit PowerPC ELF ABI Supplement 1.9,
         * available here:
         * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#PARAM-PASS
         */

        // Chapter 3.1.4 and 3.2.3: alignment may require the va_list pointer to first
        // be aligned before accessing a value
        if (T.alignof >= 8)
            ap = ap.alignUp!8;
        auto p = cast(T*) ap;
        version (BigEndian)
            static if (T.sizeof < size_t.sizeof)
                p = adjustForBigEndian(p, T.sizeof);
        ap += T.sizeof.alignUp;
        return *p;
    }
    else version (LoongArch64)
    {
        auto p = cast(T*) ap;
        ap += T.sizeof.alignUp;
        return *p;
    }
    else version (MIPS_Any)
    {
        auto p = cast(T*) ap;
        version (BigEndian)
            static if (T.sizeof < size_t.sizeof)
                p = adjustForBigEndian(p, T.sizeof);
        ap += T.sizeof.alignUp;
        return *p;
    }
    else version (RISCV_Any)
    {
        static if (T.sizeof > (size_t.sizeof << 1))
            auto p = *cast(T**) ap;
        else
        {
            static if (T.alignof == (size_t.sizeof << 1))
                ap = ap.alignUp!(size_t.sizeof << 1);
            auto p = cast(T*) ap;
        }
        ap += T.sizeof.alignUp;
        return *p;
    }
    else
        static assert(0, "Unsupported platform");
}


/**
 * Retrieve and store in parmn the next value that is of type T.
 */
void va_arg(T)(ref va_list ap, ref T parmn)
{
    parmn = va_arg!T(ap);
}


/**
 * End use of ap.
 */
version (LDC)
{
    pragma(LDC_va_end)
    void va_end(va_list ap);
}
else version (DigitalMars)
{
    void va_end()(va_list ap) {}
}


/**
 * Make a copy of ap.
 */
version (LDC)
{
    pragma(LDC_va_copy)
    void va_copy(out va_list dest, va_list src);
}
else version (DigitalMars)
{
    version (SysV_x64)
    {
        void va_copy(out va_list dest, va_list src, void* storage = alloca(__va_list_tag.sizeof))
        {
            // Instead of copying the pointers, and aliasing the source va_list,
            // the default argument alloca will allocate storage in the caller's
            // stack frame.  This is still not correct (it should be allocated in
            // the place where the va_list variable is declared) but most of the
            // time the caller's stack frame _is_ the place where the va_list is
            // allocated, so in most cases this will now work.
            dest = cast(va_list) storage;
            *dest = *src;
        }

        import core.stdc.stdlib : alloca;
    }
    else
    {
        void va_copy(out va_list dest, va_list src)
        {
            dest = src;
        }
    }
}
