Changes in src/CodeGen/FixMain.cc [61efa42:bef4f1a]
- File:
-
- 1 edited
-
src/CodeGen/FixMain.cc (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/FixMain.cc
r61efa42 rbef4f1a 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // FixMain.cc -- Tools to change a Cforall main into a C main.7 // FixMain.cc -- 8 8 // 9 9 // Author : Thierry Delisle … … 25 25 #include "AST/Type.hpp" 26 26 #include "AST/Vector.hpp" 27 #include "Common/PassVisitor.h" 27 28 #include "Common/SemanticError.h" // for SemanticError 28 29 #include "CodeGen/GenType.h" // for GenType 30 #include "SynTree/Declaration.h" // for FunctionDecl, operator<< 31 #include "SynTree/Type.h" // for FunctionType 29 32 #include "SymTab/Mangler.h" 30 33 … … 33 36 namespace { 34 37 35 struct FindMainCore final { 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 { 36 52 ast::FunctionDecl const * main_declaration = nullptr; 37 53 38 54 void previsit( ast::FunctionDecl const * decl ) { 39 if ( isMain( decl ) ) {55 if ( FixMain::isMain( decl ) ) { 40 56 if ( main_declaration ) { 41 57 SemanticError( decl, "Multiple definition of main routine\n" ); … … 49 65 return genType( types[at], "", Options( false, false, false, false ) ); 50 66 } 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 { 51 102 52 103 ast::ObjectDecl * makeIntObj(){ … … 106 157 } 107 158 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 118 159 } // namespace 119 160 120 bool isMain( const ast::FunctionDecl * decl ) {161 bool FixMain::isMain( FunctionDecl * decl ) { 121 162 if ( std::string("main") != decl->name ) { 122 163 return false; 123 164 } 165 return is_main( SymTab::Mangler::mangle( decl, true, true ) ); 166 } 167 168 bool FixMain::isMain( const ast::FunctionDecl * decl ) { 169 if ( std::string("main") != decl->name ) { 170 return false; 171 } 124 172 return is_main( Mangle::mangle( decl, Mangle::Type ) ); 125 173 } 126 174 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, 175 void FixMain::fix( ast::TranslationUnit & translationUnit, 135 176 std::ostream &os, const char * bootloader_filename ) { 136 177 137 ast::Pass<FindMainCore > main_finder;178 ast::Pass<FindMainCore_new> main_finder; 138 179 ast::accept_all( translationUnit, main_finder ); 139 180 if ( nullptr == main_finder.core.main_declaration ) return;
Note:
See TracChangeset
for help on using the changeset viewer.