Changes in / [f1ec88a:f685679]
- Location:
- src
- Files:
-
- 12 edited
-
AST/Convert.cpp (modified) (1 diff)
-
AST/Decl.cpp (modified) (1 diff)
-
AST/Decl.hpp (modified) (1 diff)
-
AST/Expr.cpp (modified) (1 diff)
-
AST/Expr.hpp (modified) (1 diff)
-
AST/Pass.proto.hpp (modified) (4 diffs)
-
AST/Print.cpp (modified) (13 diffs)
-
AST/Type.hpp (modified) (6 diffs)
-
Common/Eval.cc (modified) (3 diffs)
-
Common/PassVisitor.impl.h (modified) (2 diffs)
-
InitTweak/InitTweak.cc (modified) (10 diffs)
-
InitTweak/InitTweak.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
rf1ec88a rf685679 704 704 } 705 705 706 bool isIntlikeConstantType(const ast::Type *t) { 707 if ( const ast::BasicType * basicType = dynamic_cast< const ast::BasicType * >( t ) ) { 708 if ( basicType->isInteger() ) { 709 return true; 710 } 711 } else if ( dynamic_cast< const ast::OneType * >( t ) ) { 712 return true; 713 } else if ( dynamic_cast< const ast::ZeroType * >( t ) ) { 714 return true; 715 } else if ( dynamic_cast< const ast::PointerType * >( t ) ) { 716 // null pointer constants, with zero int-values 717 return true; 718 } 719 return false; 720 } 721 722 bool isFloatlikeConstantType(const ast::Type *t) { 723 if ( const ast::BasicType * bty = dynamic_cast< const ast::BasicType * >( t ) ) { 724 if ( ! bty->isInteger() ) { 725 return true; 726 } 727 } 728 return false; 729 } 730 731 bool isStringlikeConstantType(const ast::Type *t) { 732 if ( const ast::ArrayType * aty = dynamic_cast< const ast::ArrayType * >( t ) ) { 733 if ( const ast::BasicType * bty = aty->base.as<ast::BasicType>() ) { 734 if ( bty->kind == ast::BasicType::Kind::Char ) { 735 return true; 736 } 737 } 738 } 739 return false; 740 } 741 706 742 const ast::Expr * visit( const ast::ConstantExpr * node ) override final { 707 743 ConstantExpr *rslt = nullptr; 708 switch ( node->kind ) { 709 case ast::ConstantExpr::Integer: 710 rslt = new ConstantExpr{Constant{ 711 get<Type>().accept1( node->result ), 744 if (isIntlikeConstantType(node->result)) { 745 rslt = new ConstantExpr(Constant( 746 get<Type>().accept1(node->result), 712 747 node->rep, 713 748 (unsigned long long) node->intValue() 714 }}; 715 break; 716 case ast::ConstantExpr::FloatingPoint: 717 rslt = new ConstantExpr{Constant{ 749 )); 750 } else if (isFloatlikeConstantType(node->result)) { 751 rslt = new ConstantExpr(Constant( 718 752 get<Type>().accept1(node->result), 719 753 node->rep, 720 754 (double) node->floatValue() 721 }};722 break;723 case ast::ConstantExpr::String:724 rslt = new ConstantExpr{Constant::from_string( node->rep )};725 break;755 )); 756 } else if (isStringlikeConstantType(node->result)) { 757 rslt = new ConstantExpr(Constant::from_string( 758 node->rep 759 )); 726 760 } 727 761 assert(rslt); -
src/AST/Decl.cpp
rf1ec88a rf685679 72 72 // --- EnumDecl 73 73 74 bool EnumDecl::valueOf( const Decl* enumerator, long long& value ) const {74 bool EnumDecl::valueOf( Decl* enumerator, long long& value ) const { 75 75 if ( enumValues.empty() ) { 76 76 long long crntVal = 0; 77 for ( const Decl * member : members ) {77 for ( const Decl* member : members ) { 78 78 const ObjectDecl* field = strict_dynamic_cast< const ObjectDecl* >( member ); 79 79 if ( field->init ) { -
src/AST/Decl.hpp
rf1ec88a rf685679 287 287 288 288 /// gets the integer value for this enumerator, returning true iff value found 289 bool valueOf( const Decl* enumerator, long long& value ) const;289 bool valueOf( Decl* enumerator, long long& value ) const; 290 290 291 291 const Decl * accept( Visitor & v ) const override { return v.visit( this ); } -
src/AST/Expr.cpp
rf1ec88a rf685679 241 241 FixedLen, DynamicDim }, 242 242 std::string{"\""} + s + "\"", 243 (unsigned long long)0, 244 ConstantExpr::String }; 243 (unsigned long long)0 }; 245 244 } 246 245 -
src/AST/Expr.hpp
rf1ec88a rf685679 337 337 public: 338 338 std::string rep; 339 enum Kind { Integer, FloatingPoint, String } kind;340 339 341 340 ConstantExpr( 342 const CodeLocation & loc, const Type * ty, const std::string & r, unsigned long long v, 343 Kind k = Integer ) 344 : Expr( loc, ty ), val( v ), rep( r ), kind( k ) {} 341 const CodeLocation & loc, const Type * ty, const std::string & r, unsigned long long v ) 342 : Expr( loc, ty ), val( v ), rep( r ) {} 345 343 ConstantExpr( const CodeLocation & loc, const Type * ty, const std::string & r, double v ) 346 : Expr( loc, ty ), val( v ), rep( r ) , kind( FloatingPoint ){}344 : Expr( loc, ty ), val( v ), rep( r ) {} 347 345 348 346 /// Gets the value of this constant as an integer -
src/AST/Pass.proto.hpp
rf1ec88a rf685679 109 109 }; 110 110 111 /// "Short hand" to check if this is a valid previsit function112 /// Mostly used to make the static_assert look (and print) prettier113 111 template<typename pass_t, typename node_t> 114 112 struct is_valid_previsit { … … 119 117 }; 120 118 121 /// Used by previsit implementation122 /// We need to reassign the result to 'node', unless the function123 /// returns void, then we just leave 'node' unchanged124 119 template<bool is_void> 125 120 struct __assign; … … 139 134 node = pass.previsit( node ); 140 135 assertf(node, "Previsit must not return NULL"); 141 }142 };143 144 /// Used by postvisit implementation145 /// We need to return the result unless the function146 /// returns void, then we just return the original node147 template<bool is_void>148 struct __return;149 150 template<>151 struct __return<true> {152 template<typename pass_t, typename node_t>153 static inline const node_t * result( pass_t & pass, const node_t * & node ) {154 pass.postvisit( node );155 return node;156 }157 };158 159 template<>160 struct __return<false> {161 template<typename pass_t, typename node_t>162 static inline auto result( pass_t & pass, const node_t * & node ) {163 return pass.postvisit( node );164 136 } 165 137 }; … … 202 174 decltype( pass.postvisit( node ), node->accept( *(Visitor*)nullptr ) ) 203 175 { 204 return __return< 205 std::is_void< 206 decltype( pass.postvisit( node ) ) 207 >::value 208 >::result( pass, node ); 176 return pass.postvisit( node ); 209 177 } 210 178 -
src/AST/Print.cpp
rf1ec88a rf685679 59 59 } 60 60 61 /// call if mandatory field is missing62 void undefined() {63 os << "UNDEFINED";64 }65 66 /// call for fields that should be mandatory67 void safe_print( const ast::Node * n ) {68 if ( n ) n->accept( *this );69 else undefined();70 }71 72 /// call to print short form. Incorporates features of safe_print()73 void short_print( const ast::Node * n ) {74 if ( ! n ) { undefined(); return; }75 bool old_short = short_mode; short_mode = true;76 n->accept( *this );77 short_mode = old_short;78 }79 80 61 81 62 static const char* Names[]; … … 118 99 } 119 100 120 void print( const ast::Expr::InferUnion & inferred, unsigned level = 0 ) {121 switch ( inferred.mode ) {122 case ast::Expr::InferUnion::Empty: return;123 case ast::Expr::InferUnion::Slots: {124 os << indent << "with " << inferred.data.resnSlots.size() << " pending inference slots"125 << std::endl;126 return;127 }128 case ast::Expr::InferUnion::Params: {129 os << indent << "with inferred parameters " << level << ":" << std::endl;130 ++indent;131 for ( const auto & i : inferred.data.inferParams ) {132 os << indent;133 short_print( Decl::fromId( i.second.decl ) );134 os << std::endl;135 print( i.second.expr->inferred, level+1 );136 }137 --indent;138 return;139 }140 }141 }142 143 void print( const ast::ParameterizedType::ForallList & forall ) {144 if ( forall.empty() ) return;145 os << "forall" << std::endl;146 ++indent;147 printAll( forall );148 os << indent;149 --indent;150 }151 152 void print( const std::vector<ptr<Attribute>> & attrs ) {153 if ( attrs.empty() ) return;154 os << "with attributes" << std::endl;155 ++indent;156 printAll( attrs );157 --indent;158 }159 160 void print( const std::vector<ptr<Expr>> & params ) {161 if ( params.empty() ) return;162 os << std::endl << indent << "... with parameters" << std::endl;163 ++indent;164 printAll( params );165 --indent;166 }167 168 101 void print( const ast::AggregateDecl * node ) { 169 102 os << node->typeString() << " " << node->name << ":"; … … 222 155 } 223 156 224 void postprint( const ast::Expr * node ) {225 print( node->inferred );226 227 if ( node->env ) {228 os << std::endl << indent << "... with environment:" << std::endl;229 ++indent;230 node->env->accept( *this );231 --indent;232 }233 234 if ( node->extension ) {235 os << std::endl << indent << "... with extension";236 }237 }238 239 void preprint( const ast::Type * node ) {240 print( node->qualifiers );241 }242 243 void preprint( const ast::ParameterizedType * node ) {244 print( node->forall );245 print( node->qualifiers );246 }247 248 void preprint( const ast::ReferenceToType * node ) {249 print( node->forall );250 print( node->attributes );251 print( node->qualifiers );252 }253 254 157 public: 255 158 virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) { … … 265 168 node->type->accept( *this ); 266 169 } else { 267 os << " untyped entity";170 os << " untyped entity "; 268 171 } // if 269 172 … … 311 214 node->type->accept( *this ); 312 215 } else { 313 os << "untyped entity ";216 os << "untyped entity "; 314 217 } // if 315 218 … … 388 291 ++indent; 389 292 os << "Expression Statement:" << endl << indent; 390 safe_print( node->expr);293 node->expr->accept( *this ); 391 294 --indent; 392 295 return node; … … 423 326 os << indent+1; 424 327 ++indent; 425 safe_print( node->cond);328 node->cond->accept( *this ); 426 329 --indent; 427 330 … … 441 344 ++indent; 442 345 os << indent; 443 safe_print( node->thenPart);346 node->thenPart->accept( *this ); 444 347 --indent; 445 348 … … 515 418 516 419 virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) { 517 ++indent;518 os << "Application of" << std::endl << indent;519 safe_print( node->func );520 os << std::endl;521 if ( ! node->args.empty() ) {522 os << indent << "... to arguments" << std::endl;523 printAll( node->args );524 }525 --indent;526 postprint( node );527 528 420 return node; 529 421 } 530 422 531 423 virtual const ast::Expr * visit( const ast::UntypedExpr * node ) { 532 ++indent;533 os << "Applying untyped:" << std::endl;534 os << indent;535 safe_print( node->func );536 os << std::endl << indent-1 << "...to:" << std::endl;537 printAll( node->args );538 --indent;539 postprint( node );540 541 424 return node; 542 425 } 543 426 544 427 virtual const ast::Expr * visit( const ast::NameExpr * node ) { 545 os << "Name: " << node->name;546 postprint( node );547 548 428 return node; 549 429 } 550 430 551 431 virtual const ast::Expr * visit( const ast::AddressExpr * node ) { 552 os << "Address of:" << std::endl;553 ++indent;554 os << indent;555 safe_print( node->arg );556 557 --indent;558 559 432 return node; 560 433 } 561 434 562 435 virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) { 563 os << "Address of label:" << node->arg;564 565 436 return node; 566 437 } 567 438 568 439 virtual const ast::Expr * visit( const ast::CastExpr * node ) { 569 ++indent;570 os << (node->isGenerated ? "Generated" : "Explicit") << " cast of:" << std::endl << indent;571 safe_print( node->arg );572 os << std::endl << indent-1 << "... to:";573 if ( ! node->result ) {574 os << " ";575 undefined();576 } else if ( node->result->isVoid() ) {577 os << " nothing";578 } else {579 os << std::endl << indent;580 node->result->accept( *this );581 } // if582 --indent;583 postprint( node );584 585 440 return node; 586 441 } 587 442 588 443 virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) { 589 ++indent;590 os << "Keyword Cast of:" << std::endl << indent;591 safe_print( node->arg );592 --indent;593 os << std::endl << indent << "... to: " << node->targetString();594 postprint( node );595 596 444 return node; 597 445 } 598 446 599 447 virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) { 600 ++indent;601 os << "Virtual Cast of:" << std::endl << indent;602 safe_print( node->arg );603 os << std::endl << indent-1 << "... to:";604 if ( ! node->result ) {605 os << " unknown";606 } else {607 os << std::endl << indent;608 node->result->accept( *this );609 }610 --indent;611 postprint( node );612 613 448 return node; 614 449 } 615 450 616 451 virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) { 617 ++indent;618 os << "Untyped Member Expression, with field: " << std::endl << indent;619 safe_print( node->member );620 os << indent-1 << "... from aggregate:" << std::endl << indent;621 safe_print( node->aggregate );622 --indent;623 postprint( node );624 625 452 return node; 626 453 } 627 454 628 455 virtual const ast::Expr * visit( const ast::MemberExpr * node ) { 629 ++indent;630 os << "Member Expression, with field:" << std::endl << indent;631 safe_print( node->member );632 os << std::endl << indent-1 << "... from aggregate:" << std::endl << indent;633 safe_print( node->aggregate );634 --indent;635 postprint( node );636 637 456 return node; 638 457 } 639 458 640 459 virtual const ast::Expr * visit( const ast::VariableExpr * node ) { 641 os << "Variable Expression: ";642 short_print( node->var );643 postprint( node );644 645 460 return node; 646 461 } 647 462 648 463 virtual const ast::Expr * visit( const ast::ConstantExpr * node ) { 649 os << "Constant Expression (" << node->rep;650 if ( node->result ) {651 os << ": ";652 node->result->accept( *this );653 }654 os << ")";655 postprint( node );656 657 464 return node; 658 465 } … … 759 566 760 567 virtual const ast::Type * visit( const ast::VoidType * node ) { 761 preprint( node );762 os << "void";763 568 return node; 764 569 } 765 570 766 571 virtual const ast::Type * visit( const ast::BasicType * node ) { 767 preprint( node );768 os << ast::BasicType::typeNames[ node->kind ];769 572 return node; 770 573 } 771 574 772 575 virtual const ast::Type * visit( const ast::PointerType * node ) { 773 preprint( node );774 if ( ! node->isArray() ) {775 os << "pointer to ";776 } else {777 os << "decayed ";778 if ( node->isStatic ) {779 os << "static ";780 }781 782 if ( node->isVarLen ) {783 os << "variable length array of ";784 } else if ( node->dimension ) {785 os << "array of ";786 node->dimension->accept( *this );787 os << " ";788 }789 }790 safe_print( node->base );791 792 576 return node; 793 577 } 794 578 795 579 virtual const ast::Type * visit( const ast::ArrayType * node ) { 796 preprint( node );797 if ( node->isStatic ) {798 os << "static ";799 }800 801 if ( node->isVarLen ) {802 os << "variable length array of ";803 } else if ( node->dimension ) {804 os << "array of ";805 } else {806 os << "open array of ";807 }808 809 safe_print( node->base );810 811 if ( node->dimension ) {812 os << " with dimension of ";813 node->dimension->accept( *this );814 }815 816 580 return node; 817 581 } 818 582 819 583 virtual const ast::Type * visit( const ast::ReferenceType * node ) { 820 preprint( node );821 os << "reference to ";822 safe_print( node->base );823 824 584 return node; 825 585 } 826 586 827 587 virtual const ast::Type * visit( const ast::QualifiedType * node ) { 828 preprint( node );829 ++indent;830 os << "Qualified Type:" << std::endl << indent;831 safe_print( node->parent );832 os << std::endl << indent;833 safe_print( node->child );834 os << std::endl;835 --indent;836 837 588 return node; 838 589 } 839 590 840 591 virtual const ast::Type * visit( const ast::FunctionType * node ) { 841 preprint( node );842 843 os << "function" << std::endl;844 if ( ! node->params.empty() ) {845 os << indent << "... with parameters" << std::endl;846 ++indent;847 printAll( node->params );848 if ( node->isVarArgs ) {849 os << indent << "and a variable number of other arguments" << std::endl;850 }851 --indent;852 } else if ( node->isVarArgs ) {853 os << indent+1 << "accepting unspecified arguments" << std::endl;854 }855 856 os << indent << "... returning";857 if ( node->returns.empty() ) {858 os << " nothing" << std::endl;859 } else {860 os << std::endl;861 ++indent;862 printAll( node->returns );863 --indent;864 }865 866 592 return node; 867 593 } 868 594 869 595 virtual const ast::Type * visit( const ast::StructInstType * node ) { 870 preprint( node );871 os << "instance of struct " << node->name;872 if ( node->base ) {873 os << " " << ( node->base->body ? "with" : "without" ) << " body";874 }875 print( node->params );876 877 596 return node; 878 597 } 879 598 880 599 virtual const ast::Type * visit( const ast::UnionInstType * node ) { 881 preprint( node );882 os << "instance of union " << node->name;883 if ( node->base ) {884 os << " " << ( node->base->body ? "with" : "without" ) << " body";885 }886 print( node->params );887 888 600 return node; 889 601 } 890 602 891 603 virtual const ast::Type * visit( const ast::EnumInstType * node ) { 892 preprint( node );893 os << "instance of enum " << node->name;894 if ( node->base ) {895 os << " " << ( node->base->body ? "with" : "without" ) << " body";896 }897 print( node->params );898 899 604 return node; 900 605 } 901 606 902 607 virtual const ast::Type * visit( const ast::TraitInstType * node ) { 903 preprint( node );904 os << "instance of trait " << node->name;905 print( node->params );906 907 608 return node; 908 609 } 909 610 910 611 virtual const ast::Type * visit( const ast::TypeInstType * node ) { 911 preprint( node );912 os << "instance of type " << node->name913 << " (" << (node->kind == ast::TypeVar::Ftype ? "" : "not ") << "function type)";914 print( node->params );915 916 612 return node; 917 613 } 918 614 919 615 virtual const ast::Type * visit( const ast::TupleType * node ) { 920 preprint( node );921 os << "tuple of types" << std::endl;922 ++indent;923 printAll( node->types );924 --indent;925 926 616 return node; 927 617 } 928 618 929 619 virtual const ast::Type * visit( const ast::TypeofType * node ) { 930 preprint( node );931 if ( node->kind == ast::TypeofType::Basetypeof ) { os << "base-"; }932 os << "type-of expression ";933 safe_print( node->expr );934 935 620 return node; 936 621 } 937 622 938 623 virtual const ast::Type * visit( const ast::VarArgsType * node ) { 939 preprint( node );940 os << "builtin var args pack";941 624 return node; 942 625 } 943 626 944 627 virtual const ast::Type * visit( const ast::ZeroType * node ) { 945 preprint( node );946 os << "zero_t";947 628 return node; 948 629 } 949 630 950 631 virtual const ast::Type * visit( const ast::OneType * node ) { 951 preprint( node );952 os << "one_t";953 632 return node; 954 633 } 955 634 956 635 virtual const ast::Type * visit( const ast::GlobalScopeType * node ) { 957 preprint( node );958 os << "Global Scope Type";959 636 return node; 960 637 } … … 975 652 virtual const ast::Init * visit( const ast::SingleInit * node ) { 976 653 os << "Simple Initializer: "; 977 safe_print( node->value);654 node->value->accept( *this ); 978 655 return node; 979 656 } … … 1038 715 os << indent+1 << i.first << " -> "; 1039 716 indent += 2; 1040 safe_print( i.second);717 i.second->accept( *this ); 1041 718 indent -= 2; 1042 719 os << std::endl; … … 1046 723 os << indent+1 << i->first << " -> "; 1047 724 indent += 2; 1048 safe_print( i->second);725 i->second->accept( *this ); 1049 726 indent -= 2; 1050 727 os << std::endl; -
src/AST/Type.hpp
rf1ec88a rf685679 308 308 virtual ReferenceToType * clone() const override = 0; 309 309 MUTATE_FRIEND 310 311 protected: 312 /// Name for the kind of type this is 313 virtual std::string typeString() const = 0; 310 314 }; 311 315 … … 329 333 StructInstType * clone() const override { return new StructInstType{ *this }; } 330 334 MUTATE_FRIEND 335 336 std::string typeString() const override { return "struct"; } 331 337 }; 332 338 … … 350 356 UnionInstType * clone() const override { return new UnionInstType{ *this }; } 351 357 MUTATE_FRIEND 358 359 std::string typeString() const override { return "union"; } 352 360 }; 353 361 … … 371 379 EnumInstType * clone() const override { return new EnumInstType{ *this }; } 372 380 MUTATE_FRIEND 381 382 std::string typeString() const override { return "enum"; } 373 383 }; 374 384 … … 393 403 TraitInstType * clone() const override { return new TraitInstType{ *this }; } 394 404 MUTATE_FRIEND 405 406 std::string typeString() const override { return "trait"; } 395 407 }; 396 408 … … 420 432 TypeInstType * clone() const override { return new TypeInstType{ *this }; } 421 433 MUTATE_FRIEND 434 435 std::string typeString() const override { return "type"; } 422 436 }; 423 437 -
src/Common/Eval.cc
rf1ec88a rf685679 17 17 18 18 #include "Common/PassVisitor.h" 19 #include "AST/Pass.hpp"20 19 #include "InitTweak/InitTweak.h" 21 20 #include "SynTree/Expression.h" 22 21 23 //------------------------------------------------------------- 24 // Old AST 25 struct EvalOld : public WithShortCircuiting { 22 struct Eval : public WithShortCircuiting { 26 23 long long int value = 0; 27 24 bool valid = true; … … 83 80 }; 84 81 85 //-------------------------------------------------------------86 // New AST87 struct EvalNew : public ast::WithShortCircuiting {88 long long int value = 0;89 bool valid = true;90 91 void previsit( const ast::Node * ) { visit_children = false; }92 void postvisit( const ast::Node * ) { valid = false; }93 94 void postvisit( const ast::ConstantExpr * expr ) {95 value = expr->intValue();96 }97 98 void postvisit( const ast::CastExpr * expr ) {99 auto arg = eval(expr->arg);100 valid = arg.second;101 value = arg.first;102 // TODO: perform type conversion on value if valid103 }104 105 void postvisit( const ast::VariableExpr * expr ) {106 if ( const ast::EnumInstType * inst = dynamic_cast<const ast::EnumInstType *>(expr->result.get()) ) {107 if ( const ast::EnumDecl * decl = inst->base ) {108 if ( decl->valueOf( expr->var, value ) ) { // value filled by valueOf109 return;110 }111 }112 }113 valid = false;114 }115 116 void postvisit( const ast::ApplicationExpr * expr ) {117 const ast::DeclWithType * function = InitTweak::getFunction(expr);118 if ( ! function || function->linkage != ast::Linkage::Intrinsic ) { valid = false; return; }119 const std::string & fname = function->name;120 assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() );121 std::pair<long long int, bool> arg1, arg2;122 arg1 = eval(expr->args.front());123 valid = valid && arg1.second;124 if ( ! valid ) return;125 if ( expr->args.size() == 2 ) {126 arg2 = eval(expr->args.back());127 valid = valid && arg2.second;128 if ( ! valid ) return;129 }130 if (fname == "?+?") {131 value = arg1.first + arg2.first;132 } else if (fname == "?-?") {133 value = arg1.first - arg2.first;134 } else if (fname == "?*?") {135 value = arg1.first * arg2.first;136 } else if (fname == "?/?") {137 value = arg1.first / arg2.first;138 } else if (fname == "?%?") {139 value = arg1.first % arg2.first;140 } else {141 valid = false;142 }143 // TODO: implement other intrinsic functions144 }145 };146 147 82 std::pair<long long int, bool> eval(Expression * expr) { 148 PassVisitor<Eval Old> ev;83 PassVisitor<Eval> ev; 149 84 if (expr) { 150 85 expr->accept(ev); … … 156 91 157 92 std::pair<long long int, bool> eval(const ast::Expr * expr) { 158 ast::Pass<EvalNew> ev; 159 if (expr) { 160 expr->accept(ev); 161 return std::make_pair(ev.pass.value, ev.pass.valid); 162 } else { 163 return std::make_pair(0, false); 164 } 93 #warning not implemented 94 return { 0, false }; 165 95 } 166 96 -
src/Common/PassVisitor.impl.h
rf1ec88a rf685679 23 23 assert( __return ); \ 24 24 return __return; 25 26 27 #define VISIT_BODY( node ) \ 28 VISIT_START( node ); \ 29 if( children_guard ) { \ 30 Visitor::visit( node ); \ 31 } \ 32 VISIT_END( node ); \ 33 34 35 #define MUTATE_BODY( type, node ) \ 36 MUTATE_START( node ); \ 37 if( children_guard ) { \ 38 Mutator::mutate( node ); \ 39 } \ 40 MUTATE_END( type, node ); \ 41 25 42 26 43 … … 2745 2762 MUTATE_END( TypeSubstitution, node ); 2746 2763 } 2747 2748 #undef VISIT_START2749 #undef VISIT_END2750 2751 #undef MUTATE_START2752 #undef MUTATE_END -
src/InitTweak/InitTweak.cc
rf1ec88a rf685679 346 346 namespace { 347 347 DeclarationWithType * getCalledFunction( Expression * expr ); 348 const ast::DeclWithType * getCalledFunction( const ast::Expr * expr );349 348 350 349 template<typename CallExpr> … … 356 355 return getCalledFunction( expr->get_args().front() ); 357 356 } 358 359 template<typename CallExpr>360 const ast::DeclWithType * handleDerefCalledFunction( const CallExpr * expr ) {361 // (*f)(x) => should get "f"362 std::string name = getFunctionName( expr );363 assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );364 assertf( ! expr->args.empty(), "Cannot get called function from dereference with no arguments" );365 return getCalledFunction( expr->args.front() );366 }367 368 357 369 358 DeclarationWithType * getCalledFunction( Expression * expr ) { … … 386 375 return nullptr; 387 376 } 388 389 const ast::DeclWithType * getCalledFunction( const ast::Expr * expr ) {390 assert( expr );391 if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( expr ) ) {392 return varExpr->var;393 } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( expr ) ) {394 return memberExpr->member;395 } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( expr ) ) {396 return getCalledFunction( castExpr->arg );397 } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( expr ) ) {398 return handleDerefCalledFunction( untypedExpr );399 } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * > ( expr ) ) {400 return handleDerefCalledFunction( appExpr );401 } else if ( const ast::AddressExpr * addrExpr = dynamic_cast< const ast::AddressExpr * >( expr ) ) {402 return getCalledFunction( addrExpr->arg );403 } else if ( const ast::CommaExpr * commaExpr = dynamic_cast< const ast::CommaExpr * >( expr ) ) {404 return getCalledFunction( commaExpr->arg2 );405 }406 return nullptr;407 }408 377 } 409 378 … … 413 382 } else if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * > ( expr ) ) { 414 383 return getCalledFunction( untyped->get_function() ); 415 }416 assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() );417 }418 419 const ast::DeclWithType * getFunction( const ast::Expr * expr ) {420 if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr ) ) {421 return getCalledFunction( appExpr->func );422 } else if ( const ast::UntypedExpr * untyped = dynamic_cast< const ast::UntypedExpr * > ( expr ) ) {423 return getCalledFunction( untyped->func );424 384 } 425 385 assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() ); … … 474 434 } 475 435 476 template<typename CallExpr>477 const ast::Expr * callArg( const CallExpr * call, unsigned int pos ) {478 if( pos >= call->args.size() ) {479 assertf( false, "getCallArg for argument that doesn't exist: (%u); %s.",480 pos, toString( call ).c_str() );481 }482 for ( const ast::Expr * arg : call->args ) {483 if ( pos == 0 ) return arg;484 --pos;485 }486 assert( false );487 }436 // template<typename CallExpr> 437 // const ast::Expr * callArg( const CallExpr * call, unsigned int pos ) { 438 // if( pos >= call->args.size() ) { 439 // assertf( false, "getCallArg for argument that doesn't exist: (%u); %s.", 440 // pos, toString( call ).c_str() ); 441 // } 442 // for ( const ast::Expr * arg : call->args ) { 443 // if ( pos == 0 ) return arg; 444 // --pos; 445 // } 446 // assert( false ); 447 // } 488 448 } 489 449 … … 506 466 } 507 467 } 508 509 468 const ast::Expr * getCallArg( const ast::Expr * call, unsigned pos ) { 510 if ( auto app = dynamic_cast< const ast::ApplicationExpr * >( call ) ) { 511 return callArg( app, pos ); 512 } else if ( auto untyped = dynamic_cast< const ast::UntypedExpr * >( call ) ) { 513 return callArg( untyped, pos ); 514 } else if ( auto tupleAssn = dynamic_cast< const ast::TupleAssignExpr * >( call ) ) { 515 const std::list<ast::ptr<ast::Stmt>>& stmts = tupleAssn->stmtExpr->stmts->kids; 516 assertf( ! stmts.empty(), "TupleAssignExpr missing statements." ); 517 auto stmt = strict_dynamic_cast< const ast::ExprStmt * >( stmts.back().get() ); 518 auto tuple = strict_dynamic_cast< const ast::TupleExpr * >( stmt->expr.get() ); 519 assertf( ! tuple->exprs.empty(), "TupleAssignExpr has empty tuple expr."); 520 return getCallArg( tuple->exprs.front(), pos ); 521 } else if ( auto ctor = dynamic_cast< const ast::ImplicitCopyCtorExpr * >( call ) ) { 522 return getCallArg( ctor->callExpr, pos ); 523 } else { 524 assertf( false, "Unexpected expression type passed to getCallArg: %s", 525 toString( call ).c_str() ); 526 } 469 (void)call; 470 (void)pos; 471 #warning unimplemented; needs to build AST/Expr.cpp 472 assertf(false, "unimplemented; needs to build AST/Expr.cpp"); 473 // if ( auto app = dynamic_cast< const ast::ApplicationExpr * >( call ) ) { 474 // return callArg( app, pos ); 475 // } else if ( auto untyped = dynamic_cast< const ast::UntypedExpr * >( call ) ) { 476 // return callArg( untyped, pos ); 477 // } else if ( auto tupleAssn = dynamic_cast< const ast::TupleAssignExpr * >( call ) ) { 478 // const std::list<ast::ptr<ast::Stmt>>& stmts = tupleAssn->stmtExpr->stmts->kids; 479 // assertf( ! stmts.empty(), "TupleAssignExpr missing statements." ); 480 // const ExprStmt * stmt = strict_dynamic_cast< const ast::ExprStmt * >( stmts.back() ); 481 // const TupleExpr * tuple = strict_dynamic_cast< const ast::TupleExpr * >( stmt->expr ); 482 // assertf( ! tuple->exprs.empty(), "TupleAssignExpr has empty tuple expr."); 483 // return getCallArg( tuple->exprs.front(), pos ); 484 // } else if ( auto ctor = dynamic_cast< const ast::ImplicitCopyCtorExpr * >( call ) ) { 485 // return getCallArg( ctor->callExpr, pos ); 486 // } else { 487 // assertf( false, "Unexpected expression type passed to getCallArg: %s", 488 // toString( call ).c_str() ); 489 // } 527 490 } 528 491 529 492 namespace { 530 493 std::string funcName( Expression * func ); 531 std::string funcName( const ast::Expr * func );532 494 533 495 template<typename CallExpr> … … 538 500 assertf( ! expr->get_args().empty(), "Cannot get function name from dereference with no arguments" ); 539 501 return funcName( expr->get_args().front() ); 540 }541 542 template<typename CallExpr>543 std::string handleDerefName( const CallExpr * expr ) {544 // (*f)(x) => should get name "f"545 std::string name = getFunctionName( expr );546 assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );547 assertf( ! expr->args.empty(), "Cannot get function name from dereference with no arguments" );548 return funcName( expr->args.front() );549 502 } 550 503 … … 570 523 } 571 524 } 572 573 std::string funcName( const ast::Expr * func ) {574 if ( const ast::NameExpr * nameExpr = dynamic_cast< const ast::NameExpr * >( func ) ) {575 return nameExpr->name;576 } else if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( func ) ) {577 return varExpr->var->name;578 } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( func ) ) {579 return funcName( castExpr->arg );580 } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( func ) ) {581 return memberExpr->member->name;582 } else if ( const ast::UntypedMemberExpr * memberExpr = dynamic_cast< const ast::UntypedMemberExpr * > ( func ) ) {583 return funcName( memberExpr->member );584 } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( func ) ) {585 return handleDerefName( untypedExpr );586 } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( func ) ) {587 return handleDerefName( appExpr );588 } else if ( const ast::ConstructorExpr * ctorExpr = dynamic_cast< const ast::ConstructorExpr * >( func ) ) {589 return funcName( getCallArg( ctorExpr->callExpr, 0 ) );590 } else {591 assertf( false, "Unexpected expression type being called as a function in call expression: %s", toString( func ).c_str() );592 }593 }594 525 } 595 526 … … 608 539 } 609 540 610 std::string getFunctionName( const ast::Expr * expr ) {611 // there's some unforunate overlap here with getCalledFunction. Ideally this would be able to use getCalledFunction and612 // return the name of the DeclarationWithType, but this needs to work for NameExpr and UntypedMemberExpr, where getCalledFunction613 // can't possibly do anything reasonable.614 if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr ) ) {615 return funcName( appExpr->func );616 } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * > ( expr ) ) {617 return funcName( untypedExpr->func );618 } else {619 std::cerr << expr << std::endl;620 assertf( false, "Unexpected expression type passed to getFunctionName" );621 }622 }623 624 541 Type * getPointerBase( Type * type ) { 625 542 if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) { … … 634 551 } 635 552 const ast::Type* getPointerBase( const ast::Type* t ) { 636 if ( const auto * p = dynamic_cast< const ast::PointerType * >( t ) ) { 637 return p->base; 638 } else if ( const auto * a = dynamic_cast< const ast::ArrayType * >( t ) ) { 639 return a->base; 640 } else if ( const auto * r = dynamic_cast< const ast::ReferenceType * >( t ) ) { 641 return r->base; 642 } else return nullptr; 553 (void)t; 554 #warning needs to build Type.cpp before inclusion 555 assertf(false, "needs to build Type.cpp before inclusion"); 556 // if ( const auto * p = dynamic_cast< const ast::PointerType * >( t ) ) { 557 // return p->base; 558 // } else if ( const auto * a = dynamic_cast< const ast::ArrayType * >( t ) ) { 559 // return a->base; 560 // } else if ( const auto * r = dynamic_cast< const ast::ReferenceType * >( t ) ) { 561 // return r->base; 562 // } else return nullptr; 643 563 } 644 564 -
src/InitTweak/InitTweak.h
rf1ec88a rf685679 58 58 /// returns the declaration of the function called by the expr (must be ApplicationExpr or UntypedExpr) 59 59 DeclarationWithType * getFunction( Expression * expr ); 60 const ast::DeclWithType * getFunction( const ast::Expr * expr );61 60 62 61 /// Non-Null if expr is a call expression whose target function is intrinsic … … 79 78 /// returns the name of the function being called 80 79 std::string getFunctionName( Expression * expr ); 81 std::string getFunctionName( const ast::Expr * expr );82 80 83 81 /// returns the argument to a call expression in position N indexed from 0
Note:
See TracChangeset
for help on using the changeset viewer.