Skip to content

Commit 622b084

Browse files
authored
Merge pull request #1198 from czgdp1807/sizeof
Adding support for ``sizeof`` in LLVM/C backend
2 parents cd92044 + f095734 commit 622b084

File tree

12 files changed

+210
-5
lines changed

12 files changed

+210
-5
lines changed

integration_tests/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ RUN(NAME structs_03 LABELS llvm c)
255255
RUN(NAME structs_04 LABELS cpython llvm c)
256256
RUN(NAME structs_05 LABELS llvm c)
257257
RUN(NAME structs_06 LABELS cpython llvm c)
258+
RUN(NAME structs_07 LABELS llvm c
259+
EXTRAFILES structs_07b.c)
260+
RUN(NAME sizeof_01 LABELS llvm c
261+
EXTRAFILES sizeof_01b.c)
258262
RUN(NAME enum_01 LABELS cpython llvm c)
259263
RUN(NAME enum_02 LABELS cpython llvm)
260264
RUN(NAME enum_03 LABELS cpython llvm c)

integration_tests/sizeof_01.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from ltypes import sizeof, i64, i32, f32, f64, c32, c64, ccall, CPtr
2+
3+
@ccall
4+
def cmalloc(bytes: i64) -> CPtr:
5+
pass
6+
7+
@ccall
8+
def cfree(x: CPtr) -> bool:
9+
pass
10+
11+
@ccall
12+
def fill_carray(arr: CPtr, size: i32):
13+
pass
14+
15+
@ccall
16+
def sum_carray(arr: CPtr, size: i32) -> i64:
17+
pass
18+
19+
def test_sizeof():
20+
xi: i32 = 0
21+
yi: i64 = 0
22+
xf: f32 = 0.0
23+
yf: f64 = 0.0
24+
xz: c32 = complex(0, 0)
25+
yz: c64 = complex(0, 0)
26+
assert sizeof(xi) == sizeof(i32)
27+
assert sizeof(yi) == sizeof(i64)
28+
assert sizeof(xf) == sizeof(f32)
29+
assert sizeof(yf) == sizeof(f64)
30+
assert sizeof(xz) == sizeof(c32)
31+
assert sizeof(yz) == sizeof(c64)
32+
33+
34+
def test_c_array():
35+
summed_up: i64
36+
carray: CPtr = cmalloc(sizeof(i64) * 100)
37+
fill_carray(carray, 100)
38+
summed_up = sum_carray(carray, 100)
39+
print(summed_up)
40+
assert summed_up == int(5050)
41+
42+
test_sizeof()
43+
test_c_array()

integration_tests/sizeof_01b.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include "sizeof_01b.h"
2+
#include <stdio.h>
3+
4+
void* cmalloc(int64_t bytes) {
5+
return malloc(bytes);
6+
}
7+
8+
bool cfree(void* x) {
9+
free(x);
10+
return 1;
11+
}
12+
13+
void fill_carray(void* arr, int32_t size) {
14+
int64_t* arr_int = arr;
15+
for( int32_t i = 0; i < size; i++ ) {
16+
arr_int[i] = i + 1;
17+
}
18+
}
19+
20+
int64_t sum_carray(void* arr, int32_t size) {
21+
int64_t* arr_int = arr;
22+
int64_t sum = 0;
23+
for( int32_t i = 0; i < size; i++ ) {
24+
sum += arr_int[i];
25+
}
26+
return sum;
27+
}

integration_tests/sizeof_01b.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <inttypes.h>
2+
#include <stdbool.h>
3+
#include <stdlib.h>
4+
5+
void* cmalloc(int64_t bytes);
6+
bool cfree(void* x);
7+
void fill_carray(void* arr, int32_t size);
8+
int64_t sum_carray(void* arr, int32_t size);

integration_tests/structs_07.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from ltypes import i32, i64, i8, CPtr, sizeof, dataclass, ccall
2+
3+
@dataclass
4+
class A:
5+
x: i32
6+
y: i64
7+
z: i8
8+
9+
@ccall
10+
def cmalloc(bytes: i64) -> CPtr:
11+
pass
12+
13+
@ccall
14+
def cfree(x: CPtr) -> i32:
15+
pass
16+
17+
def call_malloc():
18+
x: CPtr = cmalloc(sizeof(A) * 20)
19+
assert cfree(x) == True
20+
21+
call_malloc()

integration_tests/structs_07b.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include "structs_07b.h"
2+
3+
void* cmalloc(int64_t bytes) {
4+
return malloc(bytes);
5+
}
6+
7+
bool cfree(void* x) {
8+
free(x);
9+
return 1;
10+
}

integration_tests/structs_07b.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include <inttypes.h>
2+
#include <stdbool.h>
3+
#include <stdlib.h>
4+
5+
void* cmalloc(int64_t bytes);
6+
bool cfree(void* x);

src/libasr/ASR.asdl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,8 @@ expr
306306
| IntegerBitLen(expr a, ttype type, expr? value)
307307
| Ichar(expr arg, ttype type, expr? value)
308308

309+
| SizeOfType(ttype arg, ttype type, expr? value)
310+
309311

310312
-- `len` in Character:
311313
-- >=0 ... the length of the string, known at compile time

src/libasr/asr_utils.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,27 @@ static inline Vec<char*> get_scope_names(Allocator &al, const SymbolTable *symta
938938
return scope_names;
939939
}
940940

941+
static inline ASR::expr_t* get_constant_expression_with_given_type(Allocator& al, ASR::ttype_t* asr_type) {
942+
switch (asr_type->type) {
943+
case ASR::ttypeType::Integer: {
944+
return ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, asr_type->base.loc, -1, asr_type));
945+
}
946+
case ASR::ttypeType::Real: {
947+
return ASRUtils::EXPR(ASR::make_RealConstant_t(al, asr_type->base.loc, 0.0, asr_type));
948+
}
949+
case ASR::ttypeType::Complex: {
950+
return ASRUtils::EXPR(ASR::make_ComplexConstant_t(al, asr_type->base.loc, 0.0, 0.0, asr_type));
951+
}
952+
case ASR::ttypeType::Logical: {
953+
return ASRUtils::EXPR(ASR::make_LogicalConstant_t(al, asr_type->base.loc, false, asr_type));
954+
}
955+
default: {
956+
throw LCompilersException("Not implemented " + std::to_string(asr_type->type));
957+
}
958+
}
959+
return nullptr;
960+
}
961+
941962
const ASR::intentType intent_local=ASR::intentType::Local; // local variable (not a dummy argument)
942963
const ASR::intentType intent_in =ASR::intentType::In; // dummy argument, intent(in)
943964
const ASR::intentType intent_out =ASR::intentType::Out; // dummy argument, intent(out)

src/libasr/codegen/asr_to_c_cpp.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,11 @@ R"(#include <stdio.h>
924924
}
925925
}
926926

927+
void visit_SizeOfType(const ASR::SizeOfType_t& x) {
928+
std::string c_type = get_c_type_from_ttype_t(x.m_arg);
929+
src = "sizeof(" + c_type + ")";
930+
}
931+
927932
void visit_StringSection(const ASR::StringSection_t& x) {
928933
self().visit_expr(*x.m_arg);
929934
std::string arg, left, right, step, left_present, rig_present;
@@ -1571,6 +1576,26 @@ R"(#include <stdio.h>
15711576
type_src = list_type_c;
15721577
break;
15731578
}
1579+
case ASR::ttypeType::Complex: {
1580+
if( kind == 4 ) {
1581+
if( is_c ) {
1582+
headers.insert("complex");
1583+
type_src = "float complex";
1584+
} else {
1585+
type_src = "std::complex<float>";
1586+
}
1587+
} else if( kind == 8 ) {
1588+
if( is_c ) {
1589+
headers.insert("complex");
1590+
type_src = "double complex";
1591+
} else {
1592+
type_src = "std::complex<double>";
1593+
}
1594+
} else {
1595+
throw CodeGenError(std::to_string(kind * 8) + "-bit floating points not yet supported.");
1596+
}
1597+
break;
1598+
}
15741599
default: {
15751600
throw CodeGenError("Type " + ASRUtils::type_to_str_python(t) + " not supported yet.");
15761601
}

0 commit comments

Comments
 (0)