Changeset 92355883 for src


Ignore:
Timestamp:
Aug 31, 2023, 5:51:00 PM (16 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
2a301ff
Parents:
c84dd61
Message:

Array can use enum instance with explicit initializer as designator. More general case will be covered in later commit

Location:
src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/parser.yy

    rc84dd61 r92355883  
    26962696        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt
    26972697                {
    2698                         if ( $3->storageClasses.any() || $3->type->qualifiers.val != 0 ) {
     2698                        if ( $3 && ($3->storageClasses.any() || $3->type->qualifiers.val != 0 )) {
    26992699                                SemanticError( yylloc, "syntax error, storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." );
    27002700                        }
  • src/ResolvExpr/CurrentObject.cc

    rc84dd61 r92355883  
    10451045                        PRINT( std::cerr << "____untyped: " << expr << std::endl; )
    10461046                        auto dit = desigAlts.begin();
    1047                         if ( auto nexpr = dynamic_cast< const NameExpr * >( expr ) ) {
    1048                                 for ( const Type * t : curTypes ) {
    1049                                         assert( dit != desigAlts.end() );
    1050 
    1051                                         DesignatorChain & d = *dit;
     1047
     1048                        for ( const Type * t : curTypes ) {
     1049                                assert( dit != desigAlts.end() );
     1050                                DesignatorChain & d = *dit;
     1051                                if ( auto nexpr = dynamic_cast< const NameExpr *>( expr ) ) {
    10521052                                        PRINT( std::cerr << "____actual: " << t << std::endl; )
    10531053                                        if ( auto refType = dynamic_cast< const BaseInstType * >( t ) ) {
     
    10621062                                                        }
    10631063                                                }
     1064                                        } else if ( auto at = dynamic_cast< const ArrayType * >( t ) ) {
     1065                                                auto nexpr = dynamic_cast< const NameExpr *>( expr );
     1066                                                auto res = eval( nexpr );
     1067                                                for ( const Decl * mem : refType->lookup( nexpr->name ) ) {
     1068                                                        if ( auto field = dynamic_cast< const ObjectDecl * >( mem ) ) {
     1069                                                                DesignatorChain d2 = d;
     1070                                                                d2.emplace_back( new VariableExpr{ expr->location, field } );
     1071                                                                newDesigAlts.emplace_back( std::move( d2 ) );
     1072                                                                // newTypes.emplace_back( field->type );
     1073                                                                newTypes.emplace_back( at->base );
     1074                                                        }
     1075                                                }
     1076
     1077                                                // d.emplace_back( expr );
     1078                                                // newDesigAlts.emplace_back( d );
     1079                                                // newTypes.emplace_back( at->base );
    10641080                                        }
    10651081
    10661082                                        ++dit;
    1067                                 }
    1068                         } else {
    1069                                 for ( const Type * t : curTypes ) {
    1070                                         assert( dit != desigAlts.end() );
    1071 
    1072                                         DesignatorChain & d = *dit;
     1083                                } else {
    10731084                                        if ( auto at = dynamic_cast< const ArrayType * >( t ) ) {
    10741085                                                PRINT( std::cerr << "____alt: " << at->get_base() << std::endl; )
  • src/ResolvExpr/ResolveTypeof.cc

    rc84dd61 r92355883  
    1515
    1616#include "ResolveTypeof.h"
    17 #include "RenameVars.h"
    18 
    19 #include <cassert>               // for assert
     17
     18#include <cassert>  // for assert
    2019
    2120#include "AST/CVQualifiers.hpp"
     
    2524#include "AST/Type.hpp"
    2625#include "AST/TypeEnvironment.hpp"
    27 #include "Common/PassVisitor.h"  // for PassVisitor
    28 #include "Common/utility.h"      // for copy
    29 #include "Resolver.h"            // for resolveInVoidContext
     26#include "Common/PassVisitor.h"   // for PassVisitor
     27#include "Common/utility.h"       // for copy
     28#include "InitTweak/InitTweak.h"  // for isConstExpr
     29#include "RenameVars.h"
     30#include "Resolver.h"  // for resolveInVoidContext
     31#include "SymTab/Mangler.h"
    3032#include "SynTree/Expression.h"  // for Expression
    3133#include "SynTree/Mutator.h"     // for Mutator
    3234#include "SynTree/Type.h"        // for TypeofType, Type
    33 #include "SymTab/Mangler.h"
    34 #include "InitTweak/InitTweak.h" // for isConstExpr
    3535
    3636namespace SymTab {
     
    3939
    4040namespace ResolvExpr {
    41         namespace {
     41namespace {
    4242#if 0
    4343                void
     
    5252        }
    5353
    54         class ResolveTypeof_old : public WithShortCircuiting {
    55           public:
     54class ResolveTypeof_old : public WithShortCircuiting {
     55   public:
    5656                ResolveTypeof_old( const SymTab::Indexer &indexer ) : indexer( indexer ) {}
    5757                void premutate( TypeofType *typeofType );
    5858                Type * postmutate( TypeofType *typeofType );
    5959
    60           private:
    61                 const SymTab::Indexer &indexer;
    62         };
     60   private:
     61    const SymTab::Indexer &indexer;
     62};
    6363
    6464        Type * resolveTypeof( Type *type, const SymTab::Indexer &indexer ) {
     
    7171        }
    7272
    73         Type * ResolveTypeof_old::postmutate( TypeofType *typeofType ) {
     73    Type * ResolveTypeof_old::postmutate( TypeofType *typeofType ) {
    7474#if 0
    7575                std::cerr << "resolving typeof: ";
     
    7777                std::cerr << std::endl;
    7878#endif
    79                 // pass on null expression
     79    // pass on null expression
    8080                if ( ! typeofType->expr ) return typeofType;
    8181
    82                 bool isBasetypeof = typeofType->is_basetypeof;
    83                 auto oldQuals = typeofType->get_qualifiers().val;
    84 
    85                 Type* newType;
     82    bool isBasetypeof = typeofType->is_basetypeof;
     83    auto oldQuals = typeofType->get_qualifiers().val;
     84
     85    Type* newType;
    8686                if ( TypeExpr* tyExpr = dynamic_cast<TypeExpr*>(typeofType->expr) ) {
    87                         // typeof wrapping type
    88                         newType = tyExpr->type;
    89                         tyExpr->type = nullptr;
    90                         delete tyExpr;
    91                 } else {
    92                         // typeof wrapping expression
     87        // typeof wrapping type
     88        newType = tyExpr->type;
     89        tyExpr->type = nullptr;
     90        delete tyExpr;
     91    } else {
     92        // typeof wrapping expression
    9393                        Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer );
    9494                        assert( newExpr->result && ! newExpr->result->isVoid() );
    95                         newType = newExpr->result;
    96                         newExpr->result = nullptr;
    97                         delete typeofType;
    98                         delete newExpr;
    99                 }
    100 
    101                 // clear qualifiers for base, combine with typeoftype quals in any case
    102                 if ( isBasetypeof ) {
     95        newType = newExpr->result;
     96        newExpr->result = nullptr;
     97        delete typeofType;
     98        delete newExpr;
     99    }
     100
     101    // clear qualifiers for base, combine with typeoftype quals in any case
     102    if ( isBasetypeof ) {
    103103                        // replace basetypeof(<enum>) by int
    104104                        if ( dynamic_cast<EnumInstType*>(newType) ) {
     
    112112                                = ( newType->get_qualifiers().val & ~Type::Qualifiers::Mask ) | oldQuals;
    113113                } else {
    114                         newType->get_qualifiers().val |= oldQuals;
    115                 }
    116 
    117                 return newType;
    118         }
     114        newType->get_qualifiers().val |= oldQuals;
     115    }
     116
     117    return newType;
     118}
    119119
    120120namespace {
    121         struct ResolveTypeof_new : public ast::WithShortCircuiting {
    122                 const ResolveContext & context;
     121struct ResolveTypeof_new : public ast::WithShortCircuiting {
     122    const ResolveContext & context;
    123123
    124124                ResolveTypeof_new( const ResolveContext & context ) :
     
    127127                void previsit( const ast::TypeofType * ) { visit_children = false; }
    128128
    129                 const ast::Type * postvisit( const ast::TypeofType * typeofType ) {
    130                         // pass on null expression
    131                         if ( ! typeofType->expr ) return typeofType;
    132 
    133                         ast::ptr< ast::Type > newType;
    134                         if ( auto tyExpr = typeofType->expr.as< ast::TypeExpr >() ) {
    135                                 // typeof wrapping type
    136                                 newType = tyExpr->type;
    137                         } else {
    138                                 // typeof wrapping expression
    139                                 ast::TypeEnvironment dummy;
    140                                 ast::ptr< ast::Expr > newExpr =
    141                                         resolveInVoidContext( typeofType->expr, context, dummy );
    142                                 assert( newExpr->result && ! newExpr->result->isVoid() );
    143                                 newType = newExpr->result;
    144                         }
    145 
    146                         // clear qualifiers for base, combine with typeoftype quals regardless
    147                         if ( typeofType->kind == ast::TypeofType::Basetypeof ) {
    148                                 // replace basetypeof(<enum>) by int
     129        const ast::Type * postvisit( const ast::TypeofType * typeofType ) {
     130        // pass on null expression
     131            if ( ! typeofType->expr ) return typeofType;
     132
     133            ast::ptr< ast::Type > newType;
     134            if ( auto tyExpr = typeofType->expr.as< ast::TypeExpr >() ) {
     135            // typeof wrapping type
     136            newType = tyExpr->type;
     137        } else {
     138            // typeof wrapping expression
     139            ast::TypeEnvironment dummy;
     140            ast::ptr< ast::Expr > newExpr =
     141                resolveInVoidContext( typeofType->expr, context, dummy );
     142            assert( newExpr->result && ! newExpr->result->isVoid() );
     143            newType = newExpr->result;
     144        }
     145
     146        // clear qualifiers for base, combine with typeoftype quals regardless
     147        if ( typeofType->kind == ast::TypeofType::Basetypeof ) {
     148            // replace basetypeof(<enum>) by int
    149149                                if ( newType.as< ast::EnumInstType >() ) {
    150150                                        newType = new ast::BasicType{
    151151                                                ast::BasicType::SignedInt, newType->qualifiers, copy(newType->attributes) };
    152                                 }
     152            }
    153153                                reset_qualifiers(
    154154                                        newType,
    155155                                        ( newType->qualifiers & ~ast::CV::EquivQualifiers ) | typeofType->qualifiers );
    156                         } else {
     156        } else {
    157157                                add_qualifiers( newType, typeofType->qualifiers );
    158                         }
    159 
    160                         return newType.release();
    161                 }
    162         };
     158        }
     159
     160        return newType.release();
     161    }
     162};
    163163} // anonymous namespace
    164164
     
    195195
    196196const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & context ) {
    197         if (decl->isTypeFixed) {
    198                 return decl;
    199         }
    200 
    201         auto mutDecl = mutate(decl);
    202         {
    203                 auto resolvedType = resolveTypeof(decl->type, context);
    204                 resolvedType = fixArrayType(resolvedType, context);
    205                 mutDecl->type = resolvedType;
    206         }
    207 
    208         // Do not mangle unnamed variables.
    209         if (!mutDecl->name.empty()) {
    210                 mutDecl->mangleName = Mangle::mangle(mutDecl);
    211         }
    212 
    213         mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID);
    214         mutDecl->isTypeFixed = true;
    215         return mutDecl;
    216 }
    217 
    218 } // namespace ResolvExpr
     197    if (decl->isTypeFixed) {
     198        return decl;
     199    }
     200
     201    auto mutDecl = mutate(decl);
     202    fixObjectInit(decl, context);
     203    {
     204        auto resolvedType = resolveTypeof(decl->type, context);
     205        resolvedType = fixArrayType(resolvedType, context);
     206        mutDecl->type = resolvedType;
     207    }
     208
     209    // Do not mangle unnamed variables.
     210    if (!mutDecl->name.empty()) {
     211        mutDecl->mangleName = Mangle::mangle(mutDecl);
     212    }
     213
     214    mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID);
     215    mutDecl->isTypeFixed = true;
     216    return mutDecl;
     217}
     218
     219const ast::ObjectDecl *fixObjectInit(const ast::ObjectDecl *decl,
     220                                     const ResolveContext &context) {
     221    if (decl->isTypeFixed) {
     222        return decl;
     223    }
     224
     225    auto mutDecl = mutate(decl);
     226
     227    if ( auto mutListInit = mutDecl->init.as<ast::ListInit>() ) {
     228        // std::list<ast::Designation *> newDesignations;       
     229
     230        for ( size_t k = 0; k < mutListInit->designations.size(); k++ ) {
     231            const ast::Designation *des = mutListInit->designations[k].get();
     232            // Desination here
     233            ast::Designation * newDesination = new ast::Designation(des->location);
     234
     235            if (des->designators.size() == 0) continue;
     236
     237            // The designator I want to replace
     238            const ast::Expr * designator = des->designators.at(0);
     239
     240            if ( const ast::NameExpr * designatorName = dynamic_cast<const ast::NameExpr *>(designator) ) {
     241                auto candidates = context.symtab.lookupId(designatorName->name);
     242                // Does not work for the overloading case currently
     243                // assert( candidates.size() == 1 );
     244                if ( candidates.size() != 1 ) return mutDecl;
     245                auto candidate = candidates.at(0);
     246                if ( const ast::EnumInstType * enumInst = dynamic_cast<const ast::EnumInstType *>(candidate.id->get_type()) ) {
     247                    // determine that is an enumInst, swap it with its const value
     248                    assert( candidates.size() == 1 );
     249                    const ast::EnumDecl * baseEnum = enumInst->base;
     250                    // Need to iterate over all enum value to find the initializer to swap
     251                    for ( size_t m = 0; m < baseEnum->members.size(); ++m ) {
     252                        if ( baseEnum->members.at(m)->name == designatorName->name ) {
     253                            const ast::ObjectDecl * mem = baseEnum->members.at(m).as<const ast::ObjectDecl>();
     254                            assert(mem);
     255                            if ( mem->init ) {
     256                                const ast::SingleInit * memInit = mem->init.as<const ast::SingleInit>();
     257                                ast::Expr * initValue = shallowCopy( memInit->value.get() );
     258                                newDesination->designators.push_back( initValue );
     259                            } else {
     260                                SemanticError(des->location, "TODO: Enum Array Designation with no explicit value is not implemented");
     261                            }
     262                        }
     263                    }
     264                    if ( newDesination->designators.size() == 0 ) {
     265                        SemanticError(des->location, "Resolution Error: Resolving array designation as Enum Instance value, but cannot find a desgination value");
     266                    }
     267                } else {
     268                    newDesination->designators.push_back( des->designators.at(0) );
     269                }
     270            } else {
     271                newDesination->designators.push_back( des->designators.at(0) );
     272            }
     273            mutListInit = ast::mutate_field_index(mutListInit, &ast::ListInit::designations, k, newDesination);
     274        }
     275    }
     276    return mutDecl;
     277}
     278
     279}  // namespace ResolvExpr
    219280
    220281// Local Variables: //
  • src/ResolvExpr/ResolveTypeof.h

    rc84dd61 r92355883  
    3131        const ast::Type * resolveTypeof( const ast::Type *, const ResolveContext & );
    3232        const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & );
     33        const ast::ObjectDecl * fixObjectInit( const ast::ObjectDecl * decl , const ResolveContext &);
    3334} // namespace ResolvExpr
    3435
  • src/ResolvExpr/Resolver.cc

    rc84dd61 r92355883  
    15071507                                if ( InitTweak::tryConstruct( mutDecl ) && ( managedTypes.isManaged( mutDecl ) || ((! isInFunction() || mutDecl->storage.is_static ) && ! InitTweak::isConstExpr( mutDecl->init ) ) ) ) {
    15081508                                        // constructed objects cannot be designated
    1509                                         if ( InitTweak::isDesignated( mutDecl->init ) ) SemanticError( mutDecl, "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n" );
     1509                                        // if ( InitTweak::isDesignated( mutDecl->init ) ) SemanticError( mutDecl, "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n" );
     1510                                        if ( InitTweak::isDesignated( mutDecl->init ) ) {
     1511                                                SemanticError( mutDecl, "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n" );
     1512                                        }
    15101513                                        // constructed objects should not have initializers nested too deeply
    15111514                                        if ( ! InitTweak::checkInitDepth( mutDecl ) ) SemanticError( mutDecl, "Managed object's initializer is too deep " );
Note: See TracChangeset for help on using the changeset viewer.