source: src/ResolvExpr/PtrsCastable.cpp @ a51dc0d

Last change on this file since a51dc0d was 5f225f5, checked in by Andrew Beach <ajbeach@…>, 6 months ago

Perhaps only src/Makefile.am needed to change, but I did a text search to try and be absolutely sure I got everything.

  • Property mode set to 100644
File size: 4.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.cpp --
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 "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable
23
24namespace ResolvExpr {
25
26namespace {
27        // can this type be cast to an object (1 for yes, -1 for no)
28        int objectCast(
29                const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
30        ) {
31                if ( dynamic_cast< const ast::FunctionType * >( src ) ) {
32                        return -1;
33                } else if ( auto inst = dynamic_cast< const ast::TypeInstType * >( src ) ) {
34                        if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {
35                                if ( auto tyDecl = dynamic_cast< const ast::TypeDecl * >( named ) ) {
36                                        if ( tyDecl->kind == ast::TypeDecl::Ftype ) {
37                                                return -1;
38                                        }
39                                }
40                        } else if ( const ast::EqvClass * eqvClass = env.lookup( *inst ) ) {
41                                if ( eqvClass->data.kind == ast::TypeDecl::Ftype ) {
42                                        return -1;
43                                }
44                        }
45                }
46
47                return 1;
48        }
49
50        // can this type be cast to a function (inverse of objectCast)
51        int functionCast(
52                const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
53        ) {
54                return -1 * objectCast( src, env, symtab );
55        }
56
57        class PtrsCastable : public ast::WithShortCircuiting {
58                const ast::Type * dst;
59                const ast::TypeEnvironment & env;
60                const ast::SymbolTable & symtab;
61        public:
62                int result;
63
64                PtrsCastable(
65                        const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms )
66                : dst( d ), env( e ), symtab( syms ), result( 0 ) {}
67
68                void previsit( const ast::Type * ) { visit_children = false; }
69
70                void postvisit( const ast::VoidType * ) {
71                        result = objectCast( dst, env, symtab );
72                }
73
74                void postvisit( const ast::BasicType * ) {
75                        result = objectCast( dst, env, symtab );
76                }
77
78                void postvisit( const ast::PointerType * ) {
79                        result = objectCast( dst, env, symtab );
80                }
81
82                void postvisit( const ast::ArrayType * ) {
83                        result = objectCast( dst, env, symtab );
84                }
85
86                void postvisit( const ast::FunctionType * ) {
87                        result = functionCast( dst, env, symtab );
88                }
89
90                void postvisit( const ast::StructInstType * ) {
91                        result = objectCast( dst, env, symtab );
92                }
93
94                void postvisit( const ast::UnionInstType * ) {
95                        result = objectCast( dst, env, symtab );
96                }
97
98                void postvisit( const ast::EnumInstType * ) {
99                        if ( dynamic_cast< const ast::EnumInstType * >( dst ) ) {
100                                result = 1;
101                        } else if ( auto bt = dynamic_cast< const ast::BasicType * >( dst ) ) {
102                                if ( bt->kind == ast::BasicKind::SignedInt ) {
103                                        result = 0;
104                                } else {
105                                        result = 1;
106                                }
107                        } else {
108                                result = objectCast( dst, env, symtab );
109                        }
110                }
111
112                void postvisit( const ast::TraitInstType * ) {}
113
114                void postvisit( const ast::TypeInstType * inst ) {
115                        // check trait and destination type are both object or both function
116                        result = objectCast( inst, env, symtab ) == objectCast( dst, env, symtab ) ? 1 : -1;
117                }
118
119                void postvisit( const ast::TupleType * ) {
120                        result = objectCast( dst, env, symtab );
121                }
122
123                void postvisit( const ast::VarArgsType * ) {
124                        result = objectCast( dst, env, symtab );
125                }
126
127                void postvisit( const ast::ZeroType * ) {
128                        result = objectCast( dst, env, symtab );
129                }
130
131                void postvisit( const ast::OneType * ) {
132                        result = objectCast( dst, env, symtab );
133                }
134
135        };
136} // anonymous namespace
137
138int ptrsCastable(
139        const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
140        const ast::TypeEnvironment & env
141) {
142        if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
143                if ( const ast::EqvClass * eqvClass = env.lookup( *inst ) ) {
144                        return ptrsAssignable( src, eqvClass->bound, env );
145                }
146        }
147
148        if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
149                return objectCast( src, env, symtab );
150        } else {
151                return ast::Pass<PtrsCastable>::read( src, dst, env, symtab );
152        }
153}
154
155} // namespace ResolvExpr
156
157// Local Variables: //
158// tab-width: 4 //
159// mode: c++ //
160// compile-command: "make install" //
161// End: //
Note: See TracBrowser for help on using the repository browser.