From eec0702135898f4d9790c7ac1558297fb0492cdb Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Wed, 24 Jan 2024 02:29:27 +0530 Subject: [PATCH 1/4] DEV: Added support for pre-declaring a function before defining --- src/lc/clang_ast_to_asr.h | 79 +++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/src/lc/clang_ast_to_asr.h b/src/lc/clang_ast_to_asr.h index 46bb510..12bac0d 100644 --- a/src/lc/clang_ast_to_asr.h +++ b/src/lc/clang_ast_to_asr.h @@ -1104,43 +1104,64 @@ class ClangASTtoASRVisitor: public clang::RecursiveASTVisitor(parent_scope); - std::string name = x->getName().str(); - Vec args; - args.reserve(al, 1); - for (auto &p : x->parameters()) { - TraverseDecl(p); - args.push_back(al, ASRUtils::EXPR(tmp.get())); - } + ASR::symbol_t* current_function_symbol = parent_scope->resolve_symbol(name); + ASR::Function_t* current_function = nullptr; + + if( current_function_symbol == nullptr ) { + current_scope = al.make_new(parent_scope); + Vec args; + args.reserve(al, 1); + for (auto &p : x->parameters()) { + TraverseDecl(p); + args.push_back(al, ASRUtils::EXPR(tmp.get())); + } - ASR::ttype_t* return_type = ClangTypeToASRType(x->getReturnType()); - ASR::symbol_t* return_sym = nullptr; - ASR::expr_t* return_var = nullptr; - if (return_type != nullptr) { - return_sym = ASR::down_cast(ASR::make_Variable_t(al, Lloc(x), - current_scope, s2c(al, "__return_var"), nullptr, 0, ASR::intentType::ReturnVar, nullptr, nullptr, - ASR::storage_typeType::Default, return_type, nullptr, ASR::abiType::Source, ASR::accessType::Public, - ASR::presenceType::Required, false)); - current_scope->add_symbol("__return_var", return_sym); - } + ASR::ttype_t* return_type = ClangTypeToASRType(x->getReturnType()); + ASR::symbol_t* return_sym = nullptr; + ASR::expr_t* return_var = nullptr; + if (return_type != nullptr) { + return_sym = ASR::down_cast(ASR::make_Variable_t(al, Lloc(x), + current_scope, s2c(al, "__return_var"), nullptr, 0, ASR::intentType::ReturnVar, nullptr, nullptr, + ASR::storage_typeType::Default, return_type, nullptr, ASR::abiType::Source, ASR::accessType::Public, + ASR::presenceType::Required, false)); + current_scope->add_symbol("__return_var", return_sym); + } - if (return_type != nullptr) { - return_var = ASRUtils::EXPR(ASR::make_Var_t(al, return_sym->base.loc, return_sym)); - } + if (return_type != nullptr) { + return_var = ASRUtils::EXPR(ASR::make_Var_t(al, return_sym->base.loc, return_sym)); + } - tmp = ASRUtils::make_Function_t_util(al, Lloc(x), current_scope, s2c(al, name), nullptr, 0, - args.p, args.size(), nullptr, 0, return_var, ASR::abiType::Source, ASR::accessType::Public, - ASR::deftypeType::Implementation, nullptr, false, false, false, false, false, nullptr, 0, - false, false, false); - ASR::symbol_t* current_function_symbol = ASR::down_cast(tmp.get()); - ASR::Function_t* current_function = ASR::down_cast(current_function_symbol); - parent_scope->add_symbol(name, current_function_symbol); + tmp = ASRUtils::make_Function_t_util(al, Lloc(x), current_scope, s2c(al, name), nullptr, 0, + args.p, args.size(), nullptr, 0, return_var, ASR::abiType::Source, ASR::accessType::Public, + ASR::deftypeType::Implementation, nullptr, false, false, false, false, false, nullptr, 0, + false, false, false); + current_function_symbol = ASR::down_cast(tmp.get()); + current_function = ASR::down_cast(current_function_symbol); + current_scope = current_function->m_symtab; + parent_scope->add_symbol(name, current_function_symbol); + } else { + current_function = ASR::down_cast(current_function_symbol); + current_scope = current_function->m_symtab; + for( size_t i = 0; i < current_function->n_args; i++ ) { + ASR::Var_t* argi = ASR::down_cast(current_function->m_args[i]); + if( current_scope->get_symbol(ASRUtils::symbol_name(argi->m_v)) == argi->m_v ) { + current_scope->erase_symbol(ASRUtils::symbol_name(argi->m_v)); + } + } + + int i = 0; + for (auto &p : x->parameters()) { + TraverseDecl(p); + current_function->m_args[i] = ASRUtils::EXPR(tmp.get()); + i++; + } + } Vec* current_body_copy = current_body; Vec body; body.reserve(al, 1); current_body = &body; - if( x->hasBody() ) { + if( x->doesThisDeclarationHaveABody() ) { TraverseStmt(x->getBody()); } current_body = current_body_copy; From 511125729be5c10601233daef987ad18e3c1496f Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Wed, 24 Jan 2024 02:29:53 +0530 Subject: [PATCH 2/4] TEST: Port integration_tests/functions_08.f90 from LFortran --- integration_tests/function_01.cpp | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 integration_tests/function_01.cpp diff --git a/integration_tests/function_01.cpp b/integration_tests/function_01.cpp new file mode 100644 index 0000000..094193c --- /dev/null +++ b/integration_tests/function_01.cpp @@ -0,0 +1,39 @@ +#include + +float f_real(const float); + +float f(const float a) { + float b, x; + x = 2; + b = a + f_real(0.0); + return b; +} + +float f_real(const float a) { + float b; + if( a == 0.0 ) { + b = 2.0; + } else { + b = a + f(1.0); + } + return b; +} + +int main() { + + float x = 5, y; + float p = 5, q; + float a, b, c; + y = f(x); + std::cout << y << std::endl; + if( y != 7.0 ) { + exit(2); + } + + q = f_real(p); + std::cout << q << std::endl; + if( q != 8.0 ) { + exit(2); + } + +} From 115529e8b8e43cb2bbd27d0fc9c45260f5d805e6 Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Wed, 24 Jan 2024 02:30:21 +0530 Subject: [PATCH 3/4] TEST: Added pre-declarations in array_18.cpp --- integration_tests/array_18.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/integration_tests/array_18.cpp b/integration_tests/array_18.cpp index a684abb..7a22b90 100644 --- a/integration_tests/array_18.cpp +++ b/integration_tests/array_18.cpp @@ -4,6 +4,9 @@ #include #include "xtensor/xio.hpp" +xt::xtensor solution(); +void compare_solutions(const xt::xtensor& y); + xt::xtensor solution() { xt::xtensor x = xt::empty({2}); x = {1.0, 2.0}; From 2d996f17626e3a72676a6ae5a3d8beb13e7bcec6 Mon Sep 17 00:00:00 2001 From: Gagandeep Singh Date: Wed, 24 Jan 2024 02:30:49 +0530 Subject: [PATCH 4/4] TEST: Register function_01.cpp --- integration_tests/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index da4ef29..7dd02f6 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -206,3 +206,5 @@ RUN(NAME array_20.cpp LABELS gcc llvm NOFAST) RUN(NAME array_21.cpp LABELS gcc llvm NOFAST) RUN(NAME array_22.cpp LABELS gcc llvm NOFAST) RUN(NAME array_23.cpp LABELS gcc llvm NOFAST) + +RUN(NAME function_01.cpp LABELS gcc llvm NOFAST)