source: src/ResolvExpr/ConversionCost.cpp@ fc276f3

Last change on this file since fc276f3 was 00f89a6, checked in by Fangren Yu <f37yu@…>, 10 months ago

attempt to fix const reference conversion

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