source: src/MakeLibCfa.cc@ 6fa409e

new-env
Last change on this file since 6fa409e was 68f9c43, checked in by Aaron Moss <a3moss@…>, 8 years ago

First pass at delete removal

  • Property mode set to 100644
File size: 5.0 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
[2794fff]11// Last Modified By : Rob Schluntz
[845cedc]12// Last Modified On : Fri Apr 22 13:54:15 2016
[f1e012b]13// Update Count : 40
[974906e2]14//
[51b73452]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
25#include "Parser/LinkageSpec.h" // for Spec, Intrinsic, C
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
[51b73452]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 }
[51b73452]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 }
[51b73452]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 };
[51b73452]64
[9aaac6e9]65 struct ZeroOneReplacer {
66 ZeroOneReplacer( Type * t ) : type( t ) {}
67 Type * type = nullptr;
[974906e2]68
[9aaac6e9]69 Type * common( Type * t ) {
70 if ( ! type ) return t;
71 return type->clone();
72 }
73
74 Type * postmutate( OneType * t ) { return common( t ); }
75 Type * postmutate( ZeroType * t ) { return common( t ); }
76 };
77
78 void fixZeroOneType( FunctionDecl * origFuncDecl ) {
79 // find appropriate type to replace zero_t/one_t with
80 PassVisitor<TypeFinder> finder;
81 origFuncDecl->type->accept( finder );
82 // replace zero_t/one_t in function type
83 PassVisitor<ZeroOneReplacer> replacer( finder.pass.type );
84 origFuncDecl->type->acceptMutator( replacer );
85 }
86
87 void MakeLibCfa::postvisit( FunctionDecl* origFuncDecl ) {
88 // don't change non-intrinsic functions
89 if ( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
90 // replace zero_t/one_t with void */void (*)(void)
91 fixZeroOneType( origFuncDecl );
92 // skip functions already defined
93 if ( origFuncDecl->get_statements() ) return;
94
95 FunctionDecl *funcDecl = origFuncDecl->clone();
96 CodeGen::OperatorInfo opInfo;
97 bool lookResult = CodeGen::operatorLookup( funcDecl->get_name(), opInfo );
98 assert( lookResult );
99 assert( ! funcDecl->get_statements() );
100 // build a recursive call - this is okay, as the call will actually be codegen'd using operator syntax
101 UntypedExpr *newExpr = new UntypedExpr( new NameExpr( funcDecl->get_name() ) );
102 UniqueName paramNamer( "_p" );
103 std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin();
104 assert( param != funcDecl->get_functionType()->get_parameters().end() );
105
106 for ( ; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
107 // name each unnamed parameter
108 if ( (*param)->get_name() == "" ) {
109 (*param)->set_name( paramNamer.newName() );
110 (*param)->set_linkage( LinkageSpec::C );
111 }
112 // add parameter to the expression
113 newExpr->get_args().push_back( new VariableExpr( *param ) );
114 } // for
115
[ba3706f]116 funcDecl->set_statements( new CompoundStmt() );
[9aaac6e9]117 newDecls.push_back( funcDecl );
118
[10295d8]119 Statement * stmt = nullptr;
[9aaac6e9]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:
[10295d8]129 // return the recursive call
[ba3706f]130 stmt = new ReturnStmt( newExpr );
[10295d8]131 break;
[9aaac6e9]132 case CodeGen::OT_CTOR:
133 case CodeGen::OT_DTOR:
[10295d8]134 // execute the recursive call
[ba3706f]135 stmt = new ExprStmt( newExpr );
[9aaac6e9]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
[10295d8]142 funcDecl->get_statements()->push_back( stmt );
[9aaac6e9]143 }
144 } // namespace
[51b73452]145} // namespace LibCfa
Note: See TracBrowser for help on using the repository browser.