source: src/ResolvExpr/PtrsCastable.cc@ 03bf5c8

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 03bf5c8 was 3c89751, checked in by Aaron Moss <a3moss@…>, 6 years ago

Port castCost, ptrsCastable

  • Property mode set to 100644
File size: 9.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//
[2c57025]7// PtrsCastable.cc --
[a32b204]8//
9// Author : Richard C. Bilson
10// Created On : Sun May 17 11:48:00 2015
[4040425]11// Last Modified By : Peter A. Buhr
12// Last Modified On : Wed Mar 2 17:36:18 2016
13// Update Count : 8
[a32b204]14//
[51b73452]15
[3c89751]16#include "AST/Decl.hpp"
17#include "AST/Pass.hpp"
18#include "AST/Type.hpp"
19#include "AST/TypeEnvironment.hpp"
[12145b9]20#include "Common/PassVisitor.h"
[ea6332d]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
[51b73452]27
28namespace ResolvExpr {
[3c89751]29 struct PtrsCastable_old : public WithShortCircuiting {
[a32b204]30 public:
[3c89751]31 PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
[2c57025]32
[a32b204]33 int get_result() const { return result; }
34
[12145b9]35 void previsit( Type * ) { visit_children = false; }
36
37 void postvisit( VoidType * voidType );
38 void postvisit( BasicType * basicType );
39 void postvisit( PointerType * pointerType );
40 void postvisit( ArrayType * arrayType );
41 void postvisit( FunctionType * functionType );
42 void postvisit( StructInstType * inst );
43 void postvisit( UnionInstType * inst );
44 void postvisit( EnumInstType * inst );
45 void postvisit( TraitInstType * inst );
46 void postvisit( TypeInstType * inst );
47 void postvisit( TupleType * tupleType );
48 void postvisit( VarArgsType * varArgsType );
49 void postvisit( ZeroType * zeroType );
50 void postvisit( OneType * oneType );
[a32b204]51 private:
52 Type *dest;
53 int result;
54 const TypeEnvironment &env;
55 const SymTab::Indexer &indexer;
56 };
57
[b0837e4]58 namespace {
59 int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
60 if ( dynamic_cast< FunctionType* >( src ) ) {
61 return -1;
62 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
63 if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
64 if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
65 if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
66 return -1;
67 } // if
68 } //if
[00ac42e]69 } else if ( const EqvClass *eqvClass = env.lookup( typeInst->get_name() ) ) {
70 if ( eqvClass->data.kind == TypeDecl::Ftype ) {
[a32b204]71 return -1;
72 } // if
73 } // if
[b0837e4]74 } //if
75 return 1;
76 }
77 int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
78 return -1 * objectCast( src, env, indexer ); // reverse the sense of objectCast
79 }
[1d29d46]80 }
[a32b204]81
82 int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
83 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
[00ac42e]84 if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
[12145b9]85 // xxx - should this be ptrsCastable?
[00ac42e]86 return ptrsAssignable( src, eqvClass->type, env );
[a32b204]87 } // if
88 } // if
89 if ( dynamic_cast< VoidType* >( dest ) ) {
90 return objectCast( src, env, indexer );
91 } else {
[3c89751]92 PassVisitor<PtrsCastable_old> ptrs( dest, env, indexer );
[a32b204]93 src->accept( ptrs );
[12145b9]94 return ptrs.pass.get_result();
[a32b204]95 } // if
96 }
97
[3c89751]98 PtrsCastable_old::PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
[a32b204]99 : dest( dest ), result( 0 ), env( env ), indexer( indexer ) {
100 }
101
[3c89751]102 void PtrsCastable_old::postvisit( VoidType * ) {
[a32b204]103 result = objectCast( dest, env, indexer );
104 }
105
[3c89751]106 void PtrsCastable_old::postvisit( BasicType * ) {
[a32b204]107 result = objectCast( dest, env, indexer );
108 }
109
[3c89751]110 void PtrsCastable_old::postvisit( PointerType * ) {
[a32b204]111 result = objectCast( dest, env, indexer );
112 }
113
[3c89751]114 void PtrsCastable_old::postvisit( ArrayType * ) {
[a32b204]115 result = objectCast( dest, env, indexer );
116 }
117
[3c89751]118 void PtrsCastable_old::postvisit( FunctionType * ) {
[1d29d46]119 // result = -1;
120 result = functionCast( dest, env, indexer );
[a32b204]121 }
122
[3c89751]123 void PtrsCastable_old::postvisit( StructInstType * ) {
[a32b204]124 result = objectCast( dest, env, indexer );
125 }
126
[3c89751]127 void PtrsCastable_old::postvisit( UnionInstType * ) {
[a32b204]128 result = objectCast( dest, env, indexer );
129 }
130
[3c89751]131 void PtrsCastable_old::postvisit( EnumInstType * ) {
[931dd12]132 if ( dynamic_cast< EnumInstType* >( dest ) ) {
[a32b204]133 result = 1;
[931dd12]134 } else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {
[a32b204]135 if ( bt->get_kind() == BasicType::SignedInt ) {
136 result = 0;
137 } else {
138 result = 1;
139 }
140 } else {
141 result = objectCast( dest, env, indexer );
142 }
143 }
144
[3c89751]145 void PtrsCastable_old::postvisit( TraitInstType * ) {}
[a32b204]146
[3c89751]147 void PtrsCastable_old::postvisit(TypeInstType *inst ) {
[1d29d46]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;
[a32b204]150 }
151
[3c89751]152 void PtrsCastable_old::postvisit( TupleType * ) {
[a32b204]153 result = objectCast( dest, env, indexer );
154 }
[44b7088]155
[3c89751]156 void PtrsCastable_old::postvisit( VarArgsType * ) {
[44b7088]157 result = objectCast( dest, env, indexer );
158 }
[89e6ffc]159
[3c89751]160 void PtrsCastable_old::postvisit( ZeroType * ) {
[89e6ffc]161 result = objectCast( dest, env, indexer );
162 }
163
[3c89751]164 void PtrsCastable_old::postvisit( OneType * ) {
[89e6ffc]165 result = objectCast( dest, env, indexer );
166 }
[3c89751]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
[51b73452]299} // namespace ResolvExpr
[a32b204]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.