Changes in src/CodeGen/FixMain.cc [61efa42:9939dc3]
- File:
-
- 1 edited
-
src/CodeGen/FixMain.cc (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/FixMain.cc
r61efa42 r9939dc3 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 … … 13 13 // Update Count : 0 14 14 // 15 15 16 16 17 #include "FixMain.h" … … 22 23 23 24 #include "AST/Decl.hpp" 24 #include "AST/Pass.hpp"25 25 #include "AST/Type.hpp" 26 #include " AST/Vector.hpp"26 #include "Common/PassVisitor.h" 27 27 #include "Common/SemanticError.h" // for SemanticError 28 28 #include "CodeGen/GenType.h" // for GenType 29 #include "SynTree/Declaration.h" // for FunctionDecl, operator<< 30 #include "SynTree/Type.h" // for FunctionType 29 31 #include "SymTab/Mangler.h" 30 32 … … 33 35 namespace { 34 36 35 struct FindMainCore final{36 ast::FunctionDecl const * main_declaration= nullptr;37 struct FindMainCore { 38 FunctionDecl * main_signature = nullptr; 37 39 38 void previsit( ast::FunctionDecl const* decl ) {39 if ( isMain( decl ) ) {40 if ( main_ declaration) {40 void previsit( FunctionDecl * decl ) { 41 if ( FixMain::isMain( decl ) ) { 42 if ( main_signature ) { 41 43 SemanticError( decl, "Multiple definition of main routine\n" ); 42 44 } 43 main_ declaration= decl;45 main_signature = decl; 44 46 } 45 47 } 46 48 }; 47 49 48 std::string genTypeAt( const ast::vector<ast::Type> & types, size_t at ) {49 return genType( types[at], "", Options( false, false, false, false ) );50 50 } 51 51 52 ast::ObjectDecl * makeIntObj(){ 53 return new ast::ObjectDecl( CodeLocation(), "", 54 new ast::BasicType( ast::BasicType::SignedInt ) ); 52 template<typename container> 53 std::string genTypeAt(const container& p, size_t idx) { 54 return genType((*std::next(p.begin(), idx))->get_type(), ""); 55 } 56 57 void FixMain::fix( std::list< Declaration * > & translationUnit, 58 std::ostream &os, const char* bootloader_filename ) { 59 PassVisitor< FindMainCore > main_finder; 60 acceptAll( translationUnit, main_finder ); 61 FunctionDecl * main_signature = main_finder.pass.main_signature; 62 63 if( main_signature ) { 64 os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return "; 65 main_signature->mangleName = SymTab::Mangler::mangle(main_signature); 66 67 os << main_signature->get_scopedMangleName() << "("; 68 const auto& params = main_signature->get_functionType()->get_parameters(); 69 switch(params.size()) { 70 case 3: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv, (" << genTypeAt(params, 2) << ")envp"; break; 71 case 2: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv"; break; 72 case 0: break; 73 default : assert(false); 74 } 75 os << "); }\n"; 76 77 std::ifstream bootloader(bootloader_filename, std::ios::in); 78 assertf( bootloader.is_open(), "cannot open bootloader.c\n" ); 79 os << bootloader.rdbuf(); 80 } 81 } 82 83 namespace { 84 85 ObjectDecl * signedIntObj() { 86 return new ObjectDecl( 87 "", Type::StorageClasses(), LinkageSpec::Cforall, 0, 88 new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ); 55 89 } 56 90 57 ast::ObjectDecl * makeCharStarStarObj() { 58 return new ast::ObjectDecl( CodeLocation(), "", 59 new ast::PointerType( 60 new ast::PointerType( 61 new ast::BasicType( ast::BasicType::Char ) ) ) ); 91 ObjectDecl * makeArgvObj() { 92 return new ObjectDecl( 93 "", Type::StorageClasses(), LinkageSpec::Cforall, 0, 94 new PointerType( Type::Qualifiers(), 95 new PointerType( Type::Qualifiers(), 96 new BasicType( Type::Qualifiers(), BasicType::Char ) ) ), 97 nullptr ); 62 98 } 63 99 64 std::string getMangledNameOfMain( 65 ast::vector<ast::DeclWithType> && params, ast::ArgumentFlag isVarArgs ) { 66 ast::ptr<ast::FunctionDecl> decl = new ast::FunctionDecl( 67 CodeLocation(), 68 "main", 69 ast::vector<ast::TypeDecl>(), 70 ast::vector<ast::DeclWithType>(), 71 std::move( params ), 72 { makeIntObj() }, 73 nullptr, 74 ast::Storage::Classes(), 75 ast::Linkage::Spec(), 76 ast::vector<ast::Attribute>(), 77 ast::Function::Specs(), 78 isVarArgs 79 ); 80 return Mangle::mangle( decl.get() ); 100 std::string create_mangled_main_function_name( FunctionType * function_type ) { 101 std::unique_ptr<FunctionDecl> decl( new FunctionDecl( 102 "main", Type::StorageClasses(), LinkageSpec::Cforall, 103 function_type, nullptr ) ); 104 return SymTab::Mangler::mangle( decl.get() ); 81 105 } 82 106 83 std::string getMangledNameOf0ParameterMain() { 84 return getMangledNameOfMain( {}, ast::VariableArgs ); 107 std::string mangled_0_argument_main() { 108 FunctionType* main_type = new FunctionType( Type::Qualifiers(), true ); 109 main_type->get_returnVals().push_back( signedIntObj() ); 110 return create_mangled_main_function_name( main_type ); 85 111 } 86 112 87 std::string getMangledNameOf2ParameterMain() { 88 return getMangledNameOfMain( { 89 makeIntObj(), 90 makeCharStarStarObj(), 91 }, ast::FixedArgs ); 113 std::string mangled_2_argument_main() { 114 FunctionType* main_type = new FunctionType( Type::Qualifiers(), false ); 115 main_type->get_returnVals().push_back( signedIntObj() ); 116 main_type->get_parameters().push_back( signedIntObj() ); 117 main_type->get_parameters().push_back( makeArgvObj() ); 118 return create_mangled_main_function_name( main_type ); 92 119 } 93 120 … … 95 122 // This breaks if you move it out of the function. 96 123 static const std::string mangled_mains[] = { 97 getMangledNameOf0ParameterMain(),98 getMangledNameOf2ParameterMain(),99 // getMangledNameOf3ParameterMain(),124 mangled_0_argument_main(), 125 mangled_2_argument_main(), 126 //mangled_3_argument_main(), 100 127 }; 101 128 … … 106 133 } 107 134 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 135 } // namespace 119 136 120 bool isMain( const ast::FunctionDecl * decl ) { 137 bool FixMain::isMain( FunctionDecl * decl ) { 138 if ( std::string("main") != decl->name ) { 139 return false; 140 } 141 return is_main( SymTab::Mangler::mangle( decl, true, true ) ); 142 } 143 144 bool FixMain::isMain( const ast::FunctionDecl * decl ) { 121 145 if ( std::string("main") != decl->name ) { 122 146 return false; … … 125 149 } 126 150 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, 135 std::ostream &os, const char * bootloader_filename ) { 136 137 ast::Pass<FindMainCore> main_finder; 138 ast::accept_all( translationUnit, main_finder ); 139 if ( nullptr == main_finder.core.main_declaration ) return; 140 141 ast::FunctionDecl * main_declaration = 142 ast::mutate( main_finder.core.main_declaration ); 143 144 main_declaration->mangleName = Mangle::mangle( main_declaration ); 145 146 os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return "; 147 os << main_declaration->scopedMangleName() << "("; 148 const auto& params = main_declaration->type->params; 149 switch ( params.size() ) { 150 case 3: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv, (" << genTypeAt(params, 2) << ")envp"; break; 151 case 2: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv"; break; 152 case 0: break; 153 default : assert(false); 154 } 155 os << "); }\n"; 156 157 std::ifstream bootloader( bootloader_filename, std::ios::in ); 158 assertf( bootloader.is_open(), "cannot open bootloader.c\n" ); 159 os << bootloader.rdbuf(); 160 } 161 162 } // namespace CodeGen 151 };
Note:
See TracChangeset
for help on using the changeset viewer.