Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/FixMain.cc

    r8e48fca4 r16ba4a6f  
    2222#include <string>                  // for operator<<
    2323
    24 #include "AST/Decl.hpp"
    25 #include "AST/Type.hpp"
    26 #include "Common/PassVisitor.h"
    2724#include "Common/SemanticError.h"  // for SemanticError
    2825#include "CodeGen/GenType.h"       // for GenType
     
    3229
    3330namespace 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 
    5231        bool FixMain::replace_main = false;
     32        std::unique_ptr<FunctionDecl> FixMain::main_signature = nullptr;
    5333
    5434        template<typename container>
     
    5737        }
    5838
    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;
     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        }
    6446
     47        void FixMain::fix(std::ostream &os, const char* bootloader_filename) {
    6548                if( main_signature ) {
    6649                        os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return ";
    67                         main_signature->mangleName = SymTab::Mangler::mangle(main_signature);
     50                        main_signature->mangleName = SymTab::Mangler::mangle(main_signature.get());
    6851
    6952                        os << main_signature->get_scopedMangleName() << "(";
     
    8265                }
    8366        }
    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 
    15367};
Note: See TracChangeset for help on using the changeset viewer.