source: src/Tuples/Explode.cc@ ac74057

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since ac74057 was 8135d4c, checked in by Rob Schluntz <rschlunt@…>, 8 years ago

Merge branch 'master' into references

  • Property mode set to 100644
File size: 4.2 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 delete uniqueExpr;
74 if ( castAdded ) {
75 // if a cast was added by applyCast, then unique expr now has one more layer of reference
76 // than it had coming into this function. To ensure types still match correctly, need to cast
77 // to reference base so that outer expressions are still correct.
78 castAdded = false;
79 Type * toType = getReferenceBase( newUniqueExpr->result );
80 return new CastExpr( newUniqueExpr, toType->clone() );
81 }
82 return newUniqueExpr;
83 }
84
85
86 Expression * postmutate( TupleIndexExpr * tupleExpr ) {
87 // tuple index expr needs to be rebuilt to ensure that the type of the
88 // field is consistent with the type of the tuple expr, since the field
89 // may have changed from type T to T&.
90 Expression * expr = tupleExpr->get_tuple();
91 tupleExpr->set_tuple( nullptr );
92 TupleIndexExpr * ret = new TupleIndexExpr( expr, tupleExpr->get_index() );
93 delete tupleExpr;
94 return ret;
95 }
96 };
97 } // namespace
98
99 Expression * distributeReference( Expression * expr ) {
100 PassVisitor<CastExploder> exploder;
101 expr = expr->acceptMutator( exploder );
102 if ( ! exploder.pass.foundUniqueExpr ) {
103 // if a UniqueExpr was found, then the cast has already been added inside the UniqueExpr as appropriate
104 expr = new CastExpr( expr, new ReferenceType( Type::Qualifiers(), expr->result->clone() ) );
105 }
106 return expr;
107 }
108} // namespace Tuples
109
110// Local Variables: //
111// tab-width: 4 //
112// mode: c++ //
113// compile-command: "make install" //
114// End: //
Note: See TracBrowser for help on using the repository browser.