Skip to content

Commit

Permalink
Fix passing ArrayItem, StructInstanceMember to BindC functions (
Browse files Browse the repository at this point in the history
  • Loading branch information
czgdp1807 committed Nov 4, 2022
1 parent 6b044df commit 959a6f1
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 5 deletions.
2 changes: 2 additions & 0 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ RUN(NAME bindc_03 LABELS llvm
EXTRAFILES bindc_03b.c)
RUN(NAME bindc_05 LABELS llvm c
EXTRAFILES bindc_05b.c)
RUN(NAME bindc_06 LABELS llvm c
EXTRAFILES bindc_06b.c)
RUN(NAME test_generics_01 LABELS cpython llvm)
RUN(NAME test_cmath LABELS cpython llvm c)
RUN(NAME test_complex LABELS cpython llvm c)
Expand Down
30 changes: 30 additions & 0 deletions integration_tests/bindc_06.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from ltypes import i32, f64, ccall, dataclass
from numpy import empty, int32, float64

@dataclass
class CompareOperator:
op_code: i32
op_name: str

@ccall
def compare_array_element(value1: i32, value2: f64, op: i32) -> i32:
pass

def test_arrays():
array1: i32[40] = empty(40, dtype=int32)
array2: f64[40] = empty(40, dtype=float64)
compare_operator: CompareOperator = CompareOperator(0, "<")
i: i32

for i in range(40):
array1[i] = i + 1
array2[i] = float(2*i + 1)

is_small: bool = True
for i in range(40):
is_small = is_small and bool(compare_array_element(array1[i], array2[i], compare_operator.op_code))

print(is_small)
assert is_small == True

test_arrays()
12 changes: 12 additions & 0 deletions integration_tests/bindc_06b.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "bindc_06b.h"

int32_t compare_array_element(int32_t value1, double value2, int32_t code) {
switch( code ) {
case 0:
return value1 <= value2;
case 1:
return value1 >= value2;
default:
return 0;
}
}
3 changes: 3 additions & 0 deletions integration_tests/bindc_06b.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include <inttypes.h>

int32_t compare_array_element(int32_t value1, double value2, int32_t code);
11 changes: 10 additions & 1 deletion src/libasr/codegen/asr_to_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,16 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
if( t->n_dims != 0 ) {
sub += " = " + value_var_name;
} else {
sub += " = &" + value_var_name;
sub += " = &" + value_var_name + ";\n";
ASR::StructType_t* der_type_t = ASR::down_cast<ASR::StructType_t>(
ASRUtils::symbol_get_past_external(t->m_derived_type));
for( auto itr: der_type_t->m_symtab->get_scope() ) {
if( ASRUtils::is_character(*ASRUtils::symbol_type(itr.second)) ) {
sub += indent + std::string(v.m_name) + "->" + itr.first + " = (char*) malloc(40 * sizeof(char));\n";
}
}
sub.pop_back();
sub.pop_back();
}
return sub;
} else {
Expand Down
11 changes: 7 additions & 4 deletions src/libasr/codegen/asr_to_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5865,10 +5865,13 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
uint64_t ptr_loads_copy = ptr_loads;
ptr_loads = !LLVM::is_llvm_struct(arg_type);
this->visit_expr_wrapper(x.m_args[i].m_value);
if( x_abi == ASR::abiType::BindC &&
ASR::is_a<ASR::CPtr_t>(*arg_type) &&
ASR::is_a<ASR::StructInstanceMember_t>(*x.m_args[i].m_value) ) {
tmp = LLVM::CreateLoad(*builder, tmp);
if( x_abi == ASR::abiType::BindC ) {
if( ASR::is_a<ASR::ArrayItem_t>(*x.m_args[i].m_value) ||
ASR::is_a<ASR::StructInstanceMember_t>(*x.m_args[i].m_value) ||
(ASR::is_a<ASR::CPtr_t>(*arg_type) &&
ASR::is_a<ASR::StructInstanceMember_t>(*x.m_args[i].m_value)) ) {
tmp = LLVM::CreateLoad(*builder, tmp);
}
}
llvm::Value *value = tmp;
ptr_loads = ptr_loads_copy;
Expand Down

0 comments on commit 959a6f1

Please sign in to comment.