source: translator/GenPoly/Lvalue.cc@ 643a2e1

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since 643a2e1 was 51b73452, checked in by Peter A. Buhr <pabuhr@…>, 11 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.