source: src/ResolvExpr/ConversionCost.cpp @ 62a38e7

Last change on this file since 62a38e7 was 85855b0, checked in by JiadaL <j82liang@…>, 3 months ago
  1. Implement enum cast; 2. Change valueE so that opague enum returns quasi_void; 3. change enum hiding interpretation and pass visiting scheme
  • Property mode set to 100644
File size: 29.0 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// ConversionCost.cpp --
8//
9// Author           : Richard C. Bilson
10// Created On       : Sun May 17 07:06:19 2015
11// Last Modified By : Andrew Beach
12// Last Modified On : Wed Jul 29 16:11:00 2020
13// Update Count     : 28
14//
15
16#include "ConversionCost.hpp"
17
18#include <cassert>                       // for assert
19#include <list>                          // for list, list<>::const_iterator
20#include <string>                        // for operator==, string
21
22#include "ResolvExpr/Cost.hpp"           // for Cost
23#include "ResolvExpr/Unify.hpp"          // for typesCompatibleIgnoreQualifiers
24#include "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable
25
26namespace ResolvExpr {
27
28#if 0
29#define PRINT(x) x
30#else
31#define PRINT(x)
32#endif
33
34namespace {
35
36        // GENERATED START, DO NOT EDIT
37        // GENERATED BY BasicTypes-gen.cpp
38        /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
39                                 _Bool
40        char                signed char         unsigned char
41                  signed short int         unsigned short int
42                  signed int               unsigned int
43                  signed long int          unsigned long int
44                  signed long long int     unsigned long long int
45                  __int128                 unsigned __int128
46                  _Float16                 _Float16 _Complex
47                  _Float32                 _Float32 _Complex
48                  float                    float _Complex
49                  _Float32x                _Float32x _Complex
50                  _Float64                 _Float64 _Complex
51                  double                   double _Complex
52                  _Float64x                _Float64x _Complex
53                             __float80
54                  _Float128                _Float128 _Complex
55                            __float128
56                  long double              long double _Complex
57                  _Float128x               _Float128x _Complex
58        */
59        // GENERATED END
60
61        // GENERATED START, DO NOT EDIT
62        // GENERATED BY BasicTypes-gen.cpp
63        static const int costMatrix[ast::BasicKind::NUMBER_OF_BASIC_TYPES][ast::BasicKind::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
64                /*               B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
65                /*      B */ {   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  15,  16,  17,  16,  18,  17, },
66                /*      C */ {  -1,   0,   1,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
67                /*     SC */ {  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
68                /*     UC */ {  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
69                /*     SI */ {  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
70                /*    SUI */ {  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
71                /*      I */ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
72                /*     UI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
73                /*     LI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
74                /*    LUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
75                /*    LLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
76                /*   LLUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
77                /*     IB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
78                /*    UIB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
79                /*    _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,  10,   9,  11,  10, },
80                /*    _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,   6,  -1,  -1,   7,  -1,  -1,   8,  -1,   9, },
81                /*     _F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   9,   8,  10,   9, },
82                /*    _FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,  -1,   6,  -1,  -1,   7,  -1,   8, },
83                /*      F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   8,   7,   9,   8, },
84                /*     FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,  -1,   5,  -1,  -1,   6,  -1,   7, },
85                /*    _FX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   6,   8,   7, },
86                /*   _FXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,  -1,   4,  -1,  -1,   5,  -1,   6, },
87                /*     FD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   5,   7,   6, },
88                /*   _FDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,  -1,   3,  -1,  -1,   4,  -1,   5, },
89                /*      D */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   4,   6,   5, },
90                /*     DC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,  -1,   2,  -1,  -1,   3,  -1,   4, },
91                /*   F80X */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   3,   5,   4, },
92                /*  _FDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,  -1,   2,  -1,   3, },
93                /*    F80 */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,   0,   1,   2,   2,   3,   3,   4,   4, },
94                /*    _FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3, },
95                /*  _FLDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   1,  -1,   2, },
96                /*     FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   1,   0,   1,   2,   2,   3, },
97                /*     LD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2, },
98                /*    LDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1, },
99                /*   _FBX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1, },
100                /* _FLDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0, },
101        }; // costMatrix
102        static const int maxIntCost = 15;
103        // GENERATED END
104        static_assert(
105                sizeof(costMatrix)/sizeof(costMatrix[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES,
106                "Missing row in the cost matrix"
107        );
108
109        // GENERATED START, DO NOT EDIT
110        // GENERATED BY BasicTypes-gen.cpp
111        static const int signMatrix[ast::BasicKind::NUMBER_OF_BASIC_TYPES][ast::BasicKind::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
112                /*               B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
113                /*      B */ {   0,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
114                /*      C */ {  -1,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
115                /*     SC */ {  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
116                /*     UC */ {  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
117                /*     SI */ {  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
118                /*    SUI */ {  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
119                /*      I */ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
120                /*     UI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
121                /*     LI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
122                /*    LUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
123                /*    LLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
124                /*   LLUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
125                /*     IB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
126                /*    UIB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
127                /*    _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
128                /*    _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
129                /*     _F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
130                /*    _FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
131                /*      F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
132                /*     FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
133                /*    _FX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
134                /*   _FXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
135                /*     FD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
136                /*   _FDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
137                /*      D */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
138                /*     DC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
139                /*   F80X */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
140                /*  _FDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
141                /*    F80 */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
142                /*    _FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0, },
143                /*  _FLDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
144                /*     FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0, },
145                /*     LD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0, },
146                /*    LDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0, },
147                /*   _FBX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0, },
148                /* _FLDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0, },
149        }; // signMatrix
150        // GENERATED END
151        static_assert(
152                sizeof(signMatrix)/sizeof(signMatrix[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES,
153                "Missing row in the sign matrix"
154        );
155
156        int localPtrsAssignable(const ast::Type * t1, const ast::Type * t2,
157                        const ast::SymbolTable &, const ast::TypeEnvironment & env ) {
158                return ptrsAssignable( t1, t2, env );
159        }
160}
161
162Cost conversionCost(
163        const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
164        const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
165) {
166        if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
167                if ( const ast::EqvClass * eqv = env.lookup( *inst ) ) {
168                        if ( eqv->bound ) {
169                                return conversionCost(src, eqv->bound, srcIsLvalue, symtab, env );
170                        } else {
171                                return Cost::infinity;
172                        }
173                } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {
174                        const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( named );
175                        assertf( type, "Unexpected typedef." );
176                        if ( type->base ) {
177                                return conversionCost( src, type->base, srcIsLvalue, symtab, env ) + Cost::safe;
178                        }
179                }
180        }
181        if ( typesCompatibleIgnoreQualifiers( src, dst, env ) ) {
182                return Cost::zero;
183        } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
184                return Cost::safe;
185        } else if ( const ast::ReferenceType * refType =
186                         dynamic_cast< const ast::ReferenceType * >( dst ) ) {
187                return convertToReferenceCost( src, refType, srcIsLvalue, symtab, env, localPtrsAssignable );
188        } else {
189                return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
190        }
191}
192
193Cost enumCastCost (
194        const ast::EnumInstType * src, const ast::EnumInstType * dst, 
195        const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
196);
197
198static Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
199                int diff, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
200                PtrsCalculation func ) {
201        if ( 0 < diff ) {
202                Cost cost = convertToReferenceCost(
203                        strict_dynamic_cast< const ast::ReferenceType * >( src )->base, dst,
204                        srcIsLvalue, (diff - 1), symtab, env, func );
205                cost.incReference();
206                return cost;
207        } else if ( diff < -1 ) {
208                Cost cost = convertToReferenceCost(
209                        src, strict_dynamic_cast< const ast::ReferenceType * >( dst )->base,
210                        srcIsLvalue, (diff + 1), symtab, env, func );
211                cost.incReference();
212                return cost;
213        } else if ( 0 == diff ) {
214                const ast::ReferenceType * srcAsRef = dynamic_cast< const ast::ReferenceType * >( src );
215                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
216                if ( srcAsRef && dstAsRef ) {
217                        ast::CV::Qualifiers tq1 = srcAsRef->base->qualifiers;
218                        ast::CV::Qualifiers tq2 = dstAsRef->base->qualifiers;
219                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
220                                        srcAsRef->base, dstAsRef->base, env ) ) {
221                                if ( tq1 == tq2 ) {
222                                        return Cost::zero;
223                                } else {
224                                        return Cost::safe;
225                                }
226                        } else {
227                                int assignResult = func( srcAsRef->base, dstAsRef->base, symtab, env );
228                                if ( 0 < assignResult ) {
229                                        return Cost::safe;
230                                } else if ( assignResult < 0 ) {
231                                        return Cost::unsafe;
232                                }
233                        }
234                } else {
235                        return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
236                }
237        } else {
238                assert( -1 == diff );
239                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
240                assert( dstAsRef );
241                if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) {
242                        if ( srcIsLvalue ) {
243                                if ( src->qualifiers == dstAsRef->base->qualifiers ) {
244                                        return Cost::reference;
245                                } else if ( src->qualifiers < dstAsRef->base->qualifiers ) {
246                                        return Cost::safe;
247                                } else {
248                                        return Cost::unsafe;
249                                }
250                        } else if ( dstAsRef->base->is_const() ) {
251                                return Cost::safe;
252                        } else {
253                                return Cost::unsafe;
254                        }
255                }
256        }
257        return Cost::infinity;
258}
259
260Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dst,
261                bool srcIsLvalue, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
262                PtrsCalculation func ) {
263        int sdepth = src->referenceDepth(), ddepth = dst->referenceDepth();
264        return convertToReferenceCost( src, dst, srcIsLvalue, sdepth - ddepth, symtab, env, func );
265}
266
267void ConversionCost::postvisit( const ast::VoidType * voidType ) {
268        (void)voidType;
269        cost = Cost::infinity;
270}
271
272void ConversionCost::conversionCostFromBasicToBasic( const ast::BasicType * src, const ast::BasicType* dest ) {
273        int tableResult = costMatrix[ src->kind ][ dest->kind ];
274        if ( tableResult == -1 ) {
275                cost = Cost::unsafe;
276        } else {
277                cost = Cost::zero;
278                cost.incSafe( tableResult );
279                cost.incSign( signMatrix[ src->kind ][ dest->kind ] );
280        }
281}
282
283void ConversionCost::postvisit( const ast::BasicType * basicType ) {
284        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
285                conversionCostFromBasicToBasic( basicType, dstAsBasic );
286        }       else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
287                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
288                        cost = Cost::unsafe;
289                }
290        }
291}
292
293void ConversionCost::postvisit( const ast::PointerType * pointerType ) {
294        if ( const ast::PointerType * dstAsPtr = dynamic_cast< const ast::PointerType * >( dst ) ) {
295                ast::CV::Qualifiers tq1 = pointerType->base->qualifiers;
296                ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers;
297                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
298                                pointerType->base, dstAsPtr->base, env ) ) {
299                        if ( tq1 == tq2 ) {
300                                cost = Cost::zero;
301                        } else {
302                                cost = Cost::safe;
303                        }
304                }
305                /*
306                else if ( const ast::FunctionType * dstFunc = dstAsPtr->base.as<ast::FunctionType>()) {
307                        if (const ast::FunctionType * srcFunc = pointerType->base.as<ast::FunctionType>()) {
308                                if (dstFunc->params.empty() && dstFunc->isVarArgs ) {
309                                        cost = Cost::unsafe; // assign any function to variadic fptr
310                                }
311                        }
312                        else {
313                                ast::AssertionSet need, have; // unused
314                                ast::OpenVarSet open;
315                                env.extractOpenVars(open);
316                                ast::TypeEnvironment tenv = env;
317                                if ( unify(dstAsPtr->base, pointerType->base, tenv, need, have, open, symtab) ) {
318                                        cost = Cost::safe;
319                                }
320                        }
321                        // else infinity
322                }
323                */
324                else {
325                        int assignResult = ptrsAssignable( pointerType->base, dstAsPtr->base, env );
326                        if ( 0 < assignResult && tq1 <= tq2 ) {
327                                if ( tq1 == tq2 ) {
328                                        cost = Cost::safe;
329                                } else {
330                                        cost = Cost::safe + Cost::safe;
331                                }
332                        } else if ( assignResult < 0 ) {
333                                cost = Cost::unsafe;
334                        } // else Cost::infinity
335                }
336        }
337}
338
339void ConversionCost::postvisit( const ast::ArrayType * arrayType ) {
340        (void)arrayType;
341}
342
343void ConversionCost::postvisit( const ast::ReferenceType * refType ) {
344        assert( nullptr == dynamic_cast< const ast::ReferenceType * >( dst ) );
345
346        cost = costCalc( refType->base, dst, srcIsLvalue, symtab, env );
347
348        // xxx - should qualifiers be considered in pass-by-value?
349        /*
350        if ( refType->base->qualifiers == dst->qualifiers ) {
351                cost.incReference();
352        } else if ( refType->base->qualifiers < dst->qualifiers ) {
353                cost.incSafe();
354        } else {
355                cost.incUnsafe();
356        }
357        */
358        cost.incReference();
359}
360
361void ConversionCost::postvisit( const ast::FunctionType * functionType ) {
362        (void)functionType;
363}
364
365void ConversionCost::postvisit( const ast::EnumInstType * inst ) {
366        if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
367                cost = enumCastCost(inst, dstInst, symtab, env);
368                return;
369        }
370        static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
371        cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
372        if ( !inst->base->isTyped ) {
373                if ( cost < Cost::unsafe ) {
374                        cost.incSafe();
375                }
376                return;
377        }
378        cost.incUnsafe();
379}
380
381void ConversionCost::postvisit( const ast::TraitInstType * traitInstType ) {
382        (void)traitInstType;
383}
384
385void ConversionCost::postvisit( const ast::TypeInstType * typeInstType ) {
386        if ( const ast::EqvClass * eqv = env.lookup( *typeInstType ) ) {
387                cost = costCalc( eqv->bound, dst, srcIsLvalue, symtab, env );
388        } else if ( const ast::TypeInstType * dstAsInst =
389                        dynamic_cast< const ast::TypeInstType * >( dst ) ) {
390                if ( *typeInstType == *dstAsInst ) {
391                        cost = Cost::zero;
392                }
393        } else if ( const ast::NamedTypeDecl * namedType = symtab.lookupType( typeInstType->name ) ) {
394                const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( namedType );
395                assertf( type, "Unexpected typedef.");
396                if ( type->base ) {
397                        cost = costCalc( type->base, dst, srcIsLvalue, symtab, env ) + Cost::safe;
398                }
399        }
400}
401
402void ConversionCost::postvisit( const ast::TupleType * tupleType ) {
403        Cost c = Cost::zero;
404        if ( const ast::TupleType * dstAsTuple = dynamic_cast< const ast::TupleType * >( dst ) ) {
405                auto srcIt = tupleType->types.begin();
406                auto dstIt = dstAsTuple->types.begin();
407                auto srcEnd = tupleType->types.end();
408                auto dstEnd = dstAsTuple->types.end();
409                while ( srcIt != srcEnd && dstIt != dstEnd ) {
410                        Cost newCost = costCalc( * srcIt++, * dstIt++, srcIsLvalue, symtab, env );
411                        if ( newCost == Cost::infinity ) {
412                                return;
413                        }
414                        c += newCost;
415                }
416                if ( dstIt != dstEnd ) {
417                        cost = Cost::infinity;
418                } else {
419                        cost = c;
420                }
421        }
422}
423
424void ConversionCost::postvisit( const ast::VarArgsType * varArgsType ) {
425        (void)varArgsType;
426        if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) {
427                cost = Cost::zero;
428        }
429}
430
431void ConversionCost::postvisit( const ast::ZeroType * zeroType ) {
432        (void)zeroType;
433        if ( dynamic_cast< const ast::ZeroType * >( dst ) ) {
434                cost = Cost::zero;
435        } else if ( const ast::BasicType * dstAsBasic =
436                        dynamic_cast< const ast::BasicType * >( dst ) ) {
437                int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ];
438                if ( -1 == tableResult ) {
439                        cost = Cost::unsafe;
440                } else {
441                        cost = Cost::zero;
442                        cost.incSafe( tableResult + 1 );
443                        cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] );
444                }
445                // this has the effect of letting any expr such as x+0, x+1 to be typed
446                // the same as x, instead of at least int. are we willing to sacrifice this little
447                // bit of coherence with C?
448                // TODO: currently this does not work when no zero/one overloads exist. Find a fix for it.
449                // cost = Cost::zero;
450        } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {
451                cost = Cost::zero;
452                // +1 for zero_t ->, +1 for disambiguation
453                cost.incSafe( maxIntCost + 2 );
454                // assuming 0p is supposed to be used for pointers?
455        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
456                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
457                        cost = Cost::unsafe;
458                }
459        }
460}
461
462void ConversionCost::postvisit( const ast::OneType * oneType ) {
463        (void)oneType;
464        if ( dynamic_cast< const ast::OneType * >( dst ) ) {
465                cost = Cost::zero;
466        } else if ( const ast::BasicType * dstAsBasic =
467                        dynamic_cast< const ast::BasicType * >( dst ) ) {
468                int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ];
469                if ( -1 == tableResult ) {
470                        cost = Cost::unsafe;
471                } else {
472                        cost = Cost::zero;
473                        cost.incSafe( tableResult + 1 );
474                        cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] );
475                }
476        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
477                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
478                        cost = Cost::unsafe;
479                }
480        }
481}
482
483// (dst) src is safe is src is a subtype of dst, or dst {inline src, ...}
484Cost enumCastCost (
485        const ast::EnumInstType * src, const ast::EnumInstType * dst, 
486        const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
487) {
488        auto srcDecl = src->base;
489        auto dstDecl = dst->base;
490        if (srcDecl->name == dstDecl->name) return Cost::safe;
491        Cost minCost = Cost::infinity;
492        for (auto child: dstDecl->inlinedDecl) {
493                Cost c = enumCastCost(src, child, symtab, env) + Cost::safe;
494                if (c<minCost) minCost = c;
495        }
496        return minCost;
497}
498
499
500// size_t ConversionCost::traceId = Stats::Heap::new_stacktrace_id("ConversionCost");
501
502} // namespace ResolvExpr
503
504// Local Variables: //
505// tab-width: 4 //
506// mode: c++ //
507// compile-command: "make install" //
508// End: //
Note: See TracBrowser for help on using the repository browser.