- 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
- Files:
-
- 1 added
- 7 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 ); } -
src/Parser/ExpressionNode.cc
r8b34df0 raba20d2 357 357 new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"' 358 358 false, false ); 359 Expression * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) ); // constant 0 is ignored for pure string value359 Expression * ret = new ConstantExpr( Constant( at, str, std::nullopt ) ); 360 360 if ( units.length() != 0 ) { 361 361 ret = new UntypedExpr( new NameExpr( units ), { ret } ); -
src/ResolvExpr/Candidate.hpp
r8b34df0 raba20d2 9 9 // Author : Aaron B. Moss 10 10 // Created On : Wed Jun 5 14:30:00 2019 11 // Last Modified By : A aron B. Moss12 // Last Modified On : Wed Jun 5 14:30:00 201913 // Update Count : 111 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jun 12 14:15:00 2019 13 // Update Count : 2 14 14 // 15 15 … … 49 49 50 50 Candidate() : expr(), cost( Cost::zero ), cvtCost( Cost::zero ), env(), open(), need() {} 51 51 52 52 Candidate( const ast::Expr * x, const ast::TypeEnvironment & e ) 53 53 : expr( x ), cost( Cost::zero ), cvtCost( Cost::zero ), env( e ), open(), need() {} 54 54 55 55 Candidate( const Candidate & o, const ast::Expr * x ) 56 : expr( x ), cost( o.cost ), cvtCost( Cost::zero ), env( o.env ), open( o.open ), 56 : expr( x ), cost( o.cost ), cvtCost( Cost::zero ), env( o.env ), open( o.open ), 57 57 need( o.need ) {} 58 59 Candidate( 60 const ast::Expr * x, ast::TypeEnvironment && e, ast::OpenVarSet && o, 61 ast::AssertionSet && n, const Cost & c )62 : expr( x ), cost( c ), cvtCost( Cost::zero ), env( std::move( e ) ), open( std::move( o ) ),58 59 Candidate( 60 const ast::Expr * x, ast::TypeEnvironment && e, ast::OpenVarSet && o, 61 ast::AssertionSet && n, const Cost & c, const Cost & cvt = Cost::zero ) 62 : expr( x ), cost( c ), cvtCost( cvt ), env( std::move( e ) ), open( std::move( o ) ), 63 63 need( n.begin(), n.end() ) {} 64 64 }; -
src/SynTree/Constant.cc
r8b34df0 raba20d2 22 22 #include "Type.h" // for BasicType, Type, Type::Qualifiers, PointerType 23 23 24 Constant::Constant( Type * type, std::string rep, unsigned long long val ) : type( type ), rep( rep ), val( val ) {} 25 Constant::Constant( Type * type, std::string rep, double val ) : type( type ), rep( rep ), val( val ) {} 24 Constant::Constant( Type * type, std::string rep, std::optional<unsigned long long> ival ) : type( type ), rep( rep ), ival( ival ) {} 26 25 27 Constant::Constant( const Constant &other ) : BaseSyntaxNode( other ), rep( other.rep ), val( other.val ) {26 Constant::Constant( const Constant &other ) : BaseSyntaxNode( other ), rep( other.rep ), ival( other.ival ) { 28 27 type = other.type->clone(); 29 28 } … … 35 34 } 36 35 37 Constant Constant::from_char( char c ) {38 return Constant( new BasicType( Type::Qualifiers(), BasicType::Char ), std::to_string( c ), (unsigned long long int)c );39 }40 41 36 Constant Constant::from_int( int i ) { 42 37 return Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), std::to_string( i ), (unsigned long long int)i ); … … 45 40 Constant Constant::from_ulong( unsigned long i ) { 46 41 return Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::to_string( i ), (unsigned long long int)i ); 47 }48 49 Constant Constant::from_double( double d ) {50 return Constant( new BasicType( Type::Qualifiers(), BasicType::Double ), std::to_string( d ), d );51 }52 53 Constant Constant::from_string( std::string const & str ) {54 return Constant(55 new ArrayType(56 noQualifiers,57 new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ),58 new ConstantExpr( Constant::from_int( str.size() + 1 /* \0 */ )),59 false, false ),60 std::string("\"") + str + "\"", (unsigned long long int)0 );61 42 } 62 43 … … 74 55 unsigned long long Constant::get_ival() const { 75 56 assertf( strict_dynamic_cast<BasicType*>(type)->isInteger(), "Attempt to retrieve ival from non-integer constant." ); 76 return val.ival; 77 } 78 79 double Constant::get_dval() const { 80 assertf( ! strict_dynamic_cast<BasicType*>(type)->isInteger(), "Attempt to retrieve dval from integer constant." ); 81 return val.dval; 57 return ival.value(); 82 58 } 83 59 84 60 void Constant::print( std::ostream &os, Indenter ) const { 85 os << "(" << rep << " " << val.ival;61 os << "(" << rep << " " << (ival ? toString(ival.value()) : "") ; 86 62 if ( type ) { 87 63 os << ": "; -
src/SynTree/Constant.h
r8b34df0 raba20d2 18 18 #include <iosfwd> // for ostream 19 19 #include <string> // for string 20 #include <optional> // for optional 20 21 21 22 #include "BaseSyntaxNode.h" … … 27 28 class Constant : public BaseSyntaxNode { 28 29 public: 29 Constant( Type * type, std::string rep, unsigned long long val ); 30 Constant( Type * type, std::string rep, double val ); 30 Constant( Type * type, std::string rep, std::optional<unsigned long long> i ); 31 31 Constant( const Constant & other ); 32 32 virtual ~Constant(); … … 39 39 void set_value( std::string newValue ) { rep = newValue; } 40 40 unsigned long long get_ival() const; 41 double get_dval() const;42 41 43 42 /// generates a boolean constant of the given bool 44 43 static Constant from_bool( bool b ); 45 /// generates a char constant of the given char46 static Constant from_char( char c );47 44 /// generates an integer constant of the given int 48 45 static Constant from_int( int i ); 49 46 /// generates an integer constant of the given unsigned long int 50 47 static Constant from_ulong( unsigned long i ); 51 /// generates a floating point constant of the given double52 static Constant from_double( double d );53 /// generates an array of chars constant of the given string54 static Constant from_string( std::string const & s );55 48 56 49 /// generates a null pointer value for the given type. void * if omitted. … … 63 56 Type * type; 64 57 std::string rep; 65 union Val { 66 unsigned long long ival; 67 double dval; 68 Val( unsigned long long ival ) : ival( ival ) {} 69 Val( double dval ) : dval( dval ) {} 70 } val; 58 std::optional<unsigned long long> ival; 59 60 friend class ConverterOldToNew; 71 61 }; 72 62
Note: See TracChangeset
for help on using the changeset viewer.