source: src/GenPoly/GenPoly.cc@ 5802a4f

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 5802a4f was 1aa4b71, checked in by Rob Schluntz <rschlunt@…>, 9 years ago

added case for ConditionalExpr in getBaseVar

  • 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// GenPoly.cc --
8//
9// Author : Richard C. Bilson
10// Created On : Mon May 18 07:44:20 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Wed Jun 29 21:45:53 2016
13// Update Count : 14
14//
15
16#include "GenPoly.h"
17
18#include "SynTree/Expression.h"
19#include "SynTree/Type.h"
20
21#include <iostream>
22using namespace std;
23
24namespace GenPoly {
25 namespace {
26 /// Checks a parameter list for polymorphic parameters; will substitute according to env if present
27 bool hasPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) {
28 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
29 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
30 assert(paramType && "Aggregate parameters should be type expressions");
31 if ( isPolyType( paramType->get_type(), env ) ) return true;
32 }
33 return false;
34 }
35
36 /// Checks a parameter list for polymorphic parameters from tyVars; will substitute according to env if present
37 bool hasPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
38 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
39 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
40 assert(paramType && "Aggregate parameters should be type expressions");
41 if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true;
42 }
43 return false;
44 }
45
46 /// Checks a parameter list for dynamic-layout parameters from tyVars; will substitute according to env if present
47 bool hasDynParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
48 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
49 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
50 assert(paramType && "Aggregate parameters should be type expressions");
51 if ( isDynType( paramType->get_type(), tyVars, env ) ) return true;
52 }
53 return false;
54 }
55 }
56
57 Type* replaceTypeInst( Type* type, const TypeSubstitution* env ) {
58 if ( ! env ) return type;
59 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
60 Type *newType = env->lookup( typeInst->get_name() );
61 if ( newType ) return newType;
62 }
63 return type;
64 }
65
66 Type *isPolyType( Type *type, const TypeSubstitution *env ) {
67 type = replaceTypeInst( type, env );
68
69 if ( dynamic_cast< TypeInstType * >( type ) ) {
70 return type;
71 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
72 if ( hasPolyParams( structType->get_parameters(), env ) ) return type;
73 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
74 if ( hasPolyParams( unionType->get_parameters(), env ) ) return type;
75 }
76 return 0;
77 }
78
79 Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
80 type = replaceTypeInst( type, env );
81
82 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
83 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
84 return type;
85 }
86 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
87 if ( hasPolyParams( structType->get_parameters(), tyVars, env ) ) return type;
88 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
89 if ( hasPolyParams( unionType->get_parameters(), tyVars, env ) ) return type;
90 }
91 return 0;
92 }
93
94 ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
95 type = replaceTypeInst( type, env );
96
97 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
98 auto var = tyVars.find( typeInst->get_name() );
99 if ( var != tyVars.end() && var->second.isComplete ) {
100 return typeInst;
101 }
102 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
103 if ( hasDynParams( structType->get_parameters(), tyVars, env ) ) return structType;
104 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
105 if ( hasDynParams( unionType->get_parameters(), tyVars, env ) ) return unionType;
106 }
107 return 0;
108 }
109
110 ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &forallTypes ) {
111 if ( function->get_returnVals().empty() ) return 0;
112
113 return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes );
114 }
115
116 ReferenceToType *isDynRet( FunctionType *function ) {
117 if ( function->get_returnVals().empty() ) return 0;
118
119 TyVarMap forallTypes( TypeDecl::Data{} );
120 makeTyVarMap( function, forallTypes );
121 return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes );
122 }
123
124 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
125// if ( ! adaptee->get_returnVals().empty() && isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
126// return true;
127// } // if
128 if ( isDynRet( adaptee, tyVars ) ) return true;
129
130 for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); innerArg != adaptee->get_parameters().end(); ++innerArg ) {
131// if ( isPolyType( (*innerArg)->get_type(), tyVars ) ) {
132 if ( isDynType( (*innerArg)->get_type(), tyVars ) ) {
133 return true;
134 } // if
135 } // for
136 return false;
137 }
138
139 Type *isPolyPtr( Type *type, const TypeSubstitution *env ) {
140 type = replaceTypeInst( type, env );
141
142 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
143 return isPolyType( ptr->get_base(), env );
144 }
145 return 0;
146 }
147
148 Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
149 type = replaceTypeInst( type, env );
150
151 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
152 return isPolyType( ptr->get_base(), tyVars, env );
153 }
154 return 0;
155 }
156
157 Type * hasPolyBase( Type *type, int *levels, const TypeSubstitution *env ) {
158 int dummy;
159 if ( ! levels ) { levels = &dummy; }
160 *levels = 0;
161
162 while ( true ) {
163 type = replaceTypeInst( type, env );
164
165 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
166 type = ptr->get_base();
167 ++(*levels);
168 } else break;
169 }
170
171 return isPolyType( type, env );
172 }
173
174 Type * hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels, const TypeSubstitution *env ) {
175 int dummy;
176 if ( ! levels ) { levels = &dummy; }
177 *levels = 0;
178
179 while ( true ) {
180 type = replaceTypeInst( type, env );
181
182 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
183 type = ptr->get_base();
184 ++(*levels);
185 } else break;
186 }
187
188 return isPolyType( type, tyVars, env );
189 }
190
191 FunctionType * getFunctionType( Type *ty ) {
192 PointerType *ptrType;
193 if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {
194 return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise
195 } else {
196 return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
197 }
198 }
199
200 VariableExpr * getBaseVar( Expression *expr, int *levels ) {
201 int dummy;
202 if ( ! levels ) { levels = &dummy; }
203 *levels = 0;
204
205 while ( true ) {
206 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( expr ) ) {
207 return varExpr;
208 } else if ( MemberExpr *memberExpr = dynamic_cast< MemberExpr* >( expr ) ) {
209 expr = memberExpr->get_aggregate();
210 } else if ( AddressExpr *addressExpr = dynamic_cast< AddressExpr* >( expr ) ) {
211 expr = addressExpr->get_arg();
212 } else if ( UntypedExpr *untypedExpr = dynamic_cast< UntypedExpr* >( expr ) ) {
213 // look for compiler-inserted dereference operator
214 NameExpr *fn = dynamic_cast< NameExpr* >( untypedExpr->get_function() );
215 if ( ! fn || fn->get_name() != std::string("*?") ) return 0;
216 expr = *untypedExpr->begin_args();
217 } else if ( CommaExpr *commaExpr = dynamic_cast< CommaExpr* >( expr ) ) {
218 // copy constructors insert comma exprs, look at second argument which contains the variable
219 expr = commaExpr->get_arg2();
220 continue;
221 } else if ( ConditionalExpr * condExpr = dynamic_cast< ConditionalExpr * >( expr ) ) {
222 int lvl1;
223 int lvl2;
224 VariableExpr * var1 = getBaseVar( condExpr->get_arg2(), &lvl1 );
225 VariableExpr * var2 = getBaseVar( condExpr->get_arg3(), &lvl2 );
226 if ( lvl1 == lvl2 && var1 && var2 && var1->get_var() == var2->get_var() ) {
227 *levels = lvl1;
228 return var1;
229 }
230 break;
231 } else break;
232
233 ++(*levels);
234 }
235
236 return 0;
237 }
238
239 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
240 tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar };
241 }
242
243 void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {
244 for ( Type::ForallList::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
245 assert( *tyVar );
246 addToTyVarMap( *tyVar, tyVarMap );
247 }
248 if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {
249 makeTyVarMap( pointer->get_base(), tyVarMap );
250 }
251 }
252
253 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) {
254 for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
255 os << i->first << " (" << i->second << ") ";
256 } // for
257 os << std::endl;
258 }
259
260} // namespace GenPoly
261
262// Local Variables: //
263// tab-width: 4 //
264// mode: c++ //
265// compile-command: "make install" //
266// End: //
Note: See TracBrowser for help on using the repository browser.