Skip to content

Commit 55bb448

Browse files
authoredJan 23, 2024
Merge pull request #71 from czgdp1807/functions_01
Added support for pre-declaring functions before defining
2 parents c6bff74 + 2d996f1 commit 55bb448

File tree

4 files changed

+94
-29
lines changed

4 files changed

+94
-29
lines changed
 

‎integration_tests/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -206,3 +206,5 @@ RUN(NAME array_20.cpp LABELS gcc llvm NOFAST)
206206
RUN(NAME array_21.cpp LABELS gcc llvm NOFAST)
207207
RUN(NAME array_22.cpp LABELS gcc llvm NOFAST)
208208
RUN(NAME array_23.cpp LABELS gcc llvm NOFAST)
209+
210+
RUN(NAME function_01.cpp LABELS gcc llvm NOFAST)

‎integration_tests/array_18.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#include <xtensor/xfixed.hpp>
55
#include "xtensor/xio.hpp"
66

7+
xt::xtensor<double, 1> solution();
8+
void compare_solutions(const xt::xtensor<double, 1>& y);
9+
710
xt::xtensor<double, 1> solution() {
811
xt::xtensor<double, 1> x = xt::empty<double>({2});
912
x = {1.0, 2.0};

‎integration_tests/function_01.cpp

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include <iostream>
2+
3+
float f_real(const float);
4+
5+
float f(const float a) {
6+
float b, x;
7+
x = 2;
8+
b = a + f_real(0.0);
9+
return b;
10+
}
11+
12+
float f_real(const float a) {
13+
float b;
14+
if( a == 0.0 ) {
15+
b = 2.0;
16+
} else {
17+
b = a + f(1.0);
18+
}
19+
return b;
20+
}
21+
22+
int main() {
23+
24+
float x = 5, y;
25+
float p = 5, q;
26+
float a, b, c;
27+
y = f(x);
28+
std::cout << y << std::endl;
29+
if( y != 7.0 ) {
30+
exit(2);
31+
}
32+
33+
q = f_real(p);
34+
std::cout << q << std::endl;
35+
if( q != 8.0 ) {
36+
exit(2);
37+
}
38+
39+
}

‎src/lc/clang_ast_to_asr.h

+50-29
Original file line numberDiff line numberDiff line change
@@ -1104,43 +1104,64 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor<ClangASTtoASRVisit
11041104

11051105
bool TraverseFunctionDecl(clang::FunctionDecl *x) {
11061106
SymbolTable* parent_scope = current_scope;
1107-
current_scope = al.make_new<SymbolTable>(parent_scope);
1108-
11091107
std::string name = x->getName().str();
1110-
Vec<ASR::expr_t*> args;
1111-
args.reserve(al, 1);
1112-
for (auto &p : x->parameters()) {
1113-
TraverseDecl(p);
1114-
args.push_back(al, ASRUtils::EXPR(tmp.get()));
1115-
}
1108+
ASR::symbol_t* current_function_symbol = parent_scope->resolve_symbol(name);
1109+
ASR::Function_t* current_function = nullptr;
1110+
1111+
if( current_function_symbol == nullptr ) {
1112+
current_scope = al.make_new<SymbolTable>(parent_scope);
1113+
Vec<ASR::expr_t*> args;
1114+
args.reserve(al, 1);
1115+
for (auto &p : x->parameters()) {
1116+
TraverseDecl(p);
1117+
args.push_back(al, ASRUtils::EXPR(tmp.get()));
1118+
}
11161119

1117-
ASR::ttype_t* return_type = ClangTypeToASRType(x->getReturnType());
1118-
ASR::symbol_t* return_sym = nullptr;
1119-
ASR::expr_t* return_var = nullptr;
1120-
if (return_type != nullptr) {
1121-
return_sym = ASR::down_cast<ASR::symbol_t>(ASR::make_Variable_t(al, Lloc(x),
1122-
current_scope, s2c(al, "__return_var"), nullptr, 0, ASR::intentType::ReturnVar, nullptr, nullptr,
1123-
ASR::storage_typeType::Default, return_type, nullptr, ASR::abiType::Source, ASR::accessType::Public,
1124-
ASR::presenceType::Required, false));
1125-
current_scope->add_symbol("__return_var", return_sym);
1126-
}
1120+
ASR::ttype_t* return_type = ClangTypeToASRType(x->getReturnType());
1121+
ASR::symbol_t* return_sym = nullptr;
1122+
ASR::expr_t* return_var = nullptr;
1123+
if (return_type != nullptr) {
1124+
return_sym = ASR::down_cast<ASR::symbol_t>(ASR::make_Variable_t(al, Lloc(x),
1125+
current_scope, s2c(al, "__return_var"), nullptr, 0, ASR::intentType::ReturnVar, nullptr, nullptr,
1126+
ASR::storage_typeType::Default, return_type, nullptr, ASR::abiType::Source, ASR::accessType::Public,
1127+
ASR::presenceType::Required, false));
1128+
current_scope->add_symbol("__return_var", return_sym);
1129+
}
11271130

1128-
if (return_type != nullptr) {
1129-
return_var = ASRUtils::EXPR(ASR::make_Var_t(al, return_sym->base.loc, return_sym));
1130-
}
1131+
if (return_type != nullptr) {
1132+
return_var = ASRUtils::EXPR(ASR::make_Var_t(al, return_sym->base.loc, return_sym));
1133+
}
11311134

1132-
tmp = ASRUtils::make_Function_t_util(al, Lloc(x), current_scope, s2c(al, name), nullptr, 0,
1133-
args.p, args.size(), nullptr, 0, return_var, ASR::abiType::Source, ASR::accessType::Public,
1134-
ASR::deftypeType::Implementation, nullptr, false, false, false, false, false, nullptr, 0,
1135-
false, false, false);
1136-
ASR::symbol_t* current_function_symbol = ASR::down_cast<ASR::symbol_t>(tmp.get());
1137-
ASR::Function_t* current_function = ASR::down_cast<ASR::Function_t>(current_function_symbol);
1138-
parent_scope->add_symbol(name, current_function_symbol);
1135+
tmp = ASRUtils::make_Function_t_util(al, Lloc(x), current_scope, s2c(al, name), nullptr, 0,
1136+
args.p, args.size(), nullptr, 0, return_var, ASR::abiType::Source, ASR::accessType::Public,
1137+
ASR::deftypeType::Implementation, nullptr, false, false, false, false, false, nullptr, 0,
1138+
false, false, false);
1139+
current_function_symbol = ASR::down_cast<ASR::symbol_t>(tmp.get());
1140+
current_function = ASR::down_cast<ASR::Function_t>(current_function_symbol);
1141+
current_scope = current_function->m_symtab;
1142+
parent_scope->add_symbol(name, current_function_symbol);
1143+
} else {
1144+
current_function = ASR::down_cast<ASR::Function_t>(current_function_symbol);
1145+
current_scope = current_function->m_symtab;
1146+
for( size_t i = 0; i < current_function->n_args; i++ ) {
1147+
ASR::Var_t* argi = ASR::down_cast<ASR::Var_t>(current_function->m_args[i]);
1148+
if( current_scope->get_symbol(ASRUtils::symbol_name(argi->m_v)) == argi->m_v ) {
1149+
current_scope->erase_symbol(ASRUtils::symbol_name(argi->m_v));
1150+
}
1151+
}
1152+
1153+
int i = 0;
1154+
for (auto &p : x->parameters()) {
1155+
TraverseDecl(p);
1156+
current_function->m_args[i] = ASRUtils::EXPR(tmp.get());
1157+
i++;
1158+
}
1159+
}
11391160

11401161
Vec<ASR::stmt_t*>* current_body_copy = current_body;
11411162
Vec<ASR::stmt_t*> body; body.reserve(al, 1);
11421163
current_body = &body;
1143-
if( x->hasBody() ) {
1164+
if( x->doesThisDeclarationHaveABody() ) {
11441165
TraverseStmt(x->getBody());
11451166
}
11461167
current_body = current_body_copy;

0 commit comments

Comments
 (0)