From dad3995e5ffe2f669eb486baf486856cc7d14ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Fri, 5 Oct 2018 16:16:55 +0200 Subject: [PATCH] [NF] Use correct origin in Typing.typeCref. - Base the origin on where the component is declared when typing a cref node, rather than where it's used. Belonging to [master]: - OpenModelica/OMCompiler#2697 --- Compiler/NFFrontEnd/NFCeval.mo | 2 +- Compiler/NFFrontEnd/NFInstNode.mo | 27 +++++++++++++++++++++++++++ Compiler/NFFrontEnd/NFTyping.mo | 9 ++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/Compiler/NFFrontEnd/NFCeval.mo b/Compiler/NFFrontEnd/NFCeval.mo index 6cc2659fc6b..5725aeeacf0 100644 --- a/Compiler/NFFrontEnd/NFCeval.mo +++ b/Compiler/NFFrontEnd/NFCeval.mo @@ -298,7 +298,7 @@ protected Option start_exp; Integer pcount; algorithm - exp_origin := if Class.isFunction(InstNode.getClass(InstNode.parent(node))) + exp_origin := if InstNode.isFunction(InstNode.explicitParent(node)) then ExpOrigin.FUNCTION else ExpOrigin.CLASS; Typing.typeComponentBinding(node, exp_origin); diff --git a/Compiler/NFFrontEnd/NFInstNode.mo b/Compiler/NFFrontEnd/NFInstNode.mo index f0c9bb64aac..b87c48f29e2 100644 --- a/Compiler/NFFrontEnd/NFInstNode.mo +++ b/Compiler/NFFrontEnd/NFInstNode.mo @@ -347,6 +347,16 @@ uniontype InstNode end match; end isUserdefinedClass; + function isFunction + input InstNode node; + output Boolean isFunc; + algorithm + isFunc := match node + case CLASS_NODE() then Class.isFunction(Pointer.access(node.cls)); + else false; + end match; + end isFunction; + function isComponent input InstNode node; output Boolean isComponent; @@ -503,6 +513,11 @@ uniontype InstNode end match; end parent; + function explicitParent + input InstNode node; + output InstNode parentNode = explicitScope(parent(node)); + end explicitParent; + function classParent input InstNode node; output InstNode parent; @@ -1121,6 +1136,18 @@ uniontype InstNode end match; end openImplicitScope; + function explicitScope + "Returns the first parent of the node that's not an implicit scope, or the + node itself if it's not an implicit scope." + input InstNode node; + output InstNode scope; + algorithm + scope := match node + case IMPLICIT_SCOPE() then explicitScope(node.parentScope); + else node; + end match; + end explicitScope; + function addIterator input InstNode iterator; input output InstNode scope; diff --git a/Compiler/NFFrontEnd/NFTyping.mo b/Compiler/NFFrontEnd/NFTyping.mo index d3973cc7458..a80e3161fd2 100644 --- a/Compiler/NFFrontEnd/NFTyping.mo +++ b/Compiler/NFFrontEnd/NFTyping.mo @@ -1279,6 +1279,7 @@ algorithm Type node_ty; list subs; Variability subs_var, rest_var; + ExpOrigin.Type node_origin; case ComponentRef.CREF(origin = Origin.SCOPE) algorithm @@ -1288,7 +1289,13 @@ algorithm case ComponentRef.CREF(node = InstNode.COMPONENT_NODE()) algorithm - node_ty := typeComponent(cref.node, origin); + // The origin used when typing a component node depends on where the + // component was declared, not where it's used. This can be different to + // the given origin, e.g. for package constants used in a function. + node_origin := if InstNode.isFunction(InstNode.explicitParent(cref.node)) then + ExpOrigin.FUNCTION else ExpOrigin.CLASS; + node_ty := typeComponent(cref.node, node_origin); + (subs, subs_var) := typeSubscripts(cref.subscripts, node_ty, cref, origin, info); (rest_cr, rest_var) := typeCref2(cref.restCref, origin, info); subsVariability := Prefixes.variabilityMax(subs_var, rest_var);