@@ -172,10 +172,13 @@ class SimpleIntrinsics
172
172
173
173
static tree
174
174
offset_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype);
175
+ static tree
176
+ sizeof_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype);
175
177
176
178
static const std::map<std::string,
177
179
std::function<tree (Context *, TyTy::BaseType *)>>
178
- generic_intrinsics = {{" offset" , &offset_intrinsic_handler}};
180
+ generic_intrinsics = {{" offset" , &offset_intrinsic_handler},
181
+ {" size_of" , &sizeof_intrinsic_handler}};
179
182
180
183
Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
181
184
@@ -308,5 +311,94 @@ offset_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
308
311
return fndecl;
309
312
}
310
313
314
+ static tree
315
+ sizeof_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
316
+ {
317
+ rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
318
+ TyTy::FnType *fntype = static_cast <TyTy::FnType *> (fntype_tyty);
319
+ const Resolver::CanonicalPath &canonical_path = fntype->get_ident ().path ;
320
+
321
+ // items can be forward compiled which means we may not need to invoke this
322
+ // code. We might also have already compiled this generic function as well.
323
+ tree lookup = NULL_TREE;
324
+ if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
325
+ fntype->get_id (), fntype))
326
+ {
327
+ // has this been added to the list then it must be finished
328
+ if (ctx->function_completed (lookup))
329
+ {
330
+ tree dummy = NULL_TREE;
331
+ if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
332
+ {
333
+ ctx->insert_function_decl (fntype, lookup);
334
+ }
335
+ return lookup;
336
+ }
337
+ }
338
+
339
+ if (fntype->has_subsititions_defined ())
340
+ {
341
+ // override the Hir Lookups for the substituions in this context
342
+ fntype->override_context ();
343
+ }
344
+
345
+ // offset intrinsic has two params dst pointer and offset isize
346
+ if (fntype->get_params ().size () != 0 )
347
+ {
348
+ rust_error_at (fntype->get_ident ().locus ,
349
+ " invalid number of parameters for size of intrinsic" );
350
+ return error_mark_node;
351
+ }
352
+
353
+ // get the template parameter type tree fn size_of<T>();
354
+ rust_assert (fntype->get_num_substitutions () == 1 );
355
+ auto ¶m_mapping = fntype->get_substs ().at (0 );
356
+ const TyTy::ParamType *param_tyty = param_mapping.get_param_ty ();
357
+ TyTy::BaseType *resolved_tyty = param_tyty->resolve ();
358
+ tree template_parameter_type
359
+ = TyTyResolveCompile::compile (ctx, resolved_tyty);
360
+
361
+ // build the intrinsic function
362
+ tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
363
+ std::string ir_symbol_name
364
+ = canonical_path.get () + fntype->subst_as_string ();
365
+ std::string asm_name = ctx->mangle_item (fntype, canonical_path);
366
+
367
+ unsigned int flags = 0 ;
368
+ tree fndecl
369
+ = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name, asm_name,
370
+ flags, fntype->get_ident ().locus );
371
+ TREE_PUBLIC (fndecl) = 0 ;
372
+ TREE_READONLY (fndecl) = 1 ;
373
+ DECL_ARTIFICIAL (fndecl) = 1 ;
374
+ DECL_EXTERNAL (fndecl) = 0 ;
375
+ DECL_DECLARED_INLINE_P (fndecl) = 1 ;
376
+
377
+ tree enclosing_scope = NULL_TREE;
378
+ Location start_location = Location ();
379
+ Location end_location = Location ();
380
+
381
+ tree code_block = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
382
+ start_location, end_location);
383
+ ctx->push_block (code_block);
384
+
385
+ // BUILTIN size_of FN BODY BEGIN
386
+ tree size_expr = TYPE_SIZE_UNIT (template_parameter_type);
387
+ auto return_statement
388
+ = ctx->get_backend ()->return_statement (fndecl, {size_expr}, Location ());
389
+ ctx->add_statement (return_statement);
390
+ // BUILTIN size_of FN BODY END
391
+
392
+ tree bind_tree = ctx->pop_block ();
393
+
394
+ gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
395
+ DECL_SAVED_TREE (fndecl) = bind_tree;
396
+
397
+ ctx->pop_fn ();
398
+ ctx->push_function (fndecl);
399
+
400
+ return fndecl;
401
+ }
402
+
311
403
} // namespace Compile
312
404
} // namespace Rust
0 commit comments