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

Last change on this file since 4d5c5b6a was 90e683b, checked in by Andrew Beach <ajbeach@…>, 8 months ago

I set out to do a enum rework. It ended up being much the same and I unwound the core rework. But I hope the new names are a bit clearer and other minor fixes are helpful, so I am keeping those.

  • Property mode set to 100644
File size: 30.1 KB
RevLine 
[a32b204]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//
[c92bdcc]7// ConversionCost.cpp --
[a32b204]8//
9// Author : Richard C. Bilson
10// Created On : Sun May 17 07:06:19 2015
[fb2bde4]11// Last Modified By : Andrew Beach
[1d17939]12// Last Modified On : Wed Jul 29 16:11:00 2020
[cf32116]13// Update Count : 28
[a32b204]14//
[51b73452]15
[c92bdcc]16#include "ConversionCost.hpp"
[ea6332d]17
18#include <cassert> // for assert
19#include <list> // for list, list<>::const_iterator
20#include <string> // for operator==, string
21
[c92bdcc]22#include "ResolvExpr/Cost.hpp" // for Cost
23#include "ResolvExpr/Unify.hpp" // for typesCompatibleIgnoreQualifiers
[5bf3976]24#include "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable
[ef1da0e2]25
[51b73452]26namespace ResolvExpr {
[b46e3bd]27
[5ccb10d]28#if 0
29#define PRINT(x) x
30#else
31#define PRINT(x)
32#endif
[ada4575]33
[13de4478]34namespace {
35
[e15853c]36 // GENERATED START, DO NOT EDIT
[b2ea0cd]37 // GENERATED BY BasicTypes-gen.cpp
[cdcddfe1]38 /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
[e15853c]39 _Bool
[7870799]40 char signed char unsigned char
41 signed short int unsigned short int
42 signed int unsigned int
43 signed long int unsigned long int
44 signed long long int unsigned long long int
45 __int128 unsigned __int128
[2a5345b]46 _Float16
47 _Float16 _Complex
48 _Float32
49 _Float32 _Complex
50 float
51 float _Complex
52 _Float32x
53 _Float32x _Complex
54 _Float64
55 _Float64 _Complex
56 double
57 double _Complex
58 _Float64x
59 _Float64x _Complex
[e15853c]60 __float80
[2a5345b]61 long double
62 long double _Complex
[689d057]63 __float128
[2a5345b]64 _Float128
65 _Float128 _Complex
66 _Float128x
67 _Float128x _Complex
[cdcddfe1]68 */
[e15853c]69 // GENERATED END
[cdcddfe1]70
[e15853c]71 // GENERATED START, DO NOT EDIT
[b2ea0cd]72 // GENERATED BY BasicTypes-gen.cpp
[7a780ad]73 static const int costMatrix[ast::BasicKind::NUMBER_OF_BASIC_TYPES][ast::BasicKind::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
[689d057]74 /* B C SC UC SI USI I UI LI ULI LLI ULLI __ID__UID _FH _FHC _F _FC F FC _FX _FXC _FD _FDC D DC _FDX_FDXC _F80 LD LDC__FLD _FLD_FLDC_FLDX_FLDXC */
[2a5345b]75 /* B */ { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, },
76 /* C */ { -1, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, },
77 /* SC */ { -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, },
78 /* UC */ { -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, },
79 /* SI */ { -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, },
80 /* USI */ { -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, },
81 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, },
82 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, },
83 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, },
84 /* ULI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, },
85 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, },
86 /* ULLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, },
87 /* __ID */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, },
88 /* __UID */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, },
89 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, },
90 /* _FHC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 2, -1, 4, -1, 6, -1, 8, -1, 10, -1, 12, -1, -1, 15, -1, -1, 18, -1, 20, },
91 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, },
92 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 2, -1, 4, -1, 6, -1, 8, -1, 10, -1, -1, 13, -1, -1, 16, -1, 18, },
93 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, },
94 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 2, -1, 4, -1, 6, -1, 8, -1, -1, 11, -1, -1, 14, -1, 16, },
95 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, },
96 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 2, -1, 4, -1, 6, -1, -1, 9, -1, -1, 12, -1, 14, },
97 /* _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, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, },
98 /* _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, 2, -1, 4, -1, -1, 7, -1, -1, 10, -1, 12, },
99 /* 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, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, },
100 /* 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, 2, -1, -1, 5, -1, -1, 8, -1, 10, },
101 /* _FDX */ { -1, -1, -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, 3, 4, 5, 6, 7, 8, 9, },
102 /* _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, 3, -1, -1, 6, -1, 8, },
103 /* _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, 3, 4, 5, 6, 7, },
104 /* 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, 0, 1, 2, 3, 4, 5, 6, },
105 /* 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, 0, -1, -1, 3, -1, 5, },
106 /* __FLD */ { -1, -1, -1, -1, -1, -1, -1, -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, 3, 4, },
107 /* _FLD */ { -1, -1, -1, -1, -1, -1, -1, -1, -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, 3, },
108 /* _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, -1, -1, -1, 0, -1, 2, },
[c309af1]109 /* _FLDX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, },
[ef5b828]110 /* _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, },
[e15853c]111 }; // costMatrix
[2a5345b]112 static const int maxIntCost = 25;
[e15853c]113 // GENERATED END
[cdcddfe1]114 static_assert(
[7a780ad]115 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES,
[cdcddfe1]116 "Missing row in the cost matrix"
117 );
118
[e15853c]119 // GENERATED START, DO NOT EDIT
[b2ea0cd]120 // GENERATED BY BasicTypes-gen.cpp
[7a780ad]121 static const int signMatrix[ast::BasicKind::NUMBER_OF_BASIC_TYPES][ast::BasicKind::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
[689d057]122 /* B C SC UC SI USI I UI LI ULI LLI ULLI __ID__UID _FH _FHC _F _FC F FC _FX _FXC _FD _FDC D DC _FDX_FDXC _F80 LD LDC__FLD _FLD_FLDC_FLDX_FLDXC */
[3a55d9f]123 /* 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, },
124 /* 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, },
125 /* 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, },
126 /* 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, },
127 /* 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, },
[c309af1]128 /* USI */ { -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, },
[3a55d9f]129 /* 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, },
130 /* 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, },
131 /* 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, },
[c309af1]132 /* ULI */ { -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, },
[3a55d9f]133 /* 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, },
[c309af1]134 /* ULLI */ { -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, },
135 /* __ID */ { -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, },
136 /* __UID */ { -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, },
[3a55d9f]137 /* _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, },
[c309af1]138 /* _FHC */ { -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, },
[3a55d9f]139 /* _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, },
140 /* _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, },
141 /* 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, },
142 /* 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, },
143 /* _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, },
144 /* _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, },
[c309af1]145 /* _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, },
[3a55d9f]146 /* _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, },
147 /* 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, },
148 /* 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, },
[c309af1]149 /* _FDX */ { -1, -1, -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, },
[3a55d9f]150 /* _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, },
[689d057]151 /* _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, 0, 0, 0, 0, 0, 0, 0, },
152 /* 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, 0, 0, 0, 0, 0, 0, 0, },
153 /* 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, 0, -1, -1, 0, -1, 0, },
154 /* __FLD */ { -1, -1, -1, -1, -1, -1, -1, -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, },
155 /* _FLD */ { -1, -1, -1, -1, -1, -1, -1, -1, -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, },
156 /* _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, -1, -1, -1, 0, -1, 0, },
[c309af1]157 /* _FLDX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -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, },
[ef5b828]158 /* _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, },
[e15853c]159 }; // signMatrix
160 // GENERATED END
[cdcddfe1]161 static_assert(
[7a780ad]162 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES,
[cdcddfe1]163 "Missing row in the sign matrix"
164 );
[a32b204]165
[cf32116]166 int localPtrsAssignable(const ast::Type * t1, const ast::Type * t2,
167 const ast::SymbolTable &, const ast::TypeEnvironment & env ) {
168 return ptrsAssignable( t1, t2, env );
169 }
[fb2bde4]170}
171
172Cost conversionCost(
[cf32116]173 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
[d3aa55e9]174const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
[fb2bde4]175) {
176 if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
[3e5dd913]177 if ( const ast::EqvClass * eqv = env.lookup( *inst ) ) {
[fb2bde4]178 if ( eqv->bound ) {
[cf32116]179 return conversionCost(src, eqv->bound, srcIsLvalue, symtab, env );
[fb2bde4]180 } else {
181 return Cost::infinity;
182 }
183 } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {
184 const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( named );
185 assertf( type, "Unexpected typedef." );
186 if ( type->base ) {
[cf32116]187 return conversionCost( src, type->base, srcIsLvalue, symtab, env ) + Cost::safe;
[fb2bde4]188 }
189 }
190 }
[251ce80]191 if ( typesCompatibleIgnoreQualifiers( src, dst, env ) ) {
[9d5089e]192 return Cost::zero;
[fb2bde4]193 } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
194 return Cost::safe;
195 } else if ( const ast::ReferenceType * refType =
196 dynamic_cast< const ast::ReferenceType * >( dst ) ) {
[cf32116]197 return convertToReferenceCost( src, refType, srcIsLvalue, symtab, env, localPtrsAssignable );
[fb2bde4]198 } else {
[0bd3faf]199 return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
[fb2bde4]200 }
201}
202
[85855b0]203Cost enumCastCost (
[a7efc96]204 const ast::EnumInstType * src, const ast::EnumInstType * dst,
[85855b0]205 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
206);
207
[cf32116]208static Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
[0f19f5e5]209 int diff, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
[cf32116]210 PtrsCalculation func ) {
[fb2bde4]211 if ( 0 < diff ) {
212 Cost cost = convertToReferenceCost(
[cf32116]213 strict_dynamic_cast< const ast::ReferenceType * >( src )->base, dst,
214 srcIsLvalue, (diff - 1), symtab, env, func );
[fb2bde4]215 cost.incReference();
216 return cost;
217 } else if ( diff < -1 ) {
218 Cost cost = convertToReferenceCost(
219 src, strict_dynamic_cast< const ast::ReferenceType * >( dst )->base,
[cf32116]220 srcIsLvalue, (diff + 1), symtab, env, func );
[fb2bde4]221 cost.incReference();
222 return cost;
223 } else if ( 0 == diff ) {
224 const ast::ReferenceType * srcAsRef = dynamic_cast< const ast::ReferenceType * >( src );
225 const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
226 if ( srcAsRef && dstAsRef ) {
227 ast::CV::Qualifiers tq1 = srcAsRef->base->qualifiers;
228 ast::CV::Qualifiers tq2 = dstAsRef->base->qualifiers;
229 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
[251ce80]230 srcAsRef->base, dstAsRef->base, env ) ) {
[fb2bde4]231 if ( tq1 == tq2 ) {
232 return Cost::zero;
233 } else {
234 return Cost::safe;
235 }
236 } else {
237 int assignResult = func( srcAsRef->base, dstAsRef->base, symtab, env );
238 if ( 0 < assignResult ) {
239 return Cost::safe;
240 } else if ( assignResult < 0 ) {
241 return Cost::unsafe;
242 }
243 }
244 } else {
[0bd3faf]245 return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
[fb2bde4]246 }
[5ccc733]247 if (const ast::EnumInstType * srcAsInst = dynamic_cast< const ast::EnumInstType * >( src )) {
[90e683b]248 if ( srcAsInst->base && srcAsInst->base->is_c_enum() ) {
[5ccc733]249 static const ast::BasicType* integer = new ast::BasicType( ast::BasicKind::UnsignedInt );
250 return ast::Pass<ConversionCost>::read( integer, dst, srcIsLvalue, symtab, env, conversionCost );
251 }
252 }
[fb2bde4]253 } else {
254 assert( -1 == diff );
255 const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
256 assert( dstAsRef );
[5ccc733]257 auto dstBaseType = dstAsRef->base;
258 const ast::Type * newSrc = src;
259 if ( dynamic_cast< const ast::EnumInstType * >( src ) && dstBaseType.as<ast::BasicType>() ) {
260 newSrc = new ast::BasicType( ast::BasicKind::UnsignedInt );
261 }
[00f89a6]262 if (dstAsRef->base->is_const() ) {
263 auto cvtCost = conversionCost(newSrc, dstAsRef->base, srcIsLvalue, symtab, env) ;
264 if (cvtCost == Cost::zero) { // exact match, may use a lvalue src
265 if ( srcIsLvalue ) {
266 if ( src->qualifiers == dstAsRef->base->qualifiers ) {
267 return Cost::reference;
268 } else if ( src->qualifiers < dstAsRef->base->qualifiers ) {
269 return Cost::safe;
270 } else {
271 return Cost::unsafe;
272 }
273 }
274 else {
275 return Cost::reference;
276 }
277 }
278 else { // not exact match, conversion is needed so lvalueness of src does not matter
279 return cvtCost + Cost::reference;
280 }
281 }
[5ccc733]282 if ( typesCompatibleIgnoreQualifiers( newSrc, dstAsRef->base, env ) ) {
[cf32116]283 if ( srcIsLvalue ) {
[fb2bde4]284 if ( src->qualifiers == dstAsRef->base->qualifiers ) {
285 return Cost::reference;
286 } else if ( src->qualifiers < dstAsRef->base->qualifiers ) {
287 return Cost::safe;
288 } else {
289 return Cost::unsafe;
290 }
[00f89a6]291 } else { // rvalue-to-NC-ref conversion
[fb2bde4]292 return Cost::unsafe;
293 }
294 }
295 }
296 return Cost::infinity;
297}
298
299Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dst,
[cf32116]300 bool srcIsLvalue, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
301 PtrsCalculation func ) {
[fb2bde4]302 int sdepth = src->referenceDepth(), ddepth = dst->referenceDepth();
[cf32116]303 return convertToReferenceCost( src, dst, srcIsLvalue, sdepth - ddepth, symtab, env, func );
[fb2bde4]304}
305
[0bd3faf]306void ConversionCost::postvisit( const ast::VoidType * voidType ) {
[fb2bde4]307 (void)voidType;
308 cost = Cost::infinity;
309}
310
[0bd3faf]311void ConversionCost::conversionCostFromBasicToBasic( const ast::BasicType * src, const ast::BasicType* dest ) {
[fc134a48]312 int tableResult = costMatrix[ src->kind ][ dest->kind ];
313 if ( tableResult == -1 ) {
314 cost = Cost::unsafe;
315 } else {
316 cost = Cost::zero;
317 cost.incSafe( tableResult );
318 cost.incSign( signMatrix[ src->kind ][ dest->kind ] );
319 }
320}
321
[0bd3faf]322void ConversionCost::postvisit( const ast::BasicType * basicType ) {
[fb2bde4]323 if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
[fc134a48]324 conversionCostFromBasicToBasic( basicType, dstAsBasic );
[d3aa55e9]325 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
[90e683b]326 if ( dstAsEnumInst->base && dstAsEnumInst->base->is_c_enum() ) {
[5ccc733]327 cost = Cost::safe;
[af746cc]328 }
[fb2bde4]329 }
330}
331
[0bd3faf]332void ConversionCost::postvisit( const ast::PointerType * pointerType ) {
[fb2bde4]333 if ( const ast::PointerType * dstAsPtr = dynamic_cast< const ast::PointerType * >( dst ) ) {
334 ast::CV::Qualifiers tq1 = pointerType->base->qualifiers;
335 ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers;
336 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
[251ce80]337 pointerType->base, dstAsPtr->base, env ) ) {
[fb2bde4]338 if ( tq1 == tq2 ) {
339 cost = Cost::zero;
340 } else {
341 cost = Cost::safe;
342 }
[ef1da0e2]343 }
344 /*
345 else if ( const ast::FunctionType * dstFunc = dstAsPtr->base.as<ast::FunctionType>()) {
346 if (const ast::FunctionType * srcFunc = pointerType->base.as<ast::FunctionType>()) {
347 if (dstFunc->params.empty() && dstFunc->isVarArgs ) {
348 cost = Cost::unsafe; // assign any function to variadic fptr
349 }
350 }
351 else {
352 ast::AssertionSet need, have; // unused
353 ast::OpenVarSet open;
354 env.extractOpenVars(open);
355 ast::TypeEnvironment tenv = env;
356 if ( unify(dstAsPtr->base, pointerType->base, tenv, need, have, open, symtab) ) {
357 cost = Cost::safe;
358 }
359 }
360 // else infinity
361 }
362 */
363 else {
[fb2bde4]364 int assignResult = ptrsAssignable( pointerType->base, dstAsPtr->base, env );
365 if ( 0 < assignResult && tq1 <= tq2 ) {
366 if ( tq1 == tq2 ) {
367 cost = Cost::safe;
368 } else {
369 cost = Cost::safe + Cost::safe;
370 }
371 } else if ( assignResult < 0 ) {
372 cost = Cost::unsafe;
373 } // else Cost::infinity
374 }
375 }
376}
377
[0bd3faf]378void ConversionCost::postvisit( const ast::ArrayType * arrayType ) {
[fb2bde4]379 (void)arrayType;
380}
381
[0bd3faf]382void ConversionCost::postvisit( const ast::ReferenceType * refType ) {
[fb2bde4]383 assert( nullptr == dynamic_cast< const ast::ReferenceType * >( dst ) );
384
[cf32116]385 cost = costCalc( refType->base, dst, srcIsLvalue, symtab, env );
[46da46b]386
387 // xxx - should qualifiers be considered in pass-by-value?
388 /*
[fb2bde4]389 if ( refType->base->qualifiers == dst->qualifiers ) {
390 cost.incReference();
391 } else if ( refType->base->qualifiers < dst->qualifiers ) {
392 cost.incSafe();
393 } else {
394 cost.incUnsafe();
395 }
[46da46b]396 */
397 cost.incReference();
[fb2bde4]398}
399
[0bd3faf]400void ConversionCost::postvisit( const ast::FunctionType * functionType ) {
[fb2bde4]401 (void)functionType;
402}
403
[af746cc]404void ConversionCost::postvisit( const ast::EnumInstType * inst ) {
[85855b0]405 if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
406 cost = enumCastCost(inst, dstInst, symtab, env);
[90e683b]407 } else if ( inst->base->is_c_enum() ) {
[d3aa55e9]408 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
409 cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
[fc1a3e2]410 }
[d3aa55e9]411 // cost.incUnsafe();
[0522ebe]412}
413
[0bd3faf]414void ConversionCost::postvisit( const ast::TraitInstType * traitInstType ) {
[fb2bde4]415 (void)traitInstType;
416}
417
[0bd3faf]418void ConversionCost::postvisit( const ast::TypeInstType * typeInstType ) {
[3e5dd913]419 if ( const ast::EqvClass * eqv = env.lookup( *typeInstType ) ) {
[cf32116]420 cost = costCalc( eqv->bound, dst, srcIsLvalue, symtab, env );
[fb2bde4]421 } else if ( const ast::TypeInstType * dstAsInst =
422 dynamic_cast< const ast::TypeInstType * >( dst ) ) {
[3e5dd913]423 if ( *typeInstType == *dstAsInst ) {
[fb2bde4]424 cost = Cost::zero;
425 }
426 } else if ( const ast::NamedTypeDecl * namedType = symtab.lookupType( typeInstType->name ) ) {
427 const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( namedType );
428 assertf( type, "Unexpected typedef.");
429 if ( type->base ) {
[cf32116]430 cost = costCalc( type->base, dst, srcIsLvalue, symtab, env ) + Cost::safe;
[fb2bde4]431 }
432 }
433}
434
[0bd3faf]435void ConversionCost::postvisit( const ast::TupleType * tupleType ) {
[fb2bde4]436 Cost c = Cost::zero;
437 if ( const ast::TupleType * dstAsTuple = dynamic_cast< const ast::TupleType * >( dst ) ) {
438 auto srcIt = tupleType->types.begin();
439 auto dstIt = dstAsTuple->types.begin();
440 auto srcEnd = tupleType->types.end();
441 auto dstEnd = dstAsTuple->types.end();
442 while ( srcIt != srcEnd && dstIt != dstEnd ) {
[cf32116]443 Cost newCost = costCalc( * srcIt++, * dstIt++, srcIsLvalue, symtab, env );
[fb2bde4]444 if ( newCost == Cost::infinity ) {
445 return;
446 }
447 c += newCost;
448 }
449 if ( dstIt != dstEnd ) {
450 cost = Cost::infinity;
451 } else {
452 cost = c;
453 }
454 }
455}
456
[90e683b]457void ConversionCost::postvisit( const ast::VarArgsType * ) {
[fb2bde4]458 if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) {
459 cost = Cost::zero;
460 }
461}
462
[90e683b]463void ConversionCost::postvisit( const ast::ZeroType * ) {
[fb2bde4]464 if ( dynamic_cast< const ast::ZeroType * >( dst ) ) {
465 cost = Cost::zero;
466 } else if ( const ast::BasicType * dstAsBasic =
467 dynamic_cast< const ast::BasicType * >( dst ) ) {
[7a780ad]468 int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ];
[fb2bde4]469 if ( -1 == tableResult ) {
470 cost = Cost::unsafe;
471 } else {
472 cost = Cost::zero;
473 cost.incSafe( tableResult + 1 );
[7a780ad]474 cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] );
[fb2bde4]475 }
[46da46b]476 // this has the effect of letting any expr such as x+0, x+1 to be typed
477 // the same as x, instead of at least int. are we willing to sacrifice this little
478 // bit of coherence with C?
479 // TODO: currently this does not work when no zero/one overloads exist. Find a fix for it.
480 // cost = Cost::zero;
[2f98fb2]481 } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {
482 cost = Cost::zero;
483 // +1 for zero_t ->, +1 for disambiguation
484 cost.incSafe( maxIntCost + 2 );
[46da46b]485 // assuming 0p is supposed to be used for pointers?
[af746cc]486 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
[90e683b]487 if ( dstAsEnumInst->base && dstAsEnumInst->base->is_c_enum() ) {
[5ccc733]488 cost = Cost::safe;
[af746cc]489 }
[fb2bde4]490 }
491}
492
[90e683b]493void ConversionCost::postvisit( const ast::OneType * ) {
[fb2bde4]494 if ( dynamic_cast< const ast::OneType * >( dst ) ) {
495 cost = Cost::zero;
496 } else if ( const ast::BasicType * dstAsBasic =
[0bd3faf]497 dynamic_cast< const ast::BasicType * >( dst ) ) {
[7a780ad]498 int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ];
[fb2bde4]499 if ( -1 == tableResult ) {
500 cost = Cost::unsafe;
501 } else {
502 cost = Cost::zero;
503 cost.incSafe( tableResult + 1 );
[7a780ad]504 cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] );
[fb2bde4]505 }
[af746cc]506 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
[90e683b]507 if ( dstAsEnumInst->base && dstAsEnumInst->base->is_c_enum() ) {
[5ccc733]508 cost = Cost::safe;
[af746cc]509 }
[9d5089e]510 }
[fb2bde4]511}
[0bd3faf]512
[85855b0]513// (dst) src is safe is src is a subtype of dst, or dst {inline src, ...}
514Cost enumCastCost (
[a7efc96]515 const ast::EnumInstType * src, const ast::EnumInstType * dst,
[85855b0]516 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
517) {
518 auto srcDecl = src->base;
519 auto dstDecl = dst->base;
520 if (srcDecl->name == dstDecl->name) return Cost::safe;
521 Cost minCost = Cost::infinity;
522 for (auto child: dstDecl->inlinedDecl) {
523 Cost c = enumCastCost(src, child, symtab, env) + Cost::safe;
524 if (c<minCost) minCost = c;
525 }
526 return minCost;
527}
528
529
[0bd3faf]530// size_t ConversionCost::traceId = Stats::Heap::new_stacktrace_id("ConversionCost");
[fb2bde4]531
[51b73452]532} // namespace ResolvExpr
[a32b204]533
534// Local Variables: //
535// tab-width: 4 //
536// mode: c++ //
537// compile-command: "make install" //
538// End: //
Note: See TracBrowser for help on using the repository browser.