Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    rc36298d r8b34df0  
    576576                if ( srcInferred.mode == ast::Expr::InferUnion::Params ) {
    577577                        const ast::InferredParams &srcParams = srcInferred.inferParams();
    578                         for (auto srcParam : srcParams) {
    579                                 tgtInferParams[srcParam.first] = ParamEntry(
     578                        for (auto & srcParam : srcParams) {
     579                                auto res = tgtInferParams.emplace(srcParam.first, ParamEntry(
    580580                                        srcParam.second.decl,
    581581                                        get<Declaration>().accept1(srcParam.second.declptr),
     
    583583                                        get<Type>().accept1(srcParam.second.formalType),
    584584                                        get<Expression>().accept1(srcParam.second.expr)
    585                                 );
     585                                ));
     586                                assert(res.second);
    586587                        }
    587588                } else if ( srcInferred.mode == ast::Expr::InferUnion::Slots  ) {
     
    733734        const ast::Expr * visit( const ast::VariableExpr * node ) override final {
    734735                auto expr = new VariableExpr();
     736                visitBaseExpr( node, expr );
    735737                expr->var = get<DeclarationWithType>().accept1(node->var);
    736                 visitBaseExpr( node, expr );
     738                Type * type = expr->var->get_type()->clone();
     739                if(FunctionType * ft = dynamic_cast<FunctionType*>(type)) {
     740                        if(node->result.as<ast::PointerType>()) {
     741                                type = new PointerType({}, ft);
     742                        }
     743                }
     744
     745                type->set_lvalue( true );
     746                expr->result = type ;
    737747                this->node = expr;
    738748                return nullptr;
     
    740750
    741751        const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
    742                 // Old world:   two types: rslt->constant.type, rslt->result
    743                 // New workd:   one public type: node->result, plus node->underlyer only to support roundtrip conversion
    744                 //              preserving underlyer because the correct type for string literals is complicated to construct,
    745             //              and distinguishing a string from other literals using the type is hard to do accurately
    746                 // Both worlds: the outer, expression-level type can change during resolution
    747                 //              for a string, that's char[k] before-resolve and char * after
    748                 // Old world:   the inner Constant type stays what it was built with
    749                 //              for a string, that's char[k] always
    750                 // Both worlds: the "rep" field of a constant is the C source file fragment that compiles to the desired value
    751         //              for a string, that includes outer quotes, backslashes, et al cases from the Literals test
    752                 ConstantExpr *rslt = new ConstantExpr(Constant(
    753                         get<Type>().accept1(node->underlyer),
    754                         node->rep,
    755                         node->ival));
     752                ConstantExpr *rslt = nullptr;
     753                switch ( node->kind ) {
     754                case ast::ConstantExpr::Integer:
     755                        rslt = new ConstantExpr{Constant{
     756                                get<Type>().accept1( node->result ),
     757                                node->rep,
     758                                (unsigned long long) node->intValue()
     759                        }};
     760                        break;
     761                case ast::ConstantExpr::FloatingPoint:
     762                        rslt = new ConstantExpr{Constant{
     763                                get<Type>().accept1(node->result),
     764                                node->rep,
     765                                (double) node->floatValue()
     766                        }};
     767                        break;
     768                case ast::ConstantExpr::String:
     769                        rslt = new ConstantExpr{Constant{
     770                                get<Type>().accept1( node->result ),
     771                                node->rep,
     772                                (long long unsigned int)0
     773                        }};
     774                        break;
     775                }
     776                assert(rslt);
    756777                auto expr = visitBaseExpr( node, rslt );
    757778                this->node = expr;
     
    19822003                if ( !oldInferParams.empty() ) {
    19832004                        ast::InferredParams &tgt = newInferred.inferParams();
    1984                         for (auto old : oldInferParams) {
     2005                        for (auto & old : oldInferParams) {
    19852006                                tgt[old.first] = ast::ParamEntry(
    19862007                                        old.second.decl,
     
    21322153                );
    21332154
     2155                visitBaseExpr_SkipResultType( old,
     2156                        expr
     2157                );
     2158
    21342159                expr->var = GET_ACCEPT_1(var, DeclWithType);
    2135                 visitBaseExpr( old, expr );
    2136 
    2137                 this->node = expr;
     2160                expr->result = expr->var->get_type();
     2161                if(const ast::FunctionType * ft = expr->result.as<ast::FunctionType>()) {
     2162                        if(dynamic_cast<PointerType *>(old->result)) {
     2163                                expr->result = new ast::PointerType(ft);
     2164                        }
     2165                }
     2166                add_qualifiers( expr->result, ast::CV::Lvalue );
     2167                this->node = expr;
     2168        }
     2169
     2170        bool isIntlikeConstantType(const Type *t) {
     2171                if ( const BasicType * basicType = dynamic_cast< const BasicType * >( t ) ) {
     2172                        if ( basicType->isInteger() ) {
     2173                                return true;
     2174                        }
     2175                } else if ( dynamic_cast< const OneType * >( t ) ) {
     2176                        return true;
     2177                } else if ( dynamic_cast< const ZeroType * >( t ) ) {
     2178                        return true;
     2179                } else if ( dynamic_cast< const PointerType * >( t ) ) {
     2180                        // null pointer constants, with zero int-values
     2181                        return true;
     2182                }
     2183                return false;
     2184        }
     2185
     2186        int isFloatlikeConstantType(const Type *t) {
     2187                if ( const BasicType * bty = dynamic_cast< const BasicType * >( t ) ) {
     2188                        if ( ! bty->isInteger() ) {
     2189                                return true;
     2190                        }
     2191                }
     2192                return false;
     2193        }
     2194
     2195        int isStringlikeConstantType(const Type *t) {
     2196                const Type *referentType = nullptr;
     2197                if ( const ArrayType * aty = dynamic_cast< const ArrayType * >( t ) ) {
     2198                        referentType = aty->base;
     2199                } else if ( const PointerType * pty = dynamic_cast< const PointerType * >( t ) ) {
     2200                        referentType = pty->base;
     2201                }
     2202                if (referentType) {
     2203                        if ( const BasicType * bty = dynamic_cast< const BasicType * >( referentType ) ) {
     2204                           if ( bty->kind == BasicType::Kind::Char ) {
     2205                                   return true;
     2206                           }
     2207                        }
     2208                }
     2209                return false;
    21382210        }
    21392211
    21402212        virtual void visit( ConstantExpr * old ) override final {
    2141                 ast::ConstantExpr *rslt = new ast::ConstantExpr(
    2142                         old->location,
    2143                         GET_ACCEPT_1(result, Type),
    2144                         old->constant.get_value(),
    2145                         old->constant.ival
    2146                 );
    2147                 rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant.get_type() );
     2213                ast::ConstantExpr *rslt = nullptr;
     2214                if (isStringlikeConstantType(old->result)) {
     2215                        rslt = new ast::ConstantExpr(
     2216                                old->location,
     2217                                GET_ACCEPT_1(result, Type),
     2218                                old->constant.get_value(),
     2219                                0,
     2220                                ast::ConstantExpr::Kind::String
     2221                        );
     2222                } else if (isIntlikeConstantType(old->result)) {
     2223                        rslt = new ast::ConstantExpr(
     2224                                old->location,
     2225                                GET_ACCEPT_1(result, Type),
     2226                                old->constant.get_value(),
     2227                                (unsigned long long) old->intValue(),
     2228                                ast::ConstantExpr::Kind::Integer
     2229                        );
     2230                } else if (isFloatlikeConstantType(old->result)) {
     2231                        rslt = new ast::ConstantExpr(
     2232                                old->location,
     2233                                GET_ACCEPT_1(result, Type),
     2234                                old->constant.get_value(),
     2235                                (double) old->constant.get_dval()
     2236                        );
     2237                }
     2238                assert(rslt);
    21482239                this->node = visitBaseExpr( old, rslt );
    21492240        }
Note: See TracChangeset for help on using the changeset viewer.