source: src/ResolvExpr/ConversionCost.cc @ 7abee38

aaron-thesisarm-ehcleanup-dtorsjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpersistent-indexer
Last change on this file since 7abee38 was 7abee38, checked in by tdelisle <tdelisle@…>, 3 years ago

Cleaned some module.mk files and preparing for better stats in the compiler

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