source: src/ResolvExpr/ConversionCost.cpp@ d5efcb7

Last change on this file since d5efcb7 was 85855b0, checked in by JiadaL <j82liang@…>, 16 months ago
  1. Implement enum cast; 2. Change valueE so that opague enum returns quasi_void; 3. change enum hiding interpretation and pass visiting scheme
  • Property mode set to 100644
File size: 29.0 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
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
[e15853c]53 __float80
[7870799]54 _Float128 _Float128 _Complex
[e15853c]55 __float128
[7870799]56 long double long double _Complex
57 _Float128x _Float128x _Complex
[cdcddfe1]58 */
[e15853c]59 // GENERATED END
[cdcddfe1]60
[e15853c]61 // GENERATED START, DO NOT EDIT
[b2ea0cd]62 // GENERATED BY BasicTypes-gen.cpp
[7a780ad]63 static const int costMatrix[ast::BasicKind::NUMBER_OF_BASIC_TYPES][ast::BasicKind::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
[3a55d9f]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, },
[ef5b828]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, },
[e15853c]101 }; // costMatrix
[1c9568f0]102 static const int maxIntCost = 15;
[e15853c]103 // GENERATED END
[cdcddfe1]104 static_assert(
[7a780ad]105 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES,
[cdcddfe1]106 "Missing row in the cost matrix"
107 );
108
[e15853c]109 // GENERATED START, DO NOT EDIT
[b2ea0cd]110 // GENERATED BY BasicTypes-gen.cpp
[7a780ad]111 static const int signMatrix[ast::BasicKind::NUMBER_OF_BASIC_TYPES][ast::BasicKind::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
[3a55d9f]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, },
[ef5b828]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, },
[e15853c]149 }; // signMatrix
150 // GENERATED END
[cdcddfe1]151 static_assert(
[7a780ad]152 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == ast::BasicKind::NUMBER_OF_BASIC_TYPES * ast::BasicKind::NUMBER_OF_BASIC_TYPES,
[cdcddfe1]153 "Missing row in the sign matrix"
154 );
[a32b204]155
[cf32116]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 }
[fb2bde4]160}
161
162Cost conversionCost(
[cf32116]163 const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
164 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
[fb2bde4]165) {
166 if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
[3e5dd913]167 if ( const ast::EqvClass * eqv = env.lookup( *inst ) ) {
[fb2bde4]168 if ( eqv->bound ) {
[cf32116]169 return conversionCost(src, eqv->bound, srcIsLvalue, symtab, env );
[fb2bde4]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 ) {
[cf32116]177 return conversionCost( src, type->base, srcIsLvalue, symtab, env ) + Cost::safe;
[fb2bde4]178 }
179 }
180 }
[251ce80]181 if ( typesCompatibleIgnoreQualifiers( src, dst, env ) ) {
[9d5089e]182 return Cost::zero;
[fb2bde4]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 ) ) {
[cf32116]187 return convertToReferenceCost( src, refType, srcIsLvalue, symtab, env, localPtrsAssignable );
[fb2bde4]188 } else {
[0bd3faf]189 return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
[fb2bde4]190 }
191}
192
[85855b0]193Cost enumCastCost (
194 const ast::EnumInstType * src, const ast::EnumInstType * dst,
195 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
196);
197
[cf32116]198static Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
[0f19f5e5]199 int diff, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
[cf32116]200 PtrsCalculation func ) {
[fb2bde4]201 if ( 0 < diff ) {
202 Cost cost = convertToReferenceCost(
[cf32116]203 strict_dynamic_cast< const ast::ReferenceType * >( src )->base, dst,
204 srcIsLvalue, (diff - 1), symtab, env, func );
[fb2bde4]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,
[cf32116]210 srcIsLvalue, (diff + 1), symtab, env, func );
[fb2bde4]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(
[251ce80]220 srcAsRef->base, dstAsRef->base, env ) ) {
[fb2bde4]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 {
[0bd3faf]235 return ast::Pass<ConversionCost>::read( src, dst, srcIsLvalue, symtab, env, conversionCost );
[fb2bde4]236 }
237 } else {
238 assert( -1 == diff );
239 const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
240 assert( dstAsRef );
[251ce80]241 if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, env ) ) {
[cf32116]242 if ( srcIsLvalue ) {
[fb2bde4]243 if ( src->qualifiers == dstAsRef->base->qualifiers ) {
244 return Cost::reference;
245 } else if ( src->qualifiers < dstAsRef->base->qualifiers ) {
246 return Cost::safe;
247 } else {
248 return Cost::unsafe;
249 }
250 } else if ( dstAsRef->base->is_const() ) {
251 return Cost::safe;
252 } else {
253 return Cost::unsafe;
254 }
255 }
256 }
257 return Cost::infinity;
258}
259
260Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dst,
[cf32116]261 bool srcIsLvalue, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
262 PtrsCalculation func ) {
[fb2bde4]263 int sdepth = src->referenceDepth(), ddepth = dst->referenceDepth();
[cf32116]264 return convertToReferenceCost( src, dst, srcIsLvalue, sdepth - ddepth, symtab, env, func );
[fb2bde4]265}
266
[0bd3faf]267void ConversionCost::postvisit( const ast::VoidType * voidType ) {
[fb2bde4]268 (void)voidType;
269 cost = Cost::infinity;
270}
271
[0bd3faf]272void ConversionCost::conversionCostFromBasicToBasic( const ast::BasicType * src, const ast::BasicType* dest ) {
[fc134a48]273 int tableResult = costMatrix[ src->kind ][ dest->kind ];
274 if ( tableResult == -1 ) {
275 cost = Cost::unsafe;
276 } else {
277 cost = Cost::zero;
278 cost.incSafe( tableResult );
279 cost.incSign( signMatrix[ src->kind ][ dest->kind ] );
280 }
281}
282
[0bd3faf]283void ConversionCost::postvisit( const ast::BasicType * basicType ) {
[fb2bde4]284 if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
[fc134a48]285 conversionCostFromBasicToBasic( basicType, dstAsBasic );
[acb33f15]286 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
[c333ed2]287 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
[eb7586e]288 cost = Cost::unsafe;
[af746cc]289 }
[fb2bde4]290 }
291}
292
[0bd3faf]293void ConversionCost::postvisit( const ast::PointerType * pointerType ) {
[fb2bde4]294 if ( const ast::PointerType * dstAsPtr = dynamic_cast< const ast::PointerType * >( dst ) ) {
295 ast::CV::Qualifiers tq1 = pointerType->base->qualifiers;
296 ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers;
297 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
[251ce80]298 pointerType->base, dstAsPtr->base, env ) ) {
[fb2bde4]299 if ( tq1 == tq2 ) {
300 cost = Cost::zero;
301 } else {
302 cost = Cost::safe;
303 }
[ef1da0e2]304 }
305 /*
306 else if ( const ast::FunctionType * dstFunc = dstAsPtr->base.as<ast::FunctionType>()) {
307 if (const ast::FunctionType * srcFunc = pointerType->base.as<ast::FunctionType>()) {
308 if (dstFunc->params.empty() && dstFunc->isVarArgs ) {
309 cost = Cost::unsafe; // assign any function to variadic fptr
310 }
311 }
312 else {
313 ast::AssertionSet need, have; // unused
314 ast::OpenVarSet open;
315 env.extractOpenVars(open);
316 ast::TypeEnvironment tenv = env;
317 if ( unify(dstAsPtr->base, pointerType->base, tenv, need, have, open, symtab) ) {
318 cost = Cost::safe;
319 }
320 }
321 // else infinity
322 }
323 */
324 else {
[fb2bde4]325 int assignResult = ptrsAssignable( pointerType->base, dstAsPtr->base, env );
326 if ( 0 < assignResult && tq1 <= tq2 ) {
327 if ( tq1 == tq2 ) {
328 cost = Cost::safe;
329 } else {
330 cost = Cost::safe + Cost::safe;
331 }
332 } else if ( assignResult < 0 ) {
333 cost = Cost::unsafe;
334 } // else Cost::infinity
335 }
336 }
337}
338
[0bd3faf]339void ConversionCost::postvisit( const ast::ArrayType * arrayType ) {
[fb2bde4]340 (void)arrayType;
341}
342
[0bd3faf]343void ConversionCost::postvisit( const ast::ReferenceType * refType ) {
[fb2bde4]344 assert( nullptr == dynamic_cast< const ast::ReferenceType * >( dst ) );
345
[cf32116]346 cost = costCalc( refType->base, dst, srcIsLvalue, symtab, env );
[46da46b]347
348 // xxx - should qualifiers be considered in pass-by-value?
349 /*
[fb2bde4]350 if ( refType->base->qualifiers == dst->qualifiers ) {
351 cost.incReference();
352 } else if ( refType->base->qualifiers < dst->qualifiers ) {
353 cost.incSafe();
354 } else {
355 cost.incUnsafe();
356 }
[46da46b]357 */
358 cost.incReference();
[fb2bde4]359}
360
[0bd3faf]361void ConversionCost::postvisit( const ast::FunctionType * functionType ) {
[fb2bde4]362 (void)functionType;
363}
364
[af746cc]365void ConversionCost::postvisit( const ast::EnumInstType * inst ) {
[85855b0]366 if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
367 cost = enumCastCost(inst, dstInst, symtab, env);
[af746cc]368 return;
[7a780ad]369 }
370 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
[c75b30a]371 cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
[acb33f15]372 if ( !inst->base->isTyped ) {
373 if ( cost < Cost::unsafe ) {
374 cost.incSafe();
[fc1a3e2]375 }
[acb33f15]376 return;
[fc1a3e2]377 }
[acb33f15]378 cost.incUnsafe();
[0522ebe]379}
380
[0bd3faf]381void ConversionCost::postvisit( const ast::TraitInstType * traitInstType ) {
[fb2bde4]382 (void)traitInstType;
383}
384
[0bd3faf]385void ConversionCost::postvisit( const ast::TypeInstType * typeInstType ) {
[3e5dd913]386 if ( const ast::EqvClass * eqv = env.lookup( *typeInstType ) ) {
[cf32116]387 cost = costCalc( eqv->bound, dst, srcIsLvalue, symtab, env );
[fb2bde4]388 } else if ( const ast::TypeInstType * dstAsInst =
389 dynamic_cast< const ast::TypeInstType * >( dst ) ) {
[3e5dd913]390 if ( *typeInstType == *dstAsInst ) {
[fb2bde4]391 cost = Cost::zero;
392 }
393 } else if ( const ast::NamedTypeDecl * namedType = symtab.lookupType( typeInstType->name ) ) {
394 const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( namedType );
395 assertf( type, "Unexpected typedef.");
396 if ( type->base ) {
[cf32116]397 cost = costCalc( type->base, dst, srcIsLvalue, symtab, env ) + Cost::safe;
[fb2bde4]398 }
399 }
400}
401
[0bd3faf]402void ConversionCost::postvisit( const ast::TupleType * tupleType ) {
[fb2bde4]403 Cost c = Cost::zero;
404 if ( const ast::TupleType * dstAsTuple = dynamic_cast< const ast::TupleType * >( dst ) ) {
405 auto srcIt = tupleType->types.begin();
406 auto dstIt = dstAsTuple->types.begin();
407 auto srcEnd = tupleType->types.end();
408 auto dstEnd = dstAsTuple->types.end();
409 while ( srcIt != srcEnd && dstIt != dstEnd ) {
[cf32116]410 Cost newCost = costCalc( * srcIt++, * dstIt++, srcIsLvalue, symtab, env );
[fb2bde4]411 if ( newCost == Cost::infinity ) {
412 return;
413 }
414 c += newCost;
415 }
416 if ( dstIt != dstEnd ) {
417 cost = Cost::infinity;
418 } else {
419 cost = c;
420 }
421 }
422}
423
[0bd3faf]424void ConversionCost::postvisit( const ast::VarArgsType * varArgsType ) {
[fb2bde4]425 (void)varArgsType;
426 if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) {
427 cost = Cost::zero;
428 }
429}
430
[0bd3faf]431void ConversionCost::postvisit( const ast::ZeroType * zeroType ) {
[fb2bde4]432 (void)zeroType;
433 if ( dynamic_cast< const ast::ZeroType * >( dst ) ) {
434 cost = Cost::zero;
435 } else if ( const ast::BasicType * dstAsBasic =
436 dynamic_cast< const ast::BasicType * >( dst ) ) {
[7a780ad]437 int tableResult = costMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ];
[fb2bde4]438 if ( -1 == tableResult ) {
439 cost = Cost::unsafe;
440 } else {
441 cost = Cost::zero;
442 cost.incSafe( tableResult + 1 );
[7a780ad]443 cost.incSign( signMatrix[ ast::BasicKind::SignedInt ][ dstAsBasic->kind ] );
[fb2bde4]444 }
[46da46b]445 // this has the effect of letting any expr such as x+0, x+1 to be typed
446 // the same as x, instead of at least int. are we willing to sacrifice this little
447 // bit of coherence with C?
448 // TODO: currently this does not work when no zero/one overloads exist. Find a fix for it.
449 // cost = Cost::zero;
[2f98fb2]450 } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {
451 cost = Cost::zero;
452 // +1 for zero_t ->, +1 for disambiguation
453 cost.incSafe( maxIntCost + 2 );
[46da46b]454 // assuming 0p is supposed to be used for pointers?
[af746cc]455 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
[c333ed2]456 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
[eb7586e]457 cost = Cost::unsafe;
[af746cc]458 }
[fb2bde4]459 }
460}
461
[0bd3faf]462void ConversionCost::postvisit( const ast::OneType * oneType ) {
[fb2bde4]463 (void)oneType;
464 if ( dynamic_cast< const ast::OneType * >( dst ) ) {
465 cost = Cost::zero;
466 } else if ( const ast::BasicType * dstAsBasic =
[0bd3faf]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 }
[af746cc]476 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
[c333ed2]477 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
[eb7586e]478 cost = Cost::unsafe;
[af746cc]479 }
[9d5089e]480 }
[fb2bde4]481}
[0bd3faf]482
[85855b0]483// (dst) src is safe is src is a subtype of dst, or dst {inline src, ...}
484Cost enumCastCost (
485 const ast::EnumInstType * src, const ast::EnumInstType * dst,
486 const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
487) {
488 auto srcDecl = src->base;
489 auto dstDecl = dst->base;
490 if (srcDecl->name == dstDecl->name) return Cost::safe;
491 Cost minCost = Cost::infinity;
492 for (auto child: dstDecl->inlinedDecl) {
493 Cost c = enumCastCost(src, child, symtab, env) + Cost::safe;
494 if (c<minCost) minCost = c;
495 }
496 return minCost;
497}
498
499
[0bd3faf]500// size_t ConversionCost::traceId = Stats::Heap::new_stacktrace_id("ConversionCost");
[fb2bde4]501
[51b73452]502} // namespace ResolvExpr
[a32b204]503
504// Local Variables: //
505// tab-width: 4 //
506// mode: c++ //
507// compile-command: "make install" //
508// End: //
Note: See TracBrowser for help on using the repository browser.