source: src/ResolvExpr/ConversionCost.cc @ e15853c

aaron-thesisarm-ehcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpersistent-indexerpthread-emulationqualifiedEnum
Last change on this file since e15853c was e15853c, checked in by Peter A. Buhr <pabuhr@…>, 4 years ago

remove leading underscores in enums for _FloatNN and _Bool

  • Property mode set to 100644
File size: 35.3 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 : Peter A. Buhr
12// Last Modified On : Wed Feb 13 23:04:51 2019
13// Update Count     : 22
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/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
24#include "SymTab/Indexer.h"              // for Indexer
25#include "SynTree/Declaration.h"         // for TypeDecl, NamedTypeDecl
26#include "SynTree/Type.h"                // for Type, BasicType, TypeInstType
27#include "typeops.h"                     // for typesCompatibleIgnoreQualifiers
28
29namespace ResolvExpr {
30        const Cost Cost::zero =      Cost{  0,  0,  0,  0,  0,  0,  0 };
31        const Cost Cost::infinity =  Cost{ -1, -1, -1, -1, -1,  1, -1 };
32        const Cost Cost::unsafe =    Cost{  1,  0,  0,  0,  0,  0,  0 };
33        const Cost Cost::poly =      Cost{  0,  1,  0,  0,  0,  0,  0 };
34        const Cost Cost::safe =      Cost{  0,  0,  1,  0,  0,  0,  0 };
35        const Cost Cost::sign =      Cost{  0,  0,  0,  1,  0,  0,  0 };
36        const Cost Cost::var =       Cost{  0,  0,  0,  0,  1,  0,  0 };
37        const Cost Cost::spec =      Cost{  0,  0,  0,  0,  0, -1,  0 };
38        const Cost Cost::reference = Cost{  0,  0,  0,  0,  0,  0,  1 };
39
40#if 0
41#define PRINT(x) x
42#else
43#define PRINT(x)
44#endif
45        Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
46                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
47                        PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
48                        if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
49                                if ( eqvClass->type ) {
50                                        return conversionCost( src, eqvClass->type, indexer, env );
51                                } else {
52                                        return Cost::infinity;
53                                }
54                        } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
55                                PRINT( std::cerr << " found" << std::endl; )
56                                TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
57                                // all typedefs should be gone by this point
58                                assert( type );
59                                if ( type->base ) {
60                                        return conversionCost( src, type->base, indexer, env ) + Cost::safe;
61                                } // if
62                        } // if
63                        PRINT( std::cerr << " not found" << std::endl; )
64                } // if
65                PRINT(
66                        std::cerr << "src is ";
67                        src->print( std::cerr );
68                        std::cerr << std::endl << "dest is ";
69                        dest->print( std::cerr );
70                        std::cerr << std::endl << "env is" << std::endl;
71                        env.print( std::cerr, 8 );
72                )
73                if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
74                        PRINT( std::cerr << "compatible!" << std::endl; )
75                        return Cost::zero;
76                } else if ( dynamic_cast< VoidType* >( dest ) ) {
77                        return Cost::safe;
78                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
79                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
80                        return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
81                                return ptrsAssignable( t1, t2, env );
82                        });
83                } else {
84                        PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
85                        src->accept( converter );
86                        if ( converter.pass.get_cost() == Cost::infinity ) {
87                                return Cost::infinity;
88                        } else {
89                                return converter.pass.get_cost() + Cost::zero;
90                        } // if
91                } // if
92        }
93
94        Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
95                PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
96                if ( diff > 0 ) {
97                        // TODO: document this
98                        Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
99                        cost.incReference();
100                        return cost;
101                } else if ( diff < -1 ) {
102                        // TODO: document this
103                        Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
104                        cost.incReference();
105                        return cost;
106                } else if ( diff == 0 ) {
107                        ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src );
108                        ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
109                        if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
110                                PRINT( std::cerr << "converting between references" << std::endl; )
111                                Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers();
112                                Type::Qualifiers tq2 = destAsRef->base->get_qualifiers();
113                                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
114                                        PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
115                                        if ( tq1 == tq2 ) {
116                                                // types are the same
117                                                return Cost::zero;
118                                        } else {
119                                                // types are the same, except otherPointer has more qualifiers
120                                                return Cost::safe;
121                                        }
122                                } else {  // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
123                                        int assignResult = func( srcAsRef->base, destAsRef->base, indexer, env );
124                                        PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; )
125                                        if ( assignResult > 0 ) {
126                                                return Cost::safe;
127                                        } else if ( assignResult < 0 ) {
128                                                return Cost::unsafe;
129                                        } // if
130                                } // if
131                        } else {
132                                PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
133                                PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
134                                src->accept( converter );
135                                return converter.pass.get_cost();
136                        } // if
137                } else {
138                        ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
139                        assert( diff == -1 && destAsRef );
140                        PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
141                        if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
142                                PRINT( std::cerr << "converting compatible base type" << std::endl; )
143                                if ( src->get_lvalue() ) {
144                                        PRINT(
145                                                std::cerr << "lvalue to reference conversion" << std::endl;
146                                                std::cerr << src << " => " << destAsRef << std::endl;
147                                        )
148                                        // lvalue-to-reference conversion:  cv lvalue T => cv T &
149                                        if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
150                                                return Cost::reference; // cost needs to be non-zero to add cast
151                                        } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
152                                                return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
153                                        } else {
154                                                return Cost::unsafe;
155                                        } // if
156                                } else if ( destAsRef->base->get_const() ) {
157                                        PRINT( std::cerr << "rvalue to const ref conversion" << std::endl; )
158                                        // rvalue-to-const-reference conversion: T => const T &
159                                        return Cost::safe;
160                                } else {
161                                        PRINT( std::cerr << "rvalue to non-const reference conversion" << std::endl; )
162                                        // rvalue-to-reference conversion: T => T &
163                                        return Cost::unsafe;
164                                } // if
165                        } // if
166                        PRINT( std::cerr << "attempting to convert from incompatible base type -- fail" << std::endl; )
167                }
168                return Cost::infinity;
169        }
170
171        Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
172                int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
173                Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
174                PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; )
175                return cost;
176        }
177
178        ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
179                : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
180        }
181#if 0
182/*
183            Old
184            ===
185           Double
186             |
187           Float
188             |
189           ULong
190           /   \
191        UInt    Long
192           \   /
193            Int
194             |
195           Ushort
196             |
197           Short
198             |
199           Uchar
200           /   \
201        Schar   Char
202
203                                New
204                                ===
205                       +-----LongDoubleComplex--+
206           LongDouble--+          |             +-LongDoubleImag
207             |         +---DoubleComplex---+         |
208           Double------+        |          +----DoubleImag
209             |           +-FloatComplex-+            |
210           Float---------+              +-------FloatImag
211             |
212          ULongLong
213             |
214          LongLong
215             |
216           ULong
217           /   \
218        UInt    Long
219           \   /
220            Int
221             |
222           Ushort
223             |
224           Short
225             |
226           Uchar
227           /   \
228        Schar   Char
229           \   /
230            Bool
231*/
232
233        static const int costMatrix[][ BasicType::NUMBER_OF_BASIC_TYPES ] = {
234        /* Src \ Dest:  Bool    Char    SChar   UChar   Short   UShort  Int     UInt    Long    ULong   LLong   ULLong  Float   Double  LDbl    FCplex  DCplex  LDCplex FImag   DImag   LDImag  I128,   U128, F80, F128 */
235                /* Bool */      { 0,    1,              1,              2,              3,              4,              5,              6,              6,              7,              8,              9,              12,             13,             14,             12,             13,             14,             -1,             -1,             -1,             10,             11,       14,   15},
236                /* Char */      { -1,   0,              -1,             1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,       13,   14},
237                /* SChar */ { -1,       -1,             0,              1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,       13,   14},
238                /* UChar */ { -1,       -1,             -1,             0,              1,              2,              3,              4,              4,              5,              6,              7,              10,             11,             12,             10,             11,             12,             -1,             -1,             -1,             8,              9,        12,   13},
239                /* Short */ { -1,       -1,             -1,             -1,             0,              1,              2,              3,              3,              4,              5,              6,              9,              10,             11,             9,              10,             11,             -1,             -1,             -1,             7,              8,        11,   12},
240                /* UShort */{ -1,       -1,             -1,             -1,             -1,             0,              1,              2,              2,              3,              4,              5,              8,              9,              10,             8,              9,              10,             -1,             -1,             -1,             6,              7,        10,   11},
241                /* Int */       { -1,   -1,             -1,             -1,             -1,             -1,             0,              1,              1,              2,              3,              4,              7,              8,              9,              7,              8,              9,              -1,             -1,             -1,             5,              6,        9,    10},
242                /* UInt */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,        8,    9},
243                /* Long */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,        8,    9},
244                /* ULong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              5,              6,              7,              5,              6,              7,              -1,             -1,             -1,             3,              4,        7,    8},
245                /* LLong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              4,              5,              6,              4,              5,              6,              -1,             -1,             -1,             2,              3,        6,    7},
246                /* ULLong */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              3,              4,              5,              3,              4,              5,              -1,             -1,             -1,             1,              2,        5,    6},
247
248                /* Float */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              1,              2,              3,              -1,             -1,             -1,             -1,             -1,       2,    3},
249                /* Double */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             1,              2,              -1,             -1,             -1,             -1,             -1,       1,    2},
250                /* LDbl */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             1,              -1,             -1,             -1,             -1,             -1,       -1,   1},
251                /* FCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              -1,             -1,             -1,             -1,             -1,       -1,   -1},
252                /* DCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             -1,             -1,             -1,             -1,       -1,   -1},
253                /* LDCplex */{ -1,      -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             -1,             -1,             -1,       -1,   -1},
254                /* FImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              0,              1,              2,              -1,             -1,       -1,   -1},
255                /* DImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              -1,             0,              1,              -1,             -1,       -1,   -1},
256                /* LDImag */{ -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},
257
258                /* I128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             2,              3,              4,              3,              4,              5,              -1,             -1,             -1,             0,              1,        4,    4},
259                /* U128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              2,              3,              4,              -1,             -1,             -1,             -1,             0,        3,    3},
260
261                /* F80 */       { -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},
262                /* F128 */      { -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},
263        };
264        static_assert(
265                sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
266                "Each basic type kind should have a corresponding row in the cost matrix"
267        );
268#endif
269
270        // GENERATED START, DO NOT EDIT
271        /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
272                                 _Bool
273        char                signed char         unsigned char       
274                  signed short int         unsigned short int       
275                  signed int               unsigned int             
276                  signed long int          unsigned long int       
277                  signed long long int     unsigned long long int   
278                  __int128                 unsigned __int128       
279                  _Float16                 _Float16 _Complex       
280                  _Float32                 _Float32 _Complex       
281                  float                    float _Complex           
282                  _Float32x                _Float32x _Complex       
283                  _Float64                 _Float64 _Complex       
284                  double                   double _Complex         
285                  _Float64x                _Float64x _Complex       
286                             __float80
287                  _Float128                _Float128 _Complex       
288                            __float128
289                  long double              long double _Complex     
290                  _Float128x               _Float128x _Complex     
291        */
292        // GENERATED END
293
294        // GENERATED START, DO NOT EDIT
295        static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
296                /*          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 */
297                /*     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, 
298                /*     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, 
299                /*    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, 
300                /*    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, 
301                /*    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, 
302                /*   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, 
303                /*     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, 
304                /*    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, 
305                /*    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, 
306                /*   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, 
307                /*   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, 
308                /*  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, 
309                /*    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, 
310                /*   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, 
311                /*   _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, 
312                /*   _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, 
313                /*    _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, 
314                /*   _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, 
315                /*     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, 
316                /*    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, 
317                /*   _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, 
318                /*  _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, 
319                /*    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, 
320                /*  _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, 
321                /*     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, 
322                /*    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, 
323                /*  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, 
324                /* _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, 
325                /*   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, 
326                /*   _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, 
327                /* _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, 
328                /*    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, 
329                /*    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, 
330                /*   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, 
331                /*  _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, 
332                /*_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, 
333        }; // costMatrix
334        // GENERATED END
335        static_assert(
336                sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
337                "Missing row in the cost matrix"
338        );
339
340        // GENERATED START, DO NOT EDIT
341        static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
342                /*          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 */
343                /*     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, 
344                /*     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, 
345                /*    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, 
346                /*    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, 
347                /*    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, 
348                /*   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, 
349                /*     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, 
350                /*    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, 
351                /*    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, 
352                /*   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, 
353                /*   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, 
354                /*  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, 
355                /*    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, 
356                /*   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, 
357                /*   _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, 
358                /*   _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, 
359                /*    _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, 
360                /*   _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, 
361                /*     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, 
362                /*    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, 
363                /*   _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, 
364                /*  _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, 
365                /*    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, 
366                /*  _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, 
367                /*     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, 
368                /*    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, 
369                /*  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, 
370                /* _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, 
371                /*   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, 
372                /*   _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, 
373                /* _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, 
374                /*    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, 
375                /*    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, 
376                /*   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, 
377                /*  _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, 
378                /*_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, 
379        }; // signMatrix
380        // GENERATED END
381        static_assert(
382                sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
383                "Missing row in the sign matrix"
384        );
385
386        void ConversionCost::postvisit( VoidType * ) {
387                cost = Cost::infinity;
388        }
389
390        void ConversionCost::postvisit(BasicType *basicType) {
391                if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
392                        int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
393                        if ( tableResult == -1 ) {
394                                cost = Cost::unsafe;
395                        } else {
396                                cost = Cost::zero;
397                                cost.incSafe( tableResult );
398                                cost.incSign( signMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ] );
399                        } // if
400                } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
401                        // xxx - not positive this is correct, but appears to allow casting int => enum
402                        cost = Cost::unsafe;
403                } // if
404                // no cases for zero_t/one_t because it should not be possible to convert int, etc. to zero_t/one_t.
405        }
406
407        void ConversionCost::postvisit( PointerType * pointerType ) {
408                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
409                        PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
410                        Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
411                        Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
412                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
413                                PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
414                                if ( tq1 == tq2 ) {
415                                        // types are the same
416                                        cost = Cost::zero;
417                                } else {
418                                        // types are the same, except otherPointer has more qualifiers
419                                        cost = Cost::safe;
420                                } // if
421                        } else {
422                                int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
423                                PRINT( std::cerr << " :: " << assignResult << std::endl; )
424                                if ( assignResult > 0 && tq1 <= tq2 ) {
425                                        // xxx - want the case where qualifiers are added to be more expensive than the case where qualifiers are the same. Is 1 safe vs. 2 safe correct?
426                                        if ( tq1 == tq2 ) {
427                                                cost = Cost::safe;
428                                        } else if ( tq1 < tq2 ) {
429                                                cost = Cost::safe+Cost::safe;
430                                        }
431                                } else if ( assignResult < 0 ) {
432                                        cost = Cost::unsafe;
433                                } // if
434                                // assignResult == 0 means Cost::Infinity
435                        } // if
436                        // case case for zero_t because it should not be possible to convert pointers to zero_t.
437                } // if
438        }
439
440        void ConversionCost::postvisit( ArrayType * ) {}
441
442        void ConversionCost::postvisit( ReferenceType * refType ) {
443                // Note: dest can never be a reference, since it would have been caught in an earlier check
444                assert( ! dynamic_cast< ReferenceType * >( dest ) );
445                // convert reference to rvalue: cv T1 & => T2
446                // recursively compute conversion cost from T1 to T2.
447                // cv can be safely dropped because of 'implicit dereference' behavior.
448                cost = costFunc( refType->base, dest, indexer, env );
449                if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
450                        cost.incReference();  // prefer exact qualifiers
451                } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
452                        cost.incSafe(); // then gaining qualifiers
453                } else {
454                        cost.incUnsafe(); // lose qualifiers as last resort
455                }
456                PRINT( std::cerr << refType << " ==> " << dest << " " << cost << std::endl; )
457        }
458
459        void ConversionCost::postvisit( FunctionType * ) {}
460
461        void ConversionCost::postvisit( StructInstType * inst ) {
462                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
463                        if ( inst->name == destAsInst->name ) {
464                                cost = Cost::zero;
465                        } // if
466                } // if
467        }
468
469        void ConversionCost::postvisit( UnionInstType * inst ) {
470                if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
471                        if ( inst->name == destAsInst->name ) {
472                                cost = Cost::zero;
473                        } // if
474                } // if
475        }
476
477        void ConversionCost::postvisit( EnumInstType * ) {
478                static Type::Qualifiers q;
479                static BasicType integer( q, BasicType::SignedInt );
480                cost = costFunc( &integer, dest, indexer, env );  // safe if dest >= int
481                if ( cost < Cost::unsafe ) {
482                        cost.incSafe();
483                } // if
484        }
485
486        void ConversionCost::postvisit( TraitInstType * ) {}
487
488        void ConversionCost::postvisit( TypeInstType *inst ) {
489                if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) {
490                        cost = costFunc( eqvClass->type, dest, indexer, env );
491                } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
492                        if ( inst->name == destAsInst->name ) {
493                                cost = Cost::zero;
494                        }
495                } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
496                        TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
497                        // all typedefs should be gone by this point
498                        assert( type );
499                        if ( type->base ) {
500                                cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;
501                        } // if
502                } // if
503        }
504
505        void ConversionCost::postvisit( TupleType * tupleType ) {
506                Cost c = Cost::zero;
507                if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
508                        std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
509                        std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
510                        while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
511                                Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
512                                if ( newCost == Cost::infinity ) {
513                                        return;
514                                } // if
515                                c += newCost;
516                        } // while
517                        if ( destIt != destAsTuple->types.end() ) {
518                                cost = Cost::infinity;
519                        } else {
520                                cost = c;
521                        } // if
522                } // if
523        }
524
525        void ConversionCost::postvisit( VarArgsType * ) {
526                if ( dynamic_cast< VarArgsType* >( dest ) ) {
527                        cost = Cost::zero;
528                }
529        }
530
531        void ConversionCost::postvisit( ZeroType * ) {
532                if ( dynamic_cast< ZeroType * >( dest ) ) {
533                        cost = Cost::zero;
534                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
535                        // copied from visit(BasicType*) for signed int, but +1 for safe conversions
536                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
537                        if ( tableResult == -1 ) {
538                                cost = Cost::unsafe;
539                        } else {
540                                cost = Cost::zero;
541                                cost.incSafe( tableResult + 1 );
542                                cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
543                        } // if
544                } else if ( dynamic_cast< PointerType* >( dest ) ) {
545                        cost = Cost::safe;
546                } // if
547        }
548
549        void ConversionCost::postvisit( OneType * ) {
550                if ( dynamic_cast< OneType * >( dest ) ) {
551                        cost = Cost::zero;
552                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
553                        // copied from visit(BasicType*) for signed int, but +1 for safe conversions
554                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
555                        if ( tableResult == -1 ) {
556                                cost = Cost::unsafe;
557                        } else {
558                                cost = Cost::zero;
559                                cost.incSafe( tableResult + 1 );
560                                cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
561                        } // if
562                } // if
563        }
564} // namespace ResolvExpr
565
566// Local Variables: //
567// tab-width: 4 //
568// mode: c++ //
569// compile-command: "make install" //
570// End: //
Note: See TracBrowser for help on using the repository browser.