/
va_list.cr
36 lines (32 loc) · 1.29 KB
/
va_list.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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