source: src/CodeGen/Generate.cc @ f43146e4

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

Direct translation of code generation.

  • Property mode set to 100644
File size: 4.5 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// Generate.cc --
8//
9// Author           : Richard C. Bilson
10// Created On       : Mon May 18 07:44:20 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sun Feb 16 03:01:51 2020
13// Update Count     : 9
14//
15#include "Generate.h"
16
17#include <iostream>                  // for ostream, endl, operator<<
18#include <list>                      // for list
19#include <string>                    // for operator<<
20
21#include "CodeGeneratorNew.hpp"      // for CodeGenerator_new, doSemicolon, ...
22#include "CodeGenerator.h"           // for CodeGenerator, doSemicolon, oper...
23#include "GenType.h"                 // for genPrettyType
24#include "Common/PassVisitor.h"      // for PassVisitor
25#include "SynTree/LinkageSpec.h"     // for isBuiltin, isGeneratable
26#include "SynTree/BaseSyntaxNode.h"  // for BaseSyntaxNode
27#include "SynTree/Declaration.h"     // for Declaration
28#include "SynTree/Type.h"            // for Type
29
30using namespace std;
31
32namespace CodeGen {
33        namespace {
34                /// Removes misc. nodes that should not exist in CodeGen
35                struct TreeCleaner {
36                        void premutate( CompoundStmt * stmt );
37                        Statement * postmutate( ImplicitCtorDtorStmt * stmt );
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 );
45                        mutateAll( translationUnit, cleaner );
46                } // cleanTree
47        } // namespace
48
49        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC, bool lineMarks, bool printExprTypes ) {
50                cleanTree( translationUnit );
51
52                PassVisitor<CodeGenerator> cgv( os, pretty, generateC, lineMarks, printExprTypes );
53                for ( auto & dcl : translationUnit ) {
54                        if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) {
55                                cgv.pass.updateLocation( dcl );
56                                dcl->accept(cgv);
57                                if ( doSemicolon( dcl ) ) {
58                                        os << ";";
59                                } // if
60                                os << cgv.pass.endl;
61                        } // if
62                } // for
63        }
64
65        void generate( BaseSyntaxNode * node, std::ostream & os ) {
66                if ( Type * type = dynamic_cast< Type * >( node ) ) {
67                        os << genPrettyType( type, "" );
68                } else {
69                        PassVisitor<CodeGenerator> cgv( os, true, false, false, false );
70                        node->accept( cgv );
71                }
72                os << std::endl;
73        }
74
75        namespace {
76                void TreeCleaner::premutate( CompoundStmt * cstmt ) {
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
85                Statement * TreeCleaner::postmutate( ImplicitCtorDtorStmt * stmt ) {
86                        Statement * callStmt = nullptr;
87                        std::swap( stmt->callStmt, callStmt );
88                        delete stmt;
89                        return callStmt;
90                }
91
92                bool TreeCleaner::shouldClean( Declaration * decl ) {
93                        return dynamic_cast< TraitDecl * >( decl );
94                }
95        } // namespace
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
138} // namespace CodeGen
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.