source: src/ResolvExpr/ConversionCost.cpp @ c92bdcc

Last change on this file since c92bdcc was c92bdcc, checked in by Andrew Beach <ajbeach@…>, 5 months ago

Updated the rest of the names in src/ (except for the generated files).

  • Property mode set to 100644
File size: 29.6 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
193static Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
194                int diff, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
195                PtrsCalculation func ) {
196        if ( 0 < diff ) {
197                Cost cost = convertToReferenceCost(
198                        strict_dynamic_cast< const ast::ReferenceType * >( src )->base, dst,
199                        srcIsLvalue, (diff - 1), symtab, env, func );
200                cost.incReference();
201                return cost;
202        } else if ( diff < -1 ) {
203                Cost cost = convertToReferenceCost(
204                        src, strict_dynamic_cast< const ast::ReferenceType * >( dst )->base,
205                        srcIsLvalue, (diff + 1), symtab, env, func );
206                cost.incReference();
207                return cost;
208        } else if ( 0 == diff ) {
209                const ast::ReferenceType * srcAsRef = dynamic_cast< const ast::ReferenceType * >( src );
210                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
211                if ( srcAsRef && dstAsRef ) {
212                        ast::CV::Qualifiers tq1 = srcAsRef->base->qualifiers;
213                        ast::CV::Qualifiers tq2 = dstAsRef->base->qualifiers;
214                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
215                                        srcAsRef->base, dstAsRef->base, env ) ) {
216                                if ( tq1 == tq2 ) {
217                                        return Cost::zero;
218                                } else {
219                                        return Cost::safe;
220                                }
221                        } else {
222                                int assignResult = func( srcAsRef->base, dstAsRef->base, symtab, env );
223                                if ( 0 < assignResult ) {
224                                        return Cost::safe;
225                                } else if ( assignResult < 0 ) {
226                                        return Cost::unsafe;
227                                }
228                        }
229                } else {
230                        return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
231                }
232        } else {
233                assert( -1 == diff );
234                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
235                assert( dstAsRef );
236                if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) {
237                        if ( srcIsLvalue ) {
238                                if ( src->qualifiers == dstAsRef->base->qualifiers ) {
239                                        return Cost::reference;
240                                } else if ( src->qualifiers < dstAsRef->base->qualifiers ) {
241                                        return Cost::safe;
242                                } else {
243                                        return Cost::unsafe;
244                                }
245                        } else if ( dstAsRef->base->is_const() ) {
246                                return Cost::safe;
247                        } else {
248                                return Cost::unsafe;
249                        }
250                }
251        }
252        return Cost::infinity;
253}
254
255Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dst,
256                bool srcIsLvalue, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
257                PtrsCalculation func ) {
258        int sdepth = src->referenceDepth(), ddepth = dst->referenceDepth();
259        return convertToReferenceCost( src, dst, srcIsLvalue, sdepth - ddepth, symtab, env, func );
260}
261
262void ConversionCost::postvisit( const ast::VoidType * voidType ) {
263        (void)voidType;
264        cost = Cost::infinity;
265}
266
267void ConversionCost::conversionCostFromBasicToBasic( const ast::BasicType * src, const ast::BasicType* dest ) {
268        int tableResult = costMatrix[ src->kind ][ dest->kind ];
269        if ( tableResult == -1 ) {
270                cost = Cost::unsafe;
271        } else {
272                cost = Cost::zero;
273                cost.incSafe( tableResult );
274                cost.incSign( signMatrix[ src->kind ][ dest->kind ] );
275        }
276}
277
278void ConversionCost::postvisit( const ast::BasicType * basicType ) {
279        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
280                conversionCostFromBasicToBasic( basicType, dstAsBasic );
281        } else if ( dynamic_cast< const ast::EnumAttrType *>(dst) ) {
282                static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
283                cost = costCalc( basicType, integer, srcIsLvalue, symtab, env );
284        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
285                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
286                        cost = Cost::unsafe;
287                }
288        }
289}
290
291void ConversionCost::postvisit( const ast::PointerType * pointerType ) {
292        if ( const ast::PointerType * dstAsPtr = dynamic_cast< const ast::PointerType * >( dst ) ) {
293                ast::CV::Qualifiers tq1 = pointerType->base->qualifiers;
294                ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers;
295                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
296                                pointerType->base, dstAsPtr->base, env ) ) {
297                        if ( tq1 == tq2 ) {
298                                cost = Cost::zero;
299                        } else {
300                                cost = Cost::safe;
301                        }
302                }
303                /*
304                else if ( const ast::FunctionType * dstFunc = dstAsPtr->base.as<ast::FunctionType>()) {
305                        if (const ast::FunctionType * srcFunc = pointerType->base.as<ast::FunctionType>()) {
306                                if (dstFunc->params.empty() && dstFunc->isVarArgs ) {
307                                        cost = Cost::unsafe; // assign any function to variadic fptr
308                                }
309                        }
310                        else {
311                                ast::AssertionSet need, have; // unused
312                                ast::OpenVarSet open;
313                                env.extractOpenVars(open);
314                                ast::TypeEnvironment tenv = env;
315                                if ( unify(dstAsPtr->base, pointerType->base, tenv, need, have, open, symtab) ) {
316                                        cost = Cost::safe;
317                                }
318                        }
319                        // else infinity
320                }
321                */
322                else {
323                        int assignResult = ptrsAssignable( pointerType->base, dstAsPtr->base, env );
324                        if ( 0 < assignResult && tq1 <= tq2 ) {
325                                if ( tq1 == tq2 ) {
326                                        cost = Cost::safe;
327                                } else {
328                                        cost = Cost::safe + Cost::safe;
329                                }
330                        } else if ( assignResult < 0 ) {
331                                cost = Cost::unsafe;
332                        } // else Cost::infinity
333                }
334        }
335}
336
337void ConversionCost::postvisit( const ast::ArrayType * arrayType ) {
338        (void)arrayType;
339}
340
341void ConversionCost::postvisit( const ast::ReferenceType * refType ) {
342        assert( nullptr == dynamic_cast< const ast::ReferenceType * >( dst ) );
343
344        cost = costCalc( refType->base, dst, srcIsLvalue, symtab, env );
345
346        // xxx - should qualifiers be considered in pass-by-value?
347        /*
348        if ( refType->base->qualifiers == dst->qualifiers ) {
349                cost.incReference();
350        } else if ( refType->base->qualifiers < dst->qualifiers ) {
351                cost.incSafe();
352        } else {
353                cost.incUnsafe();
354        }
355        */
356        cost.incReference();
357}
358
359void ConversionCost::postvisit( const ast::FunctionType * functionType ) {
360        (void)functionType;
361}
362
363void ConversionCost::postvisit( const ast::EnumInstType * inst ) {
364        if ( auto dstAsInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
365                if (inst->base && dstAsInst->base) {
366                        if (inst->base->name == dstAsInst->base->name) {
367                                cost = Cost::zero;
368                                return;
369                        }
370                }
371                return;
372        }
373        static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
374        cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
375        if ( cost < Cost::unsafe ) {
376                cost.incSafe();
377        }
378}
379
380void ConversionCost::postvisit( const ast::EnumAttrType * src ) {
381        auto dstAsEnumAttrType = dynamic_cast<const ast::EnumAttrType *>(dst);
382        assert( src->attr != ast::EnumAttribute::Label );
383        if ( src->attr == ast::EnumAttribute::Value ) {
384                if ( dstAsEnumAttrType && dstAsEnumAttrType->attr == ast::EnumAttribute::Value) {
385                        cost = costCalc( src->instance, dstAsEnumAttrType->instance, srcIsLvalue, symtab, env );
386                } else {
387                        auto baseType = src->instance->base->base;
388                        cost = costCalc( baseType, dst, srcIsLvalue, symtab, env );
389                        if ( cost < Cost::infinity ) {
390                                cost.incUnsafe();
391                        }
392                }
393        } else { // ast::EnumAttribute::Posn
394                if ( auto dstBase = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
395                        cost = costCalc( src->instance, dstBase, srcIsLvalue, symtab, env );
396                        if ( cost < Cost::unsafe ) cost.incSafe();
397                } else {
398                        static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
399                        cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
400                        if ( cost < Cost::unsafe ) {
401                                cost.incSafe();
402                        }
403                }
404        }
405}
406
407void ConversionCost::postvisit( const ast::TraitInstType * traitInstType ) {
408        (void)traitInstType;
409}
410
411void ConversionCost::postvisit( const ast::TypeInstType * typeInstType ) {
412        if ( const ast::EqvClass * eqv = env.lookup( *typeInstType ) ) {
413                cost = costCalc( eqv->bound, dst, srcIsLvalue, symtab, env );
414        } else if ( const ast::TypeInstType * dstAsInst =
415                        dynamic_cast< const ast::TypeInstType * >( dst ) ) {
416                if ( *typeInstType == *dstAsInst ) {
417                        cost = Cost::zero;
418                }
419        } else if ( const ast::NamedTypeDecl * namedType = symtab.lookupType( typeInstType->name ) ) {
420                const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( namedType );
421                assertf( type, "Unexpected typedef.");
422                if ( type->base ) {
423                        cost = costCalc( type->base, dst, srcIsLvalue, symtab, env ) + Cost::safe;
424                }
425        }
426}
427
428void ConversionCost::postvisit( const ast::TupleType * tupleType ) {
429        Cost c = Cost::zero;
430        if ( const ast::TupleType * dstAsTuple = dynamic_cast< const ast::TupleType * >( dst ) ) {
431                auto srcIt = tupleType->types.begin();
432                auto dstIt = dstAsTuple->types.begin();
433                auto srcEnd = tupleType->types.end();
434                auto dstEnd = dstAsTuple->types.end();
435                while ( srcIt != srcEnd && dstIt != dstEnd ) {
436                        Cost newCost = costCalc( * srcIt++, * dstIt++, srcIsLvalue, symtab, env );
437                        if ( newCost == Cost::infinity ) {
438                                return;
439                        }
440                        c += newCost;
441                }
442                if ( dstIt != dstEnd ) {
443                        cost = Cost::infinity;
444                } else {
445                        cost = c;
446                }
447        }
448}
449
450void ConversionCost::postvisit( const ast::VarArgsType * varArgsType ) {
451        (void)varArgsType;
452        if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) {
453                cost = Cost::zero;
454        }
455}
456
457void ConversionCost::postvisit( const ast::ZeroType * zeroType ) {
458        (void)zeroType;
459        if ( dynamic_cast< const ast::ZeroType * >( dst ) ) {
460                cost = Cost::zero;
461        } else if ( const ast::BasicType * dstAsBasic =
462                        dynamic_cast< const ast::BasicType * >( dst ) ) {
463                int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ];
464                if ( -1 == tableResult ) {
465                        cost = Cost::unsafe;
466                } else {
467                        cost = Cost::zero;
468                        cost.incSafe( tableResult + 1 );
469                        cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] );
470                }
471                // this has the effect of letting any expr such as x+0, x+1 to be typed
472                // the same as x, instead of at least int. are we willing to sacrifice this little
473                // bit of coherence with C?
474                // TODO: currently this does not work when no zero/one overloads exist. Find a fix for it.
475                // cost = Cost::zero;
476        } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {
477                cost = Cost::zero;
478                // +1 for zero_t ->, +1 for disambiguation
479                cost.incSafe( maxIntCost + 2 );
480                // assuming 0p is supposed to be used for pointers?
481        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
482                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
483                        cost = Cost::unsafe;
484                }
485        }
486}
487
488void ConversionCost::postvisit( const ast::OneType * oneType ) {
489        (void)oneType;
490        if ( dynamic_cast< const ast::OneType * >( dst ) ) {
491                cost = Cost::zero;
492        } else if ( const ast::BasicType * dstAsBasic =
493                        dynamic_cast< const ast::BasicType * >( dst ) ) {
494                int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ];
495                if ( -1 == tableResult ) {
496                        cost = Cost::unsafe;
497                } else {
498                        cost = Cost::zero;
499                        cost.incSafe( tableResult + 1 );
500                        cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] );
501                }
502        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
503                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
504                        cost = Cost::unsafe;
505                }
506        }
507}
508
509// size_t ConversionCost::traceId = Stats::Heap::new_stacktrace_id("ConversionCost");
510
511} // namespace ResolvExpr
512
513// Local Variables: //
514// tab-width: 4 //
515// mode: c++ //
516// compile-command: "make install" //
517// End: //
Note: See TracBrowser for help on using the repository browser.