source: src/MakeLibCfaNew.cpp @ 7b53bfd

ADTast-experimental
Last change on this file since 7b53bfd was 6c2dc00, checked in by Henry Xue <y58xue@…>, 3 years ago

Convert makeLibCfa to use new AST

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