Changeset d3e4d6c for src/MakeLibCfa.cc


Ignore:
Timestamp:
Aug 23, 2017, 6:22:07 PM (7 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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:
87e08e24, cb811ac
Parents:
9f07232 (diff), bd37119 (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 plg2:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/MakeLibCfa.cc

    r9f07232 rd3e4d6c  
    1616#include "MakeLibCfa.h"
    1717
    18 #include <cassert>                 // for assert
     18#include <cassert>                  // for assert
    1919#include <string>                   // for operator==, string
    2020
    2121#include "CodeGen/OperatorTable.h"  // for OperatorInfo, operatorLookup, Ope...
     22#include "Common/PassVisitor.h"     // for PassVisitor
    2223#include "Common/SemanticError.h"   // for SemanticError
    2324#include "Common/UniqueName.h"      // for UniqueName
     
    3233
    3334namespace LibCfa {
    34         class MakeLibCfa : public Visitor {
    35           public:
    36                 void visit( FunctionDecl* funcDecl );
    37                 void visit( ObjectDecl* objDecl );
     35        namespace {
     36                struct MakeLibCfa {
     37                  public:
     38                        void postvisit( FunctionDecl* funcDecl );
    3839
    39                 std::list< Declaration* > &get_newDecls() { return newDecls; }
    40           private:
    41                 std::list< Declaration* > newDecls;
    42         };
     40                        std::list< Declaration* > newDecls;
     41                };
     42        }
    4343
    4444        void makeLibCfa( std::list< Declaration* > &prelude ) {
    45                 MakeLibCfa maker;
     45                PassVisitor<MakeLibCfa> maker;
    4646                acceptAll( prelude, maker );
    47                 prelude.splice( prelude.end(), maker.get_newDecls() );
     47                prelude.splice( prelude.end(), maker.pass.newDecls );
    4848        }
    4949
    50         void MakeLibCfa::visit( FunctionDecl* origFuncDecl ) {
    51                 if ( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
    52                 if ( origFuncDecl->get_statements() ) return;
     50        namespace {
     51                struct TypeFinder       {
     52                        void postvisit( TypeInstType * inst ) {
     53                                // if a type variable is seen, assume all zero_t/one_t in the parameter list
     54                                //  can be replaced with the equivalent 'general' pointer.
     55                                if ( type ) return;
     56                                if ( inst->isFtype ) {
     57                                        type = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), false ) );
     58                                } else {
     59                                        type = new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) );
     60                                }
     61                        }
     62                        Type * type = nullptr;
     63                };
    5364
    54                 FunctionDecl *funcDecl = origFuncDecl->clone();
    55                 CodeGen::OperatorInfo opInfo;
    56                 bool lookResult = CodeGen::operatorLookup( funcDecl->get_name(), opInfo );
    57                 assert( lookResult );
    58                 assert( ! funcDecl->get_statements() );
    59                 UntypedExpr *newExpr = new UntypedExpr( new NameExpr( funcDecl->get_name() ) );
    60                 UniqueName paramNamer( "_p" );
    61                 std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin();
    62                 assert( param != funcDecl->get_functionType()->get_parameters().end() );
     65                struct ZeroOneReplacer {
     66                        ZeroOneReplacer( Type * t ) : type( t ) {}
     67                        ~ZeroOneReplacer() { delete type; }
     68                        Type * type = nullptr;
    6369
    64                 for ( ; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
    65                         if ( (*param)->get_name() == "" ) {
    66                                 (*param)->set_name( paramNamer.newName() );
    67                                 (*param)->set_linkage( LinkageSpec::C );
     70                        Type * common( Type * t ) {
     71                                if ( ! type ) return t;
     72                                delete t;
     73                                return type->clone();
    6874                        }
    69                         newExpr->get_args().push_back( new VariableExpr( *param ) );
    70                 } // for
    7175
    72                 funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
    73                 newDecls.push_back( funcDecl );
     76                        Type * postmutate( OneType * t ) { return common( t ); }
     77                        Type * postmutate( ZeroType * t ) { return common( t ); }
     78                };
    7479
    75                 switch ( opInfo.type ) {
    76                   case CodeGen::OT_INDEX:
    77                   case CodeGen::OT_CALL:
    78                   case CodeGen::OT_PREFIX:
    79                   case CodeGen::OT_POSTFIX:
    80                   case CodeGen::OT_INFIX:
    81                   case CodeGen::OT_PREFIXASSIGN:
    82                   case CodeGen::OT_POSTFIXASSIGN:
    83                   case CodeGen::OT_INFIXASSIGN:
    84                   case CodeGen::OT_CTOR:
    85                   case CodeGen::OT_DTOR:
    86                                 funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
    87                                 break;
    88                   case CodeGen::OT_CONSTANT:
    89                   case CodeGen::OT_LABELADDRESS:
    90                         // there are no intrinsic definitions of 0/1 or label addresses as functions
    91                         assert( false );
    92                 } // switch
    93         }
     80                void fixZeroOneType( FunctionDecl * origFuncDecl ) {
     81                        // find appropriate type to replace zero_t/one_t with
     82                        PassVisitor<TypeFinder> finder;
     83                        origFuncDecl->type->accept( finder );
     84                        // replace zero_t/one_t in function type
     85                        PassVisitor<ZeroOneReplacer> replacer( finder.pass.type );
     86                        origFuncDecl->type->acceptMutator( replacer );
     87                }
    9488
    95         void MakeLibCfa::visit( ObjectDecl* origObjDecl ) {
    96                 if ( origObjDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
     89                void MakeLibCfa::postvisit( FunctionDecl* origFuncDecl ) {
     90                        // don't change non-intrinsic functions
     91                        if ( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
     92                        // replace zero_t/one_t with void */void (*)(void)
     93                        fixZeroOneType( origFuncDecl );
     94                        // skip functions already defined
     95                        if ( origFuncDecl->get_statements() ) return;
    9796
    98                 ObjectDecl *objDecl = origObjDecl->clone();
    99                 assert( ! objDecl->get_init() );
    100                 std::list< Expression* > noDesignators;
    101                 objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), false ) ); // cannot be constructed
    102                 newDecls.push_back( objDecl );
    103         }
     97                        FunctionDecl *funcDecl = origFuncDecl->clone();
     98                        CodeGen::OperatorInfo opInfo;
     99                        bool lookResult = CodeGen::operatorLookup( funcDecl->get_name(), opInfo );
     100                        assert( lookResult );
     101                        assert( ! funcDecl->get_statements() );
     102                        // build a recursive call - this is okay, as the call will actually be codegen'd using operator syntax
     103                        UntypedExpr *newExpr = new UntypedExpr( new NameExpr( funcDecl->get_name() ) );
     104                        UniqueName paramNamer( "_p" );
     105                        std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin();
     106                        assert( param != funcDecl->get_functionType()->get_parameters().end() );
     107
     108                        for ( ; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
     109                                // name each unnamed parameter
     110                                if ( (*param)->get_name() == "" ) {
     111                                        (*param)->set_name( paramNamer.newName() );
     112                                        (*param)->set_linkage( LinkageSpec::C );
     113                                }
     114                                // add parameter to the expression
     115                                newExpr->get_args().push_back( new VariableExpr( *param ) );
     116                        } // for
     117
     118                        funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
     119                        newDecls.push_back( funcDecl );
     120
     121                        switch ( opInfo.type ) {
     122                          case CodeGen::OT_INDEX:
     123                          case CodeGen::OT_CALL:
     124                          case CodeGen::OT_PREFIX:
     125                          case CodeGen::OT_POSTFIX:
     126                          case CodeGen::OT_INFIX:
     127                          case CodeGen::OT_PREFIXASSIGN:
     128                          case CodeGen::OT_POSTFIXASSIGN:
     129                          case CodeGen::OT_INFIXASSIGN:
     130                          case CodeGen::OT_CTOR:
     131                          case CodeGen::OT_DTOR:
     132                                // return the recursive call
     133                                        funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
     134                                        break;
     135                          case CodeGen::OT_CONSTANT:
     136                          case CodeGen::OT_LABELADDRESS:
     137                                // there are no intrinsic definitions of 0/1 or label addresses as functions
     138                                assert( false );
     139                        } // switch
     140                }
     141        } // namespace
    104142} // namespace LibCfa
Note: See TracChangeset for help on using the changeset viewer.