diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-11-16 13:45:52 +0000 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-11-16 14:06:27 +0000 |
commit | 795d70d7e6e107b3cde213fb78484b19c9a3a671 (patch) | |
tree | dc2a5e6ead63bbd081414adeca8d273913433123 /gcc | |
parent | df3e0ec232b878fb1f2228e5f6ef6ec0874d1665 (diff) | |
download | gcc-795d70d7e6e107b3cde213fb78484b19c9a3a671.zip gcc-795d70d7e6e107b3cde213fb78484b19c9a3a671.tar.gz gcc-795d70d7e6e107b3cde213fb78484b19c9a3a671.tar.bz2 |
Support parsing LangItems on traits
Lang items are attributes that mark traits for specific behaviour with
compiler support kind of like builtin's/intrinsics.
This change adds parsing support for some of the arithmetic operator
overloads. The string names always correspond to the trait-item function
name too.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-resolve.h | 26 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.h | 159 |
2 files changed, 181 insertions, 4 deletions
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.h b/gcc/rust/typecheck/rust-hir-trait-resolve.h index a32b4da..54591ce 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.h +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.h @@ -24,6 +24,7 @@ #include "rust-tyty-visitor.h" #include "rust-hir-type-check-type.h" #include "rust-hir-trait-ref.h" +#include "rust-expr.h" namespace Rust { namespace Resolver { @@ -206,6 +207,31 @@ private: // loop of trying to resolve traits as required by the types tref->on_resolved (); + // does this have any lang-item attributes? + for (auto &attr : trait_reference->get_outer_attrs ()) + { + bool is_lang_item = attr.get_path ().as_string ().compare ("lang") == 0 + && attr.has_attr_input () + && attr.get_attr_input ().get_attr_input_type () + == AST::AttrInput::AttrInputType::LITERAL; + if (is_lang_item) + { + auto &literal + = static_cast<AST::AttrInputLiteral &> (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 tref; + } + mappings->insert_lang_item ( + lang_item_type, trait_reference->get_mappings ().get_defid ()); + } + } + return tref; } diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h index 4fe64d45..09a7b36 100644 --- a/gcc/rust/util/rust-hir-map.h +++ b/gcc/rust/util/rust-hir-map.h @@ -23,13 +23,143 @@ #include "rust-location.h" #include "rust-mapping-common.h" #include "rust-canonical-path.h" - #include "rust-ast-full-decls.h" #include "rust-hir-full-decls.h" +#include "operator.h" namespace Rust { namespace Analysis { +// https://github.com/rust-lang/rust/blob/master/library/core/src/ops/arith.rs +class RustLangItem +{ +public: + enum ItemType + { + ADD, + SUBTRACT, + MULTIPLY, + DIVIDE, + REMAINDER, + NEGATION, + ADD_ASSIGN, + SUB_ASSIGN, + MUL_ASSIGN, + DIV_ASSIGN, + REM_ASSIGN, + + UNKNOWN, + }; + + static ItemType Parse (const std::string &item) + { + if (item.compare ("add") == 0) + { + return ItemType::ADD; + } + else if (item.compare ("sub") == 0) + { + return ItemType::SUBTRACT; + } + else if (item.compare ("mul") == 0) + { + return ItemType::MULTIPLY; + } + else if (item.compare ("div") == 0) + { + return ItemType::DIVIDE; + } + else if (item.compare ("rem") == 0) + { + return ItemType::REMAINDER; + } + else if (item.compare ("neg") == 0) + { + return ItemType::NEGATION; + } + else if (item.compare ("add_assign") == 0) + { + return ItemType::ADD_ASSIGN; + } + else if (item.compare ("sub_assign") == 0) + { + return ItemType::SUB_ASSIGN; + } + else if (item.compare ("mul_assign") == 0) + { + return ItemType::MUL_ASSIGN; + } + else if (item.compare ("div_assign") == 0) + { + return ItemType::DIV_ASSIGN; + } + else if (item.compare ("rem_assign") == 0) + { + return ItemType::REM_ASSIGN; + } + + return ItemType::UNKNOWN; + } + + static std::string ToString (ItemType type) + { + switch (type) + { + case ADD: + return "add"; + case SUBTRACT: + return "sub"; + case MULTIPLY: + return "mul"; + case DIVIDE: + return "div"; + case REMAINDER: + return "rem"; + case NEGATION: + return "neg"; + case ADD_ASSIGN: + return "add_assign"; + case SUB_ASSIGN: + return "sub_assign"; + case MUL_ASSIGN: + return "mul_assign"; + case DIV_ASSIGN: + return "div_assign"; + case REM_ASSIGN: + return "rem_assign"; + + case UNKNOWN: + break; + } + return "<UNKNOWN>"; + } + + static ItemType OperatorToLangItem (ArithmeticOrLogicalOperator op) + { + switch (op) + { + case ArithmeticOrLogicalOperator::ADD: + return ItemType::ADD; + case ArithmeticOrLogicalOperator::SUBTRACT: + return ItemType::SUBTRACT; + case ArithmeticOrLogicalOperator::MULTIPLY: + return ItemType::MULTIPLY; + case ArithmeticOrLogicalOperator::DIVIDE: + return ItemType::DIVIDE; + case ArithmeticOrLogicalOperator::MODULUS: + return ItemType::REMAINDER; + + case ArithmeticOrLogicalOperator::BITWISE_AND: + case ArithmeticOrLogicalOperator::BITWISE_OR: + case ArithmeticOrLogicalOperator::BITWISE_XOR: + case ArithmeticOrLogicalOperator::LEFT_SHIFT: + case ArithmeticOrLogicalOperator::RIGHT_SHIFT: + return ItemType::UNKNOWN; + } + return ItemType::UNKNOWN; + } +}; + class NodeMapping { public: @@ -237,9 +367,9 @@ public: const Resolver::CanonicalPath *p = nullptr; if (lookup_canonical_path (crate, id, &p)) { - // if we have already stored a canonical path this is ok so long as this - // new path is equal or is smaller that the existing one but in that - // case we ignore it. + // if we have already stored a canonical path this is ok so long as + // this new path is equal or is smaller that the existing one but in + // that case we ignore it. if (p->is_equal (path)) return; else @@ -267,6 +397,24 @@ public: return true; } + void insert_lang_item (RustLangItem::ItemType item_type, DefId id) + { + auto it = lang_item_mappings.find (item_type); + rust_assert (it == lang_item_mappings.end ()); + + lang_item_mappings[item_type] = id; + } + + bool lookup_lang_item (RustLangItem::ItemType item_type, DefId *id) + { + auto it = lang_item_mappings.find (item_type); + if (it == lang_item_mappings.end ()) + return false; + + *id = it->second; + return true; + } + private: Mappings (); @@ -304,6 +452,9 @@ private: hirGenericParamMappings; std::map<HirId, HIR::Trait *> hirTraitItemsToTraitMappings; + // this maps the lang=<item_type> to DefId mappings + std::map<RustLangItem::ItemType, DefId> lang_item_mappings; + // canonical paths std::map<CrateNum, std::map<NodeId, const Resolver::CanonicalPath> > paths; |