diff --git a/OMCompiler/Compiler/NFFrontEnd/NFExpression.mo b/OMCompiler/Compiler/NFFrontEnd/NFExpression.mo index 75a37b79e50..3b93dce875e 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFExpression.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFExpression.mo @@ -4478,6 +4478,13 @@ public case RECORD() then listGet(recordExp.elements, index); + case CREF() + algorithm + Type.COMPLEX(cls = node) := Type.arrayElementType(typeOf(recordExp)); + node := Class.nthComponent(index, InstNode.getClass(node)); + then + fromCref(ComponentRef.prefixCref(node, InstNode.getType(node), {}, recordExp.cref)); + case ARRAY(elements = {}, ty = Type.ARRAY(elementType = Type.COMPLEX(cls = node))) then makeEmptyArray(InstNode.getType(Class.nthComponent(index, InstNode.getClass(node)))); diff --git a/OMCompiler/Compiler/NFFrontEnd/NFInst.mo b/OMCompiler/Compiler/NFFrontEnd/NFInst.mo index 61c4a3d3157..ceb294630ed 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFInst.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFInst.mo @@ -174,13 +174,13 @@ algorithm // Apply simplifications to the model. flatModel := SimplifyModel.simplify(flatModel); - // Collect a tree of all functions that are still used in the flat model. - functions := Flatten.collectFunctions(flatModel); - // Collect package constants that couldn't be substituted with their values // (e.g. because they where used with non-constant subscripts), and add them // to the model. - flatModel := Package.collectConstants(flatModel, functions); + flatModel := Package.collectConstants(flatModel); + + // Collect a tree of all functions that are still used in the flat model. + functions := Flatten.collectFunctions(flatModel); // Dump the flat model to a stream if dumpFlat = true. flatString := if dumpFlat then diff --git a/OMCompiler/Compiler/NFFrontEnd/NFPackage.mo b/OMCompiler/Compiler/NFFrontEnd/NFPackage.mo index e6a1646c7d5..3d8ea444404 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFPackage.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFPackage.mo @@ -51,6 +51,7 @@ protected import NFInstNode.InstNode; import Sections = NFSections; import Statement = NFStatement; + import Type = NFType; import Typing = NFTyping; import Variable = NFVariable; @@ -78,7 +79,6 @@ public public function collectConstants input output FlatModel flatModel; - input FunctionTree functions; protected list vars; Constants constants; @@ -89,7 +89,7 @@ public constants := Equation.foldExpList(flatModel.initialEquations, collectExpConstants, constants); constants := Algorithm.foldExpList(flatModel.algorithms, collectExpConstants, constants); constants := Algorithm.foldExpList(flatModel.initialAlgorithms, collectExpConstants, constants); - constants := FunctionTree.fold(functions, collectFuncConstants, constants); + //constants := FunctionTree.fold(functions, collectFuncConstants, constants); vars := listReverse(Variable.fromCref(c) for c in Constants.listKeys(constants)); vars := listAppend(Variable.expand(v) for v in vars); @@ -142,18 +142,17 @@ public input output Constants constants; protected ComponentRef cref; + Binding binding; algorithm () := match exp case Expression.CREF(cref = cref as ComponentRef.CREF()) algorithm if ComponentRef.isPackageConstant(cref) then - Typing.typeComponentBinding(cref.node, NFInstContext.CLASS); + binding := getPackageConstantBinding(cref); // Add the constant to the set. constants := Constants.add(constants, ComponentRef.stripSubscriptsAll(cref)); // Collect constants from the constant's binding. - constants := collectBindingConstants( - Component.getBinding(InstNode.component(ComponentRef.node(cref))), - constants); + constants := collectBindingConstants(binding, constants); end if; then (); @@ -162,6 +161,54 @@ public end match; end collectExpConstants_traverser; + function getPackageConstantBinding + input ComponentRef cref; + output Binding binding; + protected + InstNode cr_node = ComponentRef.node(cref); + algorithm + Typing.typeComponentBinding(cr_node, NFInstContext.CLASS); + binding := Component.getImplicitBinding(InstNode.component(cr_node)); + + if Binding.isUnbound(binding) then + binding := getPackageConstantBinding2(cr_node, ComponentRef.rest(cref)); + InstNode.componentApply(cr_node, Component.setBinding, binding); + end if; + end getPackageConstantBinding; + + function getPackageConstantBinding2 + input InstNode fieldNode; + input ComponentRef cref; + output Binding binding; + protected + InstNode cr_node; + Boolean is_record; + algorithm + if not ComponentRef.isCref(cref) then + binding := NFBinding.EMPTY_BINDING; + return; + end if; + + is_record := Type.isRecord(Type.arrayElementType(ComponentRef.nodeType(cref))); + cr_node := ComponentRef.node(cref); + + if not (InstNode.isComponent(cr_node) and is_record) then + binding := NFBinding.EMPTY_BINDING; + return; + end if; + + Typing.typeComponentBinding(cr_node, NFInstContext.CLASS); + binding := Component.getBinding(InstNode.component(cr_node)); + + if Binding.isUnbound(binding) then + binding := getPackageConstantBinding2(cr_node, ComponentRef.rest(cref)); + end if; + + if Binding.isBound(binding) then + binding := Binding.recordFieldBinding(fieldNode, binding); + end if; + end getPackageConstantBinding2; + function collectFuncConstants input Absyn.Path name; input Function func; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFVariable.mo b/OMCompiler/Compiler/NFFrontEnd/NFVariable.mo index 3b0024cea5f..4de90e0e2f6 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFVariable.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFVariable.mo @@ -77,7 +77,7 @@ public node := ComponentRef.node(cref); comp := InstNode.component(node); ty := ComponentRef.getSubscriptedType(cref); - binding := Component.getBinding(comp); + binding := Component.getImplicitBinding(comp); vis := InstNode.visibility(node); attr := Component.getAttributes(comp); cmt := Component.comment(comp); @@ -104,6 +104,7 @@ public Expression.arrayScalarElements(ExpandExp.expandCref(Expression.fromCref(var.name)))); v := var; + v.ty := Type.arrayElementType(v.ty); vars := {}; binding := var.binding; diff --git a/OMCompiler/Compiler/Script/NFApi.mo b/OMCompiler/Compiler/Script/NFApi.mo index f10595fe085..ebc711fe17c 100644 --- a/OMCompiler/Compiler/Script/NFApi.mo +++ b/OMCompiler/Compiler/Script/NFApi.mo @@ -697,13 +697,9 @@ algorithm flat_model := EvalConstants.evaluate(flat_model); flat_model := UnitCheck.checkUnits(flat_model); flat_model := SimplifyModel.simplify(flat_model); + flat_model := Package.collectConstants(flat_model); funcs := Flatten.collectFunctions(flat_model); - // Collect package constants that couldn't be substituted with their values - // (e.g. because they where used with non-constant subscripts), and add them - // to the model. - flat_model := Package.collectConstants(flat_model, funcs); - // Scalarize array components in the flat model. if Flags.isSet(Flags.NF_SCALARIZE) then flat_model := Scalarize.scalarize(flat_model); diff --git a/testsuite/flattening/modelica/scodeinst/Makefile b/testsuite/flattening/modelica/scodeinst/Makefile index 2889e2ff4ce..50b75e9579d 100644 --- a/testsuite/flattening/modelica/scodeinst/Makefile +++ b/testsuite/flattening/modelica/scodeinst/Makefile @@ -728,6 +728,7 @@ OperatorOverloadError1.mo \ OperatorOverloadSum1.mo \ PackageConstant1.mo \ PackageConstant3.mo \ +PackageConstant4.mo \ ParameterBug.mos \ PartialApplication1.mo \ PartialApplicationInvalidArg1.mo \ diff --git a/testsuite/flattening/modelica/scodeinst/PackageConstant3.mo b/testsuite/flattening/modelica/scodeinst/PackageConstant3.mo index fa535d00676..973ece678ca 100644 --- a/testsuite/flattening/modelica/scodeinst/PackageConstant3.mo +++ b/testsuite/flattening/modelica/scodeinst/PackageConstant3.mo @@ -18,15 +18,21 @@ package P end ext_func; end P; -model M +model PackageConstant3 Real x = P.r[1].x; -end M; +end PackageConstant3; // Result: -// class M +// function P.ext_func +// output Real x; +// +// external "C" x = ext_func(); +// end P.ext_func; +// +// class PackageConstant3 // parameter Real P.r[1].x = P.ext_func(); // parameter Real P.r[2].x = P.ext_func(); // parameter Real P.r[3].x = P.ext_func(); // Real x = P.r[1].x; -// end M; +// end PackageConstant3; // endResult diff --git a/testsuite/flattening/modelica/scodeinst/PackageConstant4.mo b/testsuite/flattening/modelica/scodeinst/PackageConstant4.mo new file mode 100644 index 00000000000..7c86f5e4e05 --- /dev/null +++ b/testsuite/flattening/modelica/scodeinst/PackageConstant4.mo @@ -0,0 +1,38 @@ +// name: PackageConstant4 +// keywords: +// status: correct +// cflags: -d=newInst +// + +package P + record R + Real x; + end R; + + parameter R r1(x = ext_func()); + parameter R r2[1] = {r1}; + + function ext_func + output Real x; + + external "C"; + end ext_func; +end P; + +model PackageConstant4 + Real x = P.r2[1].x; +end PackageConstant4; + +// Result: +// function P.ext_func +// output Real x; +// +// external "C" x = ext_func(); +// end P.ext_func; +// +// class PackageConstant4 +// parameter Real P.r1.x = P.ext_func(); +// parameter Real P.r2[1].x = P.r1.x; +// Real x = P.r2[1].x; +// end PackageConstant4; +// endResult