CommonAtomicLockAssignStatement.java
package dev.civl.mc.model.common.statement;
import java.util.HashSet;
import java.util.Set;
import dev.civl.mc.model.IF.CIVLSource;
import dev.civl.mc.model.IF.Scope;
import dev.civl.mc.model.IF.expression.Expression;
import dev.civl.mc.model.IF.expression.LHSExpression;
import dev.civl.mc.model.IF.location.Location;
import dev.civl.mc.model.IF.statement.AtomicLockAssignStatement;
import dev.civl.mc.model.IF.variable.Variable;
/**
* When translating an $atomic block, we need to create a noop statement at the
* beginning and at the end of the block. In order to have more information
* about the transitions, we create this class to extend
* {@link CommonNoopStatement}. Currently, there is a field {@link #enter} to
* denote if the statement is
* <ol>
* <li>entering an $atomic block; or</li>
* <li>leaving an $atomic block.</li>
* </ol>
*
* @author Manchun Zheng (zmanchun)
*
*/
public class CommonAtomicLockAssignStatement extends CommonAssignStatement
implements
AtomicLockAssignStatement {
/* *************************** Instance Fields ************************* */
/**
* Denote if this statement is
* <ol>
* <li>enter == true: entering an $atomic or</li>
* <li>enter == false: leaving an $atomic block.</li>
* </ol>
*/
private boolean enter;
/**
* The external variables which are accessed in the atomic region, or null.
*/
private Set<Variable> variables = null;
/* **************************** Constructors *************************** */
/**
*
* @param civlSource
* The CIVL source of this statement. More information in
* {@link CIVLSource}.
* @param source
* The source location of this goto statement
* @param atomicKind
* The atomic kind of this statement
*/
public CommonAtomicLockAssignStatement(CIVLSource civlSource, Scope hscope,
Scope lscope, Location source, Expression guard, boolean isEntering,
LHSExpression lhs, Expression rhs) {
super(civlSource, hscope, lscope, source, guard, lhs, rhs, false);
this.enter = isEntering;
}
/* ************************* Methods from Object *********************** */
@Override
public String toString() {
String result = super.toString();
if (enter) {
result = "ENTER_ATOMIC (" + result + ", atomicCount++; vars=";
if (variables == null)
result += "unknown";
else
result += variables.toString();
result += ")";
} else
result = "LEAVE_ATOMIC (" + result + ", atomicCount--)";
return result;
}
public void setVariables(Set<Variable> variables) {
this.variables = variables;
}
@Override
public Set<Variable> getVariables() {
return variables;
}
@Override
public Set<Variable> variableAddressedOf(Scope scope) {
return null;
}
@Override
public Set<Variable> variableAddressedOf() {
return null;
}
@Override
public void calculateDerefs() {
this.hasDerefs = false;
}
@Override
public boolean enterAtomic() {
return this.enter;
}
@Override
public boolean leaveAtomic() {
return !this.enter;
}
@Override
public boolean equals(Object obj) {
if (super.equals(obj)) {
if (obj instanceof CommonAtomicLockAssignStatement) {
CommonAtomicLockAssignStatement other = (CommonAtomicLockAssignStatement) obj;
return other.enter == enter;
}
}
return false;
}
@Override
public Set<Variable> freeVariables() {
return new HashSet<>();
}
}