#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
struct String {
  int dummy;
};
typedef int /*<<< orphan*/ FILE;

/* Variables and functions */
struct String *String_create(char *);
int /*<<< orphan*/ String_destory(struct String *);
int /*<<< orphan*/ String_print(struct String *);
int /*<<< orphan*/ String_write(struct String *, int /*<<< orphan*/ *);
int /*<<< orphan*/ *fopen(char *, char *);
void String_test() {
  char buf[] = "hello world "
               "hello world "
               "hello world "
               "hello world "
               "hello world\n"
               "hello world "
               "hello world "
               "hello world "
               "hello world "
               "hello world\n"
               "hello world "
               "hello world "
               "hello world "
               "hello world "
               "hello world\n"
               "hello world "
               "hello world "
               "hello world "
               "hello world "
               "hello world\n"
               "hello world "
               "hello world "
               "hello world "
               "hello world "
               "hello world\n"
               "hello world "
               "hello world "
               "hello world "
               "hello world "
               "hello world\n"
               "hello world "
               "hello world "
               "hello world "
               "hello world "
               "hello world\n"
               "hello world "
               "hello world "
               "hello world "
               "hello world "
               "hello world\n"
               "hello world "
               "hello world "
               "hello world "
               "hello world "
               "hello world\n"
               "hello world "
               "hello world "
               "hello world "
               "hello world "
               "hello world\n";
  struct String *s;
  s = String_create(buf);
  String_print(s);
  FILE *f = fopen("String_write.out", "w");
  String_write(s, f);
  String_destory(s);
  s = NULL;
}


x86 assembly (clang, -O0):
<String_test>:
push   %rbp
mov    %rsp,%rbp
sub    $0x270,%rsp
lea    -0x260(%rbp),%rdi
lea    0xe87(%rip),%rsi
mov    $0x259,%edx
call   1030 <memcpy@plt>
lea    -0x260(%rbp),%rdi
call   1050 <String_create@plt>
mov    %rax,-0x268(%rbp)
mov    -0x268(%rbp),%rdi
call   1070 <String_print@plt>
lea    0x10b0(%rip),%rdi
lea    0x10ba(%rip),%rsi
call   1040 <fopen@plt>
mov    %rax,-0x270(%rbp)
mov    -0x268(%rbp),%rdi
mov    -0x270(%rbp),%rsi
call   1060 <String_write@plt>
mov    -0x268(%rbp),%rdi
call   1080 <String_destory@plt>
movq   $0x0,-0x268(%rbp)
add    $0x270,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<String_test>:
push   %rbx
sub    $0x260,%rsp
lea    0xe91(%rip),%rsi
mov    %rsp,%rbx
mov    $0x259,%edx
mov    %rbx,%rdi
call   1030 <memcpy@plt>
mov    %rbx,%rdi
call   1050 <String_create@plt>
mov    %rax,%rbx
mov    %rax,%rdi
call   1070 <String_print@plt>
lea    0x10c0(%rip),%rdi
lea    0x10ca(%rip),%rsi
call   1040 <fopen@plt>
mov    %rbx,%rdi
mov    %rax,%rsi
call   1060 <String_write@plt>
mov    %rbx,%rdi
call   1080 <String_destory@plt>
add    $0x260,%rsp
pop    %rbx
ret

LLVM IR (-O0):
%struct.String = type { i32 }
@__const.String_test.buf = [601 x i8] c"hello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0A\00"
@.str = [17 x i8] c"String_write.out\00"
@.str.1 = [2 x i8] c"w\00"
define void @String_test() {
%1 = alloca [601 x i8]
%2 = alloca %struct.String*
%3 = alloca i32*
%4 = bitcast [601 x i8]* %1 to i8*
%5 = getelementptr inbounds [601 x i8], [601 x i8]* %1, i64 0, i64 0
%6 = call %struct.String* @String_create(i8* %5)
store %struct.String* %6, %struct.String** %2
%7 = load %struct.String*, %struct.String** %2
%8 = call i32 @String_print(%struct.String* %7)
%9 = call i32* @fopen(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0))
store i32* %9, i32** %3
%10 = load %struct.String*, %struct.String** %2
%11 = load i32*, i32** %3
%12 = call i32 @String_write(%struct.String* %10, i32* %11)
%13 = load %struct.String*, %struct.String** %2
%14 = call i32 @String_destory(%struct.String* %13)
store %struct.String* null, %struct.String** %2
ret void
}

LLVM IR (-O2):
%struct.String = type { i32 }
@__const.String_test.buf = [601 x i8] c"hello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0Ahello world hello world hello world hello world hello world\0A\00"
@.str = [17 x i8] c"String_write.out\00"
@.str.1 = [2 x i8] c"w\00"
define void @String_test() {
%1 = alloca [601 x i8]
%2 = getelementptr inbounds [601 x i8], [601 x i8]* %1, i64 0, i64 0
%3 = call %struct.String* @String_create(i8* %2)
%4 = call i32 @String_print(%struct.String* %3)
%5 = call i32* @fopen(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0))
%6 = call i32 @String_write(%struct.String* %3, i32* %5)
%7 = call i32 @String_destory(%struct.String* %3)
ret void
}