Changes in / [51c6353:76c62b2]


Ignore:
Location:
src
Files:
2 deleted
18 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r51c6353 r76c62b2  
    195195                }
    196196
    197                 output << kind << aggDecl->get_name();
     197                output << kind;
     198                if ( aggDecl->get_name() != "" )
     199                        output << aggDecl->get_name();
    198200
    199201                if ( aggDecl->has_body() ) {
     
    231233                genAttributes( enumDecl->get_attributes() );
    232234
    233                 output << enumDecl->get_name();
     235                if ( enumDecl->get_name() != "" )
     236                        output << enumDecl->get_name();
    234237
    235238                std::list< Declaration* > &memb = enumDecl->get_members();
     
    257260        }
    258261
    259         void CodeGenerator::visit( TraitDecl * traitDecl ) {
    260                 assertf( ! genC, "TraitDecl nodes should not reach code generation." );
    261                 extension( traitDecl );
    262                 handleAggregate( traitDecl, "trait " );
    263         }
     262        void CodeGenerator::visit( __attribute__((unused)) TraitDecl * traitDecl ) {}
    264263
    265264        void CodeGenerator::visit( TypedefDecl * typeDecl ) {
     
    761760                for ( Statement * stmt : stmts ) {
    762761                        updateLocation( stmt );
    763                         output << indent << printLabels( stmt->get_labels() );
     762                        output << printLabels( stmt->get_labels() );
    764763                        if ( i+1 == numStmts ) {
    765764                                // last statement in a statement expression needs to be handled specially -
  • src/CodeGen/Generate.cc

    r51c6353 r76c62b2  
    2121#include "CodeGenerator.h"           // for CodeGenerator, doSemicolon, oper...
    2222#include "GenType.h"                 // for genPrettyType
    23 #include "Common/PassVisitor.h"      // for PassVisitor
    2423#include "Parser/LinkageSpec.h"      // for isBuiltin, isGeneratable
    2524#include "SynTree/BaseSyntaxNode.h"  // for BaseSyntaxNode
     
    3029
    3130namespace 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 
    4731        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC, bool lineMarks ) {
    48                 cleanTree( translationUnit );
    49 
    5032                CodeGen::CodeGenerator cgv( os, pretty, generateC, lineMarks );
    5133                for ( auto & dcl : translationUnit ) {
     
    7052                os << std::endl;
    7153        }
    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
    8754} // namespace CodeGen
    8855
  • src/Common/utility.h

    r51c6353 r76c62b2  
    172172auto filter(Args&&... args) -> decltype(std::copy_if(std::forward<Args>(args)...)) {
    173173  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
    189174}
    190175
  • src/GenPoly/Box.cc

    r51c6353 r76c62b2  
    141141                        virtual StructDecl *mutate( StructDecl *structDecl ) override;
    142142                        virtual UnionDecl *mutate( UnionDecl *unionDecl ) override;
    143                         virtual TraitDecl *mutate( TraitDecl *unionDecl ) override;
    144143                        virtual TypeDecl *mutate( TypeDecl *typeDecl ) override;
    145144                        virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ) override;
     
    217216                  private:
    218217                };
     218
    219219        } // anonymous namespace
    220220
     
    896896                                addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
    897897                                bodyStmt = new ExprStmt( noLabels, adapteeApp );
     898//                      } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    898899                        } else if ( isDynType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    899900                                // return type T
     
    13511352                }
    13521353
    1353                 TraitDecl * Pass2::mutate( TraitDecl *aggDecl ) {
    1354                         return handleAggDecl( aggDecl );
    1355                 }
    1356 
    13571354                TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) {
    13581355                        addToTyVarMap( typeDecl, scopeTyVars );
     
    13801377                Type *Pass2::mutate( FunctionType *funcType ) {
    13811378                        scopeTyVars.beginScope();
    1382 
    13831379                        makeTyVarMap( funcType, scopeTyVars );
    13841380
     
    15541550                                        // (alloca was previously used, but can't be safely used in loops)
    15551551                                        Type *declType = objectDecl->get_type();
    1556                                         ObjectDecl *newBuf = new ObjectDecl( bufNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0,
     1552                                        std::string bufName = bufNamer.newName();
     1553                                        ObjectDecl *newBuf = new ObjectDecl( bufName, Type::StorageClasses(), LinkageSpec::C, 0,
    15571554                                                new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Kind::Char), new NameExpr( sizeofName( mangleType(declType) ) ),
    1558                                                 true, false, std::list<Attribute*>{ new Attribute( "aligned", std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ) } ), 0 );
     1555                                                true, false, std::list<Attribute*>{ new Attribute( std::string{"aligned"}, std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ) } ), 0 );
    15591556                                        stmtsToAdd.push_back( new DeclStmt( noLabels, newBuf ) );
    15601557
    15611558                                        delete objectDecl->get_init();
    1562                                         objectDecl->set_init( new SingleInit( new VariableExpr( newBuf ) ) );
     1559
     1560                                        objectDecl->set_init( new SingleInit( new NameExpr( bufName ) ) );
    15631561                                }
    15641562                        }
  • src/GenPoly/GenPoly.cc

    r51c6353 r76c62b2  
    336336                                assertf(bparam, "Aggregate parameters should be type expressions");
    337337
    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 
    339339                                // stuffed in for dtype-statics.
    340340                                // if ( is<VoidType>( aparam->get_type() ) || is<VoidType>( bparam->get_type() ) ) continue;
    341341                                if ( ! typesPolyCompatible( aparam->get_type(), bparam->get_type() ) ) return false;
    342342                        }
    343 
     343                       
    344344                        return true;
    345345                }
     
    350350                // polymorphic types always match
    351351                if ( aid == type_index{typeid(TypeInstType)} ) return true;
    352 
     352               
    353353                type_index bid{ typeid(*b) };
    354354                // polymorphic types always match
    355355                if ( bid == type_index{typeid(TypeInstType)} ) return true;
    356 
     356               
    357357                // can't match otherwise if different types
    358358                if ( aid != bid ) return false;
     
    377377                                ConstantExpr *ad = dynamic_cast<ConstantExpr*>( aa->get_dimension() );
    378378                                ConstantExpr *bd = dynamic_cast<ConstantExpr*>( ba->get_dimension() );
    379                                 if ( ad && bd
     379                                if ( ad && bd 
    380380                                                && ad->get_constant()->get_value() != bd->get_constant()->get_value() )
    381381                                        return false;
     
    433433
    434434        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
    435                 // xxx - should this actually be insert?
    436435                tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar };
    437436        }
  • src/Parser/ExpressionNode.cc

    r51c6353 r76c62b2  
    370370Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node ) {
    371371        std::list< Expression * > args;
    372         args.push_back(  maybeMoveBuild< Expression >(expr_node) ); // xxx -- this is exactly the same as the val case now, refactor this code.
     372        args.push_back(  maybeMoveBuild< Expression >(expr_node) ); // xxx
    373373        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
    374374} // build_unary_ptr
  • src/ResolvExpr/AlternativeFinder.cc

    r51c6353 r76c62b2  
    749749                                if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) {
    750750                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    751                                                 Alternative newFunc( *func );
    752                                                 referenceToRvalueConversion( newFunc.expr );
     751                                                referenceToRvalueConversion( func->expr );
    753752                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    754753                                                        // XXX
    755754                                                        //Designators::check_alternative( function, *actualAlt );
    756                                                         makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) );
     755                                                        makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    757756                                                }
    758757                                        }
    759758                                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
     759                                        referenceToRvalueConversion( func->expr );
    760760                                        EqvClass eqvClass;
    761761                                        if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
    762762                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
    763                                                         Alternative newFunc( *func );
    764                                                         referenceToRvalueConversion( newFunc.expr );
    765763                                                        for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    766                                                                 makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) );
     764                                                                makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
    767765                                                        } // for
    768766                                                } // if
     
    775773                                        if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) {
    776774                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    777                                                         Alternative newFunc( *funcOp );
    778                                                         referenceToRvalueConversion( newFunc.expr );
     775                                                        referenceToRvalueConversion( funcOp->expr );
    779776                                                        for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    780777                                                                AltList currentAlt;
    781778                                                                currentAlt.push_back( *func );
    782779                                                                currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
    783                                                                 makeFunctionAlternatives( newFunc, function, currentAlt, std::back_inserter( candidates ) );
     780                                                                makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
    784781                                                        } // for
    785782                                                } // if
  • src/ResolvExpr/RenameVars.cc

    r51c6353 r76c62b2  
    8888                typeBefore( aggregateUseType );
    8989                acceptAll( aggregateUseType->get_parameters(), *this );
     90                acceptAll( aggregateUseType->get_members(), *this );
    9091                typeAfter( aggregateUseType );
    9192        }
  • src/ResolvExpr/TypeEnvironment.cc

    r51c6353 r76c62b2  
    2525
    2626namespace ResolvExpr {
     27        // adding this comparison operator significantly improves assertion resolution run time for
     28        // some cases. The current resolution algorithm's speed partially depends on the order of
     29        // assertions. Assertions which have fewer possible matches should appear before
     30        // assertions which have more possible matches. This seems to imply that this could
     31        // be further improved by providing an indexer as an additional argument and ordering based
     32        // on the number of matches of the same kind (object, function) for the names of the
     33        // 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 functions
     38                        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 order
     41                                        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 order
     50                                        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 parameters
     60                                        // 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 vals
     63                                        // int cmp = funcDecl1->get_name().compare( funcDecl2->get_name() );
     64                                        // if ( cmp < 0 ) return true;
     65                                        // else if ( cmp > 0 ) return false;
     66                                        // // same name
     67                                        return ftype1 < ftype2;
     68                                } else {
     69                                        return false;
     70                                }
     71                        } else {
     72                                assert( false );
     73                        }
     74                }
     75
    2776        void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent ) {
    2877                for ( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) {
  • src/ResolvExpr/TypeEnvironment.h

    r51c6353 r76c62b2  
    2828
    2929namespace 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.
    3930        struct AssertCompare {
    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                 }
     31                bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const;
    4532        };
    4633        struct AssertionSetValue {
  • src/SymTab/Indexer.cc

    r51c6353 r76c62b2  
    554554
    555555
    556         void Indexer::visit( TraitInstType *traitInst ) {
    557                 acceptAll( traitInst->get_parameters(), *this );
     556        void Indexer::visit( TraitInstType *contextInst ) {
     557                acceptAll( contextInst->get_parameters(), *this );
     558                acceptAll( contextInst->get_members(), *this );
    558559        }
    559560
  • src/SymTab/Validate.cc

    r51c6353 r76c62b2  
    127127          public:
    128128                LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
    129                 using Parent::visit;
    130                 void visit( TypeInstType *typeInst ) final;
    131 
     129                using Parent::visit;
    132130                void visit( EnumInstType *enumInst ) final;
    133131                void visit( StructInstType *structInst ) final;
    134132                void visit( UnionInstType *unionInst ) final;
    135                 void visit( TraitInstType *traitInst ) final;
    136 
     133                void visit( TraitInstType *contextInst ) final;
    137134                void visit( EnumDecl *enumDecl ) final;
    138135                void visit( StructDecl *structDecl ) final;
    139136                void visit( UnionDecl *unionDecl ) final;
    140                 void visit( TraitDecl * traitDecl ) final;
    141 
     137                void visit( TypeInstType *typeInst ) final;
    142138          private:
    143139                const Indexer *indexer;
     
    291287
    292288        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                                } // if
     300                                declList.erase( i );
     301                        } // if
     302                        i = next;
     303                } // while
    293304        }
    294305
     
    442453        }
    443454
    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                                 }
     455        void LinkReferenceToTypes::visit( TraitInstType *traitInst ) {
     456                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 variable
     459                        if ( traitInst->get_parameters().size() != 1 ) {
     460                                throw SemanticError( "incorrect number of trait parameters: ", traitInst );
    458461                        }
    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 ) {
    511                 Parent::visit( traitInst );
     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 apply
     467                        return;
     468                }
     469
    512470                // handle other traits
    513                 TraitDecl *traitDecl = indexer->lookupTrait( traitInst->name );
     471                TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() );
    514472                if ( ! traitDecl ) {
    515                         throw SemanticError( "use of undeclared trait " + traitInst->name );
     473                        throw SemanticError( "use of undeclared trait " + traitInst->get_name() );
    516474                } // if
    517475                if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
    518476                        throw SemanticError( "incorrect number of trait parameters: ", traitInst );
    519477                } // if
    520                 traitInst->baseTrait = traitDecl;
     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() ) );
    521490
    522491                // need to carry over the 'sized' status of each decl in the instance
     
    529498                        }
    530499                }
    531                 // normalizeAssertions( traitInst->members );
    532500        }
    533501
     
    593561        void forallFixer( Type * func ) {
    594562                for ( TypeDecl * type : func->get_forall() ) {
    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 );
     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
    617587                } // for
    618588        }
     
    782752                CompoundStmt *ret = Mutator::mutate( compoundStmt );
    783753                scopeLevel -= 1;
    784                 // remove and delete decl stmts
    785                 filter( compoundStmt->kids, [](Statement * stmt) {
    786                         if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
     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 ) ) {
    787758                                if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) {
    788                                         return true;
     759                                        delete *i;
     760                                        compoundStmt->get_kids().erase( i );
    789761                                } // if
    790762                        } // if
    791                         return false;
    792                 }, true);
     763                        i = next;
     764                } // while
    793765                typedefNames.endScope();
    794766                return ret;
     
    799771        template<typename AggDecl>
    800772        AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) {
    801                 filter( aggDecl->members, isTypedef, true );
     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                }
    802782                return aggDecl;
    803783        }
  • src/SynTree/Mutator.cc

    r51c6353 r76c62b2  
    538538Type * Mutator::mutate( TraitInstType *aggregateUseType ) {
    539539        handleReferenceToType( aggregateUseType );
     540        mutateAll( aggregateUseType->get_members(), *this );
    540541        return aggregateUseType;
    541542}
  • src/SynTree/ReferenceToType.cc

    r51c6353 r76c62b2  
    132132std::string TraitInstType::typeString() const { return "trait"; }
    133133
    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 ) {
     134TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ) {
     135        cloneAll( other.members, members );
    137136}
    138137
    139138TraitInstType::~TraitInstType() {
     139        deleteAll( members );
    140140}
    141141
  • src/SynTree/Type.h

    r51c6353 r76c62b2  
    471471        typedef ReferenceToType Parent;
    472472  public:
    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 * >() );
     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 ) {}
    479478        TraitInstType( const TraitInstType & other );
    480479        ~TraitInstType();
     480
     481        std::list< Declaration* >& get_members() { return members; }
    481482
    482483        virtual bool isComplete() const;
  • src/SynTree/TypeSubstitution.h

    r51c6353 r76c62b2  
    177177void applySubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actual, MemberIterator memberBegin, MemberIterator memberEnd, OutputIterator out ) {
    178178        TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual );
    179         for ( auto i = memberBegin; i != memberEnd; ++i ) {
     179        for ( std::list< Declaration* >::iterator i = memberBegin; i != memberEnd; ++i ) {
    180180                sub.apply( *i );
    181181                *out++ = *i;
  • src/SynTree/Visitor.cc

    r51c6353 r76c62b2  
    429429void Visitor::visit( TraitInstType *aggregateUseType ) {
    430430        handleReferenceToType( static_cast< ReferenceToType * >( aggregateUseType ) );
     431        acceptAll( aggregateUseType->get_members(), *this );
    431432}
    432433
  • src/prelude/prelude.cf

    r51c6353 r76c62b2  
    1414
    1515// 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) {};
    2616
    2717// ------------------------------------------------------------
Note: See TracChangeset for help on using the changeset viewer.