source: src/ResolvExpr/ConversionCost.cpp @ 4db0140

Last change on this file since 4db0140 was 5ccc733, checked in by JiadaL <j82liang@…>, 5 months ago

Fix the bug that C style enum cannot to use as an lvalue

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