Changeset 13de47bc


Ignore:
Timestamp:
Jan 12, 2017, 3:28:29 PM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
aaa1a99a
Parents:
7cc2c8d
Message:

Proper bootloader boilerplate implemented

Location:
src
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/FixMain.cc

    r7cc2c8d r13de47bc  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// FixMain.cc --
     8//
     9// Author           : Thierry Delisle
     10// Created On       : Thr Jan 12 14:11:09 2017
     11// Last Modified By :
     12// Last Modified On :
     13// Update Count     : 0
     14//
    115
     16
     17#include "FixMain.h"   
     18
     19#include <fstream>
     20#include <iostream>
     21
     22#include "Common/SemanticError.h"
     23#include "SynTree/Declaration.h"
     24
     25namespace CodeGen {
     26        bool FixMain::replace_main = false;
     27        std::unique_ptr<FunctionDecl> FixMain::main_signature = nullptr;
     28       
     29        void FixMain::registerMain(FunctionDecl* functionDecl)
     30        {
     31                if(main_signature) {
     32                        throw SemanticError("Multiple definition of main routine\n", functionDecl);
     33                }
     34                main_signature.reset( functionDecl->clone() );
     35        }
     36
     37        void FixMain::fix(std::ostream &os, const char* bootloader_filename) {
     38                if( main_signature ) {
     39                        os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return ";
     40
     41                        os << main_signature->get_scopedMangleName() << "(";
     42                        switch(main_signature->get_functionType()->get_parameters().size()) {
     43                                case 3: os << "argc, argv, envp"; break;
     44                                case 2: os << "argc, argv"; break;
     45                                case 0: break;
     46                                default : assert(false);
     47                        }
     48                        os << "); }\n";
     49
     50                        std::ifstream bootloader(bootloader_filename, std::ios::in);
     51                        assertf( bootloader.is_open(), "cannot open bootloader.c\n" );
     52                        os << bootloader.rdbuf();
     53                }
     54        }
     55};
  • src/CodeGen/FixNames.cc

    r7cc2c8d r13de47bc  
    2222#include "SymTab/Mangler.h"
    2323#include "OperatorTable.h"
    24 
    25 extern std::unique_ptr<FunctionDecl> translation_unit_main_signature;
     24#include "FixMain.h"
    2625
    2726namespace CodeGen {
     
    119118
    120119                if(is_main( SymTab::Mangler::mangle(functionDecl, true, true) )) {
    121                         if(translation_unit_main_signature) {
    122                                 throw SemanticError("Multiple definition of main routine\n", functionDecl);
     120                        int nargs = functionDecl->get_functionType()->get_parameters().size();
     121                        if( !(nargs == 0 || nargs == 2 || nargs == 3) ) {
     122                                throw SemanticError("Main expected to have 0, 2 or 3 arguments\n", main_signature.get());
    123123                        }
    124 
    125124                        functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), "0") ) ) );
    126                         translation_unit_main_signature.reset( functionDecl->clone() );
     125                        CodeGen::FixMain::registerMain( functionDecl );
    127126                }
    128127        }
  • src/SynTree/FunctionDecl.cc

    r7cc2c8d r13de47bc  
    2222#include "Common/utility.h"
    2323#include "InitTweak/InitTweak.h"
     24#include "CodeGen/FixMain.h"
    2425
    2526extern bool translation_unit_nomain;
     
    3233        // because we want to replace the main even if it is inside an extern
    3334        if ( name == "main" ) {
    34                 set_linkage( translation_unit_nomain ? LinkageSpec::C : LinkageSpec::Cforall );
     35                set_linkage( CodeGen::FixMain::mainLinkage() );
    3536        } // if
    3637}
  • src/main.cc

    r7cc2c8d r13de47bc  
    1414//
    1515
    16 #include <memory>
    1716#include <iostream>
    1817#include <fstream>
     
    3534#include "CodeGen/Generate.h"
    3635#include "CodeGen/FixNames.h"
     36#include "CodeGen/FixMain.h"
    3737#include "ControlStruct/Mutate.h"
    3838#include "SymTab/Validate.h"
     
    8080static void dump( list< Declaration * > & translationUnit, ostream & out = cout );
    8181
    82 bool translation_unit_nomain = true;
    83 std::unique_ptr<FunctionDecl> translation_unit_main_signature = nullptr;
    84 
    8582static void backtrace( int start ) {                                    // skip first N stack frames
    8683        enum { Frames = 50 };
     
    159156
    160157        parse_cmdline( argc, argv, filename );                          // process command-line arguments
    161         translation_unit_nomain = nomainp;
     158        CodeGen::FixMain::setReplaceMain( !nomainp );
    162159
    163160        try {
     
    178175                } // if
    179176
    180                 if ( optind < argc ) {                                                  // any commands after the flags and input file ? => output file name
    181                         output = new ofstream( argv[ optind ] );
    182                 } // if
    183 
    184177                // read in the builtins, extras, and the prelude
    185178                if ( ! nopreludep ) {                                                   // include gcc builtins
     
    304297                } // if
    305298
     299                if ( optind < argc ) {                                                  // any commands after the flags and input file ? => output file name
     300                        output = new ofstream( argv[ optind ] );
     301                } // if
     302
    306303                CodeGen::generate( translationUnit, *output, ! noprotop );
    307304
    308                 if( translation_unit_main_signature ) {
    309                         *output << "int main(int argc, char** argv) { return ";
    310 
    311                         *output << translation_unit_main_signature->get_scopedMangleName() << "(";
    312                         if(translation_unit_main_signature->get_functionType()->get_parameters().size() != 0){
    313                                 *output << "argc, argv";
    314                         }
    315                         *output << ");";
    316 
    317                         *output << " }\n";
    318                 }
     305                CodeGen::FixMain::fix( *output, treep ? "../prelude/bootloader.c" : CFA_LIBDIR "/bootloader.c" );
    319306
    320307                if ( output != &cout ) {
  • src/prelude/bootloader.cf

    r7cc2c8d r13de47bc  
    1 extern int invoke_main(int argc, char* argv[], char* envp[]);
     1extern "C" { static inline int invoke_main(int argc, char* argv[], char* envp[]); }
    22
    33int main(int argc, char* argv[], char* envp[]) {
  • src/tests/.expect/32/declarationSpecifier.txt

    r7cc2c8d r13de47bc  
    628628    return ((int )___retval_main__i_1);
    629629}
    630 int main(int argc, char** argv) { return __main__Fi_iPPCc__1(argc, argv); }
    631 
     630extern void *malloc(long unsigned int __size);
     631extern void free(void *__ptr);
     632extern void abort(void);
     633extern int atexit(void (*__func)(void));
     634extern void exit(int __status);
     635extern int printf(const char *__restrict __format, ...);
     636static inline int invoke_main(int argc, char **argv, char **envp);
     637int main(int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){
     638    int ___retval_main__i_1;
     639    int _tmp_cp_ret0;
     640    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
     641    ((void)(_tmp_cp_ret0) /* ^?{} */);
     642    return ((int )___retval_main__i_1);
     643}
  • src/tests/.expect/32/gccExtensions.txt

    r7cc2c8d r13de47bc  
    165165    return ((int )___retval_main__i_1);
    166166}
    167 int main(int argc, char** argv) { return __main__Fi_iPPCc__1(argc, argv); }
     167static inline int invoke_main(int argc, char* argv[], char* envp[]) { return __main__Fi_iPPCc__1(argc, argv); }
     168extern void *malloc(long unsigned int __size);
     169extern void free(void *__ptr);
     170extern void abort(void);
     171extern int atexit(void (*__func)(void));
     172extern void exit(int __status);
     173extern int printf(const char *__restrict __format, ...);
     174static inline int invoke_main(int argc, char **argv, char **envp);
     175int main(int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){
     176    int ___retval_main__i_1;
     177    int _tmp_cp_ret0;
     178    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
     179    ((void)(_tmp_cp_ret0) /* ^?{} */);
     180    return ((int )___retval_main__i_1);
     181}
  • src/tests/.expect/64/declarationSpecifier.txt

    r7cc2c8d r13de47bc  
    628628    return ((int )___retval_main__i_1);
    629629}
    630 int main(int argc, char** argv) { return __main__Fi_iPPCc__1(argc, argv); }
     630static inline int invoke_main(int argc, char* argv[], char* envp[]) { return __main__Fi_iPPCc__1(argc, argv); }
     631extern void *malloc(long unsigned int __size);
     632extern void free(void *__ptr);
     633extern void abort(void);
     634extern int atexit(void (*__func)(void));
     635extern void exit(int __status);
     636extern int printf(const char *__restrict __format, ...);
     637static inline int invoke_main(int argc, char **argv, char **envp);
     638int main(int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){
     639    int ___retval_main__i_1;
     640    int _tmp_cp_ret0;
     641    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
     642    ((void)(_tmp_cp_ret0) /* ^?{} */);
     643    return ((int )___retval_main__i_1);
     644}
  • src/tests/.expect/64/gccExtensions.txt

    r7cc2c8d r13de47bc  
    165165    return ((int )___retval_main__i_1);
    166166}
    167 int main(int argc, char** argv) { return __main__Fi_iPPCc__1(argc, argv); }
     167static inline int invoke_main(int argc, char* argv[], char* envp[]) { return __main__Fi_iPPCc__1(argc, argv); }
     168extern void *malloc(long unsigned int __size);
     169extern void free(void *__ptr);
     170extern void abort(void);
     171extern int atexit(void (*__func)(void));
     172extern void exit(int __status);
     173extern int printf(const char *__restrict __format, ...);
     174static inline int invoke_main(int argc, char **argv, char **envp);
     175int main(int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){
     176    int ___retval_main__i_1;
     177    int _tmp_cp_ret0;
     178    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
     179    ((void)(_tmp_cp_ret0) /* ^?{} */);
     180    return ((int )___retval_main__i_1);
     181}
Note: See TracChangeset for help on using the changeset viewer.