Changeset 28f8f15 for src/Validate


Ignore:
Timestamp:
Apr 27, 2023, 3:13:24 PM (2 years ago)
Author:
JiadaL <j82liang@…>
Branches:
ADT
Children:
561354f
Parents:
b110bcc
Message:

Save progress

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Validate/Autogen.cpp

    rb110bcc r28f8f15  
    125125        // Built-ins do not use autogeneration.
    126126        bool shouldAutogen() const final { return !decl->linkage.is_builtin && !structHasFlexibleArray(decl); }
     127        void genADTFuncs();
     128        void getADTFuncBody(const ast::ObjectDecl * lhs, ast::FunctionDecl * func);
    127129private:
    128130        void genFuncBody( ast::FunctionDecl * decl ) final;
     
    193195        }
    194196
    195         bool shouldAutogen() const final { return true; }
     197        bool shouldAutogen() const final { return !(decl->isData); }
    196198private:
    197199        void genFuncBody( ast::FunctionDecl * decl ) final;
     
    238240        if ( !enumDecl->body ) return;
    239241
    240         // if ( auto enumBaseType = enumDecl->base ) {
    241         //      if ( auto enumBaseTypeAsStructInst = dynamic_cast<const ast::StructInstType *>(enumBaseType.get()) ) {
    242         //              const ast::StructDecl * structDecl = enumBaseTypeAsStructInst->base.get();
    243         //              this->previsit( structDecl );
    244         //      }
    245         // }
    246 
    247242        ast::EnumInstType enumInst( enumDecl->name );
    248243        enumInst.base = enumDecl;
     
    264259        }
    265260        StructFuncGenerator gen( structDecl, &structInst, functionNesting );
     261
     262        gen.genADTFuncs();
    266263        gen.generateAndAppendFunctions( declsToAddAfter );
    267264}
     
    475472                }
    476473                produceDecl( decl );
     474        }
     475}
     476
     477void StructFuncGenerator::getADTFuncBody(
     478                const ast::ObjectDecl * lhs,
     479                ast::FunctionDecl * func
     480        ) {
     481        const CodeLocation& location = func->location;
     482        assert( decl->members.size() == 2 );
     483        auto first = (decl->members[0]).as<ast::ObjectDecl>();
     484        assert(first != nullptr);
     485        auto firstType = first->type;
     486        auto unionInstDecl = firstType.as<ast::UnionInstType>();
     487        assert(unionInstDecl != nullptr);
     488
     489        auto unionDecl = unionInstDecl->base;
     490       
     491        const ast::ObjectDecl * dstParam =
     492                        func->params.front().strict_as<ast::ObjectDecl>();
     493        const ast::ObjectDecl * srcParam =
     494                        func->params.back().strict_as<ast::ObjectDecl>();
     495       
     496        ast::Expr * srcSelect = new ast::VariableExpr( location, srcParam );
     497
     498        ast::CompoundStmt * stmts = new ast::CompoundStmt( location );
     499
     500        InitTweak::InitExpander_new srcParamTweak( srcSelect );
     501        ast::Expr * dstSelect =
     502        new ast::MemberExpr(
     503                location,
     504                lhs,
     505                new ast::MemberExpr(
     506                        location,
     507                        first,
     508                        new ast::CastExpr(
     509                                location,
     510                                new ast::VariableExpr( location, dstParam ),
     511                                dstParam->type.strict_as<ast::ReferenceType>()->base
     512                        )
     513                )
     514        );
     515        auto stmt = genImplicitCall(
     516                srcParamTweak, dstSelect, location, func->name,
     517                first, SymTab::LoopForward
     518        );
     519        stmts->push_back( stmt );
     520        func->stmts = stmts;
     521}
     522
     523void StructFuncGenerator::genADTFuncs() {
     524        if ( decl->kind != ast::AggregateDecl::ADT ) return;
     525        assert( decl->members.size() == 2 );
     526        auto first = (decl->members[0]).as<ast::ObjectDecl>();
     527        assert(first != nullptr);
     528        auto firstType = first->type;
     529        auto unionInstDecl = firstType.as<ast::UnionInstType>();
     530        assert(unionInstDecl != nullptr);
     531        auto unionDecl = unionInstDecl->base;
     532
     533        // for (auto mem: unionDecl->members) {
     534        for ( std::size_t i = 0; i < unionDecl->members.size(); ++i ) {
     535                auto mem = unionDecl->members[i];
     536                const ast::ObjectDecl * mem_as_obj = mem.as<ast::ObjectDecl>();
     537                assert( mem_as_obj );
     538                auto mem_type = mem_as_obj->type.as<ast::StructInstType>();
     539                assert( mem_type );
     540                auto location = getLocation();
     541                ast::FunctionDecl * func = new ast::FunctionDecl(
     542                        getLocation(),
     543                        "?{}", // name
     544                        {}, //forall
     545                        { dstParam(), new ast::ObjectDecl( getLocation(), "_src", ast::deepCopy( mem_type ) ) }, // params
     546                        {}, // returns
     547                        {}, // statements
     548                        // Use static storage if we are at the top level.
     549                        (0 < functionNesting) ? ast::Storage::Classes() : ast::Storage::Static,
     550                        proto_linkage,
     551                        std::vector<ast::ptr<ast::Attribute>>(),
     552                        // Auto-generated routines are inline to avoid conflicts.
     553                        ast::Function::Specs( ast::Function::Inline )
     554                );
     555                getADTFuncBody(mem_as_obj, func);
     556                func->fixUniqueId();
     557                produceForwardDecl(func);
     558                if ( CodeGen::isAssignment( func->name ) ) {
     559                        appendReturnThis( func );
     560                }
     561                produceDecl( func );
    477562        }
    478563}
Note: See TracChangeset for help on using the changeset viewer.