Commit Graph

2694 Commits

Author SHA1 Message Date
Andrew Kelley
ec8d8a9774 hook up while on error unions with result locations
```zig
export fn entry() void {
    var c: anyerror!i32 = 1234;
    var x = while (c) |y| break foo() else |e| bar();
}
```

```llvm
define void @entry() #2 !dbg !39 {
Entry:
  %c = alloca { i16, i32 }, align 4
  %x = alloca %Foo, align 4
  %0 = bitcast { i16, i32 }* %c to i8*, !dbg !56
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 bitcast ({ i16, i32 }* @0 to i8*), i64 8, i1 false), !dbg !56
  call void @llvm.dbg.declare(metadata { i16, i32 }* %c, metadata !43, metadata !DIExpression()), !dbg !56
  br label %WhileCond, !dbg !57

WhileCond:                                        ; preds = %Entry
  %1 = getelementptr inbounds { i16, i32 }, { i16, i32 }* %c, i32 0, i32 0, !dbg !58
  %2 = load i16, i16* %1, align 2, !dbg !58
  %3 = icmp ne i16 %2, 0, !dbg !58
  br i1 %3, label %WhileElse, label %WhileBody, !dbg !58

WhileBody:                                        ; preds = %WhileCond
  %4 = getelementptr inbounds { i16, i32 }, { i16, i32 }* %c, i32 0, i32 1, !dbg !57
  call void @llvm.dbg.declare(metadata i32* %4, metadata !50, metadata !DIExpression()), !dbg !57
  call fastcc void @foo(%Foo* sret %x), !dbg !59
  br label %WhileEnd, !dbg !60

WhileElse:                                        ; preds = %WhileCond
  %5 = getelementptr inbounds { i16, i32 }, { i16, i32 }* %c, i32 0, i32 0, !dbg !61
  call void @llvm.dbg.declare(metadata i16* %5, metadata !51, metadata !DIExpression()), !dbg !61
  call fastcc void @bar(%Foo* sret %x), !dbg !61
  br label %WhileEnd, !dbg !57

WhileEnd:                                         ; preds = %WhileElse, %WhileBody
  call void @llvm.dbg.declare(metadata %Foo* %x, metadata !52, metadata !DIExpression()), !dbg !62
  ret void, !dbg !63
}
```
2019-06-07 15:22:21 -04:00
Andrew Kelley
0e8b65c537 hook up peer result locs to if optional and if err 2019-06-07 14:49:26 -04:00
Andrew Kelley
ec17f4ebbe fix behavior for peer result locs with one prong unreachable 2019-06-07 14:20:35 -04:00
Andrew Kelley
4c222a482f fix behavior for non sret fn calls 2019-06-07 11:51:50 -04:00
Andrew Kelley
76a3938d69 no-copy semantics for peer result function calls
```zig
export fn entry() void {
    var c = true;
    var x = if (c) foo() else bar();
}
```

```llvm
define void @entry() #2 !dbg !35 {
Entry:
  %c = alloca i1, align 1
  %x = alloca %Foo, align 4
  store i1 true, i1* %c, align 1, !dbg !47
  call void @llvm.dbg.declare(metadata i1* %c, metadata !39, metadata !DIExpression()), !dbg !48
  %0 = load i1, i1* %c, align 1, !dbg !49
  br i1 %0, label %Then, label %Else, !dbg !49

Then:                                             ; preds = %Entry
  call fastcc void @foo(%Foo* sret %x), !dbg !50
  br label %EndIf, !dbg !51

Else:                                             ; preds = %Entry
  call fastcc void @bar(%Foo* sret %x), !dbg !52
  br label %EndIf, !dbg !51

EndIf:                                            ; preds = %Else, %Then
  call void @llvm.dbg.declare(metadata %Foo* %x, metadata !42, metadata !DIExpression()), !dbg !53
  ret void, !dbg !54
}
```
2019-06-07 11:34:47 -04:00
Andrew Kelley
b19b1c1298 no-copy semantics for switch expressions
```zig
export fn entry() void {
    var c: i32 = 1234;
    var x = switch (c) {
        1 => u8(1),
        2...4 => u16(2),
        else => u32(3),
    };
}
```

```llvm
define void @entry() #2 !dbg !35 {
Entry:
  %c = alloca i32, align 4
  %x = alloca i32, align 4
  store i32 1234, i32* %c, align 4, !dbg !44
  call void @llvm.dbg.declare(metadata i32* %c, metadata !39, metadata !DIExpression()), !dbg !44
  %0 = load i32, i32* %c, align 4, !dbg !45
  %1 = icmp sge i32 %0, 2, !dbg !46
  %2 = icmp sle i32 %0, 4, !dbg !46
  %3 = and i1 %1, %2, !dbg !46
  br i1 %3, label %SwitchRangeYes, label %SwitchRangeNo, !dbg !46

SwitchRangeYes:                                   ; preds = %Entry
  br label %SwitchEnd, !dbg !45

SwitchElse:                                       ; preds = %SwitchRangeNo
  br label %SwitchEnd, !dbg !45

SwitchProng:                                      ; preds = %SwitchRangeNo
  br label %SwitchEnd, !dbg !45

SwitchEnd:                                        ; preds = %SwitchProng, %SwitchElse, %SwitchRangeYes
  %4 = phi i32 [ 2, %SwitchRangeYes ], [ 3, %SwitchElse ], [ 1, %SwitchProng ], !dbg !45
  store i32 %4, i32* %x, align 4, !dbg !45
  call void @llvm.dbg.declare(metadata i32* %x, metadata !42, metadata !DIExpression()), !dbg !47
  ret void, !dbg !48

SwitchRangeNo:                                    ; preds = %Entry
  switch i32 %0, label %SwitchElse [
    i32 1, label %SwitchProng
  ], !dbg !45
}
```
2019-06-04 14:47:01 -04:00
Andrew Kelley
057b96006b fix the rest of the ir_build_alloca_src callsites
except for switch expressions
2019-06-03 22:21:50 -04:00
Andrew Kelley
a32abcd365 no-copy semantics for if optional and if error union
if expressions no longer introduce a stack allocation.

```zig
export fn entry() void {
    var x: anyerror!i32 = 1234;
    if (x) |i| {} else |e| {}
}
```

```llvm
define void @entry() #2 !dbg !39 {
Entry:
  %x = alloca { i16, i32 }, align 4
  %0 = bitcast { i16, i32 }* %x to i8*, !dbg !52
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 bitcast ({ i16, i32 }* @0 to i8*), i64 8, i1 false), !dbg !52
  call void @llvm.dbg.declare(metadata { i16, i32 }* %x, metadata !43, metadata !DIExpression()), !dbg !52
  %1 = getelementptr inbounds { i16, i32 }, { i16, i32 }* %x, i32 0, i32 0, !dbg !53
  %2 = load i16, i16* %1, align 2, !dbg !53
  %3 = icmp ne i16 %2, 0, !dbg !53
  br i1 %3, label %TryElse, label %TryOk, !dbg !53

TryOk:                                            ; preds = %Entry
  %4 = getelementptr inbounds { i16, i32 }, { i16, i32 }* %x, i32 0, i32 1, !dbg !53
  call void @llvm.dbg.declare(metadata i32* %4, metadata !50, metadata !DIExpression()), !dbg !53
  br label %TryEnd, !dbg !53

TryElse:                                          ; preds = %Entry
  %5 = getelementptr inbounds { i16, i32 }, { i16, i32 }* %x, i32 0, i32 0, !dbg !53
  call void @llvm.dbg.declare(metadata i16* %5, metadata !51, metadata !DIExpression()), !dbg !53
  br label %TryEnd, !dbg !53

TryEnd:                                           ; preds = %TryElse, %TryOk
  ret void, !dbg !54
}
```
2019-06-03 21:53:32 -04:00
Andrew Kelley
143d6ada8f no-copy semantics for for loops
Note that only the index variable requires a stack allocation, and the
memcpy for the element is gone.

```zig
export fn entry() void {
    var buf: [10]i32 = undefined;
    for (buf) |x| {}
}
```

```llvm
define void @entry() #2 !dbg !35 {
Entry:
  %buf = alloca [10 x i32], align 4
  %i = alloca i64, align 8
  %0 = bitcast [10 x i32]* %buf to i8*, !dbg !47
  call void @llvm.memset.p0i8.i64(i8* align 4 %0, i8 -86, i64 40, i1 false), !dbg !47
  call void @llvm.dbg.declare(metadata [10 x i32]* %buf, metadata !39, metadata !DIExpression()), !dbg !47
  store i64 0, i64* %i, align 8, !dbg !48
  call void @llvm.dbg.declare(metadata i64* %i, metadata !45, metadata !DIExpression()), !dbg !48
  br label %ForCond, !dbg !48

ForCond:                                          ; preds = %ForBody, %Entry
  %1 = load i64, i64* %i, align 8, !dbg !48
  %2 = icmp ult i64 %1, 10, !dbg !48
  br i1 %2, label %ForBody, label %ForEnd, !dbg !48

ForBody:                                          ; preds = %ForCond
  %3 = getelementptr inbounds [10 x i32], [10 x i32]* %buf, i64 0, i64 %1, !dbg !48
  call void @llvm.dbg.declare(metadata i32* %3, metadata !46, metadata !DIExpression()), !dbg !49
  %4 = add nuw i64 %1, 1, !dbg !48
  store i64 %4, i64* %i, align 8, !dbg !48
  br label %ForCond, !dbg !48

ForEnd:                                           ; preds = %ForCond
  ret void, !dbg !50
}
```
2019-06-03 21:40:56 -04:00
Andrew Kelley
d4054e35fe while loops
Note that neither the payload capture variable nor the error capture
variable require a stack allocation.

```zig
export fn entry() void {
    var c: anyerror!i32 = 1234;
    while (c) |hi| {} else |e| {}
}
```

```llvm
define void @entry() #2 !dbg !39 {
Entry:
  %c = alloca { i16, i32 }, align 4
  %0 = bitcast { i16, i32 }* %c to i8*, !dbg !52
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 bitcast ({ i16, i32 }* @0 to i8*), i64 8, i1 false), !dbg !52
  call void @llvm.dbg.declare(metadata { i16, i32 }* %c, metadata !43, metadata !DIExpression()), !dbg !52
  br label %WhileCond, !dbg !53

WhileCond:                                        ; preds = %WhileBody, %Entry
  %1 = getelementptr inbounds { i16, i32 }, { i16, i32 }* %c, i32 0, i32 0, !dbg !54
  %2 = load i16, i16* %1, align 2, !dbg !54
  %3 = icmp ne i16 %2, 0, !dbg !54
  br i1 %3, label %WhileElse, label %WhileBody, !dbg !54

WhileBody:                                        ; preds = %WhileCond
  %4 = getelementptr inbounds { i16, i32 }, { i16, i32 }* %c, i32 0, i32 1, !dbg !53
  call void @llvm.dbg.declare(metadata i32* %4, metadata !50, metadata !DIExpression()), !dbg !53
  br label %WhileCond, !dbg !53

WhileElse:                                        ; preds = %WhileCond
  %5 = getelementptr inbounds { i16, i32 }, { i16, i32 }* %c, i32 0, i32 0, !dbg !55
  call void @llvm.dbg.declare(metadata i16* %5, metadata !51, metadata !DIExpression()), !dbg !55
  ret void, !dbg !56
}
```
2019-06-03 20:56:22 -04:00
Andrew Kelley
b6108eed52 fix alignment of consts 2019-06-03 19:11:41 -04:00
Andrew Kelley
eb8a132d23 var types, alignment, and comptime 2019-06-03 17:46:58 -04:00
Andrew Kelley
735543d502 add missing ir_expr_wrap calls 2019-06-03 15:44:53 -04:00
Andrew Kelley
ccce3d8526 no-copy semantics for function forwarding
```zig
fn foo() Foo {
    return bar();
}
```

```llvm
define internal fastcc void @foo(%Foo* nonnull sret) unnamed_addr #2 !dbg !48 {
Entry:
  call fastcc void @bar(%Foo* sret %0), !dbg !52
  ret void, !dbg !54
}
```
2019-05-31 01:36:57 -04:00
Andrew Kelley
461382ae94 no-copy semantics for function call init var and literal
```zig
export fn entry() void {
    var x = foo();
}
const Foo = struct {
    x: i32,
};
fn foo() Foo {
    return Foo{
        .x = 1234,
    };
}
```

```llvm
define void @entry() #2 !dbg !35 {
Entry:
  %x = alloca %Foo, align 4
  call fastcc void @foo(%Foo* sret %x), !dbg !45
  call void @llvm.dbg.declare(metadata %Foo* %x, metadata !39, metadata !DIExpression()), !dbg !46
  ret void, !dbg !47
}
define internal fastcc void @foo(%Foo* nonnull sret) unnamed_addr #2 !dbg !48 {
Entry:
  %1 = bitcast %Foo* %0 to i8*, !dbg !52
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %1, i8* align 4 bitcast (%Foo* @0 to i8*), i64 4, i1 false), !dbg !52
  ret void, !dbg !52
}
```
2019-05-31 01:08:16 -04:00
Andrew Kelley
8aba0643a5 peer result locations with mixed runtime/comptime
```zig
export fn entry() void {
    var c = true;
    var a = u8(4);
    const x = if (c) a else u32(8);
}
```

```llvm
define void @entry() #2 !dbg !35 {
Entry:
  %c = alloca i1, align 1
  %a = alloca i8, align 1
  %x = alloca i32, align 4
  store i1 true, i1* %c, align 1, !dbg !45
  call void @llvm.dbg.declare(metadata i1* %c, metadata !39, metadata !DIExpression()), !dbg !46
  store i8 4, i8* %a, align 1, !dbg !47
  call void @llvm.dbg.declare(metadata i8* %a, metadata !42, metadata !DIExpression()), !dbg !48
  %0 = load i1, i1* %c, align 1, !dbg !49
  br i1 %0, label %Then, label %Else, !dbg !49

Then:                                             ; preds = %Entry
  %1 = load i8, i8* %a, align 1, !dbg !50
  %2 = zext i8 %1 to i32, !dbg !50
  br label %EndIf, !dbg !51

Else:                                             ; preds = %Entry
  br label %EndIf, !dbg !51

EndIf:                                            ; preds = %Else, %Then
  %3 = phi i32 [ %2, %Then ], [ 8, %Else ], !dbg !51
  store i32 %3, i32* %x, align 4, !dbg !51
  call void @llvm.dbg.declare(metadata i32* %x, metadata !43, metadata !DIExpression()), !dbg !52
  ret void, !dbg !53
}
```
2019-05-31 00:54:10 -04:00
Andrew Kelley
3702c278e3 local consts with comptime init exprs
```zig
export fn entry() void {
    const x = if (true) u8(4) else u32(8);
}
```

```llvm
define void @entry() #2 !dbg !35 {
Entry:
  call void @llvm.dbg.declare(metadata i8* @0, metadata !39, metadata !DIExpression()), !dbg !41
  ret void, !dbg !42
}
```
2019-05-31 00:22:12 -04:00
Andrew Kelley
95d9835898 no-copy semantics for nested if
```zig
export fn entry() void {
    var c = true;
    var x = if (c) u8(4) else if (c) u16(100) else u32(10);
}
```

```llvm
define void @entry() #2 !dbg !35 {
Entry:
  %c = alloca i1, align 1
  %x = alloca i32, align 4
  store i1 true, i1* %c, align 1, !dbg !44
  call void @llvm.dbg.declare(metadata i1* %c, metadata !39, metadata !DIExpression()), !dbg !45
  %0 = load i1, i1* %c, align 1, !dbg !46
  br i1 %0, label %Then2, label %Else, !dbg !46

Else:                                             ; preds = %Entry
  %1 = load i1, i1* %c, align 1, !dbg !47
  br i1 %1, label %Then, label %Else1, !dbg !47

Then:                                             ; preds = %Else
  br label %EndIf, !dbg !48

Else1:                                            ; preds = %Else
  br label %EndIf, !dbg !48

Then2:                                            ; preds = %Entry
  br label %EndIf3, !dbg !49

EndIf:                                            ; preds = %Else1, %Then
  %2 = phi i32 [ 100, %Then ], [ 10, %Else1 ], !dbg !48
  br label %EndIf3, !dbg !49

EndIf3:                                           ; preds = %EndIf, %Then2
  %3 = phi i32 [ 4, %Then2 ], [ %2, %EndIf ], !dbg !49
  store i32 %3, i32* %x, align 4, !dbg !49
  call void @llvm.dbg.declare(metadata i32* %x, metadata !42, metadata !DIExpression()), !dbg !50
  ret void, !dbg !51
}
```
2019-05-30 23:25:37 -04:00
Andrew Kelley
a4aca78722 no-copy semantics for if expr
```zig
export fn entry() void {
    var c = true;
    var x = if (c) u8(4) else u32(10);
}
```

```llvm
define void @entry() #2 !dbg !35 {
Entry:
  %c = alloca i1, align 1
  %x = alloca i32, align 4
  store i1 true, i1* %c, align 1, !dbg !44
  call void @llvm.dbg.declare(metadata i1* %c, metadata !39, metadata !DIExpression()), !dbg !45
  %0 = load i1, i1* %c, align 1, !dbg !46
  br i1 %0, label %Then, label %Else, !dbg !46

Then:                                             ; preds = %Entry
  br label %EndIf, !dbg !47

Else:                                             ; preds = %Entry
  br label %EndIf, !dbg !47

EndIf:                                            ; preds = %Else, %Then
  %1 = phi i32 [ 4, %Then ], [ 10, %Else ], !dbg !47
  store i32 %1, i32* %x, align 4, !dbg !47
  call void @llvm.dbg.declare(metadata i32* %x, metadata !42, metadata !DIExpression()), !dbg !48
  ret void, !dbg !49
}
```
2019-05-30 23:16:11 -04:00
Andrew Kelley
5e1003bc81 no-copy semantics for basic runtime function call variable init
```zig
export fn entry() void {
    var x: Foo = foo();
}
```

```llvm
define void @entry() #2 !dbg !37 {
Entry:
  %x = alloca %Foo, align 4
  call fastcc void @foo(%Foo* sret %x), !dbg !48
  call void @llvm.dbg.declare(metadata %Foo* %x, metadata !41, metadata !DIExpression()), !dbg !49
  ret void, !dbg !50
}
```
2019-05-30 17:11:14 -04:00
Andrew Kelley
78f32259da default struct field initialization expressions
closes #485
2019-05-30 15:46:11 -04:00
Andrew Kelley
5954d5235f Merge pull request #2182 from mikdusan/issue.2046
new .d file parser for stage1 compiler
2019-05-30 11:53:08 -04:00
tgschultz
f9e7bd2682 std.meta/trait: def/definition => decl/declaration
TypeInfo: defs/Definition => decls/Declarations
2019-05-29 20:43:07 -04:00
Shawn Landden
4188faeac5 stage1: AstNodes cannot be casted, but are rather accessed via a union.
Unlike IrInstruction[Foo]s, which all start with:
    IrInstruction base;
AstNodes do not work like this, and instead use a pointer to their
specializations. The code assumed otherwise.
2019-05-29 20:21:07 -04:00
Andrew Kelley
b7a82288ad change use to usingnamespace
See #2014

`use` syntax is still accepted for now. `zig fmt` automatically
updates code. After a release cycle the old syntax will be removed.
2019-05-29 19:09:58 -04:00
Andrew Kelley
9a7cf73b3b main: set subsystem in zig builtin when explicitly provided 2019-05-29 18:18:18 -04:00
Andrew Kelley
3819654c39 codegen: initialize subsystem 2019-05-29 16:55:02 -04:00
Andrew Kelley
1ab0ac3ea2 cleanups for windows subsystem in builtin.zig 2019-05-29 16:55:02 -04:00
emekoi
b461e600e2 set subsystem to null if not on windows or uefi 2019-05-29 16:55:01 -04:00
emekoi
6bc5b07e3e try to resolve TargetSubSystemAuto to actual subsystem 2019-05-29 16:55:01 -04:00
emekoi
fb5dc28921 added subsystem to builtin.zig 2019-05-29 16:54:59 -04:00
Andrew Kelley
1ccbd1fb67 use works on unions and enums in addition to structs 2019-05-29 16:31:49 -04:00
Andrew Kelley
9891c4f30d Merge branch 'use-struct-pt2' of https://github.com/LemonBoy/zig into LemonBoy-use-struct-pt2 2019-05-29 15:48:49 -04:00
Michael Dusan
2975bdc684 add review changes
- use std.heap.c_allocator
- use @panic instead of unreachable
- use extern enum for tokenizer result type
2019-05-29 14:39:13 -04:00
Andrew Kelley
b66438eb80 no "use of undeclared identifer" in dead comptime branches 2019-05-28 18:19:27 -04:00
LemonBoy
528c151a55 Reject undefined as type
Make analyze_type_expr behave like ir_resolve_type when the user tries
to use `undefined` as a type.

Closes #2436
2019-05-28 18:02:57 -04:00
LemonBoy
a169d844c7 Warn the user if run/test is paired with emit options 2019-05-28 17:50:28 -04:00
LemonBoy
048169cbea Avoid a crash when there are no namespace components
Fixes #2500
2019-05-28 17:49:37 -04:00
Andrew Kelley
9d16839420 fix invalid LLVM IR generated for ?*void const casts
closes #2578
2019-05-28 16:11:36 -04:00
LemonBoy
e2c2263434 Move __zig_fail_unwrap locals on stack 2019-05-28 13:02:45 -04:00
emekoi
3f302594b8 respect subsystem flag in all cases 2019-05-27 22:15:33 -04:00
Andrew Kelley
f924fbddcf Merge pull request #2552 from Sahnvour/issue-2543
gen-h: do not output visibility macros when the build is static
2019-05-27 21:51:34 -04:00
Andrew Kelley
2c0280ba08 improve the stack check CLI options
See #2526
2019-05-27 20:59:19 -04:00
Michael Dusan
d4b241c14e new .d file parser for C compilation
- wip for #2046
- clang .d output must be created with `clang -MV` switch
- implemented in Zig
- hybridized for zig stage0 and stage1
- zig test src-self-hosted/dep_tokenizer.zig
2019-05-27 19:47:10 -04:00
Andrew Kelley
f68d8060ec Merge pull request #2526 from LemonBoy/arch-format-osx
Build archives using the K_DARWIN format when targeting osx
2019-05-27 19:25:58 -04:00
Andrew Kelley
df7aa9a4f0 allow implicit optional pointer to optional c_void pointer 2019-05-26 17:55:20 -04:00
Andrew Kelley
269a53b6af introduce @hasDecl builtin function
closes #1439
2019-05-26 16:21:03 -04:00
Andrew Kelley
21ed939117 support enum literals implicit casting to tagged unions 2019-05-26 12:59:30 -04:00
Sahnvour
99ee0608f7 gen-h: do not output visibility macros when the build is static 2019-05-25 14:17:59 +02:00
LemonBoy
86b3007b94 Reject slices in use expressions
Co-Authored-By: emekoi <emekankurumeh@outlook.com>
2019-05-24 13:20:44 +02:00