source: src/ResolvExpr/ConversionCost.cpp @ 048dde4

Last change on this file since 048dde4 was a8404d9, checked in by Andrew Beach <ajbeach@…>, 7 weeks ago

Just some formatting clean-up I did while investigating EnumDecl::inlinedDecl.

  • Property mode set to 100644
File size: 30.1 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
47                     _Float16 _Complex
48                              _Float32
49                     _Float32 _Complex
50                                 float
51                        float _Complex
52                             _Float32x
53                    _Float32x _Complex
54                              _Float64
55                     _Float64 _Complex
56                                double
57                       double _Complex
58                             _Float64x
59                    _Float64x _Complex
60                             __float80
61                           long double
62                  long double _Complex
63                            __float128
64                             _Float128
65                    _Float128 _Complex
66                            _Float128x
67                   _Float128x _Complex
68        */
69        // GENERATED END
70
71        // GENERATED START, DO NOT EDIT
72        // GENERATED BY BasicTypes-gen.cpp
73        static const int costMatrix[ast::BasicKind::NUMBER_OF_BASIC_TYPES][ast::BasicKind::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
74                /*               B    C   SC   UC   SI  USI    I   UI   LI  ULI  LLI ULLI __ID__UID  _FH _FHC   _F  _FC    F   FC  _FX _FXC  _FD _FDC    D   DC _FDX_FDXC _F80   LD  LDC__FLD _FLD_FLDC_FLDX_FLDXC */
75                /*      B */ {   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28, },
76                /*      C */ {  -1,   0,   1,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27, },
77                /*     SC */ {  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27, },
78                /*     UC */ {  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27, },
79                /*     SI */ {  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26, },
80                /*    USI */ {  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26, },
81                /*      I */ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25, },
82                /*     UI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25, },
83                /*     LI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24, },
84                /*    ULI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24, },
85                /*    LLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23, },
86                /*   ULLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23, },
87                /*   __ID */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22, },
88                /*  __UID */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22, },
89                /*    _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21, },
90                /*   _FHC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   2,  -1,   4,  -1,   6,  -1,   8,  -1,  10,  -1,  12,  -1,  -1,  15,  -1,  -1,  18,  -1,  20, },
91                /*     _F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19, },
92                /*    _FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   2,  -1,   4,  -1,   6,  -1,   8,  -1,  10,  -1,  -1,  13,  -1,  -1,  16,  -1,  18, },
93                /*      F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17, },
94                /*     FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   2,  -1,   4,  -1,   6,  -1,   8,  -1,  -1,  11,  -1,  -1,  14,  -1,  16, },
95                /*    _FX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15, },
96                /*   _FXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   2,  -1,   4,  -1,   6,  -1,  -1,   9,  -1,  -1,  12,  -1,  14, },
97                /*    _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,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13, },
98                /*   _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,   2,  -1,   4,  -1,  -1,   7,  -1,  -1,  10,  -1,  12, },
99                /*      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,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11, },
100                /*     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,   2,  -1,  -1,   5,  -1,  -1,   8,  -1,  10, },
101                /*   _FDX */ {  -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,   3,   4,   5,   6,   7,   8,   9, },
102                /*  _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,   3,  -1,  -1,   6,  -1,   8, },
103                /*   _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,   3,   4,   5,   6,   7, },
104                /*     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,   0,   1,   2,   3,   4,   5,   6, },
105                /*    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,   0,  -1,  -1,   3,  -1,   5, },
106                /*  __FLD */ {  -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,   3,   4, },
107                /*   _FLD */ {  -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,   2,   3, },
108                /*  _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,  -1,  -1,  -1,   0,  -1,   2, },
109                /*  _FLDX */ {  -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, },
110                /* _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, },
111        }; // costMatrix
112        static const int maxIntCost = 25;
113        // GENERATED END
114        static_assert(
115                sizeof(costMatrix)/sizeof(costMatrix[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES,
116                "Missing row in the cost matrix"
117        );
118
119        // GENERATED START, DO NOT EDIT
120        // GENERATED BY BasicTypes-gen.cpp
121        static const int signMatrix[ast::BasicKind::NUMBER_OF_BASIC_TYPES][ast::BasicKind::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
122                /*               B    C   SC   UC   SI  USI    I   UI   LI  ULI  LLI ULLI __ID__UID  _FH _FHC   _F  _FC    F   FC  _FX _FXC  _FD _FDC    D   DC _FDX_FDXC _F80   LD  LDC__FLD _FLD_FLDC_FLDX_FLDXC */
123                /*      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, },
124                /*      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, },
125                /*     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, },
126                /*     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, },
127                /*     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, },
128                /*    USI */ {  -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, },
129                /*      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, },
130                /*     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, },
131                /*     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, },
132                /*    ULI */ {  -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, },
133                /*    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, },
134                /*   ULLI */ {  -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, },
135                /*   __ID */ {  -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, },
136                /*  __UID */ {  -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, },
137                /*    _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, },
138                /*   _FHC */ {  -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, },
139                /*     _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, },
140                /*    _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, },
141                /*      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, },
142                /*     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, },
143                /*    _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, },
144                /*   _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, },
145                /*    _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, },
146                /*   _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, },
147                /*      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, },
148                /*     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, },
149                /*   _FDX */ {  -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, },
150                /*  _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, },
151                /*   _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,   0,   0,   0,   0,   0,   0,   0, },
152                /*     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,   0,   0,   0,   0,   0,   0,   0, },
153                /*    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,   0,  -1,  -1,   0,  -1,   0, },
154                /*  __FLD */ {  -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,   0, },
155                /*   _FLD */ {  -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, },
156                /*  _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,  -1,  -1,  -1,   0,  -1,   0, },
157                /*  _FLDX */ {  -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, },
158                /* _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, },
159        }; // signMatrix
160        // GENERATED END
161        static_assert(
162                sizeof(signMatrix)/sizeof(signMatrix[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES,
163                "Missing row in the sign matrix"
164        );
165
166        int localPtrsAssignable(const ast::Type * t1, const ast::Type * t2,
167                        const ast::SymbolTable &, const ast::TypeEnvironment & env ) {
168                return ptrsAssignable( t1, t2, env );
169        }
170}
171
172Cost conversionCost(
173        const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
174const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
175) {
176        if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
177                if ( const ast::EqvClass * eqv = env.lookup( *inst ) ) {
178                        if ( eqv->bound ) {
179                                return conversionCost(src, eqv->bound, srcIsLvalue, symtab, env );
180                        } else {
181                                return Cost::infinity;
182                        }
183                } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {
184                        const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( named );
185                        assertf( type, "Unexpected typedef." );
186                        if ( type->base ) {
187                                return conversionCost( src, type->base, srcIsLvalue, symtab, env ) + Cost::safe;
188                        }
189                }
190        }
191        if ( typesCompatibleIgnoreQualifiers( src, dst, env ) ) {
192                return Cost::zero;
193        } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
194                return Cost::safe;
195        } else if ( const ast::ReferenceType * refType =
196                         dynamic_cast< const ast::ReferenceType * >( dst ) ) {
197                return convertToReferenceCost( src, refType, srcIsLvalue, symtab, env, localPtrsAssignable );
198        } else {
199                return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
200        }
201}
202
203Cost enumCastCost (
204        const ast::EnumInstType * src, const ast::EnumInstType * dst,
205        const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
206);
207
208static Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
209                int diff, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
210                PtrsCalculation func ) {
211        if ( 0 < diff ) {
212                Cost cost = convertToReferenceCost(
213                        strict_dynamic_cast< const ast::ReferenceType * >( src )->base, dst,
214                        srcIsLvalue, (diff - 1), symtab, env, func );
215                cost.incReference();
216                return cost;
217        } else if ( diff < -1 ) {
218                Cost cost = convertToReferenceCost(
219                        src, strict_dynamic_cast< const ast::ReferenceType * >( dst )->base,
220                        srcIsLvalue, (diff + 1), symtab, env, func );
221                cost.incReference();
222                return cost;
223        } else if ( 0 == diff ) {
224                const ast::ReferenceType * srcAsRef = dynamic_cast< const ast::ReferenceType * >( src );
225                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
226                if ( srcAsRef && dstAsRef ) {
227                        ast::CV::Qualifiers tq1 = srcAsRef->base->qualifiers;
228                        ast::CV::Qualifiers tq2 = dstAsRef->base->qualifiers;
229                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
230                                        srcAsRef->base, dstAsRef->base, env ) ) {
231                                if ( tq1 == tq2 ) {
232                                        return Cost::zero;
233                                } else {
234                                        return Cost::safe;
235                                }
236                        } else {
237                                int assignResult = func( srcAsRef->base, dstAsRef->base, symtab, env );
238                                if ( 0 < assignResult ) {
239                                        return Cost::safe;
240                                } else if ( assignResult < 0 ) {
241                                        return Cost::unsafe;
242                                }
243                        }
244                } else {
245                        return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
246                }
247                if (const ast::EnumInstType * srcAsInst = dynamic_cast< const ast::EnumInstType * >( src )) {
248                        if ( srcAsInst->base && srcAsInst->base->is_c_enum() ) {
249                                static const ast::BasicType* integer = new ast::BasicType( ast::BasicKind::UnsignedInt );
250                                return ast::Pass<ConversionCost>::read( integer, dst, srcIsLvalue, symtab, env, conversionCost );
251                        }
252                }
253        } else {
254                assert( -1 == diff );
255                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
256                assert( dstAsRef );
257                auto dstBaseType = dstAsRef->base;
258                const ast::Type * newSrc = src;
259                if ( dynamic_cast< const ast::EnumInstType * >( src ) && dstBaseType.as<ast::BasicType>() ) {
260                        newSrc = new ast::BasicType( ast::BasicKind::UnsignedInt );
261                }
262                if (dstAsRef->base->is_const() ) {
263                        auto cvtCost = conversionCost(newSrc, dstAsRef->base, srcIsLvalue, symtab, env) ;
264                        if (cvtCost == Cost::zero) { // exact match, may use a lvalue src
265                                if ( srcIsLvalue ) {
266                                        if ( src->qualifiers == dstAsRef->base->qualifiers ) {
267                                                return Cost::reference;
268                                        } else if ( src->qualifiers < dstAsRef->base->qualifiers ) {
269                                                return Cost::safe;
270                                        } else {
271                                                return Cost::unsafe;
272                                        }
273                                }
274                                else {
275                                        return Cost::reference;
276                                }
277                        }
278                        else { // not exact match, conversion is needed so lvalueness of src does not matter
279                                return cvtCost + Cost::reference;
280                        }
281                }
282                if ( typesCompatibleIgnoreQualifiers( newSrc, dstAsRef->base, env ) ) {
283                        if ( srcIsLvalue ) {
284                                if ( src->qualifiers == dstAsRef->base->qualifiers ) {
285                                        return Cost::reference;
286                                } else if ( src->qualifiers < dstAsRef->base->qualifiers ) {
287                                        return Cost::safe;
288                                } else {
289                                        return Cost::unsafe;
290                                }
291                        } else { // rvalue-to-NC-ref conversion
292                                return Cost::unsafe;
293                        }
294                }
295        }
296        return Cost::infinity;
297}
298
299Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dst,
300                bool srcIsLvalue, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
301                PtrsCalculation func ) {
302        int sdepth = src->referenceDepth(), ddepth = dst->referenceDepth();
303        return convertToReferenceCost( src, dst, srcIsLvalue, sdepth - ddepth, symtab, env, func );
304}
305
306void ConversionCost::postvisit( const ast::VoidType * voidType ) {
307        (void)voidType;
308        cost = Cost::infinity;
309}
310
311void ConversionCost::conversionCostFromBasicToBasic( const ast::BasicType * src, const ast::BasicType* dest ) {
312        int tableResult = costMatrix[ src->kind ][ dest->kind ];
313        if ( tableResult == -1 ) {
314                cost = Cost::unsafe;
315        } else {
316                cost = Cost::zero;
317                cost.incSafe( tableResult );
318                cost.incSign( signMatrix[ src->kind ][ dest->kind ] );
319        }
320}
321
322void ConversionCost::postvisit( const ast::BasicType * basicType ) {
323        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
324                conversionCostFromBasicToBasic( basicType, dstAsBasic );
325        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
326                if ( dstAsEnumInst->base && dstAsEnumInst->base->is_c_enum() ) {
327                        cost = Cost::safe;
328                }
329        }
330}
331
332void ConversionCost::postvisit( const ast::PointerType * pointerType ) {
333        if ( const ast::PointerType * dstAsPtr = dynamic_cast< const ast::PointerType * >( dst ) ) {
334                ast::CV::Qualifiers tq1 = pointerType->base->qualifiers;
335                ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers;
336                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
337                                pointerType->base, dstAsPtr->base, env ) ) {
338                        if ( tq1 == tq2 ) {
339                                cost = Cost::zero;
340                        } else {
341                                cost = Cost::safe;
342                        }
343                }
344                /*
345                else if ( const ast::FunctionType * dstFunc = dstAsPtr->base.as<ast::FunctionType>()) {
346                        if (const ast::FunctionType * srcFunc = pointerType->base.as<ast::FunctionType>()) {
347                                if (dstFunc->params.empty() && dstFunc->isVarArgs ) {
348                                        cost = Cost::unsafe; // assign any function to variadic fptr
349                                }
350                        }
351                        else {
352                                ast::AssertionSet need, have; // unused
353                                ast::OpenVarSet open;
354                                env.extractOpenVars(open);
355                                ast::TypeEnvironment tenv = env;
356                                if ( unify(dstAsPtr->base, pointerType->base, tenv, need, have, open, symtab) ) {
357                                        cost = Cost::safe;
358                                }
359                        }
360                        // else infinity
361                }
362                */
363                else {
364                        int assignResult = ptrsAssignable( pointerType->base, dstAsPtr->base, env );
365                        if ( 0 < assignResult && tq1 <= tq2 ) {
366                                if ( tq1 == tq2 ) {
367                                        cost = Cost::safe;
368                                } else {
369                                        cost = Cost::safe + Cost::safe;
370                                }
371                        } else if ( assignResult < 0 ) {
372                                cost = Cost::unsafe;
373                        } // else Cost::infinity
374                }
375        }
376}
377
378void ConversionCost::postvisit( const ast::ArrayType * arrayType ) {
379        (void)arrayType;
380}
381
382void ConversionCost::postvisit( const ast::ReferenceType * refType ) {
383        assert( nullptr == dynamic_cast< const ast::ReferenceType * >( dst ) );
384
385        cost = costCalc( refType->base, dst, srcIsLvalue, symtab, env );
386
387        // xxx - should qualifiers be considered in pass-by-value?
388        /*
389        if ( refType->base->qualifiers == dst->qualifiers ) {
390                cost.incReference();
391        } else if ( refType->base->qualifiers < dst->qualifiers ) {
392                cost.incSafe();
393        } else {
394                cost.incUnsafe();
395        }
396        */
397        cost.incReference();
398}
399
400void ConversionCost::postvisit( const ast::FunctionType * functionType ) {
401        (void)functionType;
402}
403
404void ConversionCost::postvisit( const ast::EnumInstType * inst ) {
405        if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
406                cost = enumCastCost(inst, dstInst, symtab, env);
407        } else if ( inst->base->is_c_enum() ) {
408                static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
409                cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
410        }
411        // cost.incUnsafe();
412}
413
414void ConversionCost::postvisit( const ast::TraitInstType * traitInstType ) {
415        (void)traitInstType;
416}
417
418void ConversionCost::postvisit( const ast::TypeInstType * typeInstType ) {
419        if ( const ast::EqvClass * eqv = env.lookup( *typeInstType ) ) {
420                cost = costCalc( eqv->bound, dst, srcIsLvalue, symtab, env );
421        } else if ( const ast::TypeInstType * dstAsInst =
422                        dynamic_cast< const ast::TypeInstType * >( dst ) ) {
423                if ( *typeInstType == *dstAsInst ) {
424                        cost = Cost::zero;
425                }
426        } else if ( const ast::NamedTypeDecl * namedType = symtab.lookupType( typeInstType->name ) ) {
427                const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( namedType );
428                assertf( type, "Unexpected typedef.");
429                if ( type->base ) {
430                        cost = costCalc( type->base, dst, srcIsLvalue, symtab, env ) + Cost::safe;
431                }
432        }
433}
434
435void ConversionCost::postvisit( const ast::TupleType * tupleType ) {
436        Cost c = Cost::zero;
437        if ( const ast::TupleType * dstAsTuple = dynamic_cast< const ast::TupleType * >( dst ) ) {
438                auto srcIt = tupleType->types.begin();
439                auto dstIt = dstAsTuple->types.begin();
440                auto srcEnd = tupleType->types.end();
441                auto dstEnd = dstAsTuple->types.end();
442                while ( srcIt != srcEnd && dstIt != dstEnd ) {
443                        Cost newCost = costCalc( * srcIt++, * dstIt++, srcIsLvalue, symtab, env );
444                        if ( newCost == Cost::infinity ) {
445                                return;
446                        }
447                        c += newCost;
448                }
449                if ( dstIt != dstEnd ) {
450                        cost = Cost::infinity;
451                } else {
452                        cost = c;
453                }
454        }
455}
456
457void ConversionCost::postvisit( const ast::VarArgsType * ) {
458        if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) {
459                cost = Cost::zero;
460        }
461}
462
463void ConversionCost::postvisit( const ast::ZeroType * ) {
464        if ( dynamic_cast< const ast::ZeroType * >( 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                // this has the effect of letting any expr such as x+0, x+1 to be typed
477                // the same as x, instead of at least int. are we willing to sacrifice this little
478                // bit of coherence with C?
479                // TODO: currently this does not work when no zero/one overloads exist. Find a fix for it.
480                // cost = Cost::zero;
481        } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {
482                cost = Cost::zero;
483                // +1 for zero_t ->, +1 for disambiguation
484                cost.incSafe( maxIntCost + 2 );
485                // assuming 0p is supposed to be used for pointers?
486        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
487                if ( dstAsEnumInst->base && dstAsEnumInst->base->is_c_enum() ) {
488                        cost = Cost::safe;
489                }
490        }
491}
492
493void ConversionCost::postvisit( const ast::OneType * ) {
494        if ( dynamic_cast< const ast::OneType * >( dst ) ) {
495                cost = Cost::zero;
496        } else if ( const ast::BasicType * dstAsBasic =
497                        dynamic_cast< const ast::BasicType * >( dst ) ) {
498                int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ];
499                if ( -1 == tableResult ) {
500                        cost = Cost::unsafe;
501                } else {
502                        cost = Cost::zero;
503                        cost.incSafe( tableResult + 1 );
504                        cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] );
505                }
506        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
507                if ( dstAsEnumInst->base && dstAsEnumInst->base->is_c_enum() ) {
508                        cost = Cost::safe;
509                }
510        }
511}
512
513// (dst) src is safe is src is a subtype of dst, or dst {inline src, ...}
514Cost enumCastCost (
515        const ast::EnumInstType * src, const ast::EnumInstType * dst,
516        const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
517) {
518        auto srcDecl = src->base;
519        auto dstDecl = dst->base;
520        if ( srcDecl->name == dstDecl->name ) return Cost::safe;
521        Cost minCost = Cost::infinity;
522        for ( auto child : dstDecl->inlinedDecl ) {
523                Cost c = enumCastCost( src, child, symtab, env ) + Cost::safe;
524                if ( c < minCost ) minCost = c;
525        }
526        return minCost;
527}
528
529
530// size_t ConversionCost::traceId = Stats::Heap::new_stacktrace_id("ConversionCost");
531
532} // namespace ResolvExpr
533
534// Local Variables: //
535// tab-width: 4 //
536// mode: c++ //
537// compile-command: "make install" //
538// End: //
Note: See TracBrowser for help on using the repository browser.