// Path: src/main/java/de/uni/bremen/monty/moco/codegeneration/identifier/FunctionSignature.java
// public class FunctionSignature<T extends LLVMType> extends LLVMIdentifier<T> {
// 
// 	private List<LLVMIdentifier<? extends LLVMType>> parameter;
// 
// 	FunctionSignature(T type, String name, List<LLVMIdentifier<? extends LLVMType>> parameter) {
// 		super(type, name, false);
// 		this.parameter = parameter;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return type + " " + name + "(" + StringUtils.join(parameter, ", ") + ")";
// 	}
// }
// 
// Path: src/main/java/de/uni/bremen/monty/moco/codegeneration/identifier/LLVMIdentifier.java
// public class LLVMIdentifier<T extends LLVMType> {
// 	protected final String name;
// 	protected final T type;
// 
// 	/** This is indicates if this value is a concrete value, or a pointer to a value, that needs to be resolved or
// 	 * dereference to gets its value. */
// 	private boolean resolvable;
// 
// 	/** Don't use this. Only {@link LLVMIdentifierFactory} should create instances.
// 	 *
// 	 * @param type
// 	 * @param name
// 	 * @param resolvable */
// 	LLVMIdentifier(T type, String name, boolean resolvable) {
// 		this.name = name;
// 		this.type = type;
// 		this.resolvable = resolvable;
// 	}
// 
// 	public String getName() {
// 		return name;
// 	}
// 
// 	public T getType() {
// 		return type;
// 	}
// 
// 	/** @returns the LLVM-IR representation. e.g. new LLVMIdentifier(pointer(int64(),"%foobar").toString() ==
// 	 *          "i64* %foobar" */
// 	@Override
// 	public String toString() {
// 		return type + " " + getName();
// 	}
// 
// 	/** Is it a value or a pointer to value
// 	 *
// 	 * @return true if its a pointer to a value */
// 	public boolean needToBeResolved() {
// 		return resolvable;
// 	}
// 
// }
// 
// Path: src/main/java/de/uni/bremen/monty/moco/codegeneration/types/LLVMPointer.java
// public class LLVMPointer<T extends LLVMType> extends LLVMType {
// 	private T internalType;
// 
// 	LLVMPointer(T internalType) {
// 		this.internalType = internalType;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return internalType.toString() + "*";
// 	}
// 
// 	@Override
// 	public boolean equals(Object o) {
// 		if (this == o) return true;
// 		if (o == null || getClass() != o.getClass()) return false;
// 
// 		LLVMPointer that = (LLVMPointer) o;
// 
// 		if (!internalType.equals(that.internalType)) return false;
// 
// 		return true;
// 	}
// 
// 	@Override
// 	public int hashCode() {
// 		return internalType.hashCode();
// 	}
// 
// 	public T getInternalType() {
// 		return internalType;
// 	}
// }
// 
// Path: src/main/java/de/uni/bremen/monty/moco/codegeneration/types/LLVMTypeFactory.java
// public static class LLVMBool extends LLVMSimpleType implements LLVMIntType {
// 	public LLVMBool() {
// 		super("i1");
// 	}
// }
// 
// Path: src/main/java/de/uni/bremen/monty/moco/codegeneration/types/LLVMTypeFactory.java
// public static interface LLVMIntType {
// }
// 
// Path: src/main/java/de/uni/bremen/monty/moco/codegeneration/types/LLVMTypeFactory.java
// public static <T extends LLVMType> LLVMPointer<T> pointer(T type) {
// 	return new LLVMPointer<>(type);
// }


import de.uni.bremen.monty.moco.codegeneration.identifier.FunctionSignature;
import de.uni.bremen.monty.moco.codegeneration.identifier.LLVMIdentifier;
import de.uni.bremen.monty.moco.codegeneration.types.LLVMPointer;
import de.uni.bremen.monty.moco.codegeneration.types.LLVMStructType;
import de.uni.bremen.monty.moco.codegeneration.types.LLVMType;
import de.uni.bremen.monty.moco.codegeneration.types.LLVMTypeFactory.LLVMBool;
import de.uni.bremen.monty.moco.codegeneration.types.LLVMTypeFactory.LLVMIntType;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
import java.util.List;
import static de.uni.bremen.monty.moco.codegeneration.types.LLVMTypeFactory.pointer;

		private Linkage(String name) {
			this.name = name;
		}

		private Linkage() {

		}

		public String toString() {
			if (name == null) {
				return name();
			} else {
				return name;
			}
		}
	}

	/** Return instruction for functions
	 *
	 * @param llvmIdentifier
	 *            Value to return */
	public void ret(LLVMIdentifier<?> llvmIdentifier) {
		appendLine("ret " + llvmIdentifier);
	}

	/** Declares a function. Declare means the implementation of the function is somewhere else.
	 *
	 * @param functionSignature
	 *            Name and return type of the function */
// Path: src/main/java/de/uni/bremen/monty/moco/codegeneration/identifier/FunctionSignature.java
// public class FunctionSignature<T extends LLVMType> extends LLVMIdentifier<T> {
// 
// 	private List<LLVMIdentifier<? extends LLVMType>> parameter;
// 
// 	FunctionSignature(T type, String name, List<LLVMIdentifier<? extends LLVMType>> parameter) {
// 		super(type, name, false);
// 		this.parameter = parameter;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return type + " " + name + "(" + StringUtils.join(parameter, ", ") + ")";
// 	}
// }
// 
// Path: src/main/java/de/uni/bremen/monty/moco/codegeneration/identifier/LLVMIdentifier.java
// public class LLVMIdentifier<T extends LLVMType> {
// 	protected final String name;
// 	protected final T type;
// 
// 	/** This is indicates if this value is a concrete value, or a pointer to a value, that needs to be resolved or
// 	 * dereference to gets its value. */
// 	private boolean resolvable;
// 
// 	/** Don't use this. Only {@link LLVMIdentifierFactory} should create instances.
// 	 *
// 	 * @param type
// 	 * @param name
// 	 * @param resolvable */
// 	LLVMIdentifier(T type, String name, boolean resolvable) {
// 		this.name = name;
// 		this.type = type;
// 		this.resolvable = resolvable;
// 	}
// 
// 	public String getName() {
// 		return name;
// 	}
// 
// 	public T getType() {
// 		return type;
// 	}
// 
// 	/** @returns the LLVM-IR representation. e.g. new LLVMIdentifier(pointer(int64(),"%foobar").toString() ==
// 	 *          "i64* %foobar" */
// 	@Override
// 	public String toString() {
// 		return type + " " + getName();
// 	}
// 
// 	/** Is it a value or a pointer to value
// 	 *
// 	 * @return true if its a pointer to a value */
// 	public boolean needToBeResolved() {
// 		return resolvable;
// 	}
// 
// }
// 
// Path: src/main/java/de/uni/bremen/monty/moco/codegeneration/types/LLVMPointer.java
// public class LLVMPointer<T extends LLVMType> extends LLVMType {
// 	private T internalType;
// 
// 	LLVMPointer(T internalType) {
// 		this.internalType = internalType;
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return internalType.toString() + "*";
// 	}
// 
// 	@Override
// 	public boolean equals(Object o) {
// 		if (this == o) return true;
// 		if (o == null || getClass() != o.getClass()) return false;
// 
// 		LLVMPointer that = (LLVMPointer) o;
// 
// 		if (!internalType.equals(that.internalType)) return false;
// 
// 		return true;
// 	}
// 
// 	@Override
// 	public int hashCode() {
// 		return internalType.hashCode();
// 	}
// 
// 	public T getInternalType() {
// 		return internalType;
// 	}
// }
// 
// Path: src/main/java/de/uni/bremen/monty/moco/codegeneration/types/LLVMTypeFactory.java
// public static class LLVMBool extends LLVMSimpleType implements LLVMIntType {
// 	public LLVMBool() {
// 		super("i1");
// 	}
// }
// 
// Path: src/main/java/de/uni/bremen/monty/moco/codegeneration/types/LLVMTypeFactory.java
// public static interface LLVMIntType {
// }
// 
// Path: src/main/java/de/uni/bremen/monty/moco/codegeneration/types/LLVMTypeFactory.java
// public static <T extends LLVMType> LLVMPointer<T> pointer(T type) {
// 	return new LLVMPointer<>(type);
// }


// Path: src/main/java/de/uni/bremen/monty/moco/codegeneration/context/CodeContext.java
import de.uni.bremen.monty.moco.codegeneration.identifier.FunctionSignature;
import de.uni.bremen.monty.moco.codegeneration.identifier.LLVMIdentifier;
import de.uni.bremen.monty.moco.codegeneration.types.LLVMPointer;
import de.uni.bremen.monty.moco.codegeneration.types.LLVMStructType;
import de.uni.bremen.monty.moco.codegeneration.types.LLVMType;
import de.uni.bremen.monty.moco.codegeneration.types.LLVMTypeFactory.LLVMBool;
import de.uni.bremen.monty.moco.codegeneration.types.LLVMTypeFactory.LLVMIntType;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
import java.util.List;
import static de.uni.bremen.monty.moco.codegeneration.types.LLVMTypeFactory.pointer;


		private Linkage(String name) {
			this.name = name;
		}

		private Linkage() {

		}

		public String toString() {
			if (name == null) {
				return name();
			} else {
				return name;
			}
		}
	}

	/** Return instruction for functions
	 *
	 * @param llvmIdentifier
	 *            Value to return */
	public void ret(LLVMIdentifier<?> llvmIdentifier) {
		appendLine("ret " + llvmIdentifier);
	}

	/** Declares a function. Declare means the implementation of the function is somewhere else.
	 *
	 * @param functionSignature
	 *            Name and return type of the function */
	public void declare(FunctionSignature<LLVMType> functionSignature) {