source: src/ResolvExpr/PtrsCastable.cc@ 9317419

ADT ast-experimental
Last change on this file since 9317419 was 5bf3976, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Header Clean-Up: Created new headers for new AST typeops and moved declarations.

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