Skip to content

Commit

Permalink
Fix for attribute propagation with redeclares.
Browse files Browse the repository at this point in the history
- Treat (redeclare Real3 x) with type Real3 = Real[3] the same as
  (redeclare Real x[3]).
  • Loading branch information
perost authored and OpenModelica-Hudson committed Oct 15, 2015
1 parent f9ed55d commit e1a4c64
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 26 deletions.
29 changes: 27 additions & 2 deletions Compiler/FrontEnd/Inst.mo
Expand Up @@ -4056,7 +4056,7 @@ algorithm
m_3 = Mod.merge(m_2, old_m_1, env_1, pre);
m_3 = Mod.merge(m_3, cmod, env_1, pre);

redecl = NFSCodeFlattenRedeclare.propagateAttributesVar(comp, redComp);
(cache, redecl) = propagateRedeclCompAttr(cache, env_1, comp, redComp);
redecl = SCode.setComponentMod(redecl, mod);
then
(cache,env_1,ih,redecl,m_3);
Expand Down Expand Up @@ -4085,7 +4085,7 @@ algorithm
m_3 = Mod.merge(m_2, old_m_1, env_1, pre);
m_3 = Mod.merge(cmod, m_3 ,env_1,pre);

redecl = NFSCodeFlattenRedeclare.propagateAttributesVar(comp, redComp);
(cache, redecl) = propagateRedeclCompAttr(cache, env_1, comp, redComp);
redecl = SCode.setComponentMod(redecl, mod);
then
(cache,env_1,ih,redecl,m_3);
Expand Down Expand Up @@ -4160,6 +4160,31 @@ algorithm
end matchcontinue;
end redeclareType;

protected function propagateRedeclCompAttr
"Helper function to redeclareType, propagates attributes from the old
component to the new according to the rules for redeclare."
input FCore.Cache inCache;
input FCore.Graph inEnv;
input SCode.Element inOldComponent;
input SCode.Element inNewComponent;
output FCore.Cache outCache = inCache;
output SCode.Element outComponent;
protected
Boolean is_array = false;
algorithm
// If the old component has array dimensions but the new one doesn't, then we
// need to check if the new component's type is an array type. If it is we
// shouldn't propagate the dimensions from the old component. I.e. we should
// treat: type Real3 = Real[3]; comp(redeclare Real3 x);
// in the same way as: comp(redeclare Real x[3]).
if SCode.isArrayComponent(inOldComponent) and not SCode.isArrayComponent(inNewComponent) then
(outCache, is_array) := Lookup.isArrayType(outCache, inEnv,
Absyn.typeSpecPath(SCode.getComponentTypeSpec(inNewComponent)));
end if;

outComponent := SCode.propagateAttributesVar(inOldComponent, inNewComponent, is_array);
end propagateRedeclCompAttr;

protected function updateComponentsInEnv
"author: PA
This function is the second pass of component instantiation, when a
Expand Down
34 changes: 34 additions & 0 deletions Compiler/FrontEnd/Lookup.mo
Expand Up @@ -3220,5 +3220,39 @@ algorithm
end match;
end prefixSplicedExp;

public function isArrayType
input FCore.Cache inCache;
input FCore.Graph inEnv;
input Absyn.Path inPath;
output FCore.Cache outCache;
output Boolean outIsArray;
protected
SCode.Element el;
Absyn.Path p;
FCore.Graph env;
algorithm
try
(outCache, el, env) := lookupClass(inCache, inEnv, inPath, false);

outIsArray := match el
case SCode.CLASS(classDef = SCode.DERIVED(typeSpec = Absyn.TPATH(arrayDim = SOME(_))))
then true;

case SCode.CLASS(classDef = SCode.DERIVED(attributes = SCode.ATTR(arrayDims = _ :: _)))
then true;

case SCode.CLASS(classDef = SCode.DERIVED(typeSpec = Absyn.TPATH(path = p)))
algorithm
(outCache, outIsArray) := isArrayType(outCache, env, p);
then
outIsArray;

else false;
end match;
else
outIsArray := false;
end try;
end isArrayType;

annotation(__OpenModelica_Interface="frontend");
end Lookup;
52 changes: 28 additions & 24 deletions Compiler/FrontEnd/SCode.mo
Expand Up @@ -5284,6 +5284,7 @@ end mergeComponentModifiers;
public function propagateAttributes
input Attributes inOriginalAttributes;
input Attributes inNewAttributes;
input Boolean inNewTypeIsArray = false;
output Attributes outNewAttributes;
protected
Absyn.ArrayDim dims1, dims2;
Expand All @@ -5294,7 +5295,15 @@ protected
algorithm
ATTR(dims1, ct1, prl1, var1, dir1) := inOriginalAttributes;
ATTR(dims2, ct2, prl2, var2, dir2) := inNewAttributes;
dims2 := propagateArrayDimensions(dims1, dims2);

// If the new component has an array type, don't propagate the old dimensions.
// E.g. type Real3 = Real[3];
// replaceable Real x[:];
// comp(redeclare Real3 x) => Real[3] x
if not inNewTypeIsArray then
dims2 := propagateArrayDimensions(dims1, dims2);
end if;

ct2 := propagateConnectorType(ct1, ct2);
prl2 := propagateParallelism(prl1,prl2);
var2 := propagateVariability(var1, var2);
Expand Down Expand Up @@ -5329,18 +5338,10 @@ public function propagateParallelism
input Parallelism inNewParallelism;
output Parallelism outNewParallelism;
algorithm
outNewParallelism := matchcontinue(inOriginalParallelism, inNewParallelism)
outNewParallelism := match(inOriginalParallelism, inNewParallelism)
case (_, NON_PARALLEL()) then inOriginalParallelism;
case (_,_)
equation
// equality(inNewParallelism = inOriginalParallelism);
then inNewParallelism;
else
equation
print("failure in propagateParallelism: parallelism mismatch.");
then
fail();
end matchcontinue;
else inNewParallelism;
end match;
end propagateParallelism;

public function propagateVariability
Expand All @@ -5359,23 +5360,16 @@ public function propagateDirection
input Absyn.Direction inNewDirection;
output Absyn.Direction outNewDirection;
algorithm
outNewDirection := matchcontinue(inOriginalDirection, inNewDirection)
outNewDirection := match(inOriginalDirection, inNewDirection)
case (_, Absyn.BIDIR()) then inOriginalDirection;
case(_,_)
equation
// equality(inNewDirection = inOriginalDirection);
then inNewDirection;
else
equation
print(" failure in propagateDirection, inner outer mismatch");
then
fail();
end matchcontinue;
else inNewDirection;
end match;
end propagateDirection;

public function propagateAttributesVar
input Element inOriginalVar;
input Element inNewVar;
input Boolean inNewTypeIsArray;
output Element outNewVar;
protected
Ident name;
Expand All @@ -5390,7 +5384,7 @@ algorithm
COMPONENT(prefixes = pref1, attributes = attr1) := inOriginalVar;
COMPONENT(name, pref2, attr2, ty, mod, cmt, cond, info) := inNewVar;
pref2 := propagatePrefixes(pref1, pref2);
attr2 := propagateAttributes(attr1, attr2);
attr2 := propagateAttributes(attr1, attr2, inNewTypeIsArray);
outNewVar := COMPONENT(name, pref2, attr2, ty, mod, cmt, cond, info);
end propagateAttributesVar;

Expand Down Expand Up @@ -5648,5 +5642,15 @@ algorithm
outE := COMPONENT(inName, pr, atr, ts, m, cmt, cnd, i);
end setComponentName;

public function isArrayComponent
input Element inElement;
output Boolean outIsArray;
algorithm
outIsArray := match inElement
case COMPONENT(attributes = ATTR(arrayDims = _ :: _)) then true;
else false;
end match;
end isArrayComponent;

annotation(__OpenModelica_Interface="frontend");
end SCode;

0 comments on commit e1a4c64

Please sign in to comment.