Changeset bef4f1a


Ignore:
Timestamp:
Oct 26, 2023, 12:44:25 PM (14 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
f43146e4
Parents:
8941b6b
Message:

Translation of the fix main pass to the new ast data structures.

Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/FixMain.cc

    r8941b6b rbef4f1a  
    1414//
    1515
    16 
    1716#include "FixMain.h"
    1817
     
    2322
    2423#include "AST/Decl.hpp"
     24#include "AST/Pass.hpp"
    2525#include "AST/Type.hpp"
     26#include "AST/Vector.hpp"
    2627#include "Common/PassVisitor.h"
    2728#include "Common/SemanticError.h"  // for SemanticError
     
    4748        }
    4849};
     50
     51struct FindMainCore_new {
     52        ast::FunctionDecl const * main_declaration = nullptr;
     53
     54        void previsit( ast::FunctionDecl const * decl ) {
     55                if ( FixMain::isMain( decl ) ) {
     56                        if ( main_declaration ) {
     57                                SemanticError( decl, "Multiple definition of main routine\n" );
     58                        }
     59                        main_declaration = decl;
     60                }
     61        }
     62};
     63
     64std::string genTypeAt( const ast::vector<ast::Type> & types, size_t at ) {
     65        return genType( types[at], "", Options( false, false, false, false ) );
     66}
    4967
    5068}
     
    83101namespace {
    84102
    85 ObjectDecl * signedIntObj() {
    86         return new ObjectDecl(
    87                 "", Type::StorageClasses(), LinkageSpec::Cforall, 0,
    88                 new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr );
    89 }
    90 
    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 );
    98 }
    99 
    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() );
    105 }
    106 
    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 );
    111 }
    112 
    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 );
     103ast::ObjectDecl * makeIntObj(){
     104        return new ast::ObjectDecl( CodeLocation(), "",
     105                new ast::BasicType( ast::BasicType::SignedInt ) );
     106}
     107
     108ast::ObjectDecl * makeCharStarStarObj() {
     109        return new ast::ObjectDecl( CodeLocation(), "",
     110                new ast::PointerType(
     111                        new ast::PointerType(
     112                                new ast::BasicType( ast::BasicType::Char ) ) ) );
     113}
     114
     115std::string getMangledNameOfMain(
     116                ast::vector<ast::DeclWithType> && params, ast::ArgumentFlag isVarArgs ) {
     117        ast::ptr<ast::FunctionDecl> decl = new ast::FunctionDecl(
     118                CodeLocation(),
     119                "main",
     120                ast::vector<ast::TypeDecl>(),
     121                ast::vector<ast::DeclWithType>(),
     122                std::move( params ),
     123                { makeIntObj() },
     124                nullptr,
     125                ast::Storage::Classes(),
     126                ast::Linkage::Spec(),
     127                ast::vector<ast::Attribute>(),
     128                ast::Function::Specs(),
     129                isVarArgs
     130        );
     131        return Mangle::mangle( decl.get() );
     132}
     133
     134std::string getMangledNameOf0ParameterMain() {
     135        return getMangledNameOfMain( {}, ast::VariableArgs );
     136}
     137
     138std::string getMangledNameOf2ParameterMain() {
     139        return getMangledNameOfMain( {
     140                makeIntObj(),
     141                makeCharStarStarObj(),
     142        }, ast::FixedArgs );
    119143}
    120144
     
    122146        // This breaks if you move it out of the function.
    123147        static const std::string mangled_mains[] = {
    124                 mangled_0_argument_main(),
    125                 mangled_2_argument_main(),
    126                 //mangled_3_argument_main(),
     148                getMangledNameOf0ParameterMain(),
     149                getMangledNameOf2ParameterMain(),
     150                //getMangledNameOf3ParameterMain(),
    127151        };
    128152
     
    149173}
    150174
    151 };
     175void FixMain::fix( ast::TranslationUnit & translationUnit,
     176                std::ostream &os, const char * bootloader_filename ) {
     177
     178        ast::Pass<FindMainCore_new> main_finder;
     179        ast::accept_all( translationUnit, main_finder );
     180        if ( nullptr == main_finder.core.main_declaration ) return;
     181
     182        ast::FunctionDecl * main_declaration =
     183                ast::mutate( main_finder.core.main_declaration );
     184
     185        main_declaration->mangleName = Mangle::mangle( main_declaration );
     186
     187        os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return ";
     188        os << main_declaration->scopedMangleName() << "(";
     189        const auto& params = main_declaration->type->params;
     190        switch ( params.size() ) {
     191                case 3: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv, (" << genTypeAt(params, 2) << ")envp"; break;
     192                case 2: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv"; break;
     193                case 0: break;
     194                default : assert(false);
     195        }
     196        os << "); }\n";
     197
     198        std::ifstream bootloader( bootloader_filename, std::ios::in );
     199        assertf( bootloader.is_open(), "cannot open bootloader.c\n" );
     200        os << bootloader.rdbuf();
     201}
     202
     203} // namespace CodeGen
  • src/CodeGen/FixMain.h

    r8941b6b rbef4f1a  
    2727namespace ast {
    2828        class FunctionDecl;
     29        class TranslationUnit;
    2930}
    3031
     
    4950        static void fix( std::list< Declaration * > & decls,
    5051                        std::ostream &os, const char* bootloader_filename );
     52        static void fix( ast::TranslationUnit & translationUnit,
     53                        std::ostream &os, const char * bootloader_filename );
    5154
    5255private:
  • src/main.cc

    r8941b6b rbef4f1a  
    437437                PASS( "Code Gen", CodeGen::generate, transUnit, *output, !genproto, prettycodegenp, true, linemarks, false );
    438438
    439                 translationUnit = convert( std::move( transUnit ) );
    440 
    441                 CodeGen::FixMain::fix( translationUnit, *output,
     439                CodeGen::FixMain::fix( transUnit, *output,
    442440                                (PreludeDirector + "/bootloader.c").c_str() );
    443441                if ( output != &cout ) {
Note: See TracChangeset for help on using the changeset viewer.