source: src/MakeLibCfaNew.cpp@ 0026d67

ADT ast-experimental
Last change on this file since 0026d67 was 6c2dc00, checked in by Henry Xue <y58xue@…>, 4 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.