diff --git a/.gitignore b/.gitignore index 3a2e5ec1f7..d1515a304b 100644 --- a/.gitignore +++ b/.gitignore @@ -168,4 +168,5 @@ src/lpython/parser/parser.tab.hh integration_tests/test_c_interop_01.c integration_tests/test_c_interop_01 integration_tests/test_c_interop_03 +integration_tests/test_c_interop_03.c integration_tests/test_c_interop_04 diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 336a9c20f4..3d450135db 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -154,7 +154,7 @@ RUN(NAME test_math_02 LABELS cpython llvm) RUN(NAME test_c_interop_01 LABELS cpython llvm c) RUN(NAME test_c_interop_02 LABELS cpython llvm c EXTRAFILES test_c_interop_02b.c) -RUN(NAME test_c_interop_03 LABELS llvm +RUN(NAME test_c_interop_03 LABELS llvm c EXTRAFILES test_c_interop_03b.c) RUN(NAME test_c_interop_04 LABELS llvm EXTRAFILES test_c_interop_04b.c) diff --git a/integration_tests/test_c_interop_03.py b/integration_tests/test_c_interop_03.py index 368c86fe10..45eb583a17 100644 --- a/integration_tests/test_c_interop_03.py +++ b/integration_tests/test_c_interop_03.py @@ -26,17 +26,20 @@ def test_c_callbacks(): xi64: i64 xi64 = 3 - p_c_pointer(xi64, p) + p_c_pointer(pointer(xi64), p) + print(pointer(xi64), p) assert f_pi64_i32(p) == 4 xf32: f32 xf32 = 3.3 - p_c_pointer(xf32, p) + p_c_pointer(pointer(xf32), p) + print(pointer(xf32), p) assert abs(f_pf32_i32(p)-4.3) < 1e-6 xf64: f64 xf64 = 3.3 - p_c_pointer(xf64, p) + p_c_pointer(pointer(xf64), p) + print(pointer(xf64), p) assert abs(f_pf64_i32(p)-4.3) < 1e-12 test_c_callbacks() diff --git a/src/libasr/asr_utils.h b/src/libasr/asr_utils.h index fdba65e715..b22ed8e689 100644 --- a/src/libasr/asr_utils.h +++ b/src/libasr/asr_utils.h @@ -197,7 +197,10 @@ static inline std::string type_to_str_python(const ASR::ttype_t *t) ASR::List_t *l = (ASR::List_t *)t; return "list[" + type_to_str_python(l->m_type) + "]"; } - default : throw LFortranException("Not implemented"); + case ASR::ttypeType::CPtr: { + return "CPtr"; + } + default : throw LFortranException("Not implemented " + std::to_string(t->type)); } } diff --git a/src/libasr/codegen/asr_to_c.cpp b/src/libasr/codegen/asr_to_c.cpp index a80a3cb8bc..b6308f6174 100644 --- a/src/libasr/codegen/asr_to_c.cpp +++ b/src/libasr/codegen/asr_to_c.cpp @@ -114,6 +114,8 @@ class ASRToCVisitor : public BaseCCPPVisitor ASR::Derived_t *t = ASR::down_cast(v.m_type); std::string dims = convert_dims_c(t->n_dims, t->m_dims); sub = format_type_c(dims, "struct", v.m_name, use_ref, dummy); + } else if (ASR::is_a(*v.m_type)) { + sub = format_type_c("", "void*", v.m_name, false, false); } else { diag.codegen_error_label("Type number '" + std::to_string(v.m_type->type) @@ -333,6 +335,12 @@ R"( case ASR::ttypeType::Character: { return "%s"; } + case ASR::ttypeType::CPtr: { + return "%p"; + } + case ASR::ttypeType::Pointer: { + return "%p"; + } default : throw LFortranException("Not implemented"); } } diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index a8cfd36e51..8575f1b2da 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -685,6 +685,42 @@ R"(#include } } + std::string get_c_type_from_ttype_t(ASR::ttype_t* t) { + std::string type_src = ""; + switch( t->type ) { + case ASR::ttypeType::Integer: { + type_src = "int"; + break; + } + case ASR::ttypeType::Pointer: { + ASR::Pointer_t* ptr_type = ASR::down_cast(t); + type_src = get_c_type_from_ttype_t(ptr_type->m_type) + "*"; + break; + } + case ASR::ttypeType::CPtr: { + type_src = "void*"; + break; + } + default: { + throw CodeGenError("Type " + ASRUtils::type_to_str_python(t) + " not supported yet."); + } + } + return type_src; + } + + void visit_GetPointer(const ASR::GetPointer_t& x) { + self().visit_expr(*x.m_arg); + std::string arg_src = std::move(src); + src = "&" + arg_src; + } + + void visit_PointerToCPtr(const ASR::PointerToCPtr_t& x) { + self().visit_expr(*x.m_arg); + std::string arg_src = std::move(src); + std::string type_src = get_c_type_from_ttype_t(x.m_type); + src = "(" + type_src + ") " + arg_src; + } + void visit_BinOp(const ASR::BinOp_t &x) { self().visit_expr(*x.m_left); std::string left = std::move(src);