Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/FixNames.cc

    r0c577f7 r16ba4a6f  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Oct 29 15:49:00 2021
    13 // Update Count     : 23
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Dec 13 23:39:14 2019
     13// Update Count     : 21
    1414//
    1515
     
    1919#include <string>                  // for string, operator!=, operator==
    2020
    21 #include "AST/Chain.hpp"
    22 #include "AST/Expr.hpp"
    23 #include "AST/Pass.hpp"
    2421#include "Common/PassVisitor.h"
    2522#include "Common/SemanticError.h"  // for SemanticError
     
    4946        };
    5047
     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
    5197        void fixNames( std::list< Declaration* > & translationUnit ) {
    5298                PassVisitor<FixNames> fixer;
     
    72118                fixDWT( functionDecl );
    73119
    74                 if ( FixMain::isMain( functionDecl ) ) {
     120                if(is_main( SymTab::Mangler::mangle(functionDecl, true, true) )) {
    75121                        int nargs = functionDecl->get_functionType()->get_parameters().size();
    76122                        if( !(nargs == 0 || nargs == 2 || nargs == 3) ) {
     
    78124                        }
    79125                        functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( new ConstantExpr( Constant::from_int( 0 ) ) ) );
     126                        CodeGen::FixMain::registerMain( functionDecl );
    80127                }
    81128        }
     
    85132                GuardAction( [this](){ scopeLevel--; } );
    86133        }
    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 
    139134} // namespace CodeGen
    140135
Note: See TracChangeset for help on using the changeset viewer.