All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.qbicc.machine.llvm.impl.FunctionDefinitionImpl Maven / Gradle / Ivy

package org.qbicc.machine.llvm.impl;

import java.io.IOException;

import org.qbicc.machine.llvm.AddressNaming;
import org.qbicc.machine.llvm.CallingConvention;
import org.qbicc.machine.llvm.DllStorageClass;
import org.qbicc.machine.llvm.FunctionDefinition;
import org.qbicc.machine.llvm.LLBasicBlock;
import org.qbicc.machine.llvm.LLValue;
import org.qbicc.machine.llvm.Linkage;
import org.qbicc.machine.llvm.RuntimePreemption;
import org.qbicc.machine.llvm.Visibility;
import io.smallrye.common.constraint.Assert;

/**
 *
 */
final class FunctionDefinitionImpl extends AbstractFunction implements FunctionDefinition {
    final ModuleImpl module;
    final BasicBlockImpl rootBlock = new BasicBlockImpl(null, this);
    BasicBlockImpl lastBlock = rootBlock;
    String section;
    RuntimePreemption preemption = RuntimePreemption.PREEMPTABLE;
    private int blockCounter;
    private int localCounter;
    private String gc = null;
    private AbstractValue personalityType = null;
    private AbstractValue personalityValue = null;

    FunctionDefinitionImpl(final ModuleImpl module, final String name) {
        super(name);
        this.module = module;
    }

    public FunctionDefinition section(final String section) {
        this.section = Assert.checkNotNullParam("section", section);
        return this;
    }

    public FunctionDefinition preemption(final RuntimePreemption preemption) {
        this.preemption = Assert.checkNotNullParam("preemption", preemption);
        return this;
    }

    @Override
    public FunctionDefinition personality(final LLValue personalityValue, final LLValue personalityType) {
        this.personalityValue = (AbstractValue) Assert.checkNotNullParam("personalityValue", personalityValue);
        this.personalityType = (AbstractValue) Assert.checkNotNullParam("personalityType", personalityType);
        return this;
    }

    @Override
    public FunctionDefinition gc(String gc) {
        this.gc = gc;
        return this;
    }

    //////////////////////////
    // Override return type //
    //////////////////////////

    public FunctionDefinitionImpl linkage(final Linkage linkage) {
        super.linkage(linkage);
        return this;
    }

    public FunctionDefinitionImpl visibility(final Visibility visibility) {
        super.visibility(visibility);
        return this;
    }

    public FunctionDefinitionImpl dllStorageClass(final DllStorageClass dllStorageClass) {
        super.dllStorageClass(dllStorageClass);
        return this;
    }

    public FunctionDefinitionImpl callingConvention(final CallingConvention callingConvention) {
        super.callingConvention(callingConvention);
        return this;
    }

    public FunctionDefinitionImpl addressNaming(final AddressNaming addressNaming) {
        super.addressNaming(addressNaming);
        return this;
    }

    public FunctionDefinitionImpl addressSpace(final int addressSpace) {
        super.addressSpace(addressSpace);
        return this;
    }

    public FunctionDefinitionImpl alignment(final int alignment) {
        super.alignment(alignment);
        return this;
    }

    public FunctionDefinitionImpl variadic() {
        super.variadic();
        return this;
    }

    public FunctionDefinitionImpl meta(final String name, final LLValue data) {
        super.meta(name, data);
        return this;
    }

    public FunctionDefinitionImpl comment(final String comment) {
        super.comment(comment);
        return this;
    }

    ///////////////////////
    // Basic block stuff //
    ///////////////////////

    public LLBasicBlock createBlock() {
        return lastBlock = new BasicBlockImpl(lastBlock, this);
    }

    public LLBasicBlock getRootBlock() {
        return rootBlock;
    }

    ////////////
    // Output //
    ////////////

    private void appendPreemption(final Appendable target) throws IOException {
        if (preemption != RuntimePreemption.PREEMPTABLE) {
            target.append(preemption.toString()).append(' ');
        }
    }

    private void appendSection(final Appendable target) throws IOException {
        if (section != null) {
            target.append(" section ");
            appendEscapedString(target, section);
        }
    }

    private void appendGc(final Appendable target) throws IOException {
        if (gc != null) {
            target.append(" gc ");
            appendEscapedString(target, gc);
        }
    }

    private void appendPersonality(final Appendable target) throws IOException {
        if (personalityValue != null) {
            target.append(" personality ");
            personalityType.appendTo(target);
            personalityValue.appendTo(target);
        }
    }

    @Override
    public Appendable appendTo(Appendable target) throws IOException {
        target.append("define ");
        appendLinkage(target);
        appendPreemption(target);
        appendVisibility(target);
        appendDllStorageClass(target);
        appendCallingConvention(target);
        appendNameAndType(target);
        appendAddressNaming(target);
        appendAddressSpace(target);
        appendFunctionAttributes(target);
        appendAlign(target);
        appendSection(target);
        appendGc(target);
        appendPersonality(target);
        appendMeta(target);
        target.append(" {");
        appendComment(target);
        target.append(System.lineSeparator());
        lastBlock.appendAsBlockTo(target);
        target.append('}');

        return target;
    }

    void assignName(final BasicBlockImpl basicBlock) {
        basicBlock.name("B" + Integer.toHexString(blockCounter++));
    }

    int nextLocalId() {
        return localCounter++;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy