-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Add the CTypes
module for common C type aliases
#14448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
# This module exposes the various common platform-dependent arithmetic types | ||
# from the C language, to be used in lib bindings. | ||
# | ||
# For convenience, libs can import types from this module using aliases, so that | ||
# the types can be used inside the lib without fully qualified paths: | ||
# | ||
# ``` | ||
# lib LibFoo | ||
# alias Int = CTypes::Int | ||
# | ||
# fun foo(x : Int) : Int # okay | ||
# fun bar(x : CTypes::Char*) # okay | ||
# end | ||
# ``` | ||
module CTypes | ||
{% unless flag?(:bits32) || flag?(:bits64) %} | ||
{% if target = Crystal.constant("TARGET_TRIPLE") %} | ||
{% raise "Unsupported target: #{target.id}" %} | ||
{% else %} | ||
# this is for old compilers that attempt to directly use a newer stdlib | ||
# for cross-compilation | ||
{% raise "Architecture with unsupported word size" %} | ||
{% end %} | ||
{% end %} | ||
|
||
# The C `char` type. | ||
# | ||
# Guaranteed to have at least 8 bits. Equivalent to `UInt8` on all currently | ||
# supported targets. | ||
alias Char = UInt8 | ||
|
||
# The C `signed char` type. | ||
# | ||
# Guaranteed to have at least 8 bits. Equivalent to `Int8` on all currently | ||
# supported targets. | ||
alias SChar = Int8 | ||
|
||
# The C `unsigned char` type. | ||
# | ||
# Guaranteed to have at least 8 bits. Equivalent to `UInt8` on all currently | ||
# supported targets. | ||
alias UChar = UInt8 | ||
|
||
# The C `short` type. | ||
# | ||
# Guaranteed to have at least 16 bits. Equivalent to `Int16` on all currently | ||
# supported targets. | ||
alias Short = Int16 | ||
|
||
# The C `unsigned short` type. | ||
# | ||
# Guaranteed to have at least 16 bits. Equivalent to `UInt16` on all currently | ||
# supported targets. | ||
alias UShort = UInt16 | ||
|
||
# The C `int` type. | ||
# | ||
# Guaranteed to have at least 16 bits. Equivalent to `Int32` on all currently | ||
# supported targets. | ||
alias Int = Int32 | ||
|
||
# The C `unsigned int` type. | ||
# | ||
# Guaranteed to have at least 16 bits. Equivalent to `UInt32` on all currently | ||
# supported targets. | ||
alias UInt = UInt32 | ||
|
||
# The C `long` type. | ||
# | ||
# Guaranteed to have at least 32 bits. Equivalent to `Int32` on Windows and | ||
# on 32-bit targets. Equivalent to `Int64` on 64-bit, non-Windows targets. | ||
{% if flag?(:bits32) || flag?(:win32) %} | ||
alias Long = Int32 | ||
{% elsif flag?(:bits64) %} | ||
alias Long = Int64 | ||
{% end %} | ||
|
||
# The C `unsigned long` type. | ||
# | ||
# Guaranteed to have at least 32 bits. Equivalent to `UInt32` on Windows and | ||
# on 32-bit targets. Equivalent to `UInt64` on 64-bit, non-Windows targets. | ||
{% if flag?(:bits32) || flag?(:win32) %} | ||
alias ULong = UInt32 | ||
{% elsif flag?(:bits64) %} | ||
alias ULong = UInt64 | ||
{% end %} | ||
|
||
# The C `long long` type. | ||
# | ||
# Guaranteed to have at least 64 bits. Equivalent to `Int64` on all currently | ||
# supported targets. | ||
alias LongLong = Int64 | ||
|
||
# The C `unsigned long long` type. | ||
# | ||
# Guaranteed to have at least 64 bits. Equivalent to `UInt64` on all currently | ||
# supported targets. | ||
alias ULongLong = UInt64 | ||
|
||
# The C `float` type. | ||
# | ||
# Equivalent to `Float32` on all currently supported targets. | ||
alias Float = Float32 | ||
|
||
# The C `double` type. | ||
# | ||
# Equivalent to `Float64` on all currently supported targets. | ||
alias Double = Float64 | ||
|
||
# The C `intptr_t` type. | ||
# | ||
# Large enough to hold the value of `Pointer#address`. Equivalent to `Int32` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: Is this actually true? Isn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is more like " |
||
# on 32-bit targets, `Int64` on 64-bit targets. | ||
{% if flag?(:bits32) %} | ||
alias IntPtrT = Int32 | ||
{% elsif flag?(:bits64) %} | ||
alias IntPtrT = Int64 | ||
{% end %} | ||
|
||
# The C `uintptr_t` type. | ||
# | ||
# Large enough to hold the value of `Pointer#address`. Equivalent to `UInt32` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This isn't true, uintptr_t is an integer type large enough to hold the pointer itself. Namely, on 64-bit CHERI architectures, the pointer is 128 bits long (size_t or ptrdiff_t are 64 bits there). There are other exotic architectures which also behave weirdly here, depending on the platform (IA-32 technically uses discontinuous 48-bit memory (16-bit segment-number plus 32-bit offset), but OSes normally move applications into a 32-bit segment to create the illusion of flat 32-bit memory). |
||
# on 32-bit targets, `UInt64` on 64-bit targets. | ||
{% if flag?(:bits32) %} | ||
alias UIntPtrT = UInt32 | ||
{% elsif flag?(:bits64) %} | ||
alias UIntPtrT = UInt64 | ||
{% end %} | ||
|
||
# The C `size_t` type. | ||
# | ||
# Large enough to hold the value of `sizeof` for any type. Guaranteed to have | ||
# at least 16 bits. Equivalent to `UInt32` on 32-bit targets, `UInt64` on | ||
# 64-bit targets. | ||
{% if flag?(:bits32) %} | ||
alias SizeT = UInt32 | ||
{% elsif flag?(:bits64) %} | ||
alias SizeT = UInt64 | ||
{% end %} | ||
|
||
# The C `ptrdiff_t` type. | ||
# | ||
# Large enough to hold the value of `Pointer#-(Pointer)`. Guaranteed to have | ||
# at least 17 bits. Equivalent to `Int32` on 32-bit targets, `Int64` on 64-bit | ||
# targets. | ||
{% if flag?(:bits32) %} | ||
alias PtrDiffT = Int32 | ||
{% elsif flag?(:bits64) %} | ||
alias PtrDiffT = Int64 | ||
{% end %} | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = ULong | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = ULong | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = ULong | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = ULong | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = UInt | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = UInt | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = UInt | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = ULong | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = ULong | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = ULong | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = ULong | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = ULong | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = ULong | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = ULong | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = ULong | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = ULong | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias SizeT = UInt64 | ||
alias SizeT = CTypes::SizeT | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
require "c_types" | ||
|
||
lib LibC | ||
alias IntPtrT = Int64 | ||
alias UIntPtrT = UInt64 | ||
alias IntPtrT = CTypes::IntPtrT | ||
alias UIntPtrT = CTypes::UIntPtrT | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thought: I was wondering if
module C
could be an option as it allows to conveniently writeC::Char
. But that would likely cause confusion becauseA
,B
,C
are commonly used as stub constants.Importing with a local alias (
private alias C = ::CTypes
) would be of similar convenience.(ref #13504 (comment) ff.)