- Timestamp:
- Oct 29, 2021, 5:24:56 PM (4 years ago)
- Branches:
- ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
- Children:
- a7026b4
- Parents:
- 42b7fa5f (diff), 8e48fca4 (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
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/FixMain.cc
r42b7fa5f re58e423 22 22 #include <string> // for operator<< 23 23 24 #include "AST/Decl.hpp" 25 #include "AST/Type.hpp" 26 #include "Common/PassVisitor.h" 24 27 #include "Common/SemanticError.h" // for SemanticError 25 28 #include "CodeGen/GenType.h" // for GenType … … 29 32 30 33 namespace CodeGen { 34 35 namespace { 36 37 struct FindMainCore { 38 FunctionDecl * main_signature = nullptr; 39 40 void previsit( FunctionDecl * decl ) { 41 if ( FixMain::isMain( decl ) ) { 42 if ( main_signature ) { 43 SemanticError( decl, "Multiple definition of main routine\n" ); 44 } 45 main_signature = decl; 46 } 47 } 48 }; 49 50 } 51 31 52 bool FixMain::replace_main = false; 32 std::unique_ptr<FunctionDecl> FixMain::main_signature = nullptr;33 53 34 54 template<typename container> … … 37 57 } 38 58 39 void FixMain::registerMain(FunctionDecl* functionDecl) 40 { 41 if(main_signature) { 42 SemanticError(functionDecl, "Multiple definition of main routine\n"); 43 } 44 main_signature.reset( functionDecl->clone() ); 45 } 59 void FixMain::fix( std::list< Declaration * > & translationUnit, 60 std::ostream &os, const char* bootloader_filename ) { 61 PassVisitor< FindMainCore > main_finder; 62 acceptAll( translationUnit, main_finder ); 63 FunctionDecl * main_signature = main_finder.pass.main_signature; 46 64 47 void FixMain::fix(std::ostream &os, const char* bootloader_filename) {48 65 if( main_signature ) { 49 66 os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return "; 50 main_signature->mangleName = SymTab::Mangler::mangle(main_signature .get());67 main_signature->mangleName = SymTab::Mangler::mangle(main_signature); 51 68 52 69 os << main_signature->get_scopedMangleName() << "("; … … 65 82 } 66 83 } 84 85 namespace { 86 87 ObjectDecl * signedIntObj() { 88 return new ObjectDecl( 89 "", Type::StorageClasses(), LinkageSpec::Cforall, 0, 90 new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ); 91 } 92 93 ObjectDecl * charStarObj() { 94 return new ObjectDecl( 95 "", Type::StorageClasses(), LinkageSpec::Cforall, 0, 96 new PointerType( Type::Qualifiers(), 97 new PointerType( Type::Qualifiers(), 98 new BasicType( Type::Qualifiers(), BasicType::Char ) ) ), 99 nullptr ); 100 } 101 102 std::string create_mangled_main_function_name( FunctionType * function_type ) { 103 std::unique_ptr<FunctionDecl> decl( new FunctionDecl( 104 "main", Type::StorageClasses(), LinkageSpec::Cforall, 105 function_type, nullptr ) ); 106 return SymTab::Mangler::mangle( decl.get() ); 107 } 108 109 std::string mangled_0_argument_main() { 110 FunctionType* main_type = new FunctionType( Type::Qualifiers(), true ); 111 main_type->get_returnVals().push_back( signedIntObj() ); 112 return create_mangled_main_function_name( main_type ); 113 } 114 115 std::string mangled_2_argument_main() { 116 FunctionType* main_type = new FunctionType( Type::Qualifiers(), false ); 117 main_type->get_returnVals().push_back( signedIntObj() ); 118 main_type->get_parameters().push_back( signedIntObj() ); 119 main_type->get_parameters().push_back( charStarObj() ); 120 return create_mangled_main_function_name( main_type ); 121 } 122 123 bool is_main( const std::string & mangled_name ) { 124 // This breaks if you move it out of the function. 125 static const std::string mangled_mains[] = { 126 mangled_0_argument_main(), 127 mangled_2_argument_main(), 128 //mangled_3_argument_main(), 129 }; 130 131 for ( auto main_name : mangled_mains ) { 132 if ( main_name == mangled_name ) return true; 133 } 134 return false; 135 } 136 137 } // namespace 138 139 bool FixMain::isMain( FunctionDecl * decl ) { 140 if ( std::string("main") != decl->name ) { 141 return false; 142 } 143 return is_main( SymTab::Mangler::mangle( decl, true, true ) ); 144 } 145 146 bool FixMain::isMain( const ast::FunctionDecl * decl ) { 147 if ( std::string("main") != decl->name ) { 148 return false; 149 } 150 return is_main( Mangle::mangle( decl, Mangle::Type ) ); 151 } 152 67 153 }; -
src/CodeGen/FixMain.h
r42b7fa5f re58e423 9 9 // Author : Thierry Delisle 10 10 // Created On : Thr Jan 12 14:11:09 2017 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sun Feb 16 03:24:32 202013 // Update Count : 511 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 29 16:20:00 2021 13 // Update Count : 8 14 14 // 15 15 … … 18 18 #include <iosfwd> 19 19 #include <memory> 20 #include <list> 20 21 21 22 #include "SynTree/LinkageSpec.h" 22 23 24 class Declaration; 23 25 class FunctionDecl; 26 namespace ast { 27 class FunctionDecl; 28 } 24 29 25 30 namespace CodeGen { 26 class FixMain {27 public :28 static inline LinkageSpec::Spec mainLinkage() {29 return replace_main ? LinkageSpec::Cforall : LinkageSpec::C;30 }31 32 static inline void setReplaceMain(bool val) {33 replace_main = val;34 }35 31 36 static void registerMain(FunctionDecl* val); 32 class FixMain { 33 public : 34 static inline LinkageSpec::Spec mainLinkage() { 35 return replace_main ? LinkageSpec::Cforall : LinkageSpec::C; 36 } 37 37 38 static void fix(std::ostream &os, const char* bootloader_filename); 38 static inline void setReplaceMain(bool val) { 39 replace_main = val; 40 } 39 41 40 private: 41 static bool replace_main; 42 static std::unique_ptr<FunctionDecl> main_signature; 43 }; 42 static bool isMain(FunctionDecl* decl); 43 static bool isMain(const ast::FunctionDecl * decl); 44 45 static void fix( std::list< Declaration * > & decls, 46 std::ostream &os, const char* bootloader_filename ); 47 48 private: 49 static bool replace_main; 50 }; 51 44 52 } // namespace CodeGen -
src/CodeGen/FixNames.cc
r42b7fa5f re58e423 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Dec 13 23:39:14 201913 // Update Count : 2 111 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 29 15:49:00 2021 13 // Update Count : 23 14 14 // 15 15 … … 19 19 #include <string> // for string, operator!=, operator== 20 20 21 #include "AST/Chain.hpp" 22 #include "AST/Expr.hpp" 23 #include "AST/Pass.hpp" 21 24 #include "Common/PassVisitor.h" 22 25 #include "Common/SemanticError.h" // for SemanticError … … 46 49 }; 47 50 48 std::string mangle_main() {49 FunctionType* main_type;50 std::unique_ptr<FunctionDecl> mainDecl { new FunctionDecl( "main", Type::StorageClasses(), LinkageSpec::Cforall,51 main_type = new FunctionType( Type::Qualifiers(), true ), nullptr )52 };53 main_type->get_returnVals().push_back(54 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr )55 );56 57 auto && name = SymTab::Mangler::mangle( mainDecl.get() );58 // std::cerr << name << std::endl;59 return std::move(name);60 }61 std::string mangle_main_args() {62 FunctionType* main_type;63 std::unique_ptr<FunctionDecl> mainDecl { new FunctionDecl( "main", Type::StorageClasses(), LinkageSpec::Cforall,64 main_type = new FunctionType( Type::Qualifiers(), false ), nullptr )65 };66 main_type->get_returnVals().push_back(67 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr )68 );69 70 main_type->get_parameters().push_back(71 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr )72 );73 74 main_type->get_parameters().push_back(75 new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0,76 new PointerType( Type::Qualifiers(), new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Char ) ) ),77 nullptr )78 );79 80 auto&& name = SymTab::Mangler::mangle( mainDecl.get() );81 // std::cerr << name << std::endl;82 return std::move(name);83 }84 85 bool is_main(const std::string& name) {86 static std::string mains[] = {87 mangle_main(),88 mangle_main_args()89 };90 91 for(const auto& m : mains) {92 if( name == m ) return true;93 }94 return false;95 }96 97 51 void fixNames( std::list< Declaration* > & translationUnit ) { 98 52 PassVisitor<FixNames> fixer; … … 118 72 fixDWT( functionDecl ); 119 73 120 if (is_main( SymTab::Mangler::mangle(functionDecl, true, true) )) {74 if ( FixMain::isMain( functionDecl ) ) { 121 75 int nargs = functionDecl->get_functionType()->get_parameters().size(); 122 76 if( !(nargs == 0 || nargs == 2 || nargs == 3) ) { … … 124 78 } 125 79 functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( new ConstantExpr( Constant::from_int( 0 ) ) ) ); 126 CodeGen::FixMain::registerMain( functionDecl );127 80 } 128 81 } … … 132 85 GuardAction( [this](){ scopeLevel--; } ); 133 86 } 87 88 /// Does work with the main function and scopeLevels. 89 class FixNames_new : public ast::WithGuards { 90 int scopeLevel = 1; 91 92 bool shouldSetScopeLevel( const ast::DeclWithType * dwt ) { 93 return !dwt->name.empty() && dwt->linkage.is_mangled 94 && dwt->scopeLevel != scopeLevel; 95 } 96 public: 97 const ast::ObjectDecl *postvisit( const ast::ObjectDecl *objectDecl ) { 98 if ( shouldSetScopeLevel( objectDecl ) ) { 99 return ast::mutate_field( objectDecl, &ast::ObjectDecl::scopeLevel, scopeLevel ); 100 } 101 return objectDecl; 102 } 103 104 const ast::FunctionDecl *postvisit( const ast::FunctionDecl *functionDecl ) { 105 // This store is used to ensure a maximum of one call to mutate. 106 ast::FunctionDecl * mutDecl = nullptr; 107 108 if ( shouldSetScopeLevel( functionDecl ) ) { 109 mutDecl = ast::mutate( functionDecl ); 110 mutDecl->scopeLevel = scopeLevel; 111 } 112 113 if ( FixMain::isMain( functionDecl ) ) { 114 if ( !mutDecl ) { mutDecl = ast::mutate( functionDecl ); } 115 116 int nargs = mutDecl->params.size(); 117 if ( 0 != nargs && 2 != nargs && 3 != nargs ) { 118 SemanticError( functionDecl, "Main expected to have 0, 2 or 3 arguments\n" ); 119 } 120 ast::chain_mutate( mutDecl->stmts )->kids.push_back( 121 new ast::ReturnStmt( 122 mutDecl->location, 123 ast::ConstantExpr::from_int( mutDecl->location, 0 ) 124 ) 125 ); 126 } 127 return mutDecl ? mutDecl : functionDecl; 128 } 129 130 void previsit( const ast::CompoundStmt * ) { 131 GuardValue( scopeLevel ) += 1; 132 } 133 }; 134 135 void fixNames( ast::TranslationUnit & translationUnit ) { 136 ast::Pass<FixNames_new>::run( translationUnit ); 137 } 138 134 139 } // namespace CodeGen 135 140 -
src/CodeGen/FixNames.h
r42b7fa5f re58e423 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Jul 21 22:17:33 201713 // Update Count : 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Oct 26 13:47:00 2021 13 // Update Count : 4 14 14 // 15 15 … … 19 19 20 20 class Declaration; 21 namespace ast { 22 struct TranslationUnit; 23 } 21 24 22 25 namespace CodeGen { 23 26 /// mangles object and function names 24 27 void fixNames( std::list< Declaration* > & translationUnit ); 28 void fixNames( ast::TranslationUnit & translationUnit ); 25 29 } // namespace CodeGen 26 30 -
src/main.cc
r42b7fa5f re58e423 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 2 2 16:06:00 202113 // Update Count : 65 312 // Last Modified On : Fri Oct 29 16:34:00 2021 13 // Update Count : 655 14 14 // 15 15 … … 335 335 PASS( "Translate Throws", ControlStruct::translateThrows( translationUnit ) ); 336 336 PASS( "Fix Labels", ControlStruct::fixLabels( translationUnit ) ); 337 PASS( "Fix Names", CodeGen::fixNames( translationUnit ) );338 337 339 338 CodeTools::fillLocations( translationUnit ); … … 348 347 forceFillCodeLocations( transUnit ); 349 348 349 PASS( "Fix Names", CodeGen::fixNames( transUnit ) ); 350 350 PASS( "Gen Init", InitTweak::genInit( transUnit ) ); 351 351 PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( transUnit ) ); … … 383 383 translationUnit = convert( move( transUnit ) ); 384 384 } else { 385 PASS( "Fix Names", CodeGen::fixNames( translationUnit ) ); 385 386 PASS( "Gen Init", InitTweak::genInit( translationUnit ) ); 386 387 PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( translationUnit ) ); … … 471 472 PASS( "Code Gen", CodeGen::generate( translationUnit, *output, ! genproto, prettycodegenp, true, linemarks ) ); 472 473 473 CodeGen::FixMain::fix( *output, (PreludeDirector + "/bootloader.c").c_str() ); 474 CodeGen::FixMain::fix( translationUnit, *output, 475 (PreludeDirector + "/bootloader.c").c_str() ); 474 476 if ( output != &cout ) { 475 477 delete output;
Note:
See TracChangeset
for help on using the changeset viewer.