Skip to content

Commit

Permalink
[NF] Fix redeclaration of enumerations.
Browse files Browse the repository at this point in the history
Belonging to [master]:
  - #156
  - OpenModelica/OMCompiler#3073
  • Loading branch information
perost authored and OpenModelica-Hudson committed May 2, 2019
1 parent 364f80f commit f6e1212
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 15 deletions.
19 changes: 12 additions & 7 deletions Compiler/NFFrontEnd/NFBuiltin.mo
Expand Up @@ -127,7 +127,7 @@ constant array<NFInstNode.CachedData> EMPTY_NODE_CACHE = listArrayLiteral({
constant InstNode POLYMORPHIC_NODE = InstNode.CLASS_NODE("polymorphic",
Elements.ANY, Visibility.PUBLIC,
Pointer.createImmutable(Class.PARTIAL_BUILTIN(Type.POLYMORPHIC(""), ClassTree.EMPTY_TREE(),
Modifier.NOMOD(), Restriction.TYPE())),
Modifier.NOMOD(), NFClass.DEFAULT_PREFIXES, Restriction.TYPE())),
EMPTY_NODE_CACHE, InstNode.EMPTY_NODE(), InstNodeType.BUILTIN_CLASS());

// Lookup tree for Real. Generated by makeBuiltinLookupTree.
Expand Down Expand Up @@ -196,7 +196,8 @@ constant ClassTree REAL_CLASS_TREE = ClassTree.FLAT_TREE(
constant InstNode REAL_NODE = InstNode.CLASS_NODE("Real",
Elements.REAL, Visibility.PUBLIC,
Pointer.createImmutable(
Class.PARTIAL_BUILTIN(Type.REAL(), REAL_CLASS_TREE, Modifier.NOMOD(), Restriction.TYPE())),
Class.PARTIAL_BUILTIN(Type.REAL(), REAL_CLASS_TREE, Modifier.NOMOD(),
NFClass.DEFAULT_PREFIXES, Restriction.TYPE())),
EMPTY_NODE_CACHE, InstNode.EMPTY_NODE(), InstNodeType.BUILTIN_CLASS());

// Lookup tree for Integer. Generated by makeBuiltinLookupTree.
Expand Down Expand Up @@ -239,7 +240,8 @@ constant ClassTree INTEGER_CLASS_TREE = ClassTree.FLAT_TREE(
constant InstNode INTEGER_NODE = InstNode.CLASS_NODE("Integer",
Elements.INTEGER, Visibility.PUBLIC,
Pointer.createImmutable(
Class.PARTIAL_BUILTIN(Type.INTEGER(), INTEGER_CLASS_TREE, Modifier.NOMOD(), Restriction.TYPE())),
Class.PARTIAL_BUILTIN(Type.INTEGER(), INTEGER_CLASS_TREE, Modifier.NOMOD(),
NFClass.DEFAULT_PREFIXES, Restriction.TYPE())),
EMPTY_NODE_CACHE, InstNode.EMPTY_NODE(), InstNodeType.BUILTIN_CLASS());

// Lookup tree for Boolean. Generated by makeBuiltinLookupTree.
Expand Down Expand Up @@ -270,7 +272,8 @@ constant ClassTree BOOLEAN_CLASS_TREE = ClassTree.FLAT_TREE(
constant InstNode BOOLEAN_NODE = InstNode.CLASS_NODE("Boolean",
Elements.BOOLEAN, Visibility.PUBLIC,
Pointer.createImmutable(
Class.PARTIAL_BUILTIN(Type.BOOLEAN(), BOOLEAN_CLASS_TREE, Modifier.NOMOD(), Restriction.TYPE())),
Class.PARTIAL_BUILTIN(Type.BOOLEAN(), BOOLEAN_CLASS_TREE, Modifier.NOMOD(),
NFClass.DEFAULT_PREFIXES, Restriction.TYPE())),
EMPTY_NODE_CACHE, InstNode.EMPTY_NODE(), InstNodeType.BUILTIN_CLASS());

constant ComponentRef BOOLEAN_CREF =
Expand Down Expand Up @@ -304,7 +307,8 @@ constant ClassTree STRING_CLASS_TREE = ClassTree.FLAT_TREE(
constant InstNode STRING_NODE = InstNode.CLASS_NODE("String",
Elements.STRING, Visibility.PUBLIC,
Pointer.createImmutable(
Class.PARTIAL_BUILTIN(Type.STRING(), STRING_CLASS_TREE, Modifier.NOMOD(), Restriction.TYPE())),
Class.PARTIAL_BUILTIN(Type.STRING(), STRING_CLASS_TREE, Modifier.NOMOD(),
NFClass.DEFAULT_PREFIXES, Restriction.TYPE())),
EMPTY_NODE_CACHE, InstNode.EMPTY_NODE(), InstNodeType.BUILTIN_CLASS());

// Lookup tree for enumerations. Generated by makeBuiltinLookupTree.
Expand All @@ -326,7 +330,7 @@ constant LookupTree.Tree ENUM_LOOKUP_TREE = LookupTree.Tree.NODE(
constant InstNode ENUM_NODE = InstNode.CLASS_NODE("enumeration",
Elements.ENUMERATION, Visibility.PUBLIC,
Pointer.createImmutable(Class.PARTIAL_BUILTIN(Type.ENUMERATION_ANY(), NFClassTree.EMPTY_TREE(),
Modifier.NOMOD(), Restriction.ENUMERATION())),
Modifier.NOMOD(), NFClass.DEFAULT_PREFIXES, Restriction.ENUMERATION())),
EMPTY_NODE_CACHE, InstNode.EMPTY_NODE(), InstNodeType.BUILTIN_CLASS());

constant Type STATESELECT_TYPE = Type.ENUMERATION(
Expand Down Expand Up @@ -369,7 +373,8 @@ constant ClassTree CLOCK_CLASS_TREE = ClassTree.FLAT_TREE(
constant InstNode CLOCK_NODE = InstNode.CLASS_NODE("Clock",
Elements.CLOCK, Visibility.PUBLIC,
Pointer.createImmutable(
Class.PARTIAL_BUILTIN(Type.CLOCK(), CLOCK_CLASS_TREE, Modifier.NOMOD(), Restriction.CLOCK())),
Class.PARTIAL_BUILTIN(Type.CLOCK(), CLOCK_CLASS_TREE, Modifier.NOMOD(),
NFClass.DEFAULT_PREFIXES, Restriction.CLOCK())),
EMPTY_NODE_CACHE, InstNode.EMPTY_NODE(), InstNodeType.BUILTIN_CLASS());

constant ComponentRef CLOCK_CREF =
Expand Down
4 changes: 2 additions & 2 deletions Compiler/NFFrontEnd/NFBuiltinFuncs.mo
Expand Up @@ -201,7 +201,7 @@ constant Function STRING_ENUM = Function.FUNCTION(Path.IDENT("String"),
constant InstNode STRING_NODE = InstNode.CLASS_NODE("String",
DUMMY_ELEMENT, Visibility.PUBLIC,
Pointer.createImmutable(Class.PARTIAL_BUILTIN(Type.STRING(), ClassTree.EMPTY_TREE(),
Modifier.NOMOD(), Restriction.TYPE())),
Modifier.NOMOD(), NFClass.DEFAULT_PREFIXES, Restriction.TYPE())),
listArrayLiteral({
NFInstNode.CachedData.FUNCTION({
STRING_ENUM,
Expand Down Expand Up @@ -341,7 +341,7 @@ constant Function CLOCK_SOLVER = Function.FUNCTION(Path.IDENT("Clock"),
constant InstNode CLOCK_NODE = InstNode.CLASS_NODE("Clock",
DUMMY_ELEMENT, Visibility.PUBLIC,
Pointer.createImmutable(Class.PARTIAL_BUILTIN(Type.CLOCK(), ClassTree.EMPTY_TREE(),
Modifier.NOMOD(), Restriction.TYPE())),
Modifier.NOMOD(), NFClass.DEFAULT_PREFIXES, Restriction.TYPE())),
listArrayLiteral({
NFInstNode.CachedData.FUNCTION({
CLOCK_INFERED,
Expand Down
6 changes: 4 additions & 2 deletions Compiler/NFFrontEnd/NFClass.mo
Expand Up @@ -87,6 +87,7 @@ uniontype Class
Type ty;
ClassTree elements;
Modifier modifier;
Class.Prefixes prefixes;
Restriction restriction;
end PARTIAL_BUILTIN;

Expand Down Expand Up @@ -145,14 +146,14 @@ uniontype Class
function fromEnumeration
input list<SCode.Enum> literals;
input Type enumType;
input Prefixes prefixes;
input InstNode enumClass;
output Class cls;
protected
ClassTree tree;
algorithm
tree := ClassTree.fromEnumeration(literals, enumType, enumClass);
cls := PARTIAL_BUILTIN(enumType, tree, Modifier.NOMOD(),
Restriction.ENUMERATION());
cls := PARTIAL_BUILTIN(enumType, tree, Modifier.NOMOD(), prefixes, Restriction.ENUMERATION());
end fromEnumeration;

function makeRecordConstructor
Expand Down Expand Up @@ -609,6 +610,7 @@ uniontype Class
algorithm
prefs := match cls
case PARTIAL_CLASS() then cls.prefixes;
case PARTIAL_BUILTIN() then cls.prefixes;
case EXPANDED_CLASS() then cls.prefixes;
case EXPANDED_DERIVED() then cls.prefixes;
end match;
Expand Down
49 changes: 45 additions & 4 deletions Compiler/NFFrontEnd/NFInst.mo
Expand Up @@ -295,7 +295,7 @@ algorithm
algorithm
ty := makeEnumerationType(cdef.enumLst, scope);
then
Class.fromEnumeration(cdef.enumLst, ty, scope);
Class.fromEnumeration(cdef.enumLst, ty, prefs, scope);

else Class.PARTIAL_CLASS(NFClassTree.EMPTY, Modifier.NOMOD(), prefs);
end match;
Expand Down Expand Up @@ -532,7 +532,7 @@ algorithm
// ComplexType instead. Using an empty class tree makes sure it's not
// possible to call the constructor or destructor explicitly.
c := Class.PARTIAL_BUILTIN(Type.COMPLEX(node, eo_ty), NFClassTree.EMPTY_FLAT,
Modifier.NOMOD(), Restriction.EXTERNAL_OBJECT());
Modifier.NOMOD(), NFClass.DEFAULT_PREFIXES, Restriction.EXTERNAL_OBJECT());
node := InstNode.updateClass(c, node);
end expandExternalObject;

Expand Down Expand Up @@ -1291,8 +1291,11 @@ algorithm
fail();
end match;
else
new_cls := match rdcl_cls
case Class.PARTIAL_CLASS()
new_cls := match (orig_cls, rdcl_cls)
case (Class.PARTIAL_BUILTIN(), _)
then redeclareEnum(rdcl_cls, orig_cls, prefs, outerMod, redeclareNode, originalNode);

case (_, Class.PARTIAL_CLASS())
algorithm
rdcl_cls.prefixes := prefs;
rdcl_cls.modifier := Modifier.merge(outerMod, rdcl_cls.modifier);
Expand All @@ -1310,6 +1313,44 @@ algorithm
redeclaredNode := InstNode.replaceClass(new_cls, redeclareNode);
end redeclareClass;

function redeclareEnum
input Class redeclareClass;
input Class originalClass;
input Class.Prefixes prefixes;
input Modifier outerMod;
input InstNode redeclareNode;
input InstNode originalNode;
output Class redeclaredClass = redeclareClass;
algorithm
redeclaredClass := match (redeclaredClass, originalClass)
local
list<String> lits1, lits2;

case (Class.PARTIAL_BUILTIN(ty = Type.ENUMERATION(literals = lits1)),
Class.PARTIAL_BUILTIN(ty = Type.ENUMERATION(literals = lits2)))
algorithm
if not (listEmpty(lits2) or List.isEqualOnTrue(lits1, lits2, stringEq)) then
Error.addMultiSourceMessage(Error.REDECLARE_ENUM_NON_SUBTYPE,
{InstNode.name(originalNode)}, {InstNode.info(redeclareNode), InstNode.info(originalNode)});
fail();
end if;

redeclaredClass.prefixes := prefixes;
redeclaredClass.modifier := Modifier.merge(outerMod, redeclaredClass.modifier);
then
redeclaredClass;

else
algorithm
Error.addMultiSourceMessage(Error.REDECLARE_CLASS_NON_SUBTYPE,
{Restriction.toString(Class.restriction(originalClass)), InstNode.name(originalNode)},
{InstNode.info(redeclareNode), InstNode.info(originalNode)});
then
fail();

end match;
end redeclareEnum;

function instComponent
input InstNode node "The component node to instantiate";
input Component.Attributes attributes "Attributes to be propagated to the component.";
Expand Down
4 changes: 4 additions & 0 deletions Compiler/Util/Error.mo
Expand Up @@ -835,6 +835,10 @@ public constant Message LIBRARY_UNEXPECTED_NAME_CASE_SENSITIVE = MESSAGE(353, SC
Util.gettext("Expected the package to have name %s, but got %s. Proceeding since only the case of the names are different."));
public constant Message PACKAGE_ORDER_CASE_SENSITIVE = MESSAGE(354, SCRIPTING(), WARNING(),
Util.gettext("The package.order file contains a class %s, which is expected to be stored in file %s, but seems to be named %s. Proceeding since only the case of the names are different."));
public constant Message REDECLARE_CLASS_NON_SUBTYPE = MESSAGE(355, TRANSLATION(), ERROR(),
Util.gettext("Redeclaration of %s ‘%s‘ is not a subtype of the redeclared element."));
public constant Message REDECLARE_ENUM_NON_SUBTYPE = MESSAGE(356, TRANSLATION(), ERROR(),
Util.gettext("Redeclaration of enumeration ‘%s‘ is not a subtype of the redeclared element (use enumeration(:) for a generic replaceable enumeration)."));
public constant Message INITIALIZATION_NOT_FULLY_SPECIFIED = MESSAGE(496, TRANSLATION(), WARNING(),
Util.gettext("The initial conditions are not fully specified. %s."));
public constant Message INITIALIZATION_OVER_SPECIFIED = MESSAGE(497, TRANSLATION(), WARNING(),
Expand Down

0 comments on commit f6e1212

Please sign in to comment.