Skip to content

Commit

Permalink
[NF] Function scoping improvements.
Browse files Browse the repository at this point in the history
- Use the instance scope instead of the class scope when prefixing
  functions.
- Use the correct scope when instantiating derived function modifiers.

Belonging to [master]:
  - OpenModelica/OMCompiler#2984
  - OpenModelica/OpenModelica-testsuite#1142
  • Loading branch information
perost authored and OpenModelica-Hudson committed Mar 19, 2019
1 parent f63f7ac commit 04df807
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 7 deletions.
3 changes: 1 addition & 2 deletions Compiler/NFFrontEnd/NFConvertDAE.mo
Expand Up @@ -1034,13 +1034,12 @@ algorithm
comp := InstNode.component(node);

element := match comp
case Component.TYPED_COMPONENT(ty = ty, info = info)
case Component.TYPED_COMPONENT(ty = ty, info = info, attributes = attr)
algorithm
cref := ComponentRef.fromNode(node, ty);
binding := Binding.toDAEExp(comp.binding);
cls := InstNode.getClass(comp.classInst);
ty_attr := list((Modifier.name(m), Modifier.binding(m)) for m in Class.getTypeAttributes(cls));
attr := comp.attributes;
var_attr := convertVarAttributes(ty_attr, ty, attr);
then
makeDAEVar(cref, ty, binding, attr, InstNode.visibility(node), var_attr,
Expand Down
17 changes: 14 additions & 3 deletions Compiler/NFFrontEnd/NFFunction.mo
Expand Up @@ -313,7 +313,7 @@ uniontype Function
// If we found a function class we include the root in the prefix, but if we
// instead found a component (i.e. a functional parameter) we don't.
is_class := InstNode.isClass(ComponentRef.node(functionRef));
prefix := ComponentRef.fromNodeList(InstNode.scopeList(InstNode.classScope(found_scope), includeRoot = is_class));
prefix := ComponentRef.fromNodeList(InstNode.scopeList(found_scope, includeRoot = is_class));
functionRef := ComponentRef.append(functionRef, prefix);
end lookupFunction;

Expand All @@ -338,14 +338,24 @@ uniontype Function
output Boolean specialBuiltin;
protected
CachedData cache;
InstNode parent;
algorithm
fn_node := InstNode.classScope(ComponentRef.node(fn_ref));
cache := InstNode.getFuncCache(fn_node);

// Check if a cached instantiation of this function already exists.
(fn_node, specialBuiltin) := match cache
case CachedData.FUNCTION() then (fn_node, cache.specialBuiltin);
else instFunction2(ComponentRef.toPath(fn_ref), fn_node, info);
else
algorithm
parent := if InstNode.isRedeclare(ComponentRef.node(fn_ref)) or ComponentRef.isSimple(fn_ref) then
InstNode.EMPTY_NODE() else ComponentRef.node(ComponentRef.rest(fn_ref));

if not InstNode.isComponent(parent) then
parent := InstNode.EMPTY_NODE();
end if;
then
instFunction2(ComponentRef.toPath(fn_ref), fn_node, info, parent);
end match;
end instFunctionRef;

Expand All @@ -371,6 +381,7 @@ uniontype Function
input Absyn.Path fnPath;
input output InstNode fnNode;
input SourceInfo info;
input InstNode parent = InstNode.EMPTY_NODE();
output Boolean specialBuiltin;
protected
SCode.Element def = InstNode.definition(fnNode);
Expand Down Expand Up @@ -423,7 +434,7 @@ uniontype Function
OperatorOverloading.checkOperatorRestrictions(fnNode);
end if;

fnNode := InstNode.setNodeType(NFInstNode.InstNodeType.ROOT_CLASS(), fnNode);
fnNode := InstNode.setNodeType(NFInstNode.InstNodeType.ROOT_CLASS(parent), fnNode);
fnNode := instFunction3(fnNode);
fn := new(fnPath, fnNode);
specialBuiltin := isSpecialBuiltin(fn);
Expand Down
4 changes: 2 additions & 2 deletions Compiler/NFFrontEnd/NFInst.mo
Expand Up @@ -131,7 +131,7 @@ algorithm

// Look up the class to instantiate and mark it as the root class.
cls := Lookup.lookupClassName(classPath, top, Absyn.dummyInfo, checkAccessViolations = false);
cls := InstNode.setNodeType(InstNodeType.ROOT_CLASS(), cls);
cls := InstNode.setNodeType(InstNodeType.ROOT_CLASS(InstNode.EMPTY_NODE()), cls);

// Initialize the storage for automatically generated inner elements.
top := InstNode.setInnerOuterCache(top, CachedData.TOP_SCOPE(NodeTree.new(), cls));
Expand Down Expand Up @@ -799,7 +799,7 @@ algorithm
Class.EXPANDED_DERIVED(baseClass = base_node) := InstNode.getClass(node);

// Merge outer modifiers and attributes.
mod := Modifier.fromElement(InstNode.definition(node), {node}, InstNode.parent(node));
mod := Modifier.fromElement(InstNode.definition(node), {node}, InstNode.rootParent(node));
outer_mod := Modifier.merge(outerMod, Modifier.addParent(node, cls.modifier));
mod := Modifier.merge(outer_mod, mod);
attrs := updateClassConnectorType(cls.restriction, cls.attributes);
Expand Down
24 changes: 24 additions & 0 deletions Compiler/NFFrontEnd/NFInstNode.mo
Expand Up @@ -79,6 +79,8 @@ uniontype InstNodeType

record ROOT_CLASS
"The root of the instance tree, i.e. the class that the instantiation starts from."
InstNode parent "The parent of the class, e.g. when instantiating a function
in a component where the component is the parent.";
end ROOT_CLASS;

record NORMAL_COMP
Expand Down Expand Up @@ -584,6 +586,28 @@ uniontype InstNode
end match;
end derivedParent;

function rootParent
input InstNode node;
output InstNode parent;
algorithm
parent := match node
case CLASS_NODE() then rootTypeParent(node.nodeType, node);
else parent(node);
end match;
end rootParent;

function rootTypeParent
input InstNodeType nodeType;
input InstNode node;
output InstNode parent;
algorithm
parent := match nodeType
case InstNodeType.ROOT_CLASS() guard not isEmpty(nodeType.parent) then nodeType.parent;
case InstNodeType.DERIVED_CLASS() then rootTypeParent(nodeType.ty, node);
else parent(node);
end match;
end rootTypeParent;

function parentScope
"Returns the parent scope of a node. In the case of a class this is simply
the enclosing class. In the case of a component it is the enclosing class of
Expand Down

0 comments on commit 04df807

Please sign in to comment.