source: src/Tuples/Explode.cc @ bfc7811

new-envwith_gc
Last change on this file since bfc7811 was 8d7bef2, checked in by Aaron Moss <a3moss@…>, 7 years ago

First compiling build of CFA-CC with GC

  • Property mode set to 100644
File size: 4.1 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// Explode.cc --
8//
9// Author           : Rob Schluntz
10// Created On       : Wed Nov 9 13:12:24 2016
11// Last Modified By : Rob Schluntz
12// Last Modified On : Wed Nov 9 13:20:24 2016
13// Update Count     : 2
14//
15
16#include "Explode.h"
17#include <list>                  // for list
18
19#include "SynTree/Mutator.h"     // for Mutator
20#include "Common/PassVisitor.h"  // for PassVisitor
21
22namespace Tuples {
23        namespace {
24                // remove one level of reference from a reference type -- may be useful elsewhere.
25                Type * getReferenceBase( Type * t ) {
26                        if ( ReferenceType * refType = dynamic_cast<ReferenceType *>( t ) ) {
27                                return refType->get_base();
28                        } else {
29                                // for the moment, I want to know immediately if a non-reference type is ever passed in here.
30                                assertf( false, "getReferenceBase for non-ref: %s", toString( refType ).c_str() );
31                                return nullptr;
32                        }
33                }
34
35                struct CastExploder {
36                        bool castAdded = false;
37                        bool foundUniqueExpr = false;
38                        Expression * applyCast( Expression * expr, bool first = true ) {
39                                if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( expr ) ){
40                                        foundUniqueExpr = true;
41                                        std::list< Expression * > exprs;
42                                        for ( Expression *& expr : tupleExpr->get_exprs() ) {
43                                                // move cast into tuple exprs
44                                                exprs.push_back( applyCast( expr, false ) );
45                                        }
46                                        // want the top-level expression to be cast to reference type, but not nested
47                                        // tuple expressions
48                                        if ( first ) {
49                                                castAdded = true;
50                                                Expression * tupleExpr = new TupleExpr( exprs );
51                                                return new CastExpr( tupleExpr, new ReferenceType( Type::Qualifiers(), tupleExpr->result->clone() ) );
52                                        } else {
53                                                return new TupleExpr( exprs );
54                                        }
55                                }
56                                if ( dynamic_cast<ReferenceType*>( expr->result ) ) {
57                                        // don't need to cast reference type to another reference type
58                                        return expr->clone();
59                                } else {
60                                        // anything else should be cast to reference as normal
61                                        castAdded = true;
62                                        return new CastExpr( expr->clone(), new ReferenceType( Type::Qualifiers(), expr->result->clone() ) );
63                                }
64                        }
65
66                        Expression * postmutate( UniqueExpr * uniqueExpr ) {
67                                // move cast into unique expr so that the unique expr has type T& rather than
68                                // type T. In particular, this transformation helps with generating the
69                                // correct code for reference-cast member tuple expressions, since the result
70                                // should now be a tuple of references rather than a reference to a tuple.
71                                // Still, this code is a bit awkward, and could use some improvement.
72                                UniqueExpr * newUniqueExpr = new UniqueExpr{ applyCast( uniqueExpr->get_expr() ), uniqueExpr->get_id() };
73                                if ( castAdded ) {
74                                        // if a cast was added by applyCast, then unique expr now has one more layer of reference
75                                        // than it had coming into this function. To ensure types still match correctly, need to cast
76                                        //  to reference base so that outer expressions are still correct.
77                                        castAdded = false;
78                                        Type * toType = getReferenceBase( newUniqueExpr->result );
79                                        return new CastExpr( newUniqueExpr, toType->clone() );
80                                }
81                                return newUniqueExpr;
82                        }
83
84
85                        Expression * postmutate( TupleIndexExpr * tupleExpr ) {
86                                // tuple index expr needs to be rebuilt to ensure that the type of the
87                                // field is consistent with the type of the tuple expr, since the field
88                                // may have changed from type T to T&.
89                                return new TupleIndexExpr( tupleExpr->get_tuple(), tupleExpr->get_index() );
90                        }
91                };
92        } // namespace
93
94        Expression * distributeReference( Expression * expr ) {
95                PassVisitor<CastExploder> exploder;
96                expr = expr->acceptMutator( exploder );
97                if ( ! exploder.pass.foundUniqueExpr ) {
98                        // if a UniqueExpr was found, then the cast has already been added inside the UniqueExpr as appropriate
99                        expr = new CastExpr( expr, new ReferenceType( Type::Qualifiers(), expr->result->clone() ) );
100                }
101                return expr;
102        }
103} // namespace Tuples
104
105// Local Variables: //
106// tab-width: 4 //
107// mode: c++ //
108// compile-command: "make install" //
109// End: //
Note: See TracBrowser for help on using the repository browser.