require "c/stdarg" struct VaList # :nodoc: getter to_unsafe # :nodoc: def initialize(@to_unsafe : LibC::VaList) end def self.open(&) ap = uninitialized LibC::VaList Intrinsics.va_start pointerof(ap) begin yield new(ap) ensure Intrinsics.va_end pointerof(ap) end end {% if flag?(:aarch64) || flag?(:win32) %} {% platform = flag?(:aarch64) ? "AArch64" : "Windows" %} {% clang_impl = flag?(:aarch64) ? "https://github.com/llvm/llvm-project/blob/a574edbba2b24fcfb733aa2d82308131f5b7d2d6/clang/lib/CodeGen/TargetInfo.cpp#L5677-L5921" : "https://github.com/llvm/llvm-project/blob/a574edbba2b24fcfb733aa2d82308131f5b7d2d6/clang/lib/CodeGen/TargetInfo.cpp#L5958-L5964" %} # Do not call this, instead use C wrappers calling the va_arg macro for the types you need. # # Clang implements va_arg on {{platform.id}} like this: {{clang_impl.id}} # If somebody wants to fix the LLVM IR va_arg instruction on {{platform}} upstream, or port the above here, that would be welcome. def next(type) \{% raise "Cannot get variadic argument on {{platform.id}}. As a workaround implement wrappers in C calling the va_arg macro for the types you need and bind to those." %} end {% else %} @[Primitive(:va_arg)] def next(type) end {% end %} end