diff options
Diffstat (limited to 'gcc/rust')
-rw-r--r-- | gcc/rust/Make-lang.in | 9 | ||||
-rw-r--r-- | gcc/rust/hir/README.md | 40 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-base.h | 251 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-expr.h | 240 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-item.h | 134 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-pattern.h | 58 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-stmt.h | 96 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-type.h | 84 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower.cc | 62 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower.h | 46 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.cc | 37 |
11 files changed, 1052 insertions, 5 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index dd42b1d..b9b2345 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -74,8 +74,9 @@ GRS_OBJS = \ rust/rust-scan.o \ rust/rust-compile.o \ rust/rust-macro-expand.o \ - rust/rust-hir-map.o \ rust/rust-hir-full-test.o \ + rust/rust-hir-map.o \ + rust/rust-ast-lower.o \ $(END) # removed object files from here @@ -275,8 +276,14 @@ rust/%.o: rust/util/%.cc $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $< $(POSTCOMPILE) +# build rust/hir files in rust folder +rust/%.o: rust/hir/%.cc + $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $< + $(POSTCOMPILE) + # build rust/hir/tree files in rust folder rust/%.o: rust/hir/tree/%.cc $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $< $(POSTCOMPILE) + diff --git a/gcc/rust/hir/README.md b/gcc/rust/hir/README.md new file mode 100644 index 0000000..550d104 --- /dev/null +++ b/gcc/rust/hir/README.md @@ -0,0 +1,40 @@ +# GCCRS HIR + +Working with the AST has proved to become difficult. To overcome non lexical scoping +a toplevel scan pass was added to provide lookups for functioins. To get ready for the +gimple conversion pass, type resolution scanned blocks to create the list of locals per +block. Type Conversion had to create awkward getters/setters on LetStmts to have a Type or +InferedType which was more of a hack that what should really be there. ArrayExprs get checked +and create their own type to be checked against a possible LetStmt type. All of these things +started to become hard to manage. + +HIR from the RFC defines how they create lookups and IDs for all the nodes which solves the toplevel +scan pass. The lowering to HIR allows for cleanup in how types are resolved. Without using +the HIR and IDs implementing the shadowing rules was going to become very difficult. + + +## IMPL: + +* AST-lower - move down to HIR classes - generate mappings and IDs + +* Name Resolution - Check for path segments naming and map to HirIDS + This should in theory map for example a call expression to already have the HirID to the function ready + Dyn dispatch may need some help here if its a method the receiver could be bound the local name hirid + the resoltion would need to be fixed up in type resolution pass + +* Expand - Gather locals per block and fix up returns is it possible to generate return expressions + at this pass? + +* Type Resolution - Port over work from AST Type resolver + generate mir from this pass? + + +For now this can then port over to the existing GIMPLE conversion faily easily. But after more +of the core data structures work MIR will be needed for all the glue that will need to be generated. + + +## Returns + +looks like its implemented by an implicit mutable return variable for the function. If were processing +a block expression and the last element on the block is an expression we can try to bind it to the mutable +return variable. diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h new file mode 100644 index 0000000..093129e --- /dev/null +++ b/gcc/rust/hir/rust-ast-lower-base.h @@ -0,0 +1,251 @@ +// Copyright (C) 2020 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_AST_LOWER_BASE +#define RUST_AST_LOWER_BASE + +#include "rust-system.h" +#include "rust-ast-full.h" +#include "rust-ast-visitor.h" +#include "rust-hir-map.h" +#include "rust-hir-full.h" + +namespace Rust { +namespace HIR { + +// base class to allow derivatives to overload as needed +class ASTLoweringBase : public AST::ASTVisitor +{ +public: + virtual ~ASTLoweringBase () {} + + // visitor impl + // rust-ast.h + // virtual void visit(AttrInput& attr_input); + // virtual void visit(TokenTree& token_tree); + // virtual void visit(MacroMatch& macro_match); + virtual void visit (AST::Token &tok) {} + virtual void visit (AST::DelimTokenTree &delim_tok_tree) {} + virtual void visit (AST::AttrInputMetaItemContainer &input) {} + // virtual void visit(MetaItem& meta_item) {} + // void vsit(Stmt& stmt) {} + // virtual void visit(Expr& expr) {} + virtual void visit (AST::IdentifierExpr &ident_expr) {} + // virtual void visit(Pattern& pattern) {} + // virtual void visit(Type& type) {} + // virtual void visit(TypeParamBound& type_param_bound) {} + virtual void visit (AST::Lifetime &lifetime) {} + // virtual void visit(GenericParam& generic_param) {} + virtual void visit (AST::LifetimeParam &lifetime_param) {} + // virtual void visit(TraitItem& trait_item) {} + // virtual void visit(InherentImplItem& inherent_impl_item) {} + // virtual void visit(TraitImplItem& trait_impl_item) {} + virtual void visit (AST::MacroInvocationSemi ¯o) {} + + // rust-path.h + virtual void visit (AST::PathInExpression &path) {} + virtual void visit (AST::TypePathSegment &segment) {} + virtual void visit (AST::TypePathSegmentGeneric &segment) {} + virtual void visit (AST::TypePathSegmentFunction &segment) {} + virtual void visit (AST::TypePath &path) {} + virtual void visit (AST::QualifiedPathInExpression &path) {} + virtual void visit (AST::QualifiedPathInType &path) {} + + // rust-expr.h + virtual void visit (AST::LiteralExpr &expr) {} + virtual void visit (AST::AttrInputLiteral &attr_input) {} + virtual void visit (AST::MetaItemLitExpr &meta_item) {} + virtual void visit (AST::MetaItemPathLit &meta_item) {} + virtual void visit (AST::BorrowExpr &expr) {} + virtual void visit (AST::DereferenceExpr &expr) {} + virtual void visit (AST::ErrorPropagationExpr &expr) {} + virtual void visit (AST::NegationExpr &expr) {} + virtual void visit (AST::ArithmeticOrLogicalExpr &expr) {} + virtual void visit (AST::ComparisonExpr &expr) {} + virtual void visit (AST::LazyBooleanExpr &expr) {} + virtual void visit (AST::TypeCastExpr &expr) {} + virtual void visit (AST::AssignmentExpr &expr) {} + virtual void visit (AST::CompoundAssignmentExpr &expr) {} + virtual void visit (AST::GroupedExpr &expr) {} + // virtual void visit(ArrayElems& elems) {} + virtual void visit (AST::ArrayElemsValues &elems) {} + virtual void visit (AST::ArrayElemsCopied &elems) {} + virtual void visit (AST::ArrayExpr &expr) {} + virtual void visit (AST::ArrayIndexExpr &expr) {} + virtual void visit (AST::TupleExpr &expr) {} + virtual void visit (AST::TupleIndexExpr &expr) {} + virtual void visit (AST::StructExprStruct &expr) {} + // virtual void visit(StructExprField& field) {} + virtual void visit (AST::StructExprFieldIdentifier &field) {} + virtual void visit (AST::StructExprFieldIdentifierValue &field) {} + virtual void visit (AST::StructExprFieldIndexValue &field) {} + virtual void visit (AST::StructExprStructFields &expr) {} + virtual void visit (AST::StructExprStructBase &expr) {} + virtual void visit (AST::StructExprTuple &expr) {} + virtual void visit (AST::StructExprUnit &expr) {} + // virtual void visit(EnumExprField& field) {} + virtual void visit (AST::EnumExprFieldIdentifier &field) {} + virtual void visit (AST::EnumExprFieldIdentifierValue &field) {} + virtual void visit (AST::EnumExprFieldIndexValue &field) {} + virtual void visit (AST::EnumExprStruct &expr) {} + virtual void visit (AST::EnumExprTuple &expr) {} + virtual void visit (AST::EnumExprFieldless &expr) {} + virtual void visit (AST::CallExpr &expr) {} + virtual void visit (AST::MethodCallExpr &expr) {} + virtual void visit (AST::FieldAccessExpr &expr) {} + virtual void visit (AST::ClosureExprInner &expr) {} + virtual void visit (AST::BlockExpr &expr) {} + virtual void visit (AST::ClosureExprInnerTyped &expr) {} + virtual void visit (AST::ContinueExpr &expr) {} + virtual void visit (AST::BreakExpr &expr) {} + virtual void visit (AST::RangeFromToExpr &expr) {} + virtual void visit (AST::RangeFromExpr &expr) {} + virtual void visit (AST::RangeToExpr &expr) {} + virtual void visit (AST::RangeFullExpr &expr) {} + virtual void visit (AST::RangeFromToInclExpr &expr) {} + virtual void visit (AST::RangeToInclExpr &expr) {} + virtual void visit (AST::ReturnExpr &expr) {} + virtual void visit (AST::UnsafeBlockExpr &expr) {} + virtual void visit (AST::LoopExpr &expr) {} + virtual void visit (AST::WhileLoopExpr &expr) {} + virtual void visit (AST::WhileLetLoopExpr &expr) {} + virtual void visit (AST::ForLoopExpr &expr) {} + virtual void visit (AST::IfExpr &expr) {} + virtual void visit (AST::IfExprConseqElse &expr) {} + virtual void visit (AST::IfExprConseqIf &expr) {} + virtual void visit (AST::IfExprConseqIfLet &expr) {} + virtual void visit (AST::IfLetExpr &expr) {} + virtual void visit (AST::IfLetExprConseqElse &expr) {} + virtual void visit (AST::IfLetExprConseqIf &expr) {} + virtual void visit (AST::IfLetExprConseqIfLet &expr) {} + // virtual void visit(MatchCase& match_case) {} + // virtual void visit (AST::MatchCaseBlockExpr &match_case) {} + // virtual void visit (AST::MatchCaseExpr &match_case) {} + virtual void visit (AST::MatchExpr &expr) {} + virtual void visit (AST::AwaitExpr &expr) {} + virtual void visit (AST::AsyncBlockExpr &expr) {} + + // rust-item.h + virtual void visit (AST::TypeParam ¶m) {} + // virtual void visit(WhereClauseItem& item) {} + virtual void visit (AST::LifetimeWhereClauseItem &item) {} + virtual void visit (AST::TypeBoundWhereClauseItem &item) {} + virtual void visit (AST::Method &method) {} + virtual void visit (AST::ModuleBodied &module) {} + virtual void visit (AST::ModuleNoBody &module) {} + virtual void visit (AST::ExternCrate &crate) {} + // virtual void visit(UseTree& use_tree) {} + virtual void visit (AST::UseTreeGlob &use_tree) {} + virtual void visit (AST::UseTreeList &use_tree) {} + virtual void visit (AST::UseTreeRebind &use_tree) {} + virtual void visit (AST::UseDeclaration &use_decl) {} + virtual void visit (AST::Function &function) {} + virtual void visit (AST::TypeAlias &type_alias) {} + virtual void visit (AST::StructStruct &struct_item) {} + virtual void visit (AST::TupleStruct &tuple_struct) {} + virtual void visit (AST::EnumItem &item) {} + virtual void visit (AST::EnumItemTuple &item) {} + virtual void visit (AST::EnumItemStruct &item) {} + virtual void visit (AST::EnumItemDiscriminant &item) {} + virtual void visit (AST::Enum &enum_item) {} + virtual void visit (AST::Union &union_item) {} + virtual void visit (AST::ConstantItem &const_item) {} + virtual void visit (AST::StaticItem &static_item) {} + virtual void visit (AST::TraitItemFunc &item) {} + virtual void visit (AST::TraitItemMethod &item) {} + virtual void visit (AST::TraitItemConst &item) {} + virtual void visit (AST::TraitItemType &item) {} + virtual void visit (AST::Trait &trait) {} + virtual void visit (AST::InherentImpl &impl) {} + virtual void visit (AST::TraitImpl &impl) {} + // virtual void visit(ExternalItem& item) {} + virtual void visit (AST::ExternalStaticItem &item) {} + virtual void visit (AST::ExternalFunctionItem &item) {} + virtual void visit (AST::ExternBlock &block) {} + + // rust-macro.h + virtual void visit (AST::MacroMatchFragment &match) {} + virtual void visit (AST::MacroMatchRepetition &match) {} + virtual void visit (AST::MacroMatcher &matcher) {} + virtual void visit (AST::MacroRulesDefinition &rules_def) {} + virtual void visit (AST::MacroInvocation ¯o_invoc) {} + virtual void visit (AST::MetaItemPath &meta_item) {} + virtual void visit (AST::MetaItemSeq &meta_item) {} + virtual void visit (AST::MetaWord &meta_item) {} + virtual void visit (AST::MetaNameValueStr &meta_item) {} + virtual void visit (AST::MetaListPaths &meta_item) {} + virtual void visit (AST::MetaListNameValueStr &meta_item) {} + + // rust-pattern.h + virtual void visit (AST::LiteralPattern &pattern) {} + virtual void visit (AST::IdentifierPattern &pattern) {} + virtual void visit (AST::WildcardPattern &pattern) {} + // virtual void visit(RangePatternBound& bound) {} + virtual void visit (AST::RangePatternBoundLiteral &bound) {} + virtual void visit (AST::RangePatternBoundPath &bound) {} + virtual void visit (AST::RangePatternBoundQualPath &bound) {} + virtual void visit (AST::RangePattern &pattern) {} + virtual void visit (AST::ReferencePattern &pattern) {} + // virtual void visit(StructPatternField& field) {} + virtual void visit (AST::StructPatternFieldTuplePat &field) {} + virtual void visit (AST::StructPatternFieldIdentPat &field) {} + virtual void visit (AST::StructPatternFieldIdent &field) {} + virtual void visit (AST::StructPattern &pattern) {} + // virtual void visit(TupleStructItems& tuple_items) {} + virtual void visit (AST::TupleStructItemsNoRange &tuple_items) {} + virtual void visit (AST::TupleStructItemsRange &tuple_items) {} + virtual void visit (AST::TupleStructPattern &pattern) {} + // virtual void visit(TuplePatternItems& tuple_items) {} + virtual void visit (AST::TuplePatternItemsMultiple &tuple_items) {} + virtual void visit (AST::TuplePatternItemsRanged &tuple_items) {} + virtual void visit (AST::TuplePattern &pattern) {} + virtual void visit (AST::GroupedPattern &pattern) {} + virtual void visit (AST::SlicePattern &pattern) {} + + // rust-stmt.h + virtual void visit (AST::EmptyStmt &stmt) {} + virtual void visit (AST::LetStmt &stmt) {} + virtual void visit (AST::ExprStmtWithoutBlock &stmt) {} + virtual void visit (AST::ExprStmtWithBlock &stmt) {} + + // rust-type.h + virtual void visit (AST::TraitBound &bound) {} + virtual void visit (AST::ImplTraitType &type) {} + virtual void visit (AST::TraitObjectType &type) {} + virtual void visit (AST::ParenthesisedType &type) {} + virtual void visit (AST::ImplTraitTypeOneBound &type) {} + virtual void visit (AST::TraitObjectTypeOneBound &type) {} + virtual void visit (AST::TupleType &type) {} + virtual void visit (AST::NeverType &type) {} + virtual void visit (AST::RawPointerType &type) {} + virtual void visit (AST::ReferenceType &type) {} + virtual void visit (AST::ArrayType &type) {} + virtual void visit (AST::SliceType &type) {} + virtual void visit (AST::InferredType &type) {} + virtual void visit (AST::BareFunctionType &type) {} + +protected: + ASTLoweringBase () : mappings (Analysis::Mappings::get ()) {} + + Analysis::Mappings *mappings; +}; + +} // namespace HIR +} // namespace Rust + +#endif // RUST_AST_LOWER_BASE diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h new file mode 100644 index 0000000..6454a78 --- /dev/null +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -0,0 +1,240 @@ +// Copyright (C) 2020 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_AST_LOWER_EXPR +#define RUST_AST_LOWER_EXPR + +#include "rust-diagnostics.h" + +#include "rust-ast-lower-base.h" + +namespace Rust { +namespace HIR { + +class ASTLoweringExpr : public ASTLoweringBase +{ +public: + static HIR::Expr *translate (AST::Expr *expr) + { + ASTLoweringExpr resolver; + expr->accept_vis (resolver); + if (resolver.translated != nullptr) + { + resolver.mappings->insert_hir_expr ( + resolver.translated->get_mappings ().get_crate_num (), + resolver.translated->get_mappings ().get_hirid (), + resolver.translated); + } + + return resolver.translated; + } + + virtual ~ASTLoweringExpr () {} + + void visit (AST::PathInExpression &expr) + { + std::vector<HIR::PathExprSegment> path_segments; + expr.iterate_path_segments ([&] (AST::PathExprSegment &s) mutable -> bool { + rust_assert (s.has_generic_args () == false); // TODO + + HIR::PathIdentSegment is (s.get_ident_segment ().as_string ()); + HIR::PathExprSegment seg (is, s.get_locus ()); + path_segments.push_back (seg); + return true; + }); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated = new HIR::PathInExpression (mapping, std::move (path_segments), + expr.get_locus (), + expr.opening_scope_resolution ()); + } + + void visit (AST::ReturnExpr &expr) + { + HIR::Expr *return_expr = expr.has_return_expr () + ? ASTLoweringExpr::translate (expr.get_expr ()) + : nullptr; + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated = new HIR::ReturnExpr (mapping, expr.get_locus (), + std::unique_ptr<HIR::Expr> (return_expr)); + } + + void visit (AST::CallExpr &expr) + { + std::vector<HIR::Attribute> outer_attribs; + HIR::Expr *func = ASTLoweringExpr::translate (expr.function.get ()); + std::vector<std::unique_ptr<HIR::Expr> > params; + expr.iterate_params ([&] (AST::Expr *p) mutable -> bool { + auto trans = ASTLoweringExpr::translate (p); + params.push_back (std::unique_ptr<HIR::Expr> (trans)); + return true; + }); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping ( + crate_num, UNKNOWN_NODEID /* this can map back to the AST*/, + mappings->get_next_hir_id (crate_num), UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::CallExpr (mapping, std::unique_ptr<HIR::Expr> (func), + std::move (params), std::move (outer_attribs), + expr.get_locus ()); + } + + void visit (AST::AssignmentExpr &expr) + { + HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_lhs ()); + HIR::Expr *rhs = ASTLoweringExpr::translate (expr.get_rhs ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::AssignmentExpr (mapping, std::unique_ptr<HIR::Expr> (lhs), + std::unique_ptr<HIR::Expr> (rhs), + expr.get_locus ()); + } + + void visit (AST::IdentifierExpr &expr) + { + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + translated + = new HIR::IdentifierExpr (mapping, expr.as_string (), expr.get_locus ()); + } + + void visit (AST::LiteralExpr &expr) + { + HIR::Literal::LitType type = HIR::Literal::LitType::CHAR; + switch (expr.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::RAW_STRING: + type = HIR::Literal::LitType::RAW_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::RAW_BYTE_STRING: + type = HIR::Literal::LitType::RAW_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; + } + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated = new HIR::LiteralExpr (mapping, expr.as_string (), type, + expr.get_locus ()); + } + + void visit (AST::ArithmeticOrLogicalExpr &expr) + { + HIR::ArithmeticOrLogicalExpr::ExprType kind + = HIR::ArithmeticOrLogicalExpr::ExprType::ADD; + switch (expr.get_expr_type ()) + { + case AST::ArithmeticOrLogicalExpr::ExprType::ADD: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::ADD; + break; + case AST::ArithmeticOrLogicalExpr::ExprType::SUBTRACT: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::SUBTRACT; + break; + case AST::ArithmeticOrLogicalExpr::ExprType::MULTIPLY: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::MULTIPLY; + break; + case AST::ArithmeticOrLogicalExpr::ExprType::DIVIDE: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::DIVIDE; + break; + case AST::ArithmeticOrLogicalExpr::ExprType::MODULUS: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::MODULUS; + break; + case AST::ArithmeticOrLogicalExpr::ExprType::BITWISE_AND: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::BITWISE_AND; + break; + case AST::ArithmeticOrLogicalExpr::ExprType::BITWISE_OR: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::BITWISE_OR; + break; + case AST::ArithmeticOrLogicalExpr::ExprType::BITWISE_XOR: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::BITWISE_XOR; + break; + case AST::ArithmeticOrLogicalExpr::ExprType::LEFT_SHIFT: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::LEFT_SHIFT; + break; + case AST::ArithmeticOrLogicalExpr::ExprType::RIGHT_SHIFT: + kind = HIR::ArithmeticOrLogicalExpr::ExprType::RIGHT_SHIFT; + break; + } + + HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_lhs ()); + rust_assert (lhs != nullptr); + HIR::Expr *rhs = ASTLoweringExpr::translate (expr.right_expr.get ()); + rust_assert (rhs != nullptr); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::ArithmeticOrLogicalExpr (mapping, + std::unique_ptr<HIR::Expr> (lhs), + std::unique_ptr<HIR::Expr> (rhs), + kind, expr.get_locus ()); + } + +private: + ASTLoweringExpr () : translated (nullptr) {} + + HIR::Expr *translated; +}; + +} // namespace HIR +} // namespace Rust + +#endif // RUST_AST_LOWER_EXPR diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h new file mode 100644 index 0000000..5983e88 --- /dev/null +++ b/gcc/rust/hir/rust-ast-lower-item.h @@ -0,0 +1,134 @@ +// Copyright (C) 2020 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_AST_LOWER_ITEM +#define RUST_AST_LOWER_ITEM + +#include "rust-diagnostics.h" + +#include "rust-ast-lower-base.h" +#include "rust-ast-lower-type.h" +#include "rust-ast-lower-stmt.h" +#include "rust-ast-lower-pattern.h" + +namespace Rust { +namespace HIR { + +class ASTLoweringItem : public ASTLoweringBase +{ +public: + static HIR::Item *translate (AST::Item *item) + { + ASTLoweringItem resolver; + item->accept_vis (resolver); + return resolver.translated; + } + + virtual ~ASTLoweringItem () {} + + void visit (AST::Function &function) + { + // ignore for now and leave empty + std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + std::vector<HIR::Attribute> outer_attrs; + std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; + HIR::WhereClause where_clause (std::move (where_clause_items)); + HIR::FunctionQualifiers qualifiers ( + HIR::FunctionQualifiers::AsyncConstStatus::NONE, false); + HIR::Visibility vis = HIR::Visibility::create_public (); + + // need + Identifier function_name = function.function_name; + Location locus = function.get_locus (); + + std::unique_ptr<HIR::Type> return_type + = function.has_function_return_type () ? std::unique_ptr<HIR::Type> ( + ASTLoweringType::translate (function.return_type.get ())) + : nullptr; + + std::vector<HIR::FunctionParam> function_params; + for (auto ¶m : function.function_params) + { + auto translated_pattern = std::unique_ptr<HIR::Pattern> ( + ASTLoweringPattern::translate (param.param_name.get ())); + auto translated_type = std::unique_ptr<HIR::Type> ( + ASTLoweringType::translate (param.type.get ())); + + function_params.push_back ( + HIR::FunctionParam (std::move (translated_pattern), + std::move (translated_type), param.get_locus ())); + } + + std::unique_ptr<HIR::BlockExpr> function_body + = std::unique_ptr<HIR::BlockExpr> ( + translate (function.function_body.get ())); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, function.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + translated + = new HIR::Function (mapping, std::move (function_name), + std::move (qualifiers), std::move (generic_params), + std::move (function_params), std::move (return_type), + std::move (where_clause), std::move (function_body), + std::move (vis), std::move (outer_attrs), locus); + + mappings->insert_defid_mapping (mapping.get_defid (), translated); + mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (), + translated); + } + + // Helpers + + HIR::BlockExpr *translate (AST::BlockExpr *function_body) + { + std::vector<std::unique_ptr<HIR::Stmt> > block_stmts; + std::unique_ptr<HIR::ExprWithoutBlock> block_expr; + std::vector<HIR::Attribute> inner_attribs; + std::vector<HIR::Attribute> outer_attribs; + + function_body->iterate_stmts ([&] (AST::Stmt *s) mutable -> bool { + auto translated_stmt = ASTLoweringStmt::translate (s); + block_stmts.push_back (std::unique_ptr<HIR::Stmt> (translated_stmt)); + return true; + }); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, function_body->get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + return new HIR::BlockExpr (mapping, std::move (block_stmts), + std::move (block_expr), + std::move (inner_attribs), + std::move (outer_attribs), + function_body->get_locus ()); + } + +private: + ASTLoweringItem () : translated (nullptr) {} + + HIR::Item *translated; +}; + +} // namespace HIR +} // namespace Rust + +#endif // RUST_AST_LOWER_ITEM diff --git a/gcc/rust/hir/rust-ast-lower-pattern.h b/gcc/rust/hir/rust-ast-lower-pattern.h new file mode 100644 index 0000000..b69c9d9 --- /dev/null +++ b/gcc/rust/hir/rust-ast-lower-pattern.h @@ -0,0 +1,58 @@ +// Copyright (C) 2020 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_AST_LOWER_PATTERN +#define RUST_AST_LOWER_PATTERN + +#include "rust-ast-lower-base.h" +#include "rust-diagnostics.h" + +namespace Rust { +namespace HIR { + +class ASTLoweringPattern : public ASTLoweringBase +{ +public: + static HIR::Pattern *translate (AST::Pattern *pattern) + { + ASTLoweringPattern resolver; + pattern->accept_vis (resolver); + return resolver.translated; + } + + virtual ~ASTLoweringPattern () {} + + void visit (AST::IdentifierPattern &pattern) + { + std::unique_ptr<Pattern> to_bind; + translated + = new HIR::IdentifierPattern (pattern.variable_ident, + pattern.get_locus (), pattern.is_ref, + pattern.is_mut, std::move (to_bind)); + } + +private: + ASTLoweringPattern () : translated (nullptr) {} + + HIR::Pattern *translated; +}; + +} // namespace HIR +} // namespace Rust + +#endif // RUST_AST_LOWER_PATTERN diff --git a/gcc/rust/hir/rust-ast-lower-stmt.h b/gcc/rust/hir/rust-ast-lower-stmt.h new file mode 100644 index 0000000..d21b49d --- /dev/null +++ b/gcc/rust/hir/rust-ast-lower-stmt.h @@ -0,0 +1,96 @@ +// Copyright (C) 2020 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_AST_LOWER_STMT +#define RUST_AST_LOWER_STMT + +#include "rust-diagnostics.h" + +#include "rust-ast-lower-base.h" +#include "rust-ast-lower-type.h" +#include "rust-ast-lower-expr.h" +#include "rust-ast-lower-pattern.h" + +namespace Rust { +namespace HIR { + +class ASTLoweringStmt : public ASTLoweringBase +{ +public: + static HIR::Stmt *translate (AST::Stmt *stmt) + { + ASTLoweringStmt resolver; + stmt->accept_vis (resolver); + if (resolver.translated == nullptr) + { + printf ("Failing translating: %s\n", stmt->as_string ().c_str ()); + rust_assert (resolver.translated != nullptr); + } + return resolver.translated; + } + + virtual ~ASTLoweringStmt () {} + + void visit (AST::ExprStmtWithoutBlock &stmt) + { + HIR::Expr *expr = ASTLoweringExpr::translate (stmt.expr.get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, stmt.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + translated + = new HIR::ExprStmtWithoutBlock (mapping, + std::unique_ptr<HIR::Expr> (expr), + stmt.get_locus ()); + } + + void visit (AST::LetStmt &stmt) + { + std::vector<HIR::Attribute> outer_attrs; + HIR::Pattern *variables + = ASTLoweringPattern::translate (stmt.variables_pattern.get ()); + HIR::Type *type = stmt.has_type () + ? ASTLoweringType::translate (stmt.type.get ()) + : nullptr; + HIR::Expr *init_expression + = stmt.has_init_expr () + ? ASTLoweringExpr::translate (stmt.init_expr.get ()) + : nullptr; + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, stmt.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + translated + = new HIR::LetStmt (mapping, std::unique_ptr<HIR::Pattern> (variables), + std::unique_ptr<HIR::Expr> (init_expression), + std::unique_ptr<HIR::Type> (type), + std::move (outer_attrs), stmt.get_locus ()); + } + +private: + ASTLoweringStmt () : translated (nullptr) {} + + HIR::Stmt *translated; +}; + +} // namespace HIR +} // namespace Rust + +#endif // RUST_AST_LOWER_PATTERN diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h new file mode 100644 index 0000000..9611ca0 --- /dev/null +++ b/gcc/rust/hir/rust-ast-lower-type.h @@ -0,0 +1,84 @@ +// Copyright (C) 2020 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_AST_LOWER_TYPE +#define RUST_AST_LOWER_TYPE + +#include "rust-ast-lower-base.h" +#include "rust-diagnostics.h" + +namespace Rust { +namespace HIR { + +class ASTLoweringType : public ASTLoweringBase +{ +public: + static HIR::Type *translate (AST::Type *type) + { + ASTLoweringType resolver; + type->accept_vis (resolver); + return resolver.translated; + } + + virtual ~ASTLoweringType () {} + + virtual void visit (AST::TypePathSegment &segment) + { + HIR::PathIdentSegment ident (segment.get_ident_segment ().as_string ()); + translated_segment + = new HIR::TypePathSegment (ident, + segment.get_separating_scope_resolution (), + segment.get_locus ()); + } + + virtual void visit (AST::TypePath &path) + { + std::vector<std::unique_ptr<HIR::TypePathSegment> > translated_segments; + + path.iterate_segments ([&] (AST::TypePathSegment *seg) mutable -> bool { + translated_segment = nullptr; + seg->accept_vis (*this); + if (translated_segment == nullptr) + { + rust_fatal_error (seg->get_locus (), + "failed to translate AST TypePathSegment"); + return false; + } + + translated_segments.push_back ( + std::unique_ptr<HIR::TypePathSegment> (translated_segment)); + return true; + }); + + translated + = new HIR::TypePath (std::move (translated_segments), path.get_locus (), + path.has_opening_scope_resolution_op ()); + } + +private: + ASTLoweringType () : translated (nullptr) {} + + HIR::Type *translated; + + HIR::TypePathSegment *translated_segment; +}; + +} // namespace HIR +} // namespace Rust + +#endif // RUST_AST_LOWER_TYPE diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc new file mode 100644 index 0000000..8a514ce --- /dev/null +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -0,0 +1,62 @@ +// Copyright (C) 2020 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 +// <http://www.gnu.org/licenses/>. + +#include "rust-ast-lower.h" +#include "rust-ast-lower-item.h" + +namespace Rust { +namespace HIR { + +ASTLowering::ASTLowering (AST::Crate &astCrate) : astCrate (astCrate) {} + +ASTLowering::~ASTLowering () {} + +HIR::Crate +ASTLowering::Resolve (AST::Crate &astCrate) +{ + ASTLowering resolver (astCrate); + return resolver.go (); +} + +HIR::Crate +ASTLowering::go () +{ + std::vector<std::unique_ptr<HIR::Item> > items; + std::vector<HIR::Attribute> inner_attrs; + bool has_utf8bom = false; + bool has_shebang = false; + + for (auto it = astCrate.items.begin (); it != astCrate.items.end (); it++) + { + auto translated = ASTLoweringItem::translate (it->get ()); + if (translated != nullptr) + items.push_back (std::unique_ptr<HIR::Item> (translated)); + } + + auto mappings = Analysis::Mappings::get (); + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, UNKNOWN_NODEID, + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + return HIR::Crate (std::move (items), std::move (inner_attrs), mapping, + has_utf8bom, has_shebang); +} + +} // namespace HIR +} // namespace Rust diff --git a/gcc/rust/hir/rust-ast-lower.h b/gcc/rust/hir/rust-ast-lower.h new file mode 100644 index 0000000..bdc21ba --- /dev/null +++ b/gcc/rust/hir/rust-ast-lower.h @@ -0,0 +1,46 @@ +// Copyright (C) 2020 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 +// <http://www.gnu.org/licenses/>. + +#ifndef RUST_HIR_LOWER +#define RUST_HIR_LOWER + +#include "rust-system.h" +#include "rust-ast-full.h" +#include "rust-ast-visitor.h" +#include "rust-hir-full.h" + +namespace Rust { +namespace HIR { + +class ASTLowering +{ +public: + static HIR::Crate Resolve (AST::Crate &astCrate); + ~ASTLowering (); + +private: + ASTLowering (AST::Crate &astCrate); + HIR::Crate go (); + + AST::Crate &astCrate; +}; + +} // namespace HIR +} // namespace Rust + +#endif // RUST_HIR_LOWER diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index da50948..f526da1 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -1,5 +1,23 @@ -#include "rust-session-manager.h" +// Copyright (C) 2020 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 +// <http://www.gnu.org/licenses/>. +// #include "rust-session-manager.h" + +#include "rust-session-manager.h" #include "rust-diagnostics.h" #include "diagnostic.h" #include "input.h" @@ -13,13 +31,13 @@ #include "rust-scan.h" #include "rust-name-resolution.h" #include "rust-type-resolution.h" -#include "rust-compile.h" #include "rust-macro-expand.h" +#include "rust-compile.h" +// hir passes wip +#include "rust-ast-lower.h" #include "rust-target.h" -#include <algorithm> - extern Linemap * rust_get_linemap (); @@ -405,6 +423,7 @@ Session::parse_files (int num_files, const char **files) { for (int i = 0; i < num_files; i++) { + printf ("Attempting to parse file: %s\n", files[i]); parse_file (files[i]); } /* TODO: should semantic analysis be dealed with here? or per file? for now, @@ -431,6 +450,10 @@ Session::parse_file (const char *filename) // generate crate from parser auto parsed_crate = parser.parse_crate (); + // setup the mappings for this AST + auto mappings = Analysis::Mappings::get (); + mappings->insert_ast_crate (&parsed_crate); + // give a chance to give some debug switch (options.dump_option) { @@ -740,6 +763,12 @@ Session::resolution (AST::Crate &crate) // Name resolution must be in front of type resolution Analysis::NameResolution::Resolve (crate, toplevel); Analysis::TypeResolution::Resolve (crate, toplevel); + + // inject hir passes + HIR::Crate hir = HIR::ASTLowering::Resolve (crate); + fprintf (stderr, "HIR PASSES:\n"); + fprintf (stderr, "%s", hir.as_string ().c_str ()); + fprintf (stderr, "HIR PASSES - DONE:\n"); fprintf (stderr, "finished name resolution\n"); } |