source: src/ResolvExpr/ConversionCost.cc @ b10c39a0

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since b10c39a0 was c378e5e, checked in by Peter A. Buhr <pabuhr@…>, 5 years ago

pack 7 resolver Costs into single word

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