Changeset c1e66d9


Ignore:
Timestamp:
Sep 21, 2023, 10:15:37 PM (5 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
deda7e6
Parents:
01510fe
Message:

Fix designator value in enumerated array and implemented enumerated array with inlined enume declaration

Location:
src
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Pass.impl.hpp

    r01510fe rc1e66d9  
    18601860                maybe_accept( node, &ArrayType::dimension );
    18611861                maybe_accept( node, &ArrayType::base );
     1862                maybe_accept( node, &ArrayType::declaredType );
    18621863        }
    18631864
  • src/AST/Type.hpp

    r01510fe rc1e66d9  
    216216        DimensionFlag isStatic;
    217217
     218        ptr<Decl> declaredType;
     219
    218220        ArrayType( const Type * b, const Expr * d, LengthFlag vl, DimensionFlag s,
    219221                CV::Qualifiers q = {} ) : Type(q), base(b), dimension(d), isVarLen(vl), isStatic(s) {}
  • src/Parser/DeclarationNode.cc

    r01510fe rc1e66d9  
    394394        return newnode->addQualifiers( qualifiers );
    395395} // DeclarationNode::newArray
     396
     397DeclarationNode * DeclarationNode::newInlineEnumeratedArray( DeclarationNode * enumDecl, DeclarationNode * qualifiers ) {
     398        DeclarationNode * newnode = new DeclarationNode;
     399        newnode->type = new TypeData( TypeData::Array );
     400        newnode->type->array.isStatic = false;
     401        newnode->type->array.isVarLen = false;
     402
     403        if ( enumDecl ) {
     404                newnode->type->declType = enumDecl->type;
     405                enumDecl->type = nullptr;
     406                delete enumDecl;
     407        } // if
     408       
     409        return newnode->addQualifiers( qualifiers );
     410}
    396411
    397412DeclarationNode * DeclarationNode::newVarArray( DeclarationNode * qualifiers ) {
  • src/Parser/DeclarationNode.h

    r01510fe rc1e66d9  
    6666        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
    6767        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
     68        static DeclarationNode * newInlineEnumeratedArray( DeclarationNode * enumDecl, DeclarationNode * qualifiers );
    6869        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
    6970        static DeclarationNode * newBitfield( ExpressionNode * size );
  • src/Parser/TypeData.cc

    r01510fe rc1e66d9  
    10211021                );
    10221022        } // if
     1023        if ( td->declType) {
     1024                at->declaredType = buildEnum( td->declType, std::vector<ast::ptr<ast::Attribute>>(), ast::Linkage::Cforall );
     1025        }
    10231026        return at;
    10241027} // buildArray
  • src/Parser/TypeData.h

    r01510fe rc1e66d9  
    8585        Kind kind;
    8686        TypeData * base;
     87        TypeData * declType;
    8788        DeclarationNode::BasicType basictype = DeclarationNode::NoBasicType;
    8889        DeclarationNode::ComplexType complextype = DeclarationNode::NoComplexType;
  • src/Parser/parser.yy

    r01510fe rc1e66d9  
    38553855        | '[' push array_type_list pop ']'                                      // CFA
    38563856                { $$ = DeclarationNode::newArray( $3, nullptr, false ); }
     3857        | '[' push INLINE enum_type_nobody pop']'
     3858                {       
     3859                        $$ = DeclarationNode::newInlineEnumeratedArray( $4, nullptr );
     3860                }
    38573861        | multi_array_dimension
    38583862        ;
  • src/ResolvExpr/ResolveTypeof.cc

    r01510fe rc1e66d9  
    2424#include "AST/Type.hpp"
    2525#include "AST/TypeEnvironment.hpp"
    26 #include "Common/PassVisitor.h"   // for PassVisitor
    27 #include "Common/utility.h"       // for copy
    28 #include "InitTweak/InitTweak.h"  // for isConstExpr
     26#include "Common/PassVisitor.h"    // for PassVisitor
     27#include "Common/SemanticError.h"  // for SemanticError
     28#include "Common/utility.h"        // for copy
     29#include "InitTweak/InitTweak.h"   // for isConstExpr
    2930#include "RenameVars.h"
    3031#include "Resolver.h"  // for resolveInVoidContext
     
    5051                }
    5152#endif
    52         }
     53}  // namespace
    5354
    5455class ResolveTypeof_old : public WithShortCircuiting {
    5556   public:
    56                 ResolveTypeof_old( const SymTab::Indexer &indexer ) : indexer( indexer ) {}
    57                 void premutate( TypeofType *typeofType );
    58                 Type * postmutate( TypeofType *typeofType );
     57    ResolveTypeof_old(const SymTab::Indexer &indexer) : indexer(indexer) {}
     58    void premutate(TypeofType *typeofType);
     59    Type *postmutate(TypeofType *typeofType);
    5960
    6061   private:
     
    6263};
    6364
    64         Type * resolveTypeof( Type *type, const SymTab::Indexer &indexer ) {
    65                 PassVisitor<ResolveTypeof_old> mutator( indexer );
    66                 return type->acceptMutator( mutator );
    67         }
    68 
    69         void ResolveTypeof_old::premutate( TypeofType * ) {
    70                 visit_children = false;
    71         }
    72 
    73     Type * ResolveTypeof_old::postmutate( TypeofType *typeofType ) {
     65Type *resolveTypeof(Type *type, const SymTab::Indexer &indexer) {
     66    PassVisitor<ResolveTypeof_old> mutator(indexer);
     67    return type->acceptMutator(mutator);
     68}
     69
     70void ResolveTypeof_old::premutate(TypeofType *) { visit_children = false; }
     71
     72Type *ResolveTypeof_old::postmutate(TypeofType *typeofType) {
    7473#if 0
    7574                std::cerr << "resolving typeof: ";
     
    7877#endif
    7978    // pass on null expression
    80                 if ( ! typeofType->expr ) return typeofType;
     79    if (!typeofType->expr) return typeofType;
    8180
    8281    bool isBasetypeof = typeofType->is_basetypeof;
     
    8483
    8584    Type* newType;
    86                 if ( TypeExpr* tyExpr = dynamic_cast<TypeExpr*>(typeofType->expr) ) {
     85    if ( TypeExpr* tyExpr = dynamic_cast<TypeExpr*>( typeofType->expr ) ) {
    8786        // typeof wrapping type
    8887        newType = tyExpr->type;
     
    9190    } else {
    9291        // typeof wrapping expression
    93                         Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer );
    94                         assert( newExpr->result && ! newExpr->result->isVoid() );
     92        Expression *newExpr = resolveInVoidContext(typeofType->expr, indexer);
     93        assert(newExpr->result && !newExpr->result->isVoid());
    9594        newType = newExpr->result;
    9695        newExpr->result = nullptr;
     
    10099
    101100    // clear qualifiers for base, combine with typeoftype quals in any case
    102     if ( isBasetypeof ) {
    103                         // replace basetypeof(<enum>) by int
    104                         if ( dynamic_cast<EnumInstType*>(newType) ) {
    105                                 Type* newerType =
    106                                         new BasicType{ newType->get_qualifiers(), BasicType::SignedInt,
    107                                         newType->attributes };
    108                                 delete newType;
    109                                 newType = newerType;
    110                         }
    111                         newType->get_qualifiers().val
    112                                 = ( newType->get_qualifiers().val & ~Type::Qualifiers::Mask ) | oldQuals;
    113                 } else {
     101    if (isBasetypeof) {
     102        // replace basetypeof(<enum>) by int
     103        if (dynamic_cast<EnumInstType *>(newType)) {
     104            Type *newerType =
     105                new BasicType{newType->get_qualifiers(), BasicType::SignedInt,
     106                              newType->attributes};
     107            delete newType;
     108            newType = newerType;
     109        }
     110        newType->get_qualifiers().val =
     111            (newType->get_qualifiers().val & ~Type::Qualifiers::Mask) |
     112            oldQuals;
     113    } else {
    114114        newType->get_qualifiers().val |= oldQuals;
    115115    }
     
    120120namespace {
    121121struct ResolveTypeof_new : public ast::WithShortCircuiting {
    122     const ResolveContext & context;
    123 
    124                 ResolveTypeof_new( const ResolveContext & context ) :
    125                         context( context ) {}
    126 
    127                 void previsit( const ast::TypeofType * ) { visit_children = false; }
    128 
    129         const ast::Type * postvisit( const ast::TypeofType * typeofType ) {
     122    const ResolveContext &context;
     123
     124    ResolveTypeof_new(const ResolveContext &context) : context(context) {}
     125
     126    void previsit(const ast::TypeofType *) { visit_children = false; }
     127
     128    const ast::Type *postvisit(const ast::TypeofType *typeofType) {
    130129        // 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 >() ) {
     130        if (!typeofType->expr) return typeofType;
     131
     132        ast::ptr<ast::Type> newType;
     133        if (auto tyExpr = typeofType->expr.as<ast::TypeExpr>()) {
    135134            // typeof wrapping type
    136135            newType = tyExpr->type;
     
    138137            // typeof wrapping expression
    139138            ast::TypeEnvironment dummy;
    140             ast::ptr< ast::Expr > newExpr =
    141                 resolveInVoidContext( typeofType->expr, context, dummy );
    142             assert( newExpr->result && ! newExpr->result->isVoid() );
     139            ast::ptr<ast::Expr> newExpr =
     140                resolveInVoidContext(typeofType->expr, context, dummy);
     141            assert(newExpr->result && !newExpr->result->isVoid());
    143142            newType = newExpr->result;
    144143        }
    145144
    146145        // clear qualifiers for base, combine with typeoftype quals regardless
    147         if ( typeofType->kind == ast::TypeofType::Basetypeof ) {
     146        if (typeofType->kind == ast::TypeofType::Basetypeof) {
    148147            // replace basetypeof(<enum>) by int
    149                                 if ( newType.as< ast::EnumInstType >() ) {
    150                                         newType = new ast::BasicType{
    151                                                 ast::BasicType::SignedInt, newType->qualifiers, copy(newType->attributes) };
     148            if (newType.as<ast::EnumInstType>()) {
     149                newType = new ast::BasicType{ast::BasicType::SignedInt,
     150                                             newType->qualifiers,
     151                                             copy(newType->attributes)};
    152152            }
    153                                 reset_qualifiers(
    154                                         newType,
    155                                         ( newType->qualifiers & ~ast::CV::EquivQualifiers ) | typeofType->qualifiers );
     153            reset_qualifiers(newType,
     154                             (newType->qualifiers & ~ast::CV::EquivQualifiers) |
     155                                 typeofType->qualifiers);
    156156        } else {
    157                                 add_qualifiers( newType, typeofType->qualifiers );
     157            add_qualifiers(newType, typeofType->qualifiers);
    158158        }
    159159
     
    161161    }
    162162};
    163 } // anonymous namespace
    164 
    165 const ast::Type * resolveTypeof( const ast::Type * type , const ResolveContext & context ) {
    166         ast::Pass< ResolveTypeof_new > mutator( context );
    167         return type->accept( mutator );
     163}  // anonymous namespace
     164
     165const ast::Type *resolveTypeof(const ast::Type *type,
     166                               const ResolveContext &context) {
     167    ast::Pass<ResolveTypeof_new> mutator(context);
     168    return type->accept(mutator);
    168169}
    169170
    170171struct FixArrayDimension {
    171         const ResolveContext & context;
    172         FixArrayDimension(const ResolveContext & context) : context( context ) {}
    173 
    174         const ast::ArrayType * previsit (const ast::ArrayType * arrayType) {
    175                 if (!arrayType->dimension) return arrayType;
    176                 auto mutType = mutate(arrayType);
    177                 auto globalSizeType = context.global.sizeType;
    178                 ast::ptr<ast::Type> sizetype = globalSizeType ? globalSizeType : new ast::BasicType(ast::BasicType::LongUnsignedInt);
    179                 mutType->dimension = findSingleExpression(arrayType->dimension, sizetype, context );
    180 
    181                 if (InitTweak::isConstExpr(mutType->dimension)) {
    182                         mutType->isVarLen = ast::LengthFlag::FixedLen;
    183                 }
    184                 else {
    185                         mutType->isVarLen = ast::LengthFlag::VariableLen;
    186                 }
    187                 return mutType;
    188         }
     172    const ResolveContext &context;
     173    FixArrayDimension(const ResolveContext &context) : context(context) {}
     174
     175    const ast::ArrayType *previsit(const ast::ArrayType *arrayType) {
     176        if (!arrayType->dimension) return arrayType;
     177        auto mutType = mutate(arrayType);
     178        auto globalSizeType = context.global.sizeType;
     179        ast::ptr<ast::Type> sizetype =
     180            globalSizeType
     181                ? globalSizeType
     182                : new ast::BasicType(ast::BasicType::LongUnsignedInt);
     183        mutType->dimension =
     184            findSingleExpression(arrayType->dimension, sizetype, context);
     185
     186        if (InitTweak::isConstExpr(mutType->dimension)) {
     187            mutType->isVarLen = ast::LengthFlag::FixedLen;
     188        } else {
     189            mutType->isVarLen = ast::LengthFlag::VariableLen;
     190        }
     191        return mutType;
     192    }
    189193};
    190194
    191 const ast::Type * fixArrayType( const ast::Type * type, const ResolveContext & context ) {
    192         ast::Pass<FixArrayDimension> visitor(context);
    193         return type->accept(visitor);
    194 }
    195 
    196 const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & context ) {
     195struct FixEnumeratedArray {
     196    const ResolveContext &context;
     197    const ast::ListInit *init;
     198    FixEnumeratedArray(const ResolveContext &context, const ast::ListInit *init)
     199        : context(context), init(init) {}
     200
     201    const ast::ArrayType *previsit(const ast::ArrayType *arrayType) {
     202        return arrayType;
     203    }
     204
     205    // Enum Defined as inline field of array needs initalizer to define its
     206    // members
     207    const ast::EnumDecl *previsit(const ast::EnumDecl *enumDecl) {
     208        auto mutType = mutate(enumDecl);
     209        for (auto designation : init->designations) {
     210            std::deque<ast::ptr<ast::Expr>> designatorList =
     211                designation->designators;
     212            if (designatorList.size() != 1) {
     213                SemanticError(mutType,
     214                              "Multiple Initialization in enumerated array is "
     215                              "not supported.");
     216            }
     217            ast::ptr<ast::Expr> designator = designatorList.at(0);
     218            ast::ptr<ast::NameExpr> designatorAsName =
     219                designator.as<ast::NameExpr>();
     220            ast::ObjectDecl *memberDecl =
     221                new ast::ObjectDecl(enumDecl->location, designatorAsName->name,
     222                                    new ast::EnumInstType("", ast::CV::Const));
     223            mutType->members.push_back(memberDecl);
     224            // mutType->members.push_back( )
     225        }
     226        return mutType;
     227    }
     228};
     229
     230const ast::Type *fixArrayType(const ast::Type *type,
     231                              const ResolveContext &context) {
     232    ast::Pass<FixArrayDimension> visitor(context);
     233    return type->accept(visitor);
     234}
     235
     236const ast::ObjectDecl *fixObjectType(const ast::ObjectDecl *decl,
     237                                     const ResolveContext &context) {
    197238    if (decl->isTypeFixed) {
    198239        return decl;
     
    219260const ast::ObjectDecl *fixObjectInit(const ast::ObjectDecl *decl,
    220261                                     const ResolveContext &context) {
    221     if (decl->isTypeFixed) {
     262    if ( decl->isTypeFixed ) {
    222263        return decl;
    223264    }
    224265
    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             // Stupid flag variable for development, to be removed
    240             bool mutated = false;
    241             if ( const ast::NameExpr * designatorName = dynamic_cast<const ast::NameExpr *>(designator) ) {
    242                 auto candidates = context.symtab.lookupId(designatorName->name);
    243                 // Does not work for the overloading case currently
    244                 // assert( candidates.size() == 1 );
    245                 if ( candidates.size() != 1 ) return mutDecl;
    246                 auto candidate = candidates.at(0);
    247                 if ( const ast::EnumInstType * enumInst = dynamic_cast<const ast::EnumInstType *>(candidate.id->get_type())) {
    248                     // determine that is an enumInst, swap it with its const value
    249                     assert( candidates.size() == 1 );
    250                     const ast::EnumDecl * baseEnum = enumInst->base;
    251                     // Need to iterate over all enum value to find the initializer to swap
    252                     for ( size_t m = 0; m < baseEnum->members.size(); ++m ) {
    253                         const ast::ObjectDecl * mem = baseEnum->members.at(m).as<const ast::ObjectDecl>();
    254                         if ( baseEnum->members.at(m)->name == designatorName->name ) {
    255                             assert(mem);
    256                             if ( mem->init ) {
    257                                 const ast::SingleInit * memInit = mem->init.as<const ast::SingleInit>();
    258                                 ast::Expr * initValue = shallowCopy( memInit->value.get() );
    259                                 newDesination->designators.push_back( initValue );
    260                                 mutated = true;
    261                             }
    262                             break;
    263                         }
    264                     }
     266    auto mutDecl = mutate( decl );
     267
     268    if ( const ast::ListInit * listInit = mutDecl->init.as<ast::ListInit>() ) {
     269        ast::ListInit * mutListInit = mutate( listInit );
     270        // ListInit::designations is std::vector<ptr<Designation>>
     271        // ((ast::ListInit)mutDecl->init).designations = newDesignations
     272        std::vector<ast::ptr<ast::Designation>> newDesignations;
     273       
     274        // The loop iterates over ListInit::designations and push member to newDesignations
     275        for ( ast::ptr<ast::Designation> des : listInit->designations ) {
     276            ast::Designation * newDesignation = mutate( des.get() );
     277           
     278            std::deque<ast::ptr<ast::Expr>> newDesignators;
     279            for ( const ast::Expr *designator : des->designators ) {
     280                if ( const ast::NameExpr *designatorName = dynamic_cast<const ast::NameExpr *>(designator) ) {
     281                    auto candidates = context.symtab.lookupId(designatorName->name);
     282                    if ( candidates.size() == 0 ) {
     283                        newDesignators.push_back(designator);
     284                    } else {
     285                        auto candidate = candidates.at(0);
     286                        if ( const ast::EnumInstType *enumInst = dynamic_cast<const ast::EnumInstType *>(candidate.id->get_type()) ) {
     287                            const ast::EnumDecl * baseEnum = enumInst->base;
     288                            // // Need to iterate over all enum value to find the
     289                            // // initializer to swap
     290                            for (size_t m = 0; m < baseEnum->members.size(); ++m) {
     291                                const ast::ObjectDecl *mem = baseEnum->members.at(m).as<const ast::ObjectDecl>();
     292                                if (baseEnum->members.at(m)->name == designatorName->name) {
     293                                    assert(mem);
     294                                    newDesignators.push_back( ast::ConstantExpr::from_int(des->location,  m ));
     295                                }
     296                            } // for
     297                            assert(newDesignators.size() > 0);
     298                        } else {
     299                            newDesignators.push_back(designator);
     300                        } //if
     301                    } 
    265302                } else {
    266                     newDesination->designators.push_back( des->designators.at(0) );
    267                 }
    268             } else {
    269                 newDesination->designators.push_back( des->designators.at(0) );
    270             }
    271             if ( mutated ) {
    272                 mutListInit = ast::mutate_field_index(mutListInit, &ast::ListInit::designations, k, newDesination);
    273             }
    274         }
    275     }
     303                    newDesignators.push_back(designator);
     304                } // if
     305            } // for
     306           
     307            newDesignation->designators = newDesignators;
     308            newDesignations.push_back( newDesignation );
     309        } // for
     310        // mutListInit->designations = newDesignations;
     311        ast::mutate_field( mutListInit, &ast::ListInit::designations, newDesignations );
     312        ast::mutate_field( mutDecl, &ast::ObjectDecl::init, mutListInit );
     313    } // if
    276314    return mutDecl;
    277315}
  • src/ResolvExpr/ResolveTypeof.h

    r01510fe rc1e66d9  
    1717
    1818class Type;
     19class ListInit;
    1920namespace SymTab {
    2021class Indexer;
     
    2223namespace ast {
    2324        class Type;
     25        class ListInit;
    2426        class ObjectDecl;
    2527}
     
    2830        struct ResolveContext;
    2931
    30         Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
     32        Type *resolveTypeof( Type *, const SymTab::Indexer &indexer );
    3133        const ast::Type * resolveTypeof( const ast::Type *, const ResolveContext & );
    32         const ast::Type * fixArrayType( const ast::Type *, const ResolveContext & );
     34        const ast::Type * fixArrayType( const ast::Type *, const ResolveContext &, const ast::ListInit * );
     35        const ast::Type * fixEnumeratedArray( const ast::Type *, const ResolveContext & );
    3336        const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & );
    34         const ast::ObjectDecl * fixObjectInit( const ast::ObjectDecl * decl , const ResolveContext &);
     37        const ast::ObjectDecl * fixObjectInit( const ast::ObjectDecl * decl , const ResolveContext & );
    3538} // namespace ResolvExpr
    3639
  • src/Validate/module.mk

    r01510fe rc1e66d9  
    2929        Validate/EnumAndPointerDecay.hpp \
    3030        Validate/FindSpecialDeclsNew.cpp \
     31        Validate/FixEnumeratedArray.hpp \
     32        Validate/FixEnumeratedArray.cpp \
    3133        Validate/FixQualifiedTypes.cpp \
    3234        Validate/FixQualifiedTypes.hpp \
  • src/main.cc

    r01510fe rc1e66d9  
    7373#include "Validate/FixQualifiedTypes.hpp"   // for fixQualifiedTypes
    7474#include "Validate/FixReturnTypes.hpp"      // for fixReturnTypes
     75#include "Validate/FixEnumeratedArray.hpp"  // for fixEnumeratedArray
    7576#include "Validate/ForallPointerDecay.hpp"  // for decayForallPointers
    7677#include "Validate/GenericParameter.hpp"    // for fillGenericParameters, tr...
     
    333334
    334335                PASS( "Link Reference To Types", Validate::linkReferenceToTypes, transUnit );
     336                PASS( "Fix Enumerated Array", Validate::fixEnumeratedArray, transUnit );
    335337
    336338                PASS( "Forall Pointer Decay", Validate::decayForallPointers, transUnit );
Note: See TracChangeset for help on using the changeset viewer.