Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/FixMain.cc

    r61efa42 rbef4f1a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FixMain.cc -- Tools to change a Cforall main into a C main.
     7// FixMain.cc --
    88//
    99// Author           : Thierry Delisle
     
    2525#include "AST/Type.hpp"
    2626#include "AST/Vector.hpp"
     27#include "Common/PassVisitor.h"
    2728#include "Common/SemanticError.h"  // for SemanticError
    2829#include "CodeGen/GenType.h"       // for GenType
     30#include "SynTree/Declaration.h"   // for FunctionDecl, operator<<
     31#include "SynTree/Type.h"          // for FunctionType
    2932#include "SymTab/Mangler.h"
    3033
     
    3336namespace {
    3437
    35 struct FindMainCore final {
     38struct 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
     51struct FindMainCore_new {
    3652        ast::FunctionDecl const * main_declaration = nullptr;
    3753
    3854        void previsit( ast::FunctionDecl const * decl ) {
    39                 if ( isMain( decl ) ) {
     55                if ( FixMain::isMain( decl ) ) {
    4056                        if ( main_declaration ) {
    4157                                SemanticError( decl, "Multiple definition of main routine\n" );
     
    4965        return genType( types[at], "", Options( false, false, false, false ) );
    5066}
     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
     101namespace {
    51102
    52103ast::ObjectDecl * makeIntObj(){
     
    106157}
    107158
    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 
    118159} // namespace
    119160
    120 bool isMain( const ast::FunctionDecl * decl ) {
     161bool FixMain::isMain( FunctionDecl * decl ) {
    121162        if ( std::string("main") != decl->name ) {
    122163                return false;
    123164        }
     165        return is_main( SymTab::Mangler::mangle( decl, true, true ) );
     166}
     167
     168bool FixMain::isMain( const ast::FunctionDecl * decl ) {
     169        if ( std::string("main") != decl->name ) {
     170                return false;
     171        }
    124172        return is_main( Mangle::mangle( decl, Mangle::Type ) );
    125173}
    126174
    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,
     175void FixMain::fix( ast::TranslationUnit & translationUnit,
    135176                std::ostream &os, const char * bootloader_filename ) {
    136177
    137         ast::Pass<FindMainCore> main_finder;
     178        ast::Pass<FindMainCore_new> main_finder;
    138179        ast::accept_all( translationUnit, main_finder );
    139180        if ( nullptr == main_finder.core.main_declaration ) return;
Note: See TracChangeset for help on using the changeset viewer.