diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-08-22 13:59:00 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-22 13:59:00 +0000 |
commit | ac3be517de2c0ec596eeee754b863243cb071098 (patch) | |
tree | 9bef8c57466f78db9fd8444f33ed854c24187d16 /gcc/rust/backend | |
parent | e9746f445cf57c12f70d0016722835ec504cc655 (diff) | |
parent | 5a0e34b74aa6de092632bad2bee4883c5a23e036 (diff) | |
download | gcc-ac3be517de2c0ec596eeee754b863243cb071098.zip gcc-ac3be517de2c0ec596eeee754b863243cb071098.tar.gz gcc-ac3be517de2c0ec596eeee754b863243cb071098.tar.bz2 |
Merge #640
640: Optional Trait items constants r=philberty a=philberty
This adds more support for optional trait items such as constants.
Some fixes come along with this PR such as improved query-based
compilation for trait items which is now a canonical implementation for
qualified and normal paths in HIR.
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r-- | gcc/rust/backend/rust-compile-implitem.h | 98 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-item.h | 48 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 293 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.h | 11 |
4 files changed, 277 insertions, 173 deletions
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h index 7337154..bdeda22 100644 --- a/gcc/rust/backend/rust-compile-implitem.h +++ b/gcc/rust/backend/rust-compile-implitem.h @@ -34,11 +34,25 @@ class CompileInherentImplItem : public HIRCompileBase using Rust::Compile::HIRCompileBase::visit; public: - static void Compile (TyTy::BaseType *self, HIR::ImplItem *item, Context *ctx, - bool compile_fns, TyTy::BaseType *concrete = nullptr) + static Bexpression *Compile (TyTy::BaseType *self, HIR::ImplItem *item, + Context *ctx, bool compile_fns, + TyTy::BaseType *concrete = nullptr, + bool is_query_mode = false, + Location ref_locus = Location ()) { - CompileInherentImplItem compiler (self, ctx, compile_fns, concrete); + CompileInherentImplItem compiler (self, ctx, compile_fns, concrete, + ref_locus); item->accept_vis (compiler); + + if (is_query_mode + && ctx->get_backend ()->is_error_expression (compiler.reference)) + { + rust_error_at (ref_locus, "failed to compile impl item: %s", + item->as_string ().c_str ()); + rust_assert ( + !ctx->get_backend ()->is_error_expression (compiler.reference)); + } + return compiler.reference; } void visit (HIR::ConstantItem &constant) override @@ -63,6 +77,8 @@ public: ctx->push_const (const_expr); ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr); + + reference = const_expr; } void visit (HIR::Function &function) override @@ -104,8 +120,13 @@ public: { Bfunction *dummy = nullptr; if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy)) - ctx->insert_function_decl (fntype->get_ty_ref (), lookup, fntype); - + { + ctx->insert_function_decl (fntype->get_ty_ref (), lookup, + fntype); + } + reference + = ctx->get_backend ()->function_code_expression (lookup, + ref_locus); return; } } @@ -281,20 +302,25 @@ public: } ctx->pop_fn (); - ctx->push_function (fndecl); + + reference + = ctx->get_backend ()->function_code_expression (fndecl, ref_locus); } private: CompileInherentImplItem (TyTy::BaseType *self, Context *ctx, bool compile_fns, - TyTy::BaseType *concrete) + TyTy::BaseType *concrete, Location ref_locus) : HIRCompileBase (ctx), self (self), compile_fns (compile_fns), - concrete (concrete) + concrete (concrete), reference (ctx->get_backend ()->error_expression ()), + ref_locus (ref_locus) {} TyTy::BaseType *self; bool compile_fns; TyTy::BaseType *concrete; + Bexpression *reference; + Location ref_locus; }; class CompileTraitItem : public HIRCompileBase @@ -302,11 +328,47 @@ class CompileTraitItem : public HIRCompileBase using Rust::Compile::HIRCompileBase::visit; public: - static void Compile (TyTy::BaseType *self, HIR::TraitItem *item, Context *ctx, - TyTy::BaseType *concrete) + static Bexpression *Compile (TyTy::BaseType *self, HIR::TraitItem *item, + Context *ctx, TyTy::BaseType *concrete, + bool is_query_mode = false, + Location ref_locus = Location ()) { - CompileTraitItem compiler (self, ctx, concrete); + CompileTraitItem compiler (self, ctx, concrete, ref_locus); item->accept_vis (compiler); + + if (is_query_mode + && ctx->get_backend ()->is_error_expression (compiler.reference)) + { + rust_error_at (ref_locus, "failed to compile trait item: %s", + item->as_string ().c_str ()); + rust_assert ( + !ctx->get_backend ()->is_error_expression (compiler.reference)); + } + return compiler.reference; + } + + void visit (HIR::TraitItemConst &constant) override + { + rust_assert (concrete != nullptr); + TyTy::BaseType *resolved_type = concrete; + + ::Btype *type = TyTyResolveCompile::compile (ctx, resolved_type); + Bexpression *value + = CompileExpr::Compile (constant.get_expr ().get (), ctx); + + const Resolver::CanonicalPath *canonical_path = nullptr; + rust_assert (ctx->get_mappings ()->lookup_canonical_path ( + constant.get_mappings ().get_crate_num (), + constant.get_mappings ().get_nodeid (), &canonical_path)); + + std::string ident = canonical_path->get (); + Bexpression *const_expr = ctx->get_backend ()->named_constant_expression ( + type, constant.get_name (), value, constant.get_locus ()); + + ctx->push_const (const_expr); + ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr); + + reference = const_expr; } void visit (HIR::TraitItemFunc &func) override @@ -330,6 +392,9 @@ public: ctx->insert_function_decl (fntype->get_ty_ref (), lookup, fntype); } + reference + = ctx->get_backend ()->function_code_expression (lookup, + ref_locus); return; } } @@ -499,16 +564,23 @@ public: ctx->pop_fn (); ctx->push_function (fndecl); + + reference + = ctx->get_backend ()->function_code_expression (fndecl, ref_locus); } private: CompileTraitItem (TyTy::BaseType *self, Context *ctx, - TyTy::BaseType *concrete) - : HIRCompileBase (ctx), self (self), concrete (concrete) + TyTy::BaseType *concrete, Location ref_locus) + : HIRCompileBase (ctx), self (self), concrete (concrete), + reference (ctx->get_backend ()->error_expression ()), + ref_locus (ref_locus) {} TyTy::BaseType *self; TyTy::BaseType *concrete; + Bexpression *reference; + Location ref_locus; }; } // namespace Compile diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h index af0bc43..eb7d9ef 100644 --- a/gcc/rust/backend/rust-compile-item.h +++ b/gcc/rust/backend/rust-compile-item.h @@ -33,14 +33,28 @@ namespace Compile { class CompileItem : public HIRCompileBase { +protected: using Rust::Compile::HIRCompileBase::visit; public: - static void compile (HIR::Item *item, Context *ctx, bool compile_fns = true, - TyTy::BaseType *concrete = nullptr) + static Bexpression *compile (HIR::Item *item, Context *ctx, + bool compile_fns = true, + TyTy::BaseType *concrete = nullptr, + bool is_query_mode = false, + Location ref_locus = Location ()) { - CompileItem compiler (ctx, compile_fns, concrete); + CompileItem compiler (ctx, compile_fns, concrete, ref_locus); item->accept_vis (compiler); + + if (is_query_mode + && ctx->get_backend ()->is_error_expression (compiler.reference)) + { + rust_error_at (ref_locus, "failed to compile item: %s", + item->as_string ().c_str ()); + rust_assert ( + !ctx->get_backend ()->is_error_expression (compiler.reference)); + } + return compiler.reference; } void visit (HIR::StaticItem &var) override @@ -73,6 +87,8 @@ public: ctx->insert_var_decl (var.get_mappings ().get_hirid (), static_global); ctx->push_var (static_global); + + reference = ctx->get_backend ()->var_expression (static_global, ref_locus); } void visit (HIR::ConstantItem &constant) override @@ -98,6 +114,8 @@ public: ctx->push_const (const_expr); ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr); + + reference = const_expr; } void visit (HIR::Function &function) override @@ -139,8 +157,14 @@ public: { Bfunction *dummy = nullptr; if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy)) - ctx->insert_function_decl (fntype->get_ty_ref (), lookup, fntype); - + { + ctx->insert_function_decl (fntype->get_ty_ref (), lookup, + fntype); + } + + reference + = ctx->get_backend ()->function_code_expression (lookup, + ref_locus); return; } } @@ -287,6 +311,9 @@ public: ctx->pop_fn (); ctx->push_function (fndecl); + + reference + = ctx->get_backend ()->function_code_expression (fndecl, ref_locus); } void visit (HIR::ImplBlock &impl_block) override @@ -319,13 +346,18 @@ public: CompileItem::compile (item.get (), ctx, compile_fns); } -private: - CompileItem (Context *ctx, bool compile_fns, TyTy::BaseType *concrete) - : HIRCompileBase (ctx), compile_fns (compile_fns), concrete (concrete) +protected: + CompileItem (Context *ctx, bool compile_fns, TyTy::BaseType *concrete, + Location ref_locus) + : HIRCompileBase (ctx), compile_fns (compile_fns), concrete (concrete), + reference (ctx->get_backend ()->error_expression ()), + ref_locus (ref_locus) {} bool compile_fns; TyTy::BaseType *concrete; + Bexpression *reference; + Location ref_locus; }; } // namespace Compile diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index 1539378..98c04df 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -29,18 +29,18 @@ namespace Compile { void ResolvePathRef::visit (HIR::QualifiedPathInExpression &expr) { - resolve (expr.get_final_segment ().get_segment (), expr.get_mappings (), - expr.get_locus (), true); + resolved = resolve (expr.get_final_segment ().get_segment (), + expr.get_mappings (), expr.get_locus (), true); } void ResolvePathRef::visit (HIR::PathInExpression &expr) { - resolve (expr.get_final_segment ().get_segment (), expr.get_mappings (), - expr.get_locus (), false); + resolved = resolve (expr.get_final_segment ().get_segment (), + expr.get_mappings (), expr.get_locus (), false); } -void +Bexpression * ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, const Analysis::NodeMapping &mappings, Location expr_locus, bool is_qualified_path) @@ -54,7 +54,7 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, if (!ctx->get_resolver ()->lookup_definition (ref_node_id, &def)) { rust_error_at (expr_locus, "unknown reference for resolved name"); - return; + return ctx->get_backend ()->error_expression (); } ref_node_id = def.parent; } @@ -62,167 +62,165 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, // this can fail because it might be a Constructor for something // in that case the caller should attempt ResolvePathType::Compile if (ref_node_id == UNKNOWN_NODEID) - return; + { + rust_error_at (expr_locus, "unknown nodeid for path expr"); + return ctx->get_backend ()->error_expression (); + } HirId ref; if (!ctx->get_mappings ()->lookup_node_to_hir (mappings.get_crate_num (), ref_node_id, &ref)) { rust_error_at (expr_locus, "reverse call path lookup failure"); - return; + return ctx->get_backend ()->error_expression (); } // might be a constant - if (ctx->lookup_const_decl (ref, &resolved)) - return; + Bexpression *constant_expr; + if (ctx->lookup_const_decl (ref, &constant_expr)) + return constant_expr; // this might be a variable reference or a function reference Bvariable *var = nullptr; if (ctx->lookup_var_decl (ref, &var)) - { - resolved = ctx->get_backend ()->var_expression (var, expr_locus); - return; - } + return ctx->get_backend ()->var_expression (var, expr_locus); - // must be a function call but it might be a generic function which needs to - // be compiled first + // it might be a function call TyTy::BaseType *lookup = nullptr; bool ok = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &lookup); rust_assert (ok); - rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF); - TyTy::FnType *fntype = static_cast<TyTy::FnType *> (lookup); + if (lookup->get_kind () == TyTy::TypeKind::FNDEF) + { + TyTy::FnType *fntype = static_cast<TyTy::FnType *> (lookup); + Bfunction *fn = nullptr; + if (ctx->lookup_function_decl (fntype->get_ty_ref (), &fn)) + { + return ctx->get_backend ()->function_code_expression (fn, expr_locus); + } + } + + // let the query system figure it out + return query_compile (ref, lookup, final_segment, mappings, expr_locus, + is_qualified_path); +} - Bfunction *fn = nullptr; - if (!ctx->lookup_function_decl (lookup->get_ty_ref (), &fn)) +Bexpression * +ResolvePathRef::query_compile (HirId ref, TyTy::BaseType *lookup, + const HIR::PathIdentSegment &final_segment, + const Analysis::NodeMapping &mappings, + Location expr_locus, bool is_qualified_path) +{ + HIR::Item *resolved_item + = ctx->get_mappings ()->lookup_hir_item (mappings.get_crate_num (), ref); + bool is_hir_item = resolved_item != nullptr; + if (is_hir_item) + { + if (!lookup->has_subsititions_defined ()) + return CompileItem::compile (resolved_item, ctx, true, nullptr, true, + expr_locus); + else + return CompileItem::compile (resolved_item, ctx, true, lookup, true, + expr_locus); + } + else { - // it must resolve to some kind of HIR::Item or HIR::InheritImplItem - HIR::Item *resolved_item - = ctx->get_mappings ()->lookup_hir_item (mappings.get_crate_num (), - ref); - if (resolved_item != nullptr) + HirId parent_impl_id = UNKNOWN_HIRID; + HIR::ImplItem *resolved_item + = ctx->get_mappings ()->lookup_hir_implitem (mappings.get_crate_num (), + ref, &parent_impl_id); + bool is_impl_item = resolved_item != nullptr; + if (is_impl_item) { + rust_assert (parent_impl_id != UNKNOWN_HIRID); + HIR::Item *impl_ref + = ctx->get_mappings ()->lookup_hir_item (mappings.get_crate_num (), + parent_impl_id); + rust_assert (impl_ref != nullptr); + HIR::ImplBlock *impl = static_cast<HIR::ImplBlock *> (impl_ref); + + TyTy::BaseType *self = nullptr; + bool ok = ctx->get_tyctx ()->lookup_type ( + impl->get_type ()->get_mappings ().get_hirid (), &self); + rust_assert (ok); + if (!lookup->has_subsititions_defined ()) - CompileItem::compile (resolved_item, ctx); + return CompileInherentImplItem::Compile (self, resolved_item, ctx, + true, nullptr, true, + expr_locus); else - CompileItem::compile (resolved_item, ctx, true, lookup); + return CompileInherentImplItem::Compile (self, resolved_item, ctx, + true, lookup, true, + expr_locus); } else { - HirId parent_impl_id = UNKNOWN_HIRID; - HIR::ImplItem *resolved_item - = ctx->get_mappings ()->lookup_hir_implitem ( - mappings.get_crate_num (), ref, &parent_impl_id); - - if (resolved_item == nullptr) + // it might be resolved to a trait item + HIR::TraitItem *trait_item + = ctx->get_mappings ()->lookup_hir_trait_item ( + mappings.get_crate_num (), ref); + HIR::Trait *trait = ctx->get_mappings ()->lookup_trait_item_mapping ( + trait_item->get_mappings ().get_hirid ()); + + Resolver::TraitReference *trait_ref + = &Resolver::TraitReference::error_node (); + bool ok = ctx->get_tyctx ()->lookup_trait_reference ( + trait->get_mappings ().get_defid (), &trait_ref); + rust_assert (ok); + + TyTy::BaseType *receiver = nullptr; + ok = ctx->get_tyctx ()->lookup_receiver (mappings.get_hirid (), + &receiver); + rust_assert (ok); + + if (receiver->get_kind () == TyTy::TypeKind::PARAM) { - // it might be resolved to a trait item - HIR::TraitItem *trait_item - = ctx->get_mappings ()->lookup_hir_trait_item ( - mappings.get_crate_num (), ref); - HIR::Trait *trait - = ctx->get_mappings ()->lookup_trait_item_mapping ( - trait_item->get_mappings ().get_hirid ()); - - Resolver::TraitReference *trait_ref - = &Resolver::TraitReference::error_node (); - bool ok = ctx->get_tyctx ()->lookup_trait_reference ( - trait->get_mappings ().get_defid (), &trait_ref); - rust_assert (ok); - - TyTy::BaseType *receiver = nullptr; - ok = ctx->get_tyctx ()->lookup_receiver (mappings.get_hirid (), - &receiver); - rust_assert (ok); + TyTy::ParamType *p = static_cast<TyTy::ParamType *> (receiver); + receiver = p->resolve (); + } - if (receiver->get_kind () == TyTy::TypeKind::PARAM) - { - TyTy::ParamType *p - = static_cast<TyTy::ParamType *> (receiver); - receiver = p->resolve (); - } - - // the type resolver can only resolve type bounds to their trait - // item so its up to us to figure out if this path should resolve - // to an trait-impl-block-item or if it can be defaulted to the - // trait-impl-item's definition - std::vector<Resolver::PathProbeCandidate> candidates; - if (!is_qualified_path) - { - candidates - = Resolver::PathProbeType::Probe (receiver, final_segment, - true, false, true); - } - - if (candidates.size () == 0) - { - // this means we are defaulting back to the trait_item if - // possible - Resolver::TraitItemReference *trait_item_ref = nullptr; - bool ok = trait_ref->lookup_hir_trait_item (*trait_item, - &trait_item_ref); - rust_assert (ok); // found - rust_assert ( - trait_item_ref->is_optional ()); // has definition - - Analysis::NodeMapping trait_mappings - = trait_item_ref->get_parent_trait_mappings (); - auto associated_impl_id - = ctx->get_tyctx () - ->lookup_associated_impl_mapping_for_self ( - trait_mappings.get_hirid (), receiver); - - rust_assert (associated_impl_id != UNKNOWN_HIRID); - - Resolver::AssociatedImplTrait *associated = nullptr; - bool found_associated_trait_impl - = ctx->get_tyctx ()->lookup_associated_trait_impl ( - associated_impl_id, &associated); - rust_assert (found_associated_trait_impl); - associated->setup_associated_types (); - - CompileTraitItem::Compile ( - receiver, trait_item_ref->get_hir_trait_item (), ctx, - fntype); - - if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &fn)) - { - resolved = ctx->get_backend ()->error_expression (); - rust_error_at (expr_locus, - "forward declaration was not compiled"); - return; - } - } - else - { - Resolver::PathProbeCandidate &candidate = candidates.at (0); - rust_assert (candidate.is_impl_candidate ()); - - HIR::ImplBlock *impl = candidate.item.impl.parent; - HIR::ImplItem *impl_item = candidate.item.impl.impl_item; - - TyTy::BaseType *self = nullptr; - bool ok = ctx->get_tyctx ()->lookup_type ( - impl->get_type ()->get_mappings ().get_hirid (), &self); - rust_assert (ok); - - if (!lookup->has_subsititions_defined ()) - CompileInherentImplItem::Compile (self, impl_item, ctx, - true); - else - CompileInherentImplItem::Compile (self, impl_item, ctx, - true, lookup); - - lookup->set_ty_ref ( - impl_item->get_impl_mappings ().get_hirid ()); - } + // the type resolver can only resolve type bounds to their trait + // item so its up to us to figure out if this path should resolve + // to an trait-impl-block-item or if it can be defaulted to the + // trait-impl-item's definition + std::vector<Resolver::PathProbeCandidate> candidates + = Resolver::PathProbeImplTrait::Probe (receiver, final_segment, + trait_ref); + if (candidates.size () == 0) + { + // this means we are defaulting back to the trait_item if + // possible + Resolver::TraitItemReference *trait_item_ref = nullptr; + bool ok = trait_ref->lookup_hir_trait_item (*trait_item, + &trait_item_ref); + rust_assert (ok); // found + rust_assert (trait_item_ref->is_optional ()); // has definition + + Analysis::NodeMapping trait_mappings + = trait_item_ref->get_parent_trait_mappings (); + auto associated_impl_id + = ctx->get_tyctx ()->lookup_associated_impl_mapping_for_self ( + trait_mappings.get_hirid (), receiver); + + rust_assert (associated_impl_id != UNKNOWN_HIRID); + + Resolver::AssociatedImplTrait *associated = nullptr; + bool found_associated_trait_impl + = ctx->get_tyctx ()->lookup_associated_trait_impl ( + associated_impl_id, &associated); + rust_assert (found_associated_trait_impl); + associated->setup_associated_types (); + + return CompileTraitItem::Compile ( + receiver, trait_item_ref->get_hir_trait_item (), ctx, lookup, + true, expr_locus); } else { - rust_assert (parent_impl_id != UNKNOWN_HIRID); - HIR::Item *impl_ref = ctx->get_mappings ()->lookup_hir_item ( - mappings.get_crate_num (), parent_impl_id); - rust_assert (impl_ref != nullptr); - HIR::ImplBlock *impl = static_cast<HIR::ImplBlock *> (impl_ref); + Resolver::PathProbeCandidate &candidate = candidates.at (0); + rust_assert (candidate.is_impl_candidate ()); + + HIR::ImplBlock *impl = candidate.item.impl.parent; + HIR::ImplItem *impl_item = candidate.item.impl.impl_item; TyTy::BaseType *self = nullptr; bool ok = ctx->get_tyctx ()->lookup_type ( @@ -230,23 +228,20 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, rust_assert (ok); if (!lookup->has_subsititions_defined ()) - CompileInherentImplItem::Compile (self, resolved_item, ctx, - true); + return CompileInherentImplItem::Compile (self, impl_item, ctx, + true, nullptr, true, + expr_locus); else - CompileInherentImplItem::Compile (self, resolved_item, ctx, - true, lookup); - } - } + return CompileInherentImplItem::Compile (self, impl_item, ctx, + true, lookup, true, + expr_locus); - if (!ctx->lookup_function_decl (lookup->get_ty_ref (), &fn)) - { - resolved = ctx->get_backend ()->error_expression (); - rust_error_at (expr_locus, "forward declaration was not compiled"); - return; + lookup->set_ty_ref (impl_item->get_impl_mappings ().get_hirid ()); + } } } - resolved = ctx->get_backend ()->function_code_expression (fn, expr_locus); + return ctx->get_backend ()->error_expression (); } } // namespace Compile diff --git a/gcc/rust/backend/rust-compile-resolve-path.h b/gcc/rust/backend/rust-compile-resolve-path.h index 41067c8..2b50ec1 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.h +++ b/gcc/rust/backend/rust-compile-resolve-path.h @@ -54,9 +54,14 @@ private: : HIRCompileBase (ctx), resolved (ctx->get_backend ()->error_expression ()) {} - void resolve (const HIR::PathIdentSegment &final_segment, - const Analysis::NodeMapping &mappings, Location locus, - bool is_qualified_path); + Bexpression *resolve (const HIR::PathIdentSegment &final_segment, + const Analysis::NodeMapping &mappings, Location locus, + bool is_qualified_path); + + Bexpression *query_compile (HirId ref, TyTy::BaseType *lookup, + const HIR::PathIdentSegment &final_segment, + const Analysis::NodeMapping &mappings, + Location expr_locus, bool is_qualified_path); Bexpression *resolved; }; |