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 | // FixInit.h --
|
---|
8 | //
|
---|
9 | // Author : Rob Schluntz
|
---|
10 | // Created On : Wed Jan 13 16:29:30 2016
|
---|
11 | // Last Modified By : Rob Schluntz
|
---|
12 | // Last Modified On : Tue Jan 19 16:36:59 2016
|
---|
13 | // Update Count : 30
|
---|
14 | //
|
---|
15 |
|
---|
16 | #include <stack>
|
---|
17 | #include <list>
|
---|
18 | #include "RemoveInit.h"
|
---|
19 | #include "SynTree/Declaration.h"
|
---|
20 | #include "SynTree/Type.h"
|
---|
21 | #include "SynTree/Expression.h"
|
---|
22 | #include "SynTree/Statement.h"
|
---|
23 | #include "SynTree/Initializer.h"
|
---|
24 | #include "SynTree/Mutator.h"
|
---|
25 | #include "GenPoly/PolyMutator.h"
|
---|
26 |
|
---|
27 | namespace InitTweak {
|
---|
28 | namespace {
|
---|
29 | const std::list<Label> noLabels;
|
---|
30 | }
|
---|
31 |
|
---|
32 | class FixInit : public GenPoly::PolyMutator {
|
---|
33 | public:
|
---|
34 | static void fixInitializers( std::list< Declaration * > &translationUnit );
|
---|
35 |
|
---|
36 | virtual ObjectDecl * mutate( ObjectDecl *objDecl );
|
---|
37 |
|
---|
38 | virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );
|
---|
39 | };
|
---|
40 |
|
---|
41 | void fix( std::list< Declaration * > & translationUnit ) {
|
---|
42 | FixInit::fixInitializers( translationUnit );
|
---|
43 | }
|
---|
44 |
|
---|
45 | void FixInit::fixInitializers( std::list< Declaration * > & translationUnit ) {
|
---|
46 | FixInit fixer;
|
---|
47 | mutateAll( translationUnit, fixer );
|
---|
48 | }
|
---|
49 |
|
---|
50 | // in the case where an object has an initializer and a polymorphic type, insert an assignment immediately after the
|
---|
51 | // declaration. This will (seemingly) cause the later phases to do the right thing with the assignment
|
---|
52 | ObjectDecl *FixInit::mutate( ObjectDecl *objDecl ) {
|
---|
53 | if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {
|
---|
54 | // a decision should have been made by the resolver, so ctor and init are not both non-NULL
|
---|
55 | assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
|
---|
56 | if ( Expression * ctor = ctorInit->get_ctor() ) {
|
---|
57 | ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
|
---|
58 | stmtsToAddAfter.push_back( ctorStmt );
|
---|
59 | objDecl->set_init( NULL );
|
---|
60 | ctorInit->set_ctor( NULL );
|
---|
61 | } else if ( Initializer * init = ctorInit->get_init() ) {
|
---|
62 | objDecl->set_init( init );
|
---|
63 | ctorInit->set_init( NULL );
|
---|
64 | } else {
|
---|
65 | // no constructor and no initializer, which is okay
|
---|
66 | objDecl->set_init( NULL );
|
---|
67 | }
|
---|
68 | delete ctorInit;
|
---|
69 | }
|
---|
70 | return objDecl;
|
---|
71 | }
|
---|
72 |
|
---|
73 | CompoundStmt * FixInit::mutate( CompoundStmt * compoundStmt ) {
|
---|
74 | std::list< Statement * > & statements = compoundStmt->get_kids();
|
---|
75 | for ( std::list< Statement * >::iterator it = statements.begin(); it != statements.end(); ) {
|
---|
76 | // remove if instrinsic destructor statement
|
---|
77 | // xxx - test user manually calling intrinsic functions - what happens?
|
---|
78 | if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( *it ) ) {
|
---|
79 | if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() ) ) {
|
---|
80 | if ( VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() ) ) {
|
---|
81 | if ( function->get_var()->get_name() == "^?{}" && function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
|
---|
82 | statements.erase(it++);
|
---|
83 | continue;
|
---|
84 | } else {
|
---|
85 | }
|
---|
86 | }
|
---|
87 | }
|
---|
88 | }
|
---|
89 | ++it;
|
---|
90 | }
|
---|
91 | // mutate non-destructor statements
|
---|
92 | return PolyMutator::mutate( compoundStmt );
|
---|
93 | }
|
---|
94 |
|
---|
95 | } // namespace InitTweak
|
---|
96 |
|
---|
97 | // Local Variables: //
|
---|
98 | // tab-width: 4 //
|
---|
99 | // mode: c++ //
|
---|
100 | // compile-command: "make install" //
|
---|
101 | // End: //
|
---|