source: src/ResolvExpr/ConversionCost.cpp@ c01a2fd

Last change on this file since c01a2fd was a7efc96, checked in by Andrew Beach <ajbeach@…>, 13 months ago

Made sure a variable is always initialized and removed some trailing whitespace.

  • Property mode set to 100644
File size: 29.5 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 ( typesCompatibleIgnoreQualifiers( newSrc, dstAsRef->base, env ) ) {
253 if ( srcIsLvalue ) {
254 if ( src->qualifiers == dstAsRef->base->qualifiers ) {
255 return Cost::reference;
256 } else if ( src->qualifiers < dstAsRef->base->qualifiers ) {
257 return Cost::safe;
258 } else {
259 return Cost::unsafe;
260 }
261 } else if ( dstAsRef->base->is_const() ) {
262 return Cost::safe;
263 } else {
264 return Cost::unsafe;
265 }
266 }
267 }
268 return Cost::infinity;
269}
270
271Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dst,
272 bool srcIsLvalue, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
273 PtrsCalculation func ) {
274 int sdepth = src->referenceDepth(), ddepth = dst->referenceDepth();
275 return convertToReferenceCost( src, dst, srcIsLvalue, sdepth - ddepth, symtab, env, func );
276}
277
278void ConversionCost::postvisit( const ast::VoidType * voidType ) {
279 (void)voidType;
280 cost = Cost::infinity;
281}
282
283void ConversionCost::conversionCostFromBasicToBasic( const ast::BasicType * src, const ast::BasicType* dest ) {
284 int tableResult = costMatrix[ src->kind ][ dest->kind ];
285 if ( tableResult == -1 ) {
286 cost = Cost::unsafe;
287 } else {
288 cost = Cost::zero;
289 cost.incSafe( tableResult );
290 cost.incSign( signMatrix[ src->kind ][ dest->kind ] );
291 }
292}
293
294void ConversionCost::postvisit( const ast::BasicType * basicType ) {
295 if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
296 conversionCostFromBasicToBasic( basicType, dstAsBasic );
297 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
298 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
299 cost = Cost::safe;
300 }
301 }
302}
303
304void ConversionCost::postvisit( const ast::PointerType * pointerType ) {
305 if ( const ast::PointerType * dstAsPtr = dynamic_cast< const ast::PointerType * >( dst ) ) {
306 ast::CV::Qualifiers tq1 = pointerType->base->qualifiers;
307 ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers;
308 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
309 pointerType->base, dstAsPtr->base, env ) ) {
310 if ( tq1 == tq2 ) {
311 cost = Cost::zero;
312 } else {
313 cost = Cost::safe;
314 }
315 }
316 /*
317 else if ( const ast::FunctionType * dstFunc = dstAsPtr->base.as<ast::FunctionType>()) {
318 if (const ast::FunctionType * srcFunc = pointerType->base.as<ast::FunctionType>()) {
319 if (dstFunc->params.empty() && dstFunc->isVarArgs ) {
320 cost = Cost::unsafe; // assign any function to variadic fptr
321 }
322 }
323 else {
324 ast::AssertionSet need, have; // unused
325 ast::OpenVarSet open;
326 env.extractOpenVars(open);
327 ast::TypeEnvironment tenv = env;
328 if ( unify(dstAsPtr->base, pointerType->base, tenv, need, have, open, symtab) ) {
329 cost = Cost::safe;
330 }
331 }
332 // else infinity
333 }
334 */
335 else {
336 int assignResult = ptrsAssignable( pointerType->base, dstAsPtr->base, env );
337 if ( 0 < assignResult && tq1 <= tq2 ) {
338 if ( tq1 == tq2 ) {
339 cost = Cost::safe;
340 } else {
341 cost = Cost::safe + Cost::safe;
342 }
343 } else if ( assignResult < 0 ) {
344 cost = Cost::unsafe;
345 } // else Cost::infinity
346 }
347 }
348}
349
350void ConversionCost::postvisit( const ast::ArrayType * arrayType ) {
351 (void)arrayType;
352}
353
354void ConversionCost::postvisit( const ast::ReferenceType * refType ) {
355 assert( nullptr == dynamic_cast< const ast::ReferenceType * >( dst ) );
356
357 cost = costCalc( refType->base, dst, srcIsLvalue, symtab, env );
358
359 // xxx - should qualifiers be considered in pass-by-value?
360 /*
361 if ( refType->base->qualifiers == dst->qualifiers ) {
362 cost.incReference();
363 } else if ( refType->base->qualifiers < dst->qualifiers ) {
364 cost.incSafe();
365 } else {
366 cost.incUnsafe();
367 }
368 */
369 cost.incReference();
370}
371
372void ConversionCost::postvisit( const ast::FunctionType * functionType ) {
373 (void)functionType;
374}
375
376void ConversionCost::postvisit( const ast::EnumInstType * inst ) {
377 if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
378 cost = enumCastCost(inst, dstInst, symtab, env);
379 } else if ( !inst->base->isCfa ) {
380 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
381 cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
382 }
383 // cost.incUnsafe();
384}
385
386void ConversionCost::postvisit( const ast::TraitInstType * traitInstType ) {
387 (void)traitInstType;
388}
389
390void ConversionCost::postvisit( const ast::TypeInstType * typeInstType ) {
391 if ( const ast::EqvClass * eqv = env.lookup( *typeInstType ) ) {
392 cost = costCalc( eqv->bound, dst, srcIsLvalue, symtab, env );
393 } else if ( const ast::TypeInstType * dstAsInst =
394 dynamic_cast< const ast::TypeInstType * >( dst ) ) {
395 if ( *typeInstType == *dstAsInst ) {
396 cost = Cost::zero;
397 }
398 } else if ( const ast::NamedTypeDecl * namedType = symtab.lookupType( typeInstType->name ) ) {
399 const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( namedType );
400 assertf( type, "Unexpected typedef.");
401 if ( type->base ) {
402 cost = costCalc( type->base, dst, srcIsLvalue, symtab, env ) + Cost::safe;
403 }
404 }
405}
406
407void ConversionCost::postvisit( const ast::TupleType * tupleType ) {
408 Cost c = Cost::zero;
409 if ( const ast::TupleType * dstAsTuple = dynamic_cast< const ast::TupleType * >( dst ) ) {
410 auto srcIt = tupleType->types.begin();
411 auto dstIt = dstAsTuple->types.begin();
412 auto srcEnd = tupleType->types.end();
413 auto dstEnd = dstAsTuple->types.end();
414 while ( srcIt != srcEnd && dstIt != dstEnd ) {
415 Cost newCost = costCalc( * srcIt++, * dstIt++, srcIsLvalue, symtab, env );
416 if ( newCost == Cost::infinity ) {
417 return;
418 }
419 c += newCost;
420 }
421 if ( dstIt != dstEnd ) {
422 cost = Cost::infinity;
423 } else {
424 cost = c;
425 }
426 }
427}
428
429void ConversionCost::postvisit( const ast::VarArgsType * varArgsType ) {
430 (void)varArgsType;
431 if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) {
432 cost = Cost::zero;
433 }
434}
435
436void ConversionCost::postvisit( const ast::ZeroType * zeroType ) {
437 (void)zeroType;
438 if ( dynamic_cast< const ast::ZeroType * >( dst ) ) {
439 cost = Cost::zero;
440 } else if ( const ast::BasicType * dstAsBasic =
441 dynamic_cast< const ast::BasicType * >( dst ) ) {
442 int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ];
443 if ( -1 == tableResult ) {
444 cost = Cost::unsafe;
445 } else {
446 cost = Cost::zero;
447 cost.incSafe( tableResult + 1 );
448 cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] );
449 }
450 // this has the effect of letting any expr such as x+0, x+1 to be typed
451 // the same as x, instead of at least int. are we willing to sacrifice this little
452 // bit of coherence with C?
453 // TODO: currently this does not work when no zero/one overloads exist. Find a fix for it.
454 // cost = Cost::zero;
455 } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {
456 cost = Cost::zero;
457 // +1 for zero_t ->, +1 for disambiguation
458 cost.incSafe( maxIntCost + 2 );
459 // assuming 0p is supposed to be used for pointers?
460 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
461 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
462 cost = Cost::safe;
463 }
464 }
465}
466
467void ConversionCost::postvisit( const ast::OneType * oneType ) {
468 (void)oneType;
469 if ( dynamic_cast< const ast::OneType * >( dst ) ) {
470 cost = Cost::zero;
471 } else if ( const ast::BasicType * dstAsBasic =
472 dynamic_cast< const ast::BasicType * >( dst ) ) {
473 int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ];
474 if ( -1 == tableResult ) {
475 cost = Cost::unsafe;
476 } else {
477 cost = Cost::zero;
478 cost.incSafe( tableResult + 1 );
479 cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] );
480 }
481 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
482 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa ) {
483 cost = Cost::safe;
484 }
485 }
486}
487
488// (dst) src is safe is src is a subtype of dst, or dst {inline src, ...}
489Cost enumCastCost (
490 const ast::EnumInstType * src, const ast::EnumInstType * dst,
491 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
492) {
493 auto srcDecl = src->base;
494 auto dstDecl = dst->base;
495 if (srcDecl->name == dstDecl->name) return Cost::safe;
496 Cost minCost = Cost::infinity;
497 for (auto child: dstDecl->inlinedDecl) {
498 Cost c = enumCastCost(src, child, symtab, env) + Cost::safe;
499 if (c<minCost) minCost = c;
500 }
501 return minCost;
502}
503
504
505// size_t ConversionCost::traceId = Stats::Heap::new_stacktrace_id("ConversionCost");
506
507} // namespace ResolvExpr
508
509// Local Variables: //
510// tab-width: 4 //
511// mode: c++ //
512// compile-command: "make install" //
513// End: //
Note: See TracBrowser for help on using the repository browser.