@@ -1131,10 +1131,19 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
1131
1131
1132
1132
void visit_ListConstant (const ASR::ListConstant_t& x) {
1133
1133
ASR::List_t* list_type = ASR::down_cast<ASR::List_t>(x.m_type );
1134
- llvm::Type* llvm_el_type = get_el_type (list_type->m_type );
1134
+ bool is_array_type_local = false , is_malloc_array_type_local = false ;
1135
+ bool is_list_local = false ;
1136
+ ASR::dimension_t * m_dims_local = nullptr ;
1137
+ int n_dims_local = -1 , a_kind_local = -1 ;
1138
+ llvm::Type* llvm_el_type = get_type_from_ttype_t (list_type->m_type ,
1139
+ ASR::storage_typeType::Default, is_array_type_local,
1140
+ is_malloc_array_type_local, is_list_local, m_dims_local,
1141
+ n_dims_local, a_kind_local);
1135
1142
std::string type_code = ASRUtils::get_type_code (list_type->m_type );
1136
1143
int32_t type_size = -1 ;
1137
- if ( ASR::is_a<ASR::Character_t>(*list_type->m_type ) ) {
1144
+ if ( ASR::is_a<ASR::Character_t>(*list_type->m_type ) ||
1145
+ LLVM::is_llvm_struct (list_type->m_type ) ||
1146
+ ASR::is_a<ASR::Complex_t>(*list_type->m_type ) ) {
1138
1147
llvm::DataLayout data_layout (module .get ());
1139
1148
type_size = data_layout.getTypeAllocSize (llvm_el_type);
1140
1149
} else {
@@ -2603,6 +2612,31 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
2603
2612
return_type = tuple_api->get_tuple_type (type_code, llvm_el_types);
2604
2613
break ;
2605
2614
}
2615
+ case (ASR::ttypeType::List) : {
2616
+ bool is_array_type = false , is_malloc_array_type = false ;
2617
+ bool is_list = true ;
2618
+ ASR::dimension_t *m_dims = nullptr ;
2619
+ ASR::storage_typeType m_storage = ASR::storage_typeType::Default;
2620
+ int n_dims = 0 , a_kind = -1 ;
2621
+ ASR::List_t* asr_list = ASR::down_cast<ASR::List_t>(return_var_type0);
2622
+ llvm::Type* el_llvm_type = get_type_from_ttype_t (asr_list->m_type , m_storage,
2623
+ is_array_type,
2624
+ is_malloc_array_type,
2625
+ is_list, m_dims, n_dims,
2626
+ a_kind);
2627
+ int32_t type_size = -1 ;
2628
+ if ( LLVM::is_llvm_struct (asr_list->m_type ) ||
2629
+ ASR::is_a<ASR::Character_t>(*asr_list->m_type ) ||
2630
+ ASR::is_a<ASR::Complex_t>(*asr_list->m_type ) ) {
2631
+ llvm::DataLayout data_layout (module .get ());
2632
+ type_size = data_layout.getTypeAllocSize (el_llvm_type);
2633
+ } else {
2634
+ type_size = a_kind;
2635
+ }
2636
+ std::string el_type_code = ASRUtils::get_type_code (asr_list->m_type );
2637
+ return_type = list_api->get_list_type (el_llvm_type, el_type_code, type_size);
2638
+ break ;
2639
+ }
2606
2640
default :
2607
2641
LFORTRAN_ASSERT (false );
2608
2642
throw CodeGenError (" Type not implemented" );
@@ -3003,15 +3037,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
3003
3037
this ->visit_expr (*x.m_target );
3004
3038
llvm::Value* target_tuple = tmp;
3005
3039
ptr_loads = ptr_loads_copy;
3006
- if ( ASR::is_a<ASR::FunctionCall_t>(*x.m_value ) ) {
3007
- builder->CreateStore (value_tuple, target_tuple);
3008
- } else {
3009
- ASR::Tuple_t* value_tuple_type = ASR::down_cast<ASR::Tuple_t>(asr_value_type);
3010
- std::string type_code = ASRUtils::get_type_code (value_tuple_type->m_type ,
3011
- value_tuple_type->n_type );
3012
- tuple_api->tuple_deepcopy (value_tuple, target_tuple,
3013
- value_tuple_type, *module );
3014
- }
3040
+ ASR::Tuple_t* value_tuple_type = ASR::down_cast<ASR::Tuple_t>(asr_value_type);
3041
+ std::string type_code = ASRUtils::get_type_code (value_tuple_type->m_type ,
3042
+ value_tuple_type->n_type );
3043
+ tuple_api->tuple_deepcopy (value_tuple, target_tuple,
3044
+ value_tuple_type, *module );
3015
3045
}
3016
3046
return ;
3017
3047
}
@@ -5202,6 +5232,33 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
5202
5232
tmp = builder->CreateOr (arg1, arg2);
5203
5233
}
5204
5234
5235
+ llvm::Value* CreatePointerToStructReturnValue (llvm::FunctionType* fnty,
5236
+ llvm::Value* return_value,
5237
+ ASR::ttype_t * asr_return_type) {
5238
+ if ( !LLVM::is_llvm_struct (asr_return_type) ) {
5239
+ return return_value;
5240
+ }
5241
+
5242
+ // Call to LLVM APIs not needed to fetch the return type of the function.
5243
+ // We can use asr_return_type as well but anyways for compactness I did it here.
5244
+ llvm::Value* pointer_to_struct = builder->CreateAlloca (fnty->getReturnType (), nullptr );
5245
+ LLVM::CreateStore (*builder, return_value, pointer_to_struct);
5246
+ return pointer_to_struct;
5247
+ }
5248
+
5249
+ llvm::Value* CreateCallUtil (llvm::FunctionType* fnty, llvm::Function* fn,
5250
+ std::vector<llvm::Value*>& args,
5251
+ ASR::ttype_t * asr_return_type) {
5252
+ llvm::Value* return_value = builder->CreateCall (fn, args);
5253
+ return CreatePointerToStructReturnValue (fnty, return_value,
5254
+ asr_return_type);
5255
+ }
5256
+
5257
+ llvm::Value* CreateCallUtil (llvm::Function* fn, std::vector<llvm::Value*>& args,
5258
+ ASR::ttype_t * asr_return_type) {
5259
+ return CreateCallUtil (fn->getFunctionType (), fn, args, asr_return_type);
5260
+ }
5261
+
5205
5262
void visit_FunctionCall (const ASR::FunctionCall_t &x) {
5206
5263
if ( ASRUtils::is_intrinsic_optimization (x.m_name ) ) {
5207
5264
ASR::Function_t* routine = ASR::down_cast<ASR::Function_t>(
@@ -5295,8 +5352,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
5295
5352
std::string m_name = std::string (((ASR::Function_t*)(&(x.m_name ->base )))->m_name );
5296
5353
std::vector<llvm::Value *> args2 = convert_call_args (x, m_name);
5297
5354
args.insert (args.end (), args2.begin (), args2.end ());
5355
+ ASR::ttype_t *return_var_type0 = EXPR2VAR (s->m_return_var )->m_type ;
5298
5356
if (s->m_abi == ASR::abiType::BindC) {
5299
- ASR::ttype_t *return_var_type0 = EXPR2VAR (s->m_return_var )->m_type ;
5300
5357
if (is_a<ASR::Complex_t>(*return_var_type0)) {
5301
5358
int a_kind = down_cast<ASR::Complex_t>(return_var_type0)->m_kind ;
5302
5359
if (a_kind == 8 ) {
@@ -5316,7 +5373,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
5316
5373
tmp = builder->CreateCall (fn, args);
5317
5374
}
5318
5375
} else {
5319
- tmp = builder-> CreateCall (fn, args);
5376
+ tmp = CreateCallUtil (fn, args, return_var_type0 );
5320
5377
}
5321
5378
}
5322
5379
if (s->m_abi == ASR::abiType::BindC) {
0 commit comments