// Copyright (C) 2020-2022 Free Software Foundation, Inc.
// This file is part of GCC.
// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3, or (at your option) any later
// version.
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
// You should have received a copy of the GNU General Public License
// along with GCC; see the file COPYING3. If not see
// .
#include "rust-ast-lower-base.h"
#include "rust-ast-lower-type.h"
#include "rust-ast-lower-pattern.h"
#include "rust-ast-lower-extern.h"
namespace Rust {
namespace HIR {
void
ASTLoweringBase::visit (AST::Token &tok)
{}
void
ASTLoweringBase::visit (AST::DelimTokenTree &delim_tok_tree)
{}
void
ASTLoweringBase::visit (AST::AttrInputMetaItemContainer &input)
{}
// void ASTLoweringBase::visit(MetaItem& meta_item) {}
// void vsit(Stmt& stmt) {}
// void ASTLoweringBase::visit(Expr& expr) {}
void
ASTLoweringBase::visit (AST::IdentifierExpr &ident_expr)
{}
// void ASTLoweringBase::visit(Pattern& pattern) {}
// void ASTLoweringBase::visit(Type& type) {}
// void ASTLoweringBase::visit(TypeParamBound& type_param_bound) {}
void
ASTLoweringBase::visit (AST::Lifetime &lifetime)
{}
// void ASTLoweringBase::visit(GenericParam& generic_param) {}
void
ASTLoweringBase::visit (AST::LifetimeParam &lifetime_param)
{}
void
ASTLoweringBase::visit (AST::ConstGenericParam &const_param)
{}
// void ASTLoweringBase::visit(TraitItem& trait_item) {}
// void ASTLoweringBase::visit(InherentImplItem& inherent_impl_item) {}
// void ASTLoweringBase::visit(TraitImplItem& trait_impl_item) {}
// rust-path.h
void
ASTLoweringBase::visit (AST::PathInExpression &path)
{}
void
ASTLoweringBase::visit (AST::TypePathSegment &segment)
{}
void
ASTLoweringBase::visit (AST::TypePathSegmentGeneric &segment)
{}
void
ASTLoweringBase::visit (AST::TypePathSegmentFunction &segment)
{}
void
ASTLoweringBase::visit (AST::TypePath &path)
{}
void
ASTLoweringBase::visit (AST::QualifiedPathInExpression &path)
{}
void
ASTLoweringBase::visit (AST::QualifiedPathInType &path)
{}
// rust-expr.h
void
ASTLoweringBase::visit (AST::LiteralExpr &expr)
{}
void
ASTLoweringBase::visit (AST::AttrInputLiteral &attr_input)
{}
void
ASTLoweringBase::visit (AST::MetaItemLitExpr &meta_item)
{}
void
ASTLoweringBase::visit (AST::MetaItemPathLit &meta_item)
{}
void
ASTLoweringBase::visit (AST::BorrowExpr &expr)
{}
void
ASTLoweringBase::visit (AST::DereferenceExpr &expr)
{}
void
ASTLoweringBase::visit (AST::ErrorPropagationExpr &expr)
{}
void
ASTLoweringBase::visit (AST::NegationExpr &expr)
{}
void
ASTLoweringBase::visit (AST::ArithmeticOrLogicalExpr &expr)
{}
void
ASTLoweringBase::visit (AST::ComparisonExpr &expr)
{}
void
ASTLoweringBase::visit (AST::LazyBooleanExpr &expr)
{}
void
ASTLoweringBase::visit (AST::TypeCastExpr &expr)
{}
void
ASTLoweringBase::visit (AST::AssignmentExpr &expr)
{}
void
ASTLoweringBase::visit (AST::CompoundAssignmentExpr &expr)
{}
void
ASTLoweringBase::visit (AST::GroupedExpr &expr)
{}
// void ASTLoweringBase::visit(ArrayElems& elems) {}
void
ASTLoweringBase::visit (AST::ArrayElemsValues &elems)
{}
void
ASTLoweringBase::visit (AST::ArrayElemsCopied &elems)
{}
void
ASTLoweringBase::visit (AST::ArrayExpr &expr)
{}
void
ASTLoweringBase::visit (AST::ArrayIndexExpr &expr)
{}
void
ASTLoweringBase::visit (AST::TupleExpr &expr)
{}
void
ASTLoweringBase::visit (AST::TupleIndexExpr &expr)
{}
void
ASTLoweringBase::visit (AST::StructExprStruct &expr)
{}
// void ASTLoweringBase::visit(StructExprField& field) {}
void
ASTLoweringBase::visit (AST::StructExprFieldIdentifier &field)
{}
void
ASTLoweringBase::visit (AST::StructExprFieldIdentifierValue &field)
{}
void
ASTLoweringBase::visit (AST::StructExprFieldIndexValue &field)
{}
void
ASTLoweringBase::visit (AST::StructExprStructFields &expr)
{}
void
ASTLoweringBase::visit (AST::StructExprStructBase &expr)
{}
void
ASTLoweringBase::visit (AST::CallExpr &expr)
{}
void
ASTLoweringBase::visit (AST::MethodCallExpr &expr)
{}
void
ASTLoweringBase::visit (AST::FieldAccessExpr &expr)
{}
void
ASTLoweringBase::visit (AST::ClosureExprInner &expr)
{}
void
ASTLoweringBase::visit (AST::BlockExpr &expr)
{}
void
ASTLoweringBase::visit (AST::ClosureExprInnerTyped &expr)
{}
void
ASTLoweringBase::visit (AST::ContinueExpr &expr)
{}
void
ASTLoweringBase::visit (AST::BreakExpr &expr)
{}
void
ASTLoweringBase::visit (AST::RangeFromToExpr &expr)
{}
void
ASTLoweringBase::visit (AST::RangeFromExpr &expr)
{}
void
ASTLoweringBase::visit (AST::RangeToExpr &expr)
{}
void
ASTLoweringBase::visit (AST::RangeFullExpr &expr)
{}
void
ASTLoweringBase::visit (AST::RangeFromToInclExpr &expr)
{}
void
ASTLoweringBase::visit (AST::RangeToInclExpr &expr)
{}
void
ASTLoweringBase::visit (AST::ReturnExpr &expr)
{}
void
ASTLoweringBase::visit (AST::UnsafeBlockExpr &expr)
{}
void
ASTLoweringBase::visit (AST::LoopExpr &expr)
{}
void
ASTLoweringBase::visit (AST::WhileLoopExpr &expr)
{}
void
ASTLoweringBase::visit (AST::WhileLetLoopExpr &expr)
{}
void
ASTLoweringBase::visit (AST::ForLoopExpr &expr)
{}
void
ASTLoweringBase::visit (AST::IfExpr &expr)
{}
void
ASTLoweringBase::visit (AST::IfExprConseqElse &expr)
{}
void
ASTLoweringBase::visit (AST::IfExprConseqIf &expr)
{}
void
ASTLoweringBase::visit (AST::IfExprConseqIfLet &expr)
{}
void
ASTLoweringBase::visit (AST::IfLetExpr &expr)
{}
void
ASTLoweringBase::visit (AST::IfLetExprConseqElse &expr)
{}
void
ASTLoweringBase::visit (AST::IfLetExprConseqIf &expr)
{}
void
ASTLoweringBase::visit (AST::IfLetExprConseqIfLet &expr)
{}
// void ASTLoweringBase::visit(MatchCase& match_case) {}
// void ASTLoweringBase:: (AST::MatchCaseBlockExpr &match_case) {}
// void ASTLoweringBase:: (AST::MatchCaseExpr &match_case) {}
void
ASTLoweringBase::visit (AST::MatchExpr &expr)
{}
void
ASTLoweringBase::visit (AST::AwaitExpr &expr)
{}
void
ASTLoweringBase::visit (AST::AsyncBlockExpr &expr)
{}
// rust-item.h
void
ASTLoweringBase::visit (AST::TypeParam ¶m)
{}
// void ASTLoweringBase::visit(WhereClauseItem& item) {}
void
ASTLoweringBase::visit (AST::LifetimeWhereClauseItem &item)
{}
void
ASTLoweringBase::visit (AST::TypeBoundWhereClauseItem &item)
{}
void
ASTLoweringBase::visit (AST::Method &method)
{}
void
ASTLoweringBase::visit (AST::Module &module)
{}
void
ASTLoweringBase::visit (AST::ExternCrate &crate)
{}
// void ASTLoweringBase::visit(UseTree& use_tree) {}
void
ASTLoweringBase::visit (AST::UseTreeGlob &use_tree)
{}
void
ASTLoweringBase::visit (AST::UseTreeList &use_tree)
{}
void
ASTLoweringBase::visit (AST::UseTreeRebind &use_tree)
{}
void
ASTLoweringBase::visit (AST::UseDeclaration &use_decl)
{}
void
ASTLoweringBase::visit (AST::Function &function)
{}
void
ASTLoweringBase::visit (AST::TypeAlias &type_alias)
{}
void
ASTLoweringBase::visit (AST::StructStruct &struct_item)
{}
void
ASTLoweringBase::visit (AST::TupleStruct &tuple_struct)
{}
void
ASTLoweringBase::visit (AST::EnumItem &item)
{}
void
ASTLoweringBase::visit (AST::EnumItemTuple &item)
{}
void
ASTLoweringBase::visit (AST::EnumItemStruct &item)
{}
void
ASTLoweringBase::visit (AST::EnumItemDiscriminant &item)
{}
void
ASTLoweringBase::visit (AST::Enum &enum_item)
{}
void
ASTLoweringBase::visit (AST::Union &union_item)
{}
void
ASTLoweringBase::visit (AST::ConstantItem &const_item)
{}
void
ASTLoweringBase::visit (AST::StaticItem &static_item)
{}
void
ASTLoweringBase::visit (AST::TraitItemFunc &item)
{}
void
ASTLoweringBase::visit (AST::TraitItemMethod &item)
{}
void
ASTLoweringBase::visit (AST::TraitItemConst &item)
{}
void
ASTLoweringBase::visit (AST::TraitItemType &item)
{}
void
ASTLoweringBase::visit (AST::Trait &trait)
{}
void
ASTLoweringBase::visit (AST::InherentImpl &impl)
{}
void
ASTLoweringBase::visit (AST::TraitImpl &impl)
{}
// void ASTLoweringBase::visit(ExternalItem& item) {}
void
ASTLoweringBase::visit (AST::ExternalStaticItem &item)
{}
void
ASTLoweringBase::visit (AST::ExternalFunctionItem &item)
{}
void
ASTLoweringBase::visit (AST::ExternBlock &block)
{}
// rust-macro.h
void
ASTLoweringBase::visit (AST::MacroMatchFragment &match)
{}
void
ASTLoweringBase::visit (AST::MacroMatchRepetition &match)
{}
void
ASTLoweringBase::visit (AST::MacroMatcher &matcher)
{}
void
ASTLoweringBase::visit (AST::MacroRulesDefinition &rules_def)
{}
void
ASTLoweringBase::visit (AST::MacroInvocation ¯o_invoc)
{}
void
ASTLoweringBase::visit (AST::MetaItemPath &meta_item)
{}
void
ASTLoweringBase::visit (AST::MetaItemSeq &meta_item)
{}
void
ASTLoweringBase::visit (AST::MetaWord &meta_item)
{}
void
ASTLoweringBase::visit (AST::MetaNameValueStr &meta_item)
{}
void
ASTLoweringBase::visit (AST::MetaListPaths &meta_item)
{}
void
ASTLoweringBase::visit (AST::MetaListNameValueStr &meta_item)
{}
// rust-pattern.h
void
ASTLoweringBase::visit (AST::LiteralPattern &pattern)
{}
void
ASTLoweringBase::visit (AST::IdentifierPattern &pattern)
{}
void
ASTLoweringBase::visit (AST::WildcardPattern &pattern)
{}
// void ASTLoweringBase::visit(RangePatternBound& bound) {}
void
ASTLoweringBase::visit (AST::RangePatternBoundLiteral &bound)
{}
void
ASTLoweringBase::visit (AST::RangePatternBoundPath &bound)
{}
void
ASTLoweringBase::visit (AST::RangePatternBoundQualPath &bound)
{}
void
ASTLoweringBase::visit (AST::RangePattern &pattern)
{}
void
ASTLoweringBase::visit (AST::ReferencePattern &pattern)
{}
// void ASTLoweringBase::visit(StructPatternField& field) {}
void
ASTLoweringBase::visit (AST::StructPatternFieldTuplePat &field)
{}
void
ASTLoweringBase::visit (AST::StructPatternFieldIdentPat &field)
{}
void
ASTLoweringBase::visit (AST::StructPatternFieldIdent &field)
{}
void
ASTLoweringBase::visit (AST::StructPattern &pattern)
{}
// void ASTLoweringBase::visit(TupleStructItems& tuple_items) {}
void
ASTLoweringBase::visit (AST::TupleStructItemsNoRange &tuple_items)
{}
void
ASTLoweringBase::visit (AST::TupleStructItemsRange &tuple_items)
{}
void
ASTLoweringBase::visit (AST::TupleStructPattern &pattern)
{}
// void ASTLoweringBase::visit(TuplePatternItems& tuple_items) {}
void
ASTLoweringBase::visit (AST::TuplePatternItemsMultiple &tuple_items)
{}
void
ASTLoweringBase::visit (AST::TuplePatternItemsRanged &tuple_items)
{}
void
ASTLoweringBase::visit (AST::TuplePattern &pattern)
{}
void
ASTLoweringBase::visit (AST::GroupedPattern &pattern)
{}
void
ASTLoweringBase::visit (AST::SlicePattern &pattern)
{}
// rust-stmt.h
void
ASTLoweringBase::visit (AST::EmptyStmt &stmt)
{}
void
ASTLoweringBase::visit (AST::LetStmt &stmt)
{}
void
ASTLoweringBase::visit (AST::ExprStmtWithoutBlock &stmt)
{}
void
ASTLoweringBase::visit (AST::ExprStmtWithBlock &stmt)
{}
// rust-type.h
void
ASTLoweringBase::visit (AST::TraitBound &bound)
{}
void
ASTLoweringBase::visit (AST::ImplTraitType &type)
{}
void
ASTLoweringBase::visit (AST::TraitObjectType &type)
{}
void
ASTLoweringBase::visit (AST::ParenthesisedType &type)
{}
void
ASTLoweringBase::visit (AST::ImplTraitTypeOneBound &type)
{}
void
ASTLoweringBase::visit (AST::TraitObjectTypeOneBound &type)
{}
void
ASTLoweringBase::visit (AST::TupleType &type)
{}
void
ASTLoweringBase::visit (AST::NeverType &type)
{}
void
ASTLoweringBase::visit (AST::RawPointerType &type)
{}
void
ASTLoweringBase::visit (AST::ReferenceType &type)
{}
void
ASTLoweringBase::visit (AST::ArrayType &type)
{}
void
ASTLoweringBase::visit (AST::SliceType &type)
{}
void
ASTLoweringBase::visit (AST::InferredType &type)
{}
void
ASTLoweringBase::visit (AST::BareFunctionType &type)
{}
HIR::Lifetime
ASTLoweringBase::lower_lifetime (AST::Lifetime &lifetime)
{
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, lifetime.get_node_id (),
mappings->get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
mappings->insert_node_to_hir (mapping.get_nodeid (), mapping.get_hirid ());
return HIR::Lifetime (mapping, lifetime.get_lifetime_type (),
lifetime.get_lifetime_name (), lifetime.get_locus ());
}
HIR::LoopLabel
ASTLoweringBase::lower_loop_label (AST::LoopLabel &loop_label)
{
HIR::Lifetime life = lower_lifetime (loop_label.get_lifetime ());
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, loop_label.get_node_id (),
mappings->get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
mappings->insert_node_to_hir (mapping.get_nodeid (), mapping.get_hirid ());
return HIR::LoopLabel (mapping, std::move (life), loop_label.get_locus ());
}
std::vector>
ASTLoweringBase::lower_generic_params (
std::vector> ¶ms)
{
std::vector> lowered;
for (auto &ast_param : params)
{
auto hir_param = ASTLowerGenericParam::translate (ast_param.get ());
lowered.push_back (std::unique_ptr (hir_param));
}
return lowered;
}
HIR::PathExprSegment
ASTLoweringBase::lower_path_expr_seg (AST::PathExprSegment &s)
{
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, s.get_node_id (),
mappings->get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
return HIR::PathExprSegment (
std::move (mapping),
HIR::PathIdentSegment (s.get_ident_segment ().as_string ()), s.get_locus (),
s.has_generic_args () ? lower_generic_args (s.get_generic_args ())
: HIR::GenericArgs::create_empty ());
}
HIR::GenericArgsBinding
ASTLoweringBase::lower_binding (AST::GenericArgsBinding &binding)
{
HIR::Type *lowered_type
= ASTLoweringType::translate (binding.get_type ().get ());
return HIR::GenericArgsBinding (binding.get_identifier (),
std::unique_ptr (lowered_type),
binding.get_locus ());
}
HIR::GenericArgs
ASTLoweringBase::lower_generic_args (AST::GenericArgs &args)
{
std::vector binding_args;
for (auto &binding : args.get_binding_args ())
{
HIR::GenericArgsBinding b = lower_binding (binding);
binding_args.push_back (std::move (b));
}
std::vector lifetime_args;
for (auto &lifetime : args.get_lifetime_args ())
{
HIR::Lifetime l = lower_lifetime (lifetime);
lifetime_args.push_back (std::move (l));
}
std::vector> type_args;
std::vector const_args;
for (auto &arg : args.get_generic_args ())
{
switch (arg.get_kind ())
{
case AST::GenericArg::Kind::Type: {
auto type = ASTLoweringType::translate (arg.get_type ().get ());
type_args.emplace_back (std::unique_ptr (type));
break;
}
case AST::GenericArg::Kind::Const: {
auto expr
= ASTLoweringExpr::translate (arg.get_expression ().get ());
const_args.emplace_back (
HIR::ConstGenericArg (std::unique_ptr (expr),
expr->get_locus ()));
break;
}
default:
gcc_unreachable ();
}
}
return HIR::GenericArgs (std::move (lifetime_args), std::move (type_args),
std::move (binding_args), std::move (const_args),
args.get_locus ());
}
HIR::SelfParam
ASTLoweringBase::lower_self (AST::SelfParam &self)
{
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, self.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
if (self.has_type ())
{
HIR::Type *type = ASTLoweringType::translate (self.get_type ().get ());
return HIR::SelfParam (mapping, std::unique_ptr (type),
self.get_is_mut (), self.get_locus ());
}
else if (!self.get_has_ref ())
{
return HIR::SelfParam (mapping, std::unique_ptr (nullptr),
self.get_is_mut (), self.get_locus ());
}
AST::Lifetime l = self.get_lifetime ();
return HIR::SelfParam (mapping, lower_lifetime (l), self.get_is_mut (),
self.get_locus ());
}
void
ASTLowerTypePath::visit (AST::TypePathSegmentGeneric &segment)
{
std::vector binding_args; // TODO
std::string segment_name = segment.get_ident_segment ().as_string ();
bool has_separating_scope_resolution
= segment.get_separating_scope_resolution ();
auto generic_args = lower_generic_args (segment.get_generic_args ());
auto crate_num = mappings->get_current_crate ();
auto hirid = mappings->get_next_hir_id (crate_num);
Analysis::NodeMapping mapping (crate_num, segment.get_node_id (), hirid,
UNKNOWN_LOCAL_DEFID);
translated_segment
= new HIR::TypePathSegmentGeneric (std::move (mapping), segment_name,
has_separating_scope_resolution,
generic_args, segment.get_locus ());
}
void
ASTLowerQualifiedPathInType::visit (AST::QualifiedPathInType &path)
{
auto crate_num = mappings->get_current_crate ();
auto hirid = mappings->get_next_hir_id (crate_num);
Analysis::NodeMapping qual_mappings (
crate_num, path.get_qualified_path_type ().get_node_id (), hirid,
UNKNOWN_LOCAL_DEFID);
HIR::Type *qual_type = ASTLoweringType::translate (
path.get_qualified_path_type ().get_type ().get ());
HIR::TypePath *qual_trait = ASTLowerTypePath::translate (
path.get_qualified_path_type ().get_as_type_path ());
HIR::QualifiedPathType qual_path_type (
qual_mappings, std::unique_ptr (qual_type),
std::unique_ptr (qual_trait),
path.get_qualified_path_type ().get_locus ());
translated_segment = nullptr;
path.get_associated_segment ()->accept_vis (*this);
if (translated_segment == nullptr)
{
rust_fatal_error (path.get_associated_segment ()->get_locus (),
"failed to translate AST TypePathSegment");
return;
}
std::unique_ptr associated_segment (translated_segment);
std::vector> translated_segments;
for (auto &seg : path.get_segments ())
{
translated_segment = nullptr;
seg->accept_vis (*this);
if (translated_segment == nullptr)
{
rust_fatal_error (seg->get_locus (),
"failed to translte AST TypePathSegment");
}
translated_segments.push_back (
std::unique_ptr (translated_segment));
}
Analysis::NodeMapping mapping (crate_num, path.get_node_id (), hirid,
mappings->get_next_localdef_id (crate_num));
translated = new HIR::QualifiedPathInType (std::move (mapping),
std::move (qual_path_type),
std::move (associated_segment),
std::move (translated_segments),
path.get_locus ());
}
void
ASTLoweringType::visit (AST::TraitObjectTypeOneBound &type)
{
std::vector> bounds;
HIR::TypeParamBound *translated_bound
= ASTLoweringTypeBounds::translate (&type.get_trait_bound ());
bounds.push_back (std::unique_ptr (translated_bound));
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
translated = new HIR::TraitObjectType (mapping, std::move (bounds),
type.get_locus (), type.is_dyn ());
}
void
ASTLoweringType::visit (AST::TraitObjectType &type)
{
std::vector> bounds;
for (auto &bound : type.get_type_param_bounds ())
{
HIR::TypeParamBound *translated_bound
= ASTLoweringTypeBounds::translate (bound.get ());
bounds.push_back (
std::unique_ptr (translated_bound));
}
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
translated = new HIR::TraitObjectType (mapping, std::move (bounds),
type.get_locus (), type.is_dyn ());
}
HIR::Type *
ASTLoweringBase::lower_type_no_bounds (AST::TypeNoBounds *type)
{
return ASTLoweringType::translate (type);
}
HIR::TypeParamBound *
ASTLoweringBase::lower_bound (AST::TypeParamBound *bound)
{
return ASTLoweringTypeBounds::translate (bound);
}
/* Checks whether the name of a field already exists. Returns true
and produces an error if so. */
bool
struct_field_name_exists (std::vector &fields,
HIR::StructField &new_field)
{
for (auto &field : fields)
{
if (field.get_field_name ().compare (new_field.get_field_name ()) == 0)
{
RichLocation r (new_field.get_locus ());
r.add_range (field.get_locus ());
rust_error_at (r, "duplicate field name %qs",
field.get_field_name ().c_str ());
return true;
}
}
return false;
}
HIR::FunctionQualifiers
ASTLoweringBase::lower_qualifiers (const AST::FunctionQualifiers &qualifiers)
{
Unsafety unsafety
= qualifiers.is_unsafe () ? Unsafety::Unsafe : Unsafety::Normal;
bool has_extern = qualifiers.is_extern ();
ABI abi = ABI::RUST;
if (qualifiers.has_abi ())
{
const std::string &extern_abi = qualifiers.get_extern_abi ();
abi = get_abi_from_string (extern_abi);
if (has_extern && abi == ABI::UNKNOWN)
rust_error_at (qualifiers.get_locus (), "unknown ABI option");
}
return HIR::FunctionQualifiers (qualifiers.get_const_status (), unsafety,
has_extern, abi);
}
void
ASTLoweringBase::handle_outer_attributes (const HIR::Item &item)
{
for (const auto &attr : item.get_outer_attrs ())
{
const auto &str_path = attr.get_path ().as_string ();
if (!is_known_attribute (str_path))
{
rust_error_at (attr.get_locus (), "unknown attribute");
continue;
}
bool is_lang_item = str_path.compare ("lang") == 0
&& attr.has_attr_input ()
&& attr.get_attr_input ().get_attr_input_type ()
== AST::AttrInput::AttrInputType::LITERAL;
bool is_doc_item = str_path.compare ("doc") == 0;
if (is_doc_item)
handle_doc_item_attribute (item, attr);
else if (is_lang_item)
handle_lang_item_attribute (item, attr);
else if (!attribute_handled_in_another_pass (str_path))
{
rust_error_at (attr.get_locus (), "unhandled attribute: [%s]",
attr.get_path ().as_string ().c_str ());
}
}
}
void
ASTLoweringBase::handle_doc_item_attribute (const HIR::Item &item,
const AST::Attribute &attr)
{
auto simple_doc_comment = attr.has_attr_input ()
&& attr.get_attr_input ().get_attr_input_type ()
== AST::AttrInput::AttrInputType::LITERAL;
if (simple_doc_comment)
return;
const AST::AttrInput &input = attr.get_attr_input ();
bool is_token_tree
= input.get_attr_input_type () == AST::AttrInput::AttrInputType::TOKEN_TREE;
rust_assert (is_token_tree);
const auto &option = static_cast (input);
AST::AttrInputMetaItemContainer *meta_item = option.parse_to_meta_item ();
// TODO: add actual and complete checks for the doc attributes
//
// FIXME: Move this to the AttributeChecker visitor
rust_assert (meta_item);
}
void
ASTLoweringBase::handle_lang_item_attribute (const HIR::Item &item,
const AST::Attribute &attr)
{
auto &literal = static_cast (attr.get_attr_input ());
const auto &lang_item_type_str = literal.get_literal ().as_string ();
auto lang_item_type = Analysis::RustLangItem::Parse (lang_item_type_str);
if (lang_item_type == Analysis::RustLangItem::ItemType::UNKNOWN)
{
rust_error_at (attr.get_locus (), "unknown lang item");
return;
}
mappings->insert_lang_item (lang_item_type,
item.get_mappings ().get_defid ());
}
bool
ASTLoweringBase::is_known_attribute (const std::string &attribute_path) const
{
const auto &lookup = attr_mappings->lookup_builtin (attribute_path);
return !lookup.is_error ();
}
bool
ASTLoweringBase::attribute_handled_in_another_pass (
const std::string &attribute_path) const
{
const auto &lookup = attr_mappings->lookup_builtin (attribute_path);
if (lookup.is_error ())
return false;
if (lookup.handler == Analysis::CompilerPass::UNKNOWN)
return false;
return lookup.handler != Analysis::CompilerPass::HIR_LOWERING;
}
std::unique_ptr
ASTLoweringBase::lower_tuple_pattern_multiple (
AST::TuplePatternItemsMultiple &pattern)
{
std::vector> patterns;
for (auto &p : pattern.get_patterns ())
{
HIR::Pattern *translated = ASTLoweringPattern::translate (p.get ());
patterns.push_back (std::unique_ptr (translated));
}
return std::unique_ptr (
new HIR::TuplePatternItemsMultiple (std::move (patterns)));
}
std::unique_ptr
ASTLoweringBase::lower_tuple_pattern_ranged (
AST::TuplePatternItemsRanged &pattern)
{
std::vector> lower_patterns;
std::vector> upper_patterns;
for (auto &p : pattern.get_lower_patterns ())
{
HIR::Pattern *translated = ASTLoweringPattern::translate (p.get ());
lower_patterns.push_back (std::unique_ptr (translated));
}
for (auto &p : pattern.get_upper_patterns ())
{
HIR::Pattern *translated = ASTLoweringPattern::translate (p.get ());
upper_patterns.push_back (std::unique_ptr (translated));
}
return std::unique_ptr (
new HIR::TuplePatternItemsRanged (std::move (lower_patterns),
std::move (upper_patterns)));
}
std::unique_ptr
ASTLoweringBase::lower_range_pattern_bound (AST::RangePatternBound *bound)
{
std::unique_ptr hir_bound = nullptr;
switch (bound->get_bound_type ())
{
case AST::RangePatternBound::RangePatternBoundType::LITERAL: {
AST::RangePatternBoundLiteral &ref
= *static_cast (bound);
HIR::Literal literal = lower_literal (ref.get_literal ());
hir_bound = std::unique_ptr (
new HIR::RangePatternBoundLiteral (literal, ref.get_locus (),
ref.get_has_minus ()));
}
break;
case AST::RangePatternBound::RangePatternBoundType::PATH: {
AST::RangePatternBoundPath &ref
= *static_cast (bound);
HIR::PathInExpression *path
= ASTLowerPathInExpression::translate (&ref.get_path ());
hir_bound = std::unique_ptr (
new HIR::RangePatternBoundPath (*path));
}
break;
case AST::RangePatternBound::RangePatternBoundType::QUALPATH: {
AST::RangePatternBoundQualPath &ref
= *static_cast (bound);
HIR::QualifiedPathInExpression *qualpath
= ASTLowerQualPathInExpression::translate (
&ref.get_qualified_path ());
hir_bound = std::unique_ptr (
new HIR::RangePatternBoundQualPath (*qualpath));
}
break;
}
return hir_bound;
}
HIR::Literal
ASTLoweringBase::lower_literal (const AST::Literal &literal)
{
HIR::Literal::LitType type = HIR::Literal::LitType::CHAR;
switch (literal.get_lit_type ())
{
case AST::Literal::LitType::CHAR:
type = HIR::Literal::LitType::CHAR;
break;
case AST::Literal::LitType::STRING:
type = HIR::Literal::LitType::STRING;
break;
case AST::Literal::LitType::BYTE:
type = HIR::Literal::LitType::BYTE;
break;
case AST::Literal::LitType::BYTE_STRING:
type = HIR::Literal::LitType::BYTE_STRING;
break;
case AST::Literal::LitType::INT:
type = HIR::Literal::LitType::INT;
break;
case AST::Literal::LitType::FLOAT:
type = HIR::Literal::LitType::FLOAT;
break;
case AST::Literal::LitType::BOOL:
type = HIR::Literal::LitType::BOOL;
break;
case AST::Literal::LitType::ERROR:
gcc_unreachable ();
break;
}
return HIR::Literal (literal.as_string (), type, literal.get_type_hint ());
}
HIR::ExternBlock *
ASTLoweringBase::lower_extern_block (AST::ExternBlock &extern_block)
{
HIR::Visibility vis = translate_visibility (extern_block.get_visibility ());
auto crate_num = mappings->get_current_crate ();
Analysis::NodeMapping mapping (crate_num, extern_block.get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
std::vector> extern_items;
for (auto &item : extern_block.get_extern_items ())
{
if (item->is_marked_for_strip ())
continue;
HIR::ExternalItem *lowered
= ASTLoweringExternItem::translate (item.get (), mapping.get_hirid ());
extern_items.push_back (std::unique_ptr (lowered));
}
ABI abi = ABI::RUST;
if (extern_block.has_abi ())
{
const std::string &extern_abi = extern_block.get_abi ();
abi = get_abi_from_string (extern_abi);
if (abi == ABI::UNKNOWN)
rust_error_at (extern_block.get_locus (), "unknown ABI option");
}
HIR::ExternBlock *hir_extern_block
= new HIR::ExternBlock (mapping, abi, std::move (extern_items),
std::move (vis), extern_block.get_inner_attrs (),
extern_block.get_outer_attrs (),
extern_block.get_locus ());
mappings->insert_hir_extern_block (hir_extern_block);
return hir_extern_block;
}
} // namespace HIR
} // namespace Rust