Skip to content

Commit

Permalink
Fix for #3281:
Browse files Browse the repository at this point in the history
- Fixed handling of subscripted MetaModelica array crefs.


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@25678 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
perost committed Apr 22, 2015
1 parent b0bedfc commit b35172a
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 98 deletions.
1 change: 1 addition & 0 deletions Compiler/FrontEnd/Absyn.mo
Expand Up @@ -6311,6 +6311,7 @@ public function crefExplode
algorithm
outCrefParts := match inCref
case CREF_QUAL() then crefExplode(inCref.componentRef, crefFirstCref(inCref) :: inAccum);
case CREF_FULLYQUALIFIED() then crefExplode(inCref.componentRef, inAccum);
else listReverse(inCref :: inAccum);
end match;
end crefExplode;
Expand Down
9 changes: 5 additions & 4 deletions Compiler/FrontEnd/InstSection.mo
Expand Up @@ -5148,12 +5148,13 @@ protected function getIteratorType
input SourceInfo info;
output DAE.Type oty;
algorithm
oty := match (ty,id,info)
oty := match ty
local
String str;
case (DAE.T_ARRAY(ty = oty),_,_) then oty;
case (DAE.T_METALIST(ty = oty),_,_) then Types.boxIfUnboxedType(oty);
case (DAE.T_METAARRAY(ty = oty),_,_) then Types.boxIfUnboxedType(oty);
case DAE.T_ARRAY(ty = oty) then oty;
case DAE.T_METALIST(ty = oty) then Types.boxIfUnboxedType(oty);
case DAE.T_METAARRAY(ty = oty) then Types.boxIfUnboxedType(oty);
case DAE.T_METATYPE(ty = oty) then getIteratorType(ty.ty, id, info);
else
equation
str = Types.unparseType(ty);
Expand Down
3 changes: 3 additions & 0 deletions Compiler/FrontEnd/Lookup.mo
Expand Up @@ -2661,6 +2661,9 @@ algorithm

case(t as DAE.T_UNKNOWN(_), _) then t;

case (DAE.T_METAARRAY(), {DAE.INDEX()}) then inType.ty;
case (DAE.T_METAARRAY(), {_}) then inType;

case (t,s)
equation
true = Flags.isSet(Flags.FAILTRACE);
Expand Down
91 changes: 46 additions & 45 deletions Compiler/FrontEnd/Static.mo
Expand Up @@ -10361,12 +10361,12 @@ function: elabCref
output FCore.Cache outCache;
output Option<tuple<DAE.Exp,DAE.Properties,DAE.Attributes>> res;
algorithm
(outCache,res) := matchcontinue (inCache,inEnv,inComponentRef,inImplicit,performVectorization,inPrefix,evalCref,info)
(outCache,res) := matchcontinue (inCache,inEnv,inComponentRef,inImplicit,inPrefix)
local
DAE.ComponentRef c_1;
DAE.Const const,const1,const2,constCref,constSubs;
DAE.TypeSource tySource;
DAE.Type t,origt;
DAE.Type t,origt, sub_ty;
DAE.Type tt;
DAE.Exp exp,exp1,exp2,crefExp,expASUB;
FCore.Graph env;
Expand All @@ -10389,7 +10389,7 @@ algorithm
DAE.Binding binding "equation modification";

// wildcard
case (cache,_,Absyn.WILD(),_,_,_,_,_)
case (cache, _, Absyn.WILD(), _, _)
equation
t = DAE.T_ANYTYPE_DEFAULT;
et = Types.simplifyType(t);
Expand All @@ -10398,7 +10398,7 @@ algorithm
(cache,SOME((crefExp,DAE.PROP(t, DAE.C_VAR()),DAE.dummyAttrVar)));

// Boolean => {false, true}
case (cache, _, Absyn.CREF_IDENT(name = "Boolean"), _, _, _, _, _)
case (cache, _, Absyn.CREF_IDENT(name = "Boolean"), _, _)
equation
exp = Expression.makeScalarArray({DAE.BCONST(false), DAE.BCONST(true)}, DAE.T_BOOL_DEFAULT);
t = DAE.T_ARRAY(DAE.T_BOOL_DEFAULT, {DAE.DIM_INTEGER(2)}, DAE.emptyTypeSource);
Expand All @@ -10407,51 +10407,49 @@ algorithm

// MetaModelica arrays are only used in function context as IDENT, and at most one subscript
// No vectorization is performed
case (cache,env,Absyn.CREF_IDENT(name=id, subscripts={Absyn.SUBSCRIPT(e)}),impl,_,pre,_,_)
equation
true = Config.acceptMetaModelicaGrammar();
(cache,SOME((exp1,DAE.PROP(DAE.T_METAARRAY(ty = t), const1),attr))) = elabCref1(cache,env,Absyn.CREF_IDENT(id,{}),false,false,pre,evalCref,info);
(cache,exp2,DAE.PROP(DAE.T_INTEGER(), const2),_) = elabExpInExpression(cache,env,e,impl,NONE(),false,pre,info);
const = Types.constAnd(const1,const2);
expASUB = Expression.makeASUB(exp1,{exp2});
then
(cache,SOME((expASUB,DAE.PROP(t, const),attr)));
case (cache, env, Absyn.CREF_IDENT(name = id, subscripts = {Absyn.SUBSCRIPT(e)}), impl, pre)
algorithm
true := Config.acceptMetaModelicaGrammar();
// Elaborate the cref without the subscript.
(cache, SOME((exp1, DAE.PROP(t, const1), attr))) :=
elabCref1(cache, env, Absyn.CREF_IDENT(id, {}), false, false, pre, evalCref, info);

// a normal cref, fully-qualified and lookupVar failed in some weird way in the previous case
case (cache,env,Absyn.CREF_FULLYQUALIFIED(c),impl,doVect,pre,_,_)
equation
c = replaceEnd(c);
env = FGraph.topScope(env);
(cache,c_1,constSubs,hasZeroSizeDim) = elabCrefSubs(cache, env, inEnv, c, pre, Prefix.NOPRE(), impl, false, info);
(cache,attr,t,binding,forIteratorConstOpt,splicedExpData,_,_,_) = Lookup.lookupVar(cache, env, c_1);
// variability = applySubscriptsVariability(DAEUtil.getAttrVariability(attr), constSubs);
// attr = DAEUtil.setAttrVariability(attr, variability);
// get the binding if is a constant
(cache,exp,constCref,attr) = elabCref2(cache, env, c_1, attr, constSubs, forIteratorConstOpt, t, binding, doVect, splicedExpData, pre, evalCref, info);
const = constCref; // Types.constAnd(constCref, constSubs);
t = fixEnumerationType(t);
(exp,const) = evaluateEmptyVariable(hasZeroSizeDim and evalCref,exp,t,const);
// Check that the type is a MetaModelica array, and get the element type.
t := Types.metaArrayElementType(t);

// Elaborate the subscript.
(cache,exp2,DAE.PROP(sub_ty, const2),_) :=
elabExpInExpression(cache,env,e,impl,NONE(),false,pre,info);

// Unbox the subscript if it's boxed, since it will be converted to an
// arrayGet/arrayUpdate in code generation.
if Types.isMetaBoxedType(sub_ty) then
sub_ty := Types.unboxedType(sub_ty);
exp2 := DAE.UNBOX(exp2, sub_ty);
end if;

true := Types.isScalarInteger(sub_ty);
const := Types.constAnd(const1,const2);
exp := Expression.makeASUB(exp1,{exp2});
then
(cache,SOME((exp,DAE.PROP(t, const),attr)));
(cache, SOME((exp, DAE.PROP(t, const), attr)));

// a normal cref
case (cache,env,c,impl,doVect,pre,_,_)
equation
c = replaceEnd(c);
(cache,c_1,constSubs,hasZeroSizeDim) = elabCrefSubs(cache, env, env, c, pre, Prefix.NOPRE(), impl, false, info);
(cache,attr,t,binding,forIteratorConstOpt,splicedExpData,_,_,_) = Lookup.lookupVar(cache, env, c_1);
// variability = applySubscriptsVariability(DAEUtil.getAttrVariability(attr), constSubs);
// attr = DAEUtil.setAttrVariability(attr, variability);
case (cache, env, c, impl, pre)
algorithm
c := replaceEnd(c);
env := if Absyn.crefIsFullyQualified(inComponentRef) then FGraph.topScope(inEnv) else inEnv;
(cache,c_1,constSubs,hasZeroSizeDim) := elabCrefSubs(cache, env, inEnv, c, pre, Prefix.NOPRE(), impl, false, info);
(cache,attr,t,binding,forIteratorConstOpt,splicedExpData) := Lookup.lookupVar(cache, env, c_1);
// get the binding if is a constant
(cache,exp,constCref,attr) = elabCref2(cache, env, c_1, attr, constSubs, forIteratorConstOpt, t, binding, doVect, splicedExpData, pre, evalCref, info);
const = constCref; // Types.constAnd(constCref, constSubs);
t = fixEnumerationType(t);
(exp,const) = evaluateEmptyVariable(hasZeroSizeDim and evalCref,exp,t,const);
(cache,exp,const,attr) := elabCref2(cache, env, c_1, attr, constSubs, forIteratorConstOpt, t, binding, performVectorization, splicedExpData, pre, evalCref, info);
t := fixEnumerationType(t);
(exp,const) := evaluateEmptyVariable(hasZeroSizeDim and evalCref,exp,t,const);
then
(cache,SOME((exp,DAE.PROP(t, const),attr)));

// An enumeration type => array of enumeration literals.
case (cache, env, c, _, _, _, _, _)
case (cache, env, c, _, _)
equation
c = replaceEnd(c);
path = Absyn.crefToPath(c);
Expand All @@ -10465,7 +10463,7 @@ algorithm
(cache,SOME((exp,DAE.PROP(t, DAE.C_CONST()),DAE.dummyAttrConst /* RO */)));

// MetaModelica Partial Function
case (cache,env,c,_,_,_,_,_)
case (cache, env, c, _, _)
equation
// true = Flags.isSet(Flags.FNPTR) or Config.acceptMetaModelicaGrammar();
path = Absyn.crefToPath(c);
Expand All @@ -10489,14 +10487,14 @@ algorithm
(cache,SOME((exp,DAE.PROP(t,DAE.C_VAR()),DAE.dummyAttrConst /* RO */)));

// MetaModelica extension
case (cache,_,Absyn.CREF_IDENT("NONE",{}),_,_,_,_,_)
case (cache, _, Absyn.CREF_IDENT("NONE",{}), _, _)
equation
true = Config.acceptMetaModelicaGrammar();
Error.addSourceMessage(Error.META_NONE_CREF, {}, info);
then
(cache,NONE());

case (_,env,c,_,_,_,_,_)
case (_, env, c, _, _)
equation
// enabled with +d=failtrace
true = Flags.isSet(Flags.FAILTRACE);
Expand All @@ -10522,12 +10520,13 @@ algorithm
then
(cache,NONE());*/

case (cache,env,c,impl,_,pre,_,_)
case (cache, env, c, impl, pre)
equation
failure((_,_,_,_) = elabCrefSubs(cache,env, env,c, pre, Prefix.NOPRE(),impl,false,info));
s = Dump.printComponentRefStr(c);
scope = FGraph.printGraphPathStr(env);
Error.addSourceMessage(Error.LOOKUP_VARIABLE_ERROR, {s,scope}, info); // - no need to add prefix info since problem only depends on the scope?
// No need to add prefix info since problem only depends on the scope?
Error.addSourceMessage(Error.LOOKUP_VARIABLE_ERROR, {s,scope}, info);
then
(cache,NONE());
end matchcontinue;
Expand Down Expand Up @@ -12184,6 +12183,8 @@ algorithm
case DAE.T_ARRAY(ty = DAE.T_INTEGER()) then DAE.SLICE(inDaeExp);
case DAE.T_ARRAY(ty = DAE.T_ENUMERATION()) then DAE.SLICE(inDaeExp);
case DAE.T_ARRAY(ty = DAE.T_BOOL()) then DAE.SLICE(inDaeExp);
case DAE.T_METABOXED()
then elabSubscriptType(inType.ty, inAbsynExp, inDaeExp, inInfo);

else
equation
Expand Down
52 changes: 27 additions & 25 deletions Compiler/FrontEnd/Types.mo
Expand Up @@ -942,33 +942,15 @@ end getDimensionSizes;
public function getDimensions
"Returns the dimensions of a Type."
input DAE.Type inType;
output DAE.Dimensions outIntegerLst;
output DAE.Dimensions outDimensions;
algorithm
outIntegerLst := matchcontinue (inType)
local
DAE.Dimensions res;
Type tp;
DAE.Dimensions dims;

case (DAE.T_ARRAY(dims = dims,ty = tp))
equation
res = getDimensions(tp);
res = listAppend(dims, res);
then
res;

case (DAE.T_METAARRAY(ty = tp))
equation
res = getDimensions(tp);
then
(DAE.DIM_UNKNOWN() :: res);

case (DAE.T_SUBTYPE_BASIC(complexType =tp))
then
getDimensions(tp);

outDimensions := match inType
case DAE.T_ARRAY() then listAppend(inType.dims, getDimensions(inType.ty));
case DAE.T_METAARRAY() then DAE.DIM_UNKNOWN() :: getDimensions(inType.ty);
case DAE.T_SUBTYPE_BASIC() then getDimensions(inType.complexType);
case DAE.T_METATYPE() then getDimensions(inType.ty);
else {};
end matchcontinue;
end match;
end getDimensions;

public function getDimensionNth
Expand Down Expand Up @@ -5540,6 +5522,16 @@ algorithm
end match;
end isBoxedType;

public function isMetaBoxedType
input DAE.Type inType;
output Boolean outIsMetaBoxed;
algorithm
outIsMetaBoxed := match inType
case DAE.T_METABOXED() then true;
else false;
end match;
end isMetaBoxedType;

public function boxIfUnboxedType
input DAE.Type ty;
output DAE.Type outType;
Expand Down Expand Up @@ -8742,5 +8734,15 @@ algorithm
end match;
end arrayHasUnknownDims;

public function metaArrayElementType
input DAE.Type inType;
output DAE.Type outType;
algorithm
outType := match inType
case DAE.T_METAARRAY() then inType.ty;
case DAE.T_METATYPE() then metaArrayElementType(inType.ty);
end match;
end metaArrayElementType;

annotation(__OpenModelica_Interface="frontend");
end Types;
50 changes: 26 additions & 24 deletions Compiler/Template/CodegenC.tpl
Expand Up @@ -6938,7 +6938,7 @@ template algStmtAssign(DAE.Statement stmt, Context context, Text &varDecls, Text
(match expTypeFromExpShort(exp)
case "metatype" then
// MetaModelica Array
(match exp case ASUB(exp=arr, sub={idx}) then
(match exp1 case ASUB(exp=arr, sub={idx}) then
let &preExp = buffer ""
let arr1 = daeExp(arr, context, &preExp, &varDecls, &auxFunction)
let idx1 = daeExp(idx, context, &preExp, &varDecls, &auxFunction)
Expand Down Expand Up @@ -7858,29 +7858,30 @@ template daeExpCrefRhsFunContext(Exp ecr, Context context, Text &preExp,
let dimsValuesStr = (crefSubs(cr) |> INDEX(__) =>
daeDimensionExp(exp, context, &preExp, &varDecls, &auxFunction)
;separator=", ")
match context
case FUNCTION_CONTEXT(__) then
match ty
case (T_ARRAY(ty = T_COMPLEX(complexClassType = record_state))) then
let rec_name = '<%underscorePath(ClassInf.getStateName(record_state))%>'
<<
(*((<%rec_name%>*)(generic_array_element_addr(&<%arrName%>, sizeof(<%rec_name%>), <%dimsLenStr%>, <%dimsValuesStr%>))))
>>
case (T_COMPLEX(complexClassType = record_state)) then
let rec_name = '<%underscorePath(ClassInf.getStateName(record_state))%>'
<<
(*((<%rec_name%>*)(generic_array_element_addr(&<%arrName%>, sizeof(<%rec_name%>), <%dimsLenStr%>, <%dimsValuesStr%>))))
>>
else
<<
(*<%arrayType%>_element_addr(&<%arrName%>, <%dimsLenStr%>, <%dimsValuesStr%>))
>>
case PARALLEL_FUNCTION_CONTEXT(__) then
<<
(*<%arrayType%>_element_addr_c99_<%dimsLenStr%>(&<%arrName%>, <%dimsLenStr%>, <%dimsValuesStr%>))
>>
match cr
case CREF_IDENT(identType = T_METATYPE(ty = T_METAARRAY()))
case CREF_IDENT(identType = T_METAARRAY()) then
'arrayGet(<%arrName%>, <%dimsValuesStr%>)'
else
error(sourceInfo(),'This should have been handled in the new daeExpCrefRhsSimContext function. <%printExpStr(ecr)%>')
match context
case FUNCTION_CONTEXT(__) then
match ty
case (T_ARRAY(ty = T_COMPLEX(complexClassType = record_state)))
case (T_COMPLEX(complexClassType = record_state)) then
let rec_name = '<%underscorePath(ClassInf.getStateName(record_state))%>'
<<
(*((<%rec_name%>*)(generic_array_element_addr(&<%arrName%>, sizeof(<%rec_name%>), <%dimsLenStr%>, <%dimsValuesStr%>))))
>>
else
<<
(*<%arrayType%>_element_addr(&<%arrName%>, <%dimsLenStr%>, <%dimsValuesStr%>))
>>
case PARALLEL_FUNCTION_CONTEXT(__) then
<<
(*<%arrayType%>_element_addr_c99_<%dimsLenStr%>(&<%arrName%>, <%dimsLenStr%>, <%dimsValuesStr%>))
>>
else
error(sourceInfo(),'This should have been handled in the new daeExpCrefRhsSimContext function. <%printExpStr(ecr)%>')
else
match context
case FUNCTION_CONTEXT(__)
Expand All @@ -7893,7 +7894,8 @@ template daeExpCrefRhsFunContext(Exp ecr, Context context, Text &preExp,
let spec1 = daeExpCrefIndexSpec(crefSubs(cr), context, &preExp, &varDecls, &auxFunction)
let &preExp += 'index_alloc_<%arrayType%>(&<%arrName%>, &<%spec1%>, &<%tmp%>);<%\n%>'
tmp
else error(sourceInfo(),'daeExpCrefRhsFunContext: Slice in simulation context: <%ExpressionDump.printExpStr(ecr)%>')
else
error(sourceInfo(),'daeExpCrefRhsFunContext: Slice in simulation context: <%ExpressionDump.printExpStr(ecr)%>')
case ecr then
error(sourceInfo(),'daeExpCrefRhsFunContext: UNHANDLED EXPRESSION: <%ExpressionDump.printExpStr(ecr)%>')
end daeExpCrefRhsFunContext;
Expand Down

0 comments on commit b35172a

Please sign in to comment.