Ignore:
Timestamp:
Oct 29, 2021, 5:24:56 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
Children:
a7026b4
Parents:
42b7fa5f (diff), 8e48fca4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/FixNames.cc

    r42b7fa5f re58e423  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Dec 13 23:39:14 2019
    13 // Update Count     : 21
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Oct 29 15:49:00 2021
     13// Update Count     : 23
    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"
    2124#include "Common/PassVisitor.h"
    2225#include "Common/SemanticError.h"  // for SemanticError
     
    4649        };
    4750
    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 
    9751        void fixNames( std::list< Declaration* > & translationUnit ) {
    9852                PassVisitor<FixNames> fixer;
     
    11872                fixDWT( functionDecl );
    11973
    120                 if(is_main( SymTab::Mangler::mangle(functionDecl, true, true) )) {
     74                if ( FixMain::isMain( functionDecl ) ) {
    12175                        int nargs = functionDecl->get_functionType()->get_parameters().size();
    12276                        if( !(nargs == 0 || nargs == 2 || nargs == 3) ) {
     
    12478                        }
    12579                        functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( new ConstantExpr( Constant::from_int( 0 ) ) ) );
    126                         CodeGen::FixMain::registerMain( functionDecl );
    12780                }
    12881        }
     
    13285                GuardAction( [this](){ scopeLevel--; } );
    13386        }
     87
     88/// Does work with the main function and scopeLevels.
     89class 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        }
     96public:
     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
     135void fixNames( ast::TranslationUnit & translationUnit ) {
     136        ast::Pass<FixNames_new>::run( translationUnit );
     137}
     138
    134139} // namespace CodeGen
    135140
Note: See TracChangeset for help on using the changeset viewer.