source: src/MakeLibCfa.cc @ fcd65ca

ADTast-experimentalenumforall-pointer-decaypthread-emulationqualifiedEnum
Last change on this file since fcd65ca was 60a8062, checked in by Peter A. Buhr <pabuhr@…>, 5 years ago

rewrite most of OperatorTable? and change caller modules to use new interface

  • Property mode set to 100644
File size: 5.1 KB
RevLine 
[b87a5ed]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//
[974906e2]7// MakeLibCfa.cc --
[b87a5ed]8//
9// Author           : Richard C. Bilson
10// Created On       : Sat May 16 10:33:33 2015
[d08beee]11// Last Modified By : Peter A. Buhr
[60a8062]12// Last Modified On : Sun Feb 16 03:49:49 2020
13// Update Count     : 45
[974906e2]14//
[51b7345]15
16#include "MakeLibCfa.h"
[bf2438c]17
[9aaac6e9]18#include <cassert>                  // for assert
[bf2438c]19#include <string>                   // for operator==, string
20
21#include "CodeGen/OperatorTable.h"  // for OperatorInfo, operatorLookup, Ope...
[9aaac6e9]22#include "Common/PassVisitor.h"     // for PassVisitor
[bf2438c]23#include "Common/SemanticError.h"   // for SemanticError
24#include "Common/UniqueName.h"      // for UniqueName
[07de76b]25#include "SynTree/LinkageSpec.h"    // for Spec, Intrinsic, C
[bf2438c]26#include "SynTree/Declaration.h"    // for FunctionDecl, ObjectDecl, Declara...
27#include "SynTree/Expression.h"     // for NameExpr, UntypedExpr, VariableExpr
28#include "SynTree/Initializer.h"    // for SingleInit
29#include "SynTree/Label.h"          // for Label
30#include "SynTree/Statement.h"      // for CompoundStmt, ReturnStmt
31#include "SynTree/Type.h"           // for FunctionType
32#include "SynTree/Visitor.h"        // for acceptAll, Visitor
[51b7345]33
34namespace LibCfa {
[9aaac6e9]35        namespace {
36                struct MakeLibCfa {
37                  public:
38                        void postvisit( FunctionDecl* funcDecl );
[974906e2]39
[9aaac6e9]40                        std::list< Declaration* > newDecls;
41                };
42        }
[51b7345]43
[b87a5ed]44        void makeLibCfa( std::list< Declaration* > &prelude ) {
[9aaac6e9]45                PassVisitor<MakeLibCfa> maker;
[b87a5ed]46                acceptAll( prelude, maker );
[9aaac6e9]47                prelude.splice( prelude.end(), maker.pass.newDecls );
[b87a5ed]48        }
[51b7345]49
[9aaac6e9]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                                }
[f1e012b]61                        }
[9aaac6e9]62                        Type * type = nullptr;
63                };
[51b7345]64
[9aaac6e9]65                struct ZeroOneReplacer {
66                        ZeroOneReplacer( Type * t ) : type( t ) {}
67                        ~ZeroOneReplacer() { delete type; }
68                        Type * type = nullptr;
[974906e2]69
[9aaac6e9]70                        Type * common( Type * t ) {
71                                if ( ! type ) return t;
72                                delete t;
73                                return type->clone();
74                        }
75
76                        Type * postmutate( OneType * t ) { return common( t ); }
77                        Type * postmutate( ZeroType * t ) { return common( t ); }
78                };
79
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                }
88
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;
96
97                        FunctionDecl *funcDecl = origFuncDecl->clone();
[60a8062]98                        const CodeGen::OperatorInfo * opInfo;
99                        opInfo = CodeGen::operatorLookup( funcDecl->get_name() );
100                        assert( opInfo );
[9aaac6e9]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
[ba3706f]118                        funcDecl->set_statements( new CompoundStmt() );
[9aaac6e9]119                        newDecls.push_back( funcDecl );
120
[10295d8]121                        Statement * stmt = nullptr;
[60a8062]122                        switch ( opInfo->type ) {
[9aaac6e9]123                          case CodeGen::OT_INDEX:
124                          case CodeGen::OT_CALL:
125                          case CodeGen::OT_PREFIX:
126                          case CodeGen::OT_POSTFIX:
127                          case CodeGen::OT_INFIX:
128                          case CodeGen::OT_PREFIXASSIGN:
129                          case CodeGen::OT_POSTFIXASSIGN:
130                          case CodeGen::OT_INFIXASSIGN:
[10295d8]131                                        // return the recursive call
[ba3706f]132                                        stmt = new ReturnStmt( newExpr );
[10295d8]133                                        break;
[9aaac6e9]134                          case CodeGen::OT_CTOR:
135                          case CodeGen::OT_DTOR:
[10295d8]136                                        // execute the recursive call
[ba3706f]137                                        stmt = new ExprStmt( newExpr );
[9aaac6e9]138                                        break;
139                          case CodeGen::OT_CONSTANT:
140                          case CodeGen::OT_LABELADDRESS:
141                                // there are no intrinsic definitions of 0/1 or label addresses as functions
142                                assert( false );
143                        } // switch
[10295d8]144                        funcDecl->get_statements()->push_back( stmt );
[9aaac6e9]145                }
146        } // namespace
[51b7345]147} // namespace LibCfa
[d08beee]148
149// Local Variables: //
150// tab-width: 4 //
151// End: //
Note: See TracBrowser for help on using the repository browser.