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