source: src/ResolvExpr/ConversionCost.cc@ 566cc33

Last change on this file since 566cc33 was 13de4478, checked in by Andrew Beach <ajbeach@…>, 17 months ago

Updated files in ResolvExpr to the new indentation style. It seems the remaining places have reason to break from the style.

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