Changeset 8d182b1 for src/CodeGen
- Timestamp:
- Nov 14, 2023, 12:19:09 PM (2 years ago)
- Branches:
- master
- Children:
- 1ccae59, 89a8bab
- Parents:
- df8ba61a (diff), 5625427 (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/CodeGen
- Files:
-
- 3 deleted
- 12 edited
-
CodeGenerator.cc (deleted)
-
CodeGenerator.h (deleted)
-
CodeGeneratorNew.cpp (modified) (69 diffs)
-
CodeGeneratorNew.hpp (modified) (3 diffs)
-
FixMain.cc (modified) (6 diffs)
-
FixMain.h (modified) (3 diffs)
-
FixMain2.cc (deleted)
-
FixNames.cc (modified) (3 diffs)
-
FixNames.h (modified) (2 diffs)
-
GenType.cc (modified) (25 diffs)
-
Generate.cc (modified) (3 diffs)
-
Generate.h (modified) (2 diffs)
-
LinkOnce.cc (modified) (2 diffs)
-
LinkOnce.h (modified) (2 diffs)
-
module.mk (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGeneratorNew.cpp
rdf8ba61a r8d182b1 24 24 namespace CodeGen { 25 25 26 int CodeGenerator _new::tabsize = 4;26 int CodeGenerator::tabsize = 4; 27 27 28 28 // The kinds of statements that should be followed by whitespace. … … 35 35 } 36 36 37 void CodeGenerator _new::extension( ast::Expr const * expr ) {37 void CodeGenerator::extension( ast::Expr const * expr ) { 38 38 if ( expr->extension ) output << "__extension__ "; 39 39 } 40 40 41 void CodeGenerator _new::extension( ast::Decl const * decl ) {41 void CodeGenerator::extension( ast::Decl const * decl ) { 42 42 if ( decl->extension ) output << "__extension__ "; 43 43 } 44 44 45 void CodeGenerator _new::asmName( ast::DeclWithType const * decl ) {45 void CodeGenerator::asmName( ast::DeclWithType const * decl ) { 46 46 if ( auto asmName = decl->asmName.as<ast::ConstantExpr>() ) { 47 47 output << " asm ( " << asmName->rep << " )"; … … 49 49 } 50 50 51 CodeGenerator _new::LabelPrinter & CodeGenerator_new::LabelPrinter::operator()(51 CodeGenerator::LabelPrinter & CodeGenerator::LabelPrinter::operator()( 52 52 std::vector<ast::Label> const & l ) { 53 53 labels = &l; … … 55 55 } 56 56 57 std::ostream & CodeGenerator _new::LabelPrinter::operator()( std::ostream & output ) const {57 std::ostream & CodeGenerator::LabelPrinter::operator()( std::ostream & output ) const { 58 58 const std::vector<ast::Label> & labels = *this->labels; 59 59 for ( const ast::Label & label : labels ) { … … 66 66 // Using updateLocation at the beginning of a node and endl within a node 67 67 // should become the method of formating. 68 void CodeGenerator _new::updateLocation( CodeLocation const & to ) {68 void CodeGenerator::updateLocation( CodeLocation const & to ) { 69 69 // Skip if linemarks shouldn't appear or if location is unset. 70 70 if ( !options.lineMarks || to.isUnset() ) return; … … 86 86 } 87 87 88 void CodeGenerator _new::updateLocation( ast::ParseNode const * to ) {88 void CodeGenerator::updateLocation( ast::ParseNode const * to ) { 89 89 updateLocation( to->location ); 90 90 } 91 91 92 std::ostream & CodeGenerator _new::LineEnder::operator()( std::ostream & os ) const {92 std::ostream & CodeGenerator::LineEnder::operator()( std::ostream & os ) const { 93 93 os << "\n" << std::flush; 94 94 cg.currentLocation.first_line++; … … 96 96 } 97 97 98 CodeGenerator _new::CodeGenerator_new( std::ostream & os, const Options & options ) :99 indent( 0, CodeGenerator _new::tabsize ), output( os ),98 CodeGenerator::CodeGenerator( std::ostream & os, const Options & options ) : 99 indent( 0, CodeGenerator::tabsize ), output( os ), 100 100 options( options ), printLabels( *this ), endl( *this ) 101 101 {} 102 102 103 std::string CodeGenerator _new::mangleName( ast::DeclWithType const * decl ) {103 std::string CodeGenerator::mangleName( ast::DeclWithType const * decl ) { 104 104 // GCC builtins should always be printed unmangled. 105 105 if ( options.pretty || decl->linkage.is_gcc_builtin ) { … … 112 112 } 113 113 114 void CodeGenerator _new::genAttributes(114 void CodeGenerator::genAttributes( 115 115 const std::vector<ast::ptr<ast::Attribute>> & attributes ) { 116 116 if ( attributes.empty() ) return; … … 129 129 } 130 130 131 void CodeGenerator _new::previsit( ast::Node const * ) {131 void CodeGenerator::previsit( ast::Node const * ) { 132 132 // All traversal is manual. 133 133 // TODO: Which means the ast::Pass is just providing a default no visit? … … 135 135 } 136 136 137 void CodeGenerator _new::previsit( ast::ParseNode const * node ) {137 void CodeGenerator::previsit( ast::ParseNode const * node ) { 138 138 previsit( (ast::Node const *)node ); 139 139 updateLocation( node ); 140 140 } 141 141 142 void CodeGenerator _new::postvisit( ast::Node const * node ) {142 void CodeGenerator::postvisit( ast::Node const * node ) { 143 143 std::stringstream ss; 144 144 ast::print( ss, node ); … … 146 146 } 147 147 148 void CodeGenerator _new::previsit( ast::Expr const * expr ) {148 void CodeGenerator::previsit( ast::Expr const * expr ) { 149 149 previsit( (ast::ParseNode const *)expr ); 150 150 GuardAction( [this, expr](){ … … 155 155 } 156 156 157 void CodeGenerator _new::postvisit( ast::FunctionDecl const * decl ) {157 void CodeGenerator::postvisit( ast::FunctionDecl const * decl ) { 158 158 // Deleted decls should never be used, so don't print them in C. 159 159 if ( decl->isDeleted && options.genC ) return; … … 168 168 169 169 std::ostringstream acc; 170 ast::Pass<CodeGenerator _new> subCG( acc, subOptions );170 ast::Pass<CodeGenerator> subCG( acc, subOptions ); 171 171 // Add the forall clause. 172 172 // TODO: These probably should be removed by now and the assert used. … … 213 213 } 214 214 215 //void CodeGenerator_new::postvisit( ast::ObjectDecl const * decl_ ) { 216 ast::ObjectDecl const * CodeGenerator_new::postvisit( 215 ast::ObjectDecl const * CodeGenerator::postvisit( 217 216 ast::ObjectDecl const * decl ) { 218 217 // Deleted decls should never be used, so don't print them in C. … … 262 261 } 263 262 264 void CodeGenerator _new::handleStorageClass( ast::DeclWithType const * decl ) {263 void CodeGenerator::handleStorageClass( ast::DeclWithType const * decl ) { 265 264 if ( decl->storage.any() ) { 266 265 ast::print( output, decl->storage ); … … 268 267 } 269 268 270 void CodeGenerator _new::handleAggregate(269 void CodeGenerator::handleAggregate( 271 270 ast::AggregateDecl const * decl, std::string const & kind ) { 272 271 if ( !decl->params.empty() && !options.genC ) { … … 296 295 } 297 296 298 void CodeGenerator _new::postvisit( ast::StructDecl const * decl ) {297 void CodeGenerator::postvisit( ast::StructDecl const * decl ) { 299 298 extension( decl ); 300 299 handleAggregate( decl, "struct " ); 301 300 } 302 301 303 void CodeGenerator _new::postvisit( ast::UnionDecl const * decl ) {302 void CodeGenerator::postvisit( ast::UnionDecl const * decl ) { 304 303 extension( decl ); 305 304 handleAggregate( decl, "union " ); … … 332 331 } 333 332 334 void CodeGenerator _new::postvisit( ast::EnumDecl const * decl ) {333 void CodeGenerator::postvisit( ast::EnumDecl const * decl ) { 335 334 extension( decl ); 336 335 auto members = decl->members; … … 370 369 } 371 370 372 void CodeGenerator _new::postvisit( ast::TraitDecl const * decl ) {371 void CodeGenerator::postvisit( ast::TraitDecl const * decl ) { 373 372 assertf( !options.genC, "TraitDecls should not reach code generation." ); 374 373 extension( decl ); … … 376 375 } 377 376 378 void CodeGenerator _new::postvisit( ast::TypedefDecl const * decl ) {377 void CodeGenerator::postvisit( ast::TypedefDecl const * decl ) { 379 378 assertf( !options.genC, "Typedefs should not reach code generation." ); 380 379 output << "typedef " << genType( decl->base, decl->name, options ) << endl; 381 380 } 382 381 383 void CodeGenerator _new::postvisit( ast::TypeDecl const * decl ) {382 void CodeGenerator::postvisit( ast::TypeDecl const * decl ) { 384 383 assertf( !options.genC, "TypeDecls should not reach code generation." ); 385 384 output << decl->genTypeString() << " " << decl->name; … … 397 396 } 398 397 399 void CodeGenerator _new::postvisit( ast::StaticAssertDecl const * decl ) {398 void CodeGenerator::postvisit( ast::StaticAssertDecl const * decl ) { 400 399 output << "_Static_assert("; 401 400 decl->cond->accept( *visitor ); … … 405 404 } 406 405 407 void CodeGenerator _new::postvisit( ast::Designation const * designation ) {406 void CodeGenerator::postvisit( ast::Designation const * designation ) { 408 407 auto designators = designation->designators; 409 408 if ( 0 == designators.size() ) return; … … 423 422 } 424 423 425 void CodeGenerator _new::postvisit( ast::SingleInit const * init ) {424 void CodeGenerator::postvisit( ast::SingleInit const * init ) { 426 425 init->value->accept( *visitor ); 427 426 } 428 427 429 void CodeGenerator _new::postvisit( ast::ListInit const * init ) {428 void CodeGenerator::postvisit( ast::ListInit const * init ) { 430 429 auto initBegin = init->initializers.begin(); 431 430 auto initEnd = init->initializers.end(); … … 446 445 } 447 446 448 void CodeGenerator _new::postvisit( ast::ConstructorInit const * init ) {447 void CodeGenerator::postvisit( ast::ConstructorInit const * init ) { 449 448 assertf( !options.genC, "ConstructorInit nodes should not reach code generation." ); 450 449 // This isn't actual code, but labels the constructor/destructor pairs. … … 456 455 } 457 456 458 void CodeGenerator _new::postvisit( ast::ApplicationExpr const * expr ) {457 void CodeGenerator::postvisit( ast::ApplicationExpr const * expr ) { 459 458 extension( expr ); 460 459 if ( auto var = expr->func.as<ast::VariableExpr>() ) { … … 550 549 } 551 550 552 void CodeGenerator _new::postvisit( ast::UntypedExpr const * expr ) {551 void CodeGenerator::postvisit( ast::UntypedExpr const * expr ) { 553 552 extension( expr ); 554 553 if ( auto name = expr->func.as<ast::NameExpr>() ) { … … 638 637 } 639 638 640 void CodeGenerator _new::postvisit( ast::RangeExpr const * expr ) {639 void CodeGenerator::postvisit( ast::RangeExpr const * expr ) { 641 640 expr->low->accept( *visitor ); 642 641 output << " ... "; … … 644 643 } 645 644 646 void CodeGenerator _new::postvisit( ast::NameExpr const * expr ) {645 void CodeGenerator::postvisit( ast::NameExpr const * expr ) { 647 646 extension( expr ); 648 647 if ( const OperatorInfo * opInfo = operatorLookup( expr->name ) ) { … … 657 656 } 658 657 659 void CodeGenerator _new::postvisit( ast::DimensionExpr const * expr ) {658 void CodeGenerator::postvisit( ast::DimensionExpr const * expr ) { 660 659 extension( expr ); 661 660 output << "/*non-type*/" << expr->name; 662 661 } 663 662 664 void CodeGenerator _new::postvisit( ast::AddressExpr const * expr ) {663 void CodeGenerator::postvisit( ast::AddressExpr const * expr ) { 665 664 extension( expr ); 666 665 output << "(&"; … … 669 668 } 670 669 671 void CodeGenerator _new::postvisit( ast::LabelAddressExpr const * expr ) {670 void CodeGenerator::postvisit( ast::LabelAddressExpr const * expr ) { 672 671 extension( expr ); 673 672 output << "(&&" << expr->arg << ")"; 674 673 } 675 674 676 void CodeGenerator _new::postvisit( ast::CastExpr const * expr ) {675 void CodeGenerator::postvisit( ast::CastExpr const * expr ) { 677 676 extension( expr ); 678 677 output << "("; … … 688 687 } 689 688 690 void CodeGenerator _new::postvisit( ast::KeywordCastExpr const * expr ) {689 void CodeGenerator::postvisit( ast::KeywordCastExpr const * expr ) { 691 690 assertf( !options.genC, "KeywordCastExpr should not reach code generation." ); 692 691 extension( expr ); … … 696 695 } 697 696 698 void CodeGenerator _new::postvisit( ast::VirtualCastExpr const * expr ) {697 void CodeGenerator::postvisit( ast::VirtualCastExpr const * expr ) { 699 698 assertf( !options.genC, "VirtualCastExpr should not reach code generation." ); 700 699 extension( expr ); … … 705 704 } 706 705 707 void CodeGenerator _new::postvisit( ast::UntypedMemberExpr const * expr ) {706 void CodeGenerator::postvisit( ast::UntypedMemberExpr const * expr ) { 708 707 assertf( !options.genC, "UntypedMemberExpr should not reach code generation." ); 709 708 extension( expr ); … … 713 712 } 714 713 715 void CodeGenerator _new::postvisit( ast::MemberExpr const * expr ) {714 void CodeGenerator::postvisit( ast::MemberExpr const * expr ) { 716 715 extension( expr ); 717 716 expr->aggregate->accept( *visitor ); … … 719 718 } 720 719 721 void CodeGenerator _new::postvisit( ast::VariableExpr const * expr ) {720 void CodeGenerator::postvisit( ast::VariableExpr const * expr ) { 722 721 extension( expr ); 723 722 const OperatorInfo * opInfo; … … 733 732 } 734 733 735 void CodeGenerator _new::postvisit( ast::ConstantExpr const * expr ) {734 void CodeGenerator::postvisit( ast::ConstantExpr const * expr ) { 736 735 extension( expr ); 737 736 output << expr->rep; 738 737 } 739 738 740 void CodeGenerator _new::postvisit( ast::SizeofExpr const * expr ) {739 void CodeGenerator::postvisit( ast::SizeofExpr const * expr ) { 741 740 extension( expr ); 742 741 output << "sizeof("; … … 749 748 } 750 749 751 void CodeGenerator _new::postvisit( ast::AlignofExpr const * expr ) {750 void CodeGenerator::postvisit( ast::AlignofExpr const * expr ) { 752 751 // Using the GCC extension to avoid changing the std to C11. 753 752 extension( expr ); … … 761 760 } 762 761 763 void CodeGenerator _new::postvisit( ast::UntypedOffsetofExpr const * expr ) {762 void CodeGenerator::postvisit( ast::UntypedOffsetofExpr const * expr ) { 764 763 assertf( !options.genC, "UntypedOffsetofExpr should not reach code generation." ); 765 764 output << "offsetof("; … … 769 768 } 770 769 771 void CodeGenerator _new::postvisit( ast::OffsetofExpr const * expr ) {770 void CodeGenerator::postvisit( ast::OffsetofExpr const * expr ) { 772 771 // Use GCC builtin 773 772 output << "__builtin_offsetof("; … … 777 776 } 778 777 779 void CodeGenerator _new::postvisit( ast::OffsetPackExpr const * expr ) {778 void CodeGenerator::postvisit( ast::OffsetPackExpr const * expr ) { 780 779 assertf( !options.genC, "OffsetPackExpr should not reach code generation." ); 781 780 output << "__CFA_offsetpack(" << genType( expr->type, "", options ) << ")"; 782 781 } 783 782 784 void CodeGenerator _new::postvisit( ast::LogicalExpr const * expr ) {783 void CodeGenerator::postvisit( ast::LogicalExpr const * expr ) { 785 784 extension( expr ); 786 785 output << "("; … … 791 790 } 792 791 793 void CodeGenerator _new::postvisit( ast::ConditionalExpr const * expr ) {792 void CodeGenerator::postvisit( ast::ConditionalExpr const * expr ) { 794 793 extension( expr ); 795 794 output << "("; … … 802 801 } 803 802 804 void CodeGenerator _new::postvisit( ast::CommaExpr const * expr ) {803 void CodeGenerator::postvisit( ast::CommaExpr const * expr ) { 805 804 extension( expr ); 806 805 output << "("; … … 818 817 } 819 818 820 void CodeGenerator _new::postvisit( ast::TupleAssignExpr const * expr ) {819 void CodeGenerator::postvisit( ast::TupleAssignExpr const * expr ) { 821 820 assertf( !options.genC, "TupleAssignExpr should not reach code generation." ); 822 821 expr->stmtExpr->accept( *visitor ); 823 822 } 824 823 825 void CodeGenerator _new::postvisit( ast::UntypedTupleExpr const * expr ) {824 void CodeGenerator::postvisit( ast::UntypedTupleExpr const * expr ) { 826 825 assertf( !options.genC, "UntypedTupleExpr should not reach code generation." ); 827 826 extension( expr ); … … 831 830 } 832 831 833 void CodeGenerator _new::postvisit( ast::TupleExpr const * expr ) {832 void CodeGenerator::postvisit( ast::TupleExpr const * expr ) { 834 833 assertf( !options.genC, "TupleExpr should not reach code generation." ); 835 834 extension( expr ); … … 839 838 } 840 839 841 void CodeGenerator _new::postvisit( ast::TupleIndexExpr const * expr ) {840 void CodeGenerator::postvisit( ast::TupleIndexExpr const * expr ) { 842 841 assertf( !options.genC, "TupleIndexExpr should not reach code generation." ); 843 842 extension( expr ); … … 846 845 } 847 846 848 void CodeGenerator _new::postvisit( ast::TypeExpr const * expr ) {847 void CodeGenerator::postvisit( ast::TypeExpr const * expr ) { 849 848 // TODO: Should there be an assertion there? 850 849 if ( !options.genC ) { … … 853 852 } 854 853 855 void CodeGenerator _new::postvisit( ast::AsmExpr const * expr ) {854 void CodeGenerator::postvisit( ast::AsmExpr const * expr ) { 856 855 if ( !expr->inout.empty() ) { 857 856 output << "[ " << expr->inout << " ] "; … … 863 862 } 864 863 865 void CodeGenerator _new::postvisit( ast::CompoundLiteralExpr const * expr ) {864 void CodeGenerator::postvisit( ast::CompoundLiteralExpr const * expr ) { 866 865 //assert( expr->result && dynamic_cast<ast::ListInit const *>( expr->init ) ); 867 866 assert( expr->result && expr->init.as<ast::ListInit>() ); … … 870 869 } 871 870 872 void CodeGenerator _new::postvisit( ast::UniqueExpr const * expr ) {871 void CodeGenerator::postvisit( ast::UniqueExpr const * expr ) { 873 872 assertf( !options.genC, "UniqueExpr should not reach code generation." ); 874 873 output << "unq<" << expr->id << ">{ "; … … 877 876 } 878 877 879 void CodeGenerator _new::postvisit( ast::StmtExpr const * expr ) {878 void CodeGenerator::postvisit( ast::StmtExpr const * expr ) { 880 879 auto stmts = expr->stmts->kids; 881 880 output << "({" << endl; … … 905 904 } 906 905 907 void CodeGenerator _new::postvisit( ast::ConstructorExpr const * expr ) {906 void CodeGenerator::postvisit( ast::ConstructorExpr const * expr ) { 908 907 assertf( !options.genC, "ConstructorExpr should not reach code generation." ); 909 908 expr->callExpr->accept( *visitor ); 910 909 } 911 910 912 void CodeGenerator _new::postvisit( ast::DeletedExpr const * expr ) {911 void CodeGenerator::postvisit( ast::DeletedExpr const * expr ) { 913 912 assertf( !options.genC, "DeletedExpr should not reach code generation." ); 914 913 expr->expr->accept( *visitor ); 915 914 } 916 915 917 void CodeGenerator _new::postvisit( ast::DefaultArgExpr const * expr ) {916 void CodeGenerator::postvisit( ast::DefaultArgExpr const * expr ) { 918 917 assertf( !options.genC, "DefaultArgExpr should not reach code generation." ); 919 918 expr->expr->accept( *visitor ); 920 919 } 921 920 922 void CodeGenerator _new::postvisit( ast::GenericExpr const * expr ) {921 void CodeGenerator::postvisit( ast::GenericExpr const * expr ) { 923 922 assertf( !options.genC, "GenericExpr should not reach code generation." ); 924 923 output << "_Generic("; … … 940 939 } 941 940 942 void CodeGenerator _new::postvisit( ast::CompoundStmt const * stmt ) {941 void CodeGenerator::postvisit( ast::CompoundStmt const * stmt ) { 943 942 output << "{" << endl; 944 943 … … 955 954 } 956 955 957 void CodeGenerator _new::postvisit( ast::ExprStmt const * stmt ) {956 void CodeGenerator::postvisit( ast::ExprStmt const * stmt ) { 958 957 assert( stmt ); 959 958 // Cast the top-level expression to void to reduce gcc warnings. … … 967 966 } 968 967 969 void CodeGenerator _new::postvisit( ast::AsmStmt const * stmt ) {968 void CodeGenerator::postvisit( ast::AsmStmt const * stmt ) { 970 969 output << "asm "; 971 970 if ( stmt->isVolatile ) output << "volatile "; … … 991 990 } 992 991 993 void CodeGenerator _new::postvisit( ast::AsmDecl const * decl ) {992 void CodeGenerator::postvisit( ast::AsmDecl const * decl ) { 994 993 output << "asm "; 995 994 ast::AsmStmt const * stmt = decl->stmt; … … 999 998 } 1000 999 1001 void CodeGenerator _new::postvisit( ast::DirectiveDecl const * decl ) {1000 void CodeGenerator::postvisit( ast::DirectiveDecl const * decl ) { 1002 1001 // endl prevents spaces before the directive. 1003 1002 output << endl << decl->stmt->directive; 1004 1003 } 1005 1004 1006 void CodeGenerator _new::postvisit( ast::DirectiveStmt const * stmt ) {1005 void CodeGenerator::postvisit( ast::DirectiveStmt const * stmt ) { 1007 1006 // endl prevents spaces before the directive. 1008 1007 output << endl << stmt->directive; 1009 1008 } 1010 1009 1011 void CodeGenerator _new::postvisit( ast::IfStmt const * stmt ) {1010 void CodeGenerator::postvisit( ast::IfStmt const * stmt ) { 1012 1011 output << "if ( "; 1013 1012 stmt->cond->accept( *visitor ); … … 1022 1021 } 1023 1022 1024 void CodeGenerator _new::postvisit( ast::SwitchStmt const * stmt ) {1023 void CodeGenerator::postvisit( ast::SwitchStmt const * stmt ) { 1025 1024 output << "switch ( "; 1026 1025 stmt->cond->accept( *visitor ); … … 1036 1035 } 1037 1036 1038 void CodeGenerator _new::postvisit( ast::CaseClause const * clause ) {1037 void CodeGenerator::postvisit( ast::CaseClause const * clause ) { 1039 1038 updateLocation( clause ); 1040 1039 output << indent; … … 1056 1055 } 1057 1056 1058 void CodeGenerator _new::postvisit( ast::BranchStmt const * stmt ) {1057 void CodeGenerator::postvisit( ast::BranchStmt const * stmt ) { 1059 1058 switch ( stmt->kind ) { 1060 1059 case ast::BranchStmt::Goto: … … 1091 1090 } 1092 1091 1093 void CodeGenerator _new::postvisit( ast::ReturnStmt const * stmt ) {1092 void CodeGenerator::postvisit( ast::ReturnStmt const * stmt ) { 1094 1093 output << "return "; 1095 1094 if ( stmt->expr ) stmt->expr->accept( *visitor ); … … 1097 1096 } 1098 1097 1099 void CodeGenerator _new::postvisit( ast::ThrowStmt const * stmt ) {1098 void CodeGenerator::postvisit( ast::ThrowStmt const * stmt ) { 1100 1099 assertf( !options.genC, "ThrowStmt should not reach code generation." ); 1101 1100 … … 1112 1111 } 1113 1112 1114 void CodeGenerator _new::postvisit( ast::CatchClause const * stmt ) {1113 void CodeGenerator::postvisit( ast::CatchClause const * stmt ) { 1115 1114 assertf( !options.genC, "CatchClause should not reach code generation." ); 1116 1115 … … 1126 1125 } 1127 1126 1128 void CodeGenerator _new::postvisit( ast::WaitForStmt const * stmt ) {1127 void CodeGenerator::postvisit( ast::WaitForStmt const * stmt ) { 1129 1128 assertf( !options.genC, "WaitforStmt should not reach code generation." ); 1130 1129 … … 1172 1171 } 1173 1172 1174 void CodeGenerator _new::postvisit( ast::WithStmt const * stmt ) {1173 void CodeGenerator::postvisit( ast::WithStmt const * stmt ) { 1175 1174 assertf( !options.genC, "WithStmt should not reach code generation." ); 1176 1175 … … 1181 1180 } 1182 1181 1183 void CodeGenerator _new::postvisit( ast::WhileDoStmt const * stmt ) {1182 void CodeGenerator::postvisit( ast::WhileDoStmt const * stmt ) { 1184 1183 if ( stmt->isDoWhile ) { 1185 1184 output << "do"; … … 1191 1190 output << " "; 1192 1191 1193 output << CodeGenerator _new::printLabels( stmt->body->labels );1192 output << CodeGenerator::printLabels( stmt->body->labels ); 1194 1193 stmt->body->accept( *visitor ); 1195 1194 … … 1203 1202 } 1204 1203 1205 void CodeGenerator _new::postvisit( ast::ForStmt const * stmt ) {1204 void CodeGenerator::postvisit( ast::ForStmt const * stmt ) { 1206 1205 // Initializer is always hoised so don't generate it. 1207 1206 // TODO: Do an assertion check? … … 1226 1225 } 1227 1226 1228 void CodeGenerator _new::postvisit( ast::NullStmt const * ) {1227 void CodeGenerator::postvisit( ast::NullStmt const * ) { 1229 1228 output << "/* null statement */ ;"; 1230 1229 } 1231 1230 1232 void CodeGenerator _new::postvisit( ast::DeclStmt const * stmt ) {1231 void CodeGenerator::postvisit( ast::DeclStmt const * stmt ) { 1233 1232 stmt->decl->accept( *visitor ); 1234 1233 … … 1236 1235 } 1237 1236 1238 void CodeGenerator _new::postvisit( ast::ImplicitCtorDtorStmt const * stmt ) {1237 void CodeGenerator::postvisit( ast::ImplicitCtorDtorStmt const * stmt ) { 1239 1238 assertf( !options.genC, "ImplicitCtorCtorStmt should not reach code generation." ); 1240 1239 stmt->callStmt->accept( *visitor ); 1241 1240 } 1242 1241 1243 void CodeGenerator _new::postvisit( ast::MutexStmt const * stmt ) {1242 void CodeGenerator::postvisit( ast::MutexStmt const * stmt ) { 1244 1243 assertf( !options.genC, "MutexStmt should not reach code generation." ); 1245 1244 // TODO: But this isn't what a mutex statement looks like. -
src/CodeGen/CodeGeneratorNew.hpp
rdf8ba61a r8d182b1 25 25 namespace CodeGen { 26 26 27 #warning Remove the _new when old version is removed. 28 struct CodeGenerator_new : 27 struct CodeGenerator final : 29 28 public ast::WithGuards, 30 29 public ast::WithShortCircuiting, 31 public ast::WithVisitorRef<CodeGenerator _new> {32 CodeGenerator _new( std::ostream & out, Options const & options );30 public ast::WithVisitorRef<CodeGenerator> { 31 CodeGenerator( std::ostream & out, Options const & options ); 33 32 34 33 // Turn off visit_children for all nodes. … … 119 118 /// Custom local implementation of endl that updates print location. 120 119 struct LineEnder { 121 CodeGenerator _new& cg;122 LineEnder( CodeGenerator _new& cg ) : cg( cg ) {}120 CodeGenerator & cg; 121 LineEnder( CodeGenerator & cg ) : cg( cg ) {} 123 122 std::ostream & operator()( std::ostream & ) const; 124 123 }; … … 129 128 /// Wrapper class to help print vectors of Labels. 130 129 struct LabelPrinter { 131 LabelPrinter( CodeGenerator _new& cg ) : cg( cg ), labels( nullptr ) {}130 LabelPrinter( CodeGenerator & cg ) : cg( cg ), labels( nullptr ) {} 132 131 LabelPrinter & operator()( std::vector<ast::Label> const & l ); 133 132 std::ostream & operator()( std::ostream & ) const; 134 CodeGenerator _new& cg;133 CodeGenerator & cg; 135 134 std::vector<ast::Label> const * labels; 136 135 }; -
src/CodeGen/FixMain.cc
rdf8ba61a r8d182b1 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // FixMain.cc -- 7 // FixMain.cc -- Tools to change a Cforall main into a C main. 8 8 // 9 9 // Author : Thierry Delisle … … 25 25 #include "AST/Type.hpp" 26 26 #include "AST/Vector.hpp" 27 #include "Common/PassVisitor.h"28 27 #include "Common/SemanticError.h" // for SemanticError 29 28 #include "CodeGen/GenType.h" // for GenType 30 #include "SynTree/Declaration.h" // for FunctionDecl, operator<<31 #include "SynTree/Type.h" // for FunctionType32 29 #include "SymTab/Mangler.h" 33 30 … … 36 33 namespace { 37 34 38 struct FindMainCore { 39 FunctionDecl * main_signature = nullptr; 40 41 void previsit( FunctionDecl * decl ) { 42 if ( FixMain::isMain( decl ) ) { 43 if ( main_signature ) { 44 SemanticError( decl, "Multiple definition of main routine\n" ); 45 } 46 main_signature = decl; 47 } 48 } 49 }; 50 51 struct FindMainCore_new { 35 struct FindMainCore final { 52 36 ast::FunctionDecl const * main_declaration = nullptr; 53 37 54 38 void previsit( ast::FunctionDecl const * decl ) { 55 if ( FixMain::isMain( decl ) ) {39 if ( isMain( decl ) ) { 56 40 if ( main_declaration ) { 57 41 SemanticError( decl, "Multiple definition of main routine\n" ); … … 65 49 return genType( types[at], "", Options( false, false, false, false ) ); 66 50 } 67 68 }69 70 template<typename container>71 std::string genTypeAt(const container& p, size_t idx) {72 return genType((*std::next(p.begin(), idx))->get_type(), "");73 }74 75 void FixMain::fix( std::list< Declaration * > & translationUnit,76 std::ostream &os, const char* bootloader_filename ) {77 PassVisitor< FindMainCore > main_finder;78 acceptAll( translationUnit, main_finder );79 FunctionDecl * main_signature = main_finder.pass.main_signature;80 81 if( main_signature ) {82 os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return ";83 main_signature->mangleName = SymTab::Mangler::mangle(main_signature);84 85 os << main_signature->get_scopedMangleName() << "(";86 const auto& params = main_signature->get_functionType()->get_parameters();87 switch(params.size()) {88 case 3: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv, (" << genTypeAt(params, 2) << ")envp"; break;89 case 2: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv"; break;90 case 0: break;91 default : assert(false);92 }93 os << "); }\n";94 95 std::ifstream bootloader(bootloader_filename, std::ios::in);96 assertf( bootloader.is_open(), "cannot open bootloader.c\n" );97 os << bootloader.rdbuf();98 }99 }100 101 namespace {102 51 103 52 ast::ObjectDecl * makeIntObj(){ … … 157 106 } 158 107 108 struct FixLinkageCore final { 109 ast::Linkage::Spec const spec; 110 FixLinkageCore( ast::Linkage::Spec spec ) : spec( spec ) {} 111 112 ast::FunctionDecl const * previsit( ast::FunctionDecl const * decl ) { 113 if ( decl->name != "main" ) return decl; 114 return ast::mutate_field( decl, &ast::FunctionDecl::linkage, spec ); 115 } 116 }; 117 159 118 } // namespace 160 119 161 bool FixMain::isMain( FunctionDecl * decl ) { 162 if ( std::string("main") != decl->name ) { 163 return false; 164 } 165 return is_main( SymTab::Mangler::mangle( decl, true, true ) ); 166 } 167 168 bool FixMain::isMain( const ast::FunctionDecl * decl ) { 120 bool isMain( const ast::FunctionDecl * decl ) { 169 121 if ( std::string("main") != decl->name ) { 170 122 return false; … … 173 125 } 174 126 175 void FixMain::fix( ast::TranslationUnit & translationUnit, 127 void fixMainLinkage( ast::TranslationUnit & translationUnit, 128 bool replace_main ) { 129 ast::Linkage::Spec const spec = 130 ( replace_main ) ? ast::Linkage::Cforall : ast::Linkage::C; 131 ast::Pass<FixLinkageCore>::run( translationUnit, spec ); 132 } 133 134 void fixMainInvoke( ast::TranslationUnit & translationUnit, 176 135 std::ostream &os, const char * bootloader_filename ) { 177 136 178 ast::Pass<FindMainCore _new> main_finder;137 ast::Pass<FindMainCore> main_finder; 179 138 ast::accept_all( translationUnit, main_finder ); 180 139 if ( nullptr == main_finder.core.main_declaration ) return; -
src/CodeGen/FixMain.h
rdf8ba61a r8d182b1 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // FixMain.h -- 7 // FixMain.h -- Tools to change a Cforall main into a C main. 8 8 // 9 9 // Author : Thierry Delisle … … 17 17 18 18 #include <iosfwd> 19 #include <memory>20 #include <list>21 19 22 #include "AST/LinkageSpec.hpp"23 #include "SynTree/LinkageSpec.h"24 25 class Declaration;26 class FunctionDecl;27 20 namespace ast { 28 21 class FunctionDecl; … … 32 25 namespace CodeGen { 33 26 34 class FixMain { 35 public : 36 static inline LinkageSpec::Spec mainLinkage() { 37 return replace_main ? LinkageSpec::Cforall : LinkageSpec::C; 38 } 39 static inline ast::Linkage::Spec getMainLinkage() { 40 return replace_main ? ast::Linkage::Cforall : ast::Linkage::C; 41 } 27 /// Is this function a program main function? 28 bool isMain( const ast::FunctionDecl * decl ); 42 29 43 static inline void setReplaceMain(bool val) { 44 replace_main = val; 45 } 30 /// Adjust the linkage of main functions. 31 void fixMainLinkage( ast::TranslationUnit & transUnit, bool replaceMain ); 46 32 47 static bool isMain(FunctionDecl* decl); 48 static bool isMain(const ast::FunctionDecl * decl); 49 50 static void fix( std::list< Declaration * > & decls, 51 std::ostream &os, const char* bootloader_filename ); 52 static void fix( ast::TranslationUnit & translationUnit, 53 std::ostream &os, const char * bootloader_filename ); 54 55 private: 56 static bool replace_main; 57 }; 33 /// Add a wrapper around to run the Cforall main. 34 void fixMainInvoke( ast::TranslationUnit & transUnit, 35 std::ostream & os, const char * bootloaderFilename ); 58 36 59 37 } // namespace CodeGen -
src/CodeGen/FixNames.cc
rdf8ba61a r8d182b1 22 22 #include "AST/Expr.hpp" 23 23 #include "AST/Pass.hpp" 24 #include "Common/PassVisitor.h"25 24 #include "Common/SemanticError.h" // for SemanticError 26 25 #include "FixMain.h" // for FixMain 27 26 #include "SymTab/Mangler.h" // for Mangler 28 #include "SynTree/LinkageSpec.h" // for Cforall, isMangled29 #include "SynTree/Constant.h" // for Constant30 #include "SynTree/Declaration.h" // for FunctionDecl, ObjectDecl, Declarat...31 #include "SynTree/Expression.h" // for ConstantExpr32 #include "SynTree/Label.h" // for Label, noLabels33 #include "SynTree/Statement.h" // for ReturnStmt, CompoundStmt34 #include "SynTree/Type.h" // for Type, BasicType, Type::Qualifiers35 #include "SynTree/Visitor.h" // for Visitor, acceptAll36 27 #include "CompilationState.h" 37 28 38 29 namespace CodeGen { 39 class FixNames : public WithGuards {40 public:41 void postvisit( ObjectDecl *objectDecl );42 void postvisit( FunctionDecl *functionDecl );43 30 44 void previsit( CompoundStmt *compoundStmt ); 45 private: 46 int scopeLevel = 1; 47 48 void fixDWT( DeclarationWithType *dwt ); 49 }; 50 51 void fixNames( std::list< Declaration* > & translationUnit ) { 52 PassVisitor<FixNames> fixer; 53 acceptAll( translationUnit, fixer ); 54 } 55 56 void FixNames::fixDWT( DeclarationWithType * dwt ) { 57 if ( dwt->get_name() != "" ) { 58 if ( LinkageSpec::isMangled( dwt->get_linkage() ) ) { 59 if (!useNewAST) { 60 dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) ); 61 } 62 dwt->set_scopeLevel( scopeLevel ); 63 } // if 64 } // if 65 } 66 67 void FixNames::postvisit( ObjectDecl * objectDecl ) { 68 fixDWT( objectDecl ); 69 } 70 71 void FixNames::postvisit( FunctionDecl * functionDecl ) { 72 fixDWT( functionDecl ); 73 74 if ( FixMain::isMain( functionDecl ) ) { 75 int nargs = functionDecl->get_functionType()->get_parameters().size(); 76 if( !(nargs == 0 || nargs == 2 || nargs == 3) ) { 77 SemanticError(functionDecl, "Main expected to have 0, 2 or 3 arguments\n"); 78 } 79 functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( new ConstantExpr( Constant::from_int( 0 ) ) ) ); 80 } 81 } 82 83 void FixNames::previsit( CompoundStmt * ) { 84 scopeLevel++; 85 GuardAction( [this](){ scopeLevel--; } ); 86 } 31 namespace { 87 32 88 33 /// Does work with the main function and scopeLevels. 89 class FixNames _newfinal {34 class FixNames final { 90 35 int scopeLevel = 1; 91 36 … … 103 48 104 49 const ast::FunctionDecl *postvisit( const ast::FunctionDecl *functionDecl ) { 105 if ( FixMain::isMain( functionDecl ) ) {50 if ( isMain( functionDecl ) ) { 106 51 auto mutDecl = ast::mutate( functionDecl ); 107 52 … … 138 83 }; 139 84 85 } // namespace 86 140 87 void fixNames( ast::TranslationUnit & translationUnit ) { 141 ast::Pass<FixNames _new>::run( translationUnit );88 ast::Pass<FixNames>::run( translationUnit ); 142 89 } 143 90 -
src/CodeGen/FixNames.h
rdf8ba61a r8d182b1 16 16 #pragma once 17 17 18 #include <list> // for list19 20 class Declaration;21 18 namespace ast { 22 19 class TranslationUnit; … … 24 21 25 22 namespace CodeGen { 26 /// mangles object and function names 27 void fixNames( std::list< Declaration* > & translationUnit ); 23 28 24 /// Sets scope levels and fills in main's default return. 29 25 void fixNames( ast::TranslationUnit & translationUnit ); 26 30 27 } // namespace CodeGen 31 28 -
src/CodeGen/GenType.cc
rdf8ba61a r8d182b1 21 21 #include "AST/Print.hpp" // for print 22 22 #include "AST/Vector.hpp" // for vector 23 #include "CodeGenerator.h" // for CodeGenerator 24 #include "CodeGeneratorNew.hpp" // for CodeGenerator_new 25 #include "SynTree/Declaration.h" // for DeclarationWithType 26 #include "SynTree/Expression.h" // for Expression 27 #include "SynTree/Type.h" // for PointerType, Type, FunctionType 28 #include "SynTree/Visitor.h" // for Visitor 23 #include "CodeGeneratorNew.hpp" // for CodeGenerator 24 #include "Common/UniqueName.h" // for UniqueName 29 25 30 26 namespace CodeGen { 31 struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting {32 std::string typeString;33 GenType( const std::string &typeString, const Options &options );34 35 void previsit( BaseSyntaxNode * );36 void postvisit( BaseSyntaxNode * );37 38 void postvisit( FunctionType * funcType );39 void postvisit( VoidType * voidType );40 void postvisit( BasicType * basicType );41 void postvisit( PointerType * pointerType );42 void postvisit( ArrayType * arrayType );43 void postvisit( ReferenceType * refType );44 void postvisit( StructInstType * structInst );45 void postvisit( UnionInstType * unionInst );46 void postvisit( EnumInstType * enumInst );47 void postvisit( TypeInstType * typeInst );48 void postvisit( TupleType * tupleType );49 void postvisit( VarArgsType * varArgsType );50 void postvisit( ZeroType * zeroType );51 void postvisit( OneType * oneType );52 void postvisit( GlobalScopeType * globalType );53 void postvisit( TraitInstType * inst );54 void postvisit( TypeofType * typeof );55 void postvisit( VTableType * vtable );56 void postvisit( QualifiedType * qualType );57 58 private:59 void handleQualifiers( Type *type );60 std::string handleGeneric( ReferenceToType * refType );61 void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );62 63 Options options;64 };65 66 std::string genType( Type *type, const std::string &baseString, const Options &options ) {67 PassVisitor<GenType> gt( baseString, options );68 std::ostringstream os;69 70 if ( ! type->get_attributes().empty() ) {71 PassVisitor<CodeGenerator> cg( os, options );72 cg.pass.genAttributes( type->get_attributes() );73 } // if74 75 type->accept( gt );76 return os.str() + gt.pass.typeString;77 }78 79 std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) {80 return genType( type, baseString, Options(pretty, genC, lineMarks, false ) );81 }82 83 std::string genPrettyType( Type * type, const std::string & baseString ) {84 return genType( type, baseString, true, false );85 }86 87 GenType::GenType( const std::string &typeString, const Options &options ) : typeString( typeString ), options( options ) {}88 89 // *** BaseSyntaxNode90 void GenType::previsit( BaseSyntaxNode * ) {91 // turn off automatic recursion for all nodes, to allow each visitor to92 // precisely control the order in which its children are visited.93 visit_children = false;94 }95 96 void GenType::postvisit( BaseSyntaxNode * node ) {97 std::stringstream ss;98 node->print( ss );99 assertf( false, "Unhandled node reached in GenType: %s", ss.str().c_str() );100 }101 102 void GenType::postvisit( VoidType * voidType ) {103 typeString = "void " + typeString;104 handleQualifiers( voidType );105 }106 107 void GenType::postvisit( BasicType * basicType ) {108 BasicType::Kind kind = basicType->kind;109 assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES );110 typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString;111 handleQualifiers( basicType );112 }113 114 void GenType::genArray( const Type::Qualifiers & qualifiers, Type * base, Expression *dimension, bool isVarLen, bool isStatic ) {115 std::ostringstream os;116 if ( typeString != "" ) {117 if ( typeString[ 0 ] == '*' ) {118 os << "(" << typeString << ")";119 } else {120 os << typeString;121 } // if122 } // if123 os << "[";124 125 if ( isStatic ) {126 os << "static ";127 } // if128 if ( qualifiers.is_const ) {129 os << "const ";130 } // if131 if ( qualifiers.is_volatile ) {132 os << "volatile ";133 } // if134 if ( qualifiers.is_restrict ) {135 os << "__restrict ";136 } // if137 if ( qualifiers.is_atomic ) {138 os << "_Atomic ";139 } // if140 if ( dimension != 0 ) {141 PassVisitor<CodeGenerator> cg( os, options );142 dimension->accept( cg );143 } else if ( isVarLen ) {144 // no dimension expression on a VLA means it came in with the * token145 os << "*";146 } // if147 os << "]";148 149 typeString = os.str();150 151 base->accept( *visitor );152 }153 154 void GenType::postvisit( PointerType * pointerType ) {155 assert( pointerType->base != 0);156 if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->dimension ) {157 genArray( pointerType->get_qualifiers(), pointerType->base, pointerType->dimension, pointerType->get_isVarLen(), pointerType->get_isStatic() );158 } else {159 handleQualifiers( pointerType );160 if ( typeString[ 0 ] == '?' ) {161 typeString = "* " + typeString;162 } else {163 typeString = "*" + typeString;164 } // if165 pointerType->base->accept( *visitor );166 } // if167 }168 169 void GenType::postvisit( ArrayType * arrayType ) {170 genArray( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->get_isVarLen(), arrayType->get_isStatic() );171 }172 173 void GenType::postvisit( ReferenceType * refType ) {174 assert( 0 != refType->base );175 assertf( ! options.genC, "Reference types should not reach code generation." );176 handleQualifiers( refType );177 typeString = "&" + typeString;178 refType->base->accept( *visitor );179 }180 181 void GenType::postvisit( FunctionType * funcType ) {182 std::ostringstream os;183 184 if ( typeString != "" ) {185 if ( typeString[ 0 ] == '*' ) {186 os << "(" << typeString << ")";187 } else {188 os << typeString;189 } // if190 } // if191 192 /************* parameters ***************/193 194 const std::list<DeclarationWithType *> &pars = funcType->parameters;195 196 if ( pars.empty() ) {197 if ( funcType->get_isVarArgs() ) {198 os << "()";199 } else {200 os << "(void)";201 } // if202 } else {203 PassVisitor<CodeGenerator> cg( os, options );204 os << "(" ;205 206 cg.pass.genCommaList( pars.begin(), pars.end() );207 208 if ( funcType->get_isVarArgs() ) {209 os << ", ...";210 } // if211 os << ")";212 } // if213 214 typeString = os.str();215 216 if ( funcType->returnVals.size() == 0 ) {217 typeString = "void " + typeString;218 } else {219 funcType->returnVals.front()->get_type()->accept( *visitor );220 } // if221 222 // add forall223 if( ! funcType->forall.empty() && ! options.genC ) {224 // assertf( ! genC, "Aggregate type parameters should not reach code generation." );225 std::ostringstream os;226 PassVisitor<CodeGenerator> cg( os, options );227 os << "forall(";228 cg.pass.genCommaList( funcType->forall.begin(), funcType->forall.end() );229 os << ")" << std::endl;230 typeString = os.str() + typeString;231 }232 }233 234 std::string GenType::handleGeneric( ReferenceToType * refType ) {235 if ( ! refType->parameters.empty() ) {236 std::ostringstream os;237 PassVisitor<CodeGenerator> cg( os, options );238 os << "(";239 cg.pass.genCommaList( refType->parameters.begin(), refType->parameters.end() );240 os << ") ";241 return os.str();242 }243 return "";244 }245 246 void GenType::postvisit( StructInstType * structInst ) {247 typeString = structInst->name + handleGeneric( structInst ) + " " + typeString;248 if ( options.genC ) typeString = "struct " + typeString;249 handleQualifiers( structInst );250 }251 252 void GenType::postvisit( UnionInstType * unionInst ) {253 typeString = unionInst->name + handleGeneric( unionInst ) + " " + typeString;254 if ( options.genC ) typeString = "union " + typeString;255 handleQualifiers( unionInst );256 }257 258 void GenType::postvisit( EnumInstType * enumInst ) {259 if ( enumInst->baseEnum && enumInst->baseEnum->base ) {260 typeString = genType(enumInst->baseEnum->base, typeString, options);261 } else {262 typeString = enumInst->name + " " + typeString;263 if ( options.genC ) {264 typeString = "enum " + typeString;265 }266 }267 handleQualifiers( enumInst );268 }269 270 void GenType::postvisit( TypeInstType * typeInst ) {271 assertf( ! options.genC, "Type instance types should not reach code generation." );272 typeString = typeInst->name + " " + typeString;273 handleQualifiers( typeInst );274 }275 276 void GenType::postvisit( TupleType * tupleType ) {277 assertf( ! options.genC, "Tuple types should not reach code generation." );278 unsigned int i = 0;279 std::ostringstream os;280 os << "[";281 for ( Type * t : *tupleType ) {282 i++;283 os << genType( t, "", options ) << (i == tupleType->size() ? "" : ", ");284 }285 os << "] ";286 typeString = os.str() + typeString;287 }288 289 void GenType::postvisit( VarArgsType * varArgsType ) {290 typeString = "__builtin_va_list " + typeString;291 handleQualifiers( varArgsType );292 }293 294 void GenType::postvisit( ZeroType * zeroType ) {295 // ideally these wouldn't hit codegen at all, but should be safe to make them ints296 typeString = (options.pretty ? "zero_t " : "long int ") + typeString;297 handleQualifiers( zeroType );298 }299 300 void GenType::postvisit( OneType * oneType ) {301 // ideally these wouldn't hit codegen at all, but should be safe to make them ints302 typeString = (options.pretty ? "one_t " : "long int ") + typeString;303 handleQualifiers( oneType );304 }305 306 void GenType::postvisit( GlobalScopeType * globalType ) {307 assertf( ! options.genC, "Global scope type should not reach code generation." );308 handleQualifiers( globalType );309 }310 311 void GenType::postvisit( TraitInstType * inst ) {312 assertf( ! options.genC, "Trait types should not reach code generation." );313 typeString = inst->name + " " + typeString;314 handleQualifiers( inst );315 }316 317 void GenType::postvisit( TypeofType * typeof ) {318 std::ostringstream os;319 PassVisitor<CodeGenerator> cg( os, options );320 os << "typeof(";321 typeof->expr->accept( cg );322 os << ") " << typeString;323 typeString = os.str();324 handleQualifiers( typeof );325 }326 327 void GenType::postvisit( VTableType * vtable ) {328 assertf( ! options.genC, "Virtual table types should not reach code generation." );329 std::ostringstream os;330 os << "vtable(" << genType( vtable->base, "", options ) << ") " << typeString;331 typeString = os.str();332 handleQualifiers( vtable );333 }334 335 void GenType::postvisit( QualifiedType * qualType ) {336 assertf( ! options.genC, "Qualified types should not reach code generation." );337 std::ostringstream os;338 os << genType( qualType->parent, "", options ) << "." << genType( qualType->child, "", options ) << typeString;339 typeString = os.str();340 handleQualifiers( qualType );341 }342 343 void GenType::handleQualifiers( Type * type ) {344 if ( type->get_const() ) {345 typeString = "const " + typeString;346 } // if347 if ( type->get_volatile() ) {348 typeString = "volatile " + typeString;349 } // if350 if ( type->get_restrict() ) {351 typeString = "__restrict " + typeString;352 } // if353 if ( type->get_atomic() ) {354 typeString = "_Atomic " + typeString;355 } // if356 }357 27 358 28 namespace { 359 29 360 #warning Remove the _new when old version is removed. 361 struct GenType_new : 30 struct GenType final : 362 31 public ast::WithShortCircuiting, 363 public ast::WithVisitorRef<GenType _new> {32 public ast::WithVisitorRef<GenType> { 364 33 std::string result; 365 GenType _new( const std::string &typeString, const Options &options );34 GenType( const std::string &typeString, const Options &options ); 366 35 367 36 void previsit( ast::Node const * ); … … 397 66 }; 398 67 399 GenType _new::GenType_new( const std::string &typeString, const Options &options ) : result( typeString ), options( options ) {}400 401 void GenType _new::previsit( ast::Node const * ) {68 GenType::GenType( const std::string &typeString, const Options &options ) : result( typeString ), options( options ) {} 69 70 void GenType::previsit( ast::Node const * ) { 402 71 // Turn off automatic recursion for all nodes, to allow each visitor to 403 72 // precisely control the order in which its children are visited. … … 405 74 } 406 75 407 void GenType _new::postvisit( ast::Node const * node ) {76 void GenType::postvisit( ast::Node const * node ) { 408 77 std::stringstream ss; 409 78 ast::print( ss, node ); … … 411 80 } 412 81 413 void GenType _new::postvisit( ast::VoidType const * type ) {82 void GenType::postvisit( ast::VoidType const * type ) { 414 83 result = "void " + result; 415 84 handleQualifiers( type ); 416 85 } 417 86 418 void GenType _new::postvisit( ast::BasicType const * type ) {87 void GenType::postvisit( ast::BasicType const * type ) { 419 88 ast::BasicType::Kind kind = type->kind; 420 89 assert( 0 <= kind && kind < ast::BasicType::NUMBER_OF_BASIC_TYPES ); … … 423 92 } 424 93 425 void GenType _new::genArray( const ast::CV::Qualifiers & qualifiers, ast::Type const * base, ast::Expr const *dimension, bool isVarLen, bool isStatic ) {94 void GenType::genArray( const ast::CV::Qualifiers & qualifiers, ast::Type const * base, ast::Expr const *dimension, bool isVarLen, bool isStatic ) { 426 95 std::ostringstream os; 427 96 if ( result != "" ) { … … 449 118 } 450 119 if ( dimension != 0 ) { 451 ast::Pass<CodeGenerator _new>::read( dimension, os, options );120 ast::Pass<CodeGenerator>::read( dimension, os, options ); 452 121 } else if ( isVarLen ) { 453 122 // no dimension expression on a VLA means it came in with the * token … … 461 130 } 462 131 463 void GenType _new::postvisit( ast::PointerType const * type ) {132 void GenType::postvisit( ast::PointerType const * type ) { 464 133 if ( type->isStatic || type->isVarLen || type->dimension ) { 465 134 genArray( type->qualifiers, type->base, type->dimension, type->isVarLen, type->isStatic ); … … 475 144 } 476 145 477 void GenType _new::postvisit( ast::ArrayType const * type ) {146 void GenType::postvisit( ast::ArrayType const * type ) { 478 147 genArray( type->qualifiers, type->base, type->dimension, type->isVarLen, type->isStatic ); 479 148 } 480 149 481 void GenType _new::postvisit( ast::ReferenceType const * type ) {150 void GenType::postvisit( ast::ReferenceType const * type ) { 482 151 assertf( !options.genC, "Reference types should not reach code generation." ); 483 152 handleQualifiers( type ); … … 486 155 } 487 156 488 void GenType _new::postvisit( ast::FunctionType const * type ) {157 void GenType::postvisit( ast::FunctionType const * type ) { 489 158 std::ostringstream os; 490 159 … … 526 195 //assertf( !options.genC, "FunctionDecl type parameters should not reach code generation." ); 527 196 std::ostringstream os; 528 ast::Pass<CodeGenerator _new> cg( os, options );197 ast::Pass<CodeGenerator> cg( os, options ); 529 198 os << "forall("; 530 199 cg.core.genCommaList( type->forall ); … … 534 203 } 535 204 536 std::string GenType _new::handleGeneric( ast::BaseInstType const * type ) {205 std::string GenType::handleGeneric( ast::BaseInstType const * type ) { 537 206 if ( !type->params.empty() ) { 538 207 std::ostringstream os; 539 ast::Pass<CodeGenerator _new> cg( os, options );208 ast::Pass<CodeGenerator> cg( os, options ); 540 209 os << "("; 541 210 cg.core.genCommaList( type->params ); … … 546 215 } 547 216 548 void GenType _new::postvisit( ast::StructInstType const * type ) {217 void GenType::postvisit( ast::StructInstType const * type ) { 549 218 result = type->name + handleGeneric( type ) + " " + result; 550 219 if ( options.genC ) result = "struct " + result; … … 552 221 } 553 222 554 void GenType _new::postvisit( ast::UnionInstType const * type ) {223 void GenType::postvisit( ast::UnionInstType const * type ) { 555 224 result = type->name + handleGeneric( type ) + " " + result; 556 225 if ( options.genC ) result = "union " + result; … … 558 227 } 559 228 560 void GenType _new::postvisit( ast::EnumInstType const * type ) {229 void GenType::postvisit( ast::EnumInstType const * type ) { 561 230 if ( type->base && type->base->base ) { 562 231 result = genType( type->base->base, result, options ); … … 570 239 } 571 240 572 void GenType _new::postvisit( ast::TypeInstType const * type ) {241 void GenType::postvisit( ast::TypeInstType const * type ) { 573 242 assertf( !options.genC, "TypeInstType should not reach code generation." ); 574 243 result = type->name + " " + result; … … 576 245 } 577 246 578 void GenType _new::postvisit( ast::TupleType const * type ) {247 void GenType::postvisit( ast::TupleType const * type ) { 579 248 assertf( !options.genC, "TupleType should not reach code generation." ); 580 249 unsigned int i = 0; … … 589 258 } 590 259 591 void GenType _new::postvisit( ast::VarArgsType const * type ) {260 void GenType::postvisit( ast::VarArgsType const * type ) { 592 261 result = "__builtin_va_list " + result; 593 262 handleQualifiers( type ); 594 263 } 595 264 596 void GenType _new::postvisit( ast::ZeroType const * type ) {265 void GenType::postvisit( ast::ZeroType const * type ) { 597 266 // Ideally these wouldn't hit codegen at all, but should be safe to make them ints. 598 267 result = (options.pretty ? "zero_t " : "long int ") + result; … … 600 269 } 601 270 602 void GenType _new::postvisit( ast::OneType const * type ) {271 void GenType::postvisit( ast::OneType const * type ) { 603 272 // Ideally these wouldn't hit codegen at all, but should be safe to make them ints. 604 273 result = (options.pretty ? "one_t " : "long int ") + result; … … 606 275 } 607 276 608 void GenType _new::postvisit( ast::GlobalScopeType const * type ) {277 void GenType::postvisit( ast::GlobalScopeType const * type ) { 609 278 assertf( !options.genC, "GlobalScopeType should not reach code generation." ); 610 279 handleQualifiers( type ); 611 280 } 612 281 613 void GenType _new::postvisit( ast::TraitInstType const * type ) {282 void GenType::postvisit( ast::TraitInstType const * type ) { 614 283 assertf( !options.genC, "TraitInstType should not reach code generation." ); 615 284 result = type->name + " " + result; … … 617 286 } 618 287 619 void GenType _new::postvisit( ast::TypeofType const * type ) {288 void GenType::postvisit( ast::TypeofType const * type ) { 620 289 std::ostringstream os; 621 290 os << "typeof("; 622 ast::Pass<CodeGenerator _new>::read( type, os, options );291 ast::Pass<CodeGenerator>::read( type, os, options ); 623 292 os << ") " << result; 624 293 result = os.str(); … … 626 295 } 627 296 628 void GenType _new::postvisit( ast::VTableType const * type ) {297 void GenType::postvisit( ast::VTableType const * type ) { 629 298 assertf( !options.genC, "Virtual table types should not reach code generation." ); 630 299 std::ostringstream os; … … 634 303 } 635 304 636 void GenType _new::postvisit( ast::QualifiedType const * type ) {305 void GenType::postvisit( ast::QualifiedType const * type ) { 637 306 assertf( !options.genC, "QualifiedType should not reach code generation." ); 638 307 std::ostringstream os; … … 642 311 } 643 312 644 void GenType _new::handleQualifiers( ast::Type const * type ) {313 void GenType::handleQualifiers( ast::Type const * type ) { 645 314 if ( type->is_const() ) { 646 315 result = "const " + result; … … 657 326 } 658 327 659 std::string GenType _new::genParamList( const ast::vector<ast::Type> & range ) {328 std::string GenType::genParamList( const ast::vector<ast::Type> & range ) { 660 329 auto cur = range.begin(); 661 330 auto end = range.end(); 662 331 if ( cur == end ) return ""; 663 332 std::ostringstream oss; 664 for ( unsigned int i = 0 ; ; ++i ) { 665 oss << genType( *cur++, "__param_" + std::to_string(i), options ); 333 UniqueName param( "__param_" ); 334 while ( true ) { 335 oss << genType( *cur++, options.genC ? param.newName() : "", options ); 666 336 if ( cur == end ) break; 667 337 oss << ", "; … … 675 345 std::ostringstream os; 676 346 if ( !type->attributes.empty() ) { 677 ast::Pass<CodeGenerator _new> cg( os, options );347 ast::Pass<CodeGenerator> cg( os, options ); 678 348 cg.core.genAttributes( type->attributes ); 679 349 } 680 350 681 return os.str() + ast::Pass<GenType _new>::read( type, base, options );351 return os.str() + ast::Pass<GenType>::read( type, base, options ); 682 352 } 683 353 684 354 std::string genTypeNoAttr( ast::Type const * type, const std::string & base, const Options & options ) { 685 return ast::Pass<GenType _new>::read( type, base, options );355 return ast::Pass<GenType>::read( type, base, options ); 686 356 } 687 357 -
src/CodeGen/Generate.cc
rdf8ba61a r8d182b1 19 19 #include <string> // for operator<< 20 20 21 #include "CodeGeneratorNew.hpp" // for CodeGenerator_new, doSemicolon, ... 22 #include "CodeGenerator.h" // for CodeGenerator, doSemicolon, oper... 21 #include "CodeGeneratorNew.hpp" // for CodeGenerator, doSemicolon, ... 23 22 #include "GenType.h" // for genPrettyType 24 #include "Common/PassVisitor.h" // for PassVisitor25 #include "SynTree/LinkageSpec.h" // for isBuiltin, isGeneratable26 #include "SynTree/BaseSyntaxNode.h" // for BaseSyntaxNode27 #include "SynTree/Declaration.h" // for Declaration28 #include "SynTree/Type.h" // for Type29 23 30 24 using namespace std; 31 25 32 26 namespace CodeGen { 33 namespace {34 /// Removes misc. nodes that should not exist in CodeGen35 struct TreeCleaner {36 void premutate( CompoundStmt * stmt );37 Statement * postmutate( ImplicitCtorDtorStmt * stmt );38 39 static bool shouldClean( Declaration * );40 };41 42 void cleanTree( std::list< Declaration * > & translationUnit ) {43 PassVisitor<TreeCleaner> cleaner;44 filter( translationUnit, [](Declaration * decl) { return TreeCleaner::shouldClean(decl); }, false );45 mutateAll( translationUnit, cleaner );46 } // cleanTree47 } // namespace48 49 void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC, bool lineMarks, bool printExprTypes ) {50 cleanTree( translationUnit );51 52 PassVisitor<CodeGenerator> cgv( os, pretty, generateC, lineMarks, printExprTypes );53 for ( auto & dcl : translationUnit ) {54 if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) {55 cgv.pass.updateLocation( dcl );56 dcl->accept(cgv);57 if ( doSemicolon( dcl ) ) {58 os << ";";59 } // if60 os << cgv.pass.endl;61 } // if62 } // for63 }64 65 void generate( BaseSyntaxNode * node, std::ostream & os ) {66 if ( Type * type = dynamic_cast< Type * >( node ) ) {67 os << genPrettyType( type, "" );68 } else {69 PassVisitor<CodeGenerator> cgv( os, true, false, false, false );70 node->accept( cgv );71 }72 os << std::endl;73 }74 75 namespace {76 void TreeCleaner::premutate( CompoundStmt * cstmt ) {77 filter( cstmt->kids, [](Statement * stmt) {78 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {79 return shouldClean( declStmt->decl );80 }81 return false;82 }, false );83 }84 85 Statement * TreeCleaner::postmutate( ImplicitCtorDtorStmt * stmt ) {86 Statement * callStmt = nullptr;87 std::swap( stmt->callStmt, callStmt );88 delete stmt;89 return callStmt;90 }91 92 bool TreeCleaner::shouldClean( Declaration * decl ) {93 return dynamic_cast< TraitDecl * >( decl );94 }95 } // namespace96 27 97 28 namespace { … … 101 32 102 33 /// Removes various nodes that should not exist in CodeGen. 103 struct TreeCleaner _new{34 struct TreeCleaner final { 104 35 ast::CompoundStmt const * previsit( ast::CompoundStmt const * stmt ) { 105 36 auto mutStmt = ast::mutate( stmt ); … … 120 51 bool pretty, bool generateC, bool lineMarks, bool printExprTypes ) { 121 52 erase_if( translationUnit.decls, shouldClean ); 122 ast::Pass<TreeCleaner _new>::run( translationUnit );53 ast::Pass<TreeCleaner>::run( translationUnit ); 123 54 124 ast::Pass<CodeGenerator _new> cgv( os,55 ast::Pass<CodeGenerator> cgv( os, 125 56 Options( pretty, generateC, lineMarks, printExprTypes ) ); 126 57 for ( auto & decl : translationUnit.decls ) { -
src/CodeGen/Generate.h
rdf8ba61a r8d182b1 17 17 18 18 #include <iostream> // for ostream 19 #include <list> // for list20 21 class BaseSyntaxNode;22 class Declaration;23 19 24 20 namespace ast { … … 27 23 28 24 namespace CodeGen { 29 /// Generates code. doIntrinsics determines if intrinsic functions are printed, pretty formats output nicely (e.g., uses unmangled names, etc.), generateC is true when the output must consist only of C code (allows some assertions, etc.)30 void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC = false , bool lineMarks = false, bool printTypeExpr = false );31 32 /// Generate code for a single node -- helpful for debugging in gdb33 void generate( BaseSyntaxNode * node, std::ostream & os );34 25 35 26 /// Generates all code in transUnit and writing it to the os. -
src/CodeGen/LinkOnce.cc
rdf8ba61a r8d182b1 22 22 #include "AST/Expr.hpp" 23 23 #include "AST/Pass.hpp" 24 #include "Common/PassVisitor.h" // for PassVisitor, WithShortCircuiting25 24 26 25 namespace CodeGen { 27 26 28 27 namespace { 29 30 bool is_cfa_linkonce_old( Attribute const * attr ) {31 return std::string("cfa_linkonce") == attr->name;32 }33 34 bool is_section_attribute_old( Attribute const * attr ) {35 return std::string("section") == attr->name;36 }37 38 class LinkOnceVisitorCore : public WithShortCircuiting {39 public:40 void previsit( Declaration * ) {41 visit_children = false;42 }43 44 void previsit( DeclarationWithType * decl ) {45 std::list< Attribute * > & attributes = decl->attributes;46 // See if we can find the element:47 auto found = std::find_if(attributes.begin(), attributes.end(), is_cfa_linkonce_old );48 if ( attributes.end() != found ) {49 // Remove any other sections:50 attributes.remove_if( is_section_attribute_old );51 // Iterator to the cfa_linkonce attribute should still be valid.52 Attribute * attribute = *found;53 assert( attribute->parameters.empty() );54 assert( !decl->mangleName.empty() );55 // Overwrite the attribute in place.56 const std::string section_name = ".gnu.linkonce." + decl->mangleName;57 attribute->name = "section";58 attribute->parameters.push_back(59 new ConstantExpr( Constant::from_string( section_name ) )60 );61 62 // Unconditionnaly add "visibility(default)" to anything with gnu.linkonce63 // visibility is a mess otherwise64 attributes.push_back(new Attribute("visibility", {new ConstantExpr( Constant::from_string( "default" ) )}));65 66 }67 visit_children = false;68 }69 };70 28 71 29 bool is_cfa_linkonce( ast::Attribute const * attr ) { … … 122 80 } // namespace 123 81 124 void translateLinkOnce( std::list< Declaration *> & translationUnit ) {125 PassVisitor<LinkOnceVisitorCore> translator;126 acceptAll( translationUnit, translator );127 }128 129 82 void translateLinkOnce( ast::TranslationUnit & translationUnit ) { 130 83 ast::Pass<LinkOnceCore>::run( translationUnit ); -
src/CodeGen/LinkOnce.h
rdf8ba61a r8d182b1 20 20 // for now its almost the only attribute we handle. 21 21 22 #include <list> // for list23 22 24 class Declaration;25 23 namespace ast { 26 24 class TranslationUnit; … … 29 27 namespace CodeGen { 30 28 31 void translateLinkOnce( std::list< Declaration *> & translationUnit );32 29 void translateLinkOnce( ast::TranslationUnit & translationUnit ); 33 30 /* Convert the cfa_linkonce attribute on top level declaration into -
src/CodeGen/module.mk
rdf8ba61a r8d182b1 16 16 17 17 SRC_CODEGEN = \ 18 CodeGen/FixMain2.cc \ 19 CodeGen/FixMain.h \ 18 CodeGen/CodeGeneratorNew.cpp \ 19 CodeGen/CodeGeneratorNew.hpp \ 20 CodeGen/GenType.cc \ 21 CodeGen/GenType.h \ 20 22 CodeGen/OperatorTable.cc \ 21 23 CodeGen/OperatorTable.h 22 24 23 25 SRC += $(SRC_CODEGEN) \ 24 CodeGen/CodeGenerator.cc \25 CodeGen/CodeGenerator.h \26 CodeGen/CodeGeneratorNew.cpp \27 CodeGen/CodeGeneratorNew.hpp \28 26 CodeGen/Generate.cc \ 29 27 CodeGen/Generate.h \ 30 28 CodeGen/FixMain.cc \ 29 CodeGen/FixMain.h \ 31 30 CodeGen/FixNames.cc \ 32 31 CodeGen/FixNames.h \ 33 CodeGen/GenType.cc \34 CodeGen/GenType.h \35 32 CodeGen/LinkOnce.cc \ 36 33 CodeGen/LinkOnce.h \
Note:
See TracChangeset
for help on using the changeset viewer.