Changeset b067d9b for src/GenPoly
- Timestamp:
- Oct 29, 2019, 4:01:24 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
- Children:
- 773db65, 9421f3d8
- Parents:
- 7951100 (diff), 8364209 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- src/GenPoly
- Files:
-
- 9 edited
-
Box.cc (modified) (9 diffs)
-
GenPoly.cc (modified) (5 diffs)
-
GenPoly.h (modified) (3 diffs)
-
InstantiateGeneric.cc (modified) (1 diff)
-
Lvalue.cc (modified) (13 diffs)
-
ScopedSet.h (modified) (7 diffs)
-
ScrubTyVars.cc (modified) (1 diff)
-
Specialize.cc (modified) (6 diffs)
-
module.mk (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r7951100 rb067d9b 76 76 77 77 /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call 78 class Pass1 final : public BoxPass, public With TypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {78 class Pass1 final : public BoxPass, public WithConstTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting { 79 79 public: 80 80 Pass1(); … … 150 150 /// * Calculates polymorphic offsetof expressions from offset array 151 151 /// * Inserts dynamic calculation of polymorphic type layouts where needed 152 class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public With TypeSubstitution {152 class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithConstTypeSubstitution { 153 153 public: 154 154 PolyGenericCalculator(); … … 657 657 paramExpr = new AddressExpr( paramExpr ); 658 658 } // if 659 arg = appExpr-> get_args().insert( arg, paramExpr ); // add argument to function call659 arg = appExpr->args.insert( arg, paramExpr ); // add argument to function call 660 660 arg++; 661 661 // Build a comma expression to call the function and emulate a normal return. 662 662 CommaExpr *commaExpr = new CommaExpr( appExpr, retExpr ); 663 commaExpr-> set_env( appExpr->get_env() );664 appExpr-> set_env( 0 );663 commaExpr->env = appExpr->env; 664 appExpr->env = nullptr; 665 665 return commaExpr; 666 666 } … … 708 708 // if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) { 709 709 if ( isDynRet( function, tyVars ) ) { 710 ret = addRetParam( appExpr, function-> get_returnVals().front()->get_type(), arg );710 ret = addRetParam( appExpr, function->returnVals.front()->get_type(), arg ); 711 711 } // if 712 712 std::string mangleName = mangleAdapterName( function, tyVars ); … … 715 715 // cast adaptee to void (*)(), since it may have any type inside a polymorphic function 716 716 Type * adapteeType = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ); 717 appExpr->get_args().push_front( new CastExpr( appExpr-> get_function(), adapteeType ) );717 appExpr->get_args().push_front( new CastExpr( appExpr->function, adapteeType ) ); 718 718 appExpr->set_function( new NameExpr( adapterName ) ); // xxx - result is never set on NameExpr 719 719 … … 725 725 if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return; 726 726 727 if ( arg-> result->get_lvalue() ) {727 if ( arg->get_lvalue() ) { 728 728 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 729 729 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { … … 798 798 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 799 799 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) { 800 InferredParams::const_iterator inferParam = appExpr-> get_inferParams().find( (*assert)->get_uniqueId() );801 assertf( inferParam != appExpr-> get_inferParams().end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );800 InferredParams::const_iterator inferParam = appExpr->inferParams.find( (*assert)->get_uniqueId() ); 801 assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() ); 802 802 Expression *newExpr = inferParam->second.expr->clone(); 803 803 addCast( newExpr, (*assert)->get_type(), tyVars ); … … 837 837 deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 838 838 deref->result = arg->get_type()->clone(); 839 deref->result->set_lvalue( true );840 839 return deref; 841 840 } // if … … 1764 1763 1765 1764 Expression *PolyGenericCalculator::postmutate( SizeofExpr *sizeofExpr ) { 1766 Type *ty = sizeofExpr->get_isType() ? 1765 Type *ty = sizeofExpr->get_isType() ? 1767 1766 sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result(); 1768 1767 1769 1768 Expression * gen = genSizeof( ty ); 1770 1769 if ( gen ) { -
src/GenPoly/GenPoly.cc
r7951100 rb067d9b 24 24 #include <vector> // for vector 25 25 26 #include "AST/Type.hpp" 26 27 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_it... 27 28 #include "ResolvExpr/typeops.h" // for flatten … … 262 263 } else { 263 264 return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise 265 } 266 } 267 268 const ast::FunctionType * getFunctionType( const ast::Type * ty ) { 269 if ( auto pty = dynamic_cast< const ast::PointerType * >( ty ) ) { 270 return pty->base.as< ast::FunctionType >(); 271 } else { 272 return dynamic_cast< const ast::FunctionType * >( ty ); 264 273 } 265 274 } … … 440 449 } 441 450 442 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env ) {451 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) { 443 452 // is parameter is not polymorphic, don't need to box 444 453 if ( ! isPolyType( param, exprTyVars ) ) return false; … … 450 459 } 451 460 452 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env ) {461 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) { 453 462 FunctionType * function = getFunctionType( appExpr->function->result ); 454 463 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() ); … … 459 468 460 469 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) { 461 // xxx - should this actually be insert? 462 tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar }; 470 tyVarMap.insert( tyVar->name, TypeDecl::Data{ tyVar } ); 463 471 } 464 472 -
src/GenPoly/GenPoly.h
r7951100 rb067d9b 20 20 21 21 #include "ErasableScopedMap.h" // for ErasableScopedMap 22 #include "AST/Fwd.hpp" 22 23 #include "SymTab/Mangler.h" // for Mangler 23 24 #include "SynTree/Declaration.h" // for TypeDecl::Data, AggregateDecl, Type... … … 72 73 /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise 73 74 FunctionType *getFunctionType( Type *ty ); 75 const ast::FunctionType * getFunctionType( const ast::Type * ty ); 74 76 75 77 /// If expr (after dereferencing N >= 0 pointers) is a variable expression, returns the variable expression, NULL otherwise; … … 81 83 82 84 /// true if arg requires boxing given exprTyVars 83 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env );85 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ); 84 86 85 87 /// true if arg requires boxing in the call to appExpr 86 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env );88 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ); 87 89 88 90 /// Adds the type variable `tyVar` to `tyVarMap` -
src/GenPoly/InstantiateGeneric.cc
r7951100 rb067d9b 168 168 169 169 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 170 struct GenericInstantiator final : public With TypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards {170 struct GenericInstantiator final : public WithConstTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards { 171 171 /// Map of (generic type, parameter list) pairs to concrete type instantiations 172 172 InstantiationMap< AggregateDecl, AggregateDecl > instantiations; -
src/GenPoly/Lvalue.cc
r7951100 rb067d9b 21 21 #include "Lvalue.h" 22 22 23 #include "InitTweak/InitTweak.h" 23 24 #include "Parser/LinkageSpec.h" // for Spec, isBuiltin, Intrinsic 24 25 #include "ResolvExpr/TypeEnvironment.h" // for AssertionSet, OpenVarSet 25 26 #include "ResolvExpr/Unify.h" // for unify 26 27 #include "ResolvExpr/typeops.h" 27 #include "SymTab/Autogen.h"28 28 #include "SymTab/Indexer.h" // for Indexer 29 29 #include "SynTree/Declaration.h" // for Declaration, FunctionDecl … … 33 33 #include "SynTree/Type.h" // for PointerType, Type, FunctionType 34 34 #include "SynTree/Visitor.h" // for Visitor, acceptAll 35 #include "Validate/FindSpecialDecls.h" // for dereferenceOperator 35 36 36 37 #if 0 … … 44 45 // TODO: fold this into the general createDeref function?? 45 46 Expression * mkDeref( Expression * arg ) { 46 if ( SymTab::dereferenceOperator ) {47 if ( Validate::dereferenceOperator ) { 47 48 // note: reference depth can be arbitrarily deep here, so peel off the outermost pointer/reference, not just pointer because they are effecitvely equivalent in this pass 48 VariableExpr * deref = new VariableExpr( SymTab::dereferenceOperator );49 VariableExpr * deref = new VariableExpr( Validate::dereferenceOperator ); 49 50 deref->result = new PointerType( Type::Qualifiers(), deref->result ); 50 51 Type * base = InitTweak::getPointerBase( arg->result ); … … 53 54 delete ret->result; 54 55 ret->result = base->clone(); 55 ret->result->set_lvalue( true );56 56 return ret; 57 57 } else { … … 146 146 147 147 namespace { 148 // true for intrinsic function calls that return a reference148 // true for intrinsic function calls that return an lvalue in C 149 149 bool isIntrinsicReference( Expression * expr ) { 150 // known intrinsic-reference prelude functions 151 static std::set<std::string> lvalueFunctions = { "*?", "?[?]" }; 150 152 if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( expr ) ) { 151 153 std::string fname = InitTweak::getFunctionName( untyped ); 152 // known intrinsic-reference prelude functions 153 return fname == "*?" || fname == "?[?]"; 154 return lvalueFunctions.count(fname); 154 155 } else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) { 155 156 if ( DeclarationWithType * func = InitTweak::getFunction( appExpr ) ) { 156 // use type of return variable rather than expr result type, since it may have been changed to a pointer type 157 FunctionType * ftype = GenPoly::getFunctionType( func->get_type() ); 158 Type * ret = ftype->returnVals.empty() ? nullptr : ftype->returnVals.front()->get_type(); 159 return func->linkage == LinkageSpec::Intrinsic && dynamic_cast<ReferenceType *>( ret ); 157 return func->linkage == LinkageSpec::Intrinsic && lvalueFunctions.count(func->name); 160 158 } 161 159 } … … 168 166 ReferenceType * result = strict_dynamic_cast< ReferenceType * >( appExpr->result ); 169 167 appExpr->result = result->base->clone(); 170 appExpr->result->set_lvalue( true );171 168 if ( ! inIntrinsic ) { 172 169 // when not in an intrinsic function, add a cast to … … 197 194 unsigned int i = 0; 198 195 const unsigned int end = ftype->parameters.size(); 196 197 /// The for loop may eagerly dereference the iterators and fail on empty lists 198 if(i == end) { return appExpr; } 199 199 for ( auto p : unsafe_group_iterate( appExpr->args, ftype->parameters ) ) { 200 if (i == end) break;201 200 Expression *& arg = std::get<0>( p ); 202 201 Type * formal = std::get<1>( p )->get_type(); … … 212 211 // TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation. 213 212 214 if ( function-> get_linkage()!= LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {213 if ( function->linkage != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) { 215 214 // needed for definition of prelude functions, etc. 216 215 // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address … … 228 227 arg = new AddressExpr( arg ); 229 228 // } else if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) { 230 } else if ( function-> get_linkage()== LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {229 } else if ( function->linkage == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) { 231 230 // argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument 232 231 PRINT( … … 243 242 } 244 243 ++i; 244 if (i == end) break; 245 245 } 246 246 } … … 355 355 Type * destType = castExpr->result; 356 356 Type * srcType = castExpr->arg->result; 357 assertf( destType, "Cast to no type in: %s", toCString( castExpr ) ); 358 assertf( srcType, "Cast from no type in: %s", toCString( castExpr ) ); 357 359 int depth1 = destType->referenceDepth(); 358 360 int depth2 = srcType->referenceDepth(); 359 361 int diff = depth1 - depth2; 360 362 361 if ( diff > 0 && ! srcType->get_lvalue() ) {363 if ( diff > 0 && ! castExpr->arg->get_lvalue() ) { 362 364 // rvalue to reference conversion -- introduce temporary 363 365 // know that reference depth of cast argument is 0, need to introduce n temporaries for reference depth of n, e.g. … … 403 405 ret = new AddressExpr( ret ); 404 406 } 405 if ( srcType->get_lvalue() && ! ResolvExpr::typesCompatible( srcType, strict_dynamic_cast<ReferenceType *>( destType )->base, SymTab::Indexer() ) ) {407 if ( castExpr->arg->get_lvalue() && ! ResolvExpr::typesCompatible( srcType, strict_dynamic_cast<ReferenceType *>( destType )->base, SymTab::Indexer() ) ) { 406 408 // must keep cast if cast-to type is different from the actual type 407 409 castExpr->arg = ret; … … 432 434 delete ret->result; 433 435 ret->result = castExpr->result; 434 ret->result->set_lvalue( true); // ensure result is lvalue436 assert( ret->get_lvalue() ); // ensure result is lvalue 435 437 castExpr->env = nullptr; 436 438 castExpr->arg = nullptr; -
src/GenPoly/ScopedSet.h
r7951100 rb067d9b 38 38 typedef typename Scope::pointer pointer; 39 39 typedef typename Scope::const_pointer const_pointer; 40 40 41 41 class iterator : public std::iterator< std::bidirectional_iterator_tag, 42 42 value_type > { … … 72 72 return *this; 73 73 } 74 74 75 75 reference operator* () { return *it; } 76 76 pointer operator-> () { return it.operator->(); } … … 104 104 bool operator!= (const iterator &that) { return !( *this == that ); } 105 105 106 size_type get_level() const { return i; } 107 106 108 private: 107 109 scope_list const *scopes; … … 180 182 bool operator!= (const const_iterator &that) { return !( *this == that ); } 181 183 184 size_type get_level() const { return i; } 185 182 186 private: 183 187 scope_list const *scopes; … … 185 189 size_type i; 186 190 }; 187 191 188 192 /// Starts a new scope 189 193 void beginScope() { … … 222 226 return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) ); 223 227 } 224 228 225 229 /// Finds the given key in the outermost scope inside the given scope where it occurs 226 230 iterator findNext( const_iterator &it, const Value &key ) { … … 242 246 return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second ); 243 247 } 244 248 245 249 }; 246 250 } // namespace GenPoly -
src/GenPoly/ScrubTyVars.cc
r7951100 rb067d9b 50 50 delete typeInst; 51 51 return new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ); 52 default: 53 assertf(false, "Unhandled tyvar kind: %d", tyVar->second.kind); 52 54 } // switch 53 55 } // if -
src/GenPoly/Specialize.cc
r7951100 rb067d9b 42 42 43 43 namespace GenPoly { 44 struct Specialize final : public With TypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> {44 struct Specialize final : public WithConstTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> { 45 45 Expression * postmutate( ApplicationExpr *applicationExpr ); 46 46 Expression * postmutate( CastExpr *castExpr ); … … 54 54 55 55 /// Looks up open variables in actual type, returning true if any of them are bound in the environment or formal type. 56 bool needsPolySpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {56 bool needsPolySpecialization( Type *formalType, Type *actualType, const TypeSubstitution *env ) { 57 57 if ( env ) { 58 58 using namespace ResolvExpr; … … 145 145 } 146 146 147 bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {147 bool needsSpecialization( Type *formalType, Type *actualType, const TypeSubstitution *env ) { 148 148 return needsPolySpecialization( formalType, actualType, env ) || needsTupleSpecialization( formalType, actualType ); 149 149 } … … 245 245 appExpr->env = TypeSubstitution::newFromExpr( appExpr, env ); 246 246 if ( inferParams ) { 247 appExpr-> get_inferParams()= *inferParams;247 appExpr->inferParams = *inferParams; 248 248 } // if 249 249 … … 284 284 std::list< Expression* >::iterator actual; 285 285 for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) { 286 *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr-> get_inferParams());286 *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->inferParams ); 287 287 } 288 288 } … … 295 295 // alternatively, if order starts to matter then copy appExpr's inferParams and pass them to handleExplicitParams. 296 296 handleExplicitParams( appExpr ); 297 for ( InferredParams::iterator inferParam = appExpr-> get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) {298 inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, inferParam->second.inferParams.get());297 for ( InferredParams::iterator inferParam = appExpr->inferParams.begin(); inferParam != appExpr->inferParams.end(); ++inferParam ) { 298 inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, &inferParam->second.expr->inferParams ); 299 299 } 300 300 } -
src/GenPoly/module.mk
r7951100 rb067d9b 22 22 GenPoly/FindFunction.cc \ 23 23 GenPoly/InstantiateGeneric.cc 24 25 SRCDEMANGLE += GenPoly/GenPoly.cc GenPoly/Lvalue.cc 26
Note:
See TracChangeset
for help on using the changeset viewer.