source: src/ResolvExpr/PtrsCastable.cc @ a3769cc

ADTast-experimentalenumforall-pointer-decaypthread-emulationqualifiedEnum
Last change on this file since a3769cc was 3e5dd913, checked in by Fangren Yu <f37yu@…>, 4 years ago

reimplement function type and eliminate deep copy

  • Property mode set to 100644
File size: 9.3 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
[07de76b]12// Last Modified On : Wed Dec 11 21:48:33 2019
13// Update Count     : 9
[a32b204]14//
[51b7345]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
[51b7345]27
28namespace ResolvExpr {
[3c89751]29        struct PtrsCastable_old : public WithShortCircuiting  {
[a32b204]30          public:
[7870799]31                PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
[2c57025]32
[a32b204]33                int get_result() const { return result; }
34
[7870799]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 );
[a32b204]51          private:
[7870799]52                const Type * dest;
[a32b204]53                int result;
54                const TypeEnvironment &env;
55                const SymTab::Indexer &indexer;
56        };
57
[b0837e4]58        namespace {
[7870799]59                int objectCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
60                        if ( dynamic_cast< const FunctionType* >( src ) ) {
[b0837e4]61                                return -1;
[7870799]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 ) {
[b0837e4]66                                                        return -1;
67                                                } // if
68                                        } //if
[7870799]69                                } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {
[00ac42e]70                                        if ( eqvClass->data.kind == TypeDecl::Ftype ) {
[a32b204]71                                                return -1;
72                                        } // if
73                                } // if
[b0837e4]74                        } //if
75                        return 1;
76                }
[7870799]77                int functionCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
[b0837e4]78                        return -1 * objectCast( src, env, indexer );  // reverse the sense of objectCast
79                }
[1d29d46]80        }
[a32b204]81
[7870799]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() ) ) {
[12145b9]85                                // xxx - should this be ptrsCastable?
[00ac42e]86                                return ptrsAssignable( src, eqvClass->type, env );
[a32b204]87                        } // if
88                } // if
[7870799]89                if ( dynamic_cast< const VoidType* >( dest ) ) {
[a32b204]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
[7870799]98        PtrsCastable_old::PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
[a32b204]99                : dest( dest ), result( 0 ), env( env ), indexer( indexer )     {
100        }
101
[7870799]102        void PtrsCastable_old::postvisit( const VoidType * ) {
[a32b204]103                result = objectCast( dest, env, indexer );
104        }
105
[7870799]106        void PtrsCastable_old::postvisit( const BasicType * ) {
[a32b204]107                result = objectCast( dest, env, indexer );
108        }
109
[7870799]110        void PtrsCastable_old::postvisit( const PointerType * ) {
[a32b204]111                result = objectCast( dest, env, indexer );
112        }
113
[7870799]114        void PtrsCastable_old::postvisit( const ArrayType * ) {
[a32b204]115                result = objectCast( dest, env, indexer );
116        }
117
[7870799]118        void PtrsCastable_old::postvisit( const FunctionType * ) {
[1d29d46]119                // result = -1;
120                result = functionCast( dest, env, indexer );
[a32b204]121        }
122
[7870799]123        void PtrsCastable_old::postvisit( const StructInstType * ) {
[a32b204]124                result = objectCast( dest, env, indexer );
125        }
126
[7870799]127        void PtrsCastable_old::postvisit( const UnionInstType * ) {
[a32b204]128                result = objectCast( dest, env, indexer );
129        }
130
[7870799]131        void PtrsCastable_old::postvisit( const EnumInstType * ) {
132                if ( dynamic_cast< const EnumInstType * >( dest ) ) {
[a32b204]133                        result = 1;
[7870799]134                } else if ( const BasicType * bt = dynamic_cast< const BasicType * >( dest ) ) {
135                        if ( bt->kind == BasicType::SignedInt ) {
[a32b204]136                                result = 0;
137                        } else {
138                                result = 1;
139                        }
140                } else {
141                        result = objectCast( dest, env, indexer );
142                }
143        }
144
[7870799]145        void PtrsCastable_old::postvisit( const TraitInstType * ) {}
[a32b204]146
[7870799]147        void PtrsCastable_old::postvisit( const 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
[7870799]152        void PtrsCastable_old::postvisit( const TupleType * ) {
[a32b204]153                result = objectCast( dest, env, indexer );
154        }
[44b7088]155
[7870799]156        void PtrsCastable_old::postvisit( const VarArgsType * ) {
[44b7088]157                result = objectCast( dest, env, indexer );
158        }
[89e6ffc]159
[7870799]160        void PtrsCastable_old::postvisit( const ZeroType * ) {
[89e6ffc]161                result = objectCast( dest, env, indexer );
162        }
163
[7870799]164        void PtrsCastable_old::postvisit( const 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)
[7870799]170        int objectCast(
171                const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
[3c89751]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 ) ) {
[07de76b]178                                        if ( tyDecl->kind == ast::TypeDecl::Ftype ) {
[3c89751]179                                                return -1;
180                                        }
181                                }
[3e5dd913]182                        } else if ( const ast::EqvClass * eqvClass = env.lookup( *inst ) ) {
[07de76b]183                                if ( eqvClass->data.kind == ast::TypeDecl::Ftype ) {
[3c89751]184                                        return -1;
185                                }
186                        }
187                }
188
189                return 1;
190        }
191
192        // can this type be cast to a function (inverse of objectCast)
[7870799]193        int functionCast(
194                const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
[3c89751]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
[7870799]206                PtrsCastable_new(
[3c89751]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
[7870799]280int ptrsCastable(
281        const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
282        const ast::TypeEnvironment & env
[3c89751]283) {
284        if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
[3e5dd913]285                if ( const ast::EqvClass * eqvClass = env.lookup( *inst ) ) {
[3c89751]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 );
[7ff3e522]295                return ptrs.core.result;
[3c89751]296        }
297}
298
[51b7345]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.