1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
21 #include <astexpression.hxx>
22 #include <astconstant.hxx>
23 #include <astscope.hxx>
24 #include <errorhandler.hxx>
25 
26 #include <o3tl/float_int_conversion.hxx>
27 #include <osl/diagnose.h>
28 
29 #include <limits.h>
30 #include <float.h>
31 #include <memory>
32 
AstExpression(ExprComb c,AstExpression * pExpr1,AstExpression * pExpr2)33 AstExpression::AstExpression(ExprComb c, AstExpression *pExpr1, AstExpression *pExpr2)
34     : m_combOperator(c)
35     , m_subExpr1(pExpr1)
36     , m_subExpr2(pExpr2)
37 {
38 }
39 
AstExpression(sal_Int32 l)40 AstExpression::AstExpression(sal_Int32 l)
41     : m_combOperator(ExprComb::NONE)
42 {
43     m_exprValue.reset( new AstExprValue );
44     m_exprValue->et = ET_long;
45     m_exprValue->u.lval = l;
46 }
47 
AstExpression(sal_Int32 l,ExprType et)48 AstExpression::AstExpression(sal_Int32  l, ExprType et)
49     : m_combOperator(ExprComb::NONE)
50 {
51     m_exprValue.reset( new AstExprValue );
52     m_exprValue->et = et;
53     m_exprValue->u.lval = l;
54 }
55 
AstExpression(sal_Int64 h)56 AstExpression::AstExpression(sal_Int64  h)
57     : m_combOperator(ExprComb::NONE)
58 {
59     m_exprValue.reset( new AstExprValue );
60     m_exprValue->et = ET_hyper;
61     m_exprValue->u.hval = h;
62 }
63 
AstExpression(sal_uInt64 uh)64 AstExpression::AstExpression(sal_uInt64 uh)
65     : m_combOperator(ExprComb::NONE)
66 {
67     m_exprValue.reset( new AstExprValue );
68     m_exprValue->et = ET_uhyper;
69     m_exprValue->u.uhval = uh;
70 }
71 
AstExpression(double d)72 AstExpression::AstExpression(double d)
73     : m_combOperator(ExprComb::NONE)
74 {
75     m_exprValue.reset( new AstExprValue );
76     m_exprValue->et = ET_double;
77     m_exprValue->u.dval = d;
78 }
79 
AstExpression(OString * scopedName)80 AstExpression::AstExpression(OString* scopedName)
81     : m_combOperator(ExprComb::Symbol)
82 {
83     if (scopedName)
84         m_xSymbolicName = *scopedName;
85 }
86 
~AstExpression()87 AstExpression::~AstExpression()
88 {
89 }
90 
91 /*
92  * Perform the coercion from the given AstExprValue to the requested
93  * ExprType. Return an AstExprValue if successful, NULL if failed.
94  * must be done for hyper, uhyper
95  */
96 static bool
coerce_value(AstExprValue * ev,ExprType t)97 coerce_value(AstExprValue *ev, ExprType t)
98 {
99     if (ev == nullptr)
100         return false;
101 
102     switch (t)
103     {
104         case ET_short:
105             switch (ev->et)
106             {
107                 case ET_short:
108                     return true;
109                 case ET_ushort:
110                 {
111                     if (ev->u.usval > SAL_MAX_INT16)
112                         return false;
113                     auto tmp = static_cast<sal_Int16>(ev->u.usval);
114                     ev->u.sval = tmp;
115                     ev->et = ET_short;
116                     return true;
117                 }
118                 case ET_long:
119                 {
120                     if (ev->u.lval < SAL_MIN_INT16 || ev->u.lval > SAL_MAX_INT16)
121                         return false;
122                     auto tmp = static_cast<sal_Int16>(ev->u.lval);
123                     ev->u.sval = tmp;
124                     ev->et = ET_short;
125                     return true;
126                 }
127                 case ET_ulong:
128                 {
129                     if (ev->u.ulval > SAL_MAX_INT16)
130                         return false;
131                     auto tmp = static_cast<sal_Int16>(ev->u.ulval);
132                     ev->u.sval = tmp;
133                     ev->et = ET_short;
134                     return true;
135                 }
136                 case ET_hyper:
137                 {
138                     if (ev->u.hval < SAL_MIN_INT16 || ev->u.hval > SAL_MAX_INT16)
139                         return false;
140                     auto tmp = static_cast<sal_Int16>(ev->u.hval);
141                     ev->u.sval = tmp;
142                     ev->et = ET_short;
143                     return true;
144                 }
145                 case ET_uhyper:
146                 {
147                     if (ev->u.uhval > SAL_MAX_INT16)
148                         return false;
149                     auto tmp = static_cast<sal_Int16>(ev->u.uhval);
150                     ev->u.sval = tmp;
151                     ev->et = ET_short;
152                     return true;
153                 }
154                 case ET_boolean:
155                 {
156                     auto tmp = static_cast<sal_Int16>(ev->u.bval);
157                     ev->u.sval = tmp;
158                     ev->et = ET_short;
159                     return true;
160                 }
161                 case ET_float:
162                 {
163                     if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.fval), SAL_MIN_INT16)
164                           && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_INT16)))
165                     {
166                         return false;
167                     }
168                     auto tmp = static_cast<sal_Int16>(ev->u.fval);
169                     ev->u.sval = tmp;
170                     ev->et = ET_short;
171                     return true;
172                 }
173                 case ET_double:
174                 {
175                     if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.dval), SAL_MIN_INT16)
176                           && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_INT16)))
177                     {
178                         return false;
179                     }
180                     auto tmp = static_cast<sal_Int16>(ev->u.dval);
181                     ev->u.sval = tmp;
182                     ev->et = ET_short;
183                     return true;
184                 }
185                 case ET_byte:
186                 {
187                     auto tmp = static_cast<sal_Int16>(ev->u.byval);
188                     ev->u.sval = tmp;
189                     ev->et = ET_short;
190                     return true;
191                 }
192                 default:
193                     OSL_ASSERT(false);
194                     return false;
195             }
196         case ET_ushort:
197             switch (ev->et)
198             {
199                 case ET_short:
200                 {
201                     if (ev->u.sval < 0)
202                         return false;
203                     auto tmp = static_cast<sal_uInt16>(ev->u.sval);
204                     ev->u.usval = tmp;
205                     ev->et = ET_ushort;
206                     return true;
207                 }
208                 case ET_ushort:
209                     return true;
210                 case ET_long:
211                 {
212                     if (ev->u.lval < 0 || ev->u.lval > SAL_MAX_UINT16)
213                         return false;
214                     auto tmp = static_cast<sal_uInt16>(ev->u.lval);
215                     ev->u.usval = tmp;
216                     ev->et = ET_ushort;
217                     return true;
218                 }
219                 case ET_ulong:
220                 {
221                     if (ev->u.ulval > SAL_MAX_UINT16)
222                         return false;
223                     auto tmp = static_cast<sal_uInt16>(ev->u.ulval);
224                     ev->u.usval = tmp;
225                     ev->et = ET_ushort;
226                     return true;
227                 }
228                 case ET_hyper:
229                 {
230                     if (ev->u.hval < 0 || ev->u.hval > SAL_MAX_UINT16)
231                         return false;
232                     auto tmp = static_cast<sal_uInt16>(ev->u.hval);
233                     ev->u.usval = tmp;
234                     ev->et = ET_ushort;
235                     return true;
236                 }
237                 case ET_uhyper:
238                 {
239                     if (ev->u.uhval > SAL_MAX_UINT16)
240                         return false;
241                     auto tmp = static_cast<sal_uInt16>(ev->u.uhval);
242                     ev->u.usval = tmp;
243                     ev->et = ET_ushort;
244                     return true;
245                 }
246                 case ET_boolean:
247                 {
248                     auto tmp = static_cast<sal_uInt16>(ev->u.bval);
249                     ev->u.usval = tmp;
250                     ev->et = ET_short;
251                     return true;
252                 }
253                 case ET_float:
254                 {
255                     if (ev->u.fval < 0.0
256                         || !o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_UINT16))
257                     {
258                         return false;
259                     }
260                     auto tmp = static_cast<sal_uInt16>(ev->u.fval);
261                     ev->u.usval = tmp;
262                     ev->et = ET_short;
263                     return true;
264                 }
265                 case ET_double:
266                 {
267                     if (ev->u.dval < 0.0
268                         || !o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_UINT16))
269                     {
270                         return false;
271                     }
272                     auto tmp = static_cast<sal_uInt16>(ev->u.dval);
273                     ev->u.usval = tmp;
274                     ev->et = ET_short;
275                     return true;
276                 }
277                 case ET_byte:
278                 {
279                     auto tmp = static_cast<sal_uInt16>(ev->u.byval);
280                     ev->u.usval = tmp;
281                     ev->et = ET_ushort;
282                     return true;
283                 }
284                 default:
285                     OSL_ASSERT(false);
286                     return false;
287             }
288         case ET_long:
289             switch (ev->et)
290             {
291                 case ET_short:
292                 {
293                     auto tmp = static_cast<sal_Int32>(ev->u.sval);
294                     ev->u.lval = tmp;
295                     ev->et = ET_long;
296                     return true;
297                 }
298                 case ET_ushort:
299                 {
300                     auto tmp = static_cast<sal_Int32>(ev->u.usval);
301                     ev->u.lval = tmp;
302                     ev->et = ET_long;
303                     return true;
304                 }
305                 case ET_long:
306                     return true;
307                 case ET_ulong:
308                 {
309                     if (ev->u.ulval > SAL_MAX_INT32)
310                         return false;
311                     auto tmp = static_cast<sal_Int32>(ev->u.ulval);
312                     ev->u.lval = tmp;
313                     ev->et = ET_long;
314                     return true;
315                 }
316                 case ET_hyper:
317                 {
318                     if (ev->u.hval < SAL_MIN_INT32 || ev->u.hval > SAL_MAX_INT32)
319                         return false;
320                     auto tmp = static_cast<sal_Int32>(ev->u.hval);
321                     ev->u.lval = tmp;
322                     ev->et = ET_long;
323                     return true;
324                 }
325                 case ET_uhyper:
326                 {
327                     if (ev->u.uhval > SAL_MAX_INT32)
328                         return false;
329                     auto tmp = static_cast<sal_Int32>(ev->u.uhval);
330                     ev->u.lval = tmp;
331                     ev->et = ET_long;
332                     return true;
333                 }
334                 case ET_boolean:
335                 {
336                     auto tmp = static_cast<sal_Int32>(ev->u.bval);
337                     ev->u.lval = tmp;
338                     ev->et = ET_long;
339                     return true;
340                 }
341                 case ET_float:
342                 {
343                     if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.fval), SAL_MIN_INT32)
344                           && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_INT32)))
345                     {
346                         return false;
347                     }
348                     auto tmp = static_cast<sal_Int32>(ev->u.fval);
349                     ev->u.lval = tmp;
350                     ev->et = ET_long;
351                     return true;
352                 }
353                 case ET_double:
354                 {
355                     if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.dval), SAL_MIN_INT32)
356                           && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_INT32)))
357                     {
358                         return false;
359                     }
360                     auto tmp = static_cast<sal_Int32>(ev->u.dval);
361                     ev->u.lval = tmp;
362                     ev->et = ET_long;
363                     return true;
364                 }
365                 case ET_byte:
366                 {
367                     auto tmp = static_cast<sal_Int32>(ev->u.byval);
368                     ev->u.lval = tmp;
369                     ev->et = ET_long;
370                     return true;
371                 }
372                 default:
373                     OSL_ASSERT(false);
374                     return false;
375             }
376         case ET_ulong:
377             switch (ev->et)
378             {
379                 case ET_short:
380                 {
381                     if (ev->u.sval < 0)
382                         return false;
383                     auto tmp = static_cast<sal_uInt32>(ev->u.sval);
384                     ev->u.ulval = tmp;
385                     ev->et = ET_ulong;
386                     return true;
387                 }
388                 case ET_ushort:
389                 {
390                     auto tmp = static_cast<sal_uInt32>(ev->u.usval);
391                     ev->u.ulval = tmp;
392                     ev->et = ET_ulong;
393                     return true;
394                 }
395                 case ET_long:
396                 {
397                     if (ev->u.lval < 0)
398                         return false;
399                     auto tmp = static_cast<sal_uInt32>(ev->u.lval);
400                     ev->u.ulval = tmp;
401                     ev->et = ET_ulong;
402                     return true;
403                 }
404                 case ET_ulong:
405                     return true;
406                 case ET_hyper:
407                 {
408                     if (ev->u.hval < 0 || ev->u.hval > SAL_MAX_UINT32)
409                         return false;
410                     auto tmp = static_cast<sal_uInt32>(ev->u.hval);
411                     ev->u.lval = tmp;
412                     ev->et = ET_ulong;
413                     return true;
414                 }
415                 case ET_uhyper:
416                 {
417                     if (ev->u.uhval > SAL_MAX_UINT32)
418                         return false;
419                     auto tmp = static_cast<sal_uInt32>(ev->u.uhval);
420                     ev->u.ulval = tmp;
421                     ev->et = ET_ulong;
422                     return true;
423                 }
424                 case ET_boolean:
425                 {
426                     auto tmp = static_cast<sal_uInt32>(ev->u.bval);
427                     ev->u.ulval = tmp;
428                     ev->et = ET_ulong;
429                     return true;
430                 }
431                 case ET_float:
432                 {
433                     if (ev->u.fval < 0.0
434                         || !o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_UINT32))
435                     {
436                         return false;
437                     }
438                     auto tmp = static_cast<sal_uInt32>(ev->u.fval);
439                     ev->u.ulval = tmp;
440                     ev->et = ET_ulong;
441                     return true;
442                 }
443                 case ET_double:
444                 {
445                     if (ev->u.dval < 0.0
446                         || !o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_UINT32))
447                     {
448                         return false;
449                     }
450                     auto tmp = static_cast<sal_uInt32>(ev->u.dval);
451                     ev->u.ulval = tmp;
452                     ev->et = ET_ulong;
453                     return true;
454                 }
455                 case ET_byte:
456                 {
457                     auto tmp = static_cast<sal_uInt32>(ev->u.byval);
458                     ev->u.ulval = tmp;
459                     ev->et = ET_ulong;
460                     return true;
461                 }
462                 default:
463                     OSL_ASSERT(false);
464                     return false;
465             }
466         case ET_hyper:
467             switch (ev->et)
468             {
469                 case ET_short:
470                 {
471                     auto tmp = static_cast<sal_Int64>(ev->u.sval);
472                     ev->u.hval = tmp;
473                     ev->et = ET_hyper;
474                     return true;
475                 }
476                 case ET_ushort:
477                 {
478                     auto tmp = static_cast<sal_Int64>(ev->u.usval);
479                     ev->u.hval = tmp;
480                     ev->et = ET_hyper;
481                     return true;
482                 }
483                 case ET_long:
484                 {
485                     auto tmp = static_cast<sal_Int64>(ev->u.lval);
486                     ev->u.hval = tmp;
487                     ev->et = ET_hyper;
488                     return true;
489                 }
490                 case ET_ulong:
491                 {
492                     auto tmp = static_cast<sal_Int64>(ev->u.ulval);
493                     ev->u.hval = tmp;
494                     ev->et = ET_hyper;
495                     return true;
496                 }
497                 case ET_hyper:
498                     return true;
499                 case ET_uhyper:
500                 {
501                     if (ev->u.uhval > SAL_MAX_INT64)
502                         return false;
503                     auto tmp = static_cast<sal_Int64>(ev->u.uhval);
504                     ev->u.hval = tmp;
505                     ev->et = ET_long;
506                     return true;
507                 }
508                 case ET_boolean:
509                 {
510                     auto tmp = static_cast<sal_Int64>(ev->u.bval);
511                     ev->u.hval = tmp;
512                     ev->et = ET_hyper;
513                     return true;
514                 }
515                 case ET_float:
516                 {
517                     if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.fval), SAL_MIN_INT64)
518                           && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_INT64)))
519                     {
520                         return false;
521                     }
522                     auto tmp = static_cast<sal_Int64>(ev->u.fval);
523                     ev->u.hval = tmp;
524                     ev->et = ET_hyper;
525                     return true;
526                 }
527                 case ET_double:
528                 {
529                     if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.dval), SAL_MIN_INT64)
530                           && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_INT64)))
531                     {
532                         return false;
533                     }
534                     auto tmp = static_cast<sal_Int64>(ev->u.dval);
535                     ev->u.hval = tmp;
536                     ev->et = ET_hyper;
537                     return true;
538                 }
539                 case ET_byte:
540                 {
541                     auto tmp = static_cast<sal_Int64>(ev->u.byval);
542                     ev->u.hval = tmp;
543                     ev->et = ET_hyper;
544                     return true;
545                 }
546                 default:
547                     OSL_ASSERT(false);
548                     return false;
549             }
550         case ET_uhyper:
551             switch (ev->et)
552             {
553                 case ET_short:
554                 {
555                     if (ev->u.sval < 0)
556                         return false;
557                     auto tmp = static_cast<sal_uInt64>(ev->u.sval);
558                     ev->u.uhval = tmp;
559                     ev->et = ET_uhyper;
560                     return true;
561                 }
562                 case ET_ushort:
563                 {
564                     auto tmp = static_cast<sal_uInt64>(ev->u.usval);
565                     ev->u.uhval = tmp;
566                     ev->et = ET_uhyper;
567                     return true;
568                 }
569                 case ET_long:
570                 {
571                     if (ev->u.lval < 0)
572                         return false;
573                     auto tmp = static_cast<sal_uInt64>(ev->u.lval);
574                     ev->u.uhval = tmp;
575                     ev->et = ET_uhyper;
576                     return true;
577                 }
578                 case ET_ulong:
579                 {
580                     auto tmp = static_cast<sal_uInt64>(ev->u.ulval);
581                     ev->u.uhval = tmp;
582                     ev->et = ET_uhyper;
583                     return true;
584                 }
585                 case ET_hyper:
586                 {
587                     if (ev->u.hval < 0)
588                         return false;
589                     auto tmp = static_cast<sal_uInt64>(ev->u.hval);
590                     ev->u.uhval = tmp;
591                     ev->et = ET_uhyper;
592                     return true;
593                 }
594                 case ET_uhyper:
595                     return true;
596                 case ET_boolean:
597                 {
598                     auto tmp = static_cast<sal_uInt64>(ev->u.bval);
599                     ev->u.uhval = tmp;
600                     ev->et = ET_uhyper;
601                     return true;
602                 }
603                 case ET_float:
604                 {
605                     if (ev->u.fval < 0.0
606                         || !o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_UINT64))
607                     {
608                         return false;
609                     }
610                     auto tmp = static_cast<sal_uInt64>(ev->u.fval);
611                     ev->u.uhval = tmp;
612                     ev->et = ET_uhyper;
613                     return true;
614                 }
615                 case ET_double:
616                 {
617                     if (ev->u.dval < 0.0
618                         || !o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_UINT64))
619                     {
620                         return false;
621                     }
622                     auto tmp = static_cast<sal_uInt64>(ev->u.dval);
623                     ev->u.uhval = tmp;
624                     ev->et = ET_uhyper;
625                     return true;
626                 }
627                 case ET_byte:
628                 {
629                     auto tmp = static_cast<sal_uInt64>(ev->u.byval);
630                     ev->u.uhval = tmp;
631                     ev->et = ET_uhyper;
632                     return true;
633                 }
634                 default:
635                     OSL_ASSERT(false);
636                     return false;
637             }
638         case ET_boolean:
639             switch (ev->et)
640             {
641                 case ET_short:
642                     ev->u.bval = ev->u.sval != 0;
643                     ev->et = ET_boolean;
644                     return true;
645                 case ET_ushort:
646                     ev->u.bval = ev->u.usval != 0;
647                     ev->et = ET_boolean;
648                     return true;
649                 case ET_long:
650                     ev->u.bval = ev->u.lval != 0;
651                     ev->et = ET_boolean;
652                     return true;
653                 case ET_ulong:
654                     ev->u.bval = ev->u.ulval != 0;
655                     ev->et = ET_boolean;
656                     return true;
657                 case ET_hyper:
658                     ev->u.bval = ev->u.hval != 0;
659                     ev->et = ET_boolean;
660                     return true;
661                 case ET_uhyper:
662                     ev->u.bval = ev->u.uhval != 0;
663                     ev->et = ET_boolean;
664                     return true;
665                 case ET_boolean:
666                     return true;
667                 case ET_float:
668                     ev->u.bval = ev->u.fval != 0.0;
669                     ev->et = ET_boolean;
670                     return true;
671                 case ET_double:
672                     ev->u.bval = ev->u.dval != 0.0;
673                     ev->et = ET_boolean;
674                     return true;
675                 case ET_byte:
676                     ev->u.bval = ev->u.byval != 0;
677                     ev->et = ET_boolean;
678                     return true;
679                 default:
680                     OSL_ASSERT(false);
681                     return false;
682             }
683         case ET_float:
684             switch (ev->et)
685             {
686                 case ET_short:
687                 {
688                     auto tmp = static_cast<float>(ev->u.sval);
689                     ev->u.fval = tmp;
690                     ev->et = ET_float;
691                     return true;
692                 }
693                 case ET_ushort:
694                 {
695                     auto tmp = static_cast<float>(ev->u.usval);
696                     ev->u.fval = tmp;
697                     ev->et = ET_float;
698                     return true;
699                 }
700                 case ET_long:
701                 {
702                     auto tmp = static_cast<float>(ev->u.lval);
703                     ev->u.fval = tmp;
704                     ev->et = ET_float;
705                     return true;
706                 }
707                 case ET_ulong:
708                 {
709                     auto tmp = static_cast<float>(ev->u.ulval);
710                     ev->u.fval = tmp;
711                     ev->et = ET_float;
712                     return true;
713                 }
714                 case ET_hyper:
715                 {
716                     auto tmp = static_cast<float>(ev->u.hval);
717                     ev->u.fval = tmp;
718                     ev->et = ET_float;
719                     return true;
720                 }
721                 case ET_uhyper:
722                 {
723                     if (static_cast<float>(ev->u.ulval) > FLT_MAX)
724                         return false;
725                     auto tmp = static_cast<float>(ev->u.ulval);
726                     ev->u.fval = tmp;
727                     ev->et = ET_float;
728                     return true;
729                 }
730                 case ET_boolean:
731                     ev->u.fval = ev->u.bval ? 1.0f : 0.0f;
732                     ev->et = ET_float;
733                     return true;
734                 case ET_float:
735                     return true;
736                 case ET_double:
737                 {
738                     if (static_cast<float>(ev->u.dval) > FLT_MAX || static_cast<float>(ev->u.dval) < -FLT_MAX)
739                         return false;
740                     auto tmp = static_cast<float>(ev->u.dval);
741                     ev->u.fval = tmp;
742                     ev->et = ET_float;
743                     return true;
744                 }
745                 case ET_byte:
746                 {
747                     auto tmp = static_cast<float>(ev->u.byval);
748                     ev->u.fval = tmp;
749                     ev->et = ET_float;
750                     return true;
751                 }
752                 default:
753                     OSL_ASSERT(false);
754                     return false;
755             }
756         case ET_double:
757             switch (ev->et)
758             {
759                 case ET_short:
760                 {
761                     auto tmp = static_cast<double>(ev->u.sval);
762                     ev->u.dval = tmp;
763                     ev->et = ET_double;
764                     return true;
765                 }
766                 case ET_ushort:
767                 {
768                     auto tmp = static_cast<double>(ev->u.usval);
769                     ev->u.dval = tmp;
770                     ev->et = ET_double;
771                     return true;
772                 }
773                 case ET_long:
774                 {
775                     auto tmp = static_cast<double>(ev->u.lval);
776                     ev->u.dval = tmp;
777                     ev->et = ET_double;
778                     return true;
779                 }
780                 case ET_ulong:
781                 {
782                     auto tmp = static_cast<double>(ev->u.ulval);
783                     ev->u.dval = tmp;
784                     ev->et = ET_double;
785                     return true;
786                 }
787                 case ET_hyper:
788                 {
789                     auto tmp = static_cast<double>(ev->u.hval);
790                     ev->u.dval = tmp;
791                     ev->et = ET_double;
792                     return true;
793                 }
794                 case ET_uhyper:
795                 {
796                     if (ev->u.dval > FLT_MAX || ev->u.dval < -FLT_MAX)
797                         return false;
798                     auto tmp = static_cast<double>(ev->u.ulval);
799                     ev->u.dval = tmp;
800                     ev->et = ET_double;
801                     return true;
802                 }
803                 case ET_boolean:
804                     ev->u.dval = ev->u.bval ? 1.0 : 0.0;
805                     ev->et = ET_double;
806                     return true;
807                 case ET_float:
808                 {
809                     auto tmp = static_cast<double>(ev->u.fval);
810                     ev->u.dval = tmp;
811                     ev->et = ET_double;
812                     return true;
813                 }
814                 case ET_double:
815                     return true;
816                 case ET_byte:
817                 {
818                     auto tmp = static_cast<double>(ev->u.byval);
819                     ev->u.dval = tmp;
820                     ev->et = ET_double;
821                     return true;
822                 }
823                 default:
824                     OSL_ASSERT(false);
825                     return false;
826             }
827         case ET_byte:
828             switch (ev->et)
829             {
830                 case ET_short:
831                 {
832                     if (ev->u.sval < SAL_MIN_INT8 || ev->u.sval > SAL_MAX_UINT8)
833                         return false;
834                     auto tmp = static_cast<unsigned char>(ev->u.sval);
835                     ev->u.byval = tmp;
836                     ev->et = ET_byte;
837                     return true;
838                 }
839                 case ET_ushort:
840                 {
841                     if (ev->u.usval > SAL_MAX_UINT8)
842                         return false;
843                     auto tmp = static_cast<unsigned char>(ev->u.usval);
844                     ev->u.byval = tmp;
845                     ev->et = ET_byte;
846                     return true;
847                 }
848                 case ET_long:
849                 {
850                     if (ev->u.lval < SAL_MIN_INT8 || ev->u.lval > SAL_MAX_UINT8)
851                         return false;
852                     auto tmp = static_cast<unsigned char>(ev->u.lval);
853                     ev->u.byval = tmp;
854                     ev->et = ET_byte;
855                     return true;
856                 }
857                 case ET_ulong:
858                 {
859                     if (ev->u.ulval > SAL_MAX_UINT8)
860                         return false;
861                     auto tmp = static_cast<unsigned char>(ev->u.ulval);
862                     ev->u.byval = tmp;
863                     ev->et = ET_byte;
864                     return true;
865                 }
866                 case ET_hyper:
867                 {
868                     if (ev->u.hval < SAL_MIN_INT8 || ev->u.hval > SAL_MAX_UINT8)
869                         return false;
870                     auto tmp = static_cast<unsigned char>(ev->u.hval);
871                     ev->u.byval = tmp;
872                     ev->et = ET_byte;
873                     return true;
874                 }
875                 case ET_uhyper:
876                 {
877                     if (ev->u.uhval > SAL_MAX_UINT8)
878                         return false;
879                     auto tmp = static_cast<unsigned char>(ev->u.uhval);
880                     ev->u.byval = tmp;
881                     ev->et = ET_byte;
882                     return true;
883                 }
884                 case ET_boolean:
885                     ev->u.byval = ev->u.bval ? 1 : 0;
886                     ev->et = ET_byte;
887                     return true;
888                 case ET_float:
889                 {
890                     if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.fval), SAL_MIN_INT8)
891                           && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.fval), SAL_MAX_UINT8)))
892                     {
893                         return false;
894                     }
895                     auto tmp = static_cast<unsigned char>(static_cast<sal_Int32>(ev->u.fval));
896                     ev->u.byval = tmp;
897                     ev->et = ET_byte;
898                     return true;
899                 }
900                 case ET_double:
901                 {
902                     if (!(o3tl::convertsToAtLeast(o3tl::roundAway(ev->u.dval), SAL_MIN_INT8)
903                           && o3tl::convertsToAtMost(o3tl::roundAway(ev->u.dval), SAL_MAX_UINT8)))
904                     {
905                         return false;
906                     }
907                     auto tmp = static_cast<unsigned char>(static_cast<sal_Int32>(ev->u.dval));
908                     ev->u.byval = tmp;
909                     ev->et = ET_byte;
910                     return true;
911                 }
912                 case ET_byte:
913                     return true;
914                 default:
915                     OSL_ASSERT(false);
916                     return false;
917             }
918         default:
919             OSL_ASSERT(false);
920             return false;
921     }
922 }
923 
coerce(ExprType t)924 bool AstExpression::coerce(ExprType t)
925 {
926     /*
927      * Is it already of the right type?
928      */
929     if (m_exprValue != nullptr && m_exprValue->et == t)
930         return true;
931     /*
932      * OK, must coerce
933      *
934      * First, evaluate it, then try to coerce result type
935      * If already evaluated, return the result
936      */
937     evaluate();
938     if (m_exprValue == nullptr)
939         return false;
940 
941     if (!coerce_value(m_exprValue.get(), t))
942         m_exprValue.reset();
943 
944     return m_exprValue != nullptr;
945 }
946 
compareLong(AstExpression * pExpr)947 bool AstExpression::compareLong(AstExpression *pExpr)
948 {
949     bool bRet = false;
950     if (m_combOperator != pExpr->m_combOperator)
951         return bRet;
952     evaluate();
953     pExpr->evaluate();
954     if (m_exprValue == nullptr || pExpr->getExprValue() == nullptr)
955         return bRet;
956     if (m_exprValue->et != pExpr->getExprValue()->et)
957         return bRet;
958     switch (m_exprValue->et)
959     {
960         case ET_long:
961             bRet = m_exprValue->u.lval == pExpr->getExprValue()->u.lval;
962             break;
963         default:
964             OSL_ASSERT(false);
965             bRet = false;
966             break;
967     }
968     return bRet;
969 }
970 
evaluate()971 void AstExpression::evaluate()
972 {
973     /*
974      * Already evaluated?
975      */
976     if ( m_exprValue != nullptr )
977         return;
978     /*
979      * OK, must evaluate operator
980      */
981     switch (m_combOperator)
982     {
983         case ExprComb::Add:
984         case ExprComb::Minus:
985         case ExprComb::Mul:
986         case ExprComb::Div:
987         case ExprComb::Mod:
988             m_exprValue = eval_bin_op();
989             break;
990         case ExprComb::Or:
991         case ExprComb::Xor:
992         case ExprComb::And:
993         case ExprComb::Left:
994         case ExprComb::Right:
995             m_exprValue = eval_bit_op();
996             break;
997         case ExprComb::UPlus:
998         case ExprComb::UMinus:
999             m_exprValue = eval_un_op();
1000             break;
1001         case ExprComb::Symbol:
1002             m_exprValue = eval_symbol();
1003             break;
1004         case ExprComb::NONE:
1005             break;
1006     }
1007 }
1008 
eval_bin_op()1009 std::unique_ptr<AstExprValue> AstExpression::eval_bin_op()
1010 {
1011     ExprType eType = ET_double;
1012 
1013     if ( m_combOperator == ExprComb::Mod )
1014         eType = ET_hyper;
1015 
1016     if (m_subExpr1 == nullptr || m_subExpr2 == nullptr)
1017         return nullptr;
1018     m_subExpr1->evaluate();
1019     if (m_subExpr1->getExprValue() == nullptr)
1020         return nullptr;
1021     if (!m_subExpr1->coerce(eType))
1022         return nullptr;
1023     m_subExpr2->evaluate();
1024     if (m_subExpr2->getExprValue() == nullptr)
1025         return nullptr;
1026     if (!m_subExpr2->coerce(eType))
1027         return nullptr;
1028 
1029     std::unique_ptr< AstExprValue > retval(new AstExprValue);
1030     retval->et = eType;
1031 
1032     switch (m_combOperator)
1033     {
1034         case ExprComb::Mod:
1035             if (m_subExpr2->getExprValue()->u.hval == 0)
1036                 return nullptr;
1037             retval->u.hval = m_subExpr1->getExprValue()->u.hval % m_subExpr2->getExprValue()->u.hval;
1038             break;
1039         case ExprComb::Add:
1040             retval->u.dval = m_subExpr1->getExprValue()->u.dval + m_subExpr2->getExprValue()->u.dval;
1041             break;
1042         case ExprComb::Minus:
1043             retval->u.dval = m_subExpr1->getExprValue()->u.dval - m_subExpr2->getExprValue()->u.dval;
1044             break;
1045         case ExprComb::Mul:
1046             retval->u.dval = m_subExpr1->getExprValue()->u.dval * m_subExpr2->getExprValue()->u.dval;
1047             break;
1048         case ExprComb::Div:
1049             if (m_subExpr2->getExprValue()->u.dval == 0.0)
1050                 return nullptr;
1051             retval->u.dval = m_subExpr1->getExprValue()->u.dval / m_subExpr2->getExprValue()->u.dval;
1052             break;
1053         default:
1054             return nullptr;
1055     }
1056 
1057     return retval;
1058 }
1059 
eval_bit_op()1060 std::unique_ptr<AstExprValue> AstExpression::eval_bit_op()
1061 {
1062     if (m_subExpr1 == nullptr || m_subExpr2 == nullptr)
1063         return nullptr;
1064     m_subExpr1->evaluate();
1065     if (m_subExpr1->getExprValue() == nullptr)
1066         return nullptr;
1067     if (!m_subExpr1->coerce(ET_long))
1068         return nullptr;
1069     m_subExpr2->evaluate();
1070     if (m_subExpr2->getExprValue() == nullptr)
1071         return nullptr;
1072     if (!m_subExpr2->coerce(ET_long))
1073         return nullptr;
1074 
1075     std::unique_ptr< AstExprValue > retval(new AstExprValue);
1076     retval->et = ET_long;
1077 
1078     switch (m_combOperator)
1079     {
1080         case ExprComb::Or:
1081             retval->u.lval = m_subExpr1->getExprValue()->u.lval | m_subExpr2->getExprValue()->u.lval;
1082             break;
1083         case ExprComb::Xor:
1084             retval->u.lval = m_subExpr1->getExprValue()->u.lval ^ m_subExpr2->getExprValue()->u.lval;
1085             break;
1086         case ExprComb::And:
1087             retval->u.lval = m_subExpr1->getExprValue()->u.lval & m_subExpr2->getExprValue()->u.lval;
1088             break;
1089         case ExprComb::Left:
1090             retval->u.lval = m_subExpr1->getExprValue()->u.lval << m_subExpr2->getExprValue()->u.lval;
1091             break;
1092         case ExprComb::Right:
1093             retval->u.lval = m_subExpr1->getExprValue()->u.lval >> m_subExpr2->getExprValue()->u.lval;
1094             break;
1095         default:
1096             return nullptr;
1097     }
1098 
1099     return retval;
1100 }
1101 
eval_un_op()1102 std::unique_ptr<AstExprValue> AstExpression::eval_un_op()
1103 {
1104     if (m_subExpr1 == nullptr)
1105         return nullptr;
1106     m_subExpr1->evaluate();
1107     if (m_subExpr1->getExprValue() == nullptr)
1108         return nullptr;
1109     if (!m_subExpr1->coerce(ET_double))
1110         return nullptr;
1111 
1112     std::unique_ptr< AstExprValue > retval(new AstExprValue);
1113     retval->et = ET_double;
1114 
1115     switch (m_combOperator)
1116     {
1117         case ExprComb::UPlus:
1118             retval->u.lval = m_subExpr1->getExprValue()->u.lval;
1119             break;
1120         case ExprComb::UMinus:
1121             retval->u.lval = -(m_subExpr1->getExprValue()->u.lval);
1122             break;
1123         default:
1124             return nullptr;
1125     }
1126 
1127     return retval;
1128 }
1129 
eval_symbol()1130 std::unique_ptr<AstExprValue> AstExpression::eval_symbol()
1131 {
1132     AstScope        *pScope = nullptr;
1133     AstDeclaration  *pDecl;
1134     AstConstant     *pConst;
1135 
1136     /*
1137      * Is there a symbol stored?
1138      */
1139     if (!m_xSymbolicName)
1140     {
1141         ErrorHandler::evalError(this);
1142         return nullptr;
1143     }
1144     /*
1145      * Get current scope for lookup
1146      */
1147     if (idlc()->scopes()->depth() > 0)
1148         pScope = idlc()->scopes()->topNonNull();
1149     if ( !pScope )
1150     {
1151         ErrorHandler::lookupError(*m_xSymbolicName);
1152         return nullptr;
1153     }
1154     /*
1155      * Do lookup
1156      */
1157     pDecl = pScope->lookupByName(*m_xSymbolicName);
1158     if (pDecl == nullptr)
1159     {
1160         ErrorHandler::lookupError(*m_xSymbolicName);
1161         return nullptr;
1162     }
1163     /*
1164      * Is it a constant?
1165      */
1166     if (pDecl->getNodeType() != NT_const &&
1167         pDecl->getNodeType() != NT_enum_val)
1168     {
1169         ErrorHandler::constantExpected(pDecl, *m_xSymbolicName);
1170         return nullptr;
1171     }
1172     if (!ErrorHandler::checkPublished(pDecl))
1173     {
1174         return nullptr;
1175     }
1176     /*
1177      * OK, now evaluate the constant we just got, to produce its value
1178      */
1179     pConst = static_cast< AstConstant* >(pDecl);
1180     pConst->getConstValue()->evaluate();
1181     auto const val = pConst->getConstValue()->getExprValue();
1182     return val == nullptr ? nullptr : std::make_unique<AstExprValue>(*val);
1183 }
1184 
toString()1185 OString AstExpression::toString()
1186 {
1187     OString exprStr;
1188     if ( m_combOperator == ExprComb::Symbol )
1189         return m_xSymbolicName ? *m_xSymbolicName : OString("<Undefined Name>");
1190 
1191     if ( m_exprValue )
1192     {
1193         switch (m_exprValue->et)
1194         {
1195             case ET_short:
1196                 return OString::number(m_exprValue->u.sval);
1197             case ET_ushort:
1198                 return OString::number(m_exprValue->u.usval);
1199             case ET_long:
1200                 return OString::number(m_exprValue->u.lval);
1201             case ET_ulong:
1202                 return OString::number(m_exprValue->u.ulval);
1203             case ET_hyper:
1204                 return OString::number(m_exprValue->u.hval);
1205             case ET_uhyper:
1206                 return OString::number(m_exprValue->u.uhval);
1207             case ET_float:
1208                 return OString::number(m_exprValue->u.fval);
1209             case ET_double:
1210                 return OString::number(m_exprValue->u.dval);
1211             case ET_byte:
1212                 return OString::number(m_exprValue->u.byval);
1213             case ET_boolean:
1214                 if ( m_exprValue->u.lval == 0)
1215                     return "FALSE";
1216                 else
1217                     return "TRUE";
1218             default:
1219                 OSL_ASSERT(false);
1220                 return OString();
1221         }
1222     }
1223 
1224     switch (m_combOperator)
1225     {
1226         case ExprComb::UPlus:
1227             exprStr += "+";
1228             break;
1229         case ExprComb::UMinus:
1230             exprStr += "-";
1231             break;
1232         default:
1233             break;
1234     }
1235     if ( m_subExpr1 )
1236         exprStr += m_subExpr1->toString();
1237     switch (m_combOperator)
1238     {
1239         case ExprComb::Add:
1240             exprStr += " + ";
1241             break;
1242         case ExprComb::Minus:
1243             exprStr += " - ";
1244             break;
1245         case ExprComb::Mul:
1246             exprStr += " * ";
1247             break;
1248         case ExprComb::Div:
1249             exprStr += " / ";
1250             break;
1251         case ExprComb::Mod:
1252             exprStr += " % ";
1253             break;
1254         case ExprComb::Or:
1255             exprStr += " | ";
1256             break;
1257         case ExprComb::Xor:
1258             exprStr += " ^ ";
1259             break;
1260         case ExprComb::And:
1261             exprStr += " & ";
1262             break;
1263         case ExprComb::Left:
1264             exprStr += " << ";
1265             break;
1266         case ExprComb::Right:
1267             exprStr += " >> ";
1268             break;
1269         default:
1270             break;
1271     }
1272 
1273     if ( m_subExpr2 )
1274         exprStr += m_subExpr2->toString();
1275 
1276     return exprStr;
1277 }
1278 
1279 // Convert the type of an AST_Expression to a char *
exprTypeToString(ExprType t)1280 const sal_Char* exprTypeToString(ExprType t)
1281 {
1282     switch (t)
1283     {
1284         case ET_short:
1285             return "short";
1286         case ET_ushort:
1287             return "unsigned short";
1288         case ET_long:
1289             return "long";
1290         case ET_ulong:
1291             return "unsigned long";
1292         case ET_hyper:
1293             return "hyper";
1294         case ET_uhyper:
1295             return "unsigned hyper";
1296         case ET_float:
1297             return "float";
1298         case ET_double:
1299             return "double";
1300         case ET_char:
1301             return "char";
1302         case ET_byte:
1303             return "byte";
1304         case ET_boolean:
1305             return "boolean";
1306         case ET_string:
1307             return "string";
1308         case ET_any:
1309             return "any";
1310         case ET_type:
1311             return "type";
1312         case ET_void:
1313             return "void";
1314         case ET_none:
1315             return "none";
1316     }
1317 
1318     return "unknown";
1319 }
1320 
1321 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1322