Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Validate/ImplementEnumFunc.cpp

    r822332e r85855b0  
    1010        const ast::EnumDecl* decl;
    1111        unsigned int functionNesting;
     12        const ast::StructDecl* quasi_void_decl;
    1213        ast::Linkage::Spec proto_linkage;
    1314
     
    2425                : decl(decl),
    2526                  functionNesting{functionNesting},
     27                  quasi_void_decl(new ast::StructDecl(decl->location,
     28                        "quasi_void", ast::AggregateDecl::Struct,
     29                        {}, ast::Linkage::AutoGen)),
    2630                  proto_linkage{ast::Linkage::Cforall} {}
    2731
     
    5256        void genSuccPredBody(ast::FunctionDecl *, const char *) const;
    5357
     58        void genTypeNameFunc();
     59
    5460        // Implement TypedEnum trait
    5561        void genTypedEnumFuncs();
     
    5864        ast::FunctionDecl* genLabelProto() const;
    5965        ast::FunctionDecl* genValueProto() const;
     66        ast::FunctionDecl* genQuasiValueProto() const;
     67        ast::FunctionDecl* genTypeNameProto() const;
     68
    6069        void genValueOrLabelBody(
    6170                ast::FunctionDecl* func, ast::ObjectDecl* arrDecl) const;
    6271        void genPosnBody(ast::FunctionDecl* func) const;
    63 
    64         ////////////////
    65 
    66         // ---------------------------------------------------
    67         // ast::FunctionDecl* genAttrCtorProto() const;
    68         /// Changes the node inside a pointer so that it has the unused attribute.
    69         void addUnusedAttribute(ast::ptr<ast::DeclWithType>& declPtr) {
    70                 ast::DeclWithType* decl = declPtr.get_and_mutate();
    71                 decl->attributes.push_back(new ast::Attribute("unused"));
    72         }
     72        void genQuasiValueBody(ast::FunctionDecl* func) const;
     73        void genTypeNameBody(ast::FunctionDecl* func) const;
    7374
    7475        // ----------------------------------------------------
     
    117118        return inits;
    118119}
     120
    119121const ast::Init* EnumAttrFuncGenerator::getAutoInit(
    120122        const ast::Init* prev) const {
     
    189191
    190192ast::FunctionDecl* EnumAttrFuncGenerator::genValueProto() const {
     193        if (decl->base)
     194                return genProto(
     195                        "valueE",
     196                        {new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
     197                        {new ast::ObjectDecl(getLocation(), "_ret",
     198                                                                ast::deepCopy(decl->base))});
     199        else
     200                return genQuasiValueProto();
     201}
     202
     203ast::FunctionDecl* EnumAttrFuncGenerator::genQuasiValueProto() const {
    191204        return genProto(
    192205                "valueE",
    193206                {new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
    194207                {new ast::ObjectDecl(getLocation(), "_ret",
    195                                      ast::deepCopy(decl->base))});
     208                                                new ast::StructInstType(quasi_void_decl))});
    196209}
    197210
     
    210223                {new ast::ObjectDecl(getLocation(), "_ret", new ast::BasicType(ast::BasicKind::UnsignedInt))}
    211224        );
     225}
     226
     227ast::FunctionDecl* EnumAttrFuncGenerator::genTypeNameProto() const {
     228        return genProto(
     229                "type_name",
     230                {new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))},
     231                {new ast::ObjectDecl(
     232                        getLocation(), "_ret",
     233                        new ast::PointerType(new ast::BasicType{ast::BasicKind::Char}))});
    212234}
    213235
     
    268290        );
    269291}
    270 
    271292
    272293void EnumAttrFuncGenerator::genSerialTraitFuncs() {
     
    302323        const CodeLocation & loc = func->location;
    303324        auto mem = func->name=="lowerBound"?  decl->members.front() : decl->members.back();
    304         auto expr = new ast::NameExpr( loc, mem->name );
     325        // auto expr = new ast::NameExpr( loc, mem->name );
     326        auto expr = new ast::QualifiedNameExpr( loc, decl->name, mem->name );
    305327        func->stmts = new ast::CompoundStmt( loc, {new ast::ReturnStmt(loc, expr)});
    306328}
     
    349371}
    350372
     373void EnumAttrFuncGenerator::genQuasiValueBody(ast::FunctionDecl* func) const {
     374        auto location = func->location;
     375        const ast::ObjectDecl * objDecl = new ast::ObjectDecl(
     376                location, "_out", new ast::StructInstType( quasi_void_decl ));
     377        const ast::DeclStmt * declStmt = new ast::DeclStmt(location, objDecl);
     378        const ast::VariableExpr * varExpr = new ast::VariableExpr(location, objDecl);
     379        const ast::ReturnStmt * retStmt = new ast::ReturnStmt(location, varExpr);
     380
     381        func->stmts = new ast::CompoundStmt(
     382                location, {declStmt, retStmt}
     383        );
     384}
     385
    351386void EnumAttrFuncGenerator::genPosnBody(ast::FunctionDecl* func) const {
    352387        auto castExpr = new ast::CastExpr(
     
    359394}
    360395
     396void EnumAttrFuncGenerator::genTypeNameBody(ast::FunctionDecl* func) const {
     397        const ast::Expr * type_name = ast::ConstantExpr::from_string(func->location, decl->name);
     398        func->stmts = new ast::CompoundStmt(
     399                func->location, {new ast::ReturnStmt(func->location, type_name)}
     400        );
     401}
     402
    361403void EnumAttrFuncGenerator::genTypedEnumFunction(const ast::EnumAttribute attr) {
    362         if (attr == ast::EnumAttribute::Value ||
    363                 attr == ast::EnumAttribute::Label) {
    364                 // TypedEnum's backing arrays
    365                 std::vector<ast::ptr<ast::Init>> inits =
    366                         attr == ast::EnumAttribute::Value ? genValueInit() : genLabelInit();
     404        if (attr == ast::EnumAttribute::Value) {
     405                if (decl->base) {
     406                        // TypedEnum's backing arrays
     407                        std::vector<ast::ptr<ast::Init>> inits = genValueInit();
     408                        ast::ObjectDecl* arrayProto =
     409                                genAttrArrayProto(attr, getLocation(), inits);
     410                        forwards.push_back(arrayProto);
     411
     412                        ast::FunctionDecl* funcProto = genValueProto();
     413                        produceForwardDecl(funcProto);
     414                        genValueOrLabelBody(funcProto, arrayProto);
     415                        produceDecl(funcProto);
     416                }  else {
     417                        ast::FunctionDecl* funcProto = genQuasiValueProto();
     418                        produceForwardDecl(funcProto);
     419                        genQuasiValueBody(funcProto);
     420                        produceDecl(funcProto);
     421                }
     422        } else if (attr == ast::EnumAttribute::Label) {
     423                std::vector<ast::ptr<ast::Init>> inits = genLabelInit();
    367424                ast::ObjectDecl* arrayProto =
    368425                        genAttrArrayProto(attr, getLocation(), inits);
    369426                forwards.push_back(arrayProto);
    370 
    371                 ast::FunctionDecl* funcProto = ( attr == ast::EnumAttribute::Value )
    372                                                ? genValueProto()
    373                                                : genLabelProto();
     427                ast::FunctionDecl* funcProto = genLabelProto();
    374428                produceForwardDecl(funcProto);
    375429                genValueOrLabelBody(funcProto, arrayProto);
     
    384438
    385439void EnumAttrFuncGenerator::genTypedEnumFuncs() {
    386         if (decl->base) genTypedEnumFunction(ast::EnumAttribute::Value);
     440        genTypedEnumFunction(ast::EnumAttribute::Value);
    387441        genTypedEnumFunction(ast::EnumAttribute::Label);
    388442        genTypedEnumFunction(ast::EnumAttribute::Posn);
     443}
     444
     445void EnumAttrFuncGenerator::genTypeNameFunc() {
     446        ast::FunctionDecl* funcProto = genTypeNameProto();
     447        produceForwardDecl(funcProto);
     448        genTypeNameBody(funcProto);
     449        produceDecl(funcProto);
    389450}
    390451
     
    392453        std::list<ast::ptr<ast::Decl>>& decls) {
    393454        // Generate the functions (they go into forwards and definitions).
     455        genTypeNameFunc();
    394456        genTypedEnumFuncs();
    395457        genSerialTraitFuncs();
Note: See TracChangeset for help on using the changeset viewer.