source: src/ResolvExpr/PtrsCastable.cc@ 6be3b7d6

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

Port castCost, ptrsCastable

  • Property mode set to 100644
File size: 9.0 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( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
32
33 int get_result() const { return result; }
34
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 );
51 private:
52 Type *dest;
53 int result;
54 const TypeEnvironment &env;
55 const SymTab::Indexer &indexer;
56 };
57
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
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( 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( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
83 if ( TypeInstType *destAsTypeInst = dynamic_cast< 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< 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( 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( VoidType * ) {
103 result = objectCast( dest, env, indexer );
104 }
105
106 void PtrsCastable_old::postvisit( BasicType * ) {
107 result = objectCast( dest, env, indexer );
108 }
109
110 void PtrsCastable_old::postvisit( PointerType * ) {
111 result = objectCast( dest, env, indexer );
112 }
113
114 void PtrsCastable_old::postvisit( ArrayType * ) {
115 result = objectCast( dest, env, indexer );
116 }
117
118 void PtrsCastable_old::postvisit( FunctionType * ) {
119 // result = -1;
120 result = functionCast( dest, env, indexer );
121 }
122
123 void PtrsCastable_old::postvisit( StructInstType * ) {
124 result = objectCast( dest, env, indexer );
125 }
126
127 void PtrsCastable_old::postvisit( UnionInstType * ) {
128 result = objectCast( dest, env, indexer );
129 }
130
131 void PtrsCastable_old::postvisit( EnumInstType * ) {
132 if ( dynamic_cast< EnumInstType* >( dest ) ) {
133 result = 1;
134 } else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {
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
145 void PtrsCastable_old::postvisit( TraitInstType * ) {}
146
147 void PtrsCastable_old::postvisit(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( TupleType * ) {
153 result = objectCast( dest, env, indexer );
154 }
155
156 void PtrsCastable_old::postvisit( VarArgsType * ) {
157 result = objectCast( dest, env, indexer );
158 }
159
160 void PtrsCastable_old::postvisit( ZeroType * ) {
161 result = objectCast( dest, env, indexer );
162 }
163
164 void PtrsCastable_old::postvisit( 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.