source: src/MakeLibCfa.cpp@ 115ac1ce

Last change on this file since 115ac1ce was c92bdcc, checked in by Andrew Beach <ajbeach@…>, 16 months ago

Updated the rest of the names in src/ (except for the generated files).

  • 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.hpp"
17
18#include "AST/Copy.hpp"
19#include "AST/Fwd.hpp"
20#include "AST/Pass.hpp"
21#include "CodeGen/OperatorTable.hpp"
22#include "Common/UniqueName.hpp"
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.