15#include <llvm/ADT/STLExtras.h>
16#include <llvm/ADT/StringMap.h>
17#include <llvm/ADT/StringMapEntry.h>
18#include <llvm/ADT/iterator.h>
19#include <llvm/IR/Constants.h>
20#include <llvm/IR/Use.h>
21#include <llvm/Support/Casting.h>
22#include <llvm/Support/ErrorHandling.h>
23#include <llvm/Support/raw_ostream.h>
33 auto cast_expr = std::make_unique<ast::ImplicitCastExpr>(expr->token_range(), move(expr), conv);
34 cast_expr->val_ty(target_type);
35 expr = move(cast_expr);
44 auto expr_ty = expr->ensure_ty();
45 auto compat = expr_ty.compatibility(*target_ty);
49 if (!compat.conv.empty())
62 throw std::runtime_error(
"Invalid implicit conversion ('"s + expr->ensure_ty().name() +
"' -> '" +
63 target_ty->name() +
"', " + std::to_string(expr->ensure_ty().kind()) +
" -> " +
64 std::to_string(target_ty->kind()) +
")");
70 if (val > std::numeric_limits<int32_t>::max())
85template <>
void TypeWalker::expression(
ast::Type& expr) {
86 expr.
val_ty(convert_type(expr));
87 if (
auto* qual_type = dyn_cast<ast::QualType>(&expr))
88 expression(*qual_type->base);
92 auto& type = *expr.
type;
100 for (
auto& i : structs) {
102 for (
auto& [k, v] : i.instantiations)
110 expression(*expr.
type);
111 auto base_type = convert_type(*expr.
type);
114 if (i.self_ty == base_type)
119 const bool consider_ctor_overloads = st !=
nullptr;
123 if (consider_ctor_overloads) {
125 ctor_overloads = all_ctor_overloads_by_type(*st, expr);
128 for (
auto& i : expr.
args) {
130 ctor_overloads.args.push_back(i.raw_ptr());
133 if (consider_ctor_overloads) {
134#ifdef YUME_SPEW_OVERLOAD_SELECTION
135 errs() <<
"\n*** BEGIN CTOR OVERLOAD EVALUATION ***\n";
136 errs() <<
"Constructors with matching types:\n";
137 ctor_overloads.dump(errs());
140 ctor_overloads.determine_valid_overloads();
142#ifdef YUME_SPEW_OVERLOAD_SELECTION
143 errs() <<
"\nViable overloads:\n";
144 ctor_overloads.dump(errs(),
true);
147 auto best_overload = ctor_overloads.best_viable_overload();
149#ifdef YUME_SPEW_OVERLOAD_SELECTION
150 errs() <<
"\nSelected overload:\n";
151 best_overload.dump(errs());
152 errs() <<
"\n*** END CTOR OVERLOAD EVALUATION ***\n\n";
155 auto& subs = best_overload.subs;
156 auto* selected = best_overload.fn;
157 YUME_ASSERT(subs.fully_substituted(),
"Constructors cannot be generic");
163 auto [already_existed, inst_fn] = selected->get_or_create_instantiation(subs);
164 if (!already_existed) {
167 auto& new_fn = inst_fn;
177 with_saved_scope([&] {
192 for (
auto [target, expr_arg, compat] : llvm::zip(selected->arg_types(), expr.
args, best_overload.compatibilities)) {
193 YUME_ASSERT(compat.valid,
"Invalid compatibility after overload already selected?????");
194 if (compat.conv.empty())
207 auto base_type = expr->ensure_ty().without_mut();
210 if (i.self_ty == base_type)
214 YUME_ASSERT(st !=
nullptr,
"Cannot duplicate non-struct type " + base_type.
name());
217 auto ctor_receiver = std::make_unique<ast::SelfType>(expr->token_range());
218 ctor_receiver->val_ty(base_type);
219 auto ctor_args = vector<ast::AnyExpr>{};
220 ctor_args.emplace_back(move(expr));
221 auto ctor_expr = std::make_unique<ast::CtorExpr>(ctor_receiver->token_range(), move(ctor_receiver), move(ctor_args));
222 ctor_expr->val_ty(base_type);
226 ctor_overloads = all_ctor_overloads_by_type(*st, *ctor_expr);
227 ctor_overloads.args.push_back(ctor_expr->args.front().raw_ptr());
229#ifdef YUME_SPEW_OVERLOAD_SELECTION
230 errs() <<
"\n*** BEGIN CTOR OVERLOAD EVALUATION ***\n";
231 errs() <<
"Constructors with matching types:\n";
232 ctor_overloads.dump(errs());
235 ctor_overloads.determine_valid_overloads();
237#ifdef YUME_SPEW_OVERLOAD_SELECTION
238 errs() <<
"\nViable overloads:\n";
239 ctor_overloads.dump(errs(),
true);
242 auto best_overload = ctor_overloads.best_viable_overload();
244#ifdef YUME_SPEW_OVERLOAD_SELECTION
245 errs() <<
"\nSelected overload:\n";
246 best_overload.dump(errs());
247 errs() <<
"\n*** END CTOR OVERLOAD EVALUATION ***\n\n";
250 auto& subs = best_overload.subs;
251 auto* selected = best_overload.fn;
253 YUME_ASSERT(subs.fully_substituted(),
"Constructors cannot be generic");
259 auto [already_existed, inst_fn] = selected->get_or_create_instantiation(subs);
260 if (!already_existed) {
263 auto& new_fn = inst_fn;
273 with_saved_scope([&] {
275 current_decl = &new_fn;
276 body_statement(new_fn.ast());
279 decl_queue.emplace(&new_fn);
288 auto target = selected->arg_types().front();
289 auto& expr_arg = ctor_expr->args.front();
290 auto compat = best_overload.compatibilities.front();
291 YUME_ASSERT(compat.valid,
"Invalid compatibility after overload already selected?????");
292 if (!compat.conv.empty())
294 expr = move(ctor_expr);
300 for (
auto& i : expr.
args)
303 auto& slice_base = *expr.
type;
304 expression(slice_base);
305 auto base_type = create_slice_type(convert_type(slice_base));
313 with_saved_scope([&] {
317 auto arg_types = vector<ty::Type>{};
318 auto ret_type = optional<ty::Type>{};
320 for (
auto& i : expr.
args) {
322 scope.add(i.name, &i);
323 arg_types.push_back(i.ensure_ty());
327 expression(*expr.ret);
328 ret_type = expr.ret->ensure_ty();
333 auto closured_types = vector<ty::Type>();
335 closured_types.push_back(i.ast->ensure_ty());
346 YUME_ASSERT(expr.
args.size() > 1,
"Direct call must have at least 1 argument");
347 auto& base = *expr.
args.front();
351 const auto* base_ptr_ty = base.ensure_ty().base_cast<
ty::Function>();
353 for (
auto [target, expr_arg] : llvm::zip(base_ptr_ty->args(), llvm::drop_begin(expr.
args))) {
356 auto compat = expr_arg->ensure_ty().compatibility(target);
357 YUME_ASSERT(compat.valid,
"Invalid direct call with incompatible argument types");
358 if (compat.conv.empty())
364 expr.
val_ty(base_ptr_ty->ret());
384 if (
auto** var = outer_scope.find(expr.
name); var !=
nullptr) {
392 throw std::runtime_error(
"Scope doesn't contain variable called "s + expr.
name);
396 for (
const auto& cn :
compiler.m_consts)
397 if (cn.referred_to_by(expr))
398 return expr.
val_ty(cn.ast().ensure_ty());
399 throw std::runtime_error(
"Nonexistent constant called "s + expr.
name);
405 for (
auto* field : st.fields()) {
406 if (field->name == target_name) {
407 target_type = &field->type;
413 if (target_type ==
nullptr)
416 return {target_type, j};
420 optional<ty::Type> target_type;
422 if (ast_ptr !=
nullptr)
423 target_type = ast_ptr->raw_ptr()->val_ty();
425 return {target_type, j};
429 optional<ty::Type> type;
430 bool base_is_mut =
false;
434 type = expr.
base->ensure_ty();
436 if (type->is_mut()) {
437 type = type->mut_base();
445 if (!type.has_value())
446 llvm_unreachable(
"Type must be set in either branch above");
448 if (type->is_opaque_self())
451 const auto* struct_type = type->without_opaque().base_dyn_cast<
ty::Struct>();
453 if (struct_type ==
nullptr)
454 throw std::runtime_error(
"Can't access field of expression with non-struct type");
456 auto target_name = expr.
field;
457 auto [target_type, target_offset] =
find_field(*struct_type, target_name);
459 expr.
offset = target_offset;
460 expr.
val_ty(base_is_mut ? target_type->known_mut() : target_type);
464 auto fns_by_name = vector<Overload>();
466 for (
auto& fn : compiler.m_fns)
467 if (fn.name() == call.name)
468 fns_by_name.emplace_back(&fn);
473auto TypeWalker::all_ctor_overloads_by_type(Struct& st, ast::CtorExpr& call) -> OverloadSet {
474 auto ctors_by_type = vector<Overload>();
476 for (
auto& ctor : compiler.m_ctors)
477 if (ctor.self_ty && st.self_ty && *ctor.self_ty == st.self_ty->generic_base())
478 ctors_by_type.emplace_back(&ctor);
480 return OverloadSet{&call, ctors_by_type, {}};
484 auto name = expr.
name;
487 return direct_call_operator(expr);
489 auto overload_set = all_fn_overloads_by_name(expr);
491 if (overload_set.empty()) {
493 overload_set = all_fn_overloads_by_name(expr);
496 if (overload_set.empty())
497 throw std::logic_error(
"No function overload named "s + name);
502 for (
auto& i : expr.
args) {
504 overload_set.args.push_back(i.raw_ptr());
507#ifdef YUME_SPEW_OVERLOAD_SELECTION
508 errs() <<
"\n*** BEGIN FN OVERLOAD EVALUATION ***\n";
509 errs() <<
"Functions with matching names:\n";
510 overload_set.dump(errs());
513 overload_set.determine_valid_overloads();
515#ifdef YUME_SPEW_OVERLOAD_SELECTION
516 errs() <<
"\nViable overloads:\n";
517 overload_set.dump(errs(),
true);
520 const auto* maybe_best_overload = overload_set.try_best_viable_overload();
521 if (maybe_best_overload ==
nullptr && !
decl_queue.empty()) {
523 return expression(expr);
525 Overload best_overload = overload_set.best_viable_overload();
527#ifdef YUME_SPEW_OVERLOAD_SELECTION
528 errs() <<
"\nSelected overload:\n";
529 best_overload.
dump(errs());
530 errs() <<
"\n*** END FN OVERLOAD EVALUATION ***\n\n";
533 auto& subs = best_overload.
subs;
534 auto* selected = best_overload.
fn;
540 if (!already_existed) {
543 auto& new_fn = inst_fn;
553 with_saved_scope([&] {
567 for (
auto [target, expr_arg, compat] : llvm::zip(selected->arg_types(), expr.
args, best_overload.
compatibilities)) {
568 YUME_ASSERT(compat.valid,
"Invalid compatibility after overload already selected?????");
569 if (compat.conv.empty())
577 for (
const auto& expr_arg : llvm::enumerate(expr.
args)) {
578 if (expr_arg.index() >= selected->arg_count() && expr_arg.value()->ensure_ty().is_mut()) {
579 auto target_type = expr_arg.value()->ensure_ty().mut_base();
584 if (selected->ret().has_value())
595 YUME_ASSERT(expr.
lhs->ensure_ty() == bool_ty,
"BinaryLogicExpr lhs must be boolean");
596 YUME_ASSERT(expr.
rhs->ensure_ty() == bool_ty,
"BinaryLogicExpr rhs must be boolean");
601 expression(*expr.
type);
615 if (type_arg.type.has_value())
616 expression(*type_arg.type);
622 for (
auto& i : stat.
fields)
633 auto args = vector<ty::Type>();
634 auto ret = optional<ty::Type>();
636 for (
auto& i : stat.
args) {
639 args.push_back(i.ensure_ty());
643 expression(*stat.
ret);
645 ret = stat.
ret->ensure_ty();
654 if (
in_depth && std::holds_alternative<ast::Compound>(stat.
body))
655 statement(get<ast::Compound>(stat.
body));
657 YUME_ASSERT(
scope.
size() == 1,
"End of function should end with only the function scope remaining");
665 auto args = vector<ty::Type>();
667 if (struct_type ==
nullptr)
668 throw std::runtime_error(
"Can't define constructor of non-struct type");
671 for (
auto& i : stat.
args) {
674 args.push_back(i.ensure_ty());
677 for (
auto& i : stat.
args) {
689 statement(stat.
body);
691 YUME_ASSERT(
scope.
size() == 1,
"End of function should end with only the function scope remaining");
698 if (
auto* var_expr = dyn_cast<ast::VarExpr>(stat.
expr.
raw_ptr())) {
699 if (
auto** in_scope =
scope.
find(var_expr->name); in_scope !=
nullptr) {
700 if (
auto* var_decl = dyn_cast<ast::VarDecl>(*in_scope))
715 expression(*stat.
type);
726 stat.
val_ty(stat.
init->ensure_ty().known_mut());
731 expression(*stat.
type);
748 statement(*else_clause);
753 statement(stat.
body);
766 auto [already_existed, inst_struct] = struct_obj->get_or_create_instantiation(subs);
768 if (!already_existed) {
769 auto& new_st = inst_struct;
771 with_saved_scope([&] {
773 current_decl = &new_st;
774 body_statement(new_st.st_ast);
777 if (compiler.create_struct(new_st))
778 decl_queue.emplace(&new_st);
781 return *inst_struct.self_ty;
784auto TypeWalker::create_slice_type(
const ty::Type& base_type) -> ty::Type {
785 YUME_ASSERT(compiler.m_slice_struct !=
nullptr,
"Can't create slice type if a slice type was never defined");
786 Struct* struct_obj = compiler.m_slice_struct;
787 Substitutions subs = struct_obj->subs;
788 subs.associate(*subs.all_keys().at(0), {base_type});
789 return get_or_declare_instantiation(struct_obj, subs);
792auto TypeWalker::convert_type(ast::Type& ast_type) -> ty::Type {
793 auto parent = current_decl.self_ty();
794 const auto* context = current_decl.subs();
796 if (
const auto* simple_type = dyn_cast<ast::SimpleType>(&ast_type)) {
797 auto name = simple_type->name;
798 if (context !=
nullptr && !context->empty()) {
799 const auto*
generic = context->mapping_ref_or_null({name});
800 if (generic !=
nullptr && generic->holds_type())
801 return generic->as_type();
802 if (generic !=
nullptr && generic->unassigned())
803 return context->get_generic_fallback(name);
805 auto val = compiler.m_types.known.find(name);
806 if (val != compiler.m_types.known.end())
807 return val->second.get();
808 }
else if (
auto* qual_type = dyn_cast<ast::QualType>(&ast_type)) {
809 auto qualifier = qual_type->qualifier;
810 return convert_type(*qual_type->base).known_qual(qualifier);
811 }
else if (isa<ast::SelfType>(ast_type)) {
813 if (current_decl.opaque_self())
814 return {parent->known_opaque().base(), parent->is_mut(), parent->is_ref()};
815 return {parent->base(), parent->is_mut(), parent->is_ref()};
817 }
else if (
auto* proxy_type = dyn_cast<ast::ProxyType>(&ast_type)) {
819 if (
const auto* parent_struct = parent->base_dyn_cast<ty::Struct>()) {
820 auto [target_type, target_offset] =
find_field_ast(*parent_struct, proxy_type->field);
821 if (target_type !=
nullptr)
822 return convert_type(*target_type->raw_ptr());
823 throw std::runtime_error(
"Proxy type doesn't refer to a valid field?");
826 }
else if (
auto* fn_type = dyn_cast<ast::FunctionType>(&ast_type)) {
827 auto ret = optional<ty::Type>{};
828 auto args = vector<ty::Type>{};
829 if (
auto& ast_ret = fn_type->ret; ast_ret.has_value())
830 ret = convert_type(*ast_ret);
832 for (
auto& ast_arg : fn_type->args)
833 args.push_back(convert_type(*ast_arg));
836 return compiler.m_types.find_or_create_fn_ptr_type(args, ret);
837 return compiler.m_types.find_or_create_fn_type(args, ret, {});
838 }
else if (
auto* templated = dyn_cast<ast::TemplatedType>(&ast_type)) {
839 auto& template_base = *templated->base;
840 expression(template_base);
841 auto base_type = convert_type(template_base);
842 auto* struct_obj = base_type.base_cast<ty::Struct>()->decl();
844 if (struct_obj ==
nullptr)
845 throw std::logic_error(
"Can't add template arguments to non-struct types");
847 for (
auto& i : templated->type_args)
850 Substitutions gen_base = struct_obj->get_subs();
852 for (
const auto& [gen, gen_sub] : llvm::zip(gen_base.all_keys(), templated->type_args)) {
853 if (gen->holds_type()) {
854 gen_base.associate(*gen, {gen_sub.as_type()->ensure_ty()});
856 auto* expr = gen_sub.as_expr().raw_ptr();
857 auto expected_type = struct_obj->st_ast.type_args.at(i).type->
ensure_ty();
858 auto compat = expr->
ensure_ty().compatibility(expected_type);
859 YUME_ASSERT(compat.valid,
"Non-type generic argument type must match or be implicitly convertible (got `" +
860 expr->
ensure_ty().name() +
"', expected `" + expected_type.name() +
"')");
862 gen_base.associate(*gen, {expr});
870 return get_or_declare_instantiation(struct_obj, gen_base);
873 throw std::runtime_error(
"Cannot convert AST type to actual type! "s + ast_type.kind_name() +
" (" +
874 ast_type.describe() +
")");
882 with_saved_scope([&] {
883 next.visit([](std::monostate ) {},
auto declare(Fn &) -> llvm::Function *
Declare a function/constructor in bytecode, or get an existing declaration.
auto add(std::string_view key, T object) noexcept
auto push_scope_guarded() noexcept -> ScopeContainerGuard< T >
auto find(std::string_view key) const noexcept -> nullable< const T * >
auto add_to_front(std::string_view key, T object) noexcept
auto size() noexcept -> size_t
void attach_to(nonnull< AST * > other)
Make the type of this node depend on the type of other.
auto val_ty() const noexcept -> optional< ty::Type >
auto kind_name() const -> string
Human-readable string representation of the Kind of this node.
auto ensure_ty() const -> ty::Type
auto raw_ptr() const -> const T *
Expressions have an associated value and type.
auto has_value() const -> bool
auto raw_ptr() const -> const T *
Statements make up most things in source code.
A type annotation. This (ast::Type) is distinct from the actual type of a value (ty::Type).
An user-defined struct type with associated fields.
A "qualified" type, with a non-stackable qualifier, i.e. mut.
auto is_unqualified() const noexcept -> bool
auto known_meta() const -> Type
void make_implicit_conversion(ast::OptionalExpr &expr, optional< ty::Type > target_ty)
static auto for_all_instantiations(std::deque< Struct > &structs, std::invocable< Struct & > auto fn)
auto try_implicit_conversion(ast::OptionalExpr &expr, optional< ty::Type > target_ty) -> bool
void wrap_in_implicit_cast(ast::OptionalExpr &expr, ty::Conv conv, optional< ty::Type > target_type)
static auto find_field(const ty::Struct &st, string_view target_name) -> std::pair< optional< ty::Type >, int >
static auto find_field_ast(const ty::Struct &st, string_view target_name) -> std::pair< nullable< ast::AnyType * >, int >
auto body_statement(ast::Stmt &stat, auto &&... args)
auto body_expression(ast::Expr &expr, auto &&... args)
A constant declaration in the compiler.
auto fully_substituted() const noexcept -> bool
auto ast() const noexcept -> const ast::AST *
auto self_ty() const noexcept -> optional< ty::Type >
A function declaration in the compiler.
auto get_or_create_instantiation(Substitutions &subs) noexcept -> std::pair< bool, Fn & >
A struct declaration in the compiler.
auto name() const noexcept -> string
constexpr auto int8() -> IntTypePair
constexpr auto int64() -> IntTypePair
auto find_or_create_fn_ptr_type(const vector< ty::Type > &args, optional< ty::Type > ret, bool c_varargs=false) -> ty::Function *
auto find_or_create_fn_type(const vector< ty::Type > &args, optional< ty::Type > ret, const vector< ty::Type > &closure) -> ty::Function *
constexpr auto int32() -> IntTypePair
A logical operator such as || or &&. Since these aren't overloadable, they have their own AST node.
Bool literals (true or false).
A function call or operator.
Fn * selected_overload
During semantic analysis, the TypeWalker performs overload selection and saves the function declarati...
A statement consisting of multiple other statements, i.e. the body of a function.
A declaration of a constant (const).
A constant. Currently global.
A declaration of a custom constructor (def :new).
A construction of a struct or cast of a primitive.
Fn * selected_overload
During semantic analysis, the TypeWalker performs overload selection and saves the constructor declar...
Direct access of a field of a struct (::).
A declaration of a function (def).
Body body
If this function declaration refers to a primitive, this field is a string representing the name of t...
An if statement (if), with one or more IfClauses, and optionally an else clause.
optional< Compound > else_clause
vector< IfClause > clauses
Represents an implicit cast to a different type, performed during semantic analysis.
A local definition of an anonymous function.
vector< string > closured_names
vector< AST * > closured_nodes
Return from a function body.
VarDecl * extends_lifetime
A slice literal, i.e. an array.
A declaration of a struct (struct) or an interface (interface).
vector< GenericParam > type_args
vector< TypeName > fields
Represents a reference to a type.
A pair of a Type and an identifier, i.e. a parameter name.
A declaration of a local variable (let).
A variable, i.e. just an identifier.
vector< ty::Compat > compatibilities
void dump(llvm::raw_ostream &stream) const
auto make_dup(ast::AnyExpr &expr) -> Fn *
std::queue< DeclLike > decl_queue
void body_statement(ast::Stmt &)
void body_expression(ast::Expr &)
vector< ASTWithName > closured
vector< scope_t > enclosing_scopes
bool in_depth
Whether or not to compile the bodies of methods. Initially, on the parameter types of methods are tra...
#define YUME_ASSERT(assertion, message)