Changeset c36298d for src/AST/Convert.cpp
- Timestamp:
- Jun 17, 2019, 11:01:04 AM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- b4d34fa
- Parents:
- 6a1dfda
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r6a1dfda rc36298d 740 740 741 741 const ast::Expr * visit( const ast::ConstantExpr * node ) override final { 742 ConstantExpr *rslt = nullptr; 743 switch ( node->kind ) { 744 case ast::ConstantExpr::Integer: 745 rslt = new ConstantExpr{Constant{ 746 get<Type>().accept1( node->result ), 747 node->rep, 748 (unsigned long long) node->intValue() 749 }}; 750 break; 751 case ast::ConstantExpr::FloatingPoint: 752 rslt = new ConstantExpr{Constant{ 753 get<Type>().accept1(node->result), 754 node->rep, 755 (double) node->floatValue() 756 }}; 757 break; 758 case ast::ConstantExpr::String: 759 // Old world: two types: rslt->constant.type, rslt->result 760 // New workd: one type: node->result 761 // Both worlds: the outer, expression-level type can change during resolution 762 // in case of string, that's char[k] before-resolve and char * after 763 // Old world: the inner Constant type stays what it was built with 764 // in case of string, that's char[k] 765 // Both worlds: the "rep" field of a string constant is the string value it was initialized from, wrapped in quotes, but not otherwise escaped 766 ast::ptr<ast::Type> charType = nullptr; 767 if (const ast::ArrayType *arrRslt = node->result.as<ast::ArrayType>()) { 768 charType = arrRslt->base; 769 } else { 770 const ast::PointerType *ptrRslt = node->result.as<ast::PointerType>(); 771 assert(ptrRslt); 772 charType = ptrRslt->base; 773 } 774 rslt = new ConstantExpr(Constant::from_string( 775 node->rep, get<Type>().accept1(charType))); // rslt->result is char[k] 776 rslt->set_result( get<Type>().accept1( node->result ) ); // rslt->result is [[ node->rsult ]] 777 break; 778 } 779 assert(rslt); 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)); 780 756 auto expr = visitBaseExpr( node, rslt ); 781 757 this->node = expr; … … 2162 2138 } 2163 2139 2164 bool isIntlikeConstantType(const Type *t) {2165 if ( const BasicType * basicType = dynamic_cast< const BasicType * >( t ) ) {2166 if ( basicType->isInteger() ) {2167 return true;2168 }2169 } else if ( dynamic_cast< const OneType * >( t ) ) {2170 return true;2171 } else if ( dynamic_cast< const ZeroType * >( t ) ) {2172 return true;2173 } else if ( dynamic_cast< const PointerType * >( t ) ) {2174 // null pointer constants, with zero int-values2175 return true;2176 }2177 return false;2178 }2179 2180 int isFloatlikeConstantType(const Type *t) {2181 if ( const BasicType * bty = dynamic_cast< const BasicType * >( t ) ) {2182 if ( ! bty->isInteger() ) {2183 return true;2184 }2185 }2186 return false;2187 }2188 2189 int isStringlikeConstantType(const Type *t) {2190 const Type *referentType = nullptr;2191 if ( const ArrayType * aty = dynamic_cast< const ArrayType * >( t ) ) {2192 referentType = aty->base;2193 } else if ( const PointerType * pty = dynamic_cast< const PointerType * >( t ) ) {2194 referentType = pty->base;2195 }2196 if (referentType) {2197 if ( const BasicType * bty = dynamic_cast< const BasicType * >( referentType ) ) {2198 if ( bty->kind == BasicType::Kind::Char ) {2199 return true;2200 }2201 }2202 }2203 return false;2204 }2205 2206 2140 virtual void visit( ConstantExpr * old ) override final { 2207 ast::ConstantExpr *rslt = nullptr; 2208 if (isStringlikeConstantType(old->result)) { 2209 rslt = new ast::ConstantExpr( 2210 old->location, 2211 GET_ACCEPT_1(result, Type), // preserve the expression-level type (old->result, not old->constant.type); see new-to-old 2212 old->constant.get_value(), 2213 0, 2214 ast::ConstantExpr::Kind::String 2215 ); 2216 } else if (isIntlikeConstantType(old->result)) { 2217 rslt = new ast::ConstantExpr( 2218 old->location, 2219 GET_ACCEPT_1(result, Type), 2220 old->constant.get_value(), 2221 (unsigned long long) old->intValue(), 2222 ast::ConstantExpr::Kind::Integer 2223 ); 2224 } else if (isFloatlikeConstantType(old->result)) { 2225 rslt = new ast::ConstantExpr( 2226 old->location, 2227 GET_ACCEPT_1(result, Type), 2228 old->constant.get_value(), 2229 (double) old->constant.get_dval() 2230 ); 2231 } 2232 assert(rslt); 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() ); 2233 2148 this->node = visitBaseExpr( old, rslt ); 2234 2149 }
Note: See TracChangeset
for help on using the changeset viewer.