// #target: macos-x64
module foo;

extern fn void printf(char* fmt, ...);
struct Foo
{
	int x;
}

macro void Foo.@hello(&this) { this.x = 3; printf("-%d\n", this.x); }
macro void Foo.hello(Foo* this) { this.x = 4; printf("-%d\n", this.x); }
macro void Foo.hello2(Foo this) { this.x = 5; printf("-%d\n", this.x); }

fn void main()
{
	Foo a;
	a.@hello();
	printf("%d\n", a.x);
	a.hello();
	printf("%d\n", a.x);
	a.hello2();
	printf("%d\n", a.x);
}

/* #expect: foo.ll

define void @foo.main() #0 {
entry:
  %a = alloca %Foo, align 4
  %this = alloca %Foo, align 4
  store i32 0, ptr %a, align 4
  store i32 3, ptr %a, align 4
  %0 = load i32, ptr %a, align 4
  call void (ptr, ...) @printf(ptr @.str, i32 %0)
  %1 = load i32, ptr %a, align 4
  call void (ptr, ...) @printf(ptr @.str.1, i32 %1)
  store i32 4, ptr %a, align 4
  %2 = load i32, ptr %a, align 4
  call void (ptr, ...) @printf(ptr @.str.2, i32 %2)
  %3 = load i32, ptr %a, align 4
  call void (ptr, ...) @printf(ptr @.str.3, i32 %3)
  call void @llvm.memcpy.p0.p0.i32(ptr align 4 %this, ptr align 4 %a, i32 4, i1 false)
  store i32 5, ptr %this, align 4
  %4 = load i32, ptr %this, align 4
  call void (ptr, ...) @printf(ptr @.str.4, i32 %4)
  %5 = load i32, ptr %a, align 4
  call void (ptr, ...) @printf(ptr @.str.5, i32 %5)
  ret void
}