- Timestamp:
- Jun 17, 2019, 1:09:41 PM (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:
- 800bae1, 9d5089e
- Parents:
- 8b34df0 (diff), b4d34fa (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src/AST
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r8b34df0 raba20d2 734 734 const ast::Expr * visit( const ast::VariableExpr * node ) override final { 735 735 auto expr = new VariableExpr(); 736 expr->var = get<DeclarationWithType>().accept1(node->var); 736 737 visitBaseExpr( node, expr ); 737 expr->var = get<DeclarationWithType>().accept1(node->var);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 ;747 738 this->node = expr; 748 739 return nullptr; … … 750 741 751 742 const ast::Expr * visit( const ast::ConstantExpr * node ) override final { 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); 743 // Old world: two types: rslt->constant.type, rslt->result 744 // New workd: one public type: node->result, plus node->underlyer only to support roundtrip conversion 745 // preserving underlyer because the correct type for string literals is complicated to construct, 746 // and distinguishing a string from other literals using the type is hard to do accurately 747 // Both worlds: the outer, expression-level type can change during resolution 748 // for a string, that's char[k] before-resolve and char * after 749 // Old world: the inner Constant type stays what it was built with 750 // for a string, that's char[k] always 751 // Both worlds: the "rep" field of a constant is the C source file fragment that compiles to the desired value 752 // for a string, that includes outer quotes, backslashes, et al cases from the Literals test 753 ConstantExpr *rslt = new ConstantExpr(Constant( 754 get<Type>().accept1(node->underlyer), 755 node->rep, 756 node->ival)); 777 757 auto expr = visitBaseExpr( node, rslt ); 778 758 this->node = expr; … … 2153 2133 ); 2154 2134 2155 visitBaseExpr_SkipResultType( old,2156 expr2157 );2158 2159 2135 expr->var = GET_ACCEPT_1(var, DeclWithType); 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; 2136 visitBaseExpr( old, expr ); 2137 2138 this->node = expr; 2210 2139 } 2211 2140 2212 2141 virtual void visit( ConstantExpr * old ) override final { 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); 2142 ast::ConstantExpr *rslt = new ast::ConstantExpr( 2143 old->location, 2144 GET_ACCEPT_1(result, Type), 2145 old->constant.get_value(), 2146 old->constant.ival 2147 ); 2148 rslt->underlyer = getAccept1< ast::Type, Type* >( old->constant.get_type() ); 2239 2149 this->node = visitBaseExpr( old, rslt ); 2240 2150 } -
src/AST/Expr.cpp
r8b34df0 raba20d2 9 9 // Author : Aaron B. Moss 10 10 // Created On : Wed May 15 17:00:00 2019 11 // Last Modified By : A aron B. Moss12 // Created On : Wed May 15 17:00:00 201913 // Update Count : 111 // Last Modified By : Andrew Beach 12 // Created On : Thr Jun 13 13:38:00 2019 13 // Update Count : 2 14 14 // 15 15 … … 194 194 if ( const BasicType * bty = result.as< BasicType >() ) { 195 195 if ( bty->isInteger() ) { 196 return val.ival; 196 assert(ival); 197 return ival.value(); 197 198 } 198 199 } else if ( result.as< ZeroType >() ) { … … 204 205 } 205 206 206 double ConstantExpr::floatValue() const {207 if ( const BasicType * bty = result.as< BasicType >() ) {208 if ( ! bty->isInteger() ) {209 return val.dval;210 }211 }212 SemanticError( this, "Constant expression of non-floating-point type " );213 }214 215 207 ConstantExpr * ConstantExpr::from_bool( const CodeLocation & loc, bool b ) { 216 208 return new ConstantExpr{ 217 209 loc, new BasicType{ BasicType::Bool }, b ? "1" : "0", (unsigned long long)b }; 218 }219 220 ConstantExpr * ConstantExpr::from_char( const CodeLocation & loc, char c ) {221 return new ConstantExpr{222 loc, new BasicType{ BasicType::Char }, std::to_string( c ), (unsigned long long)c };223 210 } 224 211 … … 232 219 loc, new BasicType{ BasicType::LongUnsignedInt }, std::to_string( i ), 233 220 (unsigned long long)i }; 234 }235 236 ConstantExpr * ConstantExpr::from_double( const CodeLocation & loc, double d ) {237 return new ConstantExpr{ loc, new BasicType{ BasicType::Double }, std::to_string( d ), d };238 }239 240 ConstantExpr * ConstantExpr::from_string( const CodeLocation & loc, const std::string & s ) {241 return new ConstantExpr{242 loc,243 new ArrayType{244 new BasicType{ BasicType::Char, CV::Const },245 ConstantExpr::from_int( loc, s.size() + 1 /* null terminator */ ),246 FixedLen, DynamicDim },247 std::string{"\""} + s + "\"",248 (unsigned long long)0,249 ConstantExpr::String };250 221 } 251 222 … … 382 353 383 354 UniqueExpr::UniqueExpr( const CodeLocation & loc, const Expr * e, unsigned long long i ) 384 : Expr( loc, e->result ), id( i ) {355 : Expr( loc, e->result ), expr( e ), id( i ) { 385 356 assert( expr ); 386 357 if ( id == -1ull ) { -
src/AST/Expr.hpp
r8b34df0 raba20d2 22 22 #include <utility> // for move 23 23 #include <vector> 24 #include <optional> 24 25 25 26 #include "Fwd.hpp" // for UniqueId … … 32 33 33 34 class ConverterOldToNew; 35 class ConverterNewToOld; 34 36 35 37 namespace ast { … … 346 348 }; 347 349 348 /// A compile-time constant 350 /// A compile-time constant. 351 /// Mostly carries C-source text from parse to code-gen, without interpretation. E.g. strings keep their outer quotes and never have backslashes interpreted. 352 /// Integer constants get special treatment, e.g. for verifying array operations, when an integer constant occurs as the length of an array. 349 353 class ConstantExpr final : public Expr { 350 union Val { 351 unsigned long long ival; 352 double dval; 353 354 Val( unsigned long long i ) : ival( i ) {} 355 Val( double d ) : dval( d ) {} 356 } val; 357 public: 354 public: 355 // Representation of this constant, as it occurs in .cfa source and .cfa.cc result. 358 356 std::string rep; 359 enum Kind { Integer, FloatingPoint, String } kind;360 357 361 358 ConstantExpr( 362 const CodeLocation & loc, const Type * ty, const std::string & r, unsigned long long v,363 Kind k = Integer)364 : Expr( loc, ty ), val( v ), rep( r ), kind( k) {}365 ConstantExpr( const CodeLocation & loc, const Type * ty, const std::string & r, double v ) 366 : Expr( loc, ty ), val( v ), rep( r ), kind( FloatingPoint ) {}367 368 /// Gets the value of this constant as an integer359 const CodeLocation & loc, const Type * ty, const std::string & r, 360 std::optional<unsigned long long> i ) 361 : Expr( loc, ty ), rep( r ), ival( i ) {} 362 363 /// Gets the integer value of this constant, if one is appropriate to its type. 364 /// Throws a SemanticError if the type is not appropriate for value-as-integer. 365 /// Suffers an assertion failure the type is appropriate but no integer value was supplied to the constructor. 369 366 long long int intValue() const; 370 /// Gets the value of this constant as floating point371 double floatValue() const;372 367 373 368 /// generates a boolean constant of the given bool 374 369 static ConstantExpr * from_bool( const CodeLocation & loc, bool b ); 375 /// generates a char constant of the given char376 static ConstantExpr * from_char( const CodeLocation & loc, char c );377 370 /// generates an integer constant of the given int 378 371 static ConstantExpr * from_int( const CodeLocation & loc, int i ); 379 372 /// generates an integer constant of the given unsigned long int 380 373 static ConstantExpr * from_ulong( const CodeLocation & loc, unsigned long i ); 381 /// generates a floating point constant of the given double382 static ConstantExpr * from_double( const CodeLocation & loc, double d );383 /// generates an array of chars constant of the given string384 static ConstantExpr * from_string( const CodeLocation & loc, const std::string & s );385 374 /// generates a null pointer value for the given type. void * if omitted. 386 375 static ConstantExpr * null( const CodeLocation & loc, const Type * ptrType = nullptr ); … … 390 379 ConstantExpr * clone() const override { return new ConstantExpr{ *this }; } 391 380 MUTATE_FRIEND 381 382 std::optional<unsigned long long> ival; 383 384 // Intended only for legacy support of roundtripping the old AST. 385 // Captures the very-locally inferred type, before the resolver modifies the type of this ConstantExpression. 386 // In the old AST it's constExpr->constant.type 387 ptr<Type> underlyer; 388 friend class ::ConverterOldToNew; 389 friend class ::ConverterNewToOld; 392 390 }; 393 391 … … 693 691 unsigned long long id; 694 692 695 UniqueExpr( const CodeLocation & loc, const Expr * e, unsigned long long i = -1 );693 UniqueExpr( const CodeLocation & loc, const Expr * e, unsigned long long i = -1ull ); 696 694 697 695 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
Note: See TracChangeset
for help on using the changeset viewer.