From eb5e7e0a950b26f6ebdb6d7665cc59c56dac1e07 Mon Sep 17 00:00:00 2001 From: Mahder Gebremedhin Date: Sun, 25 Sep 2022 15:31:56 +0300 Subject: [PATCH] Improve #9399 using additions from #9408 (#9427) * Use the externally used records marker. * Set marker to always be true for the OF. * Use a map/dictionary instead of keeping separate lists. - Use a map (string, record Declaration) to keep a track of records in the SimCode. This allows for a simpler and quicker check. In addition we can update entries easily. * Add MetaModelica records to the map as well. * Debug help * Fix traversal order to avoid possible(?) infinite recursion. * Disable the old creation of record declarations. - See what fails in the testsuite. - It was actually affecting some tests because nested records were cycling back and messing with the order. Not exactly sure how but is not relevant anymore. * Simplify processing of record declrations. - Remove returned lists from functions: elaborateNestedRecordDeclarations elaborateRecordDeclarationsFromTypes elaborateRecordDeclarationsForRecord elaborateNestedRecordDeclarations - Remove input lists from functions: - elaborateRecordDeclarationsFromTypes * Make sure we do not overwrite true values to false. - If an entry already exists in the map and we always update, then there is a chance we might overwrite a 'true' value with a 'false' value for external conversion marker. Check if the entry exists and if it is marked false while then new incoming entry is marked true, then update it. Otherwise do nothing. * Remove input lists from functions - Remove input lists from functions: - elaborateNestedRecordDeclarations - elaborateRecordDeclarationsForRecord * Remove input and output lists from more functions. - Removed from - elaborateRecordDeclarationsForMetarecords * Remove input and output lists from elaborateRecordDeclarations. * Remove input and output lists from more functions. - Remove input and output lists from functions: - elaborateFunctions2 - elaborateFunction * Convert recursive functions to loops. - Recursive functions converted to loops: - elaborateNestedRecordDeclarations - elaborateRecordDeclarationsForMetarecords - elaborateRecordDeclarationsFromTypes * Rename some functions to be more descriptive. - elaborateRecordDeclarationsForMetarecords -> collectRecDeclsFromMetaRecordCallExps - elaborateNestedRecordDeclarations -> collectRecDeclsFromTypesVars - elaborateRecordDeclarationsFromTypes -> collectRecDeclsFromTypes - elaborateRecordDeclarationsForRecord -> collectRecDeclsFromType * Change how records are collected from metarecordcalls - Instead of: - traversing all expressions, collecting all meta record calls to a list, and then traversing this list to collect record declarations - collect record declarations while traversing all expressions (without collecting metarecordcalls into a whole new list.) * Rename functions to be more descriptive. - elaborateRecordDeclarations -> collectRecDeclsFromElems * Convert recursive functions to loops. - Convert recursive functions to loops: - collectRecDeclsFromElems (used to be `elaborateRecordDeclarations`) * Some minor cleanup and renaming. - declMap -> recDeclsMap - needsExternalConversion -> usedExternally --- OMCompiler/Compiler/FrontEnd/DAE.mo | 2 +- OMCompiler/Compiler/FrontEnd/Inst.mo | 4 +- OMCompiler/Compiler/FrontEnd/InstSection.mo | 2 +- OMCompiler/Compiler/FrontEnd/InstUtil.mo | 4 +- OMCompiler/Compiler/FrontEnd/Types.mo | 6 +- .../Compiler/SimCode/SimCodeFunction.mo | 2 +- .../Compiler/SimCode/SimCodeFunctionUtil.mo | 424 +++++++----------- .../Compiler/Template/CodegenCFunctions.tpl | 35 +- OMCompiler/Compiler/Template/SimCodeTV.mo | 1 + 9 files changed, 204 insertions(+), 276 deletions(-) diff --git a/OMCompiler/Compiler/FrontEnd/DAE.mo b/OMCompiler/Compiler/FrontEnd/DAE.mo index 5a457b62d62..b9c6e1ccef5 100644 --- a/OMCompiler/Compiler/FrontEnd/DAE.mo +++ b/OMCompiler/Compiler/FrontEnd/DAE.mo @@ -964,7 +964,7 @@ public uniontype Type "models the different front-end and back-end types" ClassInf.State complexClassType "The type of a class"; list varLst "The variables of a complex type"; EqualityConstraint equalityConstraint; - Boolean needsExternalConversion "If the record is passed to an external function at any point, we need to generate conversion functions for it (for instance to convert 'modelica_integer' to 'int')"; + Boolean usedExternally "If the record is passed to an external function at any point, we need to generate conversion functions for it (for instance to convert 'modelica_integer' to 'int')"; end T_COMPLEX; record T_SUBTYPE_BASIC diff --git a/OMCompiler/Compiler/FrontEnd/Inst.mo b/OMCompiler/Compiler/FrontEnd/Inst.mo index 2cfd10bb176..41260323cc0 100644 --- a/OMCompiler/Compiler/FrontEnd/Inst.mo +++ b/OMCompiler/Compiler/FrontEnd/Inst.mo @@ -1012,7 +1012,7 @@ algorithm end for; tvars := listReverse(tvars); - then DAE.T_COMPLEX(inType.complexClassType, tvars, inType.equalityConstraint, inType.needsExternalConversion); + then DAE.T_COMPLEX(inType.complexClassType, tvars, inType.equalityConstraint, inType.usedExternally); end match; end markDerivedRecordOutsideBindings; @@ -1084,7 +1084,7 @@ algorithm end for; tvars := listReverse(tvars); - then DAE.T_COMPLEX(inType.complexClassType, tvars, inType.equalityConstraint, inType.needsExternalConversion); + then DAE.T_COMPLEX(inType.complexClassType, tvars, inType.equalityConstraint, inType.usedExternally); end match; end markTypesVarsOutsideBindings; diff --git a/OMCompiler/Compiler/FrontEnd/InstSection.mo b/OMCompiler/Compiler/FrontEnd/InstSection.mo index 48f06ff5a3f..a87fdf9bd89 100644 --- a/OMCompiler/Compiler/FrontEnd/InstSection.mo +++ b/OMCompiler/Compiler/FrontEnd/InstSection.mo @@ -3108,7 +3108,7 @@ algorithm equation vars = List.sort(vars, connectorCompGt); then - DAE.T_COMPLEX(ci_state, vars, ec, inType.needsExternalConversion); + DAE.T_COMPLEX(ci_state, vars, ec, inType.usedExternally); else inType; diff --git a/OMCompiler/Compiler/FrontEnd/InstUtil.mo b/OMCompiler/Compiler/FrontEnd/InstUtil.mo index 50ecff3d73f..e3029549058 100644 --- a/OMCompiler/Compiler/FrontEnd/InstUtil.mo +++ b/OMCompiler/Compiler/FrontEnd/InstUtil.mo @@ -5545,7 +5545,7 @@ algorithm case (_,st,l,NONE(),equalityConstraint,_) equation failure(ClassInf.META_UNIONTYPE(_) = st); - then DAE.T_COMPLEX(st,l,equalityConstraint, false); + then DAE.T_COMPLEX(st,l,equalityConstraint, true); // extending case (_,st,l,SOME(bc),equalityConstraint,_) @@ -5646,7 +5646,7 @@ algorithm // not extending basic type! case (_,st,l,NONE(),_) - then DAE.T_COMPLEX(st,l,NONE(), false); // adrpo: TODO! check equalityConstraint! + then DAE.T_COMPLEX(st,l,NONE(), true); // adrpo: TODO! check equalityConstraint! case (_,st,l,SOME(bc),_) then DAE.T_SUBTYPE_BASIC(st,l,bc,NONE()); diff --git a/OMCompiler/Compiler/FrontEnd/Types.mo b/OMCompiler/Compiler/FrontEnd/Types.mo index e4860c5482f..3d9bd9ccd08 100644 --- a/OMCompiler/Compiler/FrontEnd/Types.mo +++ b/OMCompiler/Compiler/FrontEnd/Types.mo @@ -441,7 +441,7 @@ algorithm equation vars = List.map(vars, convertFromExpToTypesVar); then - DAE.T_COMPLEX(CIS, vars, ec, inType.needsExternalConversion); + DAE.T_COMPLEX(CIS, vars, ec, inType.usedExternally); case DAE.T_SUBTYPE_BASIC(CIS, vars, ty, ec) equation @@ -3871,7 +3871,7 @@ algorithm true = Config.acceptMetaModelicaGrammar(); varLst = list(simplifyVar(v) for v in varLst); then - DAE.T_COMPLEX(CIS, varLst, ec, inType.needsExternalConversion); + DAE.T_COMPLEX(CIS, varLst, ec, inType.usedExternally); // do this for records too, otherwise: // frame.R = Modelica.Mechanics.MultiBody.Frames.Orientation({const_matrix); @@ -3880,7 +3880,7 @@ algorithm equation varLst = list(simplifyVar(v) for v in varLst); then - DAE.T_COMPLEX(CIS, varLst, ec, inType.needsExternalConversion); + DAE.T_COMPLEX(CIS, varLst, ec, inType.usedExternally); // otherwise just return the same! case DAE.T_COMPLEX() then inType; diff --git a/OMCompiler/Compiler/SimCode/SimCodeFunction.mo b/OMCompiler/Compiler/SimCode/SimCodeFunction.mo index eefc6a99951..c32d3458d1f 100644 --- a/OMCompiler/Compiler/SimCode/SimCodeFunction.mo +++ b/OMCompiler/Compiler/SimCode/SimCodeFunction.mo @@ -120,7 +120,7 @@ uniontype RecordDeclaration Option aliasName "alias of struct (record) name ? encoded. Code generators can generate an aliasing typedef using this, and avoid problems when casting a record from one type to another (*(othertype*)(&var)), which only works if you have a lhs value."; Absyn.Path defPath "definition path"; list variables "only name and type"; - Boolean needsExternalConversion "If the record is passed to an external function at any point, we need to generate conversion functions for it (for instance to convert 'modelica_integer' to 'int')"; + Boolean usedExternally "If the record is passed to an external function at any point, we need to generate conversion functions for it (for instance to convert 'modelica_integer' to 'int')"; end RECORD_DECL_FULL; record RECORD_DECL_ADD_CONSTRCTOR diff --git a/OMCompiler/Compiler/SimCode/SimCodeFunctionUtil.mo b/OMCompiler/Compiler/SimCode/SimCodeFunctionUtil.mo index 8a196937288..6a35395f58d 100644 --- a/OMCompiler/Compiler/SimCode/SimCodeFunctionUtil.mo +++ b/OMCompiler/Compiler/SimCode/SimCodeFunctionUtil.mo @@ -58,6 +58,7 @@ import Patternm; import SCode; import SCodeUtil; import Testsuite; +import UnorderedMap; public @@ -473,27 +474,31 @@ public function elaborateFunctions input list literals; input list includes; output list functions; - output list extraRecordDecls; + output list recordDecls; output list outIncludes; output list includeDirs; output list libs; output list libpaths; protected list fns; - list outRecordTypes; HashTableStringToPath.HashTable ht; list>> g; + UnorderedMap recDeclsMap; algorithm - (extraRecordDecls, outRecordTypes) := elaborateRecordDeclarationsForMetarecords(literals, {}, {}); - (functions, outRecordTypes, extraRecordDecls, outIncludes, includeDirs, libs,libpaths) := elaborateFunctions2(program, daeElements, {}, outRecordTypes, extraRecordDecls, includes, {}, {},{}); - extraRecordDecls := List.unique(extraRecordDecls); - (extraRecordDecls, _) := elaborateRecordDeclarationsFromTypes(metarecordTypes, extraRecordDecls, outRecordTypes); - extraRecordDecls := List.sort(extraRecordDecls, orderRecordDecls); + recDeclsMap := UnorderedMap.new(stringHashDjb2Mod, stringEq); + (functions, outIncludes, includeDirs, libs, libpaths) := elaborateFunctions2(program, daeElements, {}, includes, {}, {}, {}, recDeclsMap); + + collectRecDeclsFromMetaRecCallExps(literals, recDeclsMap); + collectRecDeclsFromTypes(metarecordTypes, recDeclsMap); + + recordDecls := UnorderedMap.valueList(recDeclsMap); + recordDecls := List.sort(recordDecls, orderRecordDecls); + ht := HashTableStringToPath.emptyHashTableSized(BaseHashTable.lowBucketSize); - (extraRecordDecls,_) := List.mapFold(extraRecordDecls, aliasRecordDeclarations, ht); + (recordDecls,_) := List.mapFold(recordDecls, aliasRecordDeclarations, ht); // Topological sort since we have no guarantees in the order of generated records - g := Graph.buildGraph(extraRecordDecls, getRecordDependencies, extraRecordDecls); - (extraRecordDecls, {}) := Graph.topologicalSort(g, isRecordDeclEqual); + g := Graph.buildGraph(recordDecls, getRecordDependencies, recordDecls); + (recordDecls, {}) := Graph.topologicalSort(g, isRecordDeclEqual); end elaborateFunctions; protected function getRecordDependencies @@ -508,9 +513,9 @@ algorithm list tys; list> tyss; case (SimCodeFunction.RECORD_DECL_FULL(aliasName=SOME(name)),_) - then List.select1(allDecls, isRecordDecl, name); + then List.select1(allDecls, recordDeclHasName, name); case (SimCodeFunction.RECORD_DECL_ADD_CONSTRCTOR(name=name),_) - then List.select1(allDecls, isRecordDecl, name); + then List.select1(allDecls, recordDeclHasName, name); case (SimCodeFunction.RECORD_DECL_FULL(variables=vars),_) equation tys = list(getVarType(v) for v in vars); @@ -542,21 +547,19 @@ protected algorithm DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(path)) := ty; name := AbsynUtil.pathStringUnquoteReplaceDot(path, "_"); - decl := List.find1(allDecls, isRecordDecl, name); + decl := List.find1(allDecls, recordDeclHasName, name); end getRecordDependenciesFromType; -protected function isRecordDecl +protected function recordDeclHasName input SimCodeFunction.RecordDeclaration decl; input String name; output Boolean b; algorithm - b := match (decl,name) - local - String name1; - case (SimCodeFunction.RECORD_DECL_FULL(name=name1),_) then stringEq(name,name1); + b := match decl + case SimCodeFunction.RECORD_DECL_FULL() then stringEq(name, decl.name); else false; end match; -end isRecordDecl; +end recordDeclHasName; protected function isRecordDeclEqual input SimCodeFunction.RecordDeclaration decl1; @@ -564,11 +567,8 @@ protected function isRecordDeclEqual output Boolean b; algorithm b := match (decl1,decl2) - local - String name1,name2; - Absyn.Path path1,path2; - case (SimCodeFunction.RECORD_DECL_FULL(name=name1),SimCodeFunction.RECORD_DECL_FULL(name=name2)) then stringEq(name1,name2); - case (SimCodeFunction.RECORD_DECL_DEF(path=path1),SimCodeFunction.RECORD_DECL_DEF(path=path2)) then AbsynUtil.pathEqual(path1,path2); + case (SimCodeFunction.RECORD_DECL_FULL(),SimCodeFunction.RECORD_DECL_FULL()) then stringEq(decl1.name, decl2.name); + case (SimCodeFunction.RECORD_DECL_DEF(),SimCodeFunction.RECORD_DECL_DEF()) then AbsynUtil.pathEqual(decl1.path, decl2.path); else false; end match; end isRecordDeclEqual; @@ -577,78 +577,74 @@ protected function elaborateFunctions2 input Absyn.Program program; input list daeElements; input list inFunctions; - input list inRecordTypes; - input list inDecls; input list inIncludes; input list inIncludeDirs; input list inLibs; input list inPaths; + input UnorderedMap recDeclsMap; output list outFunctions; - output list outRecordTypes; - output list outDecls; output list outIncludes; output list outIncludeDirs; output list outLibs; output list outLibsPaths; algorithm - (outFunctions, outRecordTypes, outDecls, outIncludes, outIncludeDirs, outLibs,outLibsPaths) := - match (program, daeElements, inFunctions, inRecordTypes, inDecls, inIncludes, inIncludeDirs, inLibs,inPaths) + (outFunctions, outIncludes, outIncludeDirs, outLibs,outLibsPaths) := + match (program, daeElements, inFunctions, inIncludes, inIncludeDirs, inLibs,inPaths) local Boolean b; list accfns, fns; SimCodeFunction.Function fn; - list rt, rt_1, rt_2, includes, libs,libPaths; + list includes, libs,libPaths; DAE.Function fel; list rest; - list decls; String name, fname; list includeDirs; Absyn.Path path; - case (_, {}, accfns, rt, decls, includes, includeDirs, libs,libPaths) - then (listReverse(accfns), rt, decls, includes, includeDirs, libs,libPaths); - case (_, (DAE.FUNCTION( type_ = DAE.T_FUNCTION(functionAttributes=DAE.FUNCTION_ATTRIBUTES(isBuiltin=DAE.FUNCTION_BUILTIN_PTR()))) :: rest), accfns, rt, decls, includes, includeDirs, libs,libPaths) + case (_, {}, accfns, includes, includeDirs, libs,libPaths) + then (listReverse(accfns), includes, includeDirs, libs,libPaths); + case (_, (DAE.FUNCTION( type_ = DAE.T_FUNCTION(functionAttributes=DAE.FUNCTION_ATTRIBUTES(isBuiltin=DAE.FUNCTION_BUILTIN_PTR()))) :: rest), accfns, includes, includeDirs, libs,libPaths) equation // skip over builtin functions - (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, accfns, rt, decls, includes, includeDirs, libs,libPaths); + (fns, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, accfns, includes, includeDirs, libs,libPaths, recDeclsMap); then - (fns, rt_2, decls, includes, includeDirs, libs,libPaths); - case (_, (DAE.FUNCTION(partialPrefix = true) :: rest), accfns, rt, decls, includes, includeDirs, libs,libPaths) + (fns, includes, includeDirs, libs,libPaths); + case (_, (DAE.FUNCTION(partialPrefix = true) :: rest), accfns, includes, includeDirs, libs,libPaths) equation // skip over partial functions - (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, accfns, rt, decls, includes, includeDirs, libs,libPaths); + (fns, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, accfns, includes, includeDirs, libs,libPaths, recDeclsMap); then - (fns, rt_2, decls, includes, includeDirs, libs,libPaths); - case (_, (fel as DAE.FUNCTION(path = path, functions = DAE.FUNCTION_EXT(externalDecl = DAE.EXTERNALDECL(name=name, language="builtin"))::_))::rest, accfns, rt, decls, includes, includeDirs, libs,libPaths) + (fns, includes, includeDirs, libs,libPaths); + case (_, (fel as DAE.FUNCTION(path = path, functions = DAE.FUNCTION_EXT(externalDecl = DAE.EXTERNALDECL(name=name, language="builtin"))::_))::rest, accfns, includes, includeDirs, libs,libPaths) equation // skip over builtin functions @adrpo: we should skip ONLY IF THE NAME OF THE FUNCTION IS THE SAME AS THE NAME OF THE EXTERNAL FUNCTION! fname = AbsynUtil.pathString(AbsynUtil.makeNotFullyQualified(path)); b = stringEq(fname, name); if not b then - (fn,_, decls, includes, includeDirs, libs,libPaths) = elaborateFunction(program, fel, rt, decls, includes, includeDirs, libs,libPaths); + (fn, includes, includeDirs, libs,libPaths) = elaborateFunction(program, fel, includes, includeDirs, libs,libPaths, recDeclsMap); end if; - (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, List.consOnTrue(not b, fn, accfns), rt, decls, includes, includeDirs, libs,libPaths); + (fns, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, List.consOnTrue(not b, fn, accfns), includes, includeDirs, libs,libPaths, recDeclsMap); then - (fns, rt_2, decls, includes, includeDirs, libs,libPaths); + (fns, includes, includeDirs, libs,libPaths); - case (_, (fel as DAE.FUNCTION(path = path, functions = DAE.FUNCTION_EXT(externalDecl = DAE.EXTERNALDECL(name=name, language="C"))::_))::rest, accfns, rt, decls, includes, includeDirs, libs,libPaths) + case (_, (fel as DAE.FUNCTION(path = path, functions = DAE.FUNCTION_EXT(externalDecl = DAE.EXTERNALDECL(name=name, language="C"))::_))::rest, accfns, includes, includeDirs, libs,libPaths) equation // skip over known external C functions @adrpo: we should skip ONLY IF THE NAME OF THE FUNCTION IS THE SAME AS THE NAME OF THE EXTERNAL FUNCTION! fname = AbsynUtil.pathString(AbsynUtil.makeNotFullyQualified(path)); b = listMember(name, SCodeUtil.knownExternalCFunctions) and stringEq(fname, name); if not b then - (fn,_, decls, includes, includeDirs, libs,libPaths) = elaborateFunction(program, fel, rt, decls, includes, includeDirs, libs,libPaths); + (fn, includes, includeDirs, libs,libPaths) = elaborateFunction(program, fel, includes, includeDirs, libs,libPaths, recDeclsMap); end if; - (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, List.consOnTrue(not b, fn, accfns), rt, decls, includes, includeDirs, libs,libPaths); + (fns, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, List.consOnTrue(not b, fn, accfns), includes, includeDirs, libs,libPaths, recDeclsMap); then - (fns, rt_2, decls, includes, includeDirs, libs,libPaths); + (fns, includes, includeDirs, libs,libPaths); - case (_, (fel :: rest), accfns, rt, decls, includes, includeDirs, libs,libPaths) + case (_, (fel :: rest), accfns, includes, includeDirs, libs,libPaths) equation - (fn, rt_1, decls, includes, includeDirs, libs,libPaths) = elaborateFunction(program, fel, rt, decls, includes, includeDirs, libs,libPaths); - (fns, rt_2, decls, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, (fn :: accfns), rt_1, decls, includes, includeDirs, libs,libPaths); + (fn, includes, includeDirs, libs,libPaths) = elaborateFunction(program, fel, includes, includeDirs, libs,libPaths, recDeclsMap); + (fns, includes, includeDirs, libs,libPaths) = elaborateFunctions2(program, rest, (fn :: accfns), includes, includeDirs, libs,libPaths, recDeclsMap); then - (fns, rt_2, decls, includes, includeDirs, libs,libPaths); + (fns, includes, includeDirs, libs,libPaths); end match; end elaborateFunctions2; @@ -656,27 +652,24 @@ end elaborateFunctions2; protected function elaborateFunction input Absyn.Program program; input DAE.Function inElement; - input list inRecordTypes; - input list inRecordDecls; input list inIncludes; input list inIncludeDirs; input list inLibs; input list inLibPaths; + input UnorderedMap recDeclsMap; output SimCodeFunction.Function outFunction; - output list outRecordTypes; - output list outRecordDecls; output list outIncludes; output list outIncludeDirs; output list outLibs; output list outLibPaths; algorithm - (outFunction, outRecordTypes, outRecordDecls, outIncludes, outIncludeDirs, outLibs,outLibPaths):= - matchcontinue (program, inElement, inRecordTypes, inRecordDecls, inIncludes, inIncludeDirs, inLibs,inLibPaths) + (outFunction, outIncludes, outIncludeDirs, outLibs,outLibPaths):= + matchcontinue (program, inElement, inIncludes, inIncludeDirs, inLibs,inLibPaths) local DAE.Function fn; String extfnname, lang, str; list algs, vars; // , bivars, invars, outvars; - list includes, libs, libPaths, fn_libs,fn_paths, fn_includes, fn_includeDirs, rt, rt_1; + list includes, libs, libPaths, fn_libs,fn_paths, fn_includes, fn_includeDirs; Absyn.Path fpath; list args; DAE.Type restype, tp; @@ -687,7 +680,6 @@ algorithm Option ann; DAE.ExternalDecl extdecl; list outVars, inVars, biVars, funArgs, varDecls; - list recordDecls; list bodyStmts; list daeElts; Absyn.Path name; @@ -704,63 +696,63 @@ algorithm case (_, DAE.FUNCTION(path = fpath, source = source, visibility = visibility, functions = DAE.FUNCTION_DEF(body = daeElts)::_, // might be followed by derivative maps type_ = DAE.T_FUNCTION(funcArg=args, functionAttributes=funAttrs), - partialPrefix=false), rt, recordDecls, includes, includeDirs, libs,libPaths) + partialPrefix=false), includes, includeDirs, libs,libPaths) equation DAE.FUNCTION_ATTRIBUTES(functionParallelism=DAE.FP_NON_PARALLEL()) = funAttrs; outVars = List.map(DAEUtil.getOutputElements(daeElts), daeInOutSimVar); funArgs = List.map1(args, typesSimFunctionArg, NONE()); - (recordDecls, rt_1) = elaborateRecordDeclarations(daeElts, recordDecls, rt); + collectRecDeclsFromElems(daeElts, recDeclsMap); vars = List.filterOnTrue(daeElts, isVarQ); varDecls = List.map(vars, daeInOutSimVar); bodyStmts = listAppend(elaborateStatement(e) for e guard DAEUtil.isAlgorithm(e) in daeElts); info = ElementSource.getElementSourceFileInfo(source); then - (SimCodeFunction.FUNCTION(fpath, outVars, funArgs, varDecls, bodyStmts, visibility, info), rt_1, recordDecls, includes, includeDirs, libs,libPaths); + (SimCodeFunction.FUNCTION(fpath, outVars, funArgs, varDecls, bodyStmts, visibility, info), includes, includeDirs, libs,libPaths); case (_, DAE.FUNCTION(path = fpath, source = source, functions = DAE.FUNCTION_DEF(body = daeElts)::_, // might be followed by derivative maps type_ = DAE.T_FUNCTION(funcArg=args, functionAttributes=funAttrs), - partialPrefix=false), rt, recordDecls, includes, includeDirs, libs,libPaths) + partialPrefix=false), includes, includeDirs, libs,libPaths) equation DAE.FUNCTION_ATTRIBUTES(functionParallelism=DAE.FP_KERNEL_FUNCTION()) = funAttrs; outVars = List.map(DAEUtil.getOutputElements(daeElts), daeInOutSimVar); funArgs = List.map1(args, typesSimFunctionArg, NONE()); - (recordDecls, rt_1) = elaborateRecordDeclarations(daeElts, recordDecls, rt); + collectRecDeclsFromElems(daeElts, recDeclsMap); vars = List.filterOnTrue(daeElts, isVarNotInputNotOutput); varDecls = List.map(vars, daeInOutSimVar); bodyStmts = listAppend(elaborateStatement(e) for e guard DAEUtil.isAlgorithm(e) in daeElts); info = ElementSource.getElementSourceFileInfo(source); then - (SimCodeFunction.KERNEL_FUNCTION(fpath, outVars, funArgs, varDecls, bodyStmts, info), rt_1, recordDecls, includes, includeDirs, libs,libPaths); + (SimCodeFunction.KERNEL_FUNCTION(fpath, outVars, funArgs, varDecls, bodyStmts, info), includes, includeDirs, libs,libPaths); case (_, DAE.FUNCTION(path = fpath, source = source, functions = DAE.FUNCTION_DEF(body = daeElts)::_, // might be followed by derivative maps type_ = DAE.T_FUNCTION(funcArg=args, functionAttributes = funAttrs), - partialPrefix=false), rt, recordDecls, includes, includeDirs, libs,libPaths) + partialPrefix=false), includes, includeDirs, libs,libPaths) equation DAE.FUNCTION_ATTRIBUTES(functionParallelism=DAE.FP_PARALLEL_FUNCTION()) = funAttrs; outVars = List.map(DAEUtil.getOutputElements(daeElts), daeInOutSimVar); funArgs = List.map1(args, typesSimFunctionArg, NONE()); - (recordDecls, rt_1) = elaborateRecordDeclarations(daeElts, recordDecls, rt); + collectRecDeclsFromElems(daeElts, recDeclsMap); vars = List.filterOnTrue(daeElts, isVarQ); varDecls = List.map(vars, daeInOutSimVar); bodyStmts = listAppend(elaborateStatement(e) for e guard DAEUtil.isAlgorithm(e) in daeElts); info = ElementSource.getElementSourceFileInfo(source); then - (SimCodeFunction.PARALLEL_FUNCTION(fpath, outVars, funArgs, varDecls, bodyStmts, info), rt_1, recordDecls, includes, includeDirs, libs,libPaths); + (SimCodeFunction.PARALLEL_FUNCTION(fpath, outVars, funArgs, varDecls, bodyStmts, info), includes, includeDirs, libs,libPaths); // External functions. case (_, DAE.FUNCTION(path = fpath, source = source, visibility = visibility, functions = DAE.FUNCTION_EXT(body = daeElts, externalDecl = extdecl)::_, // might be followed by derivative maps - type_ = (DAE.T_FUNCTION(funcArg = args))), rt, recordDecls, includes, includeDirs, libs,libPaths) + type_ = (DAE.T_FUNCTION(funcArg = args))), includes, includeDirs, libs,libPaths) equation DAE.EXTERNALDECL(name=extfnname, args=extargs, returnArg=extretarg, language=lang, ann=ann) = extdecl; @@ -771,7 +763,7 @@ algorithm outVars = List.map(DAEUtil.getOutputElements(daeElts), daeInOutSimVar); inVars = List.map(DAEUtil.getInputVars(daeElts), daeInOutSimVar); biVars = List.map(DAEUtil.getBidirElements(daeElts), daeInOutSimVar); - (recordDecls, rt_1) = elaborateRecordDeclarations(daeElts, recordDecls, rt); + collectRecDeclsFromElems(daeElts, recDeclsMap); info = ElementSource.getElementSourceFileInfo(source); (fn_includes, fn_includeDirs, fn_libs, fn_paths,dynamicLoad) = generateExtFunctionIncludes(program, fpath, ann, info); includes = List.union(fn_includes, includes); @@ -785,24 +777,23 @@ algorithm lang = System.toupper(lang); then (SimCodeFunction.EXTERNAL_FUNCTION(fpath, extfnname, funArgs, simextargs, extReturn, - inVars, outVars, biVars, fn_includes, fn_libs, lang, visibility, info, dynamicLoad), - rt_1, recordDecls, includes, includeDirs, libs,libPaths); + inVars, outVars, biVars, fn_includes, fn_libs, lang, visibility, info, dynamicLoad), includes, includeDirs, libs,libPaths); // Record constructor. - case (_, DAE.RECORD_CONSTRUCTOR(source = source, type_ = DAE.T_FUNCTION(funcArg = args, funcResultType = restype as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(name)))), rt, recordDecls, includes, includeDirs, libs,libPaths) + case (_, DAE.RECORD_CONSTRUCTOR(source = source, type_ = DAE.T_FUNCTION(funcArg = args, funcResultType = restype as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(name)))), includes, includeDirs, libs,libPaths) equation funArgs = List.map1(args, typesSimFunctionArg, NONE()); - (recordDecls, rt_1) = elaborateRecordDeclarationsForRecord(restype, recordDecls, rt); + collectRecDeclsFromType(restype, recDeclsMap); DAE.T_COMPLEX(varLst = varlst) = restype; // varlst = List.filterOnTrue(varlst, Types.isProtectedVar); varlst = List.filterOnFalse(varlst, Types.isModifiableTypesVar); varDecls = List.map(varlst, typesVar); info = ElementSource.getElementSourceFileInfo(source); then - (SimCodeFunction.RECORD_CONSTRUCTOR(name, funArgs, varDecls, SCode.PUBLIC(), info), rt_1, recordDecls, includes, includeDirs, libs,libPaths); + (SimCodeFunction.RECORD_CONSTRUCTOR(name, funArgs, varDecls, SCode.PUBLIC(), info), includes, includeDirs, libs,libPaths); // failure - case (_, fn, _, _, _, _, _,_) + case (_, fn, _, _, _,_) equation Error.addInternalError("function elaborateFunction failed for function: \n" + DAEDump.dumpFunctionStr(fn), sourceInfo()); then @@ -1394,100 +1385,42 @@ algorithm end match; end isLiteralExp; -protected function elaborateRecordDeclarationsFromTypes +protected function collectRecDeclsFromTypes input list inTypes; - input list inAccRecordDecls; - input list inReturnTypes; - output list outRecordDecls; - output list outReturnTypes; + input UnorderedMap recDeclsMap; algorithm - (outRecordDecls, outReturnTypes) := - match (inTypes, inAccRecordDecls, inReturnTypes) - local - list accRecDecls; - DAE.Type firstType; - list restTypes; - list returnTypes; - - case ({}, accRecDecls, _) - then (accRecDecls, inReturnTypes); - case (firstType :: restTypes, accRecDecls, _) - equation - (accRecDecls, returnTypes) = - elaborateRecordDeclarationsForRecord(firstType, accRecDecls, inReturnTypes); - (accRecDecls, returnTypes) = - elaborateRecordDeclarationsFromTypes(restTypes, accRecDecls, returnTypes); - then (accRecDecls, returnTypes); - end match; -end elaborateRecordDeclarationsFromTypes; + for ty in inTypes loop + collectRecDeclsFromType(ty, recDeclsMap); + end for; +end collectRecDeclsFromTypes; -protected function elaborateRecordDeclarations +protected function collectRecDeclsFromElems "Translate all records used by varlist to structs." - input list inVars; - input list inAccRecordDecls; - input list inReturnTypes; - output list outRecordDecls; - output list outReturnTypes; -algorithm - (outRecordDecls, outReturnTypes) := - matchcontinue (inVars, inAccRecordDecls, inReturnTypes) - local - DAE.Element var; - list rest; - DAE.Type ft; - list rt, rt_1, rt_2; - list accRecDecls; - DAE.Algorithm algorithm_; - list expl; - Option binding; + input list inElems; + input UnorderedMap recDeclsMap; +algorithm + for elem in inElems loop - case ({}, accRecDecls, rt) then (accRecDecls, rt); + () := match elem + case DAE.VAR() algorithm + collectRecDeclsFromType(elem.ty, recDeclsMap); - case (((DAE.VAR(ty = ft, binding = binding)) :: rest), accRecDecls, rt) - equation - (accRecDecls, rt_1) = elaborateRecordDeclarationsForRecord(ft, accRecDecls, rt); - if Util.isSome(binding) and Config.acceptMetaModelicaGrammar() then - (_, expl) = Expression.traverseExpBottomUp(Util.getOption(binding), matchMetarecordCalls, {}); - (accRecDecls, rt_1) = elaborateRecordDeclarationsForMetarecords(expl, accRecDecls, rt_1); + if Util.isSome(elem.binding) and Config.acceptMetaModelicaGrammar() then + (_, _) := Expression.traverseExpBottomUp(Util.getOption(elem.binding), collectRecDeclsFromMetaRecCallExp, recDeclsMap); end if; - (accRecDecls, rt_2) = elaborateRecordDeclarations(rest, accRecDecls, rt_1); - then - (accRecDecls, rt_2); + then (); - case ((DAE.ALGORITHM(algorithm_ = algorithm_) :: rest), accRecDecls, rt) - equation - true = Config.acceptMetaModelicaGrammar(); - ((_, expl)) = DAEUtil.traverseAlgorithmExps(algorithm_, Expression.traverseSubexpressionsHelper, (matchMetarecordCalls, {})); - (accRecDecls, rt_2) = elaborateRecordDeclarationsForMetarecords(expl, accRecDecls, rt); - // TODO: ? what about rest ? , can be there something else after the ALGORITHM - (accRecDecls, rt_2) = elaborateRecordDeclarations(rest, accRecDecls, rt_2); - then - (accRecDecls, rt_2); + case DAE.ALGORITHM() algorithm + if Config.acceptMetaModelicaGrammar() then + (_, _) := DAEUtil.traverseAlgorithmExps(elem.algorithm_, Expression.traverseSubexpressionsHelper, (collectRecDeclsFromMetaRecCallExp, recDeclsMap)); + end if; + then (); - case ((_ :: rest), accRecDecls, rt) - equation - (accRecDecls, rt_1) = elaborateRecordDeclarations(rest, accRecDecls, rt); - then - (accRecDecls, rt_1); - end matchcontinue; -end elaborateRecordDeclarations; + else (); + end match; -protected function matchMetarecordCalls "Used together with getMatchingExps" - input DAE.Exp e; - input list acc; - output DAE.Exp outExp; - output list outExps; -algorithm - (outExp,outExps) := matchcontinue (e,acc) - local - Integer index; - case (DAE.METARECORDCALL(index = index), _) - equation - outExps = List.consOnTrue(-1 <> index, e, acc); - then (e, outExps); - else (e,acc); - end matchcontinue; -end matchMetarecordCalls; + end for; +end collectRecDeclsFromElems; protected function isVarQ "Succeeds if inElement is a variable or constant that is not input." @@ -1595,76 +1528,74 @@ algorithm end match; end getCrefFromExp; -protected function elaborateRecordDeclarationsForRecord +protected function collectRecDeclsFromType "Helper function to generateStructsForRecords." input DAE.Type inRecordType; - input list inAccRecordDecls; - input list inReturnTypes; - output list outRecordDecls; - output list outReturnTypes; + input UnorderedMap recDeclsMap; algorithm - (outRecordDecls, outReturnTypes) := match (inRecordType, inAccRecordDecls, inReturnTypes) + () := match (inRecordType) local Absyn.Path path; list varlst; String name,sname; - list rt, rt_1, fieldNames; - list accRecDecls; + list fieldNames; list vars; - Integer varnum; SimCodeFunction.RecordDeclaration recDecl; - Boolean is_default; + Option optRecDecl; + Boolean is_default, usedExternally, bool1; - case (DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(path), varLst = varlst), accRecDecls, rt) + case (DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(path), varLst = varlst, usedExternally = usedExternally)) algorithm name := AbsynUtil.pathStringUnquoteReplaceDot(path, "_"); - rt_1 := rt; - (sname, is_default) := checkBindingsandGetConstructorName(name, varlst); - // is_default := stringEqual(sname,name); - if not listMember(sname, rt_1) then - rt_1 := sname :: rt_1; + optRecDecl := UnorderedMap.get(sname, recDeclsMap); - if is_default then - (accRecDecls, rt_1) := elaborateNestedRecordDeclarations(varlst, accRecDecls, rt_1); + if is_default then + // If it already exists check if we need to update it. + if Util.isSome(optRecDecl) then + SOME(SimCodeFunction.RECORD_DECL_FULL(_, _, _, vars, bool1)) := optRecDecl; - vars := List.map(varlst, typesVar); - recDecl := SimCodeFunction.RECORD_DECL_FULL(sname, NONE(), path, vars, false); + if usedExternally and not bool1 then + recDecl := SimCodeFunction.RECORD_DECL_FULL(sname, NONE(), path, vars, true); + UnorderedMap.add(sname, recDecl, recDeclsMap); + end if; + // Add it if it does not exist. else vars := List.map(varlst, typesVar); - recDecl := SimCodeFunction.RECORD_DECL_ADD_CONSTRCTOR(sname, name, vars); + recDecl := SimCodeFunction.RECORD_DECL_FULL(sname, NONE(), path, vars, usedExternally); + UnorderedMap.add(sname, recDecl, recDeclsMap); + + collectRecDeclsFromTypesVars(varlst, recDeclsMap); end if; - accRecDecls := List.appendElt(recDecl, accRecDecls); + // It is not a default construtor + else + // Add it if does not exist. Otherwise do nothing. + if Util.isNone(optRecDecl) then + vars := List.map(varlst, typesVar); + recDecl := SimCodeFunction.RECORD_DECL_ADD_CONSTRCTOR(sname, name, vars); + UnorderedMap.add(sname, recDecl, recDeclsMap); + end if; end if; + then (); - then (accRecDecls, rt_1); - - case (DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_)), accRecDecls, rt) - then (accRecDecls, rt); + case (DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_))) then (); - case (DAE.T_METARECORD(path = Absyn.QUALIFIED(name="SourceInfo")), accRecDecls, rt) - then (accRecDecls, rt); + case (DAE.T_METARECORD(path = Absyn.QUALIFIED(name="SourceInfo"))) then (); - case (DAE.T_METARECORD(fields = varlst, path=path), accRecDecls, rt) + case (DAE.T_METARECORD(fields = varlst, path=path)) equation sname = AbsynUtil.pathStringUnquoteReplaceDot(path, "_"); - if not listMember(sname, rt) then - fieldNames = List.map(varlst, generateVarName); - accRecDecls = SimCodeFunction.RECORD_DECL_DEF(path, fieldNames) :: accRecDecls; - rt_1 = sname::rt; - (accRecDecls, rt_1) = elaborateNestedRecordDeclarations(varlst, accRecDecls, rt_1); - else - rt_1 = rt; - end if; - then (accRecDecls, rt_1); + fieldNames = List.map(varlst, generateVarName); + UnorderedMap.tryAdd(sname, SimCodeFunction.RECORD_DECL_DEF(path, fieldNames), recDeclsMap); + collectRecDeclsFromTypesVars(varlst, recDeclsMap); + then (); - case (_, accRecDecls, rt) - then (accRecDecls, rt); + case (_) then (); end match; -end elaborateRecordDeclarationsForRecord; +end collectRecDeclsFromType; protected function typesVarNoBinding input DAE.Var inTypesVar; @@ -1801,65 +1732,48 @@ algorithm end match; end generateVarName; -protected function elaborateNestedRecordDeclarations -"Helper function to elaborateRecordDeclarations." - input list inRecordTypes; - input list inAccRecordDecls; - input list inReturnTypes; - output list outRecordDecls; - output list outReturnTypes; +protected function collectRecDeclsFromTypesVars +"Helper function to collectRecDeclsFromElems." + input list inRecordTypeVars; + input UnorderedMap recDeclsMap; algorithm - (outRecordDecls, outReturnTypes) := matchcontinue (inRecordTypes, inAccRecordDecls, inReturnTypes) - local - DAE.Type ty; - list rest; - list rt, rt_1, rt_2; - list accRecDecls; - case ({}, accRecDecls, rt) - then (accRecDecls, rt); - case (DAE.TYPES_VAR(ty = ty as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_)))::rest, accRecDecls, rt) - equation - (accRecDecls, rt_1) = elaborateRecordDeclarationsForRecord(ty, accRecDecls, rt); - (accRecDecls, rt_2) = elaborateNestedRecordDeclarations(rest, accRecDecls, rt_1); - then (accRecDecls, rt_2); - case (_::rest, accRecDecls, rt) - equation - (accRecDecls, rt_1) = elaborateNestedRecordDeclarations(rest, accRecDecls, rt); - then (accRecDecls, rt_1); - end matchcontinue; -end elaborateNestedRecordDeclarations; + for recTyVar in inRecordTypeVars loop + () := match recTyVar + case DAE.TYPES_VAR(ty = DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_))) algorithm + collectRecDeclsFromType(recTyVar.ty, recDeclsMap); + then (); + + else (); + end match; + end for; +end collectRecDeclsFromTypesVars; -protected function elaborateRecordDeclarationsForMetarecords +protected function collectRecDeclsFromMetaRecCallExps input list inExpl; - input list inAccRecordDecls; - input list inReturnTypes; - output list outRecordDecls; - output list outReturnTypes; + input UnorderedMap recDeclsMap; algorithm - (outRecordDecls, outReturnTypes) := match (inExpl, inAccRecordDecls, inReturnTypes) - local - list rt, rt_1, rt_2, fieldNames; - list rest; - String name; - Absyn.Path path; - list accRecDecls; - Boolean b; + for exp in inExpl loop + collectRecDeclsFromMetaRecCallExp(exp, recDeclsMap); + end for; +end collectRecDeclsFromMetaRecCallExps; + +protected function collectRecDeclsFromMetaRecCallExp + input output DAE.Exp inExp; + input output UnorderedMap recDeclsMap; +protected + String name; +algorithm + () := match inExp + case DAE.METARECORDCALL() algorithm + if inExp.index <> -1 then + name := AbsynUtil.pathStringUnquoteReplaceDot(inExp.path, "_"); + UnorderedMap.tryAdd(name, SimCodeFunction.RECORD_DECL_DEF(inExp.path, inExp.fieldNames), recDeclsMap); + end if; + then (); - case ({}, accRecDecls, rt) then (accRecDecls, rt); - case (DAE.METARECORDCALL(path=path, fieldNames=fieldNames)::rest, accRecDecls, rt) - equation - name = AbsynUtil.pathStringUnquoteReplaceDot(path, "_"); - b = listMember(name, rt); - accRecDecls = List.consOnTrue(not b, SimCodeFunction.RECORD_DECL_DEF(path, fieldNames), accRecDecls); - rt_1 = List.consOnTrue(not b, name, rt); - (accRecDecls, rt_2) = elaborateRecordDeclarationsForMetarecords(rest, accRecDecls, rt_1); - then (accRecDecls, rt_2); - case (_::rest, accRecDecls, rt) - equation - (accRecDecls, rt_1) = elaborateRecordDeclarationsForMetarecords(rest, accRecDecls, rt); - then (accRecDecls, rt_1); + else (); end match; -end elaborateRecordDeclarationsForMetarecords; +end collectRecDeclsFromMetaRecCallExp; protected function generateExtFunctionIncludes "by investigating the annotation of an external function." diff --git a/OMCompiler/Compiler/Template/CodegenCFunctions.tpl b/OMCompiler/Compiler/Template/CodegenCFunctions.tpl index 84c25eaa886..60407d9b0b6 100644 --- a/OMCompiler/Compiler/Template/CodegenCFunctions.tpl +++ b/OMCompiler/Compiler/Template/CodegenCFunctions.tpl @@ -427,7 +427,7 @@ template recordDeclaration(RecordDeclaration recDecl) <%recordModelicaCallConstrctor(r.name, r.variables)%> <%recordCopyDef(r.name, r.variables)%> - <%recordCopyExternalDefs(r.name, r.variables)%> + <%if r.usedExternally then recordCopyExternalDefs(r.name, r.variables)%> >> case r as RECORD_DECL_ADD_CONSTRCTOR(__) then << @@ -498,7 +498,7 @@ end recordDeclarationExtraCtor; template recordDeclarationFullHeader(RecordDeclaration recDecl) "Generates structs for a record declaration. This will generate - a default record construtor function (no argumens) and a record copy function. + a default record constructor function (no arguments) and a record copy function. These generated functions are fully recursive. That means records in records will be handled properly. It will also generate (#define) array versions of these functions." @@ -536,28 +536,41 @@ template recordDeclarationFullHeader(RecordDeclaration recDecl) case SOME(str) then << typedef <%str%> <%rec_name%>; - typedef <%str%>_external <%rec_name%>_external; + <% if r.usedExternally then + << + typedef <%str%>_external <%rec_name%>_external; + >> + %> >> else << typedef struct { <%r.variables |> var as VARIABLE(__) => '<%varType(var)%> _<%crefStr(var.name)%>;' ;separator="\n"%> } <%rec_name%>; - typedef struct { - <%r.variables |> var as VARIABLE(__) => '<%extType(var.ty, true, false, false)%> _<%crefStr(var.name)%>;' ;separator="\n"%> - } <%rec_name%>_external; - >> %> + <% if r.usedExternally then + << + typedef struct { + <%r.variables |> var as VARIABLE(__) => '<%extType(var.ty, true, false, false)%> _<%crefStr(var.name)%>;' ;separator="\n"%> + } <%rec_name%>_external; + >> + %> + >> + %> extern struct record_description <%underscorePath(r.defPath)%>__desc; void <%ctor_func_name%>(threadData_t *threadData, void* v_ths <%ctor_additional_inputs%>); #define <%ctor_macro_name%>(td, ths <%ctor_macro_additional_inputs%>) <%ctor_func_name%>(td, &ths <%ctor_macro_additional_inputs%>) void <%cpy_func_name%>(void* v_src, void* v_dst); #define <%cpy_macro_name%>(src,dst) <%cpy_func_name%>(&src, &dst) - void <%cpy_to_external_func_name%>(void* v_src, void* v_dst); - #define <%cpy_to_external_macro_name%>(src,dst) <%cpy_to_external_func_name%>(&src, &dst) - void <%cpy_from_external_func_name%>(void* v_src, void* v_dst); - #define <%cpy_from_external_macro_name%>(src,dst) <%cpy_from_external_func_name%>(&src, &dst) + <%if r.usedExternally then + << + void <%cpy_to_external_func_name%>(void* v_src, void* v_dst); + #define <%cpy_to_external_macro_name%>(src,dst) <%cpy_to_external_func_name%>(&src, &dst) + void <%cpy_from_external_func_name%>(void* v_src, void* v_dst); + #define <%cpy_from_external_macro_name%>(src,dst) <%cpy_from_external_func_name%>(&src, &dst) + >> + %> // This function should eventually replace the default 'modelica' record constructor funcition // that omc used to generate, i.e., replace functionBodyRecordConstructor template. // <%rec_name%> <%modelica_ctor_name%>(threadData_t *threadData <%modelica_ctor_inputs%>); diff --git a/OMCompiler/Compiler/Template/SimCodeTV.mo b/OMCompiler/Compiler/Template/SimCodeTV.mo index ef98fc4de5c..6e14560fab3 100644 --- a/OMCompiler/Compiler/Template/SimCodeTV.mo +++ b/OMCompiler/Compiler/Template/SimCodeTV.mo @@ -1045,6 +1045,7 @@ package SimCodeFunction Option aliasName; Absyn.Path defPath; list variables; + Boolean usedExternally; end RECORD_DECL_FULL; record RECORD_DECL_ADD_CONSTRCTOR String ctor_name;