source: src/MakeLibCfa.cpp @ 7aa209e7

Last change on this file since 7aa209e7 was 83fd57d, checked in by Andrew Beach <ajbeach@…>, 6 months ago

Removed 'New' suffixes, they are no longer needed for disambiguation.

  • Property mode set to 100644
File size: 4.7 KB
Line 
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//
7// MakeLibCfa.cpp --
8//
9// Author           : Henry Xue
10// Created On       : Fri Aug 27 15:50:14 2021
11// Last Modified By : Henry Xue
12// Last Modified On : Fri Aug 27 15:50:14 2021
13// Update Count     : 1
14//
15
16#include "MakeLibCfa.h"
17
18#include "AST/Copy.hpp"
19#include "AST/Fwd.hpp"
20#include "AST/Pass.hpp"
21#include "CodeGen/OperatorTable.h"
22#include "Common/UniqueName.h"
23
24namespace LibCfa {
25namespace {
26        struct MakeLibCfa {
27                const ast::DeclWithType * postvisit( const ast::FunctionDecl * funcDecl );
28                std::list< ast::ptr< ast::Decl > > newDecls;
29        };
30}
31
32void makeLibCfa( ast::TranslationUnit & prelude ) {
33        ast::Pass< MakeLibCfa > maker;
34        accept_all( prelude, maker );
35        prelude.decls.splice( prelude.decls.end(), maker.core.newDecls );
36}
37
38namespace {
39        struct TypeFinder {
40                void postvisit( const ast::TypeInstType * inst ) {
41                        // if a type variable is seen, assume all zero_t/one_t in the parameter list
42                        //  can be replaced with the equivalent 'general' pointer.
43                        if ( type ) return;
44                        if ( inst->kind == ast::TypeDecl::Ftype ) {
45                                type = new ast::PointerType( new ast::FunctionType() );
46                        } else {
47                                type = new ast::PointerType( new ast::VoidType() );
48                        }
49                }
50                ast::ptr< ast::Type > type;
51        };
52
53        struct ZeroOneReplacer {
54                ZeroOneReplacer( const ast::Type * t ) : type( t ) {}
55                ast::ptr< ast::Type > type;
56
57                const ast::Type * common( const ast::Type * t ) {
58                        if ( ! type ) return t;
59                        return type;
60                }
61
62                const ast::Type * postvisit( const ast::OneType * t ) { return common( t ); }
63                const ast::Type * postvisit( const ast::ZeroType * t ) { return common( t ); }
64        };
65
66        // const ast::Type * fixZeroOneType( ast::FunctionDecl * origFuncDecl ) {
67        //      // find appropriate type to replace zero_t/one_t with
68        //      ast::Pass< TypeFinder > finder;
69        //      origFuncDecl->type->accept( finder );
70        //      // replace zero_t/one_t in function type
71        //      ast::Pass< ZeroOneReplacer > replacer( finder.core.type );
72        //      //auto funcDecl = mutate( origFuncDecl );
73        //      return origFuncDecl->type->accept( replacer );
74        // }
75
76        const ast::DeclWithType * MakeLibCfa::postvisit( const ast::FunctionDecl * origFuncDecl ) {
77                // don't change non-intrinsic functions
78                if ( origFuncDecl->linkage != ast::Linkage::Intrinsic ) return origFuncDecl;
79                // replace zero_t/one_t with void */void (*)(void)
80                auto mutDecl = mutate( origFuncDecl );
81                //mutDecl->type = fixZeroOneType( mutDecl );
82
83                // find appropriate type to replace zero_t/one_t with
84                ast::Pass< TypeFinder > finder;
85                mutDecl->type->accept( finder );
86                // replace zero_t/one_t in function type
87                ast::Pass< ZeroOneReplacer > replacer( finder.core.type );
88                mutDecl->type = mutDecl->type->accept( replacer );
89
90                // skip functions already defined
91                if ( mutDecl->has_body() ) return mutDecl;
92
93                const CodeLocation loc = mutDecl->location;
94                auto funcDecl = dynamic_cast<ast::FunctionDecl *>(ast::deepCopy( (ast::DeclWithType*)mutDecl ));
95                const CodeGen::OperatorInfo * opInfo;
96                opInfo = CodeGen::operatorLookup( funcDecl->name );
97                assert( opInfo );
98                assert( ! funcDecl->has_body() );
99                // build a recursive call - this is okay, as the call will actually be codegen'd using operator syntax
100                auto newExpr = new ast::UntypedExpr( loc, new ast::NameExpr( loc, funcDecl->name ) );
101                UniqueName paramNamer( "_p" );
102                auto param = funcDecl->params.begin();
103                assert( param != funcDecl->params.end() );
104
105                for ( ; param != funcDecl->params.end(); ++param ) {
106                        // name each unnamed parameter
107                        if ( (*param)->name == "" ) {
108                                auto _param = param->get_and_mutate();
109                                _param->name = paramNamer.newName() ;
110                                _param->linkage = ast::Linkage::C;
111                        }
112                        // add parameter to the expression
113                        newExpr->args.push_back( new ast::VariableExpr( loc, *param ) );
114                } // for
115
116                auto stmts = new ast::CompoundStmt( loc );;
117                newDecls.push_back( funcDecl );
118
119                ast::ptr< ast::Stmt > stmt;
120                switch ( opInfo->type ) {
121                        case CodeGen::OT_INDEX:
122                        case CodeGen::OT_CALL:
123                        case CodeGen::OT_PREFIX:
124                        case CodeGen::OT_POSTFIX:
125                        case CodeGen::OT_INFIX:
126                        case CodeGen::OT_PREFIXASSIGN:
127                        case CodeGen::OT_POSTFIXASSIGN:
128                        case CodeGen::OT_INFIXASSIGN:
129                                // return the recursive call
130                                stmt = new ast::ReturnStmt( loc, newExpr );
131                                break;
132                        case CodeGen::OT_CTOR:
133                        case CodeGen::OT_DTOR:
134                                // execute the recursive call
135                                stmt = new ast::ExprStmt( loc, newExpr );
136                                break;
137                        case CodeGen::OT_CONSTANT:
138                        case CodeGen::OT_LABELADDRESS:
139                        // there are no intrinsic definitions of 0/1 or label addresses as functions
140                        assert( false );
141                } // switch
142                stmts->push_back( stmt );
143                funcDecl->stmts = stmts;
144                return mutDecl;
145        }
146} // namespace
147} // namespace LibCfa
Note: See TracBrowser for help on using the repository browser.