Skip to content

Commit

Permalink
[NF] Fix record constructor DAE issue.
Browse files Browse the repository at this point in the history
- Create a real record constructor node, instead of using the record
  class itself when creating a record constructor function.

Belonging to [master]:
  - OpenModelica/OMCompiler#2304
  • Loading branch information
perost authored and OpenModelica-Hudson committed Mar 22, 2018
1 parent cd42dc7 commit fb72969
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 37 deletions.
12 changes: 12 additions & 0 deletions Compiler/NFFrontEnd/NFClass.mo
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,18 @@ uniontype Class
Restriction.ENUMERATION());
end fromEnumeration;

function makeRecordConstructor
input list<InstNode> inputs;
input list<InstNode> locals;
input InstNode out;
output Class cls;
protected
ClassTree tree;
algorithm
tree := ClassTree.fromRecordConstructor(inputs, locals, out);
cls := EXPANDED_CLASS(tree, Modifier.NOMOD(), DEFAULT_PREFIXES, Restriction.FUNCTION());
end makeRecordConstructor;

function initExpandedClass
input output Class cls;
algorithm
Expand Down
32 changes: 32 additions & 0 deletions Compiler/NFFrontEnd/NFClassTree.mo
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,38 @@ public
InstNode.updateClass(cls, clsNode);
end instantiate;

function fromRecordConstructor
input list<InstNode> inputs;
input list<InstNode> locals;
input InstNode out;
output ClassTree tree = EMPTY;
protected
LookupTree.Tree ltree = LookupTree.new();
Integer i = 1;
array<Mutable<InstNode>> comps;
algorithm
comps := arrayCreateNoInit(listLength(inputs) + listLength(locals) + 1,
Mutable.create(InstNode.EMPTY_NODE()));

for ci in inputs loop
comps[i] := Mutable.create(ci);
ltree := addLocalElement(InstNode.name(ci), LookupTree.Entry.COMPONENT(i), tree, ltree);
i := i + 1;
end for;

for cl in locals loop
comps[i] := Mutable.create(cl);
ltree := addLocalElement(InstNode.name(cl), LookupTree.Entry.COMPONENT(i), tree, ltree);
i := i + 1;
end for;

comps[i] := Mutable.create(out);
ltree := addLocalElement(InstNode.name(out), LookupTree.Entry.COMPONENT(i), tree, ltree);

tree := INSTANTIATED_TREE(ltree, listArray({}), comps, List.intRange(i),
listArray({}), listArray({}), DuplicateTree.new());
end fromRecordConstructor;

function mapRedeclareChains
input ClassTree tree;
input FuncT func;
Expand Down
24 changes: 24 additions & 0 deletions Compiler/NFFrontEnd/NFComponent.mo
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,30 @@ uniontype Component
output Boolean isInput = direction(component) == Direction.INPUT;
end isInput;

function makeInput
input output Component component;
protected
Attributes attr;
algorithm
() := match component
case UNTYPED_COMPONENT(attributes = attr)
algorithm
attr.direction := Direction.INPUT;
component.attributes := attr;
then
();

case TYPED_COMPONENT(attributes = attr)
algorithm
attr.direction := Direction.INPUT;
component.attributes := attr;
then
();

else ();
end match;
end makeInput;

function isOutput
input Component component;
output Boolean isOutput = direction(component) == Direction.OUTPUT;
Expand Down
64 changes: 27 additions & 37 deletions Compiler/NFFrontEnd/NFRecord.mo
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ import NFInstUtil;
import NFPrefixes.Variability;
import NFPrefixes.Visibility;
import NFFunction.Function;
import ClassTree = NFClassTree.ClassTree;
import NFClassTree.ClassTree;
import ComplexType = NFComplexType;
import ComponentRef = NFComponentRef;
import ErrorExt;
Expand All @@ -71,16 +71,18 @@ function instConstructors
input Absyn.Path path;
input output InstNode node;
input SourceInfo info;
protected
Class cls;
list<InstNode> inputs, outputs, locals;
InstNode out_rec, ctor_over;
DAE.FunctionAttributes attr;
Pointer<Boolean> collected;
Absyn.Path con_path;
protected
Class cls;
list<InstNode> inputs, outputs, locals, params;
InstNode out_rec, ctor_over, def_ctor_node;
DAE.FunctionAttributes attr;
Pointer<Boolean> collected;
Absyn.Path con_path;
ComponentRef con_ref;
Boolean ctor_defined;
algorithm
Component out_comp;
Class def_ctor_cls;
algorithm

// See if we have overloaded costructors.
try
Expand Down Expand Up @@ -122,25 +124,19 @@ function instConstructors
collected := Pointer.create(false);
con_path := Absyn.suffixPath(path,"'constructor'.'$default'");

// Create an output record element for the default constructor.
// create a TYPED_COMPONENT here since this output "default constructed" record is not part
// of the class node. So it will not be typed later by typeFunction. Instead of changing
// things there just handle it here.
out_rec := InstNode.COMPONENT_NODE("$out" + InstNode.name(node),
Visibility.PUBLIC,
Pointer.createImmutable(Component.TYPED_COMPONENT(
node,
Type.COMPLEX(node, ComplexType.CLASS()),
Binding.UNBOUND(),
Binding.UNBOUND(),
NFComponent.OUTPUT_ATTR,
NONE(),
Absyn.dummyInfo)),
0,
node);

InstNode.cacheAddFunc(node, Function.FUNCTION(con_path, node, inputs, {out_rec}, locals, {}, Type.UNKNOWN(), attr, collected), false);
// Create a new node for the default constructor.
def_ctor_node := InstNode.replaceClass(Class.NOT_INSTANTIATED(), node);

// Create the output record element, using the node created above as parent.
out_comp := Component.UNTYPED_COMPONENT(node, listArray({}), Binding.UNBOUND(),
Binding.UNBOUND(), NFComponent.OUTPUT_ATTR, NONE(), Absyn.dummyInfo);
out_rec := InstNode.fromComponent("$out" + InstNode.name(node), out_comp, def_ctor_node);

// Make a record constructor class and update the node with it.
def_ctor_cls := Class.makeRecordConstructor(inputs, locals, out_rec);
def_ctor_node := InstNode.updateClass(def_ctor_cls, def_ctor_node);

InstNode.cacheAddFunc(node, Function.FUNCTION(con_path, def_ctor_node, inputs, {out_rec}, locals, {}, Type.UNKNOWN(), attr, collected), false);
end instConstructors;


Expand All @@ -166,18 +162,12 @@ algorithm
n := Mutable.access(components[i]);
comp := InstNode.component(n);

if InstNode.isProtected(n) then
if InstNode.isProtected(n) or
Component.isConst(comp) and Component.hasBinding(comp) then
locals := n :: locals;
else
if Component.isConst(comp) then
if not Component.hasBinding(comp) then
inputs := n :: inputs;
else
locals := n :: locals;
end if;
else
inputs := n :: inputs;
end if;
n := InstNode.replaceComponent(Component.makeInput(comp), n);
inputs := n :: inputs;
end if;
end for;
then
Expand Down
13 changes: 13 additions & 0 deletions Compiler/Util/Array.mo
Original file line number Diff line number Diff line change
Expand Up @@ -913,5 +913,18 @@ algorithm
exists := false;
end exist;

function insertList<T>
input output array<T> arr;
input list<T> lst;
input Integer startPos;
protected
Integer i = startPos;
algorithm
for e in lst loop
arr[i] := e;
i := i + 1;
end for;
end insertList;

annotation(__OpenModelica_Interface="util");
end Array;

0 comments on commit fb72969

Please sign in to comment.