source: src/ResolvExpr/ConversionCost.cc@ fbe3f03

Last change on this file since fbe3f03 was af746cc, checked in by JiadaL <j82liang@…>, 18 months ago

Reimplement the resolution of Enum instance type

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