@@ -10630,7 +10630,7 @@ algorithm
1063010630 case (cache,env,ih,mod,pre,csets,(c as SCode.CLASS(name = n,restriction = SCode.R_RECORD())),inst_dims)
1063110631 equation
1063210632 (cache,c,cenv) = Lookup.lookupRecordConstructorClass(cache,env,Absyn.IDENT(n));
10633- (cache,env,ih,{DAE.FUNCTION(fpath,_,ty1,false,_,source,_)}) = implicitFunctionInstantiation2(cache,cenv,ih,mod,pre,csets,c,inst_dims);
10633+ (cache,env,ih,{DAE.FUNCTION(fpath,_,ty1,false,_,source,_)}) = implicitFunctionInstantiation2(cache,cenv,ih,mod,pre,csets,c,inst_dims,true );
1063410634 fun = DAE.RECORD_CONSTRUCTOR(fpath,ty1,source);
1063510635 cache = Env.addDaeFunction(cache, {fun});
1063610636 then (cache,env,ih);
@@ -10639,7 +10639,7 @@ algorithm
1063910639 equation
1064010640 failure(SCode.R_RECORD() = r);
1064110641 true = MetaUtil.strictRMLCheck(RTOpts.debugFlag("rml"),c);
10642- (cache,env,ih,funs) = implicitFunctionInstantiation2(cache,env,ih,mod,pre,csets,c,inst_dims);
10642+ (cache,env,ih,funs) = implicitFunctionInstantiation2(cache,env,ih,mod,pre,csets,c,inst_dims,false );
1064310643 cache = Env.addDaeFunction(cache, funs);
1064410644 then (cache,env,ih);
1064510645
@@ -10666,12 +10666,13 @@ protected function implicitFunctionInstantiation2
1066610666 input Connect.Sets inSets;
1066710667 input SCode.Element inClass;
1066810668 input InstDims inInstDims;
10669+ input Boolean instFunctionTypeOnly "if true, do no additional checking of the function";
1066910670 output Env.Cache outCache;
1067010671 output Env.Env outEnv;
1067110672 output InstanceHierarchy outIH;
1067210673 output list<DAE.Function> funcs;
1067310674algorithm
10674- (outCache,outEnv,outIH,funcs):= matchcontinue (inCache,inEnv,inIH,inMod,inPrefix,inSets,inClass,inInstDims)
10675+ (outCache,outEnv,outIH,funcs):= matchcontinue (inCache,inEnv,inIH,inMod,inPrefix,inSets,inClass,inInstDims,instFunctionTypeOnly )
1067510676 local
1067610677 Connect.Sets csets_1,csets;
1067710678 DAE.Type ty,ty1;
@@ -10704,7 +10705,7 @@ algorithm
1070410705 Option<SCode.Comment> cmt;
1070510706
1070610707 /* normal functions */
10707- case (cache,env,ih,mod,pre,csets,(c as SCode.CLASS(classDef=cd,partialPrefix = partialPrefix, name = n,restriction = SCode.R_FUNCTION(),info = info)),inst_dims)
10708+ case (cache,env,ih,mod,pre,csets,(c as SCode.CLASS(classDef=cd,partialPrefix = partialPrefix, name = n,restriction = SCode.R_FUNCTION(),info = info)),inst_dims,instFunctionTypeOnly )
1070810709 equation
1070910710 (cache,cenv,ih,_,DAE.DAE(daeElts),csets_1,ty,st,_,_) =
1071010711 instClass(cache, env, ih, UnitAbsynBuilder.emptyInstStore(), mod, pre, csets, c, inst_dims, true, INNER_CALL(), ConnectionGraph.EMPTY);
@@ -10726,12 +10727,14 @@ algorithm
1072610727
1072710728 daeElts = optimizeFunction(fpath,daeElts,NONE(),{},{},{});
1072810729 cmt = extractClassDefComment(cache, env, cd);
10730+ /* Not working 100% yet... Also, a lot of code has unused inputs :( */
10731+ Debug.bcall3(false and RTOpts.acceptMetaModelicaGrammar() and not instFunctionTypeOnly,checkFunctionInputUsed,daeElts,NONE(),Absyn.pathString(fpath));
1072910732 then
1073010733 (cache,env_1,ih,{DAE.FUNCTION(fpath,DAE.FUNCTION_DEF(daeElts)::derFuncs,ty1,partialPrefixBool,inlineType,source,cmt)});
1073110734
1073210735 /* External functions should also have their type in env, but no dae. */
1073310736 case (cache,env,ih,mod,pre,csets,(c as SCode.CLASS(partialPrefix=partialPrefix,name = n,restriction = (restr as SCode.R_EXT_FUNCTION()),
10734- classDef = cd as (parts as SCode.PARTS(elementLst = els)), info=info, encapsulatedPrefix = encapsulatedPrefix)),inst_dims)
10737+ classDef = cd as (parts as SCode.PARTS(elementLst = els)), info=info, encapsulatedPrefix = encapsulatedPrefix)),inst_dims,instFunctionTypeOnly )
1073510738 equation
1073610739 (cache,cenv,ih,_,DAE.DAE(daeElts),csets_1,ty,st,_,_) =
1073710740 instClass(cache,env,ih, UnitAbsynBuilder.emptyInstStore(),mod, pre,
@@ -10752,25 +10755,25 @@ algorithm
1075210755 instClassdef(cache, env_1, ih, UnitAbsyn.noStore, mod, pre, csets_1,
1075310756 ClassInf.FUNCTION(fpath), n,parts, restr, vis, partialPrefix, encapsulatedPrefix, inst_dims, true, INNER_CALL(), ConnectionGraph.EMPTY,NONE(),info) "how to get this? impl" ;
1075410757 (cache,ih,extdecl) = instExtDecl(cache, tempenv,ih, n, parts, true, pre,info) "impl" ;
10755- checkExternalFunction(daeElts,extdecl,n);
1075610758
1075710759 // set the source of this element
1075810760 source = DAEUtil.createElementSource(info, Env.getEnvPath(env), PrefixUtil.prefixToCrefOpt(pre), NONE(), NONE());
1075910761 partialPrefixBool = SCode.partialBool(partialPrefix);
1076010762 cmt = extractClassDefComment(cache, env, cd);
10763+ checkExternalFunction(daeElts,extdecl,Absyn.pathString(fpath));
1076110764 then
1076210765 (cache,env_1,ih,{DAE.FUNCTION(fpath,DAE.FUNCTION_EXT(daeElts,extdecl)::derFuncs,ty1,partialPrefixBool,DAE.NO_INLINE(),source,cmt)});
1076310766
1076410767 /* Instantiate overloaded functions */
1076510768 case (cache,env,ih,mod,pre,csets,(c as SCode.CLASS(name = n,restriction = (restr as SCode.R_FUNCTION()),
10766- classDef = SCode.OVERLOAD(pathLst = funcnames))),inst_dims)
10769+ classDef = SCode.OVERLOAD(pathLst = funcnames))),inst_dims,_ )
1076710770 equation
1076810771 (cache,env_1,ih,resfns) = instOverloadedFunctions(cache,env,ih, n, funcnames) "Overloaded functions" ;
1076910772 then
1077010773 (cache,env_1,ih,resfns);
1077110774
1077210775 // handle failure
10773- case (_,env,_,_,_,_,SCode.CLASS(name=n),_)
10776+ case (_,env,_,_,_,_,SCode.CLASS(name=n),_,_ )
1077410777 equation
1077510778 true = RTOpts.debugFlag("failtrace");
1077610779 Debug.traceln("- Inst.implicitFunctionInstantiation2 failed " +& n);
@@ -10825,7 +10828,7 @@ algorithm
1082510828 (cache,p) = makeFullyQualified(cache,cenv,p);
1082610829 // add to cache before instantiating, to break recursion for recursive definitions.
1082710830 cache = Env.addCachedInstFuncGuard(cache,p);
10828- (cache,_,ih,funcs) = implicitFunctionInstantiation2(cache,cenv,ih,DAE.NOMOD(),Prefix.NOPRE(), Connect.emptySet,cdef,{});
10831+ (cache,_,ih,funcs) = implicitFunctionInstantiation2(cache,cenv,ih,DAE.NOMOD(),Prefix.NOPRE(), Connect.emptySet,cdef,{},false );
1082910832
1083010833 funcs = addNameToDerivativeMapping(funcs,path);
1083110834 cache = Env.addDaeFunction(cache, funcs);
@@ -11398,7 +11401,7 @@ algorithm
1139811401 equation
1139911402 stripped_elts = Util.listMap(elts,stripFuncOutputsMod);
1140011403 stripped_class = SCode.CLASS(id,prefixes,e,p,r,SCode.PARTS(elts,{},{},{},{},extDecl,annotationLst,NONE()),info);
11401- (cache,env_1,ih,funs) = implicitFunctionInstantiation2(cache,env,ih, DAE.NOMOD(), Prefix.NOPRE(), Connect.emptySet, stripped_class, {});
11404+ (cache,env_1,ih,funs) = implicitFunctionInstantiation2(cache,env,ih,DAE.NOMOD(), Prefix.NOPRE(), Connect.emptySet, stripped_class, {},true );
1140211405 /* Only external functions are valid without an algorithm section... */
1140311406 cache = Env.addDaeExtFunction(cache, funs);
1140411407 then
@@ -11579,8 +11582,132 @@ protected
1157911582 Integer i;
1158011583algorithm
1158111584 Util.listMap02(els,checkExternalFunctionOutputAssigned,decl,name);
11585+ checkFunctionInputUsed(els,SOME(decl),name);
1158211586end checkExternalFunction;
1158311587
11588+ protected function checkFunctionInputUsed
11589+ input list<DAE.Element> elts;
11590+ input Option<DAE.ExternalDecl> decl;
11591+ input String name;
11592+ protected
11593+ list<DAE.Element> invars,vars,algs;
11594+ algorithm
11595+ (vars,_,_,_,algs,_) := DAEUtil.splitElements(elts);
11596+ invars := Util.listFilter(vars,DAEUtil.isInputVar);
11597+ invars := checkExternalDeclInputUsed(invars,decl);
11598+ invars := Util.listSelect1(invars,vars,checkVarBindingsInputUsed);
11599+ (_,invars) := DAEUtil.traverseDAE2(algs,checkExpInputUsed,invars);
11600+ Util.listMap01(invars,name,warnUnusedFunctionVar);
11601+ end checkFunctionInputUsed;
11602+
11603+ protected function warnUnusedFunctionVar
11604+ input DAE.Element v;
11605+ input String name;
11606+ protected
11607+ DAE.ComponentRef cr;
11608+ DAE.ElementSource source;
11609+ String str;
11610+ algorithm
11611+ DAE.VAR(componentRef=cr,source=source) := v;
11612+ str := ComponentReference.printComponentRefStr(cr);
11613+ Error.addSourceMessage(Error.FUNCTION_UNUSED_INPUT,{str,name},DAEUtil.getElementSourceFileInfo(source));
11614+ end warnUnusedFunctionVar;
11615+
11616+ protected function checkExternalDeclInputUsed
11617+ input list<DAE.Element> names;
11618+ input Option<DAE.ExternalDecl> decl;
11619+ output list<DAE.Element> onames;
11620+ algorithm
11621+ onames := match (names,decl)
11622+ local
11623+ list<DAE.ExtArg> args;
11624+ DAE.ExtArg arg;
11625+ case (names,NONE()) then names;
11626+ case ({},_) then {};
11627+ case (names,SOME(DAE.EXTERNALDECL(returnArg=arg,args=args)))
11628+ equation
11629+ names = Util.listSelect1(names,arg::args,checkExternalDeclArgs);
11630+ then names;
11631+ end match;
11632+ end checkExternalDeclInputUsed;
11633+
11634+ protected function checkExpInputUsed
11635+ input tuple<DAE.Exp,list<DAE.Element>> tpl;
11636+ output tuple<DAE.Exp,list<DAE.Element>> otpl;
11637+ protected
11638+ DAE.Exp exp;
11639+ list<DAE.Element> els;
11640+ algorithm
11641+ (exp,els) := tpl;
11642+ otpl := Expression.traverseExp(exp,checkExpInputUsed2,els);
11643+ end checkExpInputUsed;
11644+
11645+ protected function checkExpInputUsed2
11646+ input tuple<DAE.Exp,list<DAE.Element>> tpl;
11647+ output tuple<DAE.Exp,list<DAE.Element>> otpl;
11648+ algorithm
11649+ otpl := matchcontinue tpl
11650+ local
11651+ DAE.Exp exp;
11652+ list<DAE.Element> els;
11653+ DAE.ComponentRef cr;
11654+ Absyn.Path path;
11655+ case ((exp as DAE.CREF(componentRef=cr),els))
11656+ equation
11657+ els = Util.listSelect1(els,cr,checkExpInputUsed3);
11658+ then ((exp,els));
11659+ case ((exp as DAE.CALL(path=path),els))
11660+ equation
11661+ true = RTOpts.acceptMetaModelicaGrammar();
11662+ cr = ComponentReference.pathToCref(path);
11663+ els = Util.listSelect1(els,cr,checkExpInputUsed3);
11664+ then ((exp,els));
11665+ else tpl;
11666+ end matchcontinue;
11667+ end checkExpInputUsed2;
11668+
11669+ protected function checkExpInputUsed3
11670+ input DAE.Element el;
11671+ input DAE.ComponentRef cr2;
11672+ output Boolean noteq;
11673+ protected
11674+ DAE.ComponentRef cr1;
11675+ algorithm
11676+ DAE.VAR(componentRef=cr1) := el;
11677+ noteq := not ComponentReference.crefEqualNoStringCompare(cr1,cr2);
11678+ end checkExpInputUsed3;
11679+
11680+ protected function checkVarBindingsInputUsed
11681+ input DAE.Element v;
11682+ input list<DAE.Element> els;
11683+ output Boolean notfound;
11684+ algorithm
11685+ notfound := not Util.listContainsWithCompareFunc(v,els,checkVarBindingInputUsed);
11686+ end checkVarBindingsInputUsed;
11687+
11688+ protected function checkVarBindingInputUsed
11689+ input DAE.Element v;
11690+ input DAE.Element el;
11691+ output Boolean found;
11692+ algorithm
11693+ found := match (v,el)
11694+ local
11695+ DAE.Exp exp;
11696+ DAE.ComponentRef cr;
11697+ case (DAE.VAR(componentRef=_),DAE.VAR(direction=DAE.INPUT())) then false;
11698+ case (DAE.VAR(componentRef=cr),DAE.VAR(binding=SOME(exp))) then Expression.expHasCref(exp,cr);
11699+ else false;
11700+ end match;
11701+ end checkVarBindingInputUsed;
11702+
11703+ protected function checkExternalDeclArgs
11704+ input DAE.Element v;
11705+ input list<DAE.ExtArg> args;
11706+ output Boolean notfound;
11707+ algorithm
11708+ notfound := not Util.listContainsWithCompareFunc(v,args,extArgCrefEq);
11709+ end checkExternalDeclArgs;
11710+
1158411711protected function checkExternalFunctionOutputAssigned
1158511712"All outputs must either have a default binding or be used in the external function
1158611713declaration as there is no way to make assignments in external functions."
@@ -11599,10 +11726,9 @@ algorithm
1159911726 DAE.ElementSource source;
1160011727 case (DAE.VAR(direction=DAE.OUTPUT(),componentRef=cr,binding=binding,source=source),DAE.EXTERNALDECL(returnArg=arg,args=args),name)
1160111728 equation
11602- args = Util.listSelect1(arg::args,cr,extArgCrefEq);
1160311729 // Some weird functions pass the same output twice so we cannot check for exactly 1 occurance
1160411730 // Interfacing with LAPACK routines is fun, fun, fun :)
11605- b = listLength( args)>0 or Util.isSome(binding);
11731+ b = Util.listContainsWithCompareFunc(v,arg:: args,extArgCrefEq) or Util.isSome(binding);
1160611732 str = Debug.bcallret1(not b,ComponentReference.printComponentRefStr,cr,"");
1160711733 Error.assertionOrAddSourceMessage(b,Error.EXTERNAL_NOT_SINGLE_RESULT,{str,name},DAEUtil.getElementSourceFileInfo(source));
1160811734 then ();
@@ -11612,15 +11738,21 @@ end checkExternalFunctionOutputAssigned;
1161211738
1161311739protected function extArgCrefEq
1161411740 "See if an external argument matches a cref"
11741+ input DAE.Element v;
1161511742 input DAE.ExtArg arg;
11616- input DAE.ComponentRef cr2;
1161711743 output Boolean b;
1161811744algorithm
11619- b := match (arg,cr2 )
11745+ b := match (v,arg )
1162011746 local
11621- DAE.ComponentRef cr1;
11622- case (DAE.EXTARG(componentRef=cr1),cr2)
11747+ DAE.ComponentRef cr1,cr2;
11748+ DAE.Exp exp;
11749+ case (DAE.VAR(componentRef=cr1),DAE.EXTARG(componentRef=cr2))
11750+ then ComponentReference.crefEqualNoStringCompare(cr1,cr2);
11751+ case (DAE.VAR(direction=DAE.OUTPUT()),_) then false;
11752+ case (DAE.VAR(componentRef=cr1),DAE.EXTARGSIZE(componentRef=cr2))
1162311753 then ComponentReference.crefEqualNoStringCompare(cr1,cr2);
11754+ case (DAE.VAR(componentRef=cr1),DAE.EXTARGEXP(exp=exp))
11755+ then Expression.expHasCref(exp,cr1);
1162411756 else false;
1162511757 end match;
1162611758end extArgCrefEq;
0 commit comments