Changeset d807ca28


Ignore:
Timestamp:
May 25, 2018, 5:01:37 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
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, with_gc
Children:
3ed994e
Parents:
2c88368
git-author:
Rob Schluntz <rschlunt@…> (05/25/18 16:59:30)
git-committer:
Rob Schluntz <rschlunt@…> (05/25/18 17:01:37)
Message:

Add AST support for _Generic, along with C codegen

Location:
src
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r2c88368 rd807ca28  
    826826                expr->expr->accept( *visitor );
    827827        }
     828
     829        void CodeGenerator::postvisit( GenericExpr * expr ) {
     830                assertf( ! genC, "C11 _Generic expressions should not reach code generation." );
     831                output << "_Generic(";
     832                expr->control->accept( *visitor );
     833                output << ", ";
     834                unsigned int numAssocs = expr->associations.size();
     835                unsigned int i = 0;
     836                for ( GenericExpr::Association & assoc : expr->associations ) {
     837                        if (assoc.isDefault) {
     838                                output << "default: ";
     839                        } else {
     840                                output << genType( assoc.type, "", pretty, genC ) << ": ";
     841                        }
     842                        assoc.expr->accept( *visitor );
     843                        if ( i+1 != numAssocs ) {
     844                                output << ", ";
     845                        }
     846                        i++;
     847                }
     848                output << ")";
     849        }
     850
    828851
    829852        // *** Statements
  • src/CodeGen/CodeGenerator.h

    r2c88368 rd807ca28  
    9494                void postvisit( ConstructorExpr * );
    9595                void postvisit( DeletedExpr * );
     96                void postvisit( GenericExpr * );
    9697
    9798                //*** Statements
  • src/Common/PassVisitor.h

    r2c88368 rd807ca28  
    125125        virtual void visit( InitExpr *  initExpr ) override final;
    126126        virtual void visit( DeletedExpr *  delExpr ) override final;
     127        virtual void visit( GenericExpr * genExpr ) override final;
    127128
    128129        virtual void visit( VoidType * basicType ) override final;
     
    223224        virtual Expression * mutate( InitExpr *  initExpr ) override final;
    224225        virtual Expression * mutate( DeletedExpr *  delExpr ) override final;
     226        virtual Expression * mutate( GenericExpr * genExpr ) override final;
    225227
    226228        virtual Type * mutate( VoidType * basicType ) override final;
  • src/Common/PassVisitor.impl.h

    r2c88368 rd807ca28  
    20732073
    20742074//--------------------------------------------------------------------------
     2075// GenericExpr
     2076template< typename pass_type >
     2077void PassVisitor< pass_type >::visit( GenericExpr * node ) {
     2078        VISIT_START( node );
     2079
     2080        indexerScopedAccept( node->result, *this );
     2081        maybeAccept_impl( node->control, *this );
     2082        for ( GenericExpr::Association & assoc : node->associations ) {
     2083                indexerScopedAccept( assoc.type, *this );
     2084                maybeAccept_impl( assoc.expr, *this );
     2085        }
     2086
     2087        VISIT_END( node );
     2088}
     2089
     2090template< typename pass_type >
     2091Expression * PassVisitor< pass_type >::mutate( GenericExpr * node ) {
     2092        MUTATE_START( node );
     2093
     2094        indexerScopedMutate( node->env, *this );
     2095        indexerScopedMutate( node->result, *this );
     2096        maybeMutate_impl( node->control, *this );
     2097        for ( GenericExpr::Association & assoc : node->associations ) {
     2098                indexerScopedMutate( assoc.type, *this );
     2099                maybeMutate_impl( assoc.expr, *this );
     2100        }
     2101
     2102        MUTATE_END( Expression, node );
     2103}
     2104
     2105//--------------------------------------------------------------------------
    20752106// VoidType
    20762107template< typename pass_type >
  • src/Parser/parser.yy

    r2c88368 rd807ca28  
    175175        bool flag;
    176176        CatchStmt::Kind catch_kind;
     177        GenericExpr * genexpr;
    177178}
    178179
     
    259260%type<flag> asm_volatile_opt
    260261%type<en> handler_predicate_opt
     262%type<genexpr> generic_association generic_assoc_list
    261263
    262264// statements
     
    501503                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    502504        | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11
    503                 { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; }
     505                {
     506                        // add the missing control expression to the GenericExpr and return it
     507                        $5->control = maybeMoveBuild<Expression>( $3 );
     508                        $$ = new ExpressionNode( $5 );
     509                }
    504510        ;
    505511
    506512generic_assoc_list:                                                                             // C11
    507         | generic_association
     513        generic_association
    508514        | generic_assoc_list ',' generic_association
     515                {
     516                        // steal the association node from the singleton and delete the wrapper
     517                        $1->associations.splice($1->associations.end(), $3->associations);
     518                        delete $3;
     519                        $$ = $1;
     520                }
    509521        ;
    510522
    511523generic_association:                                                                    // C11
    512524        type_no_function ':' assignment_expression
     525                {
     526                        // create a GenericExpr wrapper with one association pair
     527                        $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>($3) } } );
     528                }
    513529        | DEFAULT ':' assignment_expression
     530                { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>($3) } } ); }
    514531        ;
    515532
  • src/ResolvExpr/AlternativeFinder.cc

    r2c88368 rd807ca28  
    9797                void postvisit( InitExpr * initExpr );
    9898                void postvisit( DeletedExpr * delExpr );
     99                void postvisit( GenericExpr * genExpr );
    99100
    100101                /// Adds alternatives for anonymous members
     
    17561757                assertf( false, "AlternativeFinder should never see a DeletedExpr." );
    17571758        }
     1759
     1760        void AlternativeFinder::Finder::postvisit( GenericExpr * ) {
     1761                assertf( false, "_Generic is not yet supported." );
     1762        }
    17581763} // namespace ResolvExpr
    17591764
  • src/SynTree/Expression.cc

    r2c88368 rd807ca28  
    748748}
    749749
     750GenericExpr::Association::Association( Type * type, Expression * expr ) : type( type ), expr( expr ), isDefault( false ) {}
     751GenericExpr::Association::Association( Expression * expr ) : type( nullptr ), expr( expr ), isDefault( true ) {}
     752GenericExpr::Association::Association( const Association & other ) : type( maybeClone( other.type ) ), expr( maybeClone( other.expr ) ), isDefault( other.isDefault ) {}
     753GenericExpr::Association::~Association() {
     754        delete type;
     755        delete expr;
     756}
     757
     758GenericExpr::GenericExpr( Expression * control, const std::list<Association> & assoc ) : Expression(), control( control ), associations( assoc ) {}
     759GenericExpr::GenericExpr( const GenericExpr & other ) : Expression(other), control( maybeClone( other.control ) ), associations( other.associations ) {
     760}
     761GenericExpr::~GenericExpr() {
     762        delete control;
     763}
     764
     765void GenericExpr::print( std::ostream & os, Indenter indent ) const {
     766        os << "C11 _Generic Expression" << std::endl << indent+1;
     767        control->print( os, indent+1 );
     768        os << std::endl << indent+1 << "... with associations: " << std::endl;
     769        for ( const Association & assoc : associations ) {
     770                os << indent+1;
     771                if (assoc.isDefault) {
     772                        os << "... default: ";
     773                        assoc.expr->print( os, indent+1 );
     774                } else {
     775                        os << "... type: ";
     776                        assoc.type->print( os, indent+1 );
     777                        os << std::endl << indent+1 << "... expression: ";
     778                        assoc.expr->print( os, indent+1 );
     779                        os << std::endl;
     780                }
     781                os << std::endl;
     782        }
     783}
    750784
    751785// Local Variables: //
  • src/SynTree/Expression.h

    r2c88368 rd807ca28  
    865865};
    866866
     867/// C11 _Generic expression
     868class GenericExpr : public Expression {
     869public:
     870        struct Association {
     871                Type * type = nullptr;
     872                Expression * expr = nullptr;
     873                bool isDefault = false;
     874
     875                Association( Type * type, Expression * expr );
     876                Association( Expression * expr );
     877                Association( const Association & other );
     878                Association & operator=( const Association & other ) = delete; // at the moment this isn't used, and I don't want to implement it
     879                ~Association();
     880        };
     881
     882        Expression * control;
     883        std::list<Association> associations;
     884
     885        GenericExpr( Expression * control, const std::list<Association> & assoc );
     886        GenericExpr( const GenericExpr & other );
     887        virtual ~GenericExpr();
     888
     889        virtual GenericExpr * clone() const { return new GenericExpr( * this ); }
     890        virtual void accept( Visitor & v ) { v.visit( this ); }
     891        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     892        virtual void print( std::ostream & os, Indenter indent = {} ) const;
     893};
     894
    867895// Local Variables: //
    868896// tab-width: 4 //
  • src/SynTree/Mutator.h

    r2c88368 rd807ca28  
    9393        virtual Expression * mutate( InitExpr  * initExpr ) = 0;
    9494        virtual Expression * mutate( DeletedExpr * delExpr ) = 0;
     95        virtual Expression * mutate( GenericExpr * genExpr ) = 0;
    9596
    9697        virtual Type * mutate( VoidType * basicType ) = 0;
  • src/SynTree/SynTree.h

    r2c88368 rd807ca28  
    101101class InitExpr;
    102102class DeletedExpr;
     103class GenericExpr;
    103104
    104105class Type;
  • src/SynTree/Visitor.h

    r2c88368 rd807ca28  
    9595        virtual void visit( InitExpr *  initExpr ) = 0;
    9696        virtual void visit( DeletedExpr * delExpr ) = 0;
     97        virtual void visit( GenericExpr * genExpr ) = 0;
    9798
    9899        virtual void visit( VoidType * basicType ) = 0;
Note: See TracChangeset for help on using the changeset viewer.