source: src/ResolvExpr/PtrsCastable.cc@ 4a60488

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 4a60488 was 7870799, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Cast cost and conversion cost now take constant parameters.
This required supporting visiting const node.
The PassVisitor can now visit const nodes but not when using the Indexer

  • Property mode set to 100644
File size: 9.3 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// PtrsCastable.cc --
8//
9// Author : Richard C. Bilson
10// Created On : Sun May 17 11:48:00 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Wed Mar 2 17:36:18 2016
13// Update Count : 8
14//
15
16#include "AST/Decl.hpp"
17#include "AST/Pass.hpp"
18#include "AST/Type.hpp"
19#include "AST/TypeEnvironment.hpp"
20#include "Common/PassVisitor.h"
21#include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment
22#include "SymTab/Indexer.h" // for Indexer
23#include "SynTree/Declaration.h" // for TypeDecl, TypeDecl::Kind::Ftype
24#include "SynTree/Type.h" // for TypeInstType, Type, BasicType
25#include "SynTree/Visitor.h" // for Visitor
26#include "typeops.h" // for ptrsAssignable
27
28namespace ResolvExpr {
29 struct PtrsCastable_old : public WithShortCircuiting {
30 public:
31 PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
32
33 int get_result() const { return result; }
34
35 void previsit( const Type * ) { visit_children = false; }
36
37 void postvisit( const VoidType * voidType );
38 void postvisit( const BasicType * basicType );
39 void postvisit( const PointerType * pointerType );
40 void postvisit( const ArrayType * arrayType );
41 void postvisit( const FunctionType * functionType );
42 void postvisit( const StructInstType * inst );
43 void postvisit( const UnionInstType * inst );
44 void postvisit( const EnumInstType * inst );
45 void postvisit( const TraitInstType * inst );
46 void postvisit( const TypeInstType * inst );
47 void postvisit( const TupleType * tupleType );
48 void postvisit( const VarArgsType * varArgsType );
49 void postvisit( const ZeroType * zeroType );
50 void postvisit( const OneType * oneType );
51 private:
52 const Type * dest;
53 int result;
54 const TypeEnvironment &env;
55 const SymTab::Indexer &indexer;
56 };
57
58 namespace {
59 int objectCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
60 if ( dynamic_cast< const FunctionType* >( src ) ) {
61 return -1;
62 } else if ( const TypeInstType * typeInst = dynamic_cast< const TypeInstType* >( src ) ) {
63 if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->name ) ) {
64 if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl* >( ntDecl ) ) {
65 if ( tyDecl->kind == TypeDecl::Ftype ) {
66 return -1;
67 } // if
68 } //if
69 } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {
70 if ( eqvClass->data.kind == TypeDecl::Ftype ) {
71 return -1;
72 } // if
73 } // if
74 } //if
75 return 1;
76 }
77 int functionCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
78 return -1 * objectCast( src, env, indexer ); // reverse the sense of objectCast
79 }
80 }
81
82 int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
83 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
84 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
85 // xxx - should this be ptrsCastable?
86 return ptrsAssignable( src, eqvClass->type, env );
87 } // if
88 } // if
89 if ( dynamic_cast< const VoidType* >( dest ) ) {
90 return objectCast( src, env, indexer );
91 } else {
92 PassVisitor<PtrsCastable_old> ptrs( dest, env, indexer );
93 src->accept( ptrs );
94 return ptrs.pass.get_result();
95 } // if
96 }
97
98 PtrsCastable_old::PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
99 : dest( dest ), result( 0 ), env( env ), indexer( indexer ) {
100 }
101
102 void PtrsCastable_old::postvisit( const VoidType * ) {
103 result = objectCast( dest, env, indexer );
104 }
105
106 void PtrsCastable_old::postvisit( const BasicType * ) {
107 result = objectCast( dest, env, indexer );
108 }
109
110 void PtrsCastable_old::postvisit( const PointerType * ) {
111 result = objectCast( dest, env, indexer );
112 }
113
114 void PtrsCastable_old::postvisit( const ArrayType * ) {
115 result = objectCast( dest, env, indexer );
116 }
117
118 void PtrsCastable_old::postvisit( const FunctionType * ) {
119 // result = -1;
120 result = functionCast( dest, env, indexer );
121 }
122
123 void PtrsCastable_old::postvisit( const StructInstType * ) {
124 result = objectCast( dest, env, indexer );
125 }
126
127 void PtrsCastable_old::postvisit( const UnionInstType * ) {
128 result = objectCast( dest, env, indexer );
129 }
130
131 void PtrsCastable_old::postvisit( const EnumInstType * ) {
132 if ( dynamic_cast< const EnumInstType * >( dest ) ) {
133 result = 1;
134 } else if ( const BasicType * bt = dynamic_cast< const BasicType * >( dest ) ) {
135 if ( bt->kind == BasicType::SignedInt ) {
136 result = 0;
137 } else {
138 result = 1;
139 }
140 } else {
141 result = objectCast( dest, env, indexer );
142 }
143 }
144
145 void PtrsCastable_old::postvisit( const TraitInstType * ) {}
146
147 void PtrsCastable_old::postvisit( const TypeInstType *inst ) {
148 //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1;
149 result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1;
150 }
151
152 void PtrsCastable_old::postvisit( const TupleType * ) {
153 result = objectCast( dest, env, indexer );
154 }
155
156 void PtrsCastable_old::postvisit( const VarArgsType * ) {
157 result = objectCast( dest, env, indexer );
158 }
159
160 void PtrsCastable_old::postvisit( const ZeroType * ) {
161 result = objectCast( dest, env, indexer );
162 }
163
164 void PtrsCastable_old::postvisit( const OneType * ) {
165 result = objectCast( dest, env, indexer );
166 }
167
168namespace {
169 // can this type be cast to an object (1 for yes, -1 for no)
170 int objectCast(
171 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
172 ) {
173 if ( dynamic_cast< const ast::FunctionType * >( src ) ) {
174 return -1;
175 } else if ( auto inst = dynamic_cast< const ast::TypeInstType * >( src ) ) {
176 if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {
177 if ( auto tyDecl = dynamic_cast< const ast::TypeDecl * >( named ) ) {
178 if ( tyDecl->kind == ast::TypeVar::Ftype ) {
179 return -1;
180 }
181 }
182 } else if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) {
183 if ( eqvClass->data.kind == ast::TypeVar::Ftype ) {
184 return -1;
185 }
186 }
187 }
188
189 return 1;
190 }
191
192 // can this type be cast to a function (inverse of objectCast)
193 int functionCast(
194 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
195 ) {
196 return -1 * objectCast( src, env, symtab );
197 }
198
199 class PtrsCastable_new : public ast::WithShortCircuiting {
200 const ast::Type * dst;
201 const ast::TypeEnvironment & env;
202 const ast::SymbolTable & symtab;
203 public:
204 int result;
205
206 PtrsCastable_new(
207 const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms )
208 : dst( d ), env( e ), symtab( syms ), result( 0 ) {}
209
210 void previsit( const ast::Type * ) { visit_children = false; }
211
212 void postvisit( const ast::VoidType * ) {
213 result = objectCast( dst, env, symtab );
214 }
215
216 void postvisit( const ast::BasicType * ) {
217 result = objectCast( dst, env, symtab );
218 }
219
220 void postvisit( const ast::PointerType * ) {
221 result = objectCast( dst, env, symtab );
222 }
223
224 void postvisit( const ast::ArrayType * ) {
225 result = objectCast( dst, env, symtab );
226 }
227
228 void postvisit( const ast::FunctionType * ) {
229 result = functionCast( dst, env, symtab );
230 }
231
232 void postvisit( const ast::StructInstType * ) {
233 result = objectCast( dst, env, symtab );
234 }
235
236 void postvisit( const ast::UnionInstType * ) {
237 result = objectCast( dst, env, symtab );
238 }
239
240 void postvisit( const ast::EnumInstType * ) {
241 if ( dynamic_cast< const ast::EnumInstType * >( dst ) ) {
242 result = 1;
243 } else if ( auto bt = dynamic_cast< const ast::BasicType * >( dst ) ) {
244 if ( bt->kind == ast::BasicType::SignedInt ) {
245 result = 0;
246 } else {
247 result = 1;
248 }
249 } else {
250 result = objectCast( dst, env, symtab );
251 }
252 }
253
254 void postvisit( const ast::TraitInstType * ) {}
255
256 void postvisit( const ast::TypeInstType * inst ) {
257 // check trait and destination type are both object or both function
258 result = objectCast( inst, env, symtab ) == objectCast( dst, env, symtab ) ? 1 : -1;
259 }
260
261 void postvisit( const ast::TupleType * ) {
262 result = objectCast( dst, env, symtab );
263 }
264
265 void postvisit( const ast::VarArgsType * ) {
266 result = objectCast( dst, env, symtab );
267 }
268
269 void postvisit( const ast::ZeroType * ) {
270 result = objectCast( dst, env, symtab );
271 }
272
273 void postvisit( const ast::OneType * ) {
274 result = objectCast( dst, env, symtab );
275 }
276
277 };
278} // anonymous namespace
279
280int ptrsCastable(
281 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
282 const ast::TypeEnvironment & env
283) {
284 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
285 if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) {
286 return ptrsAssignable( src, eqvClass->bound, env );
287 }
288 }
289
290 if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
291 return objectCast( src, env, symtab );
292 } else {
293 ast::Pass< PtrsCastable_new > ptrs{ dst, env, symtab };
294 src->accept( ptrs );
295 return ptrs.pass.result;
296 }
297}
298
299} // namespace ResolvExpr
300
301// Local Variables: //
302// tab-width: 4 //
303// mode: c++ //
304// compile-command: "make install" //
305// End: //
Note: See TracBrowser for help on using the repository browser.