forked from lcompilers/lpython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclass_constructor.cpp
More file actions
123 lines (100 loc) · 3.8 KB
/
Copy pathclass_constructor.cpp
File metadata and controls
123 lines (100 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <libasr/asr.h>
#include <libasr/containers.h>
#include <libasr/exception.h>
#include <libasr/asr_utils.h>
#include <libasr/asr_verify.h>
#include <libasr/pass/replace_class_constructor.h>
#include <libasr/pass/pass_utils.h>
#include <vector>
#include <utility>
namespace LCompilers {
using ASR::down_cast;
using ASR::is_a;
class ReplaceStructTypeConstructor: public ASR::BaseExprReplacer<ReplaceStructTypeConstructor> {
public:
Allocator& al;
Vec<ASR::stmt_t*>& pass_result;
bool& remove_original_statement;
SymbolTable* current_scope;
ASR::expr_t* result_var;
ReplaceStructTypeConstructor(Allocator& al_, Vec<ASR::stmt_t*>& pass_result_,
bool& remove_original_statement_) :
al(al_), pass_result(pass_result_),
remove_original_statement(remove_original_statement_),
current_scope(nullptr), result_var(nullptr) {}
void replace_StructTypeConstructor(ASR::StructTypeConstructor_t* x) {
Vec<ASR::stmt_t*>* result_vec = &pass_result;
PassUtils::ReplacerUtils::replace_StructTypeConstructor(
x, this, false, remove_original_statement, result_vec);
}
};
class StructTypeConstructorVisitor : public ASR::CallReplacerOnExpressionsVisitor<StructTypeConstructorVisitor>
{
private:
Allocator& al;
bool remove_original_statement;
ReplaceStructTypeConstructor replacer;
Vec<ASR::stmt_t*> pass_result;
public:
StructTypeConstructorVisitor(Allocator& al_) :
al(al_), remove_original_statement(false),
replacer(al_, pass_result, remove_original_statement) {
pass_result.n = 0;
pass_result.reserve(al, 0);
}
void call_replacer() {
replacer.current_expr = current_expr;
replacer.current_scope = current_scope;
replacer.replace_expr(*current_expr);
}
void transform_stmts(ASR::stmt_t **&m_body, size_t &n_body) {
Vec<ASR::stmt_t*> body;
body.reserve(al, n_body);
for (size_t i = 0; i < n_body; i++) {
pass_result.n = 0;
pass_result.reserve(al, 1);
remove_original_statement = false;
replacer.result_var = nullptr;
visit_stmt(*m_body[i]);
for (size_t j = 0; j < pass_result.size(); j++) {
body.push_back(al, pass_result[j]);
}
if( !remove_original_statement ) {
body.push_back(al, m_body[i]);
}
remove_original_statement = false;
}
m_body = body.p;
n_body = body.size();
replacer.result_var = nullptr;
pass_result.n = 0;
pass_result.reserve(al, 0);
}
void visit_Variable(const ASR::Variable_t& /*x*/) {
// Do nothing, already handled in init_expr pass
}
void visit_Assignment(const ASR::Assignment_t &x) {
if (x.m_overloaded) {
this->visit_stmt(*x.m_overloaded);
remove_original_statement = false;
return ;
}
replacer.result_var = x.m_target;
ASR::expr_t** current_expr_copy_9 = current_expr;
current_expr = const_cast<ASR::expr_t**>(&(x.m_value));
this->call_replacer();
current_expr = current_expr_copy_9;
if( !remove_original_statement ) {
this->visit_expr(*x.m_value);
}
}
};
void pass_replace_class_constructor(Allocator &al,
ASR::TranslationUnit_t &unit,
const LCompilers::PassOptions& /*pass_options*/) {
StructTypeConstructorVisitor v(al);
v.visit_TranslationUnit(unit);
PassUtils::UpdateDependenciesVisitor w(al);
w.visit_TranslationUnit(unit);
}
} // namespace LCompilers