diff --git a/doc/langref.html.in b/doc/langref.html.in
index 3e335c8d6424..1b1823311e9d 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -5458,9 +5458,51 @@ test "@intToPtr for pointer to zero bit type" {
{#header_close#}
{#header_open|Result Location Semantics#}
-
- TODO add documentation for this
-
+ Certain expressions which manipulate a value in memory will directly initialize the final location of
+ that memory, to avoid making multiple allocations and copying between them (note: "allocation" here means
+ of registers or stack space, not dynamic as is usually meant):
+ {#code_begin|syntax#}
+pub fn main() void {
+ // foo() allocates its result directly in x -- only one allocation is made
+ var x = foo();
+
+ // Result location is properly communicated through struct fields and if expressions
+ var y = Data {
+ .field1 = 26,
+ .field2 = if (condition) bar() else baz(),
+ };
+
+ // Unwrapping errors or optionals currently does not elide copy (https://github.com/ziglang/zig/issues/2765)
+ var z = quux() catch unreachable; // Value is allocated twice
+}
+
+fn foo() Large {
+ // Direct return correctly passes result location to callsite
+ return Large {
+ // ...
+ };
+}
+
+fn bar() Large {
+ // Assignment to a variable always makes another allocation, even when this variable is returned
+ // -- automatic copy elision in this case is planned (https://github.com/ziglang/zig/issues/2765)
+ var l = Large {};
+}
+
+fn quux() !Large {
+ return Large {};
+}
+ {#code_end#}
+ The current result location semantics elide copies from the following locations where possible:
+
+ - Variable declaration bodies
+ - Struct, array and union initializations
+ - If statement branches
+ - Switch statement arms
+ - Function returns
+ - {#syntax#}catch{#endsyntax#} and {#syntax#}orelse{#endsyntax#} default statements
+ - Arguments to {#link|bitCast#}
+
{#header_close#}
{#header_open|usingnamespace#}
diff --git a/lib/std/build/emit_raw.zig b/lib/std/build/emit_raw.zig
index f3549491d618..275a444bef96 100644
--- a/lib/std/build/emit_raw.zig
+++ b/lib/std/build/emit_raw.zig
@@ -95,7 +95,7 @@ const BinaryElfOutput = struct {
sort.sort(*BinaryElfSegment, self.segments.span(), segmentSortCompare);
if (self.segments.items.len > 0) {
- const firstSegment = self.segments.at(0);
+ const firstSegment = self.segments.items[0];
if (firstSegment.firstSection) |firstSection| {
const diff = firstSection.elfOffset - firstSegment.elfOffset;
diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig
index 882e5dbedf16..9cf90efffa9f 100644
--- a/lib/std/os/windows.zig
+++ b/lib/std/os/windows.zig
@@ -19,6 +19,7 @@ pub const psapi = @import("windows/psapi.zig");
pub const shell32 = @import("windows/shell32.zig");
pub const user32 = @import("windows/user32.zig");
pub const ws2_32 = @import("windows/ws2_32.zig");
+pub const gdi32 = @import("windows/gdi32.zig");
pub usingnamespace @import("windows/bits.zig");
diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig
index 6d6f3644cc2e..0708ed208129 100644
--- a/lib/std/os/windows/bits.zig
+++ b/lib/std/os/windows/bits.zig
@@ -34,6 +34,8 @@ pub const HINSTANCE = *@OpaqueType();
pub const HMENU = *@OpaqueType();
pub const HMODULE = *@OpaqueType();
pub const HWND = *@OpaqueType();
+pub const HDC = *@OpaqueType();
+pub const HGLRC = *@OpaqueType();
pub const FARPROC = *@OpaqueType();
pub const INT = c_int;
pub const LPBYTE = *BYTE;
diff --git a/lib/std/os/windows/gdi32.zig b/lib/std/os/windows/gdi32.zig
new file mode 100644
index 000000000000..3377b37f6eae
--- /dev/null
+++ b/lib/std/os/windows/gdi32.zig
@@ -0,0 +1,45 @@
+usingnamespace @import("bits.zig");
+
+pub const PIXELFORMATDESCRIPTOR = extern struct {
+ nSize: WORD = @sizeOf(PIXELFORMATDESCRIPTOR),
+ nVersion: WORD,
+ dwFlags: DWORD,
+ iPixelType: BYTE,
+ cColorBits: BYTE,
+ cRedBits: BYTE,
+ cRedShift: BYTE,
+ cGreenBits: BYTE,
+ cGreenShift: BYTE,
+ cBlueBits: BYTE,
+ cBlueShift: BYTE,
+ cAlphaBits: BYTE,
+ cAlphaShift: BYTE,
+ cAccumBits: BYTE,
+ cAccumRedBits: BYTE,
+ cAccumGreenBits: BYTE,
+ cAccumBlueBits: BYTE,
+ cAccumAlphaBits: BYTE,
+ cDepthBits: BYTE,
+ cStencilBits: BYTE,
+ cAuxBuffers: BYTE,
+ iLayerType: BYTE,
+ bReserved: BYTE,
+ dwLayerMask: DWORD,
+ dwVisibleMask: DWORD,
+ dwDamageMask: DWORD,
+};
+
+pub extern "gdi32" fn SetPixelFormat(
+ hdc: ?HDC,
+ format: i32,
+ ppfd: ?*const PIXELFORMATDESCRIPTOR,
+) callconv(.Stdcall) bool;
+
+pub extern "gdi32" fn ChoosePixelFormat(
+ hdc: ?HDC,
+ ppfd: ?*const PIXELFORMATDESCRIPTOR,
+) callconv(.Stdcall) i32;
+
+pub extern "gdi32" fn SwapBuffers(hdc: ?HDC) callconv(.Stdcall) bool;
+pub extern "gdi32" fn wglCreateContext(hdc: ?HDC) callconv(.Stdcall) ?HGLRC;
+pub extern "gdi32" fn wglMakeCurrent(hdc: ?HDC, hglrc: ?HGLRC) callconv(.Stdcall) bool;
\ No newline at end of file
diff --git a/lib/std/os/windows/user32.zig b/lib/std/os/windows/user32.zig
index f24f20cfc885..336fc38412f1 100644
--- a/lib/std/os/windows/user32.zig
+++ b/lib/std/os/windows/user32.zig
@@ -1,5 +1,104 @@
usingnamespace @import("bits.zig");
+// PM
+pub const PM_REMOVE = 0x0001;
+pub const PM_NOREMOVE = 0x0000;
+pub const PM_NOYIELD = 0x0002;
+
+// WM
+pub const WM_NULL = 0x0000;
+pub const WM_CREATE = 0x0001;
+pub const WM_DESTROY = 0x0002;
+pub const WM_MOVE = 0x0003;
+pub const WM_SIZE = 0x0005;
+
+pub const WM_ACTIVATE = 0x0006;
+pub const WM_PAINT = 0x000F;
+pub const WM_CLOSE = 0x0010;
+pub const WM_QUIT = 0x0012;
+pub const WM_SETFOCUS = 0x0007;
+
+pub const WM_KILLFOCUS = 0x0008;
+pub const WM_ENABLE = 0x000A;
+pub const WM_SETREDRAW = 0x000B;
+
+pub const WM_SYSCOLORCHANGE = 0x0015;
+pub const WM_SHOWWINDOW = 0x0018;
+
+pub const WM_WINDOWPOSCHANGING = 0x0046;
+pub const WM_WINDOWPOSCHANGED = 0x0047;
+pub const WM_POWER = 0x0048;
+
+pub const WM_CONTEXTMENU = 0x007B;
+pub const WM_STYLECHANGING = 0x007C;
+pub const WM_STYLECHANGED = 0x007D;
+pub const WM_DISPLAYCHANGE = 0x007E;
+pub const WM_GETICON = 0x007F;
+pub const WM_SETICON = 0x0080;
+
+pub const WM_INPUT_DEVICE_CHANGE = 0x00fe;
+pub const WM_INPUT = 0x00FF;
+pub const WM_KEYFIRST = 0x0100;
+pub const WM_KEYDOWN = 0x0100;
+pub const WM_KEYUP = 0x0101;
+pub const WM_CHAR = 0x0102;
+pub const WM_DEADCHAR = 0x0103;
+pub const WM_SYSKEYDOWN = 0x0104;
+pub const WM_SYSKEYUP = 0x0105;
+pub const WM_SYSCHAR = 0x0106;
+pub const WM_SYSDEADCHAR = 0x0107;
+pub const WM_UNICHAR = 0x0109;
+pub const WM_KEYLAST = 0x0109;
+
+pub const WM_COMMAND = 0x0111;
+pub const WM_SYSCOMMAND = 0x0112;
+pub const WM_TIMER = 0x0113;
+
+pub const WM_MOUSEFIRST = 0x0200;
+pub const WM_MOUSEMOVE = 0x0200;
+pub const WM_LBUTTONDOWN = 0x0201;
+pub const WM_LBUTTONUP = 0x0202;
+pub const WM_LBUTTONDBLCLK = 0x0203;
+pub const WM_RBUTTONDOWN = 0x0204;
+pub const WM_RBUTTONUP = 0x0205;
+pub const WM_RBUTTONDBLCLK = 0x0206;
+pub const WM_MBUTTONDOWN = 0x0207;
+pub const WM_MBUTTONUP = 0x0208;
+pub const WM_MBUTTONDBLCLK = 0x0209;
+pub const WM_MOUSEWHEEL = 0x020A;
+pub const WM_XBUTTONDOWN = 0x020B;
+pub const WM_XBUTTONUP = 0x020C;
+pub const WM_XBUTTONDBLCLK = 0x020D;
+
+// WA
+pub const WA_INACTIVE = 0;
+pub const WA_ACTIVE = 0x0006;
+pub const WM_ACTIVATE = 0x0006;
+
+// WS
+pub const WS_OVERLAPPED = 0x00000000;
+pub const WS_CAPTION = 0x00C00000;
+pub const WS_SYSMENU = 0x00080000;
+pub const WS_THICKFRAME = 0x00040000;
+pub const WS_MINIMIZEBOX = 0x00020000;
+pub const WS_MAXIMIZEBOX = 0x00010000;
+
+// PFD
+pub const PFD_DRAW_TO_WINDOW = 0x00000004;
+pub const PFD_SUPPORT_OPENGL = 0x00000020;
+pub const PFD_DOUBLEBUFFER = 0x00000001;
+pub const PFD_MAIN_PLANE = 0;
+pub const PFD_TYPE_RGBA = 0;
+
+// CS
+pub const CS_HREDRAW = 0x0002;
+pub const CS_VREDRAW = 0x0001;
+pub const CS_OWNDC = 0x0020;
+
+// SW
+pub const SW_HIDE = 0;
+pub const SW_SHOW = 5;
+
pub const WNDPROC = fn (HWND, UINT, WPARAM, LPARAM) callconv(.Stdcall) LRESULT;
pub const WNDCLASSEXA = extern struct {
@@ -17,6 +116,20 @@ pub const WNDCLASSEXA = extern struct {
hIconSm: ?HICON,
};
+pub const POINT = extern struct {
+ x: c_long, y: c_long
+};
+
+pub const MSG = extern struct {
+ hWnd: ?HWND,
+ message: UINT,
+ wParam: WPARAM,
+ lParam: LPARAM,
+ time: DWORD,
+ pt: POINT,
+ lPrivate: DWORD,
+};
+
pub extern "user32" fn CreateWindowExA(
dwExStyle: DWORD,
lpClassName: LPCSTR,
@@ -32,6 +145,28 @@ pub extern "user32" fn CreateWindowExA(
lpParam: ?LPVOID,
) callconv(.Stdcall) ?HWND;
+pub extern "user32" fn RegisterClassExA(*const WNDCLASSEXA) callconv(.Stdcall) c_ushort;
pub extern "user32" fn DefWindowProcA(HWND, Msg: UINT, WPARAM, LPARAM) callconv(.Stdcall) LRESULT;
+pub extern "user32" fn GetModuleHandleA(lpModuleName: ?LPCSTR) callconv(.Stdcall) HMODULE;
+pub extern "user32" fn ShowWindow(hWnd: ?HWND, nCmdShow: i32) callconv(.Stdcall) bool;
+pub extern "user32" fn UpdateWindow(hWnd: ?HWND) callconv(.Stdcall) bool;
+pub extern "user32" fn GetDC(hWnd: ?HWND) callconv(.Stdcall) ?HDC;
-pub extern "user32" fn RegisterClassExA(*const WNDCLASSEXA) callconv(.Stdcall) c_ushort;
+pub extern "user32" fn PeekMessageA(
+ lpMsg: ?*MSG,
+ hWnd: ?HWND,
+ wMsgFilterMin: UINT,
+ wMsgFilterMax: UINT,
+ wRemoveMsg: UINT,
+) callconv(.Stdcall) bool;
+
+pub extern "user32" fn GetMessageA(
+ lpMsg: ?*MSG,
+ hWnd: ?HWND,
+ wMsgFilterMin: UINT,
+ wMsgFilterMax: UINT,
+) callconv(.Stdcall) bool;
+
+pub extern "user32" fn TranslateMessage(lpMsg: *const MSG) callconv(.Stdcall) bool;
+pub extern "user32" fn DispatchMessageA(lpMsg: *const MSG) callconv(.Stdcall) LRESULT;
+pub extern "user32" fn PostQuitMessage(nExitCode: i32) callconv(.Stdcall) void;
\ No newline at end of file
diff --git a/src/ir.cpp b/src/ir.cpp
index b9438dda38fc..eb7308e8f5c6 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -16974,7 +16974,7 @@ static IrInstGen *ir_analyze_bit_shift(IrAnalyze *ira, IrInstSrcBinOp *bin_op_in
if (!instr_is_comptime(op2)) {
ir_add_error(ira, &bin_op_instruction->base.base,
- buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known"));
+ buf_sprintf("LHS of shift must be a fixed-width integer type, or RHS must be compile-time known"));
return ira->codegen->invalid_inst_gen;
}
diff --git a/src/main.cpp b/src/main.cpp
index b682aa69bbb0..523c42276801 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -37,6 +37,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
" build-obj [source] create object from source or assembly\n"
" builtin show the source code of @import(\"builtin\")\n"
" cc use Zig as a drop-in C compiler\n"
+ " c++ use Zig as a drop-in C++ compiler\n"
" fmt parse files and render in canonical zig format\n"
" id print the base64-encoded compiler id\n"
" init-exe initialize a `zig build` application in the cwd\n"
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 4db3ef3c992e..4b60deec1c83 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -5925,7 +5925,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ return 0x11 << x;
\\}
, &[_][]const u8{
- "tmp.zig:2:17: error: LHS of shift must be an integer type, or RHS must be compile-time known",
+ "tmp.zig:2:17: error: LHS of shift must be a fixed-width integer type, or RHS must be compile-time known",
});
cases.add("shifting RHS is log2 of LHS int bit width",