Changes in / [38f4953:c2a58cf]


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/ResolveTypeof.cc

    r38f4953 rc2a58cf  
    3535
    3636struct ResolveTypeof : public ast::WithShortCircuiting {
    37         const ResolveContext & context;
     37    const ResolveContext & context;
    3838
    39         ResolveTypeof( const ResolveContext & context ) : context( context ) {}
     39                ResolveTypeof( const ResolveContext & context ) :
     40                        context( context ) {}
    4041
    41         void previsit( const ast::TypeofType * ) { visit_children = false; }
     42                void previsit( const ast::TypeofType * ) { visit_children = false; }
    4243
    43         const ast::Type * postvisit( const ast::TypeofType * typeofType ) {
    44                 // pass on null expression
    45                 if ( ! typeofType->expr ) return typeofType;
     44        const ast::Type * postvisit( const ast::TypeofType * typeofType ) {
     45        // pass on null expression
     46            if ( ! typeofType->expr ) return typeofType;
    4647
    47                 ast::ptr< ast::Type > newType;
    48                 if ( auto tyExpr = typeofType->expr.as< ast::TypeExpr >() ) {
    49                         // typeof wrapping type
    50                         newType = tyExpr->type;
    51                 } else {
    52                         // typeof wrapping expression
    53                         ast::TypeEnvironment dummy;
    54                         ast::ptr< ast::Expr > newExpr =
    55                                 resolveInVoidContext( typeofType->expr, context, dummy );
    56                         assert( newExpr->result && ! newExpr->result->isVoid() );
    57                         newType = newExpr->result;
    58                 }
     48            ast::ptr< ast::Type > newType;
     49            if ( auto tyExpr = typeofType->expr.as< ast::TypeExpr >() ) {
     50            // typeof wrapping type
     51            newType = tyExpr->type;
     52        } else {
     53            // typeof wrapping expression
     54            ast::TypeEnvironment dummy;
     55            ast::ptr< ast::Expr > newExpr =
     56                resolveInVoidContext( typeofType->expr, context, dummy );
     57            assert( newExpr->result && ! newExpr->result->isVoid() );
     58            newType = newExpr->result;
     59        }
    5960
    60                 // clear qualifiers for base, combine with typeoftype quals regardless
    61                 if ( typeofType->kind == ast::TypeofType::Basetypeof ) {
    62                         // replace basetypeof(<enum>) by int
    63                         if ( newType.as< ast::EnumInstType >() ) {
    64                                 newType = new ast::BasicType(
    65                                         ast::BasicType::SignedInt, newType->qualifiers, copy(newType->attributes) );
    66                         }
    67                         reset_qualifiers(
    68                                 newType,
    69                                 ( newType->qualifiers & ~ast::CV::EquivQualifiers ) | typeofType->qualifiers );
    70                 } else {
    71                         add_qualifiers( newType, typeofType->qualifiers );
    72                 }
     61        // clear qualifiers for base, combine with typeoftype quals regardless
     62        if ( typeofType->kind == ast::TypeofType::Basetypeof ) {
     63            // replace basetypeof(<enum>) by int
     64                                if ( newType.as< ast::EnumInstType >() ) {
     65                                        newType = new ast::BasicType{
     66                                                ast::BasicType::SignedInt, newType->qualifiers, copy(newType->attributes) };
     67            }
     68                                reset_qualifiers(
     69                                        newType,
     70                                        ( newType->qualifiers & ~ast::CV::EquivQualifiers ) | typeofType->qualifiers );
     71        } else {
     72                                add_qualifiers( newType, typeofType->qualifiers );
     73        }
    7374
    74                 return newType.release();
    75         }
     75        return newType.release();
     76    }
    7677};
    7778
     
    110111
    111112const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & context ) {
    112         if ( decl->isTypeFixed ) {
    113                 return decl;
    114         }
     113    if (decl->isTypeFixed) {
     114        return decl;
     115    }
    115116
    116         auto mutDecl = mutate(decl);
    117         fixObjectInit(decl, context);
    118         {
    119                 auto resolvedType = resolveTypeof(decl->type, context);
    120                 resolvedType = fixArrayType(resolvedType, context);
    121                 mutDecl->type = resolvedType;
    122         }
     117    auto mutDecl = mutate(decl);
     118    fixObjectInit(decl, context);
     119    {
     120        auto resolvedType = resolveTypeof(decl->type, context);
     121        resolvedType = fixArrayType(resolvedType, context);
     122        mutDecl->type = resolvedType;
     123    }
    123124
    124         // Do not mangle unnamed variables.
    125         if ( !mutDecl->name.empty() ) {
    126                 mutDecl->mangleName = Mangle::mangle(mutDecl);
    127         }
     125    // Do not mangle unnamed variables.
     126    if (!mutDecl->name.empty()) {
     127        mutDecl->mangleName = Mangle::mangle(mutDecl);
     128    }
    128129
    129         mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID);
    130         mutDecl->isTypeFixed = true;
    131         return mutDecl;
     130    mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID);
     131    mutDecl->isTypeFixed = true;
     132    return mutDecl;
    132133}
    133134
    134 const ast::ObjectDecl *fixObjectInit(
    135                 const ast::ObjectDecl *decl, const ResolveContext &context) {
    136         if ( decl->isTypeFixed ) {
    137                 return decl;
    138         }
     135const ast::ObjectDecl *fixObjectInit(const ast::ObjectDecl *decl,
     136                                    const ResolveContext &context) {
     137    if (decl->isTypeFixed) {
     138        return decl;
     139    }
    139140
    140         if ( auto listInit = decl->init.as<ast::ListInit>() ) {
    141                 for ( size_t k = 0; k < listInit->designations.size(); k++ ) {
    142                         const ast::Designation *des = listInit->designations[k].get();
    143                         // Desination here
    144                         ast::Designation * newDesignation = new ast::Designation(des->location);
    145                         std::deque<ast::ptr<ast::Expr>> newDesignators;
     141    auto mutDecl = mutate(decl);
    146142
    147                         for ( ast::ptr<ast::Expr> designator : des->designators ) {
    148                                 // Stupid flag variable for development, to be removed
    149                                 if ( const ast::NameExpr * designatorName = designator.as<ast::NameExpr>() ) {
    150                                         auto candidates = context.symtab.lookupId(designatorName->name);
    151                                         // Does not work for the overloading case currently
    152                                         // assert( candidates.size() == 1 );
    153                                         if ( candidates.size() != 1 ) return decl;
    154                                         auto candidate = candidates.at(0);
    155                                         if ( const ast::EnumInstType * enumInst = dynamic_cast<const ast::EnumInstType *>(candidate.id->get_type())) {
    156                                                 // determine that is an enumInst, swap it with its const value
    157                                                 assert( candidates.size() == 1 );
    158                                                 const ast::EnumDecl * baseEnum = enumInst->base;
    159                                                 // Need to iterate over all enum value to find the initializer to swap
    160                                                 for ( size_t m = 0; m < baseEnum->members.size(); ++m ) {
    161                                                         const ast::ObjectDecl * mem = baseEnum->members.at(m).as<const ast::ObjectDecl>();
    162                                                         if ( baseEnum->members.at(m)->name == designatorName->name ) {
    163                                                                 assert( mem );
    164                                                                 newDesignators.push_back( ast::ConstantExpr::from_int(designator->location, m) );
    165                                                                 break;
    166                                                         }
    167                                                 }
    168                                         } else {
    169                                                 newDesignators.push_back( des->designators.at(0) );
    170                                         }
    171                                 } else {
    172                                         newDesignators.push_back( des->designators.at(0) );
    173                                 }
    174                         }
    175                         newDesignation->designators = newDesignators;
    176                         listInit = ast::mutate_field_index(listInit, &ast::ListInit::designations, k, newDesignation);
    177                 }
    178         }
    179         return decl;
     143    if ( auto mutListInit = mutDecl->init.as<ast::ListInit>() ) {
     144        // std::list<ast::Designation *> newDesignations;       
     145
     146        for ( size_t k = 0; k < mutListInit->designations.size(); k++ ) {
     147            const ast::Designation *des = mutListInit->designations[k].get();
     148            // Desination here
     149            ast::Designation * newDesignation = new ast::Designation(des->location);
     150            std::deque<ast::ptr<ast::Expr>> newDesignators;
     151
     152            for ( ast::ptr<ast::Expr> designator : des->designators ) {
     153                // Stupid flag variable for development, to be removed
     154                // bool mutated = false;
     155                if ( const ast::NameExpr * designatorName = designator.as<ast::NameExpr>() ) {
     156                    auto candidates = context.symtab.lookupId(designatorName->name);
     157                    // Does not work for the overloading case currently
     158                    // assert( candidates.size() == 1 );
     159                    if ( candidates.size() != 1 ) return mutDecl;
     160                    auto candidate = candidates.at(0);
     161                    if ( const ast::EnumInstType * enumInst = dynamic_cast<const ast::EnumInstType *>(candidate.id->get_type())) {
     162                        // determine that is an enumInst, swap it with its const value
     163                        assert( candidates.size() == 1 );
     164                        const ast::EnumDecl * baseEnum = enumInst->base;
     165                        // Need to iterate over all enum value to find the initializer to swap
     166                        for ( size_t m = 0; m < baseEnum->members.size(); ++m ) {
     167                            const ast::ObjectDecl * mem = baseEnum->members.at(m).as<const ast::ObjectDecl>();
     168                            if ( baseEnum->members.at(m)->name == designatorName->name ) {
     169                                assert(mem);
     170                                newDesignators.push_back( ast::ConstantExpr::from_int(designator->location, m) );
     171                                // mutated = true;
     172                                break;
     173                            }
     174                        }
     175                    } else {
     176                        newDesignators.push_back( des->designators.at(0) );
     177                    }
     178                } else {
     179                    newDesignators.push_back( des->designators.at(0) );
     180                }
     181            }           
     182           
     183            newDesignation->designators = newDesignators;
     184            mutListInit = ast::mutate_field_index(mutListInit, &ast::ListInit::designations, k, newDesignation);
     185           
     186        }
     187    }
     188    return mutDecl;
    180189}
    181190
    182 } // namespace ResolvExpr
     191}  // namespace ResolvExpr
    183192
    184193// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.