source: src/CodeGen/Generate.cc@ 8941b6b

Last change on this file since 8941b6b was 8941b6b, checked in by Andrew Beach <ajbeach@…>, 2 years ago

Direct translation of code generation.

  • Property mode set to 100644
File size: 4.5 KB
RevLine 
[51587aa]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//
[35b1bf4]7// Generate.cc --
[51587aa]8//
9// Author : Richard C. Bilson
10// Created On : Mon May 18 07:44:20 2015
[07de76b]11// Last Modified By : Peter A. Buhr
[60a8062]12// Last Modified On : Sun Feb 16 03:01:51 2020
13// Update Count : 9
[51587aa]14//
[3268a58]15#include "Generate.h"
[51587aa]16
[bf2438c]17#include <iostream> // for ostream, endl, operator<<
18#include <list> // for list
19#include <string> // for operator<<
[51b73452]20
[8941b6b]21#include "CodeGeneratorNew.hpp" // for CodeGenerator_new, doSemicolon, ...
[bf2438c]22#include "CodeGenerator.h" // for CodeGenerator, doSemicolon, oper...
23#include "GenType.h" // for genPrettyType
[a984e65]24#include "Common/PassVisitor.h" // for PassVisitor
[07de76b]25#include "SynTree/LinkageSpec.h" // for isBuiltin, isGeneratable
[bf2438c]26#include "SynTree/BaseSyntaxNode.h" // for BaseSyntaxNode
27#include "SynTree/Declaration.h" // for Declaration
28#include "SynTree/Type.h" // for Type
[51b73452]29
30using namespace std;
31
32namespace CodeGen {
[a984e65]33 namespace {
34 /// Removes misc. nodes that should not exist in CodeGen
35 struct TreeCleaner {
[acdfb45]36 void premutate( CompoundStmt * stmt );
37 Statement * postmutate( ImplicitCtorDtorStmt * stmt );
[a984e65]38
39 static bool shouldClean( Declaration * );
40 };
41
42 void cleanTree( std::list< Declaration * > & translationUnit ) {
43 PassVisitor<TreeCleaner> cleaner;
44 filter( translationUnit, [](Declaration * decl) { return TreeCleaner::shouldClean(decl); }, false );
[acdfb45]45 mutateAll( translationUnit, cleaner );
[a984e65]46 } // cleanTree
47 } // namespace
48
[5f08961d]49 void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC, bool lineMarks, bool printExprTypes ) {
[a984e65]50 cleanTree( translationUnit );
51
[5f08961d]52 PassVisitor<CodeGenerator> cgv( os, pretty, generateC, lineMarks, printExprTypes );
[e6512c8]53 for ( auto & dcl : translationUnit ) {
54 if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) {
[9857e8d]55 cgv.pass.updateLocation( dcl );
[e6512c8]56 dcl->accept(cgv);
57 if ( doSemicolon( dcl ) ) {
[51587aa]58 os << ";";
59 } // if
[d22e90f]60 os << cgv.pass.endl;
[51587aa]61 } // if
62 } // for
63 }
[262f085f]64
65 void generate( BaseSyntaxNode * node, std::ostream & os ) {
66 if ( Type * type = dynamic_cast< Type * >( node ) ) {
[60a8062]67 os << genPrettyType( type, "" );
[262f085f]68 } else {
[5f08961d]69 PassVisitor<CodeGenerator> cgv( os, true, false, false, false );
[262f085f]70 node->accept( cgv );
71 }
72 os << std::endl;
73 }
[a984e65]74
75 namespace {
[acdfb45]76 void TreeCleaner::premutate( CompoundStmt * cstmt ) {
[a984e65]77 filter( cstmt->kids, [](Statement * stmt) {
78 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
79 return shouldClean( declStmt->decl );
80 }
81 return false;
82 }, false );
83 }
84
[acdfb45]85 Statement * TreeCleaner::postmutate( ImplicitCtorDtorStmt * stmt ) {
86 Statement * callStmt = nullptr;
87 std::swap( stmt->callStmt, callStmt );
88 delete stmt;
89 return callStmt;
90 }
91
[a984e65]92 bool TreeCleaner::shouldClean( Declaration * decl ) {
93 return dynamic_cast< TraitDecl * >( decl );
94 }
95 } // namespace
[8941b6b]96
97namespace {
98 bool shouldClean( ast::Decl const * decl ) {
99 return dynamic_cast<ast::TraitDecl const *>( decl );
100 }
101
102 /// Removes various nodes that should not exist in CodeGen.
103 struct TreeCleaner_new {
104 ast::CompoundStmt const * previsit( ast::CompoundStmt const * stmt ) {
105 auto mutStmt = ast::mutate( stmt );
106 erase_if( mutStmt->kids, []( ast::Stmt const * stmt ){
107 auto declStmt = dynamic_cast<ast::DeclStmt const *>( stmt );
108 return ( declStmt ) ? shouldClean( declStmt->decl ) : false;
109 } );
110 return mutStmt;
111 }
112
113 ast::Stmt const * postvisit( ast::ImplicitCtorDtorStmt const * stmt ) {
114 return stmt->callStmt;
115 }
116 };
117} // namespace
118
119void generate( ast::TranslationUnit & translationUnit, std::ostream & os, bool doIntrinsics,
120 bool pretty, bool generateC, bool lineMarks, bool printExprTypes ) {
121 erase_if( translationUnit.decls, shouldClean );
122 ast::Pass<TreeCleaner_new>::run( translationUnit );
123
124 ast::Pass<CodeGenerator_new> cgv( os,
125 Options( pretty, generateC, lineMarks, printExprTypes ) );
126 for ( auto & decl : translationUnit.decls ) {
127 if ( decl->linkage.is_generatable && (doIntrinsics || !decl->linkage.is_builtin ) ) {
128 cgv.core.updateLocation( decl );
129 decl->accept( cgv );
130 if ( doSemicolon( decl ) ) {
131 os << ";";
132 }
133 os << cgv.core.endl;
134 }
135 }
136}
137
[51b73452]138} // namespace CodeGen
[51587aa]139
140// Local Variables: //
141// tab-width: 4 //
142// mode: c++ //
143// compile-command: "make install" //
144// End: //
Note: See TracBrowser for help on using the repository browser.