Changes in src/AST/Convert.cpp [c36298d:8b34df0]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
rc36298d r8b34df0 576 576 if ( srcInferred.mode == ast::Expr::InferUnion::Params ) { 577 577 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( 580 580 srcParam.second.decl, 581 581 get<Declaration>().accept1(srcParam.second.declptr), … … 583 583 get<Type>().accept1(srcParam.second.formalType), 584 584 get<Expression>().accept1(srcParam.second.expr) 585 ); 585 )); 586 assert(res.second); 586 587 } 587 588 } else if ( srcInferred.mode == ast::Expr::InferUnion::Slots ) { … … 733 734 const ast::Expr * visit( const ast::VariableExpr * node ) override final { 734 735 auto expr = new VariableExpr(); 736 visitBaseExpr( node, expr ); 735 737 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 ; 737 747 this->node = expr; 738 748 return nullptr; … … 740 750 741 751 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); 756 777 auto expr = visitBaseExpr( node, rslt ); 757 778 this->node = expr; … … 1982 2003 if ( !oldInferParams.empty() ) { 1983 2004 ast::InferredParams &tgt = newInferred.inferParams(); 1984 for (auto old : oldInferParams) {2005 for (auto & old : oldInferParams) { 1985 2006 tgt[old.first] = ast::ParamEntry( 1986 2007 old.second.decl, … … 2132 2153 ); 2133 2154 2155 visitBaseExpr_SkipResultType( old, 2156 expr 2157 ); 2158 2134 2159 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; 2138 2210 } 2139 2211 2140 2212 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); 2148 2239 this->node = visitBaseExpr( old, rslt ); 2149 2240 }
Note:
See TracChangeset
for help on using the changeset viewer.