static void write_c_interface_definition()

in src/tool/abi/types.cpp [726:882]


static void write_c_interface_definition(writer& w, T const& type)
{
    constexpr bool is_interface = std::is_same_v<T, interface_type>;
    constexpr bool is_delegate = std::is_same_v<T, delegate_type>;
    constexpr bool is_generic = std::is_same_v<T, generic_inst>;
    static_assert(is_interface || is_delegate | is_generic);

    w.write("typedef struct");
    if (auto info = type.is_deprecated(); info && w.config().enable_header_deprecation)
    {
        w.write('\n');
        write_deprecation_message(w, *info);
    }
    else
    {
        w.write(' ');
    }

    w.write(R"^-^(%
{
    BEGIN_INTERFACE

)^-^", bind_c_type_name(type, "Vtbl"));

    bool isDelegate = type.category() == category::delegate_type;
    if (isDelegate)
    {
        write_c_iunknown_interface(w, type);
    }
    else
    {
        write_c_iinspectable_interface(w, type);
    }

    for (auto const& func : type.functions)
    {
        write_c_function_declaration(w, bind_c_type_name(type), func);
    }

    if constexpr (is_interface)
    {
        if (type.fast_class)
        {
            w.write("\n// Supplemental functions added by use of the fast ABI attribute\n");

            auto fastAttr = get_attribute(type.fast_class->type(), metadata_namespace, "FastAbiAttribute"sv);
            std::size_t fastContractDepth = w.push_contract_guard(version_from_attribute(fastAttr)) ? 1 : 0;

            // If the class "derives" from any other class, the fast pointer-to-base functions come first
            std::vector<class_type const*> baseClasses;
            auto base = type.fast_class->base_class;
            while (base)
            {
                baseClasses.push_back(base);
                base = base->base_class;
            }

            std::for_each(baseClasses.rbegin(), baseClasses.rend(), [&](class_type const* baseClass)
            {
                w.write("    % (STDMETHODCALLTYPE* base_%)(%* This);\n",
                    [&](writer& w) { baseClass->write_c_abi_param(w); },
                    baseClass->cpp_logical_name(),
                    bind_c_type_name(type));
            });

            for (auto [iface, ver] : type.fast_class->supplemental_fast_interfaces)
            {
                w.write("\n    // Supplemental functions added for the % interface\n", iface->clr_full_name());
                fastContractDepth += w.push_contract_guard(ver) ? 1 : 0;

                for (auto const& func : iface->functions)
                {
                    write_c_function_declaration(w, bind_c_type_name(type), func);
                }
            }

            w.pop_contract_guards(fastContractDepth);
        }
    }

    w.write(R"^-^(
    END_INTERFACE
} %;

interface %
{
    CONST_VTBL struct %* lpVtbl;
};

#ifdef COBJMACROS

)^-^", bind_c_type_name(type, "Vtbl"), bind_c_type_name(type), bind_c_type_name(type, "Vtbl"));

    if (isDelegate)
    {
        write_c_iunknown_interface_macros(w, type);
    }
    else
    {
        write_c_iinspectable_interface_macros(w, type);
    }

    for (auto const& func : type.functions)
    {
        write_c_function_declaration_macro(w, type, func);
    }

    if constexpr (is_interface)
    {
        if (type.fast_class)
        {
            w.write("// Supplemental functions added by use of the fast ABI attribute\n");

            auto fastAttr = get_attribute(type.fast_class->type(), metadata_namespace, "FastAbiAttribute"sv);
            std::size_t fastContractDepth = w.push_contract_guard(version_from_attribute(fastAttr)) ? 1 : 0;
            w.write("\n");

            // If the class "derives" from any other class, the fast pointer-to-base functions come first
            std::vector<class_type const*> baseClasses;
            auto base = type.fast_class->base_class;
            while (base)
            {
                baseClasses.push_back(base);
                base = base->base_class;
            }

            std::for_each(baseClasses.rbegin(), baseClasses.rend(), [&](class_type const* baseClass)
            {
                w.write(R"^-^(#define %_base_%(This) \
    ((This)->lpVtbl->base_%(This))

)^-^", bind_mangled_name_macro(type), baseClass->cpp_logical_name(), baseClass->cpp_logical_name());
            });

            for (auto [iface, ver] : type.fast_class->supplemental_fast_interfaces)
            {
                w.write("// Supplemental functions added for the % interface\n", iface->clr_full_name());
                fastContractDepth += w.push_contract_guard(ver) ? 1 : 0;
                w.write("\n");

                for (auto const& func : iface->functions)
                {
                    write_c_function_declaration_macro(w, type, func);
                }
            }

            w.pop_contract_guards(fastContractDepth);
            if (fastContractDepth > 0)
            {
                w.write("\n");
            }
        }
    }

    w.write(R"^-^(#endif /* COBJMACROS */
)^-^");
}