/*
REQUIRED_ARGS: -HC -c -o-
PERMUTE_ARGS:
TEST_OUTPUT:
---
// Automatically generated by Digital Mars D Compiler

#pragma once

#include <stddef.h>
#include <stdint.h>


struct S;
struct Inner;

struct S
{
    int8_t a;
    int32_t b;
    int64_t c;
    S() :
        a(),
        b(),
        c()
    {
    }
};

struct S2
{
    int32_t a;
    int32_t b;
    int64_t c;
    S2(int32_t a);
    S2() :
        a(42),
        b(),
        c()
    {
    }
};

struct S3
{
    int32_t a;
    int32_t b;
    int64_t c;
    extern "C" S3(int32_t a);
    S3() :
        a(42),
        b(),
        c()
    {
    }
};

struct S4
{
    int32_t a;
    int64_t b;
    int32_t c;
    int8_t d;
    S4() :
        a(),
        b(),
        c(),
        d()
    {
    }
};

#pragma pack(push, 1)
struct Aligned
{
    int8_t a;
    int32_t b;
    int64_t c;
    Aligned(int32_t a);
    Aligned() :
        a(),
        b(),
        c()
    {
    }
};
#pragma pack(pop)

struct A
{
    int32_t a;
    S s;
    extern "C" void bar();
    void baz(int32_t x = 42);
    struct
    {
        int32_t x;
        int32_t y;
    };
    union
    {
        int32_t u1;
        char u2[4$?:32=u|64=LLU$];
    };
    struct Inner
    {
        int32_t x;
        Inner() :
            x()
        {
        }
    };

    typedef Inner I;
    class C;

    A() :
        a(),
        s()
    {
    }
};
---
*/

/*
StructDeclaration has the following issues:
  * align different than 1 does nothing; we should support align(n), where `n` in [1, 2, 4, 8, 16]
  * align(n): inside struct definition doesn’t add alignment, but breaks generation of default ctors
  * default ctors should be generated only if struct has no ctors
  * if a struct has ctors defined, only default ctor (S() { … }) should be generated to init members to default values, and the defined ctors must be declared
  * if a struct has ctors defined, the declared ctors must have the name of the struct, not __ctor, as `__ctor` might not be portable
  * if a struct has a `member = void`, dtoh code segfaults
  * a struct should only define ctors if it’s extern (C++)
*/

extern (C++) struct S
{
    byte a;
    int b;
    long c;
}

extern (C++) struct S2
{
    int a = 42;
    int b;
    long c;

    this(int a) {}
}

extern (C) struct S3
{
    int a = 42;
    int b;
    long c;

    this(int a) {}
}

extern (C) struct S4
{
    int a;
    long b;
    int c;
    byte d;
}

extern (C++) align(1) struct Aligned
{
    //align(1):
    byte a;
    int b;
    long c;

    this(int a) {}
}

extern (C++) struct A
{
    int a;
    S s;

    extern (D) void foo();
    extern (C) void bar() {}
    extern (C++) void baz(int x = 42) {}

    struct
    {
        int x;
        int y;
    }

    union
    {
        int u1;
        char[4] u2;
    }

    struct Inner
    {
        int x;
    }

    alias I = Inner;

    extern(C++) class C;

}
