source: src/ResolvExpr/PtrsAssignable.cpp@ 718601e

Last change on this file since 718601e was 5f225f5, checked in by Andrew Beach <ajbeach@…>, 17 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: 3.5 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// PtrsAssignable.cpp --
8//
9// Author : Richard C. Bilson
10// Created On : Sun May 17 11:44:11 2015
11// Last Modified By : Andrew
12// Last Modified On : Mon Jun 24 15:29:00 2019
13// Update Count : 9
14//
15
16#include "PtrsAssignable.hpp"
17
18#include "AST/Pass.hpp"
19#include "AST/Type.hpp"
20#include "AST/TypeEnvironment.hpp"
21
22namespace ResolvExpr {
23
24namespace {
25
26struct PtrsAssignable : public ast::WithShortCircuiting {
27 const ast::Type * dst;
28 const ast::TypeEnvironment & typeEnv;
29 int result;
30
31 PtrsAssignable( const ast::Type * dst, const ast::TypeEnvironment & env ) :
32 dst( dst ), typeEnv( env ), result( 0 ) {}
33
34 void previsit( ast::Type * ) { visit_children = false; }
35
36 void postvisit( const ast::EnumInstType * ) {
37 if ( dynamic_cast< const ast::BasicType * >( dst ) ) {
38 // int * = E *, etc. is safe. This isn't technically correct, as each
39 // enum has one basic type that it is compatible with, an that type can
40 // differ from enum to enum. Without replicating GCC's internal logic,
41 // there is no way to know which type this particular enum is compatible
42 // with, so punt on this for now.
43 result = 1;
44 }
45 }
46 void postvisit( const ast::TypeInstType * inst ) {
47 if ( const ast::EqvClass * eqv = typeEnv.lookup( *inst ) ) {
48 if ( eqv->bound ) {
49 // T * = S * for any S depends on the type bound to T
50 result = ptrsAssignable( eqv->bound, dst, typeEnv );
51 }
52 }
53 }
54};
55
56} // namespace
57
58int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
59 const ast::TypeEnvironment & env ) {
60 if ( const ast::TypeInstType * dstAsInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
61 if ( const ast::EqvClass * eqv = env.lookup( *dstAsInst ) ) {
62 return ptrsAssignable( src, eqv->bound, env );
63 }
64 }
65 if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
66 return -1;
67 } else {
68 ast::Pass<PtrsAssignable> visitor( dst, env );
69 src->accept( visitor );
70 return visitor.core.result;
71 }
72
73// see ticket #136 (this should be able to replace the visitor).
74#if 0
75 if ( const ast::TypeInstType * dstAsTypeInst =
76 dynamic_cast< const ast::TypeInstType* >( dst ) ) {
77 if ( const ast::EqvClass * eqv = env.lookup( dstAsTypeInst->get_name() ) ) {
78 return ptrsAssignable( src, eqv->type, env );
79 } // if
80 } // if
81 if ( dynamic_cast< VoidType* >( dst ) ) {
82 // void * = T * for any T is unsafe
83 // xxx - this should be safe, but that currently breaks the build
84 return -1;
85 } else if ( dynamic_cast< EnumInstType * >( src ) ) {
86 if ( dynamic_cast< BasicType * >( dst ) ) {
87 // int * = E *, etc. is safe. This isn't technically correct, as each
88 // enum has one basic type that it is compatible with, an that type can
89 // differ from enum to enum. Without replicating GCC's internal logic,
90 // there is no way to know which type this particular enum is compatible
91 // with, so punt on this for now.
92 return 1;
93 }
94 } else if ( const ast::TypeInstType * typeInstType =
95 dynamic_cast< const ast::TypeInstType * >( src ) ) {
96 if ( const ast::EqvClass * eqv = env.lookup( typeInstType->name ) ) {
97 if ( eqv->bound ) {
98 // T * = S * for any S depends on the type bound to T
99 return ptrsAssignable( eqv->bound, dst, env );
100 }
101 }
102 }
103 return 0;
104#endif
105}
106
107} // namespace ResolvExpr
108
109// Local Variables: //
110// tab-width: 4 //
111// mode: c++ //
112// compile-command: "make install" //
113// End: //
Note: See TracBrowser for help on using the repository browser.