From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by sourceware.org (Postfix) with ESMTPS id 089E3384BC01 for ; Wed, 26 Oct 2022 08:15:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 089E3384BC01 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-wr1-x436.google.com with SMTP id z14so11525786wrn.7 for ; Wed, 26 Oct 2022 01:15:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=lCnL/4Nl7nO+ssAcXFQsIgR40DIovPTqOXtnDsPdtTQ=; b=cAKs/AKAaSykpL6K2DSLJbR4SeX0mJK5qv8d5zB+Xb8wGtwuOicf8/y2b0sYCqxvhz JzJ4G3oremKmvFTh6rCLWohMl+n0r8AoPRXVsRBeVEfOfKpL5380DCb+oysWR2luBRG/ q92iyBGBO7i8FyoWbO2y686g3ccqHKTNkZRnaEvzNdxKBNnis8jMQOMefzLnuRN6lSXA eCL0nVNKgCWNFFZBIw/IgQBa0ZHkKxSP5jJ+pphOCLBwMGs83i7pQhLv3COBDqPU8ztd uskTiF1Pwu/B9tojNYWG8P3ZVlTydrmmbUIj/qvKQHwGM+N8IrMze5687GKpYutQb8Wy NpSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=lCnL/4Nl7nO+ssAcXFQsIgR40DIovPTqOXtnDsPdtTQ=; b=rRFCCmEWCc0kkyKHl6a7LYKk6mv6HzqYgo6L0CD7J0aKOZmiBF1cto7VM8DD/DadMT AZbPEb9YMX1rZQgq5oLhyMnROiNbKV9jifvP0CZCCsl8sVCgQR1y2lEaYYFYf0GdmWbC Ln8So81gvIA8WvQGQGVXy8GEjfzz/46eLy5RDUhOtaTln9Jj2UKJFsfYoUolSg9pYAmm myFl49H/webvNCRr99Wg597LhSzVg7TzykZ0K+zKeQ8Ox32xCn1UlVdpNrQ4/n1g+8ev 5SdFbIpfh/OkqCBTbb7EZmQovcxGwIao6lDsVwBCv2WyQHu+3GF2+5fkK9E7Yp6k1gLz P22Q== X-Gm-Message-State: ACrzQf3IoVw3YKm7EwVjHborMiDVcirFnqZp6JVfaKmURgSZDMn6lJoG S8LKslemJyWtu9/unS55voHphjs/OgMX45nJAA== X-Google-Smtp-Source: AMsMyM7+7Hcv0BsQwGc1ZV820aVPU4vH+bwZbdtzZIRzUo2Zy9TkyjqbWfwL3Ddyh66NCD4uZgLW7g== X-Received: by 2002:adf:de8d:0:b0:236:6087:e07e with SMTP id w13-20020adfde8d000000b002366087e07emr14216598wrl.533.1666772147579; Wed, 26 Oct 2022 01:15:47 -0700 (PDT) Received: from platypus.lan ([2001:861:5e4c:3bb0:6424:328a:1734:3249]) by smtp.googlemail.com with ESMTPSA id q16-20020a05600c46d000b003c6f426467fsm1134310wmo.40.2022.10.26.01.15.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Oct 2022 01:15:46 -0700 (PDT) From: arthur.cohen@embecosm.com To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org Subject: [PATCH Rust front-end v3 18/46] gccrs: Add HIR definitions and visitor framework Date: Wed, 26 Oct 2022 10:17:43 +0200 Message-Id: <20221026081811.602573-19-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20221026081811.602573-1-arthur.cohen@embecosm.com> References: <20221026081811.602573-1-arthur.cohen@embecosm.com> Reply-To: arthur.cohen@embecosm.com MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Philip Herron This patch implements the classes mentionned in the previous HIR patch, as well as a set of visitor frameworks used in handling that HIR. --- gcc/rust/hir/tree/rust-hir-full-decls.h | 232 + gcc/rust/hir/tree/rust-hir-full-test.cc | 5292 +++++++++++++++++++++++ gcc/rust/hir/tree/rust-hir-full.h | 30 + gcc/rust/hir/tree/rust-hir-visitor.h | 493 +++ gcc/rust/hir/tree/rust-hir.h | 921 ++++ 5 files changed, 6968 insertions(+) create mode 100644 gcc/rust/hir/tree/rust-hir-full-decls.h create mode 100644 gcc/rust/hir/tree/rust-hir-full-test.cc create mode 100644 gcc/rust/hir/tree/rust-hir-full.h create mode 100644 gcc/rust/hir/tree/rust-hir-visitor.h create mode 100644 gcc/rust/hir/tree/rust-hir.h diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h new file mode 100644 index 00000000000..2798ba9fd84 --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-full-decls.h @@ -0,0 +1,232 @@ +// 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 +// . + +#ifndef RUST_HIR_FULL_DECLS_H +#define RUST_HIR_FULL_DECLS_H + +namespace Rust { +namespace HIR { + +struct Literal; +class Stmt; +class Item; +class Expr; +class ExprWithoutBlock; +class Pattern; +class Type; +class TypeNoBounds; +class TypeParamBound; +class Lifetime; +class GenericParam; +class LifetimeParam; + +class TraitItem; +class ImplItem; +struct Crate; +class PathExpr; + +// rust-path.h +class PathIdentSegment; +struct GenericArgsBinding; +struct GenericArgs; +class PathExprSegment; +class PathPattern; +class PathInExpression; +class TypePathSegment; +class TypePathSegmentGeneric; +struct TypePathFunction; +class TypePathSegmentFunction; +class TypePath; +struct QualifiedPathType; +class QualifiedPathInExpression; +class QualifiedPathInType; + +// rust-expr.h +class ExprWithBlock; +class LiteralExpr; +class AttrInputLiteral; +class OperatorExpr; +class BorrowExpr; +class DereferenceExpr; +class ErrorPropagationExpr; +class NegationExpr; +class ArithmeticOrLogicalExpr; +class ComparisonExpr; +class LazyBooleanExpr; +class TypeCastExpr; +class AssignmentExpr; +class CompoundAssignmentExpr; +class GroupedExpr; +class ArrayElems; +class ArrayElemsValues; +class ArrayElemsCopied; +class ArrayExpr; +class ArrayIndexExpr; +class TupleExpr; +class TupleIndexExpr; +class StructExpr; +class StructExprStruct; +struct StructBase; +class StructExprField; +class StructExprFieldIdentifier; +class StructExprFieldWithVal; +class StructExprFieldIdentifierValue; +class StructExprFieldIndexValue; +class StructExprStructFields; +class StructExprStructBase; +class CallExpr; +class MethodCallExpr; +class FieldAccessExpr; +struct ClosureParam; +class ClosureExpr; +class ClosureExprInner; +class BlockExpr; +class ClosureExprInnerTyped; +class ContinueExpr; +class BreakExpr; +class RangeExpr; +class RangeFromToExpr; +class RangeFromExpr; +class RangeToExpr; +class RangeFullExpr; +class RangeFromToInclExpr; +class RangeToInclExpr; +class ReturnExpr; +class UnsafeBlockExpr; +class LoopLabel; +class BaseLoopExpr; +class LoopExpr; +class WhileLoopExpr; +class WhileLetLoopExpr; +class ForLoopExpr; +class IfExpr; +class IfExprConseqElse; +class IfExprConseqIf; +class IfLetExpr; +class IfExprConseqIfLet; +class IfLetExprConseqElse; +class IfLetExprConseqIf; +class IfLetExprConseqIfLet; +struct MatchArm; +// class MatchCase; +// class MatchCaseBlockExpr; +// class MatchCaseExpr; +struct MatchCase; +class MatchExpr; +class AwaitExpr; +class AsyncBlockExpr; + +// rust-stmt.h +class EmptyStmt; +class LetStmt; +class ExprStmt; +class ExprStmtWithoutBlock; +class ExprStmtWithBlock; + +// rust-item.h +class TypeParam; +class ConstGenericParam; +class WhereClauseItem; +class LifetimeWhereClauseItem; +class TypeBoundWhereClauseItem; +struct WhereClause; +struct SelfParam; +struct FunctionQualifiers; +struct FunctionParam; +struct Visibility; +class VisItem; +class Module; +class ExternCrate; +class UseTree; +class UseTreeGlob; +class UseTreeList; +class UseTreeRebind; +class UseDeclaration; +class Function; +class TypeAlias; +class Struct; +struct StructField; +class StructStruct; +struct TupleField; +class TupleStruct; +class EnumItem; +class EnumItemTuple; +class EnumItemStruct; +class EnumItemDiscriminant; +class Enum; +class Union; +class ConstantItem; +class StaticItem; +struct TraitFunctionDecl; +class TraitItemFunc; +class TraitItemConst; +class TraitItemType; +class Trait; +class ImplBlock; +class ExternalItem; +class ExternalStaticItem; +struct NamedFunctionParam; +class ExternalFunctionItem; +class ExternBlock; + +// rust-pattern.h +class LiteralPattern; +class IdentifierPattern; +class WildcardPattern; +class RangePatternBound; +class RangePatternBoundLiteral; +class RangePatternBoundPath; +class RangePatternBoundQualPath; +class RangePattern; +class ReferencePattern; +struct StructPatternEtc; +class StructPatternField; +class StructPatternFieldTuplePat; +class StructPatternFieldIdentPat; +class StructPatternFieldIdent; +class StructPattern; +class TupleStructItems; +class TupleStructItemsNoRange; +class TupleStructItemsRange; +class TupleStructPattern; +class TuplePatternItems; +class TuplePatternItemsMultiple; +class TuplePatternItemsRanged; +class TuplePattern; +class GroupedPattern; +class SlicePattern; + +// rust-type.h +class TraitBound; +class ImplTraitType; +class TraitObjectType; +class ParenthesisedType; +class ImplTraitTypeOneBound; +class TupleType; +class NeverType; +class RawPointerType; +class ReferenceType; +class ArrayType; +class SliceType; +class InferredType; +struct MaybeNamedParam; +class BareFunctionType; +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc new file mode 100644 index 00000000000..4e255320e2d --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-full-test.cc @@ -0,0 +1,5292 @@ +// 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-full.h" +#include "rust-hir-full.h" +#include "rust-hir-visitor.h" +#include "rust-diagnostics.h" + +/* Compilation unit used for various HIR-related functions that would make + * the headers too long if they were defined inline and don't receive any + * benefits from being defined inline because they are virtual. Also used + * for various other stuff. */ + +namespace Rust { +namespace HIR { + +enum indent_mode +{ + enter, + out, + stay +}; + +std::string +indent_spaces (enum indent_mode mode) +{ + static int indent = 0; + std::string str = ""; + if (out == mode) + indent--; + for (int i = 0; i < indent; i++) + str += " "; + if (enter == mode) + indent++; + + return str; +} + +// Gets a string in a certain delim type. +std::string +get_string_in_delims (std::string str_input, AST::DelimType delim_type) +{ + switch (delim_type) + { + case AST::DelimType::PARENS: + return "(" + str_input + ")"; + case AST::DelimType::SQUARE: + return "[" + str_input + "]"; + case AST::DelimType::CURLY: + return "{" + str_input + "}"; + default: + return "ERROR-MARK-STRING (delims)"; + } + gcc_unreachable (); +} + +std::string +Crate::as_string () const +{ + std::string str ("HIR::Crate: "); + + // inner attributes + str += "\n inner attributes: "; + if (inner_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "inner attribute" syntax - + * just the body */ + for (const auto &attr : inner_attrs) + { + str += "\n " + attr.as_string (); + } + } + + // items + str += "\n items: "; + if (items.empty ()) + { + str += "none"; + } + else + { + for (const auto &item : items) + { + // DEBUG: null pointer check + if (item == nullptr) + { + rust_debug ("something really terrible has gone wrong - " + "null pointer item in crate."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + item->as_string (); + } + } + + return str + "\n::" + get_mappings ().as_string () + "\n"; +} + +std::string +Visibility::as_string () const +{ + switch (vis_type) + { + case PRIVATE: + return std::string ("private"); + case PUBLIC: + return std::string ("pub"); + case RESTRICTED: + return std::string ("pub(in ") + path.get_mappings ().as_string () + + std::string (")"); + default: + gcc_unreachable (); + } +} + +// Creates a string that reflects the visibility stored. +std::string +VisItem::as_string () const +{ + // FIXME: can't do formatting on string to make identation occur. + std::string str = Item::as_string (); + + if (has_visibility ()) + { + str = visibility.as_string () + " "; + } + + return str; +} + +// Creates a string that reflects the outer attributes stored. +std::string +Item::as_string () const +{ + std::string str; + + if (!outer_attrs.empty ()) + { + for (const auto &attr : outer_attrs) + { + str += attr.as_string () + "\n"; + } + } + + return str; +} + +std::string +Module::as_string () const +{ + // get module string for "[vis] mod [name]" + std::string str = VisItem::as_string () + "mod " + module_name; + + // inner attributes + str += "\n inner attributes: "; + if (inner_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "inner attribute" syntax - + * just the body */ + for (const auto &attr : inner_attrs) + { + str += "\n " + attr.as_string (); + } + } + + // items + str += "\n items: "; + if (items.empty ()) + { + str += "none"; + } + else + { + for (const auto &item : items) + { + // DEBUG: null pointer check + if (item == nullptr) + { + rust_debug ("something really terrible has gone wrong - " + "null pointer item in crate."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + item->as_string (); + } + } + + return str + "\n"; +} + +std::string +StaticItem::as_string () const +{ + std::string str = VisItem::as_string (); + + str += indent_spaces (stay) + "static"; + + if (is_mut ()) + { + str += " mut"; + } + + str += name; + + // DEBUG: null pointer check + if (type == nullptr) + { + rust_debug ("something really terrible has gone wrong - null " + "pointer type in static item."); + return "nullptr_POINTER_MARK"; + } + str += "\n" + indent_spaces (stay) + "Type: " + type->as_string (); + + // DEBUG: null pointer check + if (expr == nullptr) + { + rust_debug ("something really terrible has gone wrong - null " + "pointer expr in static item."); + return "nullptr_POINTER_MARK"; + } + str += "\n" + indent_spaces (stay) + "Expression: " + expr->as_string (); + + return str + "\n"; +} + +std::string +ExternCrate::as_string () const +{ + std::string str = VisItem::as_string (); + + str += "extern crate " + referenced_crate; + + if (has_as_clause ()) + { + str += " as " + as_clause_name; + } + + return str; +} + +std::string +TupleStruct::as_string () const +{ + std::string str = VisItem::as_string (); + + str += "struct " + struct_name; + + // generic params + str += "\n Generic params: "; + if (generic_params.empty ()) + { + str += "none"; + } + else + { + for (const auto ¶m : generic_params) + { + // DEBUG: null pointer check + if (param == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer " + "generic param in enum."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + param->as_string (); + } + } + + // tuple fields + str += "\n Tuple fields: "; + if (fields.empty ()) + { + str += "none"; + } + else + { + for (const auto &field : fields) + { + str += "\n " + field.as_string (); + } + } + + str += "\n Where clause: "; + if (has_where_clause ()) + { + str += where_clause.as_string (); + } + else + { + str += "none"; + } + + return str; +} + +std::string +ConstantItem::as_string () const +{ + std::string str = VisItem::as_string (); + + str += "const " + identifier; + + // DEBUG: null pointer check + if (type == nullptr) + { + rust_debug ("something really terrible has gone wrong - null " + "pointer type in const item."); + return "nullptr_POINTER_MARK"; + } + str += "\n Type: " + type->as_string (); + + // DEBUG: null pointer check + if (const_expr == nullptr) + { + rust_debug ("something really terrible has gone wrong - null " + "pointer expr in const item."); + return "nullptr_POINTER_MARK"; + } + str += "\n Expression: " + const_expr->as_string (); + + return str + "\n"; +} + +std::string +ImplBlock::as_string () const +{ + std::string str = VisItem::as_string (); + + str += "impl "; + + // generic params + str += "\n Generic params: "; + if (generic_params.empty ()) + { + str += "none"; + } + else + { + for (const auto ¶m : generic_params) + { + // DEBUG: null pointer check + if (param == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer " + "generic param in impl."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + param->as_string (); + } + } + + str += "\n Type: " + impl_type->as_string (); + + str += "\n Where clause: "; + if (has_where_clause ()) + { + str += where_clause.as_string (); + } + else + { + str += "none"; + } + + // inner attributes + str += "\n inner attributes: "; + if (inner_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "inner attribute" syntax - + * just the body */ + for (const auto &attr : inner_attrs) + { + str += "\n " + attr.as_string (); + } + } + + str += "\n impl items: "; + if (!has_impl_items ()) + { + str += "none"; + } + else + { + for (const auto &item : impl_items) + { + str += "\n " + item->as_string (); + } + } + + return str; +} + +std::string +StructStruct::as_string () const +{ + std::string str = VisItem::as_string (); + + str += "struct " + struct_name; + + // generic params + str += "\n Generic params: "; + if (generic_params.empty ()) + { + str += "none"; + } + else + { + for (const auto ¶m : generic_params) + { + // DEBUG: null pointer check + if (param == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer " + "generic param in enum."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + param->as_string (); + } + } + + str += "\n Where clause: "; + if (has_where_clause ()) + { + str += where_clause.as_string (); + } + else + { + str += "none"; + } + + // struct fields + str += "\n Struct fields: "; + if (is_unit) + { + str += "none (unit)"; + } + else if (fields.empty ()) + { + str += "none (non-unit)"; + } + else + { + for (const auto &field : fields) + { + str += "\n - " + field.as_string (); + } + str += "\n"; + } + + return str + "::" + get_mappings ().as_string () + "\n"; +} + +std::string +UseDeclaration::as_string () const +{ + std::string str = VisItem::as_string (); + + // DEBUG: null pointer check + if (use_tree == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer use tree in " + "use declaration."); + return "nullptr_POINTER_MARK"; + } + + str += "use " + use_tree->as_string (); + + return str; +} + +std::string +UseTreeGlob::as_string () const +{ + switch (glob_type) + { + case NO_PATH: + return "*"; + case GLOBAL: + return "::*"; + case PATH_PREFIXED: { + std::string path_str = path.as_string (); + return path_str + "::*"; + } + default: + // some kind of error + return "ERROR-PATH"; + } + gcc_unreachable (); +} + +std::string +UseTreeList::as_string () const +{ + std::string path_str; + switch (path_type) + { + case NO_PATH: + path_str = "{"; + break; + case GLOBAL: + path_str = "::{"; + break; + case PATH_PREFIXED: { + path_str = path.as_string () + "::{"; + break; + } + default: + // some kind of error + return "ERROR-PATH-LIST"; + } + + if (has_trees ()) + { + auto i = trees.begin (); + auto e = trees.end (); + + // DEBUG: null pointer check + if (*i == nullptr) + { + rust_debug ("something really terrible has gone wrong - null pointer " + "tree in use tree list."); + return "nullptr_POINTER_MARK"; + } + + for (; i != e; i++) + { + path_str += (*i)->as_string (); + if (e != i + 1) + path_str += ", "; + } + } + else + { + path_str += "none"; + } + + return path_str + "}"; +} + +std::string +UseTreeRebind::as_string () const +{ + std::string path_str = path.as_string (); + + switch (bind_type) + { + case NONE: + // nothing to add, just path + break; + case IDENTIFIER: + path_str += " as " + identifier; + break; + case WILDCARD: + path_str += " as _"; + break; + default: + // error + return "ERROR-PATH-REBIND"; + } + + return path_str; +} + +std::string +Enum::as_string () const +{ + std::string str = VisItem::as_string (); + str += enum_name; + + // generic params + str += "\n Generic params: "; + if (generic_params.empty ()) + { + str += "none"; + } + else + { + for (const auto ¶m : generic_params) + { + // DEBUG: null pointer check + if (param == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer " + "generic param in enum."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + param->as_string (); + } + } + + str += "\n Where clause: "; + if (has_where_clause ()) + { + str += where_clause.as_string (); + } + else + { + str += "none"; + } + + // items + str += "\n Items: "; + if (items.empty ()) + { + str += "none"; + } + else + { + for (const auto &item : items) + { + // DEBUG: null pointer check + if (item == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer " + "enum item in enum."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + item->as_string (); + } + } + + return str; +} + +std::string +Trait::as_string () const +{ + std::string str = VisItem::as_string (); + + if (unsafety == Unsafety::Unsafe) + { + str += "unsafe "; + } + + str += "trait " + name; + + // generic params + str += "\n Generic params: "; + if (generic_params.empty ()) + { + str += "none"; + } + else + { + for (const auto ¶m : generic_params) + { + // DEBUG: null pointer check + if (param == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer " + "generic param in trait."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + param->as_string (); + } + } + + str += "\n Type param bounds: "; + if (!has_type_param_bounds ()) + { + str += "none"; + } + else + { + for (const auto &bound : type_param_bounds) + { + // DEBUG: null pointer check + if (bound == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer " + "type param bound in trait."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + bound->as_string (); + } + } + + str += "\n Where clause: "; + if (!has_where_clause ()) + { + str += "none"; + } + else + { + str += where_clause.as_string (); + } + + str += "\n Trait items: "; + if (!has_trait_items ()) + { + str += "none"; + } + else + { + for (const auto &item : trait_items) + { + // DEBUG: null pointer check + if (item == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer " + "trait item in trait."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + item->as_string (); + } + } + + return str; +} + +std::string +Union::as_string () const +{ + std::string str = VisItem::as_string (); + + str += "union " + union_name; + + // generic params + str += "\n Generic params: "; + if (generic_params.empty ()) + { + str += "none"; + } + else + { + for (const auto ¶m : generic_params) + { + // DEBUG: null pointer check + if (param == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer " + "generic param in union."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + param->as_string (); + } + } + + str += "\n Where clause: "; + if (has_where_clause ()) + { + str += where_clause.as_string (); + } + else + { + str += "none"; + } + + // struct fields + str += "\n Struct fields (variants): "; + if (variants.empty ()) + { + str += "none"; + } + else + { + for (const auto &field : variants) + { + str += "\n " + field.as_string (); + } + } + + return str; +} + +std::string +Function::as_string () const +{ + std::string str = VisItem::as_string () + "\n"; + std::string qstr = qualifiers.as_string (); + if ("" != qstr) + str += qstr + " "; + + if (has_function_return_type ()) + { + // DEBUG: null pointer check + if (return_type == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer return " + "type in function."); + return "nullptr_POINTER_MARK"; + } + + str += return_type->as_string () + " "; + } + else + { + str += "void "; + } + + str += function_name; + + if (has_generics ()) + { + str += "<"; + + auto i = generic_params.begin (); + auto e = generic_params.end (); + + // DEBUG: null pointer check + if (i == e) + { + rust_debug ("something really terrible has gone wrong - null pointer " + "generic param in function item."); + return "nullptr_POINTER_MARK"; + } + + for (; i != e; i++) + { + str += (*i)->as_string (); + if (e != i + 1) + str += ", "; + } + str += ">"; + } + + if (has_function_params ()) + { + auto i = function_params.begin (); + auto e = function_params.end (); + str += "("; + for (; i != e; i++) + { + str += (*i).as_string (); + if (e != i + 1) + str += ", "; + } + str += ")"; + } + else + { + str += "()"; + } + + if (has_where_clause ()) + { + str += " where " + where_clause.as_string (); + } + + str += "\n"; + + // DEBUG: null pointer check + if (function_body == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer function " + "body in function."); + return "nullptr_POINTER_MARK"; + } + return str + function_body->as_string () + "::" + get_mappings ().as_string () + + "\n"; +} + +std::string +WhereClause::as_string () const +{ + // just print where clause items, don't mention "where" or "where clause" + std::string str; + + if (where_clause_items.empty ()) + { + str = "none"; + } + else + { + for (const auto &item : where_clause_items) + { + str += "\n " + item->as_string (); + } + } + + return str; +} + +std::string +BlockExpr::as_string () const +{ + std::string istr = indent_spaces (enter); + std::string str = istr + "BlockExpr:\n" + istr; + // get outer attributes + str += "{\n" + indent_spaces (stay) + Expr::as_string (); + + // inner attributes + str += "\n" + indent_spaces (stay) + "inner attributes: "; + if (inner_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "inner attribute" syntax - + * just the body */ + for (const auto &attr : inner_attrs) + { + str += "\n" + indent_spaces (stay) + attr.as_string (); + } + } + + // statements + str += "\n" + indent_spaces (stay) + "statements: "; + if (statements.empty ()) + { + str += "none"; + } + else + { + for (const auto &stmt : statements) + { + // DEBUG: null pointer check + if (stmt == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer " + "stmt in block expr."); + return "nullptr_POINTER_MARK"; + } + + str += "\n" + indent_spaces (stay) + stmt->as_string (); + } + } + + // final expression + str += "\n" + indent_spaces (stay) + "final expression: "; + if (expr == nullptr) + { + str += "none"; + } + else + { + str += "\n" + expr->as_string (); + } + + str += "\n" + indent_spaces (out) + "}"; + return str; +} + +std::string +TypeAlias::as_string () const +{ + std::string str = VisItem::as_string (); + + str += " " + new_type_name; + + // generic params + str += "\n Generic params: "; + if (!has_generics ()) + { + str += "none"; + } + else + { + auto i = generic_params.begin (); + auto e = generic_params.end (); + + for (; i != e; i++) + { + str += (*i)->as_string (); + if (e != i + 1) + str += ", "; + } + } + + str += "\n Where clause: "; + if (!has_where_clause ()) + { + str += "none"; + } + else + { + str += where_clause.as_string (); + } + + str += "\n Type: " + existing_type->as_string (); + + return str; +} + +std::string +ExternBlock::as_string () const +{ + std::string str = VisItem::as_string (); + + str += "extern "; + str += "\"" + get_string_from_abi (abi) + "\" "; + + // inner attributes + str += "\n inner attributes: "; + if (inner_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "inner attribute" syntax - + * just the body */ + for (const auto &attr : inner_attrs) + { + str += "\n " + attr.as_string (); + } + } + + str += "\n external items: "; + if (!has_extern_items ()) + { + str += "none"; + } + else + { + for (const auto &item : extern_items) + { + str += "\n " + item->as_string (); + } + } + + return str; +} + +std::string +PathInExpression::as_string () const +{ + std::string str; + + if (has_opening_scope_resolution) + { + str = "::"; + } + + return str + PathPattern::as_string () + "::" + get_mappings ().as_string (); +} + +std::string +ExprStmtWithBlock::as_string () const +{ + std::string str = indent_spaces (enter) + "ExprStmtWithBlock: \n"; + + if (expr == nullptr) + { + str += "none (this should not happen and is an error)"; + } + else + { + indent_spaces (enter); + str += expr->as_string (); + indent_spaces (out); + } + + indent_spaces (out); + return str; +} + +std::string +ClosureParam::as_string () const +{ + std::string str (pattern->as_string ()); + + if (has_type_given ()) + { + str += " : " + type->as_string (); + } + + return str; +} + +std::string +ClosureExpr::as_string () const +{ + std::string str ("ClosureExpr:\n Has move: "); + if (has_move) + { + str += "true"; + } + else + { + str += "false"; + } + + str += "\n Params: "; + if (params.empty ()) + { + str += "none"; + } + else + { + for (const auto ¶m : params) + { + str += "\n " + param.as_string (); + } + } + + return str; +} + +std::string +ClosureExprInnerTyped::as_string () const +{ + std::string str = ClosureExpr::as_string (); + + str += "\n Return type: " + return_type->as_string (); + + str += "\n Body: " + expr->as_string (); + + return str; +} + +std::string +PathPattern::as_string () const +{ + std::string str; + + for (const auto &segment : segments) + { + str += segment.as_string () + "::"; + } + + // basically a hack - remove last two characters of string (remove final ::) + str.erase (str.length () - 2); + + return str; +} + +std::string +QualifiedPathType::as_string () const +{ + std::string str ("<"); + str += type->as_string (); + + if (has_as_clause ()) + { + str += " as " + trait->as_string (); + } + + return str + ">"; +} + +std::string +QualifiedPathInExpression::as_string () const +{ + return path_type.as_string () + "::" + PathPattern::as_string (); +} + +std::string +BorrowExpr::as_string () const +{ + std::string str ("&"); + + if (double_borrow) + { + str += "&"; + } + + if (is_mut ()) + { + str += "mut "; + } + + str += main_or_left_expr->as_string (); + + return str; +} + +std::string +ReturnExpr::as_string () const +{ + std::string str ("return "); + + if (has_return_expr ()) + { + str += return_expr->as_string (); + } + + return str + "::" + get_mappings ().as_string (); +} + +std::string +GroupedExpr::as_string () const +{ + std::string str ("Grouped expr:"); + + // inner attributes + str += "\n inner attributes: "; + if (inner_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "inner attribute" syntax - + * just the body */ + for (const auto &attr : inner_attrs) + { + str += "\n " + attr.as_string (); + } + } + + str += "\n Expr in parens: " + expr_in_parens->as_string (); + + return str; +} + +std::string +RangeToExpr::as_string () const +{ + return ".." + to->as_string (); +} + +std::string +ContinueExpr::as_string () const +{ + std::string str ("continue "); + + if (has_label ()) + { + str += label.as_string (); + } + + return str; +} + +std::string +NegationExpr::as_string () const +{ + std::string str; + + switch (expr_type) + { + case NegationOperator::NEGATE: + str = "-"; + break; + case NegationOperator::NOT: + str = "!"; + break; + default: + return "ERROR_MARK_STRING - negation expr"; + } + + str += main_or_left_expr->as_string (); + + return str; +} + +std::string +RangeFromExpr::as_string () const +{ + return from->as_string () + ".."; +} + +std::string +RangeFullExpr::as_string () const +{ + return ".."; +} + +std::string +ArrayIndexExpr::as_string () const +{ + return array_expr->as_string () + "[" + index_expr->as_string () + "]"; +} + +std::string +AssignmentExpr::as_string () const +{ + return main_or_left_expr->as_string () + " = " + right_expr->as_string () + + "::" + get_mappings ().as_string (); +} + +std::string +CompoundAssignmentExpr::as_string () const +{ + std::string operator_str; + operator_str.reserve (1); + + // get operator string + switch (expr_type) + { + case ArithmeticOrLogicalOperator::ADD: + operator_str = "+"; + break; + case ArithmeticOrLogicalOperator::SUBTRACT: + operator_str = "-"; + break; + case ArithmeticOrLogicalOperator::MULTIPLY: + operator_str = "*"; + break; + case ArithmeticOrLogicalOperator::DIVIDE: + operator_str = "/"; + break; + case ArithmeticOrLogicalOperator::MODULUS: + operator_str = "%"; + break; + case ArithmeticOrLogicalOperator::BITWISE_AND: + operator_str = "&"; + break; + case ArithmeticOrLogicalOperator::BITWISE_OR: + operator_str = "|"; + break; + case ArithmeticOrLogicalOperator::BITWISE_XOR: + operator_str = "^"; + break; + case ArithmeticOrLogicalOperator::LEFT_SHIFT: + operator_str = "<<"; + break; + case ArithmeticOrLogicalOperator::RIGHT_SHIFT: + operator_str = ">>"; + break; + default: + gcc_unreachable (); + break; + } + + operator_str += "="; + + std::string str ("CompoundAssignmentExpr: "); + if (main_or_left_expr == nullptr || right_expr == nullptr) + { + str += "error. this is probably a parsing failure."; + } + else + { + str += "\n left: " + main_or_left_expr->as_string (); + str += "\n right: " + right_expr->as_string (); + str += "\n operator: " + operator_str; + } + + return str; +} + +std::string +AsyncBlockExpr::as_string () const +{ + std::string str = "AsyncBlockExpr: "; + + // get outer attributes + str += "\n " + Expr::as_string (); + + str += "\n Has move: "; + str += has_move ? "true" : "false"; + + return str + "\n" + block_expr->as_string (); +} + +std::string +ComparisonExpr::as_string () const +{ + std::string str (main_or_left_expr->as_string ()); + + switch (expr_type) + { + case ComparisonOperator::EQUAL: + str += " == "; + break; + case ComparisonOperator::NOT_EQUAL: + str += " != "; + break; + case ComparisonOperator::GREATER_THAN: + str += " > "; + break; + case ComparisonOperator::LESS_THAN: + str += " < "; + break; + case ComparisonOperator::GREATER_OR_EQUAL: + str += " >= "; + break; + case ComparisonOperator::LESS_OR_EQUAL: + str += " <= "; + break; + default: + return "ERROR_MARK_STRING - comparison expr"; + } + + str += right_expr->as_string (); + + return str; +} + +std::string +MethodCallExpr::as_string () const +{ + std::string str ("MethodCallExpr: \n Object (receiver) expr: "); + + str += receiver->as_string (); + + str += "\n Method path segment: \n"; + + str += method_name.as_string (); + + str += "\n Call params:"; + if (params.empty ()) + { + str += "none"; + } + else + { + for (const auto ¶m : params) + { + if (param == nullptr) + { + return "ERROR_MARK_STRING - method call expr param is null"; + } + + str += "\n " + param->as_string (); + } + } + + return str; +} + +std::string +TupleIndexExpr::as_string () const +{ + return tuple_expr->as_string () + "." + std::to_string (tuple_index); +} + +std::string +DereferenceExpr::as_string () const +{ + return "*" + main_or_left_expr->as_string (); +} + +std::string +FieldAccessExpr::as_string () const +{ + return receiver->as_string () + "." + field; +} + +std::string +LazyBooleanExpr::as_string () const +{ + std::string str (main_or_left_expr->as_string ()); + + switch (expr_type) + { + case LazyBooleanOperator::LOGICAL_OR: + str += " || "; + break; + case LazyBooleanOperator::LOGICAL_AND: + str += " && "; + break; + default: + return "ERROR_MARK_STRING - lazy boolean expr out of bounds"; + } + + str += right_expr->as_string (); + + return str; +} + +std::string +RangeFromToExpr::as_string () const +{ + return from->as_string () + ".." + to->as_string (); +} + +std::string +RangeToInclExpr::as_string () const +{ + return "..=" + to->as_string (); +} + +std::string +UnsafeBlockExpr::as_string () const +{ + std::string istr = indent_spaces (enter); + std::string str = istr + "UnsafeBlockExpr:"; + str += istr + "{"; + + // get outer attributes + str += "\n" + indent_spaces (stay) + Expr::as_string (); + + return str + "\n" + indent_spaces (out) + "}\n" + expr->as_string (); +} + +std::string +ClosureExprInner::as_string () const +{ + std::string str = ClosureExpr::as_string (); + + str += "\n Expression: " + closure_inner->as_string (); + + return str; +} + +std::string +IfExpr::as_string () const +{ + std::string str ("IfExpr: "); + + str += "\n Condition expr: " + condition->as_string (); + + str += "\n If block expr: " + if_block->as_string (); + + return str; +} + +std::string +IfExprConseqElse::as_string () const +{ + std::string str = IfExpr::as_string (); + + str += "\n Else block expr: " + else_block->as_string (); + + return str; +} + +std::string +IfExprConseqIf::as_string () const +{ + std::string str = IfExpr::as_string (); + + str += "\n Else if expr: \n " + conseq_if_expr->as_string (); + + return str; +} + +std::string +IfExprConseqIfLet::as_string () const +{ + std::string str = IfExpr::as_string (); + + str += "\n Else if let expr: \n " + if_let_expr->as_string (); + + return str; +} + +std::string +IfLetExpr::as_string () const +{ + std::string str ("IfLetExpr: "); + + str += "\n Condition match arm patterns: "; + if (match_arm_patterns.empty ()) + { + str += "none"; + } + else + { + for (const auto &pattern : match_arm_patterns) + { + str += "\n " + pattern->as_string (); + } + } + + str += "\n Scrutinee expr: " + value->as_string (); + + str += "\n If let block expr: " + if_block->as_string (); + + return str; +} + +std::string +IfLetExprConseqElse::as_string () const +{ + std::string str = IfLetExpr::as_string (); + + str += "\n Else block expr: " + else_block->as_string (); + + return str; +} + +std::string +IfLetExprConseqIf::as_string () const +{ + std::string str = IfLetExpr::as_string (); + + str += "\n Else if expr: \n " + if_expr->as_string (); + + return str; +} + +std::string +IfLetExprConseqIfLet::as_string () const +{ + std::string str = IfLetExpr::as_string (); + + str += "\n Else if let expr: \n " + if_let_expr->as_string (); + + return str; +} + +std::string +RangeFromToInclExpr::as_string () const +{ + return from->as_string () + "..=" + to->as_string (); +} + +std::string +ErrorPropagationExpr::as_string () const +{ + return main_or_left_expr->as_string () + "?"; +} + +std::string +ArithmeticOrLogicalExpr::as_string () const +{ + std::string operator_str; + operator_str.reserve (1); + + // get operator string + switch (expr_type) + { + case ArithmeticOrLogicalOperator::ADD: + operator_str = "+"; + break; + case ArithmeticOrLogicalOperator::SUBTRACT: + operator_str = "-"; + break; + case ArithmeticOrLogicalOperator::MULTIPLY: + operator_str = "*"; + break; + case ArithmeticOrLogicalOperator::DIVIDE: + operator_str = "/"; + break; + case ArithmeticOrLogicalOperator::MODULUS: + operator_str = "%"; + break; + case ArithmeticOrLogicalOperator::BITWISE_AND: + operator_str = "&"; + break; + case ArithmeticOrLogicalOperator::BITWISE_OR: + operator_str = "|"; + break; + case ArithmeticOrLogicalOperator::BITWISE_XOR: + operator_str = "^"; + break; + case ArithmeticOrLogicalOperator::LEFT_SHIFT: + operator_str = "<<"; + break; + case ArithmeticOrLogicalOperator::RIGHT_SHIFT: + operator_str = ">>"; + break; + default: + gcc_unreachable (); + break; + } + + std::string str = main_or_left_expr->as_string () + " "; + str += operator_str + " "; + str += right_expr->as_string (); + + return "( " + str + " (" + get_mappings ().as_string () + "))"; +} + +std::string +CallExpr::as_string () const +{ + std::string str = function->as_string () + "("; + if (!has_params ()) + str += "none"; + else + { + for (const auto ¶m : params) + { + if (param == nullptr) + { + return "ERROR_MARK_STRING - call expr param is null"; + } + + str += param->as_string () + ","; + } + } + return str + ")" + "::" + get_mappings ().as_string (); +} + +std::string +WhileLoopExpr::as_string () const +{ + std::string str ("WhileLoopExpr: "); + + str += "\n Label: "; + if (!has_loop_label ()) + { + str += "none"; + } + else + { + str += loop_label.as_string (); + } + + str += "\n Conditional expr: " + condition->as_string (); + + str += "\n Loop block: " + loop_block->as_string (); + + return str; +} + +std::string +WhileLetLoopExpr::as_string () const +{ + std::string str ("WhileLetLoopExpr: "); + + str += "\n Label: "; + if (!has_loop_label ()) + { + str += "none"; + } + else + { + str += loop_label.as_string (); + } + + str += "\n Match arm patterns: "; + if (match_arm_patterns.empty ()) + { + str += "none"; + } + else + { + for (const auto &pattern : match_arm_patterns) + { + str += "\n " + pattern->as_string (); + } + } + + str += "\n Scrutinee expr: " + condition->as_string (); + + str += "\n Loop block: " + loop_block->as_string (); + + return str; +} + +std::string +LoopExpr::as_string () const +{ + std::string str ("LoopExpr: (infinite loop)"); + + str += "\n Label: "; + if (!has_loop_label ()) + { + str += "none"; + } + else + { + str += loop_label.as_string (); + } + + str += "\n Loop block: " + loop_block->as_string (); + + return str; +} + +std::string +ArrayExpr::as_string () const +{ + std::string str ("ArrayExpr:"); + + // inner attributes + str += "\n inner attributes: "; + if (inner_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "inner attribute" syntax - + * just the body */ + for (const auto &attr : inner_attrs) + { + str += "\n " + attr.as_string (); + } + } + + str += "\n Array elems: "; + if (!has_array_elems ()) + { + str += "none"; + } + else + { + str += internal_elements->as_string (); + } + + return str; +} + +std::string +AwaitExpr::as_string () const +{ + return awaited_expr->as_string () + ".await"; +} + +std::string +BreakExpr::as_string () const +{ + std::string str ("break "); + + if (has_label ()) + { + str += label.as_string () + " "; + } + + if (has_break_expr ()) + { + str += break_expr->as_string (); + } + + return str; +} + +std::string +LoopLabel::as_string () const +{ + return label.as_string () + ": (label) "; +} + +std::string +MatchArm::as_string () const +{ + // outer attributes + std::string str = "Outer attributes: "; + if (outer_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "outer attribute" syntax - + * just the body */ + for (const auto &attr : outer_attrs) + { + str += "\n " + attr.as_string (); + } + } + + str += "\nPatterns: "; + if (match_arm_patterns.empty ()) + { + str += "none"; + } + else + { + for (const auto &pattern : match_arm_patterns) + { + str += "\n " + pattern->as_string (); + } + } + + str += "\nGuard expr: "; + if (!has_match_arm_guard ()) + { + str += "none"; + } + else + { + str += guard_expr->as_string (); + } + + return str; +} + +std::string +MatchCase::as_string () const +{ + std::string str ("MatchCase: (match arm) "); + + str += "\n Match arm matcher: \n" + arm.as_string (); + str += "\n Expr: " + expr->as_string (); + + return str; +} + +/*std::string +MatchCaseBlockExpr::as_string () const +{ + std::string str = MatchCase::as_string (); + + str += "\n Block expr: " + block_expr->as_string (); + + return str; +} + +std::string +MatchCaseExpr::as_string () const +{ + std::string str = MatchCase::as_string (); + + str += "\n Expr: " + expr->as_string (); + + return str; +}*/ + +std::string +MatchExpr::as_string () const +{ + std::string str ("MatchExpr:"); + + str += "\n Scrutinee expr: " + branch_value->as_string (); + + // inner attributes + str += "\n inner attributes: "; + if (inner_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "inner attribute" syntax - + * just the body */ + for (const auto &attr : inner_attrs) + { + str += "\n " + attr.as_string (); + } + } + + // match arms + str += "\n Match arms: "; + if (match_arms.empty ()) + { + str += "none"; + } + else + { + for (const auto &arm : match_arms) + str += "\n " + arm.as_string (); + } + + return str; +} + +std::string +TupleExpr::as_string () const +{ + std::string str ("TupleExpr:"); + + // inner attributes + str += "\n inner attributes: "; + if (inner_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "inner attribute" syntax - + * just the body */ + for (const auto &attr : inner_attrs) + { + str += "\n " + attr.as_string (); + } + } + + str += "\n Tuple elements: "; + if (tuple_elems.empty ()) + { + str += "none"; + } + else + { + for (const auto &elem : tuple_elems) + { + str += "\n " + elem->as_string (); + } + } + + return str; +} + +std::string +ExprStmtWithoutBlock::as_string () const +{ + std::string str ("ExprStmtWithoutBlock:\n"); + indent_spaces (enter); + str += indent_spaces (stay); + + if (expr == nullptr) + { + str += "none (this shouldn't happen and is probably an error)"; + } + else + { + str += expr->as_string (); + } + indent_spaces (out); + + return str; +} + +std::string +FunctionParam::as_string () const +{ + return param_name->as_string () + " : " + type->as_string (); +} + +std::string +FunctionQualifiers::as_string () const +{ + std::string str; + + switch (const_status) + { + case NONE: + // do nothing + break; + case CONST_FN: + str += "const "; + break; + case ASYNC_FN: + str += "async "; + break; + default: + return "ERROR_MARK_STRING: async-const status failure"; + } + + if (unsafety == Unsafety::Unsafe) + { + str += "unsafe "; + } + + if (has_extern) + { + str += "extern"; + str += " \"" + get_string_from_abi (abi) + "\""; + } + + return str; +} + +std::string +TraitBound::as_string () const +{ + std::string str ("TraitBound:"); + + str += "\n Has opening question mark: "; + if (opening_question_mark) + { + str += "true"; + } + else + { + str += "false"; + } + + str += "\n For lifetimes: "; + if (!has_for_lifetimes ()) + { + str += "none"; + } + else + { + for (const auto &lifetime : for_lifetimes) + { + str += "\n " + lifetime.as_string (); + } + } + + str += "\n Type path: " + type_path.as_string (); + + return str; +} + +std::string +LifetimeParam::as_string () const +{ + std::string str ("LifetimeParam: "); + + str += "\n Outer attribute: "; + if (!has_outer_attribute ()) + { + str += "none"; + } + else + { + str += outer_attr.as_string (); + } + + str += "\n Lifetime: " + lifetime.as_string (); + + str += "\n Lifetime bounds: "; + if (!has_lifetime_bounds ()) + { + str += "none"; + } + else + { + for (const auto &bound : lifetime_bounds) + { + str += "\n " + bound.as_string (); + } + } + + return str; +} + +std::string +QualifiedPathInType::as_string () const +{ + std::string str = path_type.as_string (); + + for (const auto &segment : segments) + { + str += "::" + segment->as_string (); + } + + return str; +} + +std::string +Lifetime::as_string () const +{ + if (is_error ()) + { + return "error lifetime"; + } + + switch (lifetime_type) + { + case AST::Lifetime::LifetimeType::NAMED: + return "'" + lifetime_name; + case AST::Lifetime::LifetimeType::STATIC: + return "'static"; + case AST::Lifetime::LifetimeType::WILDCARD: + return "'_"; + default: + return "ERROR-MARK-STRING: lifetime type failure"; + } +} + +std::string +TypePath::as_string () const +{ + std::string str; + + if (has_opening_scope_resolution) + { + str = "::"; + } + + for (const auto &segment : segments) + { + str += segment->as_string () + "::"; + } + + // kinda hack - remove last 2 '::' characters + str.erase (str.length () - 2); + + return str; +} + +std::string +TypeParam::as_string () const +{ + std::string str ("TypeParam: "); + + str += "\n Outer attribute: "; + if (!has_outer_attribute ()) + { + str += "none"; + } + else + { + str += outer_attr.as_string (); + } + + str += "\n Identifier: " + type_representation; + + str += "\n Type param bounds: "; + if (!has_type_param_bounds ()) + { + str += "none"; + } + else + { + for (const auto &bound : type_param_bounds) + { + str += "\n " + bound->as_string (); + } + } + + str += "\n Type: "; + if (!has_type ()) + { + str += "none"; + } + else + { + str += type->as_string (); + } + + return str; +} + +AST::SimplePath +PathPattern::convert_to_simple_path (bool with_opening_scope_resolution) const +{ + if (!has_segments ()) + { + return AST::SimplePath::create_empty (); + } + + // create vector of reserved size (to minimise reallocations) + std::vector simple_segments; + simple_segments.reserve (segments.size ()); + + for (const auto &segment : segments) + { + // return empty path if doesn't meet simple path segment requirements + if (segment.has_generic_args () || segment.as_string () == "Self") + { + return AST::SimplePath::create_empty (); + } + + // create segment and add to vector + std::string segment_str = segment.as_string (); + simple_segments.push_back ( + AST::SimplePathSegment (std::move (segment_str), segment.get_locus ())); + } + + // kind of a HACK to get locus depending on opening scope resolution + Location locus = Linemap::unknown_location (); + if (with_opening_scope_resolution) + { + locus = simple_segments[0].get_locus () - 2; // minus 2 chars for :: + } + else + { + locus = simple_segments[0].get_locus (); + } + + return AST::SimplePath (std::move (simple_segments), + with_opening_scope_resolution, locus); +} + +AST::SimplePath +TypePath::as_simple_path () const +{ + if (segments.empty ()) + { + return AST::SimplePath::create_empty (); + } + + // create vector of reserved size (to minimise reallocations) + std::vector simple_segments; + simple_segments.reserve (segments.size ()); + + for (const auto &segment : segments) + { + // return empty path if doesn't meet simple path segment requirements + if (segment == nullptr || segment->is_error () + || !segment->is_ident_only () || segment->as_string () == "Self") + { + return AST::SimplePath::create_empty (); + } + + // create segment and add to vector + std::string segment_str = segment->as_string (); + simple_segments.push_back ( + AST::SimplePathSegment (std::move (segment_str), + segment->get_locus ())); + } + + return AST::SimplePath (std::move (simple_segments), + has_opening_scope_resolution, locus); +} + +std::string +PathExprSegment::as_string () const +{ + std::string ident_str = segment_name.as_string (); + if (has_generic_args ()) + { + ident_str += "::<" + generic_args.as_string () + ">"; + } + + return ident_str; +} + +std::string +GenericArgs::as_string () const +{ + std::string args; + + // lifetime args + if (!lifetime_args.empty ()) + { + auto i = lifetime_args.begin (); + auto e = lifetime_args.end (); + + for (; i != e; i++) + { + args += (*i).as_string (); + if (e != i + 1) + args += ", "; + } + } + + // type args + if (!type_args.empty ()) + { + auto i = type_args.begin (); + auto e = type_args.end (); + + for (; i != e; i++) + { + args += (*i)->as_string (); + if (e != i + 1) + args += ", "; + } + } + + // binding args + if (!binding_args.empty ()) + { + auto i = binding_args.begin (); + auto e = binding_args.end (); + + for (; i != e; i++) + { + args += (*i).as_string (); + if (e != i + 1) + args += ", "; + } + } + + return args; +} + +std::string +GenericArgsBinding::as_string () const +{ + return identifier + " = " + type->as_string (); +} + +std::string +ForLoopExpr::as_string () const +{ + std::string str ("ForLoopExpr: "); + + str += "\n Label: "; + if (!has_loop_label ()) + { + str += "none"; + } + else + { + str += loop_label.as_string (); + } + + str += "\n Pattern: " + pattern->as_string (); + + str += "\n Iterator expr: " + iterator_expr->as_string (); + + str += "\n Loop block: " + loop_block->as_string (); + + return str; +} + +std::string +RangePattern::as_string () const +{ + if (has_ellipsis_syntax) + { + return lower->as_string () + "..." + upper->as_string (); + } + else + { + return lower->as_string () + "..=" + upper->as_string (); + } +} + +std::string +RangePatternBoundLiteral::as_string () const +{ + std::string str; + + if (has_minus) + { + str += "-"; + } + + str += literal.as_string (); + + return str; +} + +std::string +SlicePattern::as_string () const +{ + std::string str ("SlicePattern: "); + + for (const auto &pattern : items) + { + str += "\n " + pattern->as_string (); + } + + return str; +} + +std::string +TuplePatternItemsMultiple::as_string () const +{ + std::string str; + + for (const auto &pattern : patterns) + { + str += "\n " + pattern->as_string (); + } + + return str; +} + +std::string +TuplePatternItemsRanged::as_string () const +{ + std::string str; + + str += "\n Lower patterns: "; + if (lower_patterns.empty ()) + { + str += "none"; + } + else + { + for (const auto &lower : lower_patterns) + { + str += "\n " + lower->as_string (); + } + } + + str += "\n Upper patterns: "; + if (upper_patterns.empty ()) + { + str += "none"; + } + else + { + for (const auto &upper : upper_patterns) + { + str += "\n " + upper->as_string (); + } + } + + return str; +} + +std::string +TuplePattern::as_string () const +{ + return "TuplePattern: " + items->as_string (); +} + +std::string +StructPatternField::as_string () const +{ + // outer attributes + std::string str ("Outer attributes: "); + if (outer_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "outer attribute" syntax - + * just the body */ + for (const auto &attr : outer_attrs) + { + str += "\n " + attr.as_string (); + } + } + + return str; +} + +std::string +StructPatternFieldIdent::as_string () const +{ + std::string str = StructPatternField::as_string (); + + str += "\n"; + + if (has_ref) + { + str += "ref "; + } + + if (is_mut ()) + { + str += "mut "; + } + + str += ident; + + return str; +} + +std::string +StructPatternFieldTuplePat::as_string () const +{ + std::string str = StructPatternField::as_string (); + + str += "\n"; + + str += std::to_string (index) + " : " + tuple_pattern->as_string (); + + return str; +} + +std::string +StructPatternFieldIdentPat::as_string () const +{ + std::string str = StructPatternField::as_string (); + + str += "\n"; + + str += ident + " : " + ident_pattern->as_string (); + + return str; +} + +std::string +StructPatternElements::as_string () const +{ + std::string str ("\n Fields: "); + + if (!has_struct_pattern_fields ()) + { + str += "none"; + } + else + { + for (const auto &field : fields) + { + str += "\n " + field->as_string (); + } + } + + return str; +} + +std::string +StructPattern::as_string () const +{ + std::string str ("StructPattern: \n Path: "); + + str += path.as_string (); + + str += "\n Struct pattern elems: "; + if (!has_struct_pattern_elems ()) + { + str += "none"; + } + else + { + str += elems.as_string (); + } + + return str; +} + +std::string +LiteralPattern::as_string () const +{ + return lit.as_string (); +} + +std::string +ReferencePattern::as_string () const +{ + std::string str ("&"); + + if (has_two_amps) + { + str += "&"; + } + + if (is_mut ()) + { + str += "mut "; + } + + str += pattern->as_string (); + + return str; +} + +std::string +IdentifierPattern::as_string () const +{ + std::string str; + + if (is_ref) + { + str += "ref "; + } + + if (is_mut ()) + { + str += "mut "; + } + + str += variable_ident; + + if (has_pattern_to_bind ()) + { + str += " @ " + to_bind->as_string (); + } + + return str; +} + +std::string +TupleStructItemsNoRange::as_string () const +{ + std::string str; + + for (const auto &pattern : patterns) + { + str += "\n " + pattern->as_string (); + } + + return str; +} + +std::string +TupleStructItemsRange::as_string () const +{ + std::string str ("\n Lower patterns: "); + + if (lower_patterns.empty ()) + { + str += "none"; + } + else + { + for (const auto &lower : lower_patterns) + { + str += "\n " + lower->as_string (); + } + } + + str += "\n Upper patterns: "; + if (upper_patterns.empty ()) + { + str += "none"; + } + else + { + for (const auto &upper : upper_patterns) + { + str += "\n " + upper->as_string (); + } + } + + return str; +} + +std::string +TupleStructPattern::as_string () const +{ + std::string str ("TupleStructPattern: \n Path: "); + + str += path.as_string (); + + str += "\n Tuple struct items: " + items->as_string (); + + return str; +} + +std::string +LetStmt::as_string () const +{ + // outer attributes + std::string str = "Outer attributes: "; + if (outer_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "outer attribute" syntax - + * just the body */ + indent_spaces (enter); + for (const auto &attr : outer_attrs) + { + str += "\n" + indent_spaces (stay) + attr.as_string (); + } + indent_spaces (out); + } + + str += "\n" + indent_spaces (stay) + "let " + variables_pattern->as_string (); + + if (has_type ()) + { + str += " : " + type->as_string (); + } + + if (has_init_expr ()) + { + str += " = " + init_expr->as_string (); + } + + return str; +} + +// Used to get outer attributes for expressions. +std::string +Expr::as_string () const +{ + // outer attributes + std::string str = "outer attributes: "; + if (outer_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "outer attribute" syntax - + * just the body */ + for (const auto &attr : outer_attrs) + { + str += "\n " + attr.as_string (); + } + } + + return str; +} + +// hopefully definition here will prevent circular dependency issue +TraitBound * +TypePath::to_trait_bound (bool in_parens) const +{ + // create clone FIXME is this required? or is copy constructor automatically + // called? + TypePath copy (*this); + return new TraitBound (mappings, std::move (copy), copy.get_locus (), + in_parens); +} + +std::string +InferredType::as_string () const +{ + return "_ (inferred) " + get_mappings ().as_string (); +} + +std::string +TypeCastExpr::as_string () const +{ + return main_or_left_expr->as_string () + " as " + + type_to_convert_to->as_string (); +} + +std::string +ImplTraitType::as_string () const +{ + std::string str ("ImplTraitType: \n TypeParamBounds: "); + + if (type_param_bounds.empty ()) + { + str += "none"; + } + else + { + for (const auto &bound : type_param_bounds) + { + str += "\n " + bound->as_string (); + } + } + + return str; +} + +std::string +ReferenceType::as_string () const +{ + std::string str ("&"); + + if (has_lifetime ()) + { + str += lifetime.as_string () + " "; + } + + if (is_mut ()) + { + str += "mut "; + } + + str += type->as_string (); + + return str; +} + +std::string +RawPointerType::as_string () const +{ + return std::string ("*") + (is_mut () ? "mut " : "const ") + + type->as_string (); +} + +std::string +TraitObjectType::as_string () const +{ + std::string str ("TraitObjectType: \n Has dyn dispatch: "); + + if (has_dyn) + { + str += "true"; + } + else + { + str += "false"; + } + + str += "\n TypeParamBounds: "; + if (type_param_bounds.empty ()) + { + str += "none"; + } + else + { + for (const auto &bound : type_param_bounds) + { + str += "\n " + bound->as_string (); + } + } + + return str; +} + +std::string +BareFunctionType::as_string () const +{ + std::string str ("BareFunctionType: \n For lifetimes: "); + + if (!has_for_lifetimes ()) + { + str += "none"; + } + else + { + for (const auto &for_lifetime : for_lifetimes) + { + str += "\n " + for_lifetime.as_string (); + } + } + + str += "\n Qualifiers: " + function_qualifiers.as_string (); + + str += "\n Params: "; + if (params.empty ()) + { + str += "none"; + } + else + { + for (const auto ¶m : params) + { + str += "\n " + param.as_string (); + } + } + + str += "\n Is variadic: "; + if (is_variadic) + { + str += "true"; + } + else + { + str += "false"; + } + + str += "\n Return type: "; + if (!has_return_type ()) + { + str += "none (void)"; + } + else + { + str += return_type->as_string (); + } + + return str; +} + +std::string +ImplTraitTypeOneBound::as_string () const +{ + std::string str ("ImplTraitTypeOneBound: \n TraitBound: "); + + return str + trait_bound.as_string (); +} + +std::string +TypePathSegmentGeneric::as_string () const +{ + return TypePathSegment::as_string () + "<" + generic_args.as_string () + ">"; +} + +std::string +TypePathFunction::as_string () const +{ + std::string str ("("); + + if (has_inputs ()) + { + auto i = inputs.begin (); + auto e = inputs.end (); + + for (; i != e; i++) + { + str += (*i)->as_string (); + if (e != i + 1) + str += ", "; + } + } + + str += ")"; + + if (has_return_type ()) + { + str += " -> " + return_type->as_string (); + } + + return str; +} + +std::string +TypePathSegmentFunction::as_string () const +{ + return TypePathSegment::as_string () + function_path.as_string (); +} + +std::string +ArrayType::as_string () const +{ + return "[" + elem_type->as_string () + "; " + size->as_string () + "]"; +} + +std::string +SliceType::as_string () const +{ + return "[" + elem_type->as_string () + "]"; +} + +std::string +TupleType::as_string () const +{ + std::string str ("("); + + if (!is_unit_type ()) + { + auto i = elems.begin (); + auto e = elems.end (); + + for (; i != e; i++) + { + str += (*i)->as_string (); + if (e != i + 1) + str += ", "; + } + } + + str += ")"; + + return str; +} + +std::string +StructExpr::as_string () const +{ + std::string str = ExprWithoutBlock::as_string (); + indent_spaces (enter); + str += "\n" + indent_spaces (stay) + "StructExpr:"; + indent_spaces (enter); + str += "\n" + indent_spaces (stay) + "PathInExpr:\n"; + str += indent_spaces (stay) + struct_name.as_string (); + indent_spaces (out); + indent_spaces (out); + return str; +} + +std::string +StructExprStruct::as_string () const +{ + std::string str ("StructExprStruct (or subclass): "); + + str += "\n Path: " + struct_name.as_string (); + + // inner attributes + str += "\n inner attributes: "; + if (inner_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "inner attribute" syntax - + * just the body */ + for (const auto &attr : inner_attrs) + { + str += "\n " + attr.as_string (); + } + } + + return str; +} + +std::string +StructBase::as_string () const +{ + if (base_struct != nullptr) + { + return base_struct->as_string (); + } + else + { + return "ERROR_MARK_STRING - invalid struct base had as string applied"; + } +} + +std::string +StructExprFieldWithVal::as_string () const +{ + // used to get value string + return value->as_string (); +} + +std::string +StructExprFieldIdentifierValue::as_string () const +{ + return field_name + " : " + StructExprFieldWithVal::as_string (); +} + +std::string +StructExprFieldIndexValue::as_string () const +{ + return std::to_string (index) + " : " + StructExprFieldWithVal::as_string (); +} + +std::string +StructExprStructFields::as_string () const +{ + std::string str = StructExprStruct::as_string (); + + str += "\n Fields: "; + if (fields.empty ()) + { + str += "none"; + } + else + { + for (const auto &field : fields) + { + str += "\n " + field->as_string (); + } + } + + str += "\n Struct base: "; + if (!has_struct_base ()) + { + str += "none"; + } + else + { + str += struct_base->as_string (); + } + + return str; +} + +std::string +EnumItem::as_string () const +{ + std::string str = Item::as_string (); + str += variant_name; + str += " "; + switch (get_enum_item_kind ()) + { + case Named: + str += "[Named variant]"; + break; + case Tuple: + str += "[Tuple variant]"; + break; + case Struct: + str += "[Struct variant]"; + break; + case Discriminant: + str += "[Discriminant variant]"; + break; + } + + return str; +} + +std::string +EnumItemTuple::as_string () const +{ + std::string str = EnumItem::as_string (); + + // add tuple opening parens + str += "("; + + // tuple fields + if (has_tuple_fields ()) + { + auto i = tuple_fields.begin (); + auto e = tuple_fields.end (); + + for (; i != e; i++) + { + str += (*i).as_string (); + if (e != i + 1) + str += ", "; + } + } + + // add tuple closing parens + str += ")"; + + return str; +} + +std::string +TupleField::as_string () const +{ + // outer attributes + std::string str = "outer attributes: "; + if (outer_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "outer attribute" syntax - + * just the body */ + for (const auto &attr : outer_attrs) + { + str += "\n " + attr.as_string (); + } + } + + if (has_visibility ()) + { + str += "\n" + visibility.as_string (); + } + + str += " " + field_type->as_string (); + + return str; +} + +std::string +EnumItemStruct::as_string () const +{ + std::string str = EnumItem::as_string (); + + // add struct opening parens + str += "{"; + + // tuple fields + if (has_struct_fields ()) + { + auto i = struct_fields.begin (); + auto e = struct_fields.end (); + + for (; i != e; i++) + { + str += (*i).as_string (); + if (e != i + 1) + str += ", "; + } + } + + // add struct closing parens + str += "}"; + + return str; +} + +std::string +StructField::as_string () const +{ + // outer attributes + std::string str = "outer attributes: "; + if (outer_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "outer attribute" syntax - + * just the body */ + for (const auto &attr : outer_attrs) + { + str += "\n " + attr.as_string (); + } + } + + if (has_visibility ()) + { + str += "\n" + visibility.as_string (); + } + + str += " " + field_name + " : " + field_type->as_string (); + + return str; +} + +std::string +EnumItemDiscriminant::as_string () const +{ + std::string str = EnumItem::as_string (); + + // add equal and expression + str += " = " + expression->as_string (); + + return str; +} + +std::string +ExternalItem::as_string () const +{ + // outer attributes + std::string str = "outer attributes: "; + if (outer_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "outer attribute" syntax - + * just the body */ + for (const auto &attr : outer_attrs) + { + str += "\n " + attr.as_string (); + } + } + + // start visibility on new line and with a space + str += "\n" + visibility.as_string () + " "; + + return str; +} + +std::string +ExternalStaticItem::as_string () const +{ + std::string str = ExternalItem::as_string (); + + str += "static "; + + if (is_mut ()) + { + str += "mut "; + } + + // add name + str += get_item_name (); + + // add type on new line + str += "\n Type: " + item_type->as_string (); + + return str; +} + +std::string +ExternalFunctionItem::as_string () const +{ + std::string str = ExternalItem::as_string (); + + str += "fn "; + + // add name + str += get_item_name (); + + // generic params + str += "\n Generic params: "; + if (generic_params.empty ()) + { + str += "none"; + } + else + { + for (const auto ¶m : generic_params) + { + // DEBUG: null pointer check + if (param == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer " + "generic param in external function item."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + param->as_string (); + } + } + + // function params + str += "\n Function params: "; + if (function_params.empty ()) + { + str += "none"; + } + else + { + for (const auto ¶m : function_params) + { + str += "\n " + param.as_string (); + } + if (has_variadics) + { + str += "\n .. (variadic)"; + } + } + + // add type on new line) + str += "\n (return) Type: " + + (has_return_type () ? return_type->as_string () : "()"); + + // where clause + str += "\n Where clause: "; + if (has_where_clause ()) + { + str += where_clause.as_string (); + } + else + { + str += "none"; + } + + return str; +} + +std::string +NamedFunctionParam::as_string () const +{ + std::string str = name; + + str += "\n Type: " + param_type->as_string (); + + return str; +} + +/*std::string TraitItem::as_string() const { + // outer attributes + std::string str = "outer attributes: "; + if (outer_attrs.empty()) { + str += "none"; + } else { + // note that this does not print them with "outer attribute" syntax - +just the body for (const auto& attr : outer_attrs) { str += "\n " + +attr.as_string(); + } + } + + return str; +}*/ + +std::string +TraitItemFunc::as_string () const +{ + std::string str = "outer attributes: "; + if (outer_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "outer attribute" syntax - + * just the body */ + for (const auto &attr : outer_attrs) + { + str += "\n " + attr.as_string (); + } + } + + str += "\n" + decl.as_string (); + + str += "\n Definition (block expr): "; + if (has_definition ()) + { + str += block_expr->as_string (); + } + else + { + str += "none"; + } + + return str; +} + +std::string +TraitFunctionDecl::as_string () const +{ + std::string str = qualifiers.as_string () + "fn " + function_name; + + // generic params + str += "\n Generic params: "; + if (generic_params.empty ()) + { + str += "none"; + } + else + { + for (const auto ¶m : generic_params) + { + // DEBUG: null pointer check + if (param == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer " + "generic param in trait function decl."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + param->as_string (); + } + } + + str += "\n Function params: "; + if (is_method ()) + { + str += self.as_string () + (has_params () ? ", " : ""); + } + + if (has_params ()) + { + for (const auto ¶m : function_params) + { + str += "\n " + param.as_string (); + } + } + else if (!is_method ()) + { + str += "none"; + } + + str += "\n Return type: "; + if (has_return_type ()) + { + str += return_type->as_string (); + } + else + { + str += "none (void)"; + } + + str += "\n Where clause: "; + if (has_where_clause ()) + { + str += where_clause.as_string (); + } + else + { + str += "none"; + } + + return str; +} + +std::string +TraitItemConst::as_string () const +{ + std::string str = "outer attributes: "; + if (outer_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "outer attribute" syntax - + * just the body */ + for (const auto &attr : outer_attrs) + { + str += "\n " + attr.as_string (); + } + } + + str += "\nconst " + name + " : " + type->as_string (); + + if (has_expression ()) + { + str += " = " + expr->as_string (); + } + + return str; +} + +std::string +TraitItemType::as_string () const +{ + std::string str = "outer attributes: "; + if (outer_attrs.empty ()) + { + str += "none"; + } + else + { + /* note that this does not print them with "outer attribute" syntax - + * just the body */ + for (const auto &attr : outer_attrs) + { + str += "\n " + attr.as_string (); + } + } + + str += "\ntype " + name; + + str += "\n Type param bounds: "; + if (!has_type_param_bounds ()) + { + str += "none"; + } + else + { + for (const auto &bound : type_param_bounds) + { + // DEBUG: null pointer check + if (bound == nullptr) + { + rust_debug ( + "something really terrible has gone wrong - null pointer " + "type param bound in trait item type."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + bound->as_string (); + } + } + + return str; +} + +std::string +SelfParam::as_string () const +{ + if (is_error ()) + { + return "error"; + } + else + { + if (has_type ()) + { + // type (i.e. not ref, no lifetime) + std::string str; + + if (is_mut ()) + { + str += "mut "; + } + + str += "self : "; + + str += type->as_string (); + + return str; + } + else if (has_lifetime ()) + { + // ref and lifetime + std::string str = "&" + lifetime.as_string () + " "; + + if (is_mut ()) + { + str += "mut "; + } + + str += "self"; + + return str; + } + else if (is_ref ()) + { + // ref with no lifetime + std::string str = "&"; + + if (is_mut ()) + { + str += " mut "; + } + + str += "self"; + + return str; + } + else + { + // no ref, no type + std::string str; + + if (is_mut ()) + { + str += "mut "; + } + + str += "self"; + + return str; + } + } +} + +std::string +ArrayElemsCopied::as_string () const +{ + return elem_to_copy->as_string () + "; " + num_copies->as_string (); +} + +std::string +LifetimeWhereClauseItem::as_string () const +{ + std::string str ("Lifetime: "); + + str += lifetime.as_string (); + + str += "\nLifetime bounds: "; + + for (const auto &bound : lifetime_bounds) + { + str += "\n " + bound.as_string (); + } + + return str; +} + +std::string +TypeBoundWhereClauseItem::as_string () const +{ + std::string str ("For lifetimes: "); + + if (!has_for_lifetimes ()) + { + str += "none"; + } + else + { + for (const auto &for_lifetime : for_lifetimes) + { + str += "\n " + for_lifetime.as_string (); + } + } + + str += "\nType: " + bound_type->as_string (); + + str += "\nType param bounds bounds: "; + + for (const auto &bound : type_param_bounds) + { + // debug null pointer check + if (bound == nullptr) + { + return "nullptr_POINTER_MARK - type param bounds"; + } + + str += "\n " + bound->as_string (); + } + + return str; +} + +std::string +ArrayElemsValues::as_string () const +{ + std::string str; + + for (const auto &expr : values) + { + // DEBUG: null pointer check + if (expr == nullptr) + { + rust_debug ("something really terrible has gone wrong - null pointer " + "expr in array elems values."); + return "nullptr_POINTER_MARK"; + } + + str += "\n " + expr->as_string (); + } + + return str; +} + +std::string +MaybeNamedParam::as_string () const +{ + std::string str; + + switch (param_kind) + { + case UNNAMED: + break; + case IDENTIFIER: + str = name + " : "; + break; + case WILDCARD: + str = "_ : "; + break; + default: + return "ERROR_MARK_STRING - maybe named param unrecognised param kind"; + } + + str += param_type->as_string (); + + return str; +} + +/* Override that calls the function recursively on all items contained within + * the module. */ +void +Module::add_crate_name (std::vector &names) const +{ + /* TODO: test whether module has been 'cfg'-ed out to determine whether to + * exclude it from search */ + + for (const auto &item : items) + item->add_crate_name (names); +} + +/* All accept_vis method below */ + +void +Lifetime::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +LifetimeParam::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +PathInExpression::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} +void +PathInExpression::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +TypePathSegment::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TypePathSegmentGeneric::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TypePathSegmentFunction::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TypePath::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +QualifiedPathInExpression::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} +void +QualifiedPathInExpression::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +QualifiedPathInType::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +LiteralExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +LiteralExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +BorrowExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +BorrowExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +DereferenceExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +DereferenceExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ErrorPropagationExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ErrorPropagationExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +NegationExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +NegationExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ArithmeticOrLogicalExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ArithmeticOrLogicalExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ComparisonExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ComparisonExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +LazyBooleanExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +LazyBooleanExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +TypeCastExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TypeCastExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +AssignmentExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +AssignmentExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +CompoundAssignmentExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +CompoundAssignmentExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +GroupedExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +GroupedExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ArrayElemsValues::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ArrayElemsCopied::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ArrayExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ArrayIndexExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleIndexExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprStruct::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprFieldIndexValue::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprStructFields::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprStructBase::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +CallExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +MethodCallExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +FieldAccessExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ClosureExprInner::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +BlockExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ClosureExprInnerTyped::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ContinueExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +BreakExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeFromToExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeFromExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeToExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeFullExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeFromToInclExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeToInclExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ReturnExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +UnsafeBlockExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +LoopExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +WhileLoopExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +WhileLetLoopExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ForLoopExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +IfExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +IfExprConseqElse::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +IfExprConseqIf::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +IfExprConseqIfLet::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +IfLetExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +IfLetExprConseqElse::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +IfLetExprConseqIf::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +IfLetExprConseqIfLet::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +MatchExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +AwaitExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +AsyncBlockExpr::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TypeParam::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +LifetimeWhereClauseItem::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TypeBoundWhereClauseItem::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +Module::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +Module::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +Module::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternCrate::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +UseTreeGlob::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +UseTreeList::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +UseTreeRebind::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +UseDeclaration::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +Function::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TypeAlias::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StructStruct::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleStruct::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +EnumItem::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +EnumItemTuple::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +EnumItemStruct::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +EnumItemDiscriminant::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +Enum::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +Union::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ConstantItem::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StaticItem::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TraitItemFunc::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TraitItemConst::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TraitItemType::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +Trait::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ImplBlock::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternalStaticItem::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternalFunctionItem::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternBlock::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +LiteralPattern::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +IdentifierPattern::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +WildcardPattern::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +RangePatternBoundLiteral::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +RangePatternBoundPath::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +RangePatternBoundQualPath::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +RangePattern::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ReferencePattern::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StructPatternFieldTuplePat::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StructPatternFieldIdentPat::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StructPatternFieldIdent::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StructPattern::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleStructItemsNoRange::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleStructItemsRange::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleStructPattern::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TuplePatternItemsMultiple::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TuplePatternItemsRanged::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TuplePattern::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +GroupedPattern::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +SlicePattern::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +EmptyStmt::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +LetStmt::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ExprStmtWithoutBlock::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ExprStmtWithBlock::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TraitBound::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ImplTraitType::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TraitObjectType::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ParenthesisedType::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ImplTraitTypeOneBound::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleType::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +NeverType::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +RawPointerType::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ReferenceType::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +ArrayType::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +SliceType::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +InferredType::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +BareFunctionType::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +NeverType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +ParenthesisedType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +EmptyStmt::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +GroupedPattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +WildcardPattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +TraitItemType::accept_vis (HIRTraitItemVisitor &vis) +{ + vis.visit (*this); +} + +void +TraitItemConst::accept_vis (HIRTraitItemVisitor &vis) +{ + vis.visit (*this); +} + +void +TraitItemFunc::accept_vis (HIRTraitItemVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternalFunctionItem::accept_vis (HIRExternalItemVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternalStaticItem::accept_vis (HIRExternalItemVisitor &vis) +{ + vis.visit (*this); +} + +void +EnumItemDiscriminant::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +EnumItemStruct::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +EnumItemTuple::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +EnumItem::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprStructFields::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprFieldIndexValue::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprFieldIdentifierValue::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprFieldIdentifierValue::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprFieldIdentifier::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprFieldIdentifier::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +StructExprStruct::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +SliceType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +ArrayType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +ImplTraitTypeOneBound::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +BareFunctionType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +TraitObjectType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +RawPointerType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +ReferenceType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +ImplTraitType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +InferredType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +LetStmt::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleStructPattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +IdentifierPattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +ReferencePattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +LiteralPattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +StructPattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +TuplePattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +SlicePattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +RangePattern::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +ForLoopExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +TypePath::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +QualifiedPathInType::accept_vis (HIRTypeVisitor &vis) +{ + vis.visit (*this); +} + +void +ExprStmtWithoutBlock::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +MatchExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +BreakExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +AwaitExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ArrayExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +LoopExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +WhileLetLoopExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +WhileLoopExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +CallExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeFromToInclExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfLetExprConseqIfLet::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfLetExprConseqIf::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfLetExprConseqElse::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfLetExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfExprConseqIfLet::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfExprConseqIf::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfExprConseqElse::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +IfExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ClosureExprInner::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +UnsafeBlockExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeToInclExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeFromToExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +FieldAccessExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleIndexExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +MethodCallExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +AsyncBlockExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ArrayIndexExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeFullExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeFromExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ContinueExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +RangeToExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ReturnExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +QualifiedPathInExpression::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +ClosureExprInnerTyped::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +ExprStmtWithBlock::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +PathInExpression::accept_vis (HIRPatternVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternBlock::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternBlock::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +TypeAlias::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +TypeAlias::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +TypeAlias::accept_vis (HIRImplVisitor &vis) +{ + vis.visit (*this); +} + +void +BlockExpr::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +Function::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +Function::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +Function::accept_vis (HIRImplVisitor &vis) +{ + vis.visit (*this); +} + +void +Union::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +Union::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +Trait::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +Trait::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +Enum::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +Enum::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +UseDeclaration::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +UseDeclaration::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +StructStruct::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +StructStruct::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +ImplBlock::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +ImplBlock::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +ConstantItem::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +ConstantItem::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +ConstantItem::accept_vis (HIRImplVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleStruct::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +TupleStruct::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternCrate::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +ExternCrate::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +void +StaticItem::accept_vis (HIRStmtVisitor &vis) +{ + vis.visit (*this); +} + +void +StaticItem::accept_vis (HIRVisItemVisitor &vis) +{ + vis.visit (*this); +} + +std::string +ConstGenericParam::as_string () const +{ + auto result = "ConstGenericParam: " + name + " : " + type->as_string (); + + if (default_expression) + result += " = " + default_expression->as_string (); + + return result; +} + +void +ConstGenericParam::accept_vis (HIRFullVisitor &vis) +{} + +} // namespace HIR +} // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-full.h b/gcc/rust/hir/tree/rust-hir-full.h new file mode 100644 index 00000000000..646b793654e --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-full.h @@ -0,0 +1,30 @@ +// 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 +// . + +#ifndef RUST_HIR_FULL_H +#define RUST_HIR_FULL_H + +#include "rust-hir.h" +#include "rust-hir-expr.h" +#include "rust-hir-item.h" +#include "rust-hir-path.h" +#include "rust-hir-pattern.h" +#include "rust-hir-stmt.h" +#include "rust-hir-type.h" + +#endif // RUST_HIR_FULL_H diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h new file mode 100644 index 00000000000..b3c0b9359cc --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir-visitor.h @@ -0,0 +1,493 @@ +// 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 +// . + +#ifndef RUST_HIR_VISITOR_H +#define RUST_HIR_VISITOR_H + +#include "rust-hir-full-decls.h" + +namespace Rust { +namespace HIR { + +class HIRFullVisitor +{ +public: + virtual void visit (Lifetime &lifetime) = 0; + virtual void visit (LifetimeParam &lifetime_param) = 0; + virtual void visit (PathInExpression &path) = 0; + virtual void visit (TypePathSegment &segment) = 0; + virtual void visit (TypePathSegmentGeneric &segment) = 0; + virtual void visit (TypePathSegmentFunction &segment) = 0; + virtual void visit (TypePath &path) = 0; + virtual void visit (QualifiedPathInExpression &path) = 0; + virtual void visit (QualifiedPathInType &path) = 0; + virtual void visit (LiteralExpr &expr) = 0; + virtual void visit (BorrowExpr &expr) = 0; + virtual void visit (DereferenceExpr &expr) = 0; + virtual void visit (ErrorPropagationExpr &expr) = 0; + virtual void visit (NegationExpr &expr) = 0; + virtual void visit (ArithmeticOrLogicalExpr &expr) = 0; + virtual void visit (ComparisonExpr &expr) = 0; + virtual void visit (LazyBooleanExpr &expr) = 0; + virtual void visit (TypeCastExpr &expr) = 0; + virtual void visit (AssignmentExpr &expr) = 0; + virtual void visit (CompoundAssignmentExpr &expr) = 0; + virtual void visit (GroupedExpr &expr) = 0; + virtual void visit (ArrayElemsValues &elems) = 0; + virtual void visit (ArrayElemsCopied &elems) = 0; + virtual void visit (ArrayExpr &expr) = 0; + virtual void visit (ArrayIndexExpr &expr) = 0; + virtual void visit (TupleExpr &expr) = 0; + virtual void visit (TupleIndexExpr &expr) = 0; + virtual void visit (StructExprStruct &expr) = 0; + virtual void visit (StructExprFieldIdentifier &field) = 0; + virtual void visit (StructExprFieldIdentifierValue &field) = 0; + virtual void visit (StructExprFieldIndexValue &field) = 0; + virtual void visit (StructExprStructFields &expr) = 0; + virtual void visit (StructExprStructBase &expr) = 0; + virtual void visit (CallExpr &expr) = 0; + virtual void visit (MethodCallExpr &expr) = 0; + virtual void visit (FieldAccessExpr &expr) = 0; + virtual void visit (ClosureExprInner &expr) = 0; + virtual void visit (BlockExpr &expr) = 0; + virtual void visit (ClosureExprInnerTyped &expr) = 0; + virtual void visit (ContinueExpr &expr) = 0; + virtual void visit (BreakExpr &expr) = 0; + virtual void visit (RangeFromToExpr &expr) = 0; + virtual void visit (RangeFromExpr &expr) = 0; + virtual void visit (RangeToExpr &expr) = 0; + virtual void visit (RangeFullExpr &expr) = 0; + virtual void visit (RangeFromToInclExpr &expr) = 0; + virtual void visit (RangeToInclExpr &expr) = 0; + virtual void visit (ReturnExpr &expr) = 0; + virtual void visit (UnsafeBlockExpr &expr) = 0; + virtual void visit (LoopExpr &expr) = 0; + virtual void visit (WhileLoopExpr &expr) = 0; + virtual void visit (WhileLetLoopExpr &expr) = 0; + virtual void visit (ForLoopExpr &expr) = 0; + virtual void visit (IfExpr &expr) = 0; + virtual void visit (IfExprConseqElse &expr) = 0; + virtual void visit (IfExprConseqIf &expr) = 0; + virtual void visit (IfExprConseqIfLet &expr) = 0; + virtual void visit (IfLetExpr &expr) = 0; + virtual void visit (IfLetExprConseqElse &expr) = 0; + virtual void visit (IfLetExprConseqIf &expr) = 0; + virtual void visit (IfLetExprConseqIfLet &expr) = 0; + virtual void visit (MatchExpr &expr) = 0; + virtual void visit (AwaitExpr &expr) = 0; + virtual void visit (AsyncBlockExpr &expr) = 0; + virtual void visit (TypeParam ¶m) = 0; + virtual void visit (ConstGenericParam ¶m) = 0; + virtual void visit (LifetimeWhereClauseItem &item) = 0; + virtual void visit (TypeBoundWhereClauseItem &item) = 0; + virtual void visit (Module &module) = 0; + virtual void visit (ExternCrate &crate) = 0; + virtual void visit (UseTreeGlob &use_tree) = 0; + virtual void visit (UseTreeList &use_tree) = 0; + virtual void visit (UseTreeRebind &use_tree) = 0; + virtual void visit (UseDeclaration &use_decl) = 0; + virtual void visit (Function &function) = 0; + virtual void visit (TypeAlias &type_alias) = 0; + virtual void visit (StructStruct &struct_item) = 0; + virtual void visit (TupleStruct &tuple_struct) = 0; + virtual void visit (EnumItem &item) = 0; + virtual void visit (EnumItemTuple &item) = 0; + virtual void visit (EnumItemStruct &item) = 0; + virtual void visit (EnumItemDiscriminant &item) = 0; + virtual void visit (Enum &enum_item) = 0; + virtual void visit (Union &union_item) = 0; + virtual void visit (ConstantItem &const_item) = 0; + virtual void visit (StaticItem &static_item) = 0; + virtual void visit (TraitItemFunc &item) = 0; + virtual void visit (TraitItemConst &item) = 0; + virtual void visit (TraitItemType &item) = 0; + virtual void visit (Trait &trait) = 0; + virtual void visit (ImplBlock &impl) = 0; + virtual void visit (ExternalStaticItem &item) = 0; + virtual void visit (ExternalFunctionItem &item) = 0; + virtual void visit (ExternBlock &block) = 0; + virtual void visit (LiteralPattern &pattern) = 0; + virtual void visit (IdentifierPattern &pattern) = 0; + virtual void visit (WildcardPattern &pattern) = 0; + virtual void visit (RangePatternBoundLiteral &bound) = 0; + virtual void visit (RangePatternBoundPath &bound) = 0; + virtual void visit (RangePatternBoundQualPath &bound) = 0; + virtual void visit (RangePattern &pattern) = 0; + virtual void visit (ReferencePattern &pattern) = 0; + virtual void visit (StructPatternFieldTuplePat &field) = 0; + virtual void visit (StructPatternFieldIdentPat &field) = 0; + virtual void visit (StructPatternFieldIdent &field) = 0; + virtual void visit (StructPattern &pattern) = 0; + virtual void visit (TupleStructItemsNoRange &tuple_items) = 0; + virtual void visit (TupleStructItemsRange &tuple_items) = 0; + virtual void visit (TupleStructPattern &pattern) = 0; + virtual void visit (TuplePatternItemsMultiple &tuple_items) = 0; + virtual void visit (TuplePatternItemsRanged &tuple_items) = 0; + virtual void visit (TuplePattern &pattern) = 0; + virtual void visit (GroupedPattern &pattern) = 0; + virtual void visit (SlicePattern &pattern) = 0; + virtual void visit (EmptyStmt &stmt) = 0; + virtual void visit (LetStmt &stmt) = 0; + virtual void visit (ExprStmtWithoutBlock &stmt) = 0; + virtual void visit (ExprStmtWithBlock &stmt) = 0; + virtual void visit (TraitBound &bound) = 0; + virtual void visit (ImplTraitType &type) = 0; + virtual void visit (TraitObjectType &type) = 0; + virtual void visit (ParenthesisedType &type) = 0; + virtual void visit (ImplTraitTypeOneBound &type) = 0; + virtual void visit (TupleType &type) = 0; + virtual void visit (NeverType &type) = 0; + virtual void visit (RawPointerType &type) = 0; + virtual void visit (ReferenceType &type) = 0; + virtual void visit (ArrayType &type) = 0; + virtual void visit (SliceType &type) = 0; + virtual void visit (InferredType &type) = 0; + virtual void visit (BareFunctionType &type) = 0; +}; + +class HIRFullVisitorBase : public HIRFullVisitor +{ +public: + virtual ~HIRFullVisitorBase () {} + + virtual void visit (Lifetime &) override {} + virtual void visit (LifetimeParam &) override {} + virtual void visit (PathInExpression &) override {} + virtual void visit (TypePathSegment &) override {} + virtual void visit (TypePathSegmentGeneric &) override {} + virtual void visit (TypePathSegmentFunction &) override {} + virtual void visit (TypePath &) override {} + virtual void visit (QualifiedPathInExpression &) override {} + virtual void visit (QualifiedPathInType &) override {} + + virtual void visit (LiteralExpr &) override {} + virtual void visit (BorrowExpr &) override {} + virtual void visit (DereferenceExpr &) override {} + virtual void visit (ErrorPropagationExpr &) override {} + virtual void visit (NegationExpr &) override {} + virtual void visit (ArithmeticOrLogicalExpr &) override {} + virtual void visit (ComparisonExpr &) override {} + virtual void visit (LazyBooleanExpr &) override {} + virtual void visit (TypeCastExpr &) override {} + virtual void visit (AssignmentExpr &) override {} + virtual void visit (CompoundAssignmentExpr &) override {} + virtual void visit (GroupedExpr &) override {} + + virtual void visit (ArrayElemsValues &) override {} + virtual void visit (ArrayElemsCopied &) override {} + virtual void visit (ArrayExpr &) override {} + virtual void visit (ArrayIndexExpr &) override {} + virtual void visit (TupleExpr &) override {} + virtual void visit (TupleIndexExpr &) override {} + virtual void visit (StructExprStruct &) override {} + + virtual void visit (StructExprFieldIdentifier &) override {} + virtual void visit (StructExprFieldIdentifierValue &) override {} + + virtual void visit (StructExprFieldIndexValue &) override {} + virtual void visit (StructExprStructFields &) override {} + virtual void visit (StructExprStructBase &) override {} + + virtual void visit (CallExpr &) override {} + virtual void visit (MethodCallExpr &) override {} + virtual void visit (FieldAccessExpr &) override {} + virtual void visit (ClosureExprInner &) override {} + virtual void visit (BlockExpr &) override {} + virtual void visit (ClosureExprInnerTyped &) override {} + virtual void visit (ContinueExpr &) override {} + virtual void visit (BreakExpr &) override {} + virtual void visit (RangeFromToExpr &) override {} + virtual void visit (RangeFromExpr &) override {} + virtual void visit (RangeToExpr &) override {} + virtual void visit (RangeFullExpr &) override {} + virtual void visit (RangeFromToInclExpr &) override {} + virtual void visit (RangeToInclExpr &) override {} + virtual void visit (ReturnExpr &) override {} + virtual void visit (UnsafeBlockExpr &) override {} + virtual void visit (LoopExpr &) override {} + virtual void visit (WhileLoopExpr &) override {} + virtual void visit (WhileLetLoopExpr &) override {} + virtual void visit (ForLoopExpr &) override {} + virtual void visit (IfExpr &) override {} + virtual void visit (IfExprConseqElse &) override {} + virtual void visit (IfExprConseqIf &) override {} + virtual void visit (IfExprConseqIfLet &) override {} + virtual void visit (IfLetExpr &) override {} + virtual void visit (IfLetExprConseqElse &) override {} + virtual void visit (IfLetExprConseqIf &) override {} + virtual void visit (IfLetExprConseqIfLet &) override {} + + virtual void visit (MatchExpr &) override {} + virtual void visit (AwaitExpr &) override {} + virtual void visit (AsyncBlockExpr &) override {} + + virtual void visit (TypeParam &) override {} + virtual void visit (ConstGenericParam &) override {} + + virtual void visit (LifetimeWhereClauseItem &) override {} + virtual void visit (TypeBoundWhereClauseItem &) override {} + virtual void visit (Module &) override {} + virtual void visit (ExternCrate &) override {} + + virtual void visit (UseTreeGlob &) override {} + virtual void visit (UseTreeList &) override {} + virtual void visit (UseTreeRebind &) override {} + virtual void visit (UseDeclaration &) override {} + virtual void visit (Function &) override {} + virtual void visit (TypeAlias &) override {} + virtual void visit (StructStruct &) override {} + virtual void visit (TupleStruct &) override {} + virtual void visit (EnumItem &) override {} + virtual void visit (EnumItemTuple &) override {} + virtual void visit (EnumItemStruct &) override {} + virtual void visit (EnumItemDiscriminant &) override {} + virtual void visit (Enum &) override {} + virtual void visit (Union &) override {} + virtual void visit (ConstantItem &) override {} + virtual void visit (StaticItem &) override {} + virtual void visit (TraitItemFunc &) override {} + virtual void visit (TraitItemConst &) override {} + virtual void visit (TraitItemType &) override {} + virtual void visit (Trait &) override {} + virtual void visit (ImplBlock &) override {} + + virtual void visit (ExternalStaticItem &) override {} + virtual void visit (ExternalFunctionItem &) override {} + virtual void visit (ExternBlock &) override {} + + virtual void visit (LiteralPattern &) override {} + virtual void visit (IdentifierPattern &) override {} + virtual void visit (WildcardPattern &) override {} + + virtual void visit (RangePatternBoundLiteral &) override {} + virtual void visit (RangePatternBoundPath &) override {} + virtual void visit (RangePatternBoundQualPath &) override {} + virtual void visit (RangePattern &) override {} + virtual void visit (ReferencePattern &) override {} + + virtual void visit (StructPatternFieldTuplePat &) override {} + virtual void visit (StructPatternFieldIdentPat &) override {} + virtual void visit (StructPatternFieldIdent &) override {} + virtual void visit (StructPattern &) override {} + + virtual void visit (TupleStructItemsNoRange &) override {} + virtual void visit (TupleStructItemsRange &) override {} + virtual void visit (TupleStructPattern &) override {} + + virtual void visit (TuplePatternItemsMultiple &) override {} + virtual void visit (TuplePatternItemsRanged &) override {} + virtual void visit (TuplePattern &) override {} + virtual void visit (GroupedPattern &) override {} + virtual void visit (SlicePattern &) override {} + + virtual void visit (EmptyStmt &) override {} + virtual void visit (LetStmt &) override {} + virtual void visit (ExprStmtWithoutBlock &) override {} + virtual void visit (ExprStmtWithBlock &) override {} + + virtual void visit (TraitBound &) override {} + virtual void visit (ImplTraitType &) override {} + virtual void visit (TraitObjectType &) override {} + virtual void visit (ParenthesisedType &) override {} + virtual void visit (ImplTraitTypeOneBound &) override {} + virtual void visit (TupleType &) override {} + virtual void visit (NeverType &) override {} + virtual void visit (RawPointerType &) override {} + virtual void visit (ReferenceType &) override {} + virtual void visit (ArrayType &) override {} + virtual void visit (SliceType &) override {} + virtual void visit (InferredType &) override {} + virtual void visit (BareFunctionType &) override {} +}; + +class HIRExternalItemVisitor +{ +public: + virtual void visit (ExternalStaticItem &item) = 0; + virtual void visit (ExternalFunctionItem &item) = 0; +}; + +class HIRTraitItemVisitor +{ +public: + virtual void visit (TraitItemFunc &item) = 0; + virtual void visit (TraitItemConst &item) = 0; + virtual void visit (TraitItemType &item) = 0; +}; + +class HIRVisItemVisitor +{ +public: + virtual void visit (Module &module) = 0; + virtual void visit (ExternCrate &crate) = 0; + virtual void visit (UseDeclaration &use_decl) = 0; + virtual void visit (Function &function) = 0; + virtual void visit (TypeAlias &type_alias) = 0; + virtual void visit (StructStruct &struct_item) = 0; + virtual void visit (TupleStruct &tuple_struct) = 0; + virtual void visit (Enum &enum_item) = 0; + virtual void visit (Union &union_item) = 0; + virtual void visit (ConstantItem &const_item) = 0; + virtual void visit (StaticItem &static_item) = 0; + virtual void visit (Trait &trait) = 0; + virtual void visit (ImplBlock &impl) = 0; + virtual void visit (ExternBlock &block) = 0; +}; + +class HIRImplVisitor +{ +public: + virtual void visit (Function &function) = 0; + virtual void visit (ConstantItem &const_item) = 0; + virtual void visit (TypeAlias &type_alias) = 0; +}; + +class HIRTypeVisitor +{ +public: + virtual void visit (TypePathSegmentFunction &segment) = 0; + virtual void visit (TypePath &path) = 0; + virtual void visit (QualifiedPathInType &path) = 0; + virtual void visit (TraitBound &bound) = 0; + virtual void visit (ImplTraitType &type) = 0; + virtual void visit (TraitObjectType &type) = 0; + virtual void visit (ParenthesisedType &type) = 0; + virtual void visit (ImplTraitTypeOneBound &type) = 0; + virtual void visit (TupleType &type) = 0; + virtual void visit (NeverType &type) = 0; + virtual void visit (RawPointerType &type) = 0; + virtual void visit (ReferenceType &type) = 0; + virtual void visit (ArrayType &type) = 0; + virtual void visit (SliceType &type) = 0; + virtual void visit (InferredType &type) = 0; + virtual void visit (BareFunctionType &type) = 0; +}; + +class HIRStmtVisitor +{ +public: + virtual void visit (EnumItemTuple &) = 0; + virtual void visit (EnumItemStruct &) = 0; + virtual void visit (EnumItem &item) = 0; + virtual void visit (TupleStruct &tuple_struct) = 0; + virtual void visit (EnumItemDiscriminant &) = 0; + virtual void visit (TypePathSegmentFunction &segment) = 0; + virtual void visit (TypePath &path) = 0; + virtual void visit (QualifiedPathInType &path) = 0; + virtual void visit (Module &module) = 0; + virtual void visit (ExternCrate &crate) = 0; + virtual void visit (UseDeclaration &use_decl) = 0; + virtual void visit (Function &function) = 0; + virtual void visit (TypeAlias &type_alias) = 0; + virtual void visit (StructStruct &struct_item) = 0; + virtual void visit (Enum &enum_item) = 0; + virtual void visit (Union &union_item) = 0; + virtual void visit (ConstantItem &const_item) = 0; + virtual void visit (StaticItem &static_item) = 0; + virtual void visit (Trait &trait) = 0; + virtual void visit (ImplBlock &impl) = 0; + virtual void visit (ExternBlock &block) = 0; + virtual void visit (EmptyStmt &stmt) = 0; + virtual void visit (LetStmt &stmt) = 0; + virtual void visit (ExprStmtWithoutBlock &stmt) = 0; + virtual void visit (ExprStmtWithBlock &stmt) = 0; +}; + +class HIRExpressionVisitor +{ +public: + // These are StructExprField + // Added because of CompileStructExprField + virtual void visit (StructExprFieldIdentifier &field) = 0; + virtual void visit (StructExprFieldIdentifierValue &field) = 0; + virtual void visit (StructExprFieldIndexValue &field) = 0; + + virtual void visit (HIR::QualifiedPathInExpression &expr) = 0; + virtual void visit (HIR::PathInExpression &expr) = 0; + virtual void visit (ClosureExprInnerTyped &) = 0; + virtual void visit (ClosureExprInner &expr) = 0; + virtual void visit (StructExprStructFields &) = 0; + virtual void visit (StructExprStruct &) = 0; + virtual void visit (LiteralExpr &expr) = 0; + virtual void visit (BorrowExpr &expr) = 0; + virtual void visit (DereferenceExpr &expr) = 0; + virtual void visit (ErrorPropagationExpr &expr) = 0; + virtual void visit (NegationExpr &expr) = 0; + virtual void visit (ArithmeticOrLogicalExpr &expr) = 0; + virtual void visit (ComparisonExpr &expr) = 0; + virtual void visit (LazyBooleanExpr &expr) = 0; + virtual void visit (TypeCastExpr &expr) = 0; + virtual void visit (AssignmentExpr &expr) = 0; + virtual void visit (CompoundAssignmentExpr &expr) = 0; + virtual void visit (GroupedExpr &expr) = 0; + virtual void visit (ArrayExpr &expr) = 0; + virtual void visit (ArrayIndexExpr &expr) = 0; + virtual void visit (TupleExpr &expr) = 0; + virtual void visit (TupleIndexExpr &expr) = 0; + virtual void visit (CallExpr &expr) = 0; + virtual void visit (MethodCallExpr &expr) = 0; + virtual void visit (FieldAccessExpr &expr) = 0; + virtual void visit (BlockExpr &expr) = 0; + virtual void visit (ContinueExpr &expr) = 0; + virtual void visit (BreakExpr &expr) = 0; + virtual void visit (RangeFromToExpr &expr) = 0; + virtual void visit (RangeFromExpr &expr) = 0; + virtual void visit (RangeToExpr &expr) = 0; + virtual void visit (RangeFullExpr &expr) = 0; + virtual void visit (RangeFromToInclExpr &expr) = 0; + virtual void visit (RangeToInclExpr &expr) = 0; + virtual void visit (ReturnExpr &expr) = 0; + virtual void visit (UnsafeBlockExpr &expr) = 0; + virtual void visit (LoopExpr &expr) = 0; + virtual void visit (WhileLoopExpr &expr) = 0; + virtual void visit (WhileLetLoopExpr &expr) = 0; + virtual void visit (ForLoopExpr &expr) = 0; + virtual void visit (IfExpr &expr) = 0; + virtual void visit (IfExprConseqElse &expr) = 0; + virtual void visit (IfExprConseqIf &expr) = 0; + virtual void visit (IfExprConseqIfLet &expr) = 0; + virtual void visit (IfLetExpr &expr) = 0; + virtual void visit (IfLetExprConseqElse &expr) = 0; + virtual void visit (IfLetExprConseqIf &expr) = 0; + virtual void visit (IfLetExprConseqIfLet &expr) = 0; + virtual void visit (MatchExpr &expr) = 0; + virtual void visit (AwaitExpr &expr) = 0; + virtual void visit (AsyncBlockExpr &expr) = 0; +}; + +class HIRPatternVisitor +{ +public: + virtual void visit (GroupedPattern &) = 0; + virtual void visit (IdentifierPattern &) = 0; + virtual void visit (LiteralPattern &) = 0; + virtual void visit (PathInExpression &) = 0; + virtual void visit (QualifiedPathInExpression &) = 0; + virtual void visit (RangePattern &) = 0; + virtual void visit (ReferencePattern &) = 0; + virtual void visit (SlicePattern &) = 0; + virtual void visit (StructPattern &) = 0; + virtual void visit (TuplePattern &) = 0; + virtual void visit (TupleStructPattern &) = 0; + virtual void visit (WildcardPattern &) = 0; +}; + +} // namespace HIR +} // namespace Rust + +#endif diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h new file mode 100644 index 00000000000..927ac06fc4a --- /dev/null +++ b/gcc/rust/hir/tree/rust-hir.h @@ -0,0 +1,921 @@ +// 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 +// . + +#ifndef RUST_HIR_BASE_H +#define RUST_HIR_BASE_H + +#include "rust-ast.h" +#include "rust-system.h" +#include "rust-token.h" +#include "rust-location.h" +#include "rust-hir-map.h" +#include "rust-diagnostics.h" + +namespace Rust { +typedef std::string Identifier; +typedef int TupleIndex; + +namespace HIR { +// foward decl: ast visitor +class HIRFullVisitor; +class HIRStmtVisitor; +class HIRTraitItemVisitor; +class HIRExternalItemVisitor; +class HIRVisItemVisitor; +class HIRExpressionVisitor; +class HIRPatternVisitor; +class HIRImplVisitor; +class HIRTypeVisitor; + +// forward decl for use in token tree method +class Token; + +class Node +{ +public: + // Kind for downcasting various HIR nodes to other base classes when visiting + // them + enum BaseKind + { + /* class ExternalItem */ + EXTERNAL, + /* class TraitItem */ + TRAIT_ITEM, + /* class VisItem */ + VIS_ITEM, + /* class Item */ + ITEM, + /* class ImplItem */ + IMPL, + /* class Type */ + TYPE, + /* class Stmt */ + STMT, + /* class Expr */ + EXPR, + /* class Pattern */ + PATTERN, + }; + + /** + * Get the kind of HIR node we are dealing with. This is useful for + * downcasting to more precise types when necessary, i.e going from an `Item*` + * to a `VisItem*` + */ + virtual BaseKind get_hir_kind () = 0; +}; + +// A literal - value with a type. Used in LiteralExpr and LiteralPattern. +struct Literal +{ +public: + enum LitType + { + CHAR, + STRING, + BYTE, + BYTE_STRING, + INT, + FLOAT, + BOOL + }; + +private: + std::string value_as_string; + LitType type; + PrimitiveCoreType type_hint; + +public: + std::string as_string () const { return value_as_string; } + + LitType get_lit_type () const { return type; } + + PrimitiveCoreType get_type_hint () const { return type_hint; } + + Literal (std::string value_as_string, LitType type, + PrimitiveCoreType type_hint) + : value_as_string (std::move (value_as_string)), type (type), + type_hint (type_hint) + {} + + static Literal create_error () + { + return Literal ("", CHAR, PrimitiveCoreType::CORETYPE_UNKNOWN); + } + + void set_lit_type (LitType lt) { type = lt; } + + // Returns whether literal is in an invalid state. + bool is_error () const { return value_as_string == ""; } + + bool is_equal (Literal &other) + { + return value_as_string == other.value_as_string && type == other.type + && type_hint == other.type_hint; + } +}; + +/* Base statement abstract class. Note that most "statements" are not allowed in + * top-level module scope - only a subclass of statements called "items" are. */ +class Stmt : public Node +{ +public: + // Unique pointer custom clone function + std::unique_ptr clone_stmt () const + { + return std::unique_ptr (clone_stmt_impl ()); + } + + BaseKind get_hir_kind () override { return STMT; } + + virtual ~Stmt () {} + + virtual std::string as_string () const = 0; + + virtual void accept_vis (HIRFullVisitor &vis) = 0; + virtual void accept_vis (HIRStmtVisitor &vis) = 0; + + virtual Location get_locus () const = 0; + + virtual bool is_unit_check_needed () const { return false; } + + const Analysis::NodeMapping &get_mappings () const { return mappings; } + + virtual bool is_item () const = 0; + +protected: + Stmt (Analysis::NodeMapping mappings) : mappings (std::move (mappings)) {} + + // Clone function implementation as pure virtual method + virtual Stmt *clone_stmt_impl () const = 0; + + Analysis::NodeMapping mappings; +}; + +// Rust "item" HIR node (declaration of top-level/module-level allowed stuff) +class Item : public Stmt +{ + AST::AttrVec outer_attrs; + + // TODO: should outer attrs be defined here or in each derived class? + +public: + enum class ItemKind + { + Static, + Constant, + TypeAlias, + Function, + UseDeclaration, + ExternBlock, + ExternCrate, + Struct, + Union, + Enum, + EnumItem, // FIXME: ARTHUR: Do we need that? + Trait, + Impl, + Module, + }; + + virtual ItemKind get_item_kind () const = 0; + + // Unique pointer custom clone function + std::unique_ptr clone_item () const + { + return std::unique_ptr (clone_item_impl ()); + } + + BaseKind get_hir_kind () override { return ITEM; } + + std::string as_string () const override; + + /* Adds crate names to the vector passed by reference, if it can + * (polymorphism). */ + virtual void + add_crate_name (std::vector &names ATTRIBUTE_UNUSED) const + {} + + AST::AttrVec &get_outer_attrs () { return outer_attrs; } + const AST::AttrVec &get_outer_attrs () const { return outer_attrs; } + + bool is_item () const override final { return true; } + +protected: + // Constructor + Item (Analysis::NodeMapping mappings, + AST::AttrVec outer_attribs = AST::AttrVec ()) + : Stmt (std::move (mappings)), outer_attrs (std::move (outer_attribs)) + {} + + // Clone function implementation as pure virtual method + virtual Item *clone_item_impl () const = 0; + + /* Save having to specify two clone methods in derived classes by making + * statement clone return item clone. Hopefully won't affect performance too + * much. */ + Item *clone_stmt_impl () const override { return clone_item_impl (); } +}; + +// forward decl of ExprWithoutBlock +class ExprWithoutBlock; + +// Base expression HIR node - abstract +class Expr : public Node +{ + AST::AttrVec outer_attrs; + Analysis::NodeMapping mappings; + +public: + enum BlockType + { + WITH_BLOCK, + WITHOUT_BLOCK, + }; + + enum ExprType + { + Lit, + Operator, + Grouped, + Array, + ArrayIndex, + Tuple, + TupleIdx, + Struct, + Call, + MethodCall, + FieldAccess, + Closure, + Block, + Continue, + Break, + Range, + Return, + UnsafeBlock, + BaseLoop, + If, + IfLet, + Match, + Await, + AsyncBlock, + Path, + }; + + BaseKind get_hir_kind () override final { return EXPR; } + + const AST::AttrVec &get_outer_attrs () const { return outer_attrs; } + + // Unique pointer custom clone function + std::unique_ptr clone_expr () const + { + return std::unique_ptr (clone_expr_impl ()); + } + + /* HACK: downcasting without dynamic_cast (if possible) via polymorphism - + * overrided in subclasses of ExprWithoutBlock */ + virtual ExprWithoutBlock *as_expr_without_block () const { return nullptr; } + + // TODO: make pure virtual if move out outer attributes to derived classes + virtual std::string as_string () const; + + virtual ~Expr () {} + + virtual Location get_locus () const = 0; + + const Analysis::NodeMapping &get_mappings () const { return mappings; } + + // Clone function implementation as pure virtual method + virtual Expr *clone_expr_impl () const = 0; + + virtual BlockType get_block_expr_type () const = 0; + + virtual ExprType get_expression_type () const = 0; + + virtual void accept_vis (HIRExpressionVisitor &vis) = 0; + virtual void accept_vis (HIRFullVisitor &vis) = 0; + +protected: + // Constructor + Expr (Analysis::NodeMapping mappings, + AST::AttrVec outer_attribs = AST::AttrVec ()) + : outer_attrs (std::move (outer_attribs)), mappings (std::move (mappings)) + {} + + // TODO: think of less hacky way to implement this kind of thing + // Sets outer attributes. + void set_outer_attrs (AST::AttrVec outer_attrs_to_set) + { + outer_attrs = std::move (outer_attrs_to_set); + } +}; + +// HIR node for an expression without an accompanying block - abstract +class ExprWithoutBlock : public Expr +{ +protected: + // Constructor + ExprWithoutBlock (Analysis::NodeMapping mappings, + AST::AttrVec outer_attribs = AST::AttrVec ()) + : Expr (std::move (mappings), std::move (outer_attribs)) + {} + + // pure virtual clone implementation + virtual ExprWithoutBlock *clone_expr_without_block_impl () const = 0; + + /* Save having to specify two clone methods in derived classes by making expr + * clone return exprwithoutblock clone. Hopefully won't affect performance too + * much. */ + ExprWithoutBlock *clone_expr_impl () const override + { + return clone_expr_without_block_impl (); + } + +public: + // Unique pointer custom clone function + std::unique_ptr clone_expr_without_block () const + { + return std::unique_ptr (clone_expr_without_block_impl ()); + } + + /* downcasting hack from expr to use pratt parsing with + * parse_expr_without_block */ + ExprWithoutBlock *as_expr_without_block () const override + { + return clone_expr_without_block_impl (); + } + + BlockType get_block_expr_type () const final override + { + return BlockType::WITHOUT_BLOCK; + }; +}; + +// Pattern base HIR node +class Pattern : public Node +{ +public: + enum PatternType + { + PATH, + LITERAL, + IDENTIFIER, + WILDCARD, + RANGE, + REFERENCE, + STRUCT, + TUPLE_STRUCT, + TUPLE, + GROUPED, + SLICE, + }; + + BaseKind get_hir_kind () override final { return PATTERN; } + + // Unique pointer custom clone function + std::unique_ptr clone_pattern () const + { + return std::unique_ptr (clone_pattern_impl ()); + } + + // possible virtual methods: is_refutable() + + virtual ~Pattern () {} + + virtual std::string as_string () const = 0; + + virtual void accept_vis (HIRFullVisitor &vis) = 0; + virtual void accept_vis (HIRPatternVisitor &vis) = 0; + + virtual Analysis::NodeMapping get_pattern_mappings () const = 0; + + virtual Location get_locus () const = 0; + + virtual PatternType get_pattern_type () const = 0; + +protected: + // Clone pattern implementation as pure virtual method + virtual Pattern *clone_pattern_impl () const = 0; +}; + +// forward decl for Type +class TraitBound; + +// Base class for types as represented in HIR - abstract +class Type : public Node +{ +public: + // Unique pointer custom clone function + std::unique_ptr clone_type () const + { + return std::unique_ptr (clone_type_impl ()); + } + + // virtual destructor + virtual ~Type () {} + + BaseKind get_hir_kind () override final { return TYPE; } + + virtual std::string as_string () const = 0; + + /* HACK: convert to trait bound. Virtual method overriden by classes that + * enable this. */ + virtual TraitBound *to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const + { + return nullptr; + } + /* as pointer, shouldn't require definition beforehand, only forward + * declaration. */ + + virtual void accept_vis (HIRFullVisitor &vis) = 0; + virtual void accept_vis (HIRTypeVisitor &vis) = 0; + + virtual Analysis::NodeMapping get_mappings () const { return mappings; } + virtual Location get_locus () const { return locus; } + +protected: + Type (Analysis::NodeMapping mappings, Location locus) + : mappings (mappings), locus (locus) + {} + + // Clone function implementation as pure virtual method + virtual Type *clone_type_impl () const = 0; + + Analysis::NodeMapping mappings; + Location locus; +}; + +// A type without parentheses? - abstract +class TypeNoBounds : public Type +{ +public: + // Unique pointer custom clone function + std::unique_ptr clone_type_no_bounds () const + { + return std::unique_ptr (clone_type_no_bounds_impl ()); + } + +protected: + TypeNoBounds (Analysis::NodeMapping mappings, Location locus) + : Type (mappings, locus) + {} + + // Clone function implementation as pure virtual method + virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0; + + /* Save having to specify two clone methods in derived classes by making type + * clone return typenobounds clone. Hopefully won't affect performance too + * much. */ + TypeNoBounds *clone_type_impl () const override + { + return clone_type_no_bounds_impl (); + } +}; + +/* Abstract base class representing a type param bound - Lifetime and TraitBound + * extends it */ +class TypeParamBound +{ +public: + enum BoundType + { + LIFETIME, + TRAITBOUND + }; + + virtual ~TypeParamBound () {} + + // Unique pointer custom clone function + std::unique_ptr clone_type_param_bound () const + { + return std::unique_ptr (clone_type_param_bound_impl ()); + } + + virtual std::string as_string () const = 0; + + virtual void accept_vis (HIRFullVisitor &vis) = 0; + + virtual Analysis::NodeMapping get_mappings () const = 0; + + virtual Location get_locus () const = 0; + + virtual BoundType get_bound_type () const = 0; + +protected: + // Clone function implementation as pure virtual method + virtual TypeParamBound *clone_type_param_bound_impl () const = 0; +}; + +// Represents a lifetime (and is also a kind of type param bound) +class Lifetime : public TypeParamBound +{ +private: + AST::Lifetime::LifetimeType lifetime_type; + std::string lifetime_name; + Location locus; + Analysis::NodeMapping mappings; + +public: + // Constructor + Lifetime (Analysis::NodeMapping mapping, AST::Lifetime::LifetimeType type, + std::string name, Location locus) + : lifetime_type (type), lifetime_name (std::move (name)), locus (locus), + mappings (mapping) + {} + + // Returns true if the lifetime is in an error state. + bool is_error () const + { + return lifetime_type == AST::Lifetime::LifetimeType::NAMED + && lifetime_name.empty (); + } + + static Lifetime error () + { + return Lifetime (Analysis::NodeMapping::get_error (), + AST::Lifetime::LifetimeType::NAMED, "", Location ()); + } + + std::string as_string () const override; + + void accept_vis (HIRFullVisitor &vis) override; + + std::string get_name () const { return lifetime_name; } + + AST::Lifetime::LifetimeType get_lifetime_type () const + { + return lifetime_type; + } + + Location get_locus () const override final { return locus; } + + Analysis::NodeMapping get_mappings () const override final + { + return mappings; + } + + BoundType get_bound_type () const final override { return LIFETIME; } + +protected: + /* Use covariance to implement clone function as returning this object rather + * than base */ + Lifetime *clone_type_param_bound_impl () const override + { + return new Lifetime (*this); + } +}; + +/* Base generic parameter in HIR. Abstract - can be represented by a Lifetime or + * Type param */ +class GenericParam +{ +public: + virtual ~GenericParam () {} + + enum class GenericKind + { + TYPE, + LIFETIME, + CONST, + }; + + // Unique pointer custom clone function + std::unique_ptr clone_generic_param () const + { + return std::unique_ptr (clone_generic_param_impl ()); + } + + virtual std::string as_string () const = 0; + + virtual void accept_vis (HIRFullVisitor &vis) = 0; + + virtual Location get_locus () const = 0; + + Analysis::NodeMapping get_mappings () const { return mappings; } + + enum GenericKind get_kind () const { return kind; } + +protected: + // Clone function implementation as pure virtual method + virtual GenericParam *clone_generic_param_impl () const = 0; + + Analysis::NodeMapping mappings; + + enum GenericKind kind; + + GenericParam (Analysis::NodeMapping mapping, + enum GenericKind kind = GenericKind::TYPE) + : mappings (mapping), kind (kind) + {} +}; + +// A lifetime generic parameter (as opposed to a type generic parameter) +class LifetimeParam : public GenericParam +{ + Lifetime lifetime; + + // bool has_lifetime_bounds; + // LifetimeBounds lifetime_bounds; + std::vector lifetime_bounds; // inlined LifetimeBounds + + // bool has_outer_attribute; + // std::unique_ptr outer_attr; + AST::Attribute outer_attr; + + Location locus; + +public: + Lifetime get_lifetime () { return lifetime; } + + // Returns whether the lifetime param has any lifetime bounds. + bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); } + + // Returns whether the lifetime param has an outer attribute. + bool has_outer_attribute () const { return !outer_attr.is_empty (); } + + // Returns whether the lifetime param is in an error state. + bool is_error () const { return lifetime.is_error (); } + + // Constructor + LifetimeParam (Analysis::NodeMapping mappings, Lifetime lifetime, + Location locus = Location (), + std::vector lifetime_bounds + = std::vector (), + AST::Attribute outer_attr = AST::Attribute::create_empty ()) + : GenericParam (mappings, GenericKind::LIFETIME), + lifetime (std::move (lifetime)), + lifetime_bounds (std::move (lifetime_bounds)), + outer_attr (std::move (outer_attr)), locus (locus) + {} + + // TODO: remove copy and assignment operator definitions - not required + + // Copy constructor with clone + LifetimeParam (LifetimeParam const &other) + : GenericParam (other.mappings, GenericKind::LIFETIME), + lifetime (other.lifetime), lifetime_bounds (other.lifetime_bounds), + outer_attr (other.outer_attr), locus (other.locus) + {} + + // Overloaded assignment operator to clone attribute + LifetimeParam &operator= (LifetimeParam const &other) + { + lifetime = other.lifetime; + lifetime_bounds = other.lifetime_bounds; + outer_attr = other.outer_attr; + locus = other.locus; + mappings = other.mappings; + + return *this; + } + + // move constructors + LifetimeParam (LifetimeParam &&other) = default; + LifetimeParam &operator= (LifetimeParam &&other) = default; + + std::string as_string () const override; + + void accept_vis (HIRFullVisitor &vis) override; + + Location get_locus () const override final { return locus; } + +protected: + /* Use covariance to implement clone function as returning this object rather + * than base */ + LifetimeParam *clone_generic_param_impl () const override + { + return new LifetimeParam (*this); + } +}; + +class ConstGenericParam : public GenericParam +{ +public: + ConstGenericParam (std::string name, std::unique_ptr type, + std::unique_ptr default_expression, + Analysis::NodeMapping mapping, Location locus) + : GenericParam (mapping, GenericKind::CONST), name (std::move (name)), + type (std::move (type)), + default_expression (std::move (default_expression)), locus (locus) + {} + + ConstGenericParam (const ConstGenericParam &other) : GenericParam (other) + { + name = other.name; + locus = other.locus; + + if (other.type) + type = other.type->clone_type (); + if (other.default_expression) + default_expression = other.default_expression->clone_expr (); + } + + std::string as_string () const override final; + + void accept_vis (HIRFullVisitor &vis) override final; + + Location get_locus () const override final { return locus; }; + + bool has_default_expression () { return default_expression != nullptr; } + + std::unique_ptr &get_type () { return type; } + std::unique_ptr &get_default_expression () + { + rust_assert (has_default_expression ()); + + return default_expression; + } + +protected: + /* Use covariance to implement clone function as returning this object rather + * than base */ + ConstGenericParam *clone_generic_param_impl () const override + { + return new ConstGenericParam (*this); + } + +private: + std::string name; + std::unique_ptr type; + + /* Optional - can be a null pointer if there is no default expression */ + std::unique_ptr default_expression; + + Location locus; +}; + +// Item used in trait declarations - abstract base class +class TraitItem : public Node +{ +public: + enum TraitItemKind + { + FUNC, + CONST, + TYPE + }; + + BaseKind get_hir_kind () override final { return TRAIT_ITEM; } + +protected: + // Constructor + TraitItem (Analysis::NodeMapping mappings) : mappings (mappings) {} + + // Clone function implementation as pure virtual method + virtual TraitItem *clone_trait_item_impl () const = 0; + + Analysis::NodeMapping mappings; + +public: + virtual ~TraitItem () {} + + std::unique_ptr clone_trait_item () const + { + return std::unique_ptr (clone_trait_item_impl ()); + } + + virtual std::string as_string () const = 0; + + virtual void accept_vis (HIRTraitItemVisitor &vis) = 0; + virtual void accept_vis (HIRFullVisitor &vis) = 0; + + virtual const std::string trait_identifier () const = 0; + + const Analysis::NodeMapping get_mappings () const { return mappings; } + + virtual TraitItemKind get_item_kind () const = 0; + + virtual AST::AttrVec &get_outer_attrs () = 0; + virtual const AST::AttrVec &get_outer_attrs () const = 0; +}; + +class ImplItem : public Node +{ +public: + enum ImplItemType + { + FUNCTION, + TYPE_ALIAS, + CONSTANT + }; + + virtual ~ImplItem () {} + + BaseKind get_hir_kind () override final { return IMPL; } + + // Unique pointer custom clone function + std::unique_ptr clone_inherent_impl_item () const + { + return std::unique_ptr (clone_inherent_impl_item_impl ()); + } + + virtual std::string as_string () const = 0; + + virtual void accept_vis (HIRImplVisitor &vis) = 0; + virtual void accept_vis (HIRFullVisitor &vis) = 0; + virtual void accept_vis (HIRStmtVisitor &vis) = 0; + + virtual Analysis::NodeMapping get_impl_mappings () const = 0; + + virtual Location get_locus () const = 0; + + virtual ImplItemType get_impl_item_type () const = 0; + +protected: + // Clone function implementation as pure virtual method + virtual ImplItem *clone_inherent_impl_item_impl () const = 0; +}; + +// A crate HIR object - holds all the data for a single compilation unit +struct Crate +{ + AST::AttrVec inner_attrs; + // dodgy spacing required here + /* TODO: is it better to have a vector of items here or a module (implicit + * top-level one)? */ + std::vector > items; + + Analysis::NodeMapping mappings; + +public: + // Constructor + Crate (std::vector > items, AST::AttrVec inner_attrs, + Analysis::NodeMapping mappings) + : inner_attrs (std::move (inner_attrs)), items (std::move (items)), + mappings (mappings) + {} + + // Copy constructor with vector clone + Crate (Crate const &other) + : inner_attrs (other.inner_attrs), mappings (other.mappings) + { + items.reserve (other.items.size ()); + for (const auto &e : other.items) + items.push_back (e->clone_item ()); + } + + ~Crate () = default; + + // Overloaded assignment operator with vector clone + Crate &operator= (Crate const &other) + { + inner_attrs = other.inner_attrs; + mappings = other.mappings; + + items.reserve (other.items.size ()); + for (const auto &e : other.items) + items.push_back (e->clone_item ()); + + return *this; + } + + // Move constructors + Crate (Crate &&other) = default; + Crate &operator= (Crate &&other) = default; + + // Get crate representation as string (e.g. for debugging). + std::string as_string () const; + + const Analysis::NodeMapping &get_mappings () const { return mappings; } +}; + +// Base path expression HIR node - abstract +class PathExpr : public ExprWithoutBlock +{ +protected: + PathExpr (Analysis::NodeMapping mappings, AST::AttrVec outer_attribs) + : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)) + {} + +public: + /* Replaces the outer attributes of this path expression with the given outer + * attributes. */ + void replace_outer_attrs (AST::AttrVec outer_attrs) + { + set_outer_attrs (std::move (outer_attrs)); + } + + ExprType get_expression_type () const final override + { + return ExprType::Path; + } +}; +} // namespace HIR +} // namespace Rust + +#endif -- 2.37.2