- Timestamp:
- Nov 1, 2022, 10:06:40 PM (3 years ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 7cf8006
- Parents:
- 0bdfcc3 (diff), 03c56f6 (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
- Files:
-
- 5 edited
-
AST/Pass.impl.hpp (modified) (2 diffs)
-
Common/PassVisitor.impl.h (modified) (2 diffs)
-
GenPoly/Box.cc (modified) (17 diffs)
-
GenPoly/GenPoly.cc (modified) (2 diffs)
-
GenPoly/InstantiateGenericNew.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Pass.impl.hpp
r0bdfcc3 re50d9cb8 617 617 maybe_accept( node, &FunctionDecl::returns ); 618 618 maybe_accept( node, &FunctionDecl::type ); 619 maybe_accept( node, &FunctionDecl::attributes ); 619 620 // First remember that we are now within a function. 620 621 ValueGuard< bool > oldInFunction( inFunction ); … … 625 626 atFunctionTop = true; 626 627 maybe_accept( node, &FunctionDecl::stmts ); 627 maybe_accept( node, &FunctionDecl::attributes );628 628 } 629 629 } -
src/Common/PassVisitor.impl.h
r0bdfcc3 re50d9cb8 607 607 indexerAddId( &func ); 608 608 maybeMutate_impl( node->type, *this ); 609 maybeMutate_impl( node->attributes, *this ); 609 610 // First remember that we are now within a function. 610 611 ValueGuard< bool > oldInFunction( inFunction ); … … 615 616 atFunctionTop = true; 616 617 maybeMutate_impl( node->statements, *this ); 617 maybeMutate_impl( node->attributes, *this );618 618 } 619 619 } -
src/GenPoly/Box.cc
r0bdfcc3 re50d9cb8 68 68 /// Adds layout-generation functions to polymorphic types. 69 69 class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting { 70 // Current level of nested functions:71 unsigned int functionNesting = 0;72 70 public: 73 void previsit( FunctionDecl *functionDecl );74 71 void previsit( StructDecl *structDecl ); 75 72 void previsit( UnionDecl *unionDecl ); … … 237 234 ////////////////////////////////// LayoutFunctionBuilder //////////////////////////////////////////// 238 235 239 void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) {240 visit_children = false;241 maybeAccept( functionDecl->get_functionType(), *visitor );242 ++functionNesting;243 maybeAccept( functionDecl->get_statements(), *visitor );244 --functionNesting;245 }246 247 236 /// Get a list of type declarations that will affect a layout function 248 237 std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) { … … 271 260 272 261 /// Builds a layout function declaration 273 FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, unsigned int functionNesting, FunctionType *layoutFnType ) {262 FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, bool isInFunction, FunctionType *layoutFnType ) { 274 263 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 275 264 // because each unit generates copies of the default routines for each aggregate. 276 265 FunctionDecl *layoutDecl = new FunctionDecl( layoutofName( typeDecl ), 277 functionNesting > 0? Type::StorageClasses() : Type::StorageClasses( Type::Static ),266 isInFunction ? Type::StorageClasses() : Type::StorageClasses( Type::Static ), 278 267 LinkageSpec::AutoGen, layoutFnType, new CompoundStmt(), 279 268 std::list< Attribute * >(), Type::FuncSpecifiers( Type::Inline ) ); … … 347 336 348 337 // build function decl 349 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, functionNesting, layoutFnType );338 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, isInFunction(), layoutFnType ); 350 339 351 340 // calculate struct layout in function body … … 354 343 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 0 ) ) ) ); 355 344 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 356 unsigned long n_members = 0; 357 bool firstMember = true; 358 for ( Declaration* member : structDecl->get_members() ) { 359 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member ); 345 for ( auto index_member : enumerate( structDecl->members ) ) { 346 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( index_member.val ); 360 347 assert( dwt ); 361 348 Type *memberType = dwt->get_type(); 362 349 363 if ( firstMember ) { 364 firstMember = false; 365 } else { 350 if ( 0 < index_member.idx ) { 366 351 // make sure all members after the first (automatically aligned at 0) are properly padded for alignment 367 352 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) ); … … 369 354 370 355 // place current size in the current offset index 371 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( n_members) ) ),356 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( index_member.idx ) ) ), 372 357 derefVar( sizeParam ) ) ); 373 ++n_members;374 358 375 359 // add member size to current size … … 406 390 407 391 // build function decl 408 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, functionNesting, layoutFnType );392 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, isInFunction(), layoutFnType ); 409 393 410 394 // calculate union layout in function body … … 566 550 if ( tyParam.second.isComplete ) { 567 551 Type *concrete = env->lookup( tyParam.first ); 568 if ( concrete ) { 569 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 570 arg++; 571 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 572 arg++; 573 } else { 574 // xxx - should this be an assertion? 575 SemanticError( appExpr, toString( *env, "\nunbound type variable: ", tyParam.first, " in application " ) ); 576 } // if 552 // If there is an unbound type variable, it should have detected already. 553 assertf( concrete, "Unbound type variable: %s in: %s", 554 toCString( tyParam.first ), toCString( *env ) ); 555 556 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 557 arg++; 558 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 559 arg++; 577 560 } // if 578 561 } // for … … 638 621 639 622 void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) { 640 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param) {641 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );623 for ( Expression * const param : params ) { 624 TypeExpr *paramType = dynamic_cast< TypeExpr* >( param ); 642 625 assertf(paramType, "Aggregate parameters should be type expressions"); 643 626 paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) ); … … 692 675 } 693 676 677 // find instances of polymorphic type parameters 678 struct PolyFinder { 679 const TyVarMap * tyVars = nullptr; 680 bool found = false; 681 682 void previsit( TypeInstType * t ) { 683 if ( isPolyType( t, *tyVars ) ) { 684 found = true; 685 } 686 } 687 }; 688 689 // true if there is an instance of a polymorphic type parameter in t 690 bool hasPolymorphism( Type * t, const TyVarMap &tyVars ) { 691 PassVisitor<PolyFinder> finder; 692 finder.pass.tyVars = &tyVars; 693 maybeAccept( t, finder ); 694 return finder.pass.found; 695 } 696 697 /// cast parameters to polymorphic functions so that types are replaced with 698 /// void * if they are type parameters in the formal type. 699 /// this gets rid of warnings from gcc. 700 void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) { 701 // type contains polymorphism, but isn't exactly a polytype, in which case it 702 // has some real actual type (e.g. unsigned int) and casting to void * is wrong 703 if ( hasPolymorphism( formal, tyVars ) && ! isPolyType( formal, tyVars ) ) { 704 Type * newType = formal->clone(); 705 newType = ScrubTyVars::scrub( newType, tyVars ); 706 actual = new CastExpr( actual, newType ); 707 } // if 708 } 709 694 710 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 695 711 assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() ); 712 addCast( arg, param, exprTyVars ); 696 713 if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return; 697 714 … … 724 741 } 725 742 726 // find instances of polymorphic type parameters727 struct PolyFinder {728 const TyVarMap * tyVars = nullptr;729 bool found = false;730 731 void previsit( TypeInstType * t ) {732 if ( isPolyType( t, *tyVars ) ) {733 found = true;734 }735 }736 };737 738 // true if there is an instance of a polymorphic type parameter in t739 bool hasPolymorphism( Type * t, const TyVarMap &tyVars ) {740 PassVisitor<PolyFinder> finder;741 finder.pass.tyVars = &tyVars;742 maybeAccept( t, finder );743 return finder.pass.found;744 }745 746 /// cast parameters to polymorphic functions so that types are replaced with747 /// void * if they are type parameters in the formal type.748 /// this gets rid of warnings from gcc.749 void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {750 // type contains polymorphism, but isn't exactly a polytype, in which case it751 // has some real actual type (e.g. unsigned int) and casting to void * is wrong752 if ( hasPolymorphism( formal, tyVars ) && ! isPolyType( formal, tyVars ) ) {753 Type * newType = formal->clone();754 newType = ScrubTyVars::scrub( newType, tyVars );755 actual = new CastExpr( actual, newType );756 } // if757 }758 759 743 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 760 for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->parameters.end(); ++param, ++arg) {761 assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( *param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() );762 addCast( *arg, (*param)->get_type(), exprTyVars );763 boxParam( (*param)->get_type(), *arg, exprTyVars );744 for ( DeclarationWithType * param : function->parameters ) { 745 assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() ); 746 boxParam( param->get_type(), *arg, exprTyVars ); 747 ++arg; 764 748 } // for 765 749 } … … 767 751 void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) { 768 752 std::list< Expression *>::iterator cur = arg; 769 for ( Type ::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar) {770 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert) {771 InferredParams::const_iterator inferParam = appExpr->inferParams.find( (*assert)->get_uniqueId() );772 assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );753 for ( TypeDecl * const tyVar : functionType->forall ) { 754 for ( DeclarationWithType * const assert : tyVar->assertions ) { 755 InferredParams::const_iterator inferParam = appExpr->inferParams.find( assert->get_uniqueId() ); 756 assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( assert ).c_str(), toString( appExpr ).c_str() ); 773 757 Expression *newExpr = inferParam->second.expr->clone(); 774 addCast( newExpr, (*assert)->get_type(), tyVars ); 775 boxParam( (*assert)->get_type(), newExpr, tyVars ); 758 boxParam( assert->get_type(), newExpr, tyVars ); 776 759 appExpr->get_args().insert( cur, newExpr ); 777 760 } // for … … 803 786 assert( param ); 804 787 assert( arg ); 805 if ( isPolyType( realParam->get_type(), tyVars ) ) { 806 if ( ! isPolyType( arg->get_type() ) ) { 807 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 808 deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 809 deref->result = arg->get_type()->clone(); 810 return deref; 811 } // if 788 if ( isPolyType( realParam->get_type(), tyVars ) 789 && ! isPolyType( arg->get_type() ) ) { 790 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 791 deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 792 deref->result = arg->get_type()->clone(); 793 return deref; 812 794 } // if 813 795 return new VariableExpr( param ); … … 1145 1127 } 1146 1128 1147 Expression * Pass1::postmutate( UntypedExpr *expr) {1129 bool isPolyDeref( UntypedExpr * expr, TyVarMap const & scopeTyVars, TypeSubstitution const * env ) { 1148 1130 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1149 1131 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) { 1150 1132 if ( name->name == "*?" ) { 1151 Expression *ret = expr->args.front(); 1152 expr->args.clear(); 1153 delete expr; 1154 return ret; 1133 return true; 1155 1134 } // if 1156 1135 } // if 1157 1136 } // if 1137 return false; 1138 } 1139 1140 Expression * Pass1::postmutate( UntypedExpr *expr ) { 1141 if ( isPolyDeref( expr, scopeTyVars, env ) ) { 1142 Expression *ret = expr->args.front(); 1143 expr->args.clear(); 1144 delete expr; 1145 return ret; 1146 } 1158 1147 return expr; 1159 1148 } … … 1165 1154 bool needs = false; 1166 1155 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->arg ) ) { 1167 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1168 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) { 1169 if ( name->name == "*?" ) { 1170 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) { 1171 assert( appExpr->function->result ); 1172 FunctionType *function = getFunctionType( appExpr->function->result ); 1173 assert( function ); 1174 needs = needsAdapter( function, scopeTyVars ); 1175 } // if 1176 } // if 1156 if ( isPolyDeref( expr, scopeTyVars, env ) ) { 1157 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) { 1158 assert( appExpr->function->result ); 1159 FunctionType *function = getFunctionType( appExpr->function->result ); 1160 assert( function ); 1161 needs = needsAdapter( function, scopeTyVars ); 1177 1162 } // if 1178 1163 } // if … … 1226 1211 std::list< DeclarationWithType *> ¶mList = functionType->parameters; 1227 1212 std::list< FunctionType *> functions; 1228 for ( DeclarationWithType * const arg : functionType->parameters ) {1213 for ( DeclarationWithType * const arg : functionType->parameters ) { 1229 1214 Type *orig = arg->get_type(); 1230 1215 findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter ); … … 1447 1432 1448 1433 if(!expect_func_type) { 1449 GuardAction( [this]() {1450 knownLayouts.endScope();1451 knownOffsets.endScope();1452 });1453 1434 // If this is the first function type we see 1454 1435 // Then it's the type of the declaration and we care about it 1455 knownLayouts.beginScope(); 1456 knownOffsets.beginScope(); 1436 GuardScope( *this ); 1457 1437 } 1458 1438 -
src/GenPoly/GenPoly.cc
r0bdfcc3 re50d9cb8 120 120 const ast::Type * replaceTypeInst(const ast::Type * type, const ast::TypeSubstitution * env) { 121 121 if (!env) return type; 122 if ( auto typeInst = dynamic_cast<const ast::TypeInstType*> (type)) {122 if ( auto typeInst = dynamic_cast<const ast::TypeInstType*>(type) ) { 123 123 auto newType = env->lookup(typeInst); 124 124 if (newType) return newType; … … 229 229 auto var = typeVars.find( *inst ); 230 230 if ( var != typeVars.end() && var->second.isComplete ) { 231 231 return inst; 232 232 } 233 233 } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) { -
src/GenPoly/InstantiateGenericNew.cpp
r0bdfcc3 re50d9cb8 10 10 // Created On : Tue Aug 16 10:51:00 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Sep 13 16:03:00 202213 // Update Count : 012 // Last Modified On : Mon Oct 31 16:48:00 2022 13 // Update Count : 1 14 14 // 15 15 … … 378 378 // Ptr(int) p; 379 379 // int i; 380 // The original expression: 380 381 // p.x = &i; 381 // becomes 382 // int *& _dtype_static_member_0 = (int **)&p.x; 383 // _dtype_static_member_0 = &i; 382 // Becomes the expression/declaration: 383 // int *& _dtype_static_member_0; 384 // (_dtype_static_member_0 = (int**)&p.x, 385 // _dtype_static_member_0) = &i; 386 387 // The declaration is simple: 384 388 static UniqueName tmpNamer( "_dtype_static_member_" ); 385 ast::Expr * init = new ast::CastExpr( location,386 new ast::AddressExpr( location, memberExpr ),387 new ast::PointerType( ast::deepCopy( concType ) ),388 ast::ExplicitCast389 );390 389 ast::ObjectDecl * tmp = new ast::ObjectDecl( location, 391 390 tmpNamer.newName(), 392 391 new ast::ReferenceType( concType ), 393 n ew ast::SingleInit( location, init ),392 nullptr, 394 393 ast::Storage::Classes(), 395 394 ast::Linkage::C 396 395 ); 397 396 stmtsToAddBefore.push_back( new ast::DeclStmt( location, tmp ) ); 398 return new ast::VariableExpr( location, tmp ); 397 398 // The expression is more complex, uses references and reference / 399 // pointer parity. But breaking it up risks reordering. 400 return new ast::CommaExpr( location, 401 ast::UntypedExpr::createAssign( location, 402 new ast::VariableExpr( location, tmp ), 403 new ast::CastExpr( location, 404 new ast::AddressExpr( location, memberExpr ), 405 new ast::PointerType( ast::deepCopy( concType ) ), 406 ast::ExplicitCast 407 ) 408 ), 409 new ast::VariableExpr( location, tmp ) 410 ); 399 411 } else { 400 412 // Here, it can simply add a cast to actual types.
Note:
See TracChangeset
for help on using the changeset viewer.