Changeset 78a0b88
- Timestamp:
- Sep 1, 2017, 3:33:25 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- bc3127d
- Parents:
- e8ccca3 (diff), a01f7c94 (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:
-
- 3 added
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
re8ccca3 r78a0b88 195 195 } 196 196 197 output << kind; 198 if ( aggDecl->get_name() != "" ) 199 output << aggDecl->get_name(); 197 output << kind << aggDecl->get_name(); 200 198 201 199 if ( aggDecl->has_body() ) { … … 233 231 genAttributes( enumDecl->get_attributes() ); 234 232 235 if ( enumDecl->get_name() != "" ) 236 output << enumDecl->get_name(); 233 output << enumDecl->get_name(); 237 234 238 235 std::list< Declaration* > &memb = enumDecl->get_members(); … … 260 257 } 261 258 262 void CodeGenerator::visit( __attribute__((unused)) TraitDecl * traitDecl ) {} 259 void CodeGenerator::visit( TraitDecl * traitDecl ) { 260 assertf( ! genC, "TraitDecl nodes should not reach code generation." ); 261 extension( traitDecl ); 262 handleAggregate( traitDecl, "trait " ); 263 } 263 264 264 265 void CodeGenerator::visit( TypedefDecl * typeDecl ) { … … 760 761 for ( Statement * stmt : stmts ) { 761 762 updateLocation( stmt ); 762 output << printLabels( stmt->get_labels() );763 output << indent << printLabels( stmt->get_labels() ); 763 764 if ( i+1 == numStmts ) { 764 765 // last statement in a statement expression needs to be handled specially - -
src/CodeGen/Generate.cc
re8ccca3 r78a0b88 21 21 #include "CodeGenerator.h" // for CodeGenerator, doSemicolon, oper... 22 22 #include "GenType.h" // for genPrettyType 23 #include "Common/PassVisitor.h" // for PassVisitor 23 24 #include "Parser/LinkageSpec.h" // for isBuiltin, isGeneratable 24 25 #include "SynTree/BaseSyntaxNode.h" // for BaseSyntaxNode … … 29 30 30 31 namespace CodeGen { 32 namespace { 33 /// Removes misc. nodes that should not exist in CodeGen 34 struct TreeCleaner { 35 void visit( CompoundStmt * stmt ); 36 37 static bool shouldClean( Declaration * ); 38 }; 39 40 void cleanTree( std::list< Declaration * > & translationUnit ) { 41 PassVisitor<TreeCleaner> cleaner; 42 filter( translationUnit, [](Declaration * decl) { return TreeCleaner::shouldClean(decl); }, false ); 43 acceptAll( translationUnit, cleaner ); 44 } // cleanTree 45 } // namespace 46 31 47 void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC, bool lineMarks ) { 48 cleanTree( translationUnit ); 49 32 50 CodeGen::CodeGenerator cgv( os, pretty, generateC, lineMarks ); 33 51 for ( auto & dcl : translationUnit ) { … … 52 70 os << std::endl; 53 71 } 72 73 namespace { 74 void TreeCleaner::visit( CompoundStmt * cstmt ) { 75 filter( cstmt->kids, [](Statement * stmt) { 76 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) { 77 return shouldClean( declStmt->decl ); 78 } 79 return false; 80 }, false ); 81 } 82 83 bool TreeCleaner::shouldClean( Declaration * decl ) { 84 return dynamic_cast< TraitDecl * >( decl ); 85 } 86 } // namespace 54 87 } // namespace CodeGen 55 88 -
src/Common/utility.h
re8ccca3 r78a0b88 172 172 auto filter(Args&&... args) -> decltype(std::copy_if(std::forward<Args>(args)...)) { 173 173 return std::copy_if(std::forward<Args>(args)...); 174 } 175 176 template <typename E, typename UnaryPredicate, template< typename, typename...> class Container, typename... Args > 177 void filter( Container< E *, Args... > & container, UnaryPredicate pred, bool doDelete ) { 178 auto i = begin( container ); 179 while ( i != end( container ) ) { 180 auto it = next( i ); 181 if ( pred( *i ) ) { 182 if ( doDelete ) { 183 delete *i; 184 } // if 185 container.erase( i ); 186 } // if 187 i = it; 188 } // while 174 189 } 175 190 -
src/GenPoly/Box.cc
re8ccca3 r78a0b88 141 141 virtual StructDecl *mutate( StructDecl *structDecl ) override; 142 142 virtual UnionDecl *mutate( UnionDecl *unionDecl ) override; 143 virtual TraitDecl *mutate( TraitDecl *unionDecl ) override; 143 144 virtual TypeDecl *mutate( TypeDecl *typeDecl ) override; 144 145 virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ) override; … … 216 217 private: 217 218 }; 218 219 219 } // anonymous namespace 220 220 … … 896 896 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 897 897 bodyStmt = new ExprStmt( noLabels, adapteeApp ); 898 // } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {899 898 } else if ( isDynType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 900 899 // return type T … … 1352 1351 } 1353 1352 1353 TraitDecl * Pass2::mutate( TraitDecl *aggDecl ) { 1354 return handleAggDecl( aggDecl ); 1355 } 1356 1354 1357 TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) { 1355 1358 addToTyVarMap( typeDecl, scopeTyVars ); … … 1377 1380 Type *Pass2::mutate( FunctionType *funcType ) { 1378 1381 scopeTyVars.beginScope(); 1382 1379 1383 makeTyVarMap( funcType, scopeTyVars ); 1380 1384 … … 1550 1554 // (alloca was previously used, but can't be safely used in loops) 1551 1555 Type *declType = objectDecl->get_type(); 1552 std::string bufName = bufNamer.newName(); 1553 ObjectDecl *newBuf = new ObjectDecl( bufName, Type::StorageClasses(), LinkageSpec::C, 0, 1556 ObjectDecl *newBuf = new ObjectDecl( bufNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, 1554 1557 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Kind::Char), new NameExpr( sizeofName( mangleType(declType) ) ), 1555 true, false, std::list<Attribute*>{ new Attribute( std::string{"aligned"}, std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ) } ), 0 );1558 true, false, std::list<Attribute*>{ new Attribute( "aligned", std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ) } ), 0 ); 1556 1559 stmtsToAdd.push_back( new DeclStmt( noLabels, newBuf ) ); 1557 1560 1558 1561 delete objectDecl->get_init(); 1559 1560 objectDecl->set_init( new SingleInit( new NameExpr( bufName ) ) ); 1562 objectDecl->set_init( new SingleInit( new VariableExpr( newBuf ) ) ); 1561 1563 } 1562 1564 } -
src/GenPoly/GenPoly.cc
re8ccca3 r78a0b88 336 336 assertf(bparam, "Aggregate parameters should be type expressions"); 337 337 338 // xxx - might need to let VoidType be a wildcard here too; could have some voids 338 // xxx - might need to let VoidType be a wildcard here too; could have some voids 339 339 // stuffed in for dtype-statics. 340 340 // if ( is<VoidType>( aparam->get_type() ) || is<VoidType>( bparam->get_type() ) ) continue; 341 341 if ( ! typesPolyCompatible( aparam->get_type(), bparam->get_type() ) ) return false; 342 342 } 343 343 344 344 return true; 345 345 } … … 350 350 // polymorphic types always match 351 351 if ( aid == type_index{typeid(TypeInstType)} ) return true; 352 352 353 353 type_index bid{ typeid(*b) }; 354 354 // polymorphic types always match 355 355 if ( bid == type_index{typeid(TypeInstType)} ) return true; 356 356 357 357 // can't match otherwise if different types 358 358 if ( aid != bid ) return false; … … 377 377 ConstantExpr *ad = dynamic_cast<ConstantExpr*>( aa->get_dimension() ); 378 378 ConstantExpr *bd = dynamic_cast<ConstantExpr*>( ba->get_dimension() ); 379 if ( ad && bd 379 if ( ad && bd 380 380 && ad->get_constant()->get_value() != bd->get_constant()->get_value() ) 381 381 return false; … … 433 433 434 434 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) { 435 // xxx - should this actually be insert? 435 436 tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar }; 436 437 } -
src/Parser/ExpressionNode.cc
re8ccca3 r78a0b88 360 360 Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node ) { 361 361 std::list< Expression * > args; 362 args.push_back( maybeMoveBuild< Expression >(expr_node) ); // xxx 362 args.push_back( maybeMoveBuild< Expression >(expr_node) ); // xxx -- this is exactly the same as the val case now, refactor this code. 363 363 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args ); 364 364 } // build_unary_ptr -
src/Parser/StatementNode.cc
re8ccca3 r78a0b88 99 99 } // if 100 100 101 Expression * cond = ctl->condition ? maybeMoveBuild< Expression >(ctl->condition) : new VariableExpr( dynamic_cast<DeclarationWithType *>( dynamic_cast<DeclStmt *>( init.back() )->decl ) ); 101 Expression * cond = nullptr; 102 if ( ctl->condition ) { 103 // compare the provided condition against 0 104 cond = notZeroExpr( maybeMoveBuild< Expression >(ctl->condition) ); 105 } else { 106 for ( Statement * stmt : init ) { 107 // build the && of all of the declared variables compared against 0 108 DeclStmt * declStmt = safe_dynamic_cast< DeclStmt * >( stmt ); 109 DeclarationWithType * dwt = safe_dynamic_cast< DeclarationWithType * >( declStmt->decl ); 110 Expression * nze = notZeroExpr( new VariableExpr( dwt ) ); 111 cond = cond ? new LogicalExpr( cond, nze, true ) : nze; 112 } 113 } 102 114 delete ctl; 103 return new IfStmt( noLabels, notZeroExpr( cond ), thenb, elseb, init );115 return new IfStmt( noLabels, cond, thenb, elseb, init ); 104 116 } 105 117 -
src/ResolvExpr/AlternativeFinder.cc
re8ccca3 r78a0b88 749 749 if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) { 750 750 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 751 referenceToRvalueConversion( func->expr ); 751 Alternative newFunc( *func ); 752 referenceToRvalueConversion( newFunc.expr ); 752 753 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 753 754 // XXX 754 755 //Designators::check_alternative( function, *actualAlt ); 755 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );756 makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) ); 756 757 } 757 758 } 758 759 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer) 759 referenceToRvalueConversion( func->expr );760 760 EqvClass eqvClass; 761 761 if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) { 762 762 if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) { 763 Alternative newFunc( *func ); 764 referenceToRvalueConversion( newFunc.expr ); 763 765 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 764 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );766 makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) ); 765 767 } // for 766 768 } // if … … 773 775 if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) { 774 776 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 775 referenceToRvalueConversion( funcOp->expr ); 777 Alternative newFunc( *funcOp ); 778 referenceToRvalueConversion( newFunc.expr ); 776 779 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 777 780 AltList currentAlt; 778 781 currentAlt.push_back( *func ); 779 782 currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() ); 780 makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );783 makeFunctionAlternatives( newFunc, function, currentAlt, std::back_inserter( candidates ) ); 781 784 } // for 782 785 } // if -
src/ResolvExpr/RenameVars.cc
re8ccca3 r78a0b88 88 88 typeBefore( aggregateUseType ); 89 89 acceptAll( aggregateUseType->get_parameters(), *this ); 90 acceptAll( aggregateUseType->get_members(), *this );91 90 typeAfter( aggregateUseType ); 92 91 } -
src/ResolvExpr/TypeEnvironment.cc
re8ccca3 r78a0b88 25 25 26 26 namespace ResolvExpr { 27 // adding this comparison operator significantly improves assertion resolution run time for28 // some cases. The current resolution algorithm's speed partially depends on the order of29 // assertions. Assertions which have fewer possible matches should appear before30 // assertions which have more possible matches. This seems to imply that this could31 // be further improved by providing an indexer as an additional argument and ordering based32 // on the number of matches of the same kind (object, function) for the names of the33 // declarations.34 //35 // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator.36 bool AssertCompare::operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const {37 // Objects are always less than functions38 if ( ObjectDecl * objectDecl1 = dynamic_cast< ObjectDecl * >( d1 ) ) {39 if ( ObjectDecl * objectDecl2 = dynamic_cast< ObjectDecl * >( d2 ) ) {40 // objects are ordered by name then type pointer, in that order41 int cmp = objectDecl1->get_name().compare( objectDecl2->get_name() );42 return cmp < 0 ||43 ( cmp == 0 && objectDecl1->get_type() < objectDecl2->get_type() );44 } else {45 return true;46 }47 } else if ( FunctionDecl * funcDecl1 = dynamic_cast< FunctionDecl * >( d1 ) ) {48 if ( FunctionDecl * funcDecl2 = dynamic_cast< FunctionDecl * >( d2 ) ) {49 // functions are ordered by name, # parameters, # returnVals, type pointer in that order50 FunctionType * ftype1 = funcDecl1->get_functionType();51 FunctionType * ftype2 = funcDecl2->get_functionType();52 int numThings1 = ftype1->get_parameters().size() + ftype1->get_returnVals().size();53 int numThings2 = ftype2->get_parameters().size() + ftype2->get_returnVals().size();54 if ( numThings1 < numThings2 ) return true;55 if ( numThings1 > numThings2 ) return false;56 57 // if ( ftype1->get_parameters().size() < ftype2->get_parameters().size() ) return true;58 // else if ( ftype1->get_parameters().size() > ftype2->get_parameters().size() ) return false;59 // // same number of parameters60 // if ( ftype1->get_returnVals().size() < ftype2->get_returnVals().size() ) return true;61 // else if ( ftype1->get_returnVals().size() > ftype2->get_returnVals().size() ) return false;62 // same number of return vals63 // int cmp = funcDecl1->get_name().compare( funcDecl2->get_name() );64 // if ( cmp < 0 ) return true;65 // else if ( cmp > 0 ) return false;66 // // same name67 return ftype1 < ftype2;68 } else {69 return false;70 }71 } else {72 assert( false );73 }74 }75 76 27 void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent ) { 77 28 for ( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) { -
src/ResolvExpr/TypeEnvironment.h
re8ccca3 r78a0b88 28 28 29 29 namespace ResolvExpr { 30 // adding this comparison operator significantly improves assertion resolution run time for 31 // some cases. The current resolution algorithm's speed partially depends on the order of 32 // assertions. Assertions which have fewer possible matches should appear before 33 // assertions which have more possible matches. This seems to imply that this could 34 // be further improved by providing an indexer as an additional argument and ordering based 35 // on the number of matches of the same kind (object, function) for the names of the 36 // declarations. 37 // 38 // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator. 30 39 struct AssertCompare { 31 bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const; 40 bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const { 41 int cmp = d1->get_name().compare( d2->get_name() ); 42 return cmp < 0 || 43 ( cmp == 0 && d1->get_type() < d2->get_type() ); 44 } 32 45 }; 33 46 struct AssertionSetValue { -
src/SymTab/Indexer.cc
re8ccca3 r78a0b88 554 554 555 555 556 void Indexer::visit( TraitInstType *contextInst ) { 557 acceptAll( contextInst->get_parameters(), *this ); 558 acceptAll( contextInst->get_members(), *this ); 556 void Indexer::visit( TraitInstType *traitInst ) { 557 acceptAll( traitInst->get_parameters(), *this ); 559 558 } 560 559 -
src/SymTab/Validate.cc
re8ccca3 r78a0b88 127 127 public: 128 128 LinkReferenceToTypes( bool doDebug, const Indexer *indexer ); 129 using Parent::visit; 129 using Parent::visit; 130 void visit( TypeInstType *typeInst ) final; 131 130 132 void visit( EnumInstType *enumInst ) final; 131 133 void visit( StructInstType *structInst ) final; 132 134 void visit( UnionInstType *unionInst ) final; 133 void visit( TraitInstType *contextInst ) final; 135 void visit( TraitInstType *traitInst ) final; 136 134 137 void visit( EnumDecl *enumDecl ) final; 135 138 void visit( StructDecl *structDecl ) final; 136 139 void visit( UnionDecl *unionDecl ) final; 137 void visit( TypeInstType *typeInst ) final; 140 void visit( TraitDecl * traitDecl ) final; 141 138 142 private: 139 143 const Indexer *indexer; … … 287 291 288 292 HoistStruct::HoistStruct() : inStruct( false ) { 289 }290 291 void filter( std::list< Declaration * > &declList, bool (*pred)( Declaration * ), bool doDelete ) {292 std::list< Declaration * >::iterator i = declList.begin();293 while ( i != declList.end() ) {294 std::list< Declaration * >::iterator next = i;295 ++next;296 if ( pred( *i ) ) {297 if ( doDelete ) {298 delete *i;299 } // if300 declList.erase( i );301 } // if302 i = next;303 } // while304 293 } 305 294 … … 453 442 } 454 443 455 void LinkReferenceToTypes::visit( TraitInstType *traitInst ) { 444 template< typename Decl > 445 void normalizeAssertions( std::list< Decl * > & assertions ) { 446 // ensure no duplicate trait members after the clone 447 auto pred = [](Decl * d1, Decl * d2) { 448 // only care if they're equal 449 DeclarationWithType * dwt1 = dynamic_cast<DeclarationWithType *>( d1 ); 450 DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 ); 451 if ( dwt1 && dwt2 ) { 452 if ( dwt1->get_name() == dwt2->get_name() && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) { 453 // std::cerr << "=========== equal:" << std::endl; 454 // std::cerr << "d1: " << d1 << std::endl; 455 // std::cerr << "d2: " << d2 << std::endl; 456 return false; 457 } 458 } 459 return d1 < d2; 460 }; 461 std::set<Decl *, decltype(pred)> unique_members( assertions.begin(), assertions.end(), pred ); 462 // if ( unique_members.size() != assertions.size() ) { 463 // std::cerr << "============different" << std::endl; 464 // std::cerr << unique_members.size() << " " << assertions.size() << std::endl; 465 // } 466 467 std::list< Decl * > order; 468 order.splice( order.end(), assertions ); 469 std::copy_if( order.begin(), order.end(), back_inserter( assertions ), [&]( Decl * decl ) { 470 return unique_members.count( decl ); 471 }); 472 } 473 474 // expand assertions from trait instance, performing the appropriate type variable substitutions 475 template< typename Iterator > 476 void expandAssertions( TraitInstType * inst, Iterator out ) { 477 assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toString( inst ).c_str() ); 478 std::list< DeclarationWithType * > asserts; 479 for ( Declaration * decl : inst->baseTrait->members ) { 480 asserts.push_back( safe_dynamic_cast<DeclarationWithType *>( decl->clone() ) ); 481 } 482 // substitute trait decl parameters for instance parameters 483 applySubstitution( inst->baseTrait->parameters.begin(), inst->baseTrait->parameters.end(), inst->parameters.begin(), asserts.begin(), asserts.end(), out ); 484 } 485 486 void LinkReferenceToTypes::visit( TraitDecl * traitDecl ) { 487 Parent::visit( traitDecl ); 488 489 if ( traitDecl->name == "sized" ) { 490 // "sized" is a special trait - flick the sized status on for the type variable 491 assertf( traitDecl->parameters.size() == 1, "Built-in trait 'sized' has incorrect number of parameters: %zd", traitDecl->parameters.size() ); 492 TypeDecl * td = traitDecl->parameters.front(); 493 td->set_sized( true ); 494 } 495 496 // move assertions from type parameters into the body of the trait 497 for ( TypeDecl * td : traitDecl->parameters ) { 498 for ( DeclarationWithType * assert : td->assertions ) { 499 if ( TraitInstType * inst = dynamic_cast< TraitInstType * >( assert->get_type() ) ) { 500 expandAssertions( inst, back_inserter( traitDecl->members ) ); 501 } else { 502 traitDecl->members.push_back( assert->clone() ); 503 } 504 } 505 deleteAll( td->assertions ); 506 td->assertions.clear(); 507 } // for 508 } 509 510 void LinkReferenceToTypes::visit( TraitInstType * traitInst ) { 456 511 Parent::visit( traitInst ); 457 if ( traitInst->get_name() == "sized" ) {458 // "sized" is a special trait with no members - just flick the sized status on for the type variable459 if ( traitInst->get_parameters().size() != 1 ) {460 throw SemanticError( "incorrect number of trait parameters: ", traitInst );461 }462 TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( traitInst->get_parameters().front() );463 TypeInstType * inst = safe_dynamic_cast< TypeInstType * > ( param->get_type() );464 TypeDecl * decl = inst->get_baseType();465 decl->set_sized( true );466 // since "sized" is special, the next few steps don't apply467 return;468 }469 470 512 // handle other traits 471 TraitDecl *traitDecl = indexer->lookupTrait( traitInst-> get_name());513 TraitDecl *traitDecl = indexer->lookupTrait( traitInst->name ); 472 514 if ( ! traitDecl ) { 473 throw SemanticError( "use of undeclared trait " + traitInst-> get_name());515 throw SemanticError( "use of undeclared trait " + traitInst->name ); 474 516 } // if 475 517 if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) { 476 518 throw SemanticError( "incorrect number of trait parameters: ", traitInst ); 477 519 } // if 478 479 for ( TypeDecl * td : traitDecl->get_parameters() ) { 480 for ( DeclarationWithType * assert : td->get_assertions() ) { 481 traitInst->get_members().push_back( assert->clone() ); 482 } // for 483 } // for 484 485 // need to clone members of the trait for ownership purposes 486 std::list< Declaration * > members; 487 std::transform( traitDecl->get_members().begin(), traitDecl->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } ); 488 489 applySubstitution( traitDecl->get_parameters().begin(), traitDecl->get_parameters().end(), traitInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( traitInst->get_members() ) ); 520 traitInst->baseTrait = traitDecl; 490 521 491 522 // need to carry over the 'sized' status of each decl in the instance … … 498 529 } 499 530 } 531 // normalizeAssertions( traitInst->members ); 500 532 } 501 533 … … 561 593 void forallFixer( Type * func ) { 562 594 for ( TypeDecl * type : func->get_forall() ) { 563 std::list< DeclarationWithType * > toBeDone, nextRound; 564 toBeDone.splice( toBeDone.end(), type->get_assertions() ); 565 while ( ! toBeDone.empty() ) { 566 for ( DeclarationWithType * assertion : toBeDone ) { 567 if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) { 568 // expand trait instance into all of its members 569 for ( Declaration * member : traitInst->get_members() ) { 570 DeclarationWithType *dwt = safe_dynamic_cast< DeclarationWithType * >( member ); 571 nextRound.push_back( dwt->clone() ); 572 } 573 delete traitInst; 574 } else { 575 // pass assertion through 576 FixFunction fixer; 577 assertion = assertion->acceptMutator( fixer ); 578 if ( fixer.get_isVoid() ) { 579 throw SemanticError( "invalid type void in assertion of function ", func ); 580 } 581 type->get_assertions().push_back( assertion ); 582 } // if 583 } // for 584 toBeDone.clear(); 585 toBeDone.splice( toBeDone.end(), nextRound ); 586 } // while 595 std::list< DeclarationWithType * > asserts; 596 asserts.splice( asserts.end(), type->assertions ); 597 // expand trait instances into their members 598 for ( DeclarationWithType * assertion : asserts ) { 599 if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) { 600 // expand trait instance into all of its members 601 expandAssertions( traitInst, back_inserter( type->assertions ) ); 602 delete traitInst; 603 } else { 604 // pass other assertions through 605 type->assertions.push_back( assertion ); 606 } // if 607 } // for 608 // apply FixFunction to every assertion to check for invalid void type 609 for ( DeclarationWithType *& assertion : type->assertions ) { 610 FixFunction fixer; 611 assertion = assertion->acceptMutator( fixer ); 612 if ( fixer.get_isVoid() ) { 613 throw SemanticError( "invalid type void in assertion of function ", func ); 614 } // if 615 } // for 616 // normalizeAssertions( type->assertions ); 587 617 } // for 588 618 } … … 752 782 CompoundStmt *ret = Mutator::mutate( compoundStmt ); 753 783 scopeLevel -= 1; 754 std::list< Statement * >::iterator i = compoundStmt->get_kids().begin(); 755 while ( i != compoundStmt->get_kids().end() ) { 756 std::list< Statement * >::iterator next = i+1; 757 if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( *i ) ) { 784 // remove and delete decl stmts 785 filter( compoundStmt->kids, [](Statement * stmt) { 786 if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) { 758 787 if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) { 759 delete *i; 760 compoundStmt->get_kids().erase( i ); 788 return true; 761 789 } // if 762 790 } // if 763 i = next;764 } // while791 return false; 792 }, true); 765 793 typedefNames.endScope(); 766 794 return ret; … … 771 799 template<typename AggDecl> 772 800 AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) { 773 std::list<Declaration *>::iterator it = aggDecl->get_members().begin(); 774 for ( ; it != aggDecl->get_members().end(); ) { 775 std::list< Declaration * >::iterator next = it+1; 776 if ( dynamic_cast< TypedefDecl * >( *it ) ) { 777 delete *it; 778 aggDecl->get_members().erase( it ); 779 } // if 780 it = next; 781 } 801 filter( aggDecl->members, isTypedef, true ); 782 802 return aggDecl; 783 803 } -
src/SynTree/Mutator.cc
re8ccca3 r78a0b88 538 538 Type * Mutator::mutate( TraitInstType *aggregateUseType ) { 539 539 handleReferenceToType( aggregateUseType ); 540 mutateAll( aggregateUseType->get_members(), *this );541 540 return aggregateUseType; 542 541 } -
src/SynTree/ReferenceToType.cc
re8ccca3 r78a0b88 132 132 std::string TraitInstType::typeString() const { return "trait"; } 133 133 134 TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ) { 135 cloneAll( other.members, members ); 134 TraitInstType::TraitInstType( const Type::Qualifiers & tq, TraitDecl * baseTrait, const std::list< Attribute * > & attributes ) : Parent( tq, baseTrait->name, attributes ), baseTrait( baseTrait ) {} 135 136 TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ), baseTrait( other.baseTrait ) { 136 137 } 137 138 138 139 TraitInstType::~TraitInstType() { 139 deleteAll( members );140 140 } 141 141 -
src/SynTree/Type.h
re8ccca3 r78a0b88 471 471 typedef ReferenceToType Parent; 472 472 public: 473 // this member is filled in by the validate pass, which instantiates the members of the correponding 474 // aggregate with the actual type parameters specified for this use of the context 475 std::list< Declaration* > members; 476 477 TraitInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : Parent( tq, name, attributes ) {} 473 // this decl is not "owned" by the trait inst; it is merely a pointer to elsewhere in the tree, 474 // where the trait used in this type is actually defined 475 TraitDecl * baseTrait = nullptr; 476 477 TraitInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : Parent( tq, name, attributes ) {} 478 TraitInstType( const Type::Qualifiers & tq, TraitDecl * baseTrait, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 478 479 TraitInstType( const TraitInstType & other ); 479 480 ~TraitInstType(); 480 481 std::list< Declaration* >& get_members() { return members; }482 481 483 482 virtual bool isComplete() const; -
src/SynTree/TypeSubstitution.h
re8ccca3 r78a0b88 177 177 void applySubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actual, MemberIterator memberBegin, MemberIterator memberEnd, OutputIterator out ) { 178 178 TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual ); 179 for ( std::list< Declaration* >::iteratori = memberBegin; i != memberEnd; ++i ) {179 for ( auto i = memberBegin; i != memberEnd; ++i ) { 180 180 sub.apply( *i ); 181 181 *out++ = *i; -
src/SynTree/Visitor.cc
re8ccca3 r78a0b88 429 429 void Visitor::visit( TraitInstType *aggregateUseType ) { 430 430 handleReferenceToType( static_cast< ReferenceToType * >( aggregateUseType ) ); 431 acceptAll( aggregateUseType->get_members(), *this );432 431 } 433 432 -
src/prelude/prelude.cf
re8ccca3 r78a0b88 14 14 15 15 // Section numbers from: http://plg.uwaterloo.ca/~cforall/refrat.pdf 16 17 // ------------------------------------------------------------ 18 // 19 // Section 6.7.11 Trait Declarations 20 // Note: the sized trait is used in declarations later in this 21 // file, so it must be out of order. 22 // 23 // ------------------------------------------------------------ 24 25 trait sized(dtype T) {}; 16 26 17 27 // ------------------------------------------------------------ -
src/tests/.expect/ifcond.txt
re8ccca3 r78a0b88 1 1 x != 0 correct 2 x != 0 && y == 0 incorrect2 x != 0 && y != 0 correct 3 3 x == y correct -
src/tests/ifcond.c
re8ccca3 r78a0b88 1 // 1 // 2 2 // Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo 3 3 // 4 4 // The contents of this file are covered under the licence agreement in the 5 5 // file "LICENCE" distributed with Cforall. 6 // 7 // ifcond.c -- 8 // 6 // 7 // ifcond.c -- 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Aug 26 10:13:11 2017 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Aug 30 07:55:24201713 // Update Count : 1 314 // 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri Sep 01 15:22:19 2017 13 // Update Count : 14 14 // 15 15 16 #include <fstream>16 #include <fstream> 17 17 18 18 int f( int r ) { return r; } … … 27 27 } // if 28 28 29 if ( int x = 4, y = 0 ) { // FIXME && distribution 29 if ( int x = 4, y = 0 ) { 30 sout | "x != 0 && y != 0 incorrect" | endl; 31 } else if ( int x = 4, y = 1 ) { 30 32 sout | "x != 0 && y != 0 correct" | endl; 31 32 sout | "x != 0 &&y == 0 incorrect" | endl;33 } else { 34 sout | "x == 0 || y == 0 incorrect" | endl; 33 35 } // if 34 36
Note: See TracChangeset
for help on using the changeset viewer.