Skip to content

Commit

Permalink
Improve propagation of redeclare modifiers (#9040)
Browse files Browse the repository at this point in the history
- Save propagated subscripts for redeclared components and apply them
  later when instantiating them.

Fixes #9027
  • Loading branch information
perost committed May 31, 2022
1 parent 018e7b5 commit a906e3a
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 25 deletions.
35 changes: 23 additions & 12 deletions OMCompiler/Compiler/NFFrontEnd/NFInst.mo
Expand Up @@ -909,8 +909,8 @@ algorithm
// Instantiate local components.
ClassTree.applyLocalComponents(cls_tree,
function instComponent(attributes = attributes, innerMod = Modifier.NOMOD(),
originalAttr = NONE(), useBinding = useBinding,
instLevel = instLevel + 1, context = context));
useBinding = useBinding, instLevel = instLevel + 1, context = context,
originalAttr = NONE(), propagatedSubs = {}));

// Remove duplicate elements.
cls_tree := ClassTree.replaceDuplicates(cls_tree);
Expand Down Expand Up @@ -1189,7 +1189,8 @@ algorithm

ClassTree.applyLocalComponents(cls_tree,
function instComponent(attributes = attributes, innerMod = Modifier.NOMOD(),
originalAttr = NONE(), useBinding = useBinding, instLevel = instLevel, context = context));
useBinding = useBinding, instLevel = instLevel, context = context,
originalAttr = NONE(), propagatedSubs = {}));
then
();

Expand Down Expand Up @@ -1376,8 +1377,8 @@ protected
algorithm
rdcl_node := Mutable.access(redeclareComp);
repl_node := Mutable.access(replaceableComp);
instComponent(repl_node, NFAttributes.DEFAULT_ATTR, Modifier.NOMOD(), true, instLevel, NONE(), context);
redeclareComponent(rdcl_node, repl_node, Modifier.NOMOD(), Modifier.NOMOD(), NFAttributes.DEFAULT_ATTR, rdcl_node, instLevel, context);
instComponent(repl_node, NFAttributes.DEFAULT_ATTR, Modifier.NOMOD(), true, instLevel, context);
redeclareComponent(rdcl_node, repl_node, Modifier.NOMOD(), Modifier.NOMOD(), {}, NFAttributes.DEFAULT_ATTR, rdcl_node, instLevel, context);
outComp := Mutable.create(rdcl_node);
end redeclareComponentElement;

Expand Down Expand Up @@ -1521,8 +1522,9 @@ function instComponent
input Modifier innerMod;
input Boolean useBinding "Ignore the component's binding if false.";
input Integer instLevel;
input Option<Attributes> originalAttr = NONE();
input InstContext.Type context;
input Option<Attributes> originalAttr = NONE();
input list<Subscript> propagatedSubs = {};
protected
Component comp;
SCode.Element def;
Expand All @@ -1532,6 +1534,7 @@ protected
String name;
InstNode parent;
InstContext.Type next_context;
list<Subscript> propagated_subs;
algorithm
comp_node := InstNode.resolveOuter(node);
comp := InstNode.component(comp_node);
Expand All @@ -1550,20 +1553,20 @@ algorithm
checkOuterComponentMod(outer_mod, def, comp_node);

Modifier.REDECLARE(element = rdcl_node, innerMod = inner_mod,
outerMod = outer_mod, constrainingMod = cc_mod) := outer_mod;
outerMod = outer_mod, constrainingMod = cc_mod, propagatedSubs = propagated_subs) := outer_mod;

next_context := InstContext.set(context, NFInstContext.REDECLARED);
instComponentDef(def, Modifier.NOMOD(), inner_mod, NFAttributes.DEFAULT_ATTR,
useBinding, comp_node, parent, instLevel, originalAttr, next_context);
useBinding, comp_node, parent, instLevel, originalAttr, {}, next_context);

cc_mod := getConstrainingMod(def, parent, cc_mod);
cc_mod := Modifier.merge(cc_mod, innerMod);

outer_mod := Modifier.merge(InstNode.getModifier(rdcl_node), outer_mod);
InstNode.setModifier(outer_mod, rdcl_node);
redeclareComponent(rdcl_node, node, Modifier.NOMOD(), cc_mod, attributes, node, instLevel, context);
redeclareComponent(rdcl_node, node, Modifier.NOMOD(), cc_mod, propagated_subs, attributes, node, instLevel, context);
else
instComponentDef(def, outer_mod, innerMod, attributes, useBinding, comp_node, parent, instLevel, originalAttr, context);
instComponentDef(def, outer_mod, innerMod, attributes, useBinding, comp_node, parent, instLevel, originalAttr, propagatedSubs, context);
end if;
end instComponent;

Expand All @@ -1577,6 +1580,7 @@ function instComponentDef
input InstNode parent;
input Integer instLevel;
input Option<Attributes> originalAttr = NONE();
input list<Subscript> propagatedSubs = {};
input InstContext.Type context;
algorithm
() := match component
Expand All @@ -1595,6 +1599,11 @@ algorithm
case SCode.COMPONENT(info = info)
algorithm
mod := instElementModifier(component, node, parent);

if not listEmpty(propagatedSubs) then
mod := Modifier.propagateSubs(mod, propagatedSubs);
end if;

mod := Modifier.merge(mod, innerMod);
mod := Modifier.merge(outerMod, mod);
checkOuterComponentMod(mod, component, node);
Expand Down Expand Up @@ -1785,6 +1794,7 @@ function redeclareComponent
input InstNode originalNode;
input Modifier outerMod;
input Modifier constrainingMod;
input list<Subscript> propagatedSubs;
input Attributes outerAttr;
input InstNode redeclaredNode;
input Integer instLevel;
Expand All @@ -1811,7 +1821,8 @@ algorithm
rdcl_node := InstNode.setNodeType(rdcl_type, redeclareNode);
rdcl_node := InstNode.copyInstancePtr(originalNode, rdcl_node);
rdcl_node := InstNode.updateComponent(InstNode.component(redeclareNode), rdcl_node);
instComponent(rdcl_node, outerAttr, constrainingMod, true, instLevel, SOME(Component.getAttributes(orig_comp)), context);
instComponent(rdcl_node, outerAttr, constrainingMod, true, instLevel, context,
SOME(Component.getAttributes(orig_comp)), propagatedSubs);
rdcl_comp := InstNode.component(rdcl_node);

new_comp := match (orig_comp, rdcl_comp)
Expand Down Expand Up @@ -3207,7 +3218,7 @@ algorithm
if InstNode.isComponent(n) then
// The component might have been instantiated during lookup, otherwise do
// it here (instComponent will skip already instantiated components).
instComponent(n, NFAttributes.DEFAULT_ATTR, Modifier.NOMOD(), true, 0, NONE(), NFInstContext.CLASS);
instComponent(n, NFAttributes.DEFAULT_ATTR, Modifier.NOMOD(), true, 0, NFInstContext.CLASS);

// If the component's class has a missingInnerMessage annotation, use it
// to give a diagnostic message.
Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/NFFrontEnd/NFLookup.mo
Expand Up @@ -892,7 +892,7 @@ algorithm
elseif InstNode.isGeneratedInner(scope) and Component.isDefinition(InstNode.component(scope)) then
// The scope is a generated inner component that hasn't been instantiated,
// it needs to be instantiated to continue lookup.
Inst.instComponent(scope, NFAttributes.DEFAULT_ATTR, Modifier.NOMOD(), true, 0, NONE(), NFInstContext.CLASS);
Inst.instComponent(scope, NFAttributes.DEFAULT_ATTR, Modifier.NOMOD(), true, 0, NFInstContext.CLASS);
end if;

name := AbsynUtil.crefFirstIdent(cref);
Expand Down
25 changes: 13 additions & 12 deletions OMCompiler/Compiler/NFFrontEnd/NFModifier.mo
Expand Up @@ -158,6 +158,7 @@ uniontype Modifier
Modifier innerMod;
Modifier outerMod;
Modifier constrainingMod;
list<Subscript> propagatedSubs;
end REDECLARE;

record NOMOD end NOMOD;
Expand Down Expand Up @@ -203,7 +204,7 @@ public

cc_mod := createConstrainingMod(elem, scope);
then
REDECLARE(mod.finalPrefix, mod.eachPrefix, node, NOMOD(), NOMOD(), cc_mod);
REDECLARE(mod.finalPrefix, mod.eachPrefix, node, NOMOD(), NOMOD(), cc_mod, {});

end match;
end create;
Expand Down Expand Up @@ -420,7 +421,7 @@ public

case (REDECLARE(constrainingMod = NOMOD()), REDECLARE(constrainingMod = MODIFIER()))
then REDECLARE(outerMod.finalPrefix, outerMod.eachPrefix, outerMod.element,
outerMod.innerMod, outerMod.outerMod, innerMod.constrainingMod);
outerMod.innerMod, outerMod.outerMod, innerMod.constrainingMod, outerMod.propagatedSubs);

case (REDECLARE(), _) then outerMod;
case (_, REDECLARE()) then innerMod;
Expand All @@ -441,21 +442,26 @@ public
while the parent is the node the modifier is applied to. These are usually
the same node, but can be different when the modifier comes from a short
class declaration (the origin) but is applied to a component (the parent)."
input output Modifier mod;
input Modifier mod;
input InstNode origin;
input InstNode parent;
output Modifier outMod = propagateSubs(mod, {Subscript.SPLIT_PROXY(origin, parent)});
end propagate;

function propagateSubs
input output Modifier mod;
input list<Subscript> subs;
algorithm
() := match mod
case MODIFIER()
algorithm
mod.subModifiers := ModTable.map(mod.subModifiers,
function propagateSubMod(subs = {Subscript.SPLIT_PROXY(origin, parent)}));
mod.subModifiers := ModTable.map(mod.subModifiers, function propagateSubMod(subs = subs));
then
();

else ();
end match;
end propagate;
end propagateSubs;

function propagateBinding
input output Modifier mod;
Expand All @@ -472,12 +478,6 @@ public
then
();

case REDECLARE()
algorithm
mod.innerMod := propagateBinding(mod.innerMod, origin, parent);
then
();

else ();
end match;
end propagateBinding;
Expand All @@ -499,6 +499,7 @@ public
case REDECLARE(eachPrefix = SCode.NOT_EACH())
algorithm
submod.innerMod := propagateSubMod(name, submod.innerMod, subs);
submod.propagatedSubs := listAppend(subs, submod.propagatedSubs);
then
();

Expand Down
1 change: 1 addition & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Expand Up @@ -966,6 +966,7 @@ RedeclareMod6.mo \
RedeclareMod7.mo \
RedeclareMod8.mo \
RedeclareMod9.mo \
RedeclareMod10.mo \
redeclare10.mo \
redeclare11.mo \
redeclare12.mo \
Expand Down
28 changes: 28 additions & 0 deletions testsuite/flattening/modelica/scodeinst/RedeclareMod10.mo
@@ -0,0 +1,28 @@
// name: RedeclareMod10
// keywords:
// status: correct
// cflags: -d=newInst
//

model A
Real x;
end A;

model B
replaceable A a;
end B;

model C
B b[2];
end C;

model RedeclareMod10
extends C(b(redeclare A a(x = {1, 2})));
end RedeclareMod10;

// Result:
// class RedeclareMod10
// Real b[1].a.x = 1.0;
// Real b[2].a.x = 2.0;
// end RedeclareMod10;
// endResult

0 comments on commit a906e3a

Please sign in to comment.