From 50435f2e4777e32ef49d39e308b0ef6a0733352a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Tue, 21 Dec 2010 13:32:42 +0000 Subject: [PATCH] - Added a generic error message for elabExp (only 1 testcase needed to be updated; no scary floods of failed expressions followed...) - Changed errorext.cpp slightly: Now we remove duplicate errors when pop'ing the stack. - The reason for this change is that if we called Error.addSourceMessage and the top already had a copy of that message, the error count would not increase. This could cause additional generic error messages to appear. git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@7539 f25d12d1-65f4-0310-ae8a-bbce733d8d8e --- Compiler/FrontEnd/Dump.mo | 11 +++- Compiler/FrontEnd/Static.mo | 104 +++++++++++++++++++----------- Compiler/Util/Error.mo | 2 + Compiler/runtime/ErrorMessage.cpp | 23 +++---- Compiler/runtime/ErrorMessage.hpp | 32 +++++---- Compiler/runtime/Makefile.common | 5 +- Compiler/runtime/errorext.cpp | 66 ++++++++----------- 7 files changed, 137 insertions(+), 106 deletions(-) diff --git a/Compiler/FrontEnd/Dump.mo b/Compiler/FrontEnd/Dump.mo index 11b32d6a810..3732cf65a86 100644 --- a/Compiler/FrontEnd/Dump.mo +++ b/Compiler/FrontEnd/Dump.mo @@ -4164,6 +4164,7 @@ algorithm case (Absyn.CALL(function_ = _)) then 0; case (Absyn.PARTEVALFUNCTION(function_= _)) then 0; case (Absyn.ARRAY(arrayExp = _)) then 0; + case (Absyn.LIST(exps = _)) then 0; case (Absyn.MATRIX(matrix = _)) then 0; /* arithmetic operators */ case (Absyn.BINARY(op = Absyn.POW())) then 1; @@ -4408,7 +4409,15 @@ algorithm s_2 = stringAppend(s_1, "}"); then s_2; - + + case Absyn.LIST(exps = es) + equation + s = printListStr(es, printExpStr, ",") "Does not need parentheses" ; + s_1 = stringAppend("{", s); + s_2 = stringAppend(s_1, "}"); + then + s_2; + case Absyn.TUPLE(expressions = es) equation s = printListStr(es, printExpStr, ",") "Does not need parentheses" ; diff --git a/Compiler/FrontEnd/Static.mo b/Compiler/FrontEnd/Static.mo index 8829aeb59c3..2e3254be2f4 100644 --- a/Compiler/FrontEnd/Static.mo +++ b/Compiler/FrontEnd/Static.mo @@ -219,16 +219,40 @@ function: elabExp output DAE.Exp outExp; output DAE.Properties outProperties; output Option outInteractiveInteractiveSymbolTableOption; +algorithm + (outCache,outExp,outProperties,outInteractiveInteractiveSymbolTableOption) := elabExp2(inCache,inEnv,inExp,inBoolean,inInteractiveInteractiveSymbolTableOption,performVectorization,inPrefix,info,Error.getNumErrorMessages()); +end elabExp; + +protected function elabExp2 " +function: elabExp + Static analysis of expressions means finding out the properties of + the expression. These properties are described by the + `DAE.Properties\' type, and include the type and the variability of the + expression. This function performs analysis, and returns an + `DAE.Exp\' and the properties." + input Env.Cache inCache; + input Env.Env inEnv; + input Absyn.Exp inExp; + input Boolean inBoolean; + input Option inInteractiveInteractiveSymbolTableOption; + input Boolean performVectorization; + input Prefix.Prefix inPrefix; + input Absyn.Info info; + input Integer numErrorMessages; + output Env.Cache outCache; + output DAE.Exp outExp; + output DAE.Properties outProperties; + output Option outInteractiveInteractiveSymbolTableOption; algorithm (outCache,outExp,outProperties,outInteractiveInteractiveSymbolTableOption):= - matchcontinue (inCache,inEnv,inExp,inBoolean,inInteractiveInteractiveSymbolTableOption,performVectorization,inPrefix,info) + matchcontinue (inCache,inEnv,inExp,inBoolean,inInteractiveInteractiveSymbolTableOption,performVectorization,inPrefix,info,numErrorMessages) local + Boolean impl,a,b,havereal,doVect,correctTypes; Integer x,l,i,nmax; Real r; + String id,expstr,envstr,str1,str2,s,msg; DAE.Dimension dim1,dim2; - Boolean impl,a,b,havereal,doVect,correctTypes; Option st,st_1,st_2,st_3; - Ident id,expstr,envstr,str1,str2,s; DAE.Exp exp,e1_1,e2_1,e1_2,e2_2,exp_1,exp_2,e_1,e_2,e3_1,start_1,stop_1,start_2,stop_2,step_1,step_2,mexp,mexp_1,arrexp; DAE.Properties prop,prop_1,prop1,prop2,prop3; list env; @@ -276,38 +300,38 @@ algorithm // The types below should contain the default values of the attributes of the builtin // types. But since they are default, we can leave them out for now, unit=\"\" is not // that interesting to find out. - case (cache,_,Absyn.INTEGER(value = i),impl,st,doVect,_,info) + case (cache,_,Absyn.INTEGER(value = i),impl,st,doVect,_,info,_) then (cache,DAE.ICONST(i),DAE.PROP(DAE.T_INTEGER_DEFAULT,DAE.C_CONST()),st); - case (cache,_,Absyn.REAL(value = r),impl,st,doVect,_,info) + case (cache,_,Absyn.REAL(value = r),impl,st,doVect,_,info,_) then (cache,DAE.RCONST(r),DAE.PROP(DAE.T_REAL_DEFAULT,DAE.C_CONST()),st); - case (cache,_,Absyn.STRING(value = s),impl,st,doVect,_,info) + case (cache,_,Absyn.STRING(value = s),impl,st,doVect,_,info,_) then (cache,DAE.SCONST(s),DAE.PROP(DAE.T_STRING_DEFAULT,DAE.C_CONST()),st); - case (cache,_,Absyn.BOOL(value = b),impl,st,doVect,_,info) + case (cache,_,Absyn.BOOL(value = b),impl,st,doVect,_,info,_) then (cache,DAE.BCONST(b),DAE.PROP(DAE.T_BOOL_DEFAULT,DAE.C_CONST()),st); - case (cache,_,Absyn.END(),impl,st,doVect,_,info) + case (cache,_,Absyn.END(),impl,st,doVect,_,info,_) then (cache,DAE.END(),DAE.PROP(DAE.T_INTEGER_DEFAULT,DAE.C_CONST()),st); - case (cache,env,Absyn.CREF(componentRef = cr),impl,st,doVect,pre,info) // BoschRexroth specifics + case (cache,env,Absyn.CREF(componentRef = cr),impl,st,doVect,pre,info,_) // BoschRexroth specifics equation false = OptManager.getOption("cevalEquation"); (cache,SOME((exp,prop as DAE.PROP(ty,DAE.C_PARAM()),_))) = elabCref(cache,env, cr, impl,doVect,pre,info); then (cache,exp,DAE.PROP(ty,DAE.C_VAR()),st); - case (cache,env,Absyn.CREF(componentRef = cr),impl,st,doVect,pre,info) + case (cache,env,Absyn.CREF(componentRef = cr),impl,st,doVect,pre,info,_) equation (cache,SOME((exp,prop,_))) = elabCref(cache,env, cr, impl,doVect,pre,info); then (cache,exp,prop,st); - case (cache,env,(e as Absyn.BINARY(exp1 = e1,op = op,exp2 = e2)),impl,st,doVect,pre,info) /* Binary and unary operations */ + case (cache,env,(e as Absyn.BINARY(exp1 = e1,op = op,exp2 = e2)),impl,st,doVect,pre,info,_) /* Binary and unary operations */ equation (cache,e1_1,DAE.PROP(t1,c1),st_1) = elabExp(cache,env, e1, impl, st,doVect,pre,info); (cache,e2_1,DAE.PROP(t2,c2),st_2) = elabExp(cache,env, e2, impl, st_1,doVect,pre,info); @@ -321,7 +345,7 @@ algorithm then (cache,exp_1,prop,st_2); - case (cache,env,(e as Absyn.UNARY(op = op,exp = e1)),impl,st,doVect,pre,info) + case (cache,env,(e as Absyn.UNARY(op = op,exp = e1)),impl,st,doVect,pre,info,_) equation (cache,e_1,DAE.PROP(t,c),st_1) = elabExp(cache,env,e1,impl,st,doVect,pre,info); (cache,ops) = operators(cache,op, env, t, (DAE.T_NOTYPE(),NONE())); @@ -331,7 +355,7 @@ algorithm prop = DAE.PROP(rtype,c); then (cache,exp_1,prop,st_1); - case (cache,env,(e as Absyn.LBINARY(exp1 = e1,op = op,exp2 = e2)),impl,st,doVect,pre,info) + case (cache,env,(e as Absyn.LBINARY(exp1 = e1,op = op,exp2 = e2)),impl,st,doVect,pre,info,_) equation (cache,e1_1,DAE.PROP(t1,c1),st_1) = elabExp(cache,env, e1, impl, st,doVect,pre,info) "Logical binary expressions" ; (cache,e2_1,DAE.PROP(t2,c2),st_2) = elabExp(cache,env, e2, impl, st_1,doVect,pre,info); @@ -343,7 +367,7 @@ algorithm prop = DAE.PROP(rtype,c); then (cache,exp_1,prop,st_2); - case (cache,env,(e as Absyn.LUNARY(op = op,exp = e1)),impl,st,doVect,pre,info) + case (cache,env,(e as Absyn.LUNARY(op = op,exp = e1)),impl,st,doVect,pre,info,_) equation (cache,e_1,DAE.PROP(t,c),st_1) = elabExp(cache,env,e1,impl,st,doVect,pre,info) "Logical unary expressions" ; (cache,ops) = operators(cache,op, env, t, (DAE.T_NOTYPE(),NONE())); @@ -353,7 +377,7 @@ algorithm prop = DAE.PROP(rtype,c); then (cache,exp_1,prop,st_1); - case (cache,env,(e as Absyn.RELATION(exp1 = e1,op = op,exp2 = e2)),impl,st,doVect,pre,info) + case (cache,env,(e as Absyn.RELATION(exp1 = e1,op = op,exp2 = e2)),impl,st,doVect,pre,info,_) equation (cache,e1_1,DAE.PROP(t1,c1),st_1) = elabExp(cache,env, e1, impl, st,doVect,pre,info) "Relations, e.g. a < b" ; (cache,e2_1,DAE.PROP(t2,c2),st_2) = elabExp(cache,env, e2, impl, st_1,doVect,pre,info); @@ -366,7 +390,7 @@ algorithm warnUnsafeRelations(env,c,t1,t2,e1_2,e2_2,op_1,pre); then (cache,exp_1,prop,st_2); - case (cache,env,e as Absyn.IFEXP(ifExp = _),impl,st,doVect,pre,info) /* Conditional expressions */ + case (cache,env,e as Absyn.IFEXP(ifExp = _),impl,st,doVect,pre,info,_) /* Conditional expressions */ equation Absyn.IFEXP(ifExp = e1,trueBranch = e2,elseBranch = e3) = Absyn.canonIfExp(e); (cache,e1_1,prop1,st_1) = elabExp(cache,env, e1, impl, st,doVect,pre,info) "if expressions" ; @@ -377,7 +401,7 @@ algorithm (cache,e_1,prop,st_3); // adrpo: deal with DynamicSelect(literalExp, dynamicExp) by returning literalExp only! - case (cache,env,Absyn.CALL(function_ = Absyn.CREF_IDENT("DynamicSelect",_),functionArgs = Absyn.FUNCTIONARGS(args = (e1 :: _),argNames = _)),impl,st,doVect,pre,info) + case (cache,env,Absyn.CALL(function_ = Absyn.CREF_IDENT("DynamicSelect",_),functionArgs = Absyn.FUNCTIONARGS(args = (e1 :: _),argNames = _)),impl,st,doVect,pre,info,_) equation (cache,e_1,prop,st_1) = elabExp(cache,env, e1, impl, st, doVect, pre, info); then @@ -385,7 +409,7 @@ algorithm /*--------------------------------*/ /* Part of MetaModelica extension. KS */ - case (cache,env,Absyn.CALL(function_ = Absyn.CREF_IDENT("SOME",_),functionArgs = Absyn.FUNCTIONARGS(args = (e1 :: _),argNames = _)),impl,st,doVect,pre,info) + case (cache,env,Absyn.CALL(function_ = Absyn.CREF_IDENT("SOME",_),functionArgs = Absyn.FUNCTIONARGS(args = (e1 :: _),argNames = _)),impl,st,doVect,pre,info,_) equation true = RTOpts.acceptMetaModelicaGrammar(); (cache,e_1,prop,st_1) = elabExp(cache,env, e1, impl, st,doVect,pre,info); @@ -397,7 +421,7 @@ algorithm then (cache,e_1,prop1,st); - case (cache,env,Absyn.CALL(function_ = Absyn.CREF_IDENT("NONE",_),functionArgs = Absyn.FUNCTIONARGS(args = {},argNames = _)),impl,st,doVect,_,info) + case (cache,env,Absyn.CALL(function_ = Absyn.CREF_IDENT("NONE",_),functionArgs = Absyn.FUNCTIONARGS(args = {},argNames = _)),impl,st,doVect,_,info,_) equation true = RTOpts.acceptMetaModelicaGrammar(); e_1 = DAE.META_OPTION(NONE()); @@ -419,7 +443,7 @@ algorithm /* If fail to elaborate e2 or e3 above check if cond is constant and make non-selected branch undefined. NOTE: Dirty hack to make MSL CombiTable models work!!! */ - case (cache,env,Absyn.IFEXP(ifExp = e1,trueBranch = e2,elseBranch = e3),impl,st,doVect,pre,info) /* Conditional expressions */ + case (cache,env,Absyn.IFEXP(ifExp = e1,trueBranch = e2,elseBranch = e3),impl,st,doVect,pre,info,_) /* Conditional expressions */ equation (cache,e1_1,prop1,st_1) = elabExp(cache,env, e1, impl, st,doVect,pre,info); true = Types.isParameterOrConstant(Types.propAllConst(prop1)); @@ -429,7 +453,7 @@ algorithm /* TODO elseif part */ then (cache,e_1,prop,st_2); - case (cache,env,Absyn.CALL(function_ = fn,functionArgs = Absyn.FUNCTIONARGS(args = args,argNames = nargs)),impl,st,doVect,pre,info) + case (cache,env,Absyn.CALL(function_ = fn,functionArgs = Absyn.FUNCTIONARGS(args = args,argNames = nargs)),impl,st,doVect,pre,info,_) equation Debug.fprintln("sei", "elab_exp CALL...") "Function calls PA. Only positional arguments are elaborated for now. TODO: Implement elaboration of named arguments." ; (cache,e_1,prop,st_1) = elabCall(cache,env, fn, args, nargs, impl, st,pre,info); @@ -439,12 +463,12 @@ algorithm then (cache,e_1,prop,st_1); // stefan - case (cache,env,e1 as Absyn.PARTEVALFUNCTION(function_ = _),impl,st,doVect,pre,info) + case (cache,env,e1 as Absyn.PARTEVALFUNCTION(function_ = _),impl,st,doVect,pre,info,_) equation (cache,e1_1,prop,st_1) = elabPartEvalFunction(cache,env,e1,st,impl,doVect,pre,info); then (cache,e1_1,prop,st_1); - case (cache,env,Absyn.TUPLE(expressions = es),impl,st,doVect,pre,info) /* PR. Get the properties for each expression in the tuple. + case (cache,env,Absyn.TUPLE(expressions = es),impl,st,doVect,pre,info,_) /* PR. Get the properties for each expression in the tuple. Each expression has its own constflag. */ equation @@ -452,7 +476,7 @@ algorithm (types,consts) = splitProps(props); then (cache,DAE.TUPLE(es_1),DAE.PROP_TUPLE((DAE.T_TUPLE(types),NONE()),DAE.TUPLE_CONST(consts)),st); - case (cache,env,Absyn.CALL(function_ = fn,functionArgs = Absyn.FOR_ITER_FARG(exp = e, iterators=iterators)),impl,st,doVect,pre,info) /* Array-related expressions Elab reduction expressions, including array() constructor */ + case (cache,env,Absyn.CALL(function_ = fn,functionArgs = Absyn.FOR_ITER_FARG(exp = e, iterators=iterators)),impl,st,doVect,pre,info,_) /* Array-related expressions Elab reduction expressions, including array() constructor */ equation (cache,e_1,prop,st_1) = elabCallReduction(cache,env, fn, e, iterators, impl, st,doVect,pre,info); c = Types.propAllConst(prop); @@ -460,20 +484,20 @@ algorithm then (cache,e_1,prop,st_1); - case (cache, env, Absyn.RANGE(start = _), impl, st, doVect, pre, info) + case (cache, env, Absyn.RANGE(start = _), impl, st, doVect, pre, info, _) equation (cache, e_1, prop, st_1) = elabRange(cache, env, inExp, impl, st, doVect, pre, info); then (cache, e_1, prop, st_1); // Part of the MetaModelica extension. This eliminates elab_array failed failtraces when using the empty list. sjoelund - case (cache,env,Absyn.ARRAY({}),impl,st,doVect,pre,info) + case (cache,env,Absyn.ARRAY({}),impl,st,doVect,pre,info,_) equation true = RTOpts.acceptMetaModelicaGrammar(); (cache,exp,prop,st) = elabExp(cache,env,Absyn.LIST({}),impl,st,doVect,pre,info); then (cache,exp,prop,st); - case (cache,env,Absyn.ARRAY(arrayExp = es),impl,st,doVect,pre,info) + case (cache,env,Absyn.ARRAY(arrayExp = es),impl,st,doVect,pre,info,_) equation (cache,es_1,DAE.PROP(t,const)) = elabArray(cache,env, es, impl, st,doVect,pre,info) "array expressions, e.g. {1,2,3}" ; l = listLength(es_1); @@ -487,7 +511,7 @@ algorithm then (cache,arrexp,DAE.PROP(arrtp,const),st); - case (cache,env,Absyn.MATRIX(matrix = ess),impl,st,doVect,pre,info) + case (cache,env,Absyn.MATRIX(matrix = ess),impl,st,doVect,pre,info,_) equation (cache,_,tps,_) = elabExpListList(cache, env, ess, impl, st,doVect,pre,info) "matrix expressions, e.g. {1,0;0,1} with elements of simple type." ; tps_1 = Util.listListMap(tps, Types.getPropType); @@ -503,7 +527,7 @@ algorithm t_2 = Types.unliftArray(t_1) "All elts promoted to matrix, therefore unlifting" ; then (cache,mexp_1,DAE.PROP((DAE.T_ARRAY(dim1,(DAE.T_ARRAY(dim2,t_2),NONE())),NONE()),c),st); - case (cache,env,Absyn.CODE(code = cn),impl,st,doVect,_,info) + case (cache,env,Absyn.CODE(code = cn),impl,st,doVect,_,info,_) equation tp = elabCodeType(env, cn) "Code expressions" ; tp_1 = Types.elabType(tp); @@ -512,13 +536,13 @@ algorithm //------------------------------------- // Part of the MetaModelica extension. KS - case (cache,env,Absyn.ARRAY(es),impl,st,doVect,pre,info) + case (cache,env,Absyn.ARRAY(es),impl,st,doVect,pre,info,_) equation true = RTOpts.acceptMetaModelicaGrammar(); (cache,exp,prop,st) = elabExp(cache,env,Absyn.LIST(es),impl,st,doVect,pre,info); then (cache,exp,prop,st); - case (cache,env,Absyn.CONS(e1,e2),impl,st,doVect,pre,info) + case (cache,env,Absyn.CONS(e1,e2),impl,st,doVect,pre,info,_) equation {e1,e2} = MetaUtil.transformArrayNodesToListNodes({e1,e2},{}); @@ -541,7 +565,7 @@ algorithm prop = DAE.PROP((DAE.T_LIST(t),NONE()),c); then (cache,exp,prop,st); - case (cache,env,e as Absyn.CONS(e1,e2),impl,st,doVect,pre,info) + case (cache,env,e as Absyn.CONS(e1,e2),impl,st,doVect,pre,info,_) equation {e1,e2} = MetaUtil.transformArrayNodesToListNodes({e1,e2},{}); (cache,e1_1,prop1,st_1) = elabExp(cache,env, e1, impl, st,doVect,pre,info); @@ -554,13 +578,13 @@ algorithm // The Absyn.LIST() node is used for list expressions that are // transformed from Absyn.ARRAY() - case (cache,env,Absyn.LIST({}),impl,st,doVect,_,info) + case (cache,env,Absyn.LIST({}),impl,st,doVect,_,info,_) equation t = (DAE.T_LIST((DAE.T_NOTYPE(),NONE())),NONE()); prop = DAE.PROP(t,DAE.C_CONST()); then (cache,DAE.LIST(DAE.ET_LIST(DAE.ET_OTHER()),{}),prop,st); - case (cache,env,Absyn.LIST(es),impl,st,doVect,pre,info) + case (cache,env,Absyn.LIST(es),impl,st,doVect,pre,info,_) equation (cache,es_1,propList,st_2) = elabExpList(cache,env, es, impl, st,doVect,pre,info); typeList = Util.listMap(propList, Types.getPropType); @@ -573,13 +597,16 @@ algorithm // ---------------------------------- // Pattern matching has its own module that handles match expressions - case (cache,env,e as Absyn.MATCHEXP(matchTy = _),impl,st,doVect,pre,info) + case (cache,env,e as Absyn.MATCHEXP(matchTy = _),impl,st,doVect,pre,info,numErrorMessages) equation - (cache,exp,prop,st) = Patternm.elabMatchExpression(cache,env,e,impl,st,doVect,pre,info,Error.getNumErrorMessages()); + (cache,exp,prop,st) = Patternm.elabMatchExpression(cache,env,e,impl,st,doVect,pre,info,numErrorMessages); then (cache,exp,prop,st); - case (cache,env,e,_,_,_,pre,info) + case (cache,env,e,_,_,_,pre,info,numErrorMessages) equation + true = numErrorMessages == Error.getNumErrorMessages(); + msg = Dump.printExpStr(e); + Error.addSourceMessage(Error.GENERIC_ELAB_EXPRESSION,{msg},info); /* FAILTRACE REMOVE true = RTOpts.debugFlag("failtrace"); Debug.fprint("failtrace", "- Static.elabExp failed: "); @@ -595,8 +622,7 @@ algorithm then fail(); end matchcontinue; -end elabExp; - +end elabExp2; // Part of MetaModelica extension public function elabListExp "function: elabListExp diff --git a/Compiler/Util/Error.mo b/Compiler/Util/Error.mo index bc55f08dee3..ee7d82cef72 100644 --- a/Compiler/Util/Error.mo +++ b/Compiler/Util/Error.mo @@ -243,6 +243,7 @@ public constant ErrorID FUNCTION_ELEMENT_WRONG_KIND=155; public constant ErrorID WITHOUT_SENDDATA=156 "Used in external C sources; do not use another index"; public constant ErrorID DUPLICATE_CLASSES_TOP_LEVEL=157; public constant ErrorID WHEN_EQ_LHS=158; +public constant ErrorID GENERIC_ELAB_EXPRESSION=159; public constant ErrorID UNBOUND_PARAMETER_WITH_START_VALUE_WARNING=499; public constant ErrorID UNBOUND_PARAMETER_WARNING=500; @@ -675,6 +676,7 @@ protected constant list> errorTabl (FUNCTION_ELEMENT_WRONG_KIND,TRANSLATION(),ERROR(),"Element is not allowed in function context: %s"), (WITHOUT_SENDDATA,SCRIPTING(),ERROR(),"%s failed because OpenModelica was configured without sendData support."), (WHEN_EQ_LHS,TRANSLATION(),ERROR(),"Invalid left-hand side of when-equation: %s."), + (GENERIC_ELAB_EXPRESSION,TRANSLATION(),ERROR(),"Failed to elaborate expression: %s"), (COMPILER_WARNING,TRANSLATION(),WARNING(),"%s") }; diff --git a/Compiler/runtime/ErrorMessage.cpp b/Compiler/runtime/ErrorMessage.cpp index e876cb42f64..ab1cc655ae1 100644 --- a/Compiler/runtime/ErrorMessage.cpp +++ b/Compiler/runtime/ErrorMessage.cpp @@ -56,6 +56,8 @@ endColumnNo_ = 0; isReadOnly_ = false; filename_ = std::string(""); + shortMessage = getMessage_(); + fullMessage = getFullMessage_(); } ErrorMessage::ErrorMessage(long errorID, @@ -82,21 +84,22 @@ ErrorMessage::ErrorMessage(long errorID, message_(message), tokens_(tokens) { + shortMessage = getMessage_(); + fullMessage = getFullMessage_(); } /* * adrpo, 2006-02-05 changed position handling */ -std::string ErrorMessage::getMessage() +std::string ErrorMessage::getMessage_() { - std::string fullMessage = message_; std::list::iterator tok; std::string::size_type str_pos; for (tok=tokens_.begin(); tok != tokens_.end(); tok++) { - str_pos=fullMessage.find("%s"); - if (str_pos < fullMessage.size()) + str_pos=message_.find("%s"); + if (str_pos < message_.size()) { - fullMessage.replace(str_pos,2,*tok); + message_.replace(str_pos,2,*tok); } else { @@ -110,21 +113,19 @@ std::string ErrorMessage::getMessage() if (filename_ == "" && startLineNo_ == 0 && startColumnNo_ == 0 && endLineNo_ == 0 && endColumnNo_ == 0 /*&& isReadOnly_ == false*/) { - return severity_+": "+fullMessage; + return severity_+": "+message_; } else { - return positionInfo + fullMessage; + return positionInfo + message_; } } -std::string ErrorMessage::getFullMessage() +std::string ErrorMessage::getFullMessage_() { - std::string message_text= getMessage(); - std::stringstream strbuf; - strbuf << "{\"" << message_text << "\", \"" << + strbuf << "{\"" << shortMessage << "\", \"" << messageType_ << "\", \"" << severity_ << "\", \"" << errorID_ << "\"}"; diff --git a/Compiler/runtime/ErrorMessage.hpp b/Compiler/runtime/ErrorMessage.hpp index 3dedfb58d89..a625139e0ab 100644 --- a/Compiler/runtime/ErrorMessage.hpp +++ b/Compiler/runtime/ErrorMessage.hpp @@ -55,33 +55,36 @@ class ErrorMessage { bool isReadOnly, std::string filename); - long getID() { return errorID_; }; + long getID() const { return errorID_; }; - std::string getType() { return messageType_; }; + std::string getType() const { return messageType_; }; - std::string getSeverity() { return severity_; }; + std::string getSeverity() const { return severity_; }; // Returns the expanded message with inserted tokens. - std::string getMessage(); + std::string getMessage() const {return shortMessage;}; // Returns the complete message in string format corresponding to a Modeica vector. - std::string getFullMessage(); + std::string getFullMessage() const {return fullMessage;}; - long getLineNo() { return startLineNo_; }; - long getColumnNo() { return startColumnNo_; }; + long getLineNo() const { return startLineNo_; }; + long getColumnNo() const { return startColumnNo_; }; /* adrpo added these new ones */ - long getStartLineNo() { return startLineNo_; }; - long getStartColumnNo() { return startColumnNo_; }; - long getEndLineNo() { return endLineNo_; }; - long getEndColumnNo() { return endColumnNo_; }; - bool getIsFileReadOnly() { return isReadOnly_; }; - std::string getFileName() { return filename_; }; + long getStartLineNo() const { return startLineNo_; }; + long getStartColumnNo() const { return startColumnNo_; }; + long getEndLineNo() const { return endLineNo_; }; + long getEndColumnNo() const { return endColumnNo_; }; + bool getIsFileReadOnly() const { return isReadOnly_; }; + std::string getFileName() const { return filename_; }; + std::list getTokens() const { return tokens_; }; private: long errorID_; std::string messageType_; std::string severity_; std::string message_; std::list tokens_; + std::string shortMessage; + std::string fullMessage; /* adrpo 2006-02-05 changed the ones below */ long startLineNo_; @@ -91,6 +94,9 @@ class ErrorMessage { bool isReadOnly_; std::string filename_; + std::string getMessage_(); + std::string getFullMessage_(); + }; diff --git a/Compiler/runtime/Makefile.common b/Compiler/runtime/Makefile.common index ee4b64c6877..afa66235b6c 100644 --- a/Compiler/runtime/Makefile.common +++ b/Compiler/runtime/Makefile.common @@ -54,8 +54,8 @@ Dynload_rml.o: systemimpl.h errorext.h rtopts.h ../Absyn.h ../Values.h ../../c_r Dynload_omc.o: systemimpl.h errorext.h rtopts.h ../OpenModelicaBootstrappingHeader.h ../../c_runtime/read_write.h ../../c_runtime/memory_pool.h Dynload.cpp Print_rml.o : printimpl.c Print_omc.o : printimpl.c -Error_rml.o : errorext.cpp -Error_omc.o : errorext.cpp +Error_rml.o : errorext.cpp ErrorMessage.hpp +Error_omc.o : errorext.cpp ErrorMessage.hpp System_rml.o : systemimpl.c config.h $(configUnix) System_omc.o : systemimpl.c config.h $(configUnix) RTOpts_rml.o : rtoptsimpl.c @@ -74,6 +74,7 @@ Socket_rml.o : socketimpl.c Socket_omc.o : socketimpl.c ptolemyio_rml.o : ptolemyio.cpp ptolemyio_omc.o : ptolemyio.cpp +ErrorMessage.o : ErrorMessage.cpp ErrorMessage.hpp clean: $(RM) -rf *.a *.o omc_communication.cc omc_communication.h omc_communication-* sqlite/*.o diff --git a/Compiler/runtime/errorext.cpp b/Compiler/runtime/errorext.cpp index c6ebd984002..cacc3926bd3 100644 --- a/Compiler/runtime/errorext.cpp +++ b/Compiler/runtime/errorext.cpp @@ -51,6 +51,7 @@ struct absyn_info{ }; // if error_on is true, message is added, otherwise not. static bool error_on=true; +static int numErrorMessages=0; #include "ErrorMessage.hpp" static std::string currVariable(""); @@ -66,6 +67,19 @@ static void push_message(ErrorMessage *msg) std::cerr << msg->getFullMessage() << std::endl; else errorMessageQueue.push(msg); + if (msg->getSeverity().compare(std::string("Error")) == 0) numErrorMessages++; +} + +/* pop the top of the message stack (and any duplicate messages that have also been added) */ +static void pop_message() +{ + ErrorMessage *msg = errorMessageQueue.top(); + if (msg->getSeverity().compare(std::string("Error")) == 0) numErrorMessages--; + errorMessageQueue.pop(); + int pop_more = errorMessageQueue.size() > 0 && msg->getFullMessage() == errorMessageQueue.top()->getFullMessage(); + delete msg; + if (pop_more) + pop_message(); } /* Adds a message without file info. */ @@ -82,22 +96,10 @@ extern void add_message(int errorID, else { tmp=message; } - if(!haveInfo) { - ErrorMessage *msg = new ErrorMessage((long)errorID, std::string(type ), std::string(severity), /*std::string(message),*/ tmp, tokens); - if (errorMessageQueue.empty() || (!errorMessageQueue.empty() && errorMessageQueue.top()->getFullMessage() != msg->getFullMessage())) { - // std::cerr << "inserting error message "<< msg->getFullMessage() << " on variable "<< currVariable << std::endl; fflush(stderr); - push_message(msg); - } - } else { - ErrorMessage *msg = new ErrorMessage((long)errorID, std::string(type ), std::string(severity), /*std::string(message),*/ tmp, tokens, - finfo.rs,finfo.cs,finfo.re,finfo.ce,finfo.wr/*not important?*/,finfo.fn); - - if (errorMessageQueue.empty() || (!errorMessageQueue.empty() && errorMessageQueue.top()->getFullMessage() != msg->getFullMessage())) { - // std::cerr << "inserting error message "<< msg->getFullMessage() << " on variable "<< currVariable << std::endl; - // std::cerr << "values: " << finfo.rs << " " << finfo.ce << std::endl; fflush(stderr); - push_message(msg); - } - } + ErrorMessage *msg = haveInfo ? + new ErrorMessage((long)errorID, std::string(type ), std::string(severity), tmp, tokens, finfo.rs,finfo.cs,finfo.re,finfo.ce,finfo.wr,finfo.fn) : + new ErrorMessage((long)errorID, std::string(type ), std::string(severity), tmp, tokens); + push_message(msg); } /* Adds a message with file information */ @@ -124,10 +126,7 @@ void add_source_message(int errorID, (long)endCol, isReadOnly, std::string(filename)); - if (errorMessageQueue.empty() || (!errorMessageQueue.empty() && errorMessageQueue.top()->getFullMessage() != msg->getFullMessage())) { - // std::cerr << "inserting error message "<< msg->getFullMessage() << std::endl; fflush(stderr); - push_message(msg); - } + push_message(msg); } extern "C" @@ -163,8 +162,7 @@ static void printCheckpointStack(void) printf("%5d %s message:", i, cp.second.c_str()); while(errorMessageQueue.size() > cp.first && errorMessageQueue.size() > 0){ res = errorMessageQueue.top()->getMessage()+string(" ")+res; - delete errorMessageQueue.top(); - errorMessageQueue.pop(); + pop_message(); } printf("%s\n", res.c_str()); } @@ -217,7 +215,7 @@ extern void ErrorImpl__rollBack(const char* id) res = res+errorMessageQueue.top()->getMessage()+string("\n"); printf( (string("Deleted: ") + res).c_str()); }*/ - errorMessageQueue.pop(); + pop_message(); } /*if(!errorMessageQueue.empty()){ res = res+errorMessageQueue.top()->getMessage()+string("\n"); @@ -246,8 +244,7 @@ extern char* ErrorImpl__rollBackAndPrint(const char* id) if(checkPoints.size() > 0){ while(errorMessageQueue.size() > checkPoints.back().first && errorMessageQueue.size() > 0){ res = errorMessageQueue.top()->getMessage()+string("\n")+res; - delete errorMessageQueue.top(); - errorMessageQueue.pop(); + pop_message(); } pair cp; cp = checkPoints[checkPoints.size()-1]; @@ -318,22 +315,13 @@ extern void c_add_source_message(int errorID, const char* type, const char* seve } extern int ErrorImpl__getNumErrorMessages() { - int res=0; - stack queueCopy(errorMessageQueue); - while (!queueCopy.empty()) { - if (queueCopy.top()->getSeverity().compare(std::string("Error")) == 0) { - res++; - } - queueCopy.pop(); - } - return res; + return numErrorMessages; } extern void ErrorImpl__clearMessages() { while(!errorMessageQueue.empty()) { - delete errorMessageQueue.top(); - errorMessageQueue.pop(); + pop_message(); } } @@ -343,8 +331,7 @@ extern std::string ErrorImpl__getMessagesStr() std::string res("}"); while(!errorMessageQueue.empty()) { res = errorMessageQueue.top()->getFullMessage() + res; - delete errorMessageQueue.top(); - errorMessageQueue.pop(); + pop_message(); if (!errorMessageQueue.empty()) { res = string(",") + res; } } res = string("{") + res; @@ -357,8 +344,7 @@ extern std::string ErrorImpl__printMessagesStr() std::string res(""); while(!errorMessageQueue.empty()) { res = errorMessageQueue.top()->getMessage()+string("\n")+res; - delete errorMessageQueue.top(); - errorMessageQueue.pop(); + pop_message(); } return res; }