source: translator/GenPoly/Lvalue.cc @ 51b7345

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since 51b7345 was 51b7345, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

initial commit

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/*
2 * This file is part of the Cforall project
3 *
4 * $Id: Lvalue.cc,v 1.5 2005/08/29 20:14:13 rcbilson Exp $
5 *
6 */
7
8#include <cassert>
9
10#include "Lvalue.h"
11
12#include "SynTree/Declaration.h"
13#include "SynTree/Type.h"
14#include "SynTree/Expression.h"
15#include "SynTree/Statement.h"
16#include "SynTree/Visitor.h"
17#include "SynTree/Mutator.h"
18#include "SymTab/Indexer.h"
19#include "ResolvExpr/Resolver.h"
20#include "ResolvExpr/typeops.h"
21
22#include "UniqueName.h"
23#include "utility.h"
24
25
26namespace GenPoly {
27
28namespace {
29
30const std::list<Label> noLabels;
31
32class Pass1 : public Mutator
33{
34public:
35  Pass1();
36 
37  virtual Expression *mutate( ApplicationExpr *appExpr );
38  virtual Statement *mutate( ReturnStmt *appExpr );
39  virtual DeclarationWithType *mutate( FunctionDecl *funDecl );
40
41private:
42  DeclarationWithType* retval;
43};
44
45class Pass2 : public Visitor
46{
47public:
48  virtual void visit( FunctionType *funType );
49
50private:
51};
52
53} // namespace
54
55void
56convertLvalue( std::list< Declaration* >& translationUnit )
57{
58  Pass1 p1;
59  Pass2 p2;
60  mutateAll( translationUnit, p1 );
61  acceptAll( translationUnit, p2 );
62}
63
64namespace {
65
66bool
67isLvalueRet( FunctionType *function )
68{
69  if( !function->get_returnVals().empty() ) {
70    return function->get_returnVals().front()->get_type()->get_isLvalue();
71  } else {
72    return false;
73  }
74}
75
76bool
77isIntrinsicApp( ApplicationExpr *appExpr )
78{
79  if( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( appExpr->get_function() ) ) {
80    return varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic;
81  } else {
82    return false;
83  }
84}
85
86Pass1::Pass1()
87{
88}
89
90DeclarationWithType* 
91Pass1::mutate( FunctionDecl *funcDecl )
92{
93  if( funcDecl->get_statements() ) {
94    DeclarationWithType* oldRetval = retval;
95    retval = 0;
96    if( !LinkageSpec::isBuiltin( funcDecl->get_linkage() ) && isLvalueRet( funcDecl->get_functionType() ) ) {
97      retval = funcDecl->get_functionType()->get_returnVals().front();
98    }
99    // fix expressions and return statements in this function
100    funcDecl->set_statements( funcDecl->get_statements()->acceptMutator( *this ) );
101    retval = oldRetval;
102  }
103  return funcDecl;
104}
105
106Expression* 
107Pass1::mutate( ApplicationExpr *appExpr )
108{
109  appExpr->get_function()->acceptMutator( *this );
110  mutateAll( appExpr->get_args(), *this );
111 
112  assert( !appExpr->get_function()->get_results().empty() );
113
114  PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
115  assert( pointer );
116  FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
117  assert( function );
118
119  std::string typeName;
120  if( isLvalueRet( function ) && !isIntrinsicApp( appExpr ) ) {
121    UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
122    deref->get_results().push_back( appExpr->get_results().front() );
123    appExpr->get_results().front() = new PointerType( Type::Qualifiers(), deref->get_results().front()->clone() );
124    deref->get_args().push_back( appExpr );
125    return deref;
126  } else {
127    return appExpr;
128  }
129}
130
131Statement* 
132Pass1::mutate(ReturnStmt *retStmt)
133{
134  if( retval && retStmt->get_expr() ) {
135    assert( !retStmt->get_expr()->get_results().empty() );
136    while( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
137      retStmt->set_expr( castExpr->get_arg() );
138      retStmt->get_expr()->set_env( castExpr->get_env() );
139      castExpr->set_env( 0 );
140      castExpr->set_arg( 0 );
141      delete castExpr;
142    }
143    if( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
144      retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) );
145    } else {
146      throw SemanticError( "Attempt to return non-lvalue from an lvalue-qualified function" );
147    }
148  }
149  return retStmt;
150}
151
152void 
153Pass2::visit( FunctionType *funType )
154{
155  std::string typeName;
156  if( isLvalueRet( funType ) ) {
157    DeclarationWithType *retParm = funType->get_returnVals().front();
158   
159    // make a new parameter that is a pointer to the type of the old return value
160    retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) );
161  }
162 
163  Visitor::visit( funType );
164}
165
166} // namespace
167
168} // namespace GenPoly
Note: See TracBrowser for help on using the repository browser.