Changes in src/CodeGen/FixMain.cc [9939dc3:61efa42]
- File:
-
- 1 edited
-
src/CodeGen/FixMain.cc (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/FixMain.cc
r9939dc3 r61efa42 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 … … 13 13 // Update Count : 0 14 14 // 15 16 15 17 16 #include "FixMain.h" … … 23 22 24 23 #include "AST/Decl.hpp" 24 #include "AST/Pass.hpp" 25 25 #include "AST/Type.hpp" 26 #include " Common/PassVisitor.h"26 #include "AST/Vector.hpp" 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 FunctionType31 29 #include "SymTab/Mangler.h" 32 30 … … 35 33 namespace { 36 34 37 struct FindMainCore {38 FunctionDecl * main_signature= nullptr;35 struct FindMainCore final { 36 ast::FunctionDecl const * main_declaration = nullptr; 39 37 40 void previsit( FunctionDecl* decl ) {41 if ( FixMain::isMain( decl ) ) {42 if ( main_ signature) {38 void previsit( ast::FunctionDecl const * decl ) { 39 if ( isMain( decl ) ) { 40 if ( main_declaration ) { 43 41 SemanticError( decl, "Multiple definition of main routine\n" ); 44 42 } 45 main_ signature= decl;43 main_declaration = decl; 46 44 } 47 45 } 48 46 }; 49 47 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 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 ); 52 ast::ObjectDecl * makeIntObj(){ 53 return new ast::ObjectDecl( CodeLocation(), "", 54 new ast::BasicType( ast::BasicType::SignedInt ) ); 89 55 } 90 56 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 ); 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 ) ) ) ); 98 62 } 99 63 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() ); 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() ); 105 81 } 106 82 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 ); 83 std::string getMangledNameOf0ParameterMain() { 84 return getMangledNameOfMain( {}, ast::VariableArgs ); 111 85 } 112 86 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 ); 87 std::string getMangledNameOf2ParameterMain() { 88 return getMangledNameOfMain( { 89 makeIntObj(), 90 makeCharStarStarObj(), 91 }, ast::FixedArgs ); 119 92 } 120 93 … … 122 95 // This breaks if you move it out of the function. 123 96 static const std::string mangled_mains[] = { 124 mangled_0_argument_main(),125 mangled_2_argument_main(),126 // mangled_3_argument_main(),97 getMangledNameOf0ParameterMain(), 98 getMangledNameOf2ParameterMain(), 99 //getMangledNameOf3ParameterMain(), 127 100 }; 128 101 … … 133 106 } 134 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 135 118 } // namespace 136 119 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 ) { 120 bool isMain( const ast::FunctionDecl * decl ) { 145 121 if ( std::string("main") != decl->name ) { 146 122 return false; … … 149 125 } 150 126 151 }; 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
Note:
See TracChangeset
for help on using the changeset viewer.