source: src/ResolvExpr/ConversionCost.cc

Last change on this file was 0522ebe, checked in by JiadaL <j82liang@…>, 7 days ago

Add EnumPosType? to type system

  • Property mode set to 100644
File size: 28.2 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.cc --
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.h"
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.h"             // for Cost
23#include "ResolvExpr/Unify.h"            // 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
34        // GENERATED START, DO NOT EDIT
35        // GENERATED BY BasicTypes-gen.cc
36        /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
37                                 _Bool
38        char                signed char         unsigned char
39                  signed short int         unsigned short int
40                  signed int               unsigned int
41                  signed long int          unsigned long int
42                  signed long long int     unsigned long long int
43                  __int128                 unsigned __int128
44                  _Float16                 _Float16 _Complex
45                  _Float32                 _Float32 _Complex
46                  float                    float _Complex
47                  _Float32x                _Float32x _Complex
48                  _Float64                 _Float64 _Complex
49                  double                   double _Complex
50                  _Float64x                _Float64x _Complex
51                             __float80
52                  _Float128                _Float128 _Complex
53                            __float128
54                  long double              long double _Complex
55                  _Float128x               _Float128x _Complex
56        */
57        // GENERATED END
58
59        // GENERATED START, DO NOT EDIT
60        // GENERATED BY BasicTypes-gen.cc
61        static const int costMatrix[ast::BasicType::NUMBER_OF_BASIC_TYPES][ast::BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
62                /*               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 */
63                /*      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, },
64                /*      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, },
65                /*     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, },
66                /*     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, },
67                /*     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, },
68                /*    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, },
69                /*      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, },
70                /*     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, },
71                /*     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, },
72                /*    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, },
73                /*    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, },
74                /*   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, },
75                /*     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, },
76                /*    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, },
77                /*    _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, },
78                /*    _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, },
79                /*     _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, },
80                /*    _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, },
81                /*      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, },
82                /*     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, },
83                /*    _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, },
84                /*   _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, },
85                /*     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, },
86                /*   _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, },
87                /*      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, },
88                /*     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, },
89                /*   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, },
90                /*  _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, },
91                /*    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, },
92                /*    _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, },
93                /*  _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, },
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,  -1,   1,   0,   1,   2,   2,   3, },
95                /*     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, },
96                /*    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, },
97                /*   _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, },
98                /* _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, },
99        }; // costMatrix
100        static const int maxIntCost = 15;
101        // GENERATED END
102        static_assert(
103                sizeof(costMatrix)/sizeof(costMatrix[0][0]) == ast::BasicType::NUMBER_OF_BASIC_TYPES * ast::BasicType::NUMBER_OF_BASIC_TYPES,
104                "Missing row in the cost matrix"
105        );
106
107        // GENERATED START, DO NOT EDIT
108        // GENERATED BY BasicTypes-gen.cc
109        static const int signMatrix[ast::BasicType::NUMBER_OF_BASIC_TYPES][ast::BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
110                /*               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 */
111                /*      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, },
112                /*      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, },
113                /*     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, },
114                /*     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, },
115                /*     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, },
116                /*    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, },
117                /*      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, },
118                /*     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, },
119                /*     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, },
120                /*    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, },
121                /*    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, },
122                /*   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, },
123                /*     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, },
124                /*    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, },
125                /*    _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, },
126                /*    _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, },
127                /*     _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, },
128                /*    _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, },
129                /*      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, },
130                /*     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, },
131                /*    _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, },
132                /*   _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, },
133                /*     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, },
134                /*   _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, },
135                /*      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, },
136                /*     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, },
137                /*   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, },
138                /*  _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, },
139                /*    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, },
140                /*    _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, },
141                /*  _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, },
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,  -1,   0,   0,   0,   0,   0,   0, },
143                /*     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, },
144                /*    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, },
145                /*   _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, },
146                /* _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, },
147        }; // signMatrix
148        // GENERATED END
149        static_assert(
150                sizeof(signMatrix)/sizeof(signMatrix[0][0]) == ast::BasicType::NUMBER_OF_BASIC_TYPES * ast::BasicType::NUMBER_OF_BASIC_TYPES,
151                "Missing row in the sign matrix"
152        );
153
154namespace {
155        int localPtrsAssignable(const ast::Type * t1, const ast::Type * t2,
156                        const ast::SymbolTable &, const ast::TypeEnvironment & env ) {
157                return ptrsAssignable( t1, t2, env );
158        }
159}
160
161Cost conversionCost(
162        const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
163        const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
164) {
165        if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
166                if ( const ast::EqvClass * eqv = env.lookup( *inst ) ) {
167                        if ( eqv->bound ) {
168                                return conversionCost(src, eqv->bound, srcIsLvalue, symtab, env );
169                        } else {
170                                return Cost::infinity;
171                        }
172                } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {
173                        const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( named );
174                        assertf( type, "Unexpected typedef." );
175                        if ( type->base ) {
176                                return conversionCost( src, type->base, srcIsLvalue, symtab, env ) + Cost::safe;
177                        }
178                }
179        }
180        if ( typesCompatibleIgnoreQualifiers( src, dst, env ) ) {
181                return Cost::zero;
182        } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
183                return Cost::safe;
184        } else if ( const ast::ReferenceType * refType =
185                         dynamic_cast< const ast::ReferenceType * >( dst ) ) {
186                return convertToReferenceCost( src, refType, srcIsLvalue, symtab, env, localPtrsAssignable );
187        } else {
188                return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
189        }
190}
191
192static Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
193                int diff, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
194                PtrsCalculation func ) {
195        if ( 0 < diff ) {
196                Cost cost = convertToReferenceCost(
197                        strict_dynamic_cast< const ast::ReferenceType * >( src )->base, dst,
198                        srcIsLvalue, (diff - 1), symtab, env, func );
199                cost.incReference();
200                return cost;
201        } else if ( diff < -1 ) {
202                Cost cost = convertToReferenceCost(
203                        src, strict_dynamic_cast< const ast::ReferenceType * >( dst )->base,
204                        srcIsLvalue, (diff + 1), symtab, env, func );
205                cost.incReference();
206                return cost;
207        } else if ( 0 == diff ) {
208                const ast::ReferenceType * srcAsRef = dynamic_cast< const ast::ReferenceType * >( src );
209                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
210                if ( srcAsRef && dstAsRef ) {
211                        ast::CV::Qualifiers tq1 = srcAsRef->base->qualifiers;
212                        ast::CV::Qualifiers tq2 = dstAsRef->base->qualifiers;
213                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
214                                        srcAsRef->base, dstAsRef->base, env ) ) {
215                                if ( tq1 == tq2 ) {
216                                        return Cost::zero;
217                                } else {
218                                        return Cost::safe;
219                                }
220                        } else {
221                                int assignResult = func( srcAsRef->base, dstAsRef->base, symtab, env );
222                                if ( 0 < assignResult ) {
223                                        return Cost::safe;
224                                } else if ( assignResult < 0 ) {
225                                        return Cost::unsafe;
226                                }
227                        }
228                } else {
229                        return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
230                }
231        } else {
232                assert( -1 == diff );
233                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
234                assert( dstAsRef );
235                if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) {
236                        if ( srcIsLvalue ) {
237                                if ( src->qualifiers == dstAsRef->base->qualifiers ) {
238                                        return Cost::reference;
239                                } else if ( src->qualifiers < dstAsRef->base->qualifiers ) {
240                                        return Cost::safe;
241                                } else {
242                                        return Cost::unsafe;
243                                }
244                        } else if ( dstAsRef->base->is_const() ) {
245                                return Cost::safe;
246                        } else {
247                                return Cost::unsafe;
248                        }
249                }
250        }
251        return Cost::infinity;
252}
253
254Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dst,
255                bool srcIsLvalue, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
256                PtrsCalculation func ) {
257        int sdepth = src->referenceDepth(), ddepth = dst->referenceDepth();
258        return convertToReferenceCost( src, dst, srcIsLvalue, sdepth - ddepth, symtab, env, func );
259}
260
261void ConversionCost::postvisit( const ast::VoidType * voidType ) {
262        (void)voidType;
263        cost = Cost::infinity;
264}
265
266void ConversionCost::conversionCostFromBasicToBasic( const ast::BasicType * src, const ast::BasicType* dest ) {
267        int tableResult = costMatrix[ src->kind ][ dest->kind ];
268        if ( tableResult == -1 ) {
269                cost = Cost::unsafe;
270        } else {
271                cost = Cost::zero;
272                cost.incSafe( tableResult );
273                cost.incSign( signMatrix[ src->kind ][ dest->kind ] );
274        }
275}
276
277void ConversionCost::postvisit( const ast::BasicType * basicType ) {
278        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
279                conversionCostFromBasicToBasic( basicType, dstAsBasic );
280        } 
281        else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
282                auto enumDecl = enumInst->base;
283                if ( enumDecl->base.get() ) {
284                        // cost = costCalc( basicType, baseType, srcIsLvalue, symtab, env );
285                        // cost.incUnsafe();
286                        cost = Cost::infinity;
287                } else {
288            cost = Cost::unsafe;
289                }
290        }
291}
292
293void ConversionCost::postvisit( const ast::PointerType * pointerType ) {
294        if ( const ast::PointerType * dstAsPtr = dynamic_cast< const ast::PointerType * >( dst ) ) {
295                ast::CV::Qualifiers tq1 = pointerType->base->qualifiers;
296                ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers;
297                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
298                                pointerType->base, dstAsPtr->base, env ) ) {
299                        if ( tq1 == tq2 ) {
300                                cost = Cost::zero;
301                        } else {
302                                cost = Cost::safe;
303                        }
304                }
305                /*
306                else if ( const ast::FunctionType * dstFunc = dstAsPtr->base.as<ast::FunctionType>()) {
307                        if (const ast::FunctionType * srcFunc = pointerType->base.as<ast::FunctionType>()) {
308                                if (dstFunc->params.empty() && dstFunc->isVarArgs ) {
309                                        cost = Cost::unsafe; // assign any function to variadic fptr
310                                }
311                        }
312                        else {
313                                ast::AssertionSet need, have; // unused
314                                ast::OpenVarSet open;
315                                env.extractOpenVars(open);
316                                ast::TypeEnvironment tenv = env;
317                                if ( unify(dstAsPtr->base, pointerType->base, tenv, need, have, open, symtab) ) {
318                                        cost = Cost::safe;
319                                }
320                        }
321                        // else infinity
322                }
323                */
324                else {
325                        int assignResult = ptrsAssignable( pointerType->base, dstAsPtr->base, env );
326                        if ( 0 < assignResult && tq1 <= tq2 ) {
327                                if ( tq1 == tq2 ) {
328                                        cost = Cost::safe;
329                                } else {
330                                        cost = Cost::safe + Cost::safe;
331                                }
332                        } else if ( assignResult < 0 ) {
333                                cost = Cost::unsafe;
334                        } // else Cost::infinity
335                }
336        }
337}
338
339void ConversionCost::postvisit( const ast::ArrayType * arrayType ) {
340        (void)arrayType;
341}
342
343void ConversionCost::postvisit( const ast::ReferenceType * refType ) {
344        assert( nullptr == dynamic_cast< const ast::ReferenceType * >( dst ) );
345
346        cost = costCalc( refType->base, dst, srcIsLvalue, symtab, env );
347
348        // xxx - should qualifiers be considered in pass-by-value?
349        /*
350        if ( refType->base->qualifiers == dst->qualifiers ) {
351                cost.incReference();
352        } else if ( refType->base->qualifiers < dst->qualifiers ) {
353                cost.incSafe();
354        } else {
355                cost.incUnsafe();
356        }
357        */
358        cost.incReference();
359}
360
361void ConversionCost::postvisit( const ast::FunctionType * functionType ) {
362        (void)functionType;
363}
364
365void ConversionCost::postvisit( const ast::EnumInstType * ) {
366        static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };
367        cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
368        // }
369        if ( cost < Cost::unsafe ) {
370                cost.incSafe();
371        }
372}
373
374void ConversionCost::postvisit( const ast::EnumPosType * ) {
375        static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };
376        cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
377        if ( cost < Cost::unsafe ) {
378                cost.incSafe();
379        }
380}
381
382void ConversionCost::postvisit( const ast::TraitInstType * traitInstType ) {
383        (void)traitInstType;
384}
385
386void ConversionCost::postvisit( const ast::TypeInstType * typeInstType ) {
387        if ( const ast::EqvClass * eqv = env.lookup( *typeInstType ) ) {
388                cost = costCalc( eqv->bound, dst, srcIsLvalue, symtab, env );
389        } else if ( const ast::TypeInstType * dstAsInst =
390                        dynamic_cast< const ast::TypeInstType * >( dst ) ) {
391                if ( *typeInstType == *dstAsInst ) {
392                        cost = Cost::zero;
393                }
394        } else if ( const ast::NamedTypeDecl * namedType = symtab.lookupType( typeInstType->name ) ) {
395                const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( namedType );
396                assertf( type, "Unexpected typedef.");
397                if ( type->base ) {
398                        cost = costCalc( type->base, dst, srcIsLvalue, symtab, env ) + Cost::safe;
399                }
400        }
401}
402
403void ConversionCost::postvisit( const ast::TupleType * tupleType ) {
404        Cost c = Cost::zero;
405        if ( const ast::TupleType * dstAsTuple = dynamic_cast< const ast::TupleType * >( dst ) ) {
406                auto srcIt = tupleType->types.begin();
407                auto dstIt = dstAsTuple->types.begin();
408                auto srcEnd = tupleType->types.end();
409                auto dstEnd = dstAsTuple->types.end();
410                while ( srcIt != srcEnd && dstIt != dstEnd ) {
411                        Cost newCost = costCalc( * srcIt++, * dstIt++, srcIsLvalue, symtab, env );
412                        if ( newCost == Cost::infinity ) {
413                                return;
414                        }
415                        c += newCost;
416                }
417                if ( dstIt != dstEnd ) {
418                        cost = Cost::infinity;
419                } else {
420                        cost = c;
421                }
422        }
423}
424
425void ConversionCost::postvisit( const ast::VarArgsType * varArgsType ) {
426        (void)varArgsType;
427        if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) {
428                cost = Cost::zero;
429        }
430}
431
432void ConversionCost::postvisit( const ast::ZeroType * zeroType ) {
433        (void)zeroType;
434        if ( dynamic_cast< const ast::ZeroType * >( dst ) ) {
435                cost = Cost::zero;
436        } else if ( const ast::BasicType * dstAsBasic =
437                        dynamic_cast< const ast::BasicType * >( dst ) ) {
438                int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ];
439                if ( -1 == tableResult ) {
440                        cost = Cost::unsafe;
441                } else {
442                        cost = Cost::zero;
443                        cost.incSafe( tableResult + 1 );
444                        cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );
445                }
446                // this has the effect of letting any expr such as x+0, x+1 to be typed
447                // the same as x, instead of at least int. are we willing to sacrifice this little
448                // bit of coherence with C?
449                // TODO: currently this does not work when no zero/one overloads exist. Find a fix for it.
450                // cost = Cost::zero;
451        } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {
452                cost = Cost::zero;
453                // +1 for zero_t ->, +1 for disambiguation
454                cost.incSafe( maxIntCost + 2 );
455                // assuming 0p is supposed to be used for pointers?
456        }
457}
458
459void ConversionCost::postvisit( const ast::OneType * oneType ) {
460        (void)oneType;
461        if ( dynamic_cast< const ast::OneType * >( dst ) ) {
462                cost = Cost::zero;
463        } else if ( const ast::BasicType * dstAsBasic =
464                        dynamic_cast< const ast::BasicType * >( dst ) ) {
465                int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ];
466                if ( -1 == tableResult ) {
467                        cost = Cost::unsafe;
468                } else {
469                        cost = Cost::zero;
470                        cost.incSafe( tableResult + 1 );
471                        cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );
472                }
473        }
474}
475
476// size_t ConversionCost::traceId = Stats::Heap::new_stacktrace_id("ConversionCost");
477
478} // namespace ResolvExpr
479
480// Local Variables: //
481// tab-width: 4 //
482// mode: c++ //
483// compile-command: "make install" //
484// End: //
Note: See TracBrowser for help on using the repository browser.