diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java b/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java index 2be122ebb..276548bac 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java @@ -5,8 +5,6 @@ import dk.camelot64.kickc.model.*; import dk.camelot64.kickc.model.iterator.ProgramValueIterator; import dk.camelot64.kickc.model.statements.*; import dk.camelot64.kickc.model.symbols.Procedure; -import dk.camelot64.kickc.model.symbols.ProgramScope; -import dk.camelot64.kickc.model.symbols.StructDefinition; import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolTypeInference; @@ -71,9 +69,9 @@ public class Pass1UnwindStructValues extends Pass1Base { getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> { if(programValue.get() instanceof StructMemberRef) { StructMemberRef structMemberRef = (StructMemberRef) programValue.get(); - final ValueSource structValueSource = getValueSource(getProgram(), getScope(), structMemberRef.getStruct(), currentStmt, stmtIt, currentBlock); + final ValueSource structValueSource = ValueSourceFactory.getValueSource(structMemberRef.getStruct(), getProgram(), getScope(), currentStmt, stmtIt, currentBlock); if(structValueSource != null) { - final ValueSource memberUnwinding = structValueSource.getMemberUnwinding(structMemberRef.getMemberName(), getProgram(), getScope(), currentStmt, currentBlock, stmtIt); + final ValueSource memberUnwinding = structValueSource.getMemberUnwinding(structMemberRef.getMemberName(), getProgram(), getScope(), currentStmt, stmtIt, currentBlock); RValue memberSimpleValue = memberUnwinding.getSimpleValue(getScope()); getLog().append("Replacing struct member reference " + structMemberRef.toString(getProgram()) + " with member unwinding reference " + memberSimpleValue.toString(getProgram())); programValue.set(memberSimpleValue); @@ -93,11 +91,11 @@ public class Pass1UnwindStructValues extends Pass1Base { // Unwind struct value return value boolean lvalUnwound = false; - final ValueSource lValueSource = getValueSource(getProgram(), getScope(), call.getlValue(), call, stmtIt, currentBlock); + final ValueSource lValueSource = ValueSourceFactory.getValueSource(call.getlValue(), getProgram(), getScope(), call, stmtIt, currentBlock); if(lValueSource != null && lValueSource.isUnwindable()) { ArrayList unwoundMembers = new ArrayList<>(); for(String memberName : lValueSource.getMemberNames(getScope())) { - ValueSource memberUnwinding = lValueSource.getMemberUnwinding(memberName, getProgram(), getScope(), call, currentBlock, stmtIt); + ValueSource memberUnwinding = lValueSource.getMemberUnwinding(memberName, getProgram(), getScope(), call, stmtIt, currentBlock); unwoundMembers.add(memberUnwinding.getSimpleValue(getScope())); } ValueList unwoundLValue = new ValueList(unwoundMembers); @@ -111,11 +109,11 @@ public class Pass1UnwindStructValues extends Pass1Base { boolean anyParameterUnwound = false; for(RValue parameter : call.getParameters()) { boolean unwound = false; - final ValueSource parameterSource = getValueSource(getProgram(), getScope(), parameter, call, stmtIt, currentBlock); + final ValueSource parameterSource = ValueSourceFactory.getValueSource(parameter, getProgram(), getScope(), call, stmtIt, currentBlock); if(parameterSource != null && parameterSource.isUnwindable()) { // Passing a struct variable - convert it to member variables for(String memberName : parameterSource.getMemberNames(getScope())) { - ValueSource memberUnwinding = parameterSource.getMemberUnwinding(memberName, getProgram(), getScope(), call, currentBlock, stmtIt); + ValueSource memberUnwinding = parameterSource.getMemberUnwinding(memberName, getProgram(), getScope(), call, stmtIt, currentBlock); unwoundParameters.add(memberUnwinding.getSimpleValue(getScope())); } unwound = true; @@ -143,11 +141,11 @@ public class Pass1UnwindStructValues extends Pass1Base { private boolean unwindReturn(StatementReturn statementReturn, ListIterator stmtIt, ControlFlowBlock currentBlock) { boolean modified = false; // Unwind struct value return value - final ValueSource returnVarUnwinding = getValueSource(getProgram(), getScope(), statementReturn.getValue(), statementReturn, stmtIt, currentBlock); + final ValueSource returnVarUnwinding = ValueSourceFactory.getValueSource(statementReturn.getValue(), getProgram(), getScope(), statementReturn, stmtIt, currentBlock); if(returnVarUnwinding != null && returnVarUnwinding.isUnwindable()) { ArrayList unwoundMembers = new ArrayList<>(); for(String memberName : returnVarUnwinding.getMemberNames(getScope())) { - final ValueSource memberUnwinding = returnVarUnwinding.getMemberUnwinding(memberName, getProgram(), getScope(), statementReturn, currentBlock, stmtIt); + final ValueSource memberUnwinding = returnVarUnwinding.getMemberUnwinding(memberName, getProgram(), getScope(), statementReturn, stmtIt, currentBlock); unwoundMembers.add(memberUnwinding.getSimpleValue(getScope())); } ValueList unwoundReturnValue = new ValueList(unwoundMembers); @@ -213,8 +211,8 @@ public class Pass1UnwindStructValues extends Pass1Base { if(rValue instanceof MemcpyValue || rValue instanceof MemsetValue || rValue instanceof StructUnwoundPlaceholder) return false; - ValueSource lValueSource = getValueSource(getProgram(), getScope(), lValue, assignment, stmtIt, currentBlock); - ValueSource rValueSource = getValueSource(getProgram(), getScope(), rValue, assignment, stmtIt, currentBlock); + ValueSource lValueSource = ValueSourceFactory.getValueSource(lValue, getProgram(), getScope(), assignment, stmtIt, currentBlock); + ValueSource rValueSource = ValueSourceFactory.getValueSource(rValue, getProgram(), getScope(), assignment, stmtIt, currentBlock); List lValueUnwoundList = new ArrayList<>(); if(copyValues(lValueSource, rValueSource, lValueUnwoundList, initialAssignment, assignment, currentBlock, stmtIt)) { if(lValue instanceof VariableRef) { @@ -261,8 +259,8 @@ public class Pass1UnwindStructValues extends Pass1Base { } else if(lValueSource.isUnwindable() && rValueSource.isUnwindable()) { getLog().append("Unwinding value copy " + currentStmt.toString(getProgram(), false)); for(String memberName : lValueSource.getMemberNames(getScope())) { - ValueSource lValueSubSource = lValueSource.getMemberUnwinding(memberName, getProgram(), getScope(), currentStmt, currentBlock, stmtIt); - ValueSource rValueSubSource = rValueSource.getMemberUnwinding(memberName, getProgram(), getScope(), currentStmt, currentBlock, stmtIt); + ValueSource lValueSubSource = lValueSource.getMemberUnwinding(memberName, getProgram(), getScope(), currentStmt, stmtIt, currentBlock); + ValueSource rValueSubSource = rValueSource.getMemberUnwinding(memberName, getProgram(), getScope(), currentStmt, stmtIt, currentBlock); boolean success = copyValues(lValueSubSource, rValueSubSource, lValueUnwoundList, initialAssignment, currentStmt, currentBlock, stmtIt); if(!success) throw new InternalError("Error during value unwinding copy! ", currentStmt); @@ -272,48 +270,4 @@ public class Pass1UnwindStructValues extends Pass1Base { return false; } - /** - * Get a value source for copying a value - * - * @param value The value being copied - * @param currentStmt The current statement - * @param stmtIt The statement iterator - * @param currentBlock The current block - * @return The value source for copying. null if no value source can be created. - */ - public static ValueSource getValueSource(Program program, ProgramScope programScope, Value value, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { - if(value == null) - return null; - final SymbolType valueType = SymbolTypeInference.inferType(programScope, (RValue) value); - if(valueType instanceof SymbolTypeStruct && value instanceof CastValue && ((CastValue) value).getValue() instanceof ValueList) { - ValueList valueList = (ValueList) ((CastValue) value).getValue(); - final StructDefinition structDefinition = ((SymbolTypeStruct) valueType).getStructDefinition(programScope); - int numMembers = structDefinition.getAllVars(false).size(); - if(numMembers != valueList.getList().size()) { - throw new CompileError("Struct initialization list has wrong size. Need " + numMembers + " got " + valueList.getList().size(), currentStmt); - } - return new ValueSourceStructValueList(valueList, structDefinition); - } - while(value instanceof CastValue) - value = ((CastValue) value).getValue(); - if(value instanceof VariableRef) { - Variable variable = programScope.getVariable((VariableRef) value); - return new ValueSourceVariable(variable); - } - if(value instanceof StructZero) - return new ValueSourceZero(((StructZero) value).getTypeStruct(), null); - if(value instanceof ConstantValue) - return new ValueSourceConstant(((ConstantValue) value).getType(programScope), null, (ConstantValue) value); - if(value instanceof PointerDereferenceSimple) - return new ValueSourcePointerDereferenceSimple((PointerDereferenceSimple) value, valueType, null); - if(value instanceof PointerDereferenceIndexed) - return new ValueSourcePointerDereferenceIndexed((PointerDereferenceIndexed) value, valueType, null); - if(value instanceof StructMemberRef) { - final RValue structValue = ((StructMemberRef) value).getStruct(); - final ValueSource structValueSource = getValueSource(program, programScope, structValue, currentStmt, stmtIt, currentBlock); - return structValueSource.getMemberUnwinding(((StructMemberRef) value).getMemberName(), program, programScope, currentStmt, currentBlock, stmtIt); - } - return null; - } - } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantInlining.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantInlining.java index edd7f72c3..aa1fdd2df 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantInlining.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantInlining.java @@ -3,7 +3,9 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.iterator.ProgramValue; import dk.camelot64.kickc.model.iterator.ProgramValueIterator; -import dk.camelot64.kickc.model.symbols.*; +import dk.camelot64.kickc.model.symbols.ProgramScope; +import dk.camelot64.kickc.model.symbols.Symbol; +import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.values.*; @@ -89,7 +91,7 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization { Collection allConstants = getProgram().getScope().getAllConstants(true); for(Variable constant : allConstants) { if(constant.getRef().isIntermediate()) { - if(!(constant.getType().equals(SymbolType.STRING)) && !(constant.getInitValue() instanceof ConstantArray) && !(constant.getInitValue() instanceof ConstantStructValue)) { + if(!(constant.getType().equals(SymbolType.STRING)) && !(constant.getInitValue() instanceof ConstantArray) && !(constant.getInitValue() instanceof ConstantStructValue) && !(constant.getInitValue() instanceof StructZero)) { unnamed.put(constant.getConstantRef(), constant.getInitValue()); } } diff --git a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSource.java b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSource.java index 40c27afa8..c7e0888ce 100644 --- a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSource.java +++ b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSource.java @@ -84,10 +84,10 @@ public interface ValueSource { * @param program * @param programScope The program scope * @param currentStmt - * @param currentBlock * @param stmtIt + * @param currentBlock * @return The unwinding of the member */ - ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ControlFlowBlock currentBlock, ListIterator stmtIt); + ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock); } diff --git a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceConstant.java b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceConstant.java index b684a79de..45e9dd922 100644 --- a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceConstant.java +++ b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceConstant.java @@ -1,6 +1,7 @@ package dk.camelot64.kickc.passes.unwinding; import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Initializers; import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.symbols.*; @@ -44,14 +45,22 @@ public class ValueSourceConstant extends ValueSourceBase { } @Override - public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ControlFlowBlock currentBlock, ListIterator stmtIt) { + public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { StructDefinition structDefinition = ((SymbolTypeStruct) getSymbolType()).getStructDefinition(programScope); - ConstantStructValue constantStructValue = (ConstantStructValue) value; - final Variable member = structDefinition.getMember(memberName); - final SymbolType type = member.getType(); - final ArraySpec arraySpec = member.getArraySpec(); - final ConstantValue memberValue = constantStructValue.getValue(member.getRef()); - return new ValueSourceConstant(type, arraySpec, memberValue); + if(value instanceof ConstantStructValue) { + ConstantStructValue constantStructValue = (ConstantStructValue) value; + final Variable member = structDefinition.getMember(memberName); + final SymbolType type = member.getType(); + final ArraySpec arraySpec = member.getArraySpec(); + final ConstantValue memberValue = constantStructValue.getValue(member.getRef()); + return new ValueSourceConstant(type, arraySpec, memberValue); + } else if(value instanceof StructZero) { + final SymbolType memberType = structDefinition.getMember(memberName).getType(); + final ArraySpec memberArraySpec = structDefinition.getMember(memberName).getArraySpec(); + final ConstantValue memberZeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(memberType, memberArraySpec), currentStmt.getSource()); + return new ValueSourceConstant(memberType, memberArraySpec, memberZeroValue); + } + throw new InternalError("Not supported "+value); } @Override diff --git a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceFactory.java b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceFactory.java new file mode 100644 index 000000000..54c0c8518 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceFactory.java @@ -0,0 +1,66 @@ +package dk.camelot64.kickc.passes.unwinding; + +import dk.camelot64.kickc.model.CompileError; +import dk.camelot64.kickc.model.ControlFlowBlock; +import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.statements.Statement; +import dk.camelot64.kickc.model.symbols.ProgramScope; +import dk.camelot64.kickc.model.symbols.StructDefinition; +import dk.camelot64.kickc.model.symbols.Variable; +import dk.camelot64.kickc.model.types.SymbolType; +import dk.camelot64.kickc.model.types.SymbolTypeInference; +import dk.camelot64.kickc.model.types.SymbolTypeStruct; +import dk.camelot64.kickc.model.values.*; + +import java.util.ListIterator; + +public class ValueSourceFactory { + + /** + * Get a value source for copying a value + * + * @param value The value being copied + * @param currentStmt The current statement + * @param stmtIt The statement iterator + * @param currentBlock The current block + * @return The value source for copying. null if no value source can be created. + */ + public static ValueSource getValueSource(Value value, Program program, ProgramScope programScope, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { + if(value == null) + return null; + final SymbolType valueType = SymbolTypeInference.inferType(programScope, (RValue) value); + if(valueType instanceof SymbolTypeStruct && value instanceof CastValue && ((CastValue) value).getValue() instanceof ValueList) { + ValueList valueList = (ValueList) ((CastValue) value).getValue(); + final StructDefinition structDefinition = ((SymbolTypeStruct) valueType).getStructDefinition(programScope); + int numMembers = structDefinition.getAllVars(false).size(); + if(numMembers != valueList.getList().size()) { + throw new CompileError("Struct initialization list has wrong size. Need " + numMembers + " got " + valueList.getList().size(), currentStmt); + } + return new ValueSourceStructValueList(valueList, structDefinition); + } + while(value instanceof CastValue) + value = ((CastValue) value).getValue(); + if(value instanceof VariableRef) { + Variable variable = programScope.getVariable((VariableRef) value); + return new ValueSourceVariable(variable); + } + if(value instanceof StructZero) { + //final ConstantValue zeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(valueType, null), currentStmt.getSource()); + //return new ValueSourceConstant(valueType, null, zeroValue); + return new ValueSourceZero(((StructZero) value).getTypeStruct(), null); + } + if(value instanceof ConstantValue) + return new ValueSourceConstant(((ConstantValue) value).getType(programScope), null, (ConstantValue) value); + if(value instanceof PointerDereferenceSimple) + return new ValueSourcePointerDereferenceSimple((PointerDereferenceSimple) value, valueType, null); + if(value instanceof PointerDereferenceIndexed) + return new ValueSourcePointerDereferenceIndexed((PointerDereferenceIndexed) value, valueType, null); + if(value instanceof StructMemberRef) { + final RValue structValue = ((StructMemberRef) value).getStruct(); + final ValueSource structValueSource = getValueSource(structValue, program, programScope, currentStmt, stmtIt, currentBlock); + return structValueSource.getMemberUnwinding(((StructMemberRef) value).getMemberName(), program, programScope, currentStmt, stmtIt, currentBlock); + } + return null; + } + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourcePointerDereferenceIndexed.java b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourcePointerDereferenceIndexed.java index 9b3fc2adf..1a8cf7585 100644 --- a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourcePointerDereferenceIndexed.java +++ b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourcePointerDereferenceIndexed.java @@ -68,7 +68,7 @@ public class ValueSourcePointerDereferenceIndexed extends ValueSourceBase { } @Override - public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ControlFlowBlock currentBlock, ListIterator stmtIt) { + public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { StructDefinition structDefinition = ((SymbolTypeStruct) getSymbolType()).getStructDefinition(programScope); final SymbolType memberType = structDefinition.getMember(memberName).getType(); final ArraySpec memberArraySpec = structDefinition.getMember(memberName).getArraySpec(); diff --git a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourcePointerDereferenceSimple.java b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourcePointerDereferenceSimple.java index 44a317bc4..7d411bb18 100644 --- a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourcePointerDereferenceSimple.java +++ b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourcePointerDereferenceSimple.java @@ -61,7 +61,7 @@ public class ValueSourcePointerDereferenceSimple extends ValueSourceBase { } @Override - public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ControlFlowBlock currentBlock, ListIterator stmtIt) { + public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { StructDefinition structDefinition = ((SymbolTypeStruct) getSymbolType()).getStructDefinition(programScope); final SymbolType memberType = structDefinition.getMember(memberName).getType(); final ArraySpec memberArraySpec = structDefinition.getMember(memberName).getArraySpec(); diff --git a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceStructValueList.java b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceStructValueList.java index 59c9a83e3..c70ba6ecb 100644 --- a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceStructValueList.java +++ b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceStructValueList.java @@ -11,7 +11,6 @@ import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.values.LValue; import dk.camelot64.kickc.model.values.RValue; import dk.camelot64.kickc.model.values.ValueList; -import dk.camelot64.kickc.passes.Pass1UnwindStructValues; import java.util.ListIterator; @@ -57,10 +56,10 @@ public class ValueSourceStructValueList extends ValueSourceBase { } @Override - public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ControlFlowBlock currentBlock, ListIterator stmtIt) { + public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { int memberIndex = getMemberNames(programScope).indexOf(memberName); final RValue memberValue = valueList.getList().get(memberIndex); - final ValueSource valueSource = Pass1UnwindStructValues.getValueSource(program, programScope, memberValue, currentStmt, stmtIt, currentBlock); + final ValueSource valueSource = ValueSourceFactory.getValueSource(memberValue, program, programScope, currentStmt, stmtIt, currentBlock); return valueSource; } diff --git a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceVariable.java b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceVariable.java index d33a3a322..61818bbe8 100644 --- a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceVariable.java +++ b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceVariable.java @@ -68,7 +68,7 @@ public class ValueSourceVariable extends ValueSourceBase { } @Override - public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ControlFlowBlock currentBlock, ListIterator stmtIt) { + public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { if(variable.isStructClassic()) { StructDefinition structDefinition = ((SymbolTypeStruct) getSymbolType()).getStructDefinition(programScope); SymbolType memberType = structDefinition.getMember(memberName).getType(); diff --git a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceZero.java b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceZero.java index c85cf9de4..e28ac0122 100644 --- a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceZero.java +++ b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceZero.java @@ -48,7 +48,7 @@ public class ValueSourceZero extends ValueSourceBase { } @Override - public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ControlFlowBlock currentBlock, ListIterator stmtIt) { + public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { StructDefinition structDefinition = ((SymbolTypeStruct) getSymbolType()).getStructDefinition(programScope); final SymbolType memberType = structDefinition.getMember(memberName).getType(); final ArraySpec memberArraySpec = structDefinition.getMember(memberName).getArraySpec();