source: src/ResolvExpr/PtrsCastable.cc @ ded6c2a6

ast-experimental
Last change on this file since ded6c2a6 was 5bf3976, checked in by Andrew Beach <ajbeach@…>, 22 months 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.