aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNala Ginrut <mulei@gnu.org>2020-04-30 00:22:36 +0800
committerPhilip Herron <philip.herron@embecosm.com>2020-11-27 18:07:04 +0000
commit7266d66d2321562ef74daf90ffb1ad70d081d890 (patch)
tree89ad46fd0e85eed625eac6ceba9b04d770b0390a
parent89d78a4a9e0af7e4a7da88c3e6d7688b8423fc39 (diff)
downloadgcc-7266d66d2321562ef74daf90ffb1ad70d081d890.zip
gcc-7266d66d2321562ef74daf90ffb1ad70d081d890.tar.gz
gcc-7266d66d2321562ef74daf90ffb1ad70d081d890.tar.bz2
Fix indentation
-rw-r--r--gcc/rust/ast/clone-test.h2
-rw-r--r--gcc/rust/ast/rust-ast-containers.h83
-rw-r--r--gcc/rust/ast/rust-ast-visitor.h420
-rw-r--r--gcc/rust/ast/rust-ast.h2843
-rw-r--r--gcc/rust/ast/rust-cond-compilation.h425
-rw-r--r--gcc/rust/ast/rust-expr.h9781
-rw-r--r--gcc/rust/ast/rust-macro.h1217
-rw-r--r--gcc/rust/ast/rust-path.h1661
-rw-r--r--gcc/rust/ast/rust-pattern.h2448
-rw-r--r--gcc/rust/ast/rust-stmt.h484
-rw-r--r--gcc/rust/ast/rust-type.h1730
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc130
-rw-r--r--gcc/rust/expand/rust-macro-expand.h78
-rw-r--r--gcc/rust/lang-specs.h26
-rw-r--r--gcc/rust/lex/rust-codepoint.h23
-rw-r--r--gcc/rust/lex/rust-lex.h248
-rw-r--r--gcc/rust/lex/rust-token.cc176
-rw-r--r--gcc/rust/lex/rust-token.h741
-rw-r--r--gcc/rust/operator.h97
-rw-r--r--gcc/rust/parse/rust-parse.h1008
-rw-r--r--gcc/rust/rust-backend.c48
-rw-r--r--gcc/rust/rust-buffered-queue.h255
-rw-r--r--gcc/rust/rust-diagnostics.cc207
-rw-r--r--gcc/rust/rust-diagnostics.h49
-rw-r--r--gcc/rust/rust-gcc.cc293
-rw-r--r--gcc/rust/rust-lang.cc418
-rw-r--r--gcc/rust/rust-linemap.cc105
-rw-r--r--gcc/rust/rust-linemap.h103
-rw-r--r--gcc/rust/rust-location.h45
-rw-r--r--gcc/rust/rust-object-export.c48
-rw-r--r--gcc/rust/rust-object-export.h2
-rw-r--r--gcc/rust/rust-session-manager.cc1357
-rw-r--r--gcc/rust/rust-session-manager.h368
-rw-r--r--gcc/rust/rust-system.h108
-rw-r--r--gcc/rust/rustspec.cc4
35 files changed, 14451 insertions, 12580 deletions
diff --git a/gcc/rust/ast/clone-test.h b/gcc/rust/ast/clone-test.h
index 0c71c82..7d530d2 100644
--- a/gcc/rust/ast/clone-test.h
+++ b/gcc/rust/ast/clone-test.h
@@ -87,4 +87,4 @@ namespace user_code {
}
#endif
-#endif \ No newline at end of file
+#endif
diff --git a/gcc/rust/ast/rust-ast-containers.h b/gcc/rust/ast/rust-ast-containers.h
index 81b0187..fa400f1 100644
--- a/gcc/rust/ast/rust-ast-containers.h
+++ b/gcc/rust/ast/rust-ast-containers.h
@@ -2,47 +2,52 @@
#define RUST_AST_CONTAINERS_H
// crappy redefined AST maybe. may move
-/* This is mainly the "logical", more "abstract" representation of the code, while the "AST" itself is
- * more high-level and matches the language better. */
+/* This is mainly the "logical", more "abstract" representation of the code,
+ * while the "AST" itself is more high-level and matches the language better. */
// this is now deprecated and replaced with the proper AST
#error "rust-ast-containers.h was included by accident. Don't use."
namespace Rust {
- namespace AST {
- struct Module {
- public:
- };
-
- struct Crate {
- public:
- Module root_module;
- };
-
- // replace with rust-types.h version
- struct AttributeList {
- public:
- //::std::vector<Attribute> attribs;
- };
-
- // replace with rust-types.h version
- struct Visibility {};
-
- /*enum VisibilityType {
- Private,
- PublicFull,
- PublicInPath,
- PublicCrate,
- PublicSuper,
- PublicSelfModule
- };
-
- // Represents visibility - maybe make into an enum or union or something
- struct Visibility {
- };
-
- */
- }
-}
-
-#endif \ No newline at end of file
+namespace AST {
+struct Module
+{
+public:
+};
+
+struct Crate
+{
+public:
+ Module root_module;
+};
+
+// replace with rust-types.h version
+struct AttributeList
+{
+public:
+ //::std::vector<Attribute> attribs;
+};
+
+// replace with rust-types.h version
+struct Visibility
+{
+};
+
+/*enum VisibilityType {
+ Private,
+ PublicFull,
+ PublicInPath,
+ PublicCrate,
+ PublicSuper,
+ PublicSelfModule
+};
+
+// Represents visibility - maybe make into an enum or union or something
+struct Visibility {
+};
+
+*/
+} // namespace AST
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index b8e92c2..eb680b8 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -1,224 +1,226 @@
#ifndef RUST_AST_VISITOR_H
#define RUST_AST_VISITOR_H
-// Visitor base for AST
+// Visitor base for AST
// full include not required - only forward decls
#include "rust-ast-full-decls.h"
namespace Rust {
- namespace AST {
- // Pure abstract class that provides an interface for accessing different classes of the AST.
- class ASTVisitor {
- public:
- // only concrete class overloads are required
+namespace AST {
+// Pure abstract class that provides an interface for accessing different
+// classes of the AST.
+class ASTVisitor
+{
+public:
+ // only concrete class overloads are required
- // rust-ast.h
- //virtual void visit(AttrInput& attr_input) = 0;
- //virtual void visit(TokenTree& token_tree) = 0;
- //virtual void visit(MacroMatch& macro_match) = 0;
- virtual void visit(Token& tok) = 0;
- virtual void visit(DelimTokenTree& delim_tok_tree) = 0;
- virtual void visit(AttrInputMetaItemContainer& input) = 0;
- //virtual void visit(MetaItem& meta_item) = 0;
- //virtual void visit(Stmt& stmt) = 0;
- //virtual void visit(Expr& expr) = 0;
- virtual void visit(IdentifierExpr& ident_expr) = 0;
- //virtual void visit(Pattern& pattern) = 0;
- //virtual void visit(Type& type) = 0;
- //virtual void visit(TypeParamBound& type_param_bound) = 0;
- virtual void visit(Lifetime& lifetime) = 0;
- //virtual void visit(GenericParam& generic_param) = 0;
- virtual void visit(LifetimeParam& lifetime_param) = 0;
- //virtual void visit(TraitItem& trait_item) = 0;
- //virtual void visit(InherentImplItem& inherent_impl_item) = 0;
- //virtual void visit(TraitImplItem& trait_impl_item) = 0;
- virtual void visit(MacroInvocationSemi& macro) = 0;
-
- // rust-path.h
- 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;
+ // rust-ast.h
+ // virtual void visit(AttrInput& attr_input) = 0;
+ // virtual void visit(TokenTree& token_tree) = 0;
+ // virtual void visit(MacroMatch& macro_match) = 0;
+ virtual void visit (Token &tok) = 0;
+ virtual void visit (DelimTokenTree &delim_tok_tree) = 0;
+ virtual void visit (AttrInputMetaItemContainer &input) = 0;
+ // virtual void visit(MetaItem& meta_item) = 0;
+ // virtual void visit(Stmt& stmt) = 0;
+ // virtual void visit(Expr& expr) = 0;
+ virtual void visit (IdentifierExpr &ident_expr) = 0;
+ // virtual void visit(Pattern& pattern) = 0;
+ // virtual void visit(Type& type) = 0;
+ // virtual void visit(TypeParamBound& type_param_bound) = 0;
+ virtual void visit (Lifetime &lifetime) = 0;
+ // virtual void visit(GenericParam& generic_param) = 0;
+ virtual void visit (LifetimeParam &lifetime_param) = 0;
+ // virtual void visit(TraitItem& trait_item) = 0;
+ // virtual void visit(InherentImplItem& inherent_impl_item) = 0;
+ // virtual void visit(TraitImplItem& trait_impl_item) = 0;
+ virtual void visit (MacroInvocationSemi &macro) = 0;
- // rust-expr.h
- virtual void visit(LiteralExpr& expr) = 0;
- virtual void visit(AttrInputLiteral& attr_input) = 0;
- virtual void visit(MetaItemLitExpr& meta_item) = 0;
- virtual void visit(MetaItemPathLit& meta_item) = 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(ArrayElems& elems) = 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(StructExprField& field) = 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(StructExprTuple& expr) = 0;
- virtual void visit(StructExprUnit& expr) = 0;
- //virtual void visit(EnumExprField& field) = 0;
- virtual void visit(EnumExprFieldIdentifier& field) = 0;
- virtual void visit(EnumExprFieldIdentifierValue& field) = 0;
- virtual void visit(EnumExprFieldIndexValue& field) = 0;
- virtual void visit(EnumExprStruct& expr) = 0;
- virtual void visit(EnumExprTuple& expr) = 0;
- virtual void visit(EnumExprFieldless& 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(MatchCase& match_case) = 0;
- virtual void visit(MatchCaseBlockExpr& match_case) = 0;
- virtual void visit(MatchCaseExpr& match_case) = 0;
- virtual void visit(MatchExpr& expr) = 0;
- virtual void visit(AwaitExpr& expr) = 0;
- virtual void visit(AsyncBlockExpr& expr) = 0;
+ // rust-path.h
+ 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;
- // rust-item.h
- virtual void visit(TypeParam& param) = 0;
- //virtual void visit(WhereClauseItem& item) = 0;
- virtual void visit(LifetimeWhereClauseItem& item) = 0;
- virtual void visit(TypeBoundWhereClauseItem& item) = 0;
- virtual void visit(Method& method) = 0;
- virtual void visit(ModuleBodied& module) = 0;
- virtual void visit(ModuleNoBody& module) = 0;
- virtual void visit(ExternCrate& crate) = 0;
- //virtual void visit(UseTree& use_tree) = 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(TraitItemMethod& item) = 0;
- virtual void visit(TraitItemConst& item) = 0;
- virtual void visit(TraitItemType& item) = 0;
- virtual void visit(Trait& trait) = 0;
- virtual void visit(InherentImpl& impl) = 0;
- virtual void visit(TraitImpl& impl) = 0;
- //virtual void visit(ExternalItem& item) = 0;
- virtual void visit(ExternalStaticItem& item) = 0;
- virtual void visit(ExternalFunctionItem& item) = 0;
- virtual void visit(ExternBlock& block) = 0;
+ // rust-expr.h
+ virtual void visit (LiteralExpr &expr) = 0;
+ virtual void visit (AttrInputLiteral &attr_input) = 0;
+ virtual void visit (MetaItemLitExpr &meta_item) = 0;
+ virtual void visit (MetaItemPathLit &meta_item) = 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(ArrayElems& elems) = 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(StructExprField& field) = 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 (StructExprTuple &expr) = 0;
+ virtual void visit (StructExprUnit &expr) = 0;
+ // virtual void visit(EnumExprField& field) = 0;
+ virtual void visit (EnumExprFieldIdentifier &field) = 0;
+ virtual void visit (EnumExprFieldIdentifierValue &field) = 0;
+ virtual void visit (EnumExprFieldIndexValue &field) = 0;
+ virtual void visit (EnumExprStruct &expr) = 0;
+ virtual void visit (EnumExprTuple &expr) = 0;
+ virtual void visit (EnumExprFieldless &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(MatchCase& match_case) = 0;
+ virtual void visit (MatchCaseBlockExpr &match_case) = 0;
+ virtual void visit (MatchCaseExpr &match_case) = 0;
+ virtual void visit (MatchExpr &expr) = 0;
+ virtual void visit (AwaitExpr &expr) = 0;
+ virtual void visit (AsyncBlockExpr &expr) = 0;
- // rust-macro.h
- virtual void visit(MacroMatchFragment& match) = 0;
- virtual void visit(MacroMatchRepetition& match) = 0;
- virtual void visit(MacroMatcher& matcher) = 0;
- virtual void visit(MacroRulesDefinition& rules_def) = 0;
- virtual void visit(MacroInvocation& macro_invoc) = 0;
- virtual void visit(MetaItemPath& meta_item) = 0;
- virtual void visit(MetaItemSeq& meta_item) = 0;
- virtual void visit(MetaWord& meta_item) = 0;
- virtual void visit(MetaNameValueStr& meta_item) = 0;
- virtual void visit(MetaListPaths& meta_item) = 0;
- virtual void visit(MetaListNameValueStr& meta_item) = 0;
+ // rust-item.h
+ virtual void visit (TypeParam &param) = 0;
+ // virtual void visit(WhereClauseItem& item) = 0;
+ virtual void visit (LifetimeWhereClauseItem &item) = 0;
+ virtual void visit (TypeBoundWhereClauseItem &item) = 0;
+ virtual void visit (Method &method) = 0;
+ virtual void visit (ModuleBodied &module) = 0;
+ virtual void visit (ModuleNoBody &module) = 0;
+ virtual void visit (ExternCrate &crate) = 0;
+ // virtual void visit(UseTree& use_tree) = 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 (TraitItemMethod &item) = 0;
+ virtual void visit (TraitItemConst &item) = 0;
+ virtual void visit (TraitItemType &item) = 0;
+ virtual void visit (Trait &trait) = 0;
+ virtual void visit (InherentImpl &impl) = 0;
+ virtual void visit (TraitImpl &impl) = 0;
+ // virtual void visit(ExternalItem& item) = 0;
+ virtual void visit (ExternalStaticItem &item) = 0;
+ virtual void visit (ExternalFunctionItem &item) = 0;
+ virtual void visit (ExternBlock &block) = 0;
- // rust-pattern.h
- virtual void visit(LiteralPattern& pattern) = 0;
- virtual void visit(IdentifierPattern& pattern) = 0;
- virtual void visit(WildcardPattern& pattern) = 0;
- //virtual void visit(RangePatternBound& bound) = 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(StructPatternField& field) = 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(TupleStructItems& tuple_items) = 0;
- virtual void visit(TupleStructItemsNoRange& tuple_items) = 0;
- virtual void visit(TupleStructItemsRange& tuple_items) = 0;
- virtual void visit(TupleStructPattern& pattern) = 0;
- //virtual void visit(TuplePatternItems& tuple_items) = 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;
+ // rust-macro.h
+ virtual void visit (MacroMatchFragment &match) = 0;
+ virtual void visit (MacroMatchRepetition &match) = 0;
+ virtual void visit (MacroMatcher &matcher) = 0;
+ virtual void visit (MacroRulesDefinition &rules_def) = 0;
+ virtual void visit (MacroInvocation &macro_invoc) = 0;
+ virtual void visit (MetaItemPath &meta_item) = 0;
+ virtual void visit (MetaItemSeq &meta_item) = 0;
+ virtual void visit (MetaWord &meta_item) = 0;
+ virtual void visit (MetaNameValueStr &meta_item) = 0;
+ virtual void visit (MetaListPaths &meta_item) = 0;
+ virtual void visit (MetaListNameValueStr &meta_item) = 0;
- // rust-stmt.h
- virtual void visit(EmptyStmt& stmt) = 0;
- virtual void visit(LetStmt& stmt) = 0;
- virtual void visit(ExprStmtWithoutBlock& stmt) = 0;
- virtual void visit(ExprStmtWithBlock& stmt) = 0;
-
- // rust-type.h
- 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(TraitObjectTypeOneBound& 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;
+ // rust-pattern.h
+ virtual void visit (LiteralPattern &pattern) = 0;
+ virtual void visit (IdentifierPattern &pattern) = 0;
+ virtual void visit (WildcardPattern &pattern) = 0;
+ // virtual void visit(RangePatternBound& bound) = 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(StructPatternField& field) = 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(TupleStructItems& tuple_items) = 0;
+ virtual void visit (TupleStructItemsNoRange &tuple_items) = 0;
+ virtual void visit (TupleStructItemsRange &tuple_items) = 0;
+ virtual void visit (TupleStructPattern &pattern) = 0;
+ // virtual void visit(TuplePatternItems& tuple_items) = 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;
- // TODO: rust-cond-compilation.h visiting? not currently used
- };
- }
-}
+ // rust-stmt.h
+ virtual void visit (EmptyStmt &stmt) = 0;
+ virtual void visit (LetStmt &stmt) = 0;
+ virtual void visit (ExprStmtWithoutBlock &stmt) = 0;
+ virtual void visit (ExprStmtWithBlock &stmt) = 0;
-#endif \ No newline at end of file
+ // rust-type.h
+ 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 (TraitObjectTypeOneBound &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;
+
+ // TODO: rust-cond-compilation.h visiting? not currently used
+};
+} // namespace AST
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 54634ef..6a7511e 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -24,1355 +24,1502 @@
#include "rust-location.h"
namespace Rust {
- // TODO: remove typedefs and make actual types for these
- // typedef int Location;
- // typedef ::std::string SimplePath;
- typedef ::std::string Identifier;
- typedef int TupleIndex;
-
- struct Session;
-
- namespace AST {
- // foward decl: ast visitor
- class ASTVisitor;
-
- // Delimiter types - used in macros and whatever.
- enum DelimType { PARENS, SQUARE, CURLY };
-
- // Base AST node object - TODO is this really required or useful? Where to draw line?
- /*class Node {
- public:
- // Gets node's Location.
- Location get_locus() const {
- return loc;
- }
-
- // Sets node's Location.
- void set_locus(Location loc_) {
- loc = loc_;
- }
-
- // Get node output as a string. Pure virtual.
- virtual ::std::string as_string() const = 0;
-
- virtual ~Node() {}
-
- // TODO: constructor including Location? Make all derived classes have Location?
-
- private:
- // The node's location.
- Location loc;
- };*/
- // decided to not have node as a "node" would never need to be stored
-
- // Attribute body - abstract base class
- class AttrInput {
- public:
- virtual ~AttrInput() {}
-
- // Unique pointer custom clone function
- ::std::unique_ptr<AttrInput> clone_attr_input() const {
- return ::std::unique_ptr<AttrInput>(clone_attr_input_impl());
- }
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- virtual bool check_cfg_predicate(const Session& session) const = 0;
-
- // Parse attribute input to meta item, if possible
- virtual AttrInput* parse_to_meta_item() const {
- return NULL;
- }
-
- protected:
- // pure virtual clone implementation
- virtual AttrInput* clone_attr_input_impl() const = 0;
- };
-
- // forward decl for use in token tree method
- class Token;
-
- // A tree of tokens (or a single token) - abstract base class
- class TokenTree {
- public:
- virtual ~TokenTree() {}
-
- // Unique pointer custom clone function
- ::std::unique_ptr<TokenTree> clone_token_tree() const {
- return ::std::unique_ptr<TokenTree>(clone_token_tree_impl());
- }
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- /* Converts token tree to a flat token stream. Tokens must be pointer to avoid mutual
- * dependency with Token. */
- virtual ::std::vector< ::std::unique_ptr<Token> > to_token_stream() const = 0;
-
- protected:
- // pure virtual clone implementation
- virtual TokenTree* clone_token_tree_impl() const = 0;
- };
-
- // Abstract base class for a macro match
- class MacroMatch {
- public:
- virtual ~MacroMatch() {}
-
- virtual ::std::string as_string() const = 0;
-
- // Unique pointer custom clone function
- ::std::unique_ptr<MacroMatch> clone_macro_match() const {
- return ::std::unique_ptr<MacroMatch>(clone_macro_match_impl());
- }
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- protected:
- // pure virtual clone implementation
- virtual MacroMatch* clone_macro_match_impl() const = 0;
- };
-
- // A token is a kind of token tree (except delimiter tokens)
- class Token
- : public TokenTree
- , public MacroMatch {
- // A token is a kind of token tree (except delimiter tokens)
- // A token is a kind of MacroMatch (except $ and delimiter tokens)
- // TODO: improve member variables - current ones are the same as lexer token
- // Token kind.
- TokenId token_id;
- // Token location.
- Location locus;
- // Associated text (if any) of token.
- std::string str;
- // Token type hint (if any).
- PrimitiveCoreType type_hint;
-
- public:
- // Unique pointer custom clone function
- ::std::unique_ptr<Token> clone_token() const {
- return ::std::unique_ptr<Token>(clone_token_impl());
- }
-
- // constructor from general text - avoid using if lexer const_TokenPtr is available
- Token(TokenId token_id, Location locus, ::std::string str, PrimitiveCoreType type_hint) :
- token_id(token_id), locus(locus), str(::std::move(str)), type_hint(type_hint) {}
-
- // Constructor from lexer const_TokenPtr
- /* TODO: find workaround for std::string being NULL - probably have to introduce new
- * method in lexer Token, or maybe make conversion method there*/
- Token(const_TokenPtr lexer_token_ptr) :
- token_id(lexer_token_ptr->get_id()), locus(lexer_token_ptr->get_locus()), str(""),
- type_hint(lexer_token_ptr->get_type_hint()) {
- // FIXME: change to "should have str" later?
- if (lexer_token_ptr->has_str()) {
- str = lexer_token_ptr->get_str();
-
- // DEBUG
- fprintf(stderr, "ast token created with str '%s'\n", str.c_str());
- } else {
- // FIXME: is this returning correct thing?
- str = lexer_token_ptr->get_token_description();
-
- // DEBUG
- fprintf(stderr, "ast token created with string '%s'\n", str.c_str());
- }
-
- // DEBUG
- if (lexer_token_ptr->should_have_str() && !lexer_token_ptr->has_str()) {
- fprintf(stderr, "BAD: for token '%s', should have string but does not!\n",
- lexer_token_ptr->get_token_description());
- }
- }
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- // Return copy of itself but in token stream form.
- virtual ::std::vector< ::std::unique_ptr<Token> > to_token_stream() const OVERRIDE;
-
- TokenId get_id() const {
- return token_id;
- }
-
- Location get_locus() const {
- return locus;
- }
-
- protected:
- // No virtual for now as not polymorphic but can be in future
- /*virtual*/ Token* clone_token_impl() const {
- return new Token(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual Token* clone_token_tree_impl() const OVERRIDE {
- return new Token(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual Token* clone_macro_match_impl() const OVERRIDE {
- return new Token(*this);
- }
- };
-
- // A literal - value with a type. Used in LiteralExpr and LiteralPattern.
- struct Literal {
- public:
- enum LitType {
- CHAR,
- STRING,
- RAW_STRING,
- BYTE,
- BYTE_STRING,
- RAW_BYTE_STRING,
- INT,
- FLOAT,
- BOOL
- };
-
- private:
- // TODO: maybe make subclasses of each type of literal with their typed values (or
- // generics)
- ::std::string value_as_string;
- LitType type;
-
- public:
- ::std::string as_string() const {
- return value_as_string;
- }
-
- inline LitType get_lit_type() const {
- return type;
- }
-
- Literal(::std::string value_as_string, LitType type) :
- value_as_string(::std::move(value_as_string)), type(type) {}
-
- static Literal create_error() {
- return Literal("", CHAR);
- }
-
- // Returns whether literal is in an invalid state.
- bool is_error() const {
- return value_as_string == "";
- }
- };
-
- // A token tree with delimiters
- class DelimTokenTree
- : public TokenTree
- , public AttrInput {
- DelimType delim_type;
- ::std::vector< ::std::unique_ptr<TokenTree> > token_trees;
-
- Location locus;
-
- // TODO: move all the "parse" functions into a separate class that has the token stream
- // reference - will be cleaner Parse a meta item inner.
- //::std::unique_ptr<MetaItemInner> parse_meta_item_inner(const ::std::vector<
- //::std::unique_ptr<Token> >& token_stream, int& i) const; SimplePath
- // parse_simple_path(const ::std::vector< ::std::unique_ptr<Token> >& token_stream, int&
- // i) const; SimplePathSegment parse_simple_path_segment(const ::std::vector<
- // ::std::unique_ptr<Token> >& token_stream, int& i) const;
- //::std::unique_ptr<MetaItemLitExpr> parse_meta_item_lit(const ::std::unique_ptr<Token>&
- // tok) const;
- //::std::vector< ::std::unique_ptr<MetaItemInner> > parse_meta_item_seq(const
- //::std::vector< ::std::unique_ptr<Token> >& token_stream, int& i) const; Literal
- // parse_literal(const ::std::unique_ptr<Token>& tok) const;
- //::std::unique_ptr<MetaItem> parse_path_meta_item(const ::std::vector<
- //::std::unique_ptr<Token> >& token_stream, int& i) const; bool
- // is_end_meta_item_tok(TokenId tok) const;
-
- protected:
- // Use covariance to implement clone function as returning a DelimTokenTree object
- virtual DelimTokenTree* clone_attr_input_impl() const OVERRIDE {
- return new DelimTokenTree(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual DelimTokenTree* clone_token_tree_impl() const OVERRIDE {
- return new DelimTokenTree(*this);
- }
-
- public:
- DelimTokenTree(DelimType delim_type,
- ::std::vector< ::std::unique_ptr<TokenTree> > token_trees
- = ::std::vector< ::std::unique_ptr<TokenTree> >(),
- Location locus = Location()) :
- delim_type(delim_type),
- token_trees(::std::move(token_trees)), locus(locus) {}
-
- // Copy constructor with vector clone
- DelimTokenTree(DelimTokenTree const& other) :
- delim_type(other.delim_type), locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- token_trees.reserve(other.token_trees.size());
-
- for (const auto& e : other.token_trees) {
- token_trees.push_back(e->clone_token_tree());
- }
- }
-
- // overloaded assignment operator with vector clone
- DelimTokenTree& operator=(DelimTokenTree const& other) {
- delim_type = other.delim_type;
- locus = other.locus;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- token_trees.reserve(other.token_trees.size());
-
- for (const auto& e : other.token_trees) {
- token_trees.push_back(e->clone_token_tree());
- }
-
- return *this;
- }
-
- // move constructors
- DelimTokenTree(DelimTokenTree&& other) = default;
- DelimTokenTree& operator=(DelimTokenTree&& other) = default;
-
- static DelimTokenTree create_empty() {
- return DelimTokenTree(PARENS);
- }
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- virtual bool check_cfg_predicate(const Session& session ATTRIBUTE_UNUSED) const OVERRIDE {
- // this should never be called - should be converted first
- return false;
- }
-
- virtual AttrInput* parse_to_meta_item() const OVERRIDE;
-
- virtual ::std::vector< ::std::unique_ptr<Token> > to_token_stream() const OVERRIDE;
- };
-
- // Forward decl - definition moved to rust-expr.h as it requires LiteralExpr to be defined
- class AttrInputLiteral;
-
- // TODO: move applicable stuff into here or just don't include it because nothing uses it
- // A segment of a path (maybe)
- class PathSegment {
- public:
- virtual ~PathSegment() {}
-
- virtual ::std::string as_string() const = 0;
-
- // TODO: add visitor here?
- };
-
- // A segment of a simple path without generic or type arguments
- class SimplePathSegment : public PathSegment {
- ::std::string segment_name;
- Location locus;
-
- // only allow identifiers, "super", "self", "crate", or "$crate"
- public:
- // TODO: put checks in constructor to enforce this rule?
- SimplePathSegment(::std::string segment_name, Location locus = Location()) :
- segment_name(::std::move(segment_name)), locus(locus) {}
-
- // Returns whether simple path segment is in an invalid state (currently, if empty).
- inline bool is_error() const {
- return segment_name.empty();
- }
-
- // Creates an error SimplePathSegment
- static SimplePathSegment create_error() {
- return SimplePathSegment(::std::string(""));
- }
-
- ::std::string as_string() const;
-
- inline Location get_locus() const {
- return locus;
- }
-
- // TODO: visitor pattern?
- };
-
- // A simple path without generic or type arguments
- class SimplePath {
- bool has_opening_scope_resolution;
- ::std::vector<SimplePathSegment> segments;
- Location locus;
-
- public:
- // Constructor
- SimplePath(::std::vector<SimplePathSegment> path_segments,
- bool has_opening_scope_resolution = false, Location locus = Location()) :
- has_opening_scope_resolution(has_opening_scope_resolution),
- segments(::std::move(path_segments)), locus(locus) {}
-
- // Creates an empty SimplePath.
- static SimplePath create_empty() {
- return SimplePath(::std::vector<SimplePathSegment>());
- }
-
- // Returns whether the SimplePath is empty, i.e. has path segments.
- inline bool is_empty() const {
- return segments.empty();
- }
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- // does this need visitor if not polymorphic? probably not
-
- // path-to-string comparison operator
- bool operator==(const ::std::string& rhs) {
- return !has_opening_scope_resolution && segments.size() == 1
- && segments[0].as_string() == rhs;
- }
-
- /* Creates a single-segment SimplePath from a string. This will not check to ensure that
- * this is a valid identifier in path, so be careful. Also, this will have no location
- * data.
- * TODO have checks? */
- static SimplePath from_str(::std::string str) {
- ::std::vector<AST::SimplePathSegment> single_segments
- = { AST::SimplePathSegment(::std::move(str)) };
- return SimplePath(::std::move(single_segments));
- }
- };
-
- // aka Attr
- // Attribute AST representation
- struct Attribute {
- private:
- SimplePath path;
-
- // bool has_attr_input;
- // AttrInput* attr_input;
- ::std::unique_ptr<AttrInput> attr_input;
-
- Location locus;
-
- // TODO: maybe a variable storing whether attr input is parsed or not
-
- public:
- // Returns whether Attribute has AttrInput
- inline bool has_attr_input() const {
- return attr_input != NULL;
- }
-
- // Constructor has pointer AttrInput for polymorphism reasons
- Attribute(
- SimplePath path, ::std::unique_ptr<AttrInput> input, Location locus = Location()) :
- path(::std::move(path)),
- attr_input(::std::move(input)), locus(locus) {}
-
- // Copy constructor must deep copy attr_input as unique pointer
- Attribute(Attribute const& other) : path(other.path), locus(other.locus) {
- // guard to protect from null pointer dereference
- if (other.attr_input != NULL) {
- attr_input = other.attr_input->clone_attr_input();
- }
- }
-
- // default destructor
- ~Attribute() = default;
-
- // overload assignment operator to use custom clone method
- Attribute& operator=(Attribute const& other) {
- path = other.path;
- locus = other.locus;
- // guard to protect from null pointer dereference
- if (other.attr_input != NULL) {
- attr_input = other.attr_input->clone_attr_input();
- }
-
- return *this;
- }
-
- // default move semantics
- Attribute(Attribute&& other) = default;
- Attribute& operator=(Attribute&& other) = default;
-
- // Unique pointer custom clone function
- ::std::unique_ptr<Attribute> clone_attribute() const {
- return ::std::unique_ptr<Attribute>(clone_attribute_impl());
- }
-
- /*~Attribute() {
- delete attr_input;
- }*/
-
- // Creates an empty attribute (which is invalid)
- static Attribute create_empty() {
- return Attribute(SimplePath::create_empty(), NULL);
- }
-
- // Returns whether the attribute is considered an "empty" attribute.
- inline bool is_empty() const {
- return attr_input == NULL && path.is_empty();
- }
-
- /* e.g.:
- #![crate_type = "lib"]
- #[test]
- #[cfg(target_os = "linux")]
- #[allow(non_camel_case_types)]
- #![allow(unused_variables)]
- */
-
- // Full built-in attribute list:
- /* cfg
- * cfg_attr
- * test
- * ignore
- * should_panic
- * derive
- * macro_export
- * macro_use
- * proc_macro
- * proc_macro_derive
- * proc_macro_attribute
- * allow
- * warn
- * deny
- * forbid
- * deprecated
- * must_use
- * link
- * link_name
- * no_link
- * repr
- * crate_type
- * no_main
- * export_name
- * link_section
- * no_mangle
- * used
- * crate_name
- * inline
- * cold
- * no_builtins
- * target_feature
- * doc
- * no_std
- * no_implicit_prelude
- * path
- * recursion_limit
- * type_length_limit
- * panic_handler
- * global_allocator
- * windows_subsystem
- * feature */
-
- ::std::string as_string() const;
-
- // TODO: does this require visitor pattern as not polymorphic?
-
- // Maybe change to const-reference in future
- SimplePath get_path() const {
- return path;
- }
-
- // Call to parse attribute body to meta item syntax.
- void parse_attr_to_meta_item();
-
- // Determines whether cfg predicate is true and item with attribute should not be
- // stripped.
- bool check_cfg_predicate(const Session& session) {
- // assume that cfg predicate actually can exist, i.e. attribute has cfg or cfg_attr
- // path
-
- if (!has_attr_input()) {
- return false;
- }
-
- // TODO: maybe replace with storing a "has been parsed" variable?
- parse_attr_to_meta_item();
- // can't be const because of this anyway
-
- return attr_input->check_cfg_predicate(session);
- }
-
- protected:
- // not virtual as currently no subclasses of Attribute, but could be in future
- /*virtual*/ Attribute* clone_attribute_impl() const {
- return new Attribute(*this);
- }
- };
-
- // Forward decl - defined in rust-macro.h
- class MetaNameValueStr;
-
- // abstract base meta item inner class
- class MetaItemInner {
- protected:
- // pure virtual as MetaItemInner
- virtual MetaItemInner* clone_meta_item_inner_impl() const = 0;
-
- public:
- // Unique pointer custom clone function
- ::std::unique_ptr<MetaItemInner> clone_meta_item_inner() const {
- return ::std::unique_ptr<MetaItemInner>(clone_meta_item_inner_impl());
- }
-
- virtual ~MetaItemInner() {}
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- // HACK: used to simplify parsing - creates a copy of that type, or returns null
- virtual MetaNameValueStr* to_meta_name_value_str() const {
- return NULL;
- }
-
- // HACK: used to simplify parsing - same thing
- virtual SimplePath to_path_item() const {
- return SimplePath::create_empty();
- }
-
- virtual bool check_cfg_predicate(const Session& session) const = 0;
- };
-
- // Container used to store MetaItems as AttrInput (bridge-ish kinda thing)
- class AttrInputMetaItemContainer : public AttrInput {
- ::std::vector< ::std::unique_ptr<MetaItemInner> > items;
-
- public:
- AttrInputMetaItemContainer(::std::vector< ::std::unique_ptr<MetaItemInner> > items) :
- items(::std::move(items)) {}
-
- // copy constructor with vector clone
- AttrInputMetaItemContainer(const AttrInputMetaItemContainer& other) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- items.reserve(other.items.size());
-
- for (const auto& e : other.items) {
- items.push_back(e->clone_meta_item_inner());
- }
- }
-
- // no destructor definition required
-
- // copy assignment operator with vector clone
- AttrInputMetaItemContainer& operator=(const AttrInputMetaItemContainer& other) {
- AttrInput::operator=(other);
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- items.reserve(other.items.size());
-
- for (const auto& e : other.items) {
- items.push_back(e->clone_meta_item_inner());
- }
-
- return *this;
- }
-
- // default move constructors
- AttrInputMetaItemContainer(AttrInputMetaItemContainer&& other) = default;
- AttrInputMetaItemContainer& operator=(AttrInputMetaItemContainer&& other) = default;
-
- ::std::string as_string() const OVERRIDE;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- virtual bool check_cfg_predicate(const Session& session) const OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this type
- virtual AttrInputMetaItemContainer* clone_attr_input_impl() const OVERRIDE {
- return new AttrInputMetaItemContainer(*this);
- }
- };
-
- // abstract base meta item class
- class MetaItem : public MetaItemInner {};
-
- // Forward decl - defined in rust-expr.h
- class MetaItemLitExpr;
-
- // Forward decl - defined in rust-expr.h
- class MetaItemPathLit;
-
- // Forward decl - defined in rust-macro.h
- class MetaItemPath;
-
- // Forward decl - defined in rust-macro.h
- class MetaItemSeq;
-
- // Forward decl - defined in rust-macro.h
- class MetaWord;
-
- // Forward decl - defined in rust-macro.h
- class MetaListPaths;
-
- // Forward decl - defined in rust-macro.h
- struct MetaListNameValueStr;
-
- /* 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:
- // Unique pointer custom clone function
- ::std::unique_ptr<Stmt> clone_stmt() const {
- return ::std::unique_ptr<Stmt>(clone_stmt_impl());
- }
-
- virtual ~Stmt() {}
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- protected:
- // Clone function implementation as pure virtual method
- virtual Stmt* clone_stmt_impl() const = 0;
- };
-
- // Rust "item" AST node (declaration of top-level/module-level allowed stuff)
- class Item : public Stmt {
- ::std::vector<Attribute> outer_attrs;
-
- // TODO: should outer attrs be defined here or in each derived class?
-
- public:
- // Unique pointer custom clone function
- ::std::unique_ptr<Item> clone_item() const {
- return ::std::unique_ptr<Item>(clone_item_impl());
- }
-
- ::std::string as_string() const;
-
- // Adds crate names to the vector passed by reference, if it can (polymorphism).
- virtual void add_crate_name(::std::vector< ::std::string>& names ATTRIBUTE_UNUSED) const {
- }
-
- protected:
- // Constructor
- Item(::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- 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. */
- virtual Item* clone_stmt_impl() const OVERRIDE {
- return clone_item_impl();
- }
- };
-
- // forward decl of ExprWithoutBlock
- class ExprWithoutBlock;
-
- // Base expression AST node - abstract
- class Expr {
- // TODO: move outer attribute data to derived classes?
- ::std::vector<Attribute> outer_attrs;
+// TODO: remove typedefs and make actual types for these
+// typedef int Location;
+// typedef ::std::string SimplePath;
+typedef ::std::string Identifier;
+typedef int TupleIndex;
+
+struct Session;
+
+namespace AST {
+// foward decl: ast visitor
+class ASTVisitor;
+
+// Delimiter types - used in macros and whatever.
+enum DelimType
+{
+ PARENS,
+ SQUARE,
+ CURLY
+};
+
+// Base AST node object - TODO is this really required or useful? Where to draw
+// line?
+/*class Node {
+ public:
+ // Gets node's Location.
+ Location get_locus() const {
+ return loc;
+ }
- public:
- inline const ::std::vector<Attribute>& get_outer_attrs() const {
- return outer_attrs;
- }
-
- // Unique pointer custom clone function
- ::std::unique_ptr<Expr> clone_expr() const {
- return ::std::unique_ptr<Expr>(clone_expr_impl());
- }
-
- /* TODO: public methods that could be useful:
- * - get_type() - returns type of expression. set_type() may also be useful for some?
- * - evaluate() - evaluates expression if constant? can_evaluate()? */
-
- // HACK: downcasting without dynamic_cast (if possible) via polymorphism - overrided in
- // subclasses of ExprWithoutBlock
- virtual ExprWithoutBlock* as_expr_without_block() const {
- // DEBUG
- fprintf(stderr, "clone expr without block returns null and has not been overriden\n");
-
- return NULL;
- }
-
- // TODO: make pure virtual if move out outer attributes to derived classes
- virtual ::std::string as_string() const;
-
- virtual ~Expr() {}
-
- // HACK: slow way of getting location from base expression through virtual methods.
- virtual Location get_locus_slow() const {
- return Location();
- }
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- protected:
- // Constructor
- Expr(::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- outer_attrs(::std::move(outer_attribs)) {}
-
- // Clone function implementation as pure virtual method
- virtual Expr* clone_expr_impl() const = 0;
-
- // TODO: think of less hacky way to implement this kind of thing
- // Sets outer attributes.
- void set_outer_attrs(::std::vector<Attribute> outer_attrs_to_set) {
- outer_attrs = ::std::move(outer_attrs_to_set);
- }
- };
-
- // AST node for an expression without an accompanying block - abstract
- class ExprWithoutBlock : public Expr {
- protected:
- // Constructor
- ExprWithoutBlock(::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- Expr(::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. */
- virtual ExprWithoutBlock* clone_expr_impl() const OVERRIDE {
- return clone_expr_without_block_impl();
- }
-
- public:
- // Unique pointer custom clone function
- ::std::unique_ptr<ExprWithoutBlock> clone_expr_without_block() const {
- return ::std::unique_ptr<ExprWithoutBlock>(clone_expr_without_block_impl());
- }
-
- // downcasting hack from expr to use pratt parsing with parse_expr_without_block
- virtual ExprWithoutBlock* as_expr_without_block() const OVERRIDE {
- // DEBUG
- fprintf(stderr, "about to call the impl for clone expr without block\n");
-
- return clone_expr_without_block_impl();
- }
- };
-
- // HACK: IdentifierExpr, delete when figure out identifier vs expr problem in Pratt parser
- // Alternatively, identifiers could just be represented as single-segment paths
- class IdentifierExpr : public ExprWithoutBlock {
- Identifier ident;
-
- Location locus;
-
- public:
- IdentifierExpr(Identifier ident, Location locus = Location(),
- ::std::vector<Attribute> outer_attrs = ::std::vector<Attribute>()) :
- ExprWithoutBlock(::std::move(outer_attrs)),
- ident(::std::move(ident)), locus(locus) {}
-
- ::std::string as_string() const OVERRIDE {
- return ident;
- }
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Clone method implementation
- virtual IdentifierExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new IdentifierExpr(*this);
- }
- };
-
- // Pattern base AST node
- class Pattern {
- public:
- // Unique pointer custom clone function
- ::std::unique_ptr<Pattern> clone_pattern() const {
- return ::std::unique_ptr<Pattern>(clone_pattern_impl());
- }
-
- // possible virtual methods: is_refutable()
-
- virtual ~Pattern() {}
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 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 AST - abstract
- class Type {
- public:
- // Unique pointer custom clone function
- ::std::unique_ptr<Type> clone_type() const {
- return ::std::unique_ptr<Type>(clone_type_impl());
- }
-
- // virtual destructor
- virtual ~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 NULL;
- }
- // as pointer, shouldn't require definition beforehand, only forward declaration.
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- protected:
- // Clone function implementation as pure virtual method
- virtual Type* clone_type_impl() const = 0;
- };
-
- // A type without parentheses? - abstract
- class TypeNoBounds : public Type {
- public:
- // Unique pointer custom clone function
- ::std::unique_ptr<TypeNoBounds> clone_type_no_bounds() const {
- return ::std::unique_ptr<TypeNoBounds>(clone_type_no_bounds_impl());
- }
-
- protected:
- // 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. */
- virtual 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:
- virtual ~TypeParamBound() {}
-
- // Unique pointer custom clone function
- ::std::unique_ptr<TypeParamBound> clone_type_param_bound() const {
- return ::std::unique_ptr<TypeParamBound>(clone_type_param_bound_impl());
- }
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 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 {
- public:
- enum LifetimeType {
- NAMED, // corresponds to LIFETIME_OR_LABEL
- STATIC, // corresponds to 'static
- WILDCARD // corresponds to '_
- };
-
- private:
- LifetimeType lifetime_type;
-
- // TODO: LIFETIME_OR_LABEL (aka lifetime token) is only field
- // find way of enclosing token or something
- ::std::string lifetime_name;
- // only applies for NAMED lifetime_type
-
- Location locus;
-
- public:
- // Constructor
- Lifetime(
- LifetimeType type, ::std::string name = ::std::string(), Location locus = Location()) :
- lifetime_type(type),
- lifetime_name(::std::move(name)), locus(locus) {}
-
- // Creates an "error" lifetime.
- static Lifetime error() {
- return Lifetime(NAMED, ::std::string(""));
- }
-
- // Returns true if the lifetime is in an error state.
- inline bool is_error() const {
- return lifetime_type == NAMED && lifetime_name.empty();
- }
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual Lifetime* clone_type_param_bound_impl() const OVERRIDE {
- return new Lifetime(*this);
- }
- };
-
- // Base generic parameter in AST. Abstract - can be represented by a Lifetime or Type param
- class GenericParam {
- public:
- virtual ~GenericParam() {}
-
- // Unique pointer custom clone function
- ::std::unique_ptr<GenericParam> clone_generic_param() const {
- return ::std::unique_ptr<GenericParam>(clone_generic_param_impl());
- }
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- protected:
- // Clone function implementation as pure virtual method
- virtual GenericParam* clone_generic_param_impl() const = 0;
- };
-
- // 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> lifetime_bounds; // inlined LifetimeBounds
-
- // bool has_outer_attribute;
- //::std::unique_ptr<Attribute> outer_attr;
- Attribute outer_attr;
-
- Location locus;
-
- public:
- // Returns whether the lifetime param has any lifetime bounds.
- inline bool has_lifetime_bounds() const {
- return !lifetime_bounds.empty();
- }
-
- // Returns whether the lifetime param has an outer attribute.
- inline bool has_outer_attribute() const {
- return !outer_attr.is_empty();
- }
-
- // Creates an error state lifetime param.
- static LifetimeParam create_error() {
- return LifetimeParam(Lifetime::error());
- }
-
- // Returns whether the lifetime param is in an error state.
- inline bool is_error() const {
- return lifetime.is_error();
- }
-
- // Constructor
- LifetimeParam(Lifetime lifetime, Location locus = Location(),
- ::std::vector<Lifetime> lifetime_bounds = ::std::vector<Lifetime>(),
- Attribute outer_attr = Attribute::create_empty()) :
- 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) :
- lifetime(other.lifetime), lifetime_bounds(other.lifetime_bounds),
- outer_attr(other.outer_attr), locus(other.locus) {}
-
- // Destructor - define here if required
-
- // 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;
-
- return *this;
- }
-
- // move constructors
- LifetimeParam(LifetimeParam&& other) = default;
- LifetimeParam& operator=(LifetimeParam&& other) = default;
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual LifetimeParam* clone_generic_param_impl() const OVERRIDE {
- return new LifetimeParam(*this);
- }
- };
-
- // A macro item AST node - potentially abstract base class
- class MacroItem : public Item {
- /*public:
- ::std::string as_string() const;*/
- protected:
- MacroItem(::std::vector<Attribute> outer_attribs) : Item(::std::move(outer_attribs)) {}
- };
-
- // Item used in trait declarations - abstract base class
- class TraitItem {
- // bool has_outer_attrs;
- // TODO: remove and rely on virtual functions and VisItem-derived attributes?
- //::std::vector<Attribute> outer_attrs;
-
- // NOTE: all children should have outer attributes
-
- protected:
- // Constructor
- /*TraitItem(::std::vector<Attribute> outer_attrs = ::std::vector<Attribute>()) :
- outer_attrs(::std::move(outer_attrs)) {}*/
-
- // Clone function implementation as pure virtual method
- virtual TraitItem* clone_trait_item_impl() const = 0;
-
- public:
- virtual ~TraitItem() {}
-
- // Returns whether TraitItem has outer attributes.
- /*inline bool has_outer_attrs() const {
- return !outer_attrs.empty();
- }*/
-
- // Unique pointer custom clone function
- ::std::unique_ptr<TraitItem> clone_trait_item() const {
- return ::std::unique_ptr<TraitItem>(clone_trait_item_impl());
- }
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
- };
-
- // Abstract base class for items used within an inherent impl block (the impl name {} one)
- class InherentImplItem {
- protected:
- // Clone function implementation as pure virtual method
- virtual InherentImplItem* clone_inherent_impl_item_impl() const = 0;
-
- public:
- virtual ~InherentImplItem() {}
-
- // Unique pointer custom clone function
- ::std::unique_ptr<InherentImplItem> clone_inherent_impl_item() const {
- return ::std::unique_ptr<InherentImplItem>(clone_inherent_impl_item_impl());
- }
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
- };
-
- // Abstract base class for items used in a trait impl
- class TraitImplItem {
- protected:
- virtual TraitImplItem* clone_trait_impl_item_impl() const = 0;
-
- public:
- virtual ~TraitImplItem(){};
-
- // Unique pointer custom clone function
- ::std::unique_ptr<TraitImplItem> clone_trait_impl_item() const {
- return ::std::unique_ptr<TraitImplItem>(clone_trait_impl_item_impl());
- }
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
- };
-
- // A macro invocation item (or statement) AST node (i.e. semi-coloned macro invocation)
- class MacroInvocationSemi
- : public MacroItem
- , public TraitItem
- , public InherentImplItem
- , public TraitImplItem
- /*, public Statement*/ {
- // already inherits from statement indirectly via item as item is a subclass of statement
- SimplePath path;
- // all delim types except curly must have invocation end with a semicolon
- DelimType delim_type;
- //::std::vector<TokenTree> token_trees;
- ::std::vector< ::std::unique_ptr<TokenTree> > token_trees;
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- MacroInvocationSemi(SimplePath macro_path, DelimType delim_type,
- ::std::vector< ::std::unique_ptr<TokenTree> > token_trees,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- MacroItem(::std::move(outer_attribs)),
- path(::std::move(macro_path)), delim_type(delim_type),
- token_trees(::std::move(token_trees)), locus(locus) {}
- /* TODO: possible issue with Item and TraitItem hierarchies both having outer attributes
- * - storage inefficiency at least.
- * Best current idea is to make Item preferred and have TraitItem get virtual functions
- * for attributes or something.
- * Or just redo the "composition" approach, but then this prevents polymorphism and would
- * entail redoing quite a bit of the parser. */
-
- // Copy constructor with vector clone
- MacroInvocationSemi(MacroInvocationSemi const& other) :
- MacroItem(other), TraitItem(other), InherentImplItem(other), TraitImplItem(other),
- path(other.path), delim_type(other.delim_type), locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- token_trees.reserve(other.token_trees.size());
-
- for (const auto& e : other.token_trees) {
- token_trees.push_back(e->clone_token_tree());
- }
- }
-
- // Overloaded assignment operator to vector clone
- MacroInvocationSemi& operator=(MacroInvocationSemi const& other) {
- MacroItem::operator=(other);
- TraitItem::operator=(other);
- InherentImplItem::operator=(other);
- TraitImplItem::operator=(other);
- path = other.path;
- delim_type = other.delim_type;
- locus = other.locus;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- token_trees.reserve(other.token_trees.size());
-
- for (const auto& e : other.token_trees) {
- token_trees.push_back(e->clone_token_tree());
- }
-
- return *this;
- }
-
- // Move constructors
- MacroInvocationSemi(MacroInvocationSemi&& other) = default;
- MacroInvocationSemi& operator=(MacroInvocationSemi&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual MacroInvocationSemi* clone_item_impl() const OVERRIDE {
- return new MacroInvocationSemi(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual MacroInvocationSemi* clone_inherent_impl_item_impl() const OVERRIDE {
- return new MacroInvocationSemi(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual MacroInvocationSemi* clone_trait_impl_item_impl() const OVERRIDE {
- return new MacroInvocationSemi(*this);
- }
-
- // FIXME: remove if item impl virtual override works properly
- // Use covariance to implement clone function as returning this object rather than base
- /*virtual MacroInvocationSemi* clone_statement_impl() const OVERRIDE {
- return new MacroInvocationSemi(*this);
- }*/
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual MacroInvocationSemi* clone_trait_item_impl() const OVERRIDE {
- return new MacroInvocationSemi(*this);
- }
- };
-
- // A crate AST object - holds all the data for a single compilation unit
- struct Crate {
- bool has_utf8bom;
- bool has_shebang;
-
- ::std::vector<Attribute> inner_attrs;
- //::std::vector<Item> items;
- // dodgy spacing required here
- // TODO: is it better to have a vector of items here or a module (implicit top-level one)?
- ::std::vector< ::std::unique_ptr<Item> > items;
-
- public:
- // Constructor
- Crate(::std::vector< ::std::unique_ptr<Item> > items,
- ::std::vector<Attribute> inner_attrs, bool has_utf8bom = false,
- bool has_shebang = false) :
- has_utf8bom(has_utf8bom),
- has_shebang(has_shebang), inner_attrs(::std::move(inner_attrs)),
- items(::std::move(items)) {}
-
- // Copy constructor with vector clone
- Crate(Crate const& other) :
- has_utf8bom(other.has_utf8bom), has_shebang(other.has_shebang),
- inner_attrs(other.inner_attrs) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- 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;
- has_shebang = other.has_shebang;
- has_utf8bom = other.has_utf8bom;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- 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;
- };
-
- // Base path expression AST node - abstract
- class PathExpr : public ExprWithoutBlock {
- protected:
- PathExpr(::std::vector<Attribute> outer_attribs) :
- ExprWithoutBlock(::std::move(outer_attribs)) {}
-
- public:
- // TODO: think of a better and less hacky way to allow this
-
- // Replaces the outer attributes of this path expression with the given outer attributes.
- void replace_outer_attrs(::std::vector<Attribute> outer_attrs) {
- set_outer_attrs(::std::move(outer_attrs));
- }
- };
+ // Sets node's Location.
+ void set_locus(Location loc_) {
+ loc = loc_;
}
-}
+
+ // Get node output as a string. Pure virtual.
+ virtual ::std::string as_string() const = 0;
+
+ virtual ~Node() {}
+
+ // TODO: constructor including Location? Make all derived classes have
+Location?
+
+ private:
+ // The node's location.
+ Location loc;
+};*/
+// decided to not have node as a "node" would never need to be stored
+
+// Attribute body - abstract base class
+class AttrInput
+{
+public:
+ virtual ~AttrInput () {}
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<AttrInput> clone_attr_input () const
+ {
+ return ::std::unique_ptr<AttrInput> (clone_attr_input_impl ());
+ }
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+ virtual bool check_cfg_predicate (const Session &session) const = 0;
+
+ // Parse attribute input to meta item, if possible
+ virtual AttrInput *parse_to_meta_item () const { return NULL; }
+
+protected:
+ // pure virtual clone implementation
+ virtual AttrInput *clone_attr_input_impl () const = 0;
+};
+
+// forward decl for use in token tree method
+class Token;
+
+// A tree of tokens (or a single token) - abstract base class
+class TokenTree
+{
+public:
+ virtual ~TokenTree () {}
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<TokenTree> clone_token_tree () const
+ {
+ return ::std::unique_ptr<TokenTree> (clone_token_tree_impl ());
+ }
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+ /* Converts token tree to a flat token stream. Tokens must be pointer to avoid
+ * mutual dependency with Token. */
+ virtual ::std::vector< ::std::unique_ptr<Token> >
+ to_token_stream () const = 0;
+
+protected:
+ // pure virtual clone implementation
+ virtual TokenTree *clone_token_tree_impl () const = 0;
+};
+
+// Abstract base class for a macro match
+class MacroMatch
+{
+public:
+ virtual ~MacroMatch () {}
+
+ virtual ::std::string as_string () const = 0;
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<MacroMatch> clone_macro_match () const
+ {
+ return ::std::unique_ptr<MacroMatch> (clone_macro_match_impl ());
+ }
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+protected:
+ // pure virtual clone implementation
+ virtual MacroMatch *clone_macro_match_impl () const = 0;
+};
+
+// A token is a kind of token tree (except delimiter tokens)
+class Token : public TokenTree, public MacroMatch
+{
+ // A token is a kind of token tree (except delimiter tokens)
+ // A token is a kind of MacroMatch (except $ and delimiter tokens)
+ // TODO: improve member variables - current ones are the same as lexer token
+ // Token kind.
+ TokenId token_id;
+ // Token location.
+ Location locus;
+ // Associated text (if any) of token.
+ std::string str;
+ // Token type hint (if any).
+ PrimitiveCoreType type_hint;
+
+public:
+ // Unique pointer custom clone function
+ ::std::unique_ptr<Token> clone_token () const
+ {
+ return ::std::unique_ptr<Token> (clone_token_impl ());
+ }
+
+ // constructor from general text - avoid using if lexer const_TokenPtr is
+ // available
+ Token (TokenId token_id, Location locus, ::std::string str,
+ PrimitiveCoreType type_hint)
+ : token_id (token_id), locus (locus), str (::std::move (str)),
+ type_hint (type_hint)
+ {}
+
+ // Constructor from lexer const_TokenPtr
+ /* TODO: find workaround for std::string being NULL - probably have to
+ * introduce new method in lexer Token, or maybe make conversion method
+ * there*/
+ Token (const_TokenPtr lexer_token_ptr)
+ : token_id (lexer_token_ptr->get_id ()),
+ locus (lexer_token_ptr->get_locus ()), str (""),
+ type_hint (lexer_token_ptr->get_type_hint ())
+ {
+ // FIXME: change to "should have str" later?
+ if (lexer_token_ptr->has_str ())
+ {
+ str = lexer_token_ptr->get_str ();
+
+ // DEBUG
+ fprintf (stderr, "ast token created with str '%s'\n", str.c_str ());
+ }
+ else
+ {
+ // FIXME: is this returning correct thing?
+ str = lexer_token_ptr->get_token_description ();
+
+ // DEBUG
+ fprintf (stderr, "ast token created with string '%s'\n", str.c_str ());
+ }
+
+ // DEBUG
+ if (lexer_token_ptr->should_have_str () && !lexer_token_ptr->has_str ())
+ {
+ fprintf (stderr,
+ "BAD: for token '%s', should have string but does not!\n",
+ lexer_token_ptr->get_token_description ());
+ }
+ }
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ // Return copy of itself but in token stream form.
+ virtual ::std::vector< ::std::unique_ptr<Token> >
+ to_token_stream () const OVERRIDE;
+
+ TokenId get_id () const { return token_id; }
+
+ Location get_locus () const { return locus; }
+
+protected:
+ // No virtual for now as not polymorphic but can be in future
+ /*virtual*/ Token *clone_token_impl () const { return new Token (*this); }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual Token *clone_token_tree_impl () const OVERRIDE
+ {
+ return new Token (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual Token *clone_macro_match_impl () const OVERRIDE
+ {
+ return new Token (*this);
+ }
+};
+
+// A literal - value with a type. Used in LiteralExpr and LiteralPattern.
+struct Literal
+{
+public:
+ enum LitType
+ {
+ CHAR,
+ STRING,
+ RAW_STRING,
+ BYTE,
+ BYTE_STRING,
+ RAW_BYTE_STRING,
+ INT,
+ FLOAT,
+ BOOL
+ };
+
+private:
+ // TODO: maybe make subclasses of each type of literal with their typed values
+ // (or generics)
+ ::std::string value_as_string;
+ LitType type;
+
+public:
+ ::std::string as_string () const { return value_as_string; }
+
+ inline LitType get_lit_type () const { return type; }
+
+ Literal (::std::string value_as_string, LitType type)
+ : value_as_string (::std::move (value_as_string)), type (type)
+ {}
+
+ static Literal create_error () { return Literal ("", CHAR); }
+
+ // Returns whether literal is in an invalid state.
+ bool is_error () const { return value_as_string == ""; }
+};
+
+// A token tree with delimiters
+class DelimTokenTree : public TokenTree, public AttrInput
+{
+ DelimType delim_type;
+ ::std::vector< ::std::unique_ptr<TokenTree> > token_trees;
+
+ Location locus;
+
+ // TODO: move all the "parse" functions into a separate class that has the
+ // token stream reference - will be cleaner Parse a meta item inner.
+ //::std::unique_ptr<MetaItemInner> parse_meta_item_inner(const ::std::vector<
+ //::std::unique_ptr<Token> >& token_stream, int& i) const; SimplePath
+ // parse_simple_path(const ::std::vector< ::std::unique_ptr<Token> >&
+ // token_stream, int& i) const; SimplePathSegment
+ // parse_simple_path_segment(const ::std::vector<
+ // ::std::unique_ptr<Token> >& token_stream, int& i) const;
+ //::std::unique_ptr<MetaItemLitExpr> parse_meta_item_lit(const
+ //::std::unique_ptr<Token>&
+ // tok) const;
+ //::std::vector< ::std::unique_ptr<MetaItemInner> > parse_meta_item_seq(const
+ //::std::vector< ::std::unique_ptr<Token> >& token_stream, int& i) const;
+ //Literal
+ // parse_literal(const ::std::unique_ptr<Token>& tok) const;
+ //::std::unique_ptr<MetaItem> parse_path_meta_item(const ::std::vector<
+ //::std::unique_ptr<Token> >& token_stream, int& i) const; bool
+ // is_end_meta_item_tok(TokenId tok) const;
+
+protected:
+ // Use covariance to implement clone function as returning a DelimTokenTree
+ // object
+ virtual DelimTokenTree *clone_attr_input_impl () const OVERRIDE
+ {
+ return new DelimTokenTree (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual DelimTokenTree *clone_token_tree_impl () const OVERRIDE
+ {
+ return new DelimTokenTree (*this);
+ }
+
+public:
+ DelimTokenTree (DelimType delim_type,
+ ::std::vector< ::std::unique_ptr<TokenTree> > token_trees
+ = ::std::vector< ::std::unique_ptr<TokenTree> > (),
+ Location locus = Location ())
+ : delim_type (delim_type), token_trees (::std::move (token_trees)),
+ locus (locus)
+ {}
+
+ // Copy constructor with vector clone
+ DelimTokenTree (DelimTokenTree const &other)
+ : delim_type (other.delim_type), locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ token_trees.reserve (other.token_trees.size ());
+
+ for (const auto &e : other.token_trees)
+ {
+ token_trees.push_back (e->clone_token_tree ());
+ }
+ }
+
+ // overloaded assignment operator with vector clone
+ DelimTokenTree &operator= (DelimTokenTree const &other)
+ {
+ delim_type = other.delim_type;
+ locus = other.locus;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ token_trees.reserve (other.token_trees.size ());
+
+ for (const auto &e : other.token_trees)
+ {
+ token_trees.push_back (e->clone_token_tree ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ DelimTokenTree (DelimTokenTree &&other) = default;
+ DelimTokenTree &operator= (DelimTokenTree &&other) = default;
+
+ static DelimTokenTree create_empty () { return DelimTokenTree (PARENS); }
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ virtual bool
+ check_cfg_predicate (const Session &session ATTRIBUTE_UNUSED) const OVERRIDE
+ {
+ // this should never be called - should be converted first
+ return false;
+ }
+
+ virtual AttrInput *parse_to_meta_item () const OVERRIDE;
+
+ virtual ::std::vector< ::std::unique_ptr<Token> >
+ to_token_stream () const OVERRIDE;
+};
+
+// Forward decl - definition moved to rust-expr.h as it requires LiteralExpr to
+// be defined
+class AttrInputLiteral;
+
+// TODO: move applicable stuff into here or just don't include it because
+// nothing uses it A segment of a path (maybe)
+class PathSegment
+{
+public:
+ virtual ~PathSegment () {}
+
+ virtual ::std::string as_string () const = 0;
+
+ // TODO: add visitor here?
+};
+
+// A segment of a simple path without generic or type arguments
+class SimplePathSegment : public PathSegment
+{
+ ::std::string segment_name;
+ Location locus;
+
+ // only allow identifiers, "super", "self", "crate", or "$crate"
+public:
+ // TODO: put checks in constructor to enforce this rule?
+ SimplePathSegment (::std::string segment_name, Location locus = Location ())
+ : segment_name (::std::move (segment_name)), locus (locus)
+ {}
+
+ // Returns whether simple path segment is in an invalid state (currently, if
+ // empty).
+ inline bool is_error () const { return segment_name.empty (); }
+
+ // Creates an error SimplePathSegment
+ static SimplePathSegment create_error ()
+ {
+ return SimplePathSegment (::std::string (""));
+ }
+
+ ::std::string as_string () const;
+
+ inline Location get_locus () const { return locus; }
+
+ // TODO: visitor pattern?
+};
+
+// A simple path without generic or type arguments
+class SimplePath
+{
+ bool has_opening_scope_resolution;
+ ::std::vector<SimplePathSegment> segments;
+ Location locus;
+
+public:
+ // Constructor
+ SimplePath (::std::vector<SimplePathSegment> path_segments,
+ bool has_opening_scope_resolution = false,
+ Location locus = Location ())
+ : has_opening_scope_resolution (has_opening_scope_resolution),
+ segments (::std::move (path_segments)), locus (locus)
+ {}
+
+ // Creates an empty SimplePath.
+ static SimplePath create_empty ()
+ {
+ return SimplePath (::std::vector<SimplePathSegment> ());
+ }
+
+ // Returns whether the SimplePath is empty, i.e. has path segments.
+ inline bool is_empty () const { return segments.empty (); }
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ // does this need visitor if not polymorphic? probably not
+
+ // path-to-string comparison operator
+ bool operator== (const ::std::string &rhs)
+ {
+ return !has_opening_scope_resolution && segments.size () == 1
+ && segments[0].as_string () == rhs;
+ }
+
+ /* Creates a single-segment SimplePath from a string. This will not check to
+ * ensure that this is a valid identifier in path, so be careful. Also, this
+ * will have no location data.
+ * TODO have checks? */
+ static SimplePath from_str (::std::string str)
+ {
+ ::std::vector<AST::SimplePathSegment> single_segments
+ = {AST::SimplePathSegment (::std::move (str))};
+ return SimplePath (::std::move (single_segments));
+ }
+};
+
+// aka Attr
+// Attribute AST representation
+struct Attribute
+{
+private:
+ SimplePath path;
+
+ // bool has_attr_input;
+ // AttrInput* attr_input;
+ ::std::unique_ptr<AttrInput> attr_input;
+
+ Location locus;
+
+ // TODO: maybe a variable storing whether attr input is parsed or not
+
+public:
+ // Returns whether Attribute has AttrInput
+ inline bool has_attr_input () const { return attr_input != NULL; }
+
+ // Constructor has pointer AttrInput for polymorphism reasons
+ Attribute (SimplePath path, ::std::unique_ptr<AttrInput> input,
+ Location locus = Location ())
+ : path (::std::move (path)), attr_input (::std::move (input)), locus (locus)
+ {}
+
+ // Copy constructor must deep copy attr_input as unique pointer
+ Attribute (Attribute const &other) : path (other.path), locus (other.locus)
+ {
+ // guard to protect from null pointer dereference
+ if (other.attr_input != NULL)
+ {
+ attr_input = other.attr_input->clone_attr_input ();
+ }
+ }
+
+ // default destructor
+ ~Attribute () = default;
+
+ // overload assignment operator to use custom clone method
+ Attribute &operator= (Attribute const &other)
+ {
+ path = other.path;
+ locus = other.locus;
+ // guard to protect from null pointer dereference
+ if (other.attr_input != NULL)
+ {
+ attr_input = other.attr_input->clone_attr_input ();
+ }
+
+ return *this;
+ }
+
+ // default move semantics
+ Attribute (Attribute &&other) = default;
+ Attribute &operator= (Attribute &&other) = default;
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<Attribute> clone_attribute () const
+ {
+ return ::std::unique_ptr<Attribute> (clone_attribute_impl ());
+ }
+
+ /*~Attribute() {
+ delete attr_input;
+ }*/
+
+ // Creates an empty attribute (which is invalid)
+ static Attribute create_empty ()
+ {
+ return Attribute (SimplePath::create_empty (), NULL);
+ }
+
+ // Returns whether the attribute is considered an "empty" attribute.
+ inline bool is_empty () const
+ {
+ return attr_input == NULL && path.is_empty ();
+ }
+
+ /* e.g.:
+ #![crate_type = "lib"]
+ #[test]
+ #[cfg(target_os = "linux")]
+ #[allow(non_camel_case_types)]
+ #![allow(unused_variables)]
+ */
+
+ // Full built-in attribute list:
+ /* cfg
+ * cfg_attr
+ * test
+ * ignore
+ * should_panic
+ * derive
+ * macro_export
+ * macro_use
+ * proc_macro
+ * proc_macro_derive
+ * proc_macro_attribute
+ * allow
+ * warn
+ * deny
+ * forbid
+ * deprecated
+ * must_use
+ * link
+ * link_name
+ * no_link
+ * repr
+ * crate_type
+ * no_main
+ * export_name
+ * link_section
+ * no_mangle
+ * used
+ * crate_name
+ * inline
+ * cold
+ * no_builtins
+ * target_feature
+ * doc
+ * no_std
+ * no_implicit_prelude
+ * path
+ * recursion_limit
+ * type_length_limit
+ * panic_handler
+ * global_allocator
+ * windows_subsystem
+ * feature */
+
+ ::std::string as_string () const;
+
+ // TODO: does this require visitor pattern as not polymorphic?
+
+ // Maybe change to const-reference in future
+ SimplePath get_path () const { return path; }
+
+ // Call to parse attribute body to meta item syntax.
+ void parse_attr_to_meta_item ();
+
+ // Determines whether cfg predicate is true and item with attribute should not
+ // be stripped.
+ bool check_cfg_predicate (const Session &session)
+ {
+ // assume that cfg predicate actually can exist, i.e. attribute has cfg or
+ // cfg_attr path
+
+ if (!has_attr_input ())
+ {
+ return false;
+ }
+
+ // TODO: maybe replace with storing a "has been parsed" variable?
+ parse_attr_to_meta_item ();
+ // can't be const because of this anyway
+
+ return attr_input->check_cfg_predicate (session);
+ }
+
+protected:
+ // not virtual as currently no subclasses of Attribute, but could be in future
+ /*virtual*/ Attribute *clone_attribute_impl () const
+ {
+ return new Attribute (*this);
+ }
+};
+
+// Forward decl - defined in rust-macro.h
+class MetaNameValueStr;
+
+// abstract base meta item inner class
+class MetaItemInner
+{
+protected:
+ // pure virtual as MetaItemInner
+ virtual MetaItemInner *clone_meta_item_inner_impl () const = 0;
+
+public:
+ // Unique pointer custom clone function
+ ::std::unique_ptr<MetaItemInner> clone_meta_item_inner () const
+ {
+ return ::std::unique_ptr<MetaItemInner> (clone_meta_item_inner_impl ());
+ }
+
+ virtual ~MetaItemInner () {}
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+ // HACK: used to simplify parsing - creates a copy of that type, or returns
+ // null
+ virtual MetaNameValueStr *to_meta_name_value_str () const { return NULL; }
+
+ // HACK: used to simplify parsing - same thing
+ virtual SimplePath to_path_item () const
+ {
+ return SimplePath::create_empty ();
+ }
+
+ virtual bool check_cfg_predicate (const Session &session) const = 0;
+};
+
+// Container used to store MetaItems as AttrInput (bridge-ish kinda thing)
+class AttrInputMetaItemContainer : public AttrInput
+{
+ ::std::vector< ::std::unique_ptr<MetaItemInner> > items;
+
+public:
+ AttrInputMetaItemContainer (
+ ::std::vector< ::std::unique_ptr<MetaItemInner> > items)
+ : items (::std::move (items))
+ {}
+
+ // copy constructor with vector clone
+ AttrInputMetaItemContainer (const AttrInputMetaItemContainer &other)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ items.reserve (other.items.size ());
+
+ for (const auto &e : other.items)
+ {
+ items.push_back (e->clone_meta_item_inner ());
+ }
+ }
+
+ // no destructor definition required
+
+ // copy assignment operator with vector clone
+ AttrInputMetaItemContainer &
+ operator= (const AttrInputMetaItemContainer &other)
+ {
+ AttrInput::operator= (other);
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ items.reserve (other.items.size ());
+
+ for (const auto &e : other.items)
+ {
+ items.push_back (e->clone_meta_item_inner ());
+ }
+
+ return *this;
+ }
+
+ // default move constructors
+ AttrInputMetaItemContainer (AttrInputMetaItemContainer &&other) = default;
+ AttrInputMetaItemContainer &operator= (AttrInputMetaItemContainer &&other)
+ = default;
+
+ ::std::string as_string () const OVERRIDE;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ virtual bool check_cfg_predicate (const Session &session) const OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this type
+ virtual AttrInputMetaItemContainer *clone_attr_input_impl () const OVERRIDE
+ {
+ return new AttrInputMetaItemContainer (*this);
+ }
+};
+
+// abstract base meta item class
+class MetaItem : public MetaItemInner
+{
+};
+
+// Forward decl - defined in rust-expr.h
+class MetaItemLitExpr;
+
+// Forward decl - defined in rust-expr.h
+class MetaItemPathLit;
+
+// Forward decl - defined in rust-macro.h
+class MetaItemPath;
+
+// Forward decl - defined in rust-macro.h
+class MetaItemSeq;
+
+// Forward decl - defined in rust-macro.h
+class MetaWord;
+
+// Forward decl - defined in rust-macro.h
+class MetaListPaths;
+
+// Forward decl - defined in rust-macro.h
+struct MetaListNameValueStr;
+
+/* 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:
+ // Unique pointer custom clone function
+ ::std::unique_ptr<Stmt> clone_stmt () const
+ {
+ return ::std::unique_ptr<Stmt> (clone_stmt_impl ());
+ }
+
+ virtual ~Stmt () {}
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+protected:
+ // Clone function implementation as pure virtual method
+ virtual Stmt *clone_stmt_impl () const = 0;
+};
+
+// Rust "item" AST node (declaration of top-level/module-level allowed stuff)
+class Item : public Stmt
+{
+ ::std::vector<Attribute> outer_attrs;
+
+ // TODO: should outer attrs be defined here or in each derived class?
+
+public:
+ // Unique pointer custom clone function
+ ::std::unique_ptr<Item> clone_item () const
+ {
+ return ::std::unique_ptr<Item> (clone_item_impl ());
+ }
+
+ ::std::string as_string () const;
+
+ // Adds crate names to the vector passed by reference, if it can
+ // (polymorphism).
+ virtual void
+ add_crate_name (::std::vector< ::std::string> &names ATTRIBUTE_UNUSED) const
+ {}
+
+protected:
+ // Constructor
+ Item (::std::vector<Attribute> outer_attribs = ::std::vector<Attribute> ())
+ : 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. */
+ virtual Item *clone_stmt_impl () const OVERRIDE { return clone_item_impl (); }
+};
+
+// forward decl of ExprWithoutBlock
+class ExprWithoutBlock;
+
+// Base expression AST node - abstract
+class Expr
+{
+ // TODO: move outer attribute data to derived classes?
+ ::std::vector<Attribute> outer_attrs;
+
+public:
+ inline const ::std::vector<Attribute> &get_outer_attrs () const
+ {
+ return outer_attrs;
+ }
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<Expr> clone_expr () const
+ {
+ return ::std::unique_ptr<Expr> (clone_expr_impl ());
+ }
+
+ /* TODO: public methods that could be useful:
+ * - get_type() - returns type of expression. set_type() may also be useful
+ * for some?
+ * - evaluate() - evaluates expression if constant? can_evaluate()? */
+
+ // HACK: downcasting without dynamic_cast (if possible) via polymorphism -
+ // overrided in subclasses of ExprWithoutBlock
+ virtual ExprWithoutBlock *as_expr_without_block () const
+ {
+ // DEBUG
+ fprintf (
+ stderr,
+ "clone expr without block returns null and has not been overriden\n");
+
+ return NULL;
+ }
+
+ // TODO: make pure virtual if move out outer attributes to derived classes
+ virtual ::std::string as_string () const;
+
+ virtual ~Expr () {}
+
+ // HACK: slow way of getting location from base expression through virtual
+ // methods.
+ virtual Location get_locus_slow () const { return Location (); }
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+protected:
+ // Constructor
+ Expr (::std::vector<Attribute> outer_attribs = ::std::vector<Attribute> ())
+ : outer_attrs (::std::move (outer_attribs))
+ {}
+
+ // Clone function implementation as pure virtual method
+ virtual Expr *clone_expr_impl () const = 0;
+
+ // TODO: think of less hacky way to implement this kind of thing
+ // Sets outer attributes.
+ void set_outer_attrs (::std::vector<Attribute> outer_attrs_to_set)
+ {
+ outer_attrs = ::std::move (outer_attrs_to_set);
+ }
+};
+
+// AST node for an expression without an accompanying block - abstract
+class ExprWithoutBlock : public Expr
+{
+protected:
+ // Constructor
+ ExprWithoutBlock (::std::vector<Attribute> outer_attribs
+ = ::std::vector<Attribute> ())
+ : Expr (::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.
+ */
+ virtual ExprWithoutBlock *clone_expr_impl () const OVERRIDE
+ {
+ return clone_expr_without_block_impl ();
+ }
+
+public:
+ // Unique pointer custom clone function
+ ::std::unique_ptr<ExprWithoutBlock> clone_expr_without_block () const
+ {
+ return ::std::unique_ptr<ExprWithoutBlock> (
+ clone_expr_without_block_impl ());
+ }
+
+ // downcasting hack from expr to use pratt parsing with
+ // parse_expr_without_block
+ virtual ExprWithoutBlock *as_expr_without_block () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (stderr, "about to call the impl for clone expr without block\n");
+
+ return clone_expr_without_block_impl ();
+ }
+};
+
+// HACK: IdentifierExpr, delete when figure out identifier vs expr problem in
+// Pratt parser Alternatively, identifiers could just be represented as
+// single-segment paths
+class IdentifierExpr : public ExprWithoutBlock
+{
+ Identifier ident;
+
+ Location locus;
+
+public:
+ IdentifierExpr (Identifier ident, Location locus = Location (),
+ ::std::vector<Attribute> outer_attrs
+ = ::std::vector<Attribute> ())
+ : ExprWithoutBlock (::std::move (outer_attrs)), ident (::std::move (ident)),
+ locus (locus)
+ {}
+
+ ::std::string as_string () const OVERRIDE { return ident; }
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Clone method implementation
+ virtual IdentifierExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new IdentifierExpr (*this);
+ }
+};
+
+// Pattern base AST node
+class Pattern
+{
+public:
+ // Unique pointer custom clone function
+ ::std::unique_ptr<Pattern> clone_pattern () const
+ {
+ return ::std::unique_ptr<Pattern> (clone_pattern_impl ());
+ }
+
+ // possible virtual methods: is_refutable()
+
+ virtual ~Pattern () {}
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 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 AST - abstract
+class Type
+{
+public:
+ // Unique pointer custom clone function
+ ::std::unique_ptr<Type> clone_type () const
+ {
+ return ::std::unique_ptr<Type> (clone_type_impl ());
+ }
+
+ // virtual destructor
+ virtual ~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 NULL;
+ }
+ // as pointer, shouldn't require definition beforehand, only forward
+ // declaration.
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+protected:
+ // Clone function implementation as pure virtual method
+ virtual Type *clone_type_impl () const = 0;
+};
+
+// A type without parentheses? - abstract
+class TypeNoBounds : public Type
+{
+public:
+ // Unique pointer custom clone function
+ ::std::unique_ptr<TypeNoBounds> clone_type_no_bounds () const
+ {
+ return ::std::unique_ptr<TypeNoBounds> (clone_type_no_bounds_impl ());
+ }
+
+protected:
+ // 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. */
+ virtual 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:
+ virtual ~TypeParamBound () {}
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<TypeParamBound> clone_type_param_bound () const
+ {
+ return ::std::unique_ptr<TypeParamBound> (clone_type_param_bound_impl ());
+ }
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 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
+{
+public:
+ enum LifetimeType
+ {
+ NAMED, // corresponds to LIFETIME_OR_LABEL
+ STATIC, // corresponds to 'static
+ WILDCARD // corresponds to '_
+ };
+
+private:
+ LifetimeType lifetime_type;
+
+ // TODO: LIFETIME_OR_LABEL (aka lifetime token) is only field
+ // find way of enclosing token or something
+ ::std::string lifetime_name;
+ // only applies for NAMED lifetime_type
+
+ Location locus;
+
+public:
+ // Constructor
+ Lifetime (LifetimeType type, ::std::string name = ::std::string (),
+ Location locus = Location ())
+ : lifetime_type (type), lifetime_name (::std::move (name)), locus (locus)
+ {}
+
+ // Creates an "error" lifetime.
+ static Lifetime error () { return Lifetime (NAMED, ::std::string ("")); }
+
+ // Returns true if the lifetime is in an error state.
+ inline bool is_error () const
+ {
+ return lifetime_type == NAMED && lifetime_name.empty ();
+ }
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual Lifetime *clone_type_param_bound_impl () const OVERRIDE
+ {
+ return new Lifetime (*this);
+ }
+};
+
+// Base generic parameter in AST. Abstract - can be represented by a Lifetime or
+// Type param
+class GenericParam
+{
+public:
+ virtual ~GenericParam () {}
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<GenericParam> clone_generic_param () const
+ {
+ return ::std::unique_ptr<GenericParam> (clone_generic_param_impl ());
+ }
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+protected:
+ // Clone function implementation as pure virtual method
+ virtual GenericParam *clone_generic_param_impl () const = 0;
+};
+
+// 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> lifetime_bounds; // inlined LifetimeBounds
+
+ // bool has_outer_attribute;
+ //::std::unique_ptr<Attribute> outer_attr;
+ Attribute outer_attr;
+
+ Location locus;
+
+public:
+ // Returns whether the lifetime param has any lifetime bounds.
+ inline bool has_lifetime_bounds () const { return !lifetime_bounds.empty (); }
+
+ // Returns whether the lifetime param has an outer attribute.
+ inline bool has_outer_attribute () const { return !outer_attr.is_empty (); }
+
+ // Creates an error state lifetime param.
+ static LifetimeParam create_error ()
+ {
+ return LifetimeParam (Lifetime::error ());
+ }
+
+ // Returns whether the lifetime param is in an error state.
+ inline bool is_error () const { return lifetime.is_error (); }
+
+ // Constructor
+ LifetimeParam (Lifetime lifetime, Location locus = Location (),
+ ::std::vector<Lifetime> lifetime_bounds
+ = ::std::vector<Lifetime> (),
+ Attribute outer_attr = Attribute::create_empty ())
+ : 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)
+ : lifetime (other.lifetime), lifetime_bounds (other.lifetime_bounds),
+ outer_attr (other.outer_attr), locus (other.locus)
+ {}
+
+ // Destructor - define here if required
+
+ // 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;
+
+ return *this;
+ }
+
+ // move constructors
+ LifetimeParam (LifetimeParam &&other) = default;
+ LifetimeParam &operator= (LifetimeParam &&other) = default;
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual LifetimeParam *clone_generic_param_impl () const OVERRIDE
+ {
+ return new LifetimeParam (*this);
+ }
+};
+
+// A macro item AST node - potentially abstract base class
+class MacroItem : public Item
+{
+ /*public:
+ ::std::string as_string() const;*/
+protected:
+ MacroItem (::std::vector<Attribute> outer_attribs)
+ : Item (::std::move (outer_attribs))
+ {}
+};
+
+// Item used in trait declarations - abstract base class
+class TraitItem
+{
+ // bool has_outer_attrs;
+ // TODO: remove and rely on virtual functions and VisItem-derived attributes?
+ //::std::vector<Attribute> outer_attrs;
+
+ // NOTE: all children should have outer attributes
+
+protected:
+ // Constructor
+ /*TraitItem(::std::vector<Attribute> outer_attrs = ::std::vector<Attribute>())
+ : outer_attrs(::std::move(outer_attrs)) {}*/
+
+ // Clone function implementation as pure virtual method
+ virtual TraitItem *clone_trait_item_impl () const = 0;
+
+public:
+ virtual ~TraitItem () {}
+
+ // Returns whether TraitItem has outer attributes.
+ /*inline bool has_outer_attrs() const {
+ return !outer_attrs.empty();
+ }*/
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<TraitItem> clone_trait_item () const
+ {
+ return ::std::unique_ptr<TraitItem> (clone_trait_item_impl ());
+ }
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+};
+
+// Abstract base class for items used within an inherent impl block (the impl
+// name {} one)
+class InherentImplItem
+{
+protected:
+ // Clone function implementation as pure virtual method
+ virtual InherentImplItem *clone_inherent_impl_item_impl () const = 0;
+
+public:
+ virtual ~InherentImplItem () {}
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<InherentImplItem> clone_inherent_impl_item () const
+ {
+ return ::std::unique_ptr<InherentImplItem> (
+ clone_inherent_impl_item_impl ());
+ }
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+};
+
+// Abstract base class for items used in a trait impl
+class TraitImplItem
+{
+protected:
+ virtual TraitImplItem *clone_trait_impl_item_impl () const = 0;
+
+public:
+ virtual ~TraitImplItem (){};
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<TraitImplItem> clone_trait_impl_item () const
+ {
+ return ::std::unique_ptr<TraitImplItem> (clone_trait_impl_item_impl ());
+ }
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+};
+
+// A macro invocation item (or statement) AST node (i.e. semi-coloned macro
+// invocation)
+class MacroInvocationSemi : public MacroItem,
+ public TraitItem,
+ public InherentImplItem,
+ public TraitImplItem
+/*, public Statement*/ {
+ // already inherits from statement indirectly via item as item is a subclass
+ // of statement
+ SimplePath path;
+ // all delim types except curly must have invocation end with a semicolon
+ DelimType delim_type;
+ //::std::vector<TokenTree> token_trees;
+ ::std::vector< ::std::unique_ptr<TokenTree> > token_trees;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ MacroInvocationSemi (
+ SimplePath macro_path, DelimType delim_type,
+ ::std::vector< ::std::unique_ptr<TokenTree> > token_trees,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : MacroItem (::std::move (outer_attribs)), path (::std::move (macro_path)),
+ delim_type (delim_type), token_trees (::std::move (token_trees)),
+ locus (locus)
+ {}
+ /* TODO: possible issue with Item and TraitItem hierarchies both having outer
+ * attributes
+ * - storage inefficiency at least.
+ * Best current idea is to make Item preferred and have TraitItem get virtual
+ * functions for attributes or something. Or just redo the "composition"
+ * approach, but then this prevents polymorphism and would entail redoing
+ * quite a bit of the parser. */
+
+ // Copy constructor with vector clone
+ MacroInvocationSemi (MacroInvocationSemi const &other)
+ : MacroItem (other), TraitItem (other), InherentImplItem (other),
+ TraitImplItem (other), path (other.path), delim_type (other.delim_type),
+ locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ token_trees.reserve (other.token_trees.size ());
+
+ for (const auto &e : other.token_trees)
+ {
+ token_trees.push_back (e->clone_token_tree ());
+ }
+ }
+
+ // Overloaded assignment operator to vector clone
+ MacroInvocationSemi &operator= (MacroInvocationSemi const &other)
+ {
+ MacroItem::operator= (other);
+ TraitItem::operator= (other);
+ InherentImplItem::operator= (other);
+ TraitImplItem::operator= (other);
+ path = other.path;
+ delim_type = other.delim_type;
+ locus = other.locus;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ token_trees.reserve (other.token_trees.size ());
+
+ for (const auto &e : other.token_trees)
+ {
+ token_trees.push_back (e->clone_token_tree ());
+ }
+
+ return *this;
+ }
+
+ // Move constructors
+ MacroInvocationSemi (MacroInvocationSemi &&other) = default;
+ MacroInvocationSemi &operator= (MacroInvocationSemi &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MacroInvocationSemi *clone_item_impl () const OVERRIDE
+ {
+ return new MacroInvocationSemi (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MacroInvocationSemi *clone_inherent_impl_item_impl () const OVERRIDE
+ {
+ return new MacroInvocationSemi (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MacroInvocationSemi *clone_trait_impl_item_impl () const OVERRIDE
+ {
+ return new MacroInvocationSemi (*this);
+ }
+
+ // FIXME: remove if item impl virtual override works properly
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ /*virtual MacroInvocationSemi* clone_statement_impl() const OVERRIDE {
+ return new MacroInvocationSemi(*this);
+ }*/
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MacroInvocationSemi *clone_trait_item_impl () const OVERRIDE
+ {
+ return new MacroInvocationSemi (*this);
+ }
+};
+
+// A crate AST object - holds all the data for a single compilation unit
+struct Crate
+{
+ bool has_utf8bom;
+ bool has_shebang;
+
+ ::std::vector<Attribute> inner_attrs;
+ //::std::vector<Item> items;
+ // dodgy spacing required here
+ // TODO: is it better to have a vector of items here or a module (implicit
+ // top-level one)?
+ ::std::vector< ::std::unique_ptr<Item> > items;
+
+public:
+ // Constructor
+ Crate (::std::vector< ::std::unique_ptr<Item> > items,
+ ::std::vector<Attribute> inner_attrs, bool has_utf8bom = false,
+ bool has_shebang = false)
+ : has_utf8bom (has_utf8bom), has_shebang (has_shebang),
+ inner_attrs (::std::move (inner_attrs)), items (::std::move (items))
+ {}
+
+ // Copy constructor with vector clone
+ Crate (Crate const &other)
+ : has_utf8bom (other.has_utf8bom), has_shebang (other.has_shebang),
+ inner_attrs (other.inner_attrs)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ 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;
+ has_shebang = other.has_shebang;
+ has_utf8bom = other.has_utf8bom;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ 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;
+};
+
+// Base path expression AST node - abstract
+class PathExpr : public ExprWithoutBlock
+{
+protected:
+ PathExpr (::std::vector<Attribute> outer_attribs)
+ : ExprWithoutBlock (::std::move (outer_attribs))
+ {}
+
+public:
+ // TODO: think of a better and less hacky way to allow this
+
+ // Replaces the outer attributes of this path expression with the given outer
+ // attributes.
+ void replace_outer_attrs (::std::vector<Attribute> outer_attrs)
+ {
+ set_outer_attrs (::std::move (outer_attrs));
+ }
+};
+} // namespace AST
+} // namespace Rust
#endif
diff --git a/gcc/rust/ast/rust-cond-compilation.h b/gcc/rust/ast/rust-cond-compilation.h
index 02353d3..ae6eb0a 100644
--- a/gcc/rust/ast/rust-cond-compilation.h
+++ b/gcc/rust/ast/rust-cond-compilation.h
@@ -5,196 +5,235 @@
#include "rust-ast.h"
namespace Rust {
- namespace AST {
- // Base conditional compilation configuration predicate thing - abstract
- class ConfigurationPredicate {
- public:
- virtual ~ConfigurationPredicate() {}
-
- // Unique pointer custom clone function
- ::std::unique_ptr<ConfigurationPredicate> clone_configuration_predicate() const {
- return ::std::unique_ptr<ConfigurationPredicate>(
- clone_configuration_predicate_impl());
- }
-
- // not sure if I'll use this but here anyway
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- protected:
- // Clone function impl to be overriden in base classes
- virtual ConfigurationPredicate* clone_configuration_predicate_impl() const = 0;
- };
-
- // A configuration option - true if option is set, false if option is not set.
- class ConfigurationOption : public ConfigurationPredicate {
- Identifier option_name;
-
- // bool has_string_literal_option_body;
- ::std::string option_value; // technically a string or raw string literal
-
- public:
- // Returns whether the configuration option has a "value" part of the key-value pair.
- inline bool has_option_value() const {
- return !option_value.empty();
- }
-
- // Key-value pair constructor
- ConfigurationOption(Identifier option_name, ::std::string option_value) :
- option_name(option_name), option_value(option_value) {}
-
- // Name-only constructor
- ConfigurationOption(Identifier option_name) : option_name(option_name) {}
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ConfigurationOption* clone_configuration_predicate_impl() const OVERRIDE {
- return new ConfigurationOption(*this);
- }
- };
-
- // TODO: inline
- struct ConfigurationPredicateList {
- ::std::vector< ::std::unique_ptr<ConfigurationPredicate> > predicate_list;
- };
-
- // Predicate that returns true if all of the supplied predicates return true.
- class ConfigurationAll : public ConfigurationPredicate {
- ::std::vector< ::std::unique_ptr<ConfigurationPredicate> > predicate_list; // inlined form
-
- public:
- ConfigurationAll(
- ::std::vector< ::std::unique_ptr<ConfigurationPredicate> > predicate_list) :
- predicate_list(predicate_list) {}
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ConfigurationAll* clone_configuration_predicate_impl() const OVERRIDE {
- return new ConfigurationAll(*this);
- }
- };
-
- // Predicate that returns true if any of the supplied predicates are true.
- class ConfigurationAny : public ConfigurationPredicate {
- ::std::vector< ::std::unique_ptr<ConfigurationPredicate> > predicate_list; // inlined form
-
- public:
- ConfigurationAny(
- ::std::vector< ::std::unique_ptr<ConfigurationPredicate> > predicate_list) :
- predicate_list(predicate_list) {}
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ConfigurationAny* clone_configuration_predicate_impl() const OVERRIDE {
- return new ConfigurationAny(*this);
- }
- };
-
- // Predicate that produces the negation of a supplied other configuration predicate.
- class ConfigurationNot : public ConfigurationPredicate {
- ::std::unique_ptr<ConfigurationPredicate> config_to_negate;
-
- public:
- ConfigurationNot(ConfigurationPredicate* config_to_negate) :
- config_to_negate(config_to_negate) {}
-
- // Copy constructor with clone
- ConfigurationNot(ConfigurationNot const& other) :
- config_to_negate(other.config_to_negate->clone_configuration_predicate()) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone
- ConfigurationNot& operator=(ConfigurationNot const& other) {
- config_to_negate = other.config_to_negate->clone_configuration_predicate();
-
- return *this;
- }
-
- // move constructors
- ConfigurationNot(ConfigurationNot&& other) = default;
- ConfigurationNot& operator=(ConfigurationNot&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ConfigurationNot* clone_configuration_predicate_impl() const OVERRIDE {
- return new ConfigurationNot(*this);
- }
- };
-
- // TODO: relationship to other attributes?
- class CfgAttribute {
- ::std::unique_ptr<ConfigurationPredicate> config_to_include;
-
- public:
- CfgAttribute(ConfigurationPredicate* config_to_include) :
- config_to_include(config_to_include) {}
-
- // Copy constructor with clone
- CfgAttribute(CfgAttribute const& other) :
- config_to_include(other.config_to_include->clone_configuration_predicate()) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone
- CfgAttribute& operator=(CfgAttribute const& other) {
- config_to_include = other.config_to_include->clone_configuration_predicate();
-
- return *this;
- }
-
- // move constructors
- CfgAttribute(CfgAttribute&& other) = default;
- CfgAttribute& operator=(CfgAttribute&& other) = default;
- };
- /* TODO: ok, best thing to do would be eliminating this class, making Attribute has a
- * "is_cfg()" method, and having attribute path as "cfg" and AttrInput as
- * ConfigurationPredicate (so make ConfigurationPredicate a subclass of AttrInput?). Would
- * need special handling in parser, however. */
-
- // TODO: inline
- struct CfgAttrs {
- ::std::vector<Attribute> cfg_attrs;
- };
-
- // TODO: relationship to other attributes?
- class CfgAttrAttribute {
- ::std::unique_ptr<ConfigurationPredicate> config_to_include;
- ::std::vector<Attribute> cfg_attrs;
-
- public:
- CfgAttrAttribute(
- ConfigurationPredicate* config_to_include, ::std::vector<Attribute> cfg_attrs) :
- config_to_include(config_to_include),
- cfg_attrs(cfg_attrs) {}
-
- // Copy constructor with clone
- CfgAttrAttribute(CfgAttrAttribute const& other) :
- config_to_include(other.config_to_include->clone_configuration_predicate()),
- cfg_attrs(cfg_attrs) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone
- CfgAttrAttribute& operator=(CfgAttrAttribute const& other) {
- config_to_include = other.config_to_include->clone_configuration_predicate();
- cfg_attrs = other.cfg_attrs;
-
- return *this;
- }
-
- // move constructors
- CfgAttrAttribute(CfgAttrAttribute&& other) = default;
- CfgAttrAttribute& operator=(CfgAttrAttribute&& other) = default;
- };
- }
-}
-
-#endif \ No newline at end of file
+namespace AST {
+// Base conditional compilation configuration predicate thing - abstract
+class ConfigurationPredicate
+{
+public:
+ virtual ~ConfigurationPredicate () {}
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<ConfigurationPredicate>
+ clone_configuration_predicate () const
+ {
+ return ::std::unique_ptr<ConfigurationPredicate> (
+ clone_configuration_predicate_impl ());
+ }
+
+ // not sure if I'll use this but here anyway
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+protected:
+ // Clone function impl to be overriden in base classes
+ virtual ConfigurationPredicate *
+ clone_configuration_predicate_impl () const = 0;
+};
+
+// A configuration option - true if option is set, false if option is not set.
+class ConfigurationOption : public ConfigurationPredicate
+{
+ Identifier option_name;
+
+ // bool has_string_literal_option_body;
+ ::std::string option_value; // technically a string or raw string literal
+
+public:
+ // Returns whether the configuration option has a "value" part of the
+ // key-value pair.
+ inline bool has_option_value () const { return !option_value.empty (); }
+
+ // Key-value pair constructor
+ ConfigurationOption (Identifier option_name, ::std::string option_value)
+ : option_name (option_name), option_value (option_value)
+ {}
+
+ // Name-only constructor
+ ConfigurationOption (Identifier option_name) : option_name (option_name) {}
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ConfigurationOption *
+ clone_configuration_predicate_impl () const OVERRIDE
+ {
+ return new ConfigurationOption (*this);
+ }
+};
+
+// TODO: inline
+struct ConfigurationPredicateList
+{
+ ::std::vector< ::std::unique_ptr<ConfigurationPredicate> > predicate_list;
+};
+
+// Predicate that returns true if all of the supplied predicates return true.
+class ConfigurationAll : public ConfigurationPredicate
+{
+ ::std::vector< ::std::unique_ptr<ConfigurationPredicate> >
+ predicate_list; // inlined form
+
+public:
+ ConfigurationAll (
+ ::std::vector< ::std::unique_ptr<ConfigurationPredicate> > predicate_list)
+ : predicate_list (predicate_list)
+ {}
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ConfigurationAll *clone_configuration_predicate_impl () const OVERRIDE
+ {
+ return new ConfigurationAll (*this);
+ }
+};
+
+// Predicate that returns true if any of the supplied predicates are true.
+class ConfigurationAny : public ConfigurationPredicate
+{
+ ::std::vector< ::std::unique_ptr<ConfigurationPredicate> >
+ predicate_list; // inlined form
+
+public:
+ ConfigurationAny (
+ ::std::vector< ::std::unique_ptr<ConfigurationPredicate> > predicate_list)
+ : predicate_list (predicate_list)
+ {}
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ConfigurationAny *clone_configuration_predicate_impl () const OVERRIDE
+ {
+ return new ConfigurationAny (*this);
+ }
+};
+
+// Predicate that produces the negation of a supplied other configuration
+// predicate.
+class ConfigurationNot : public ConfigurationPredicate
+{
+ ::std::unique_ptr<ConfigurationPredicate> config_to_negate;
+
+public:
+ ConfigurationNot (ConfigurationPredicate *config_to_negate)
+ : config_to_negate (config_to_negate)
+ {}
+
+ // Copy constructor with clone
+ ConfigurationNot (ConfigurationNot const &other)
+ : config_to_negate (
+ other.config_to_negate->clone_configuration_predicate ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone
+ ConfigurationNot &operator= (ConfigurationNot const &other)
+ {
+ config_to_negate = other.config_to_negate->clone_configuration_predicate ();
+
+ return *this;
+ }
+
+ // move constructors
+ ConfigurationNot (ConfigurationNot &&other) = default;
+ ConfigurationNot &operator= (ConfigurationNot &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ConfigurationNot *clone_configuration_predicate_impl () const OVERRIDE
+ {
+ return new ConfigurationNot (*this);
+ }
+};
+
+// TODO: relationship to other attributes?
+class CfgAttribute
+{
+ ::std::unique_ptr<ConfigurationPredicate> config_to_include;
+
+public:
+ CfgAttribute (ConfigurationPredicate *config_to_include)
+ : config_to_include (config_to_include)
+ {}
+
+ // Copy constructor with clone
+ CfgAttribute (CfgAttribute const &other)
+ : config_to_include (
+ other.config_to_include->clone_configuration_predicate ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone
+ CfgAttribute &operator= (CfgAttribute const &other)
+ {
+ config_to_include
+ = other.config_to_include->clone_configuration_predicate ();
+
+ return *this;
+ }
+
+ // move constructors
+ CfgAttribute (CfgAttribute &&other) = default;
+ CfgAttribute &operator= (CfgAttribute &&other) = default;
+};
+/* TODO: ok, best thing to do would be eliminating this class, making Attribute
+ * has a "is_cfg()" method, and having attribute path as "cfg" and AttrInput as
+ * ConfigurationPredicate (so make ConfigurationPredicate a subclass of
+ * AttrInput?). Would need special handling in parser, however. */
+
+// TODO: inline
+struct CfgAttrs
+{
+ ::std::vector<Attribute> cfg_attrs;
+};
+
+// TODO: relationship to other attributes?
+class CfgAttrAttribute
+{
+ ::std::unique_ptr<ConfigurationPredicate> config_to_include;
+ ::std::vector<Attribute> cfg_attrs;
+
+public:
+ CfgAttrAttribute (ConfigurationPredicate *config_to_include,
+ ::std::vector<Attribute> cfg_attrs)
+ : config_to_include (config_to_include), cfg_attrs (cfg_attrs)
+ {}
+
+ // Copy constructor with clone
+ CfgAttrAttribute (CfgAttrAttribute const &other)
+ : config_to_include (
+ other.config_to_include->clone_configuration_predicate ()),
+ cfg_attrs (cfg_attrs)
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone
+ CfgAttrAttribute &operator= (CfgAttrAttribute const &other)
+ {
+ config_to_include
+ = other.config_to_include->clone_configuration_predicate ();
+ cfg_attrs = other.cfg_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ CfgAttrAttribute (CfgAttrAttribute &&other) = default;
+ CfgAttrAttribute &operator= (CfgAttrAttribute &&other) = default;
+};
+} // namespace AST
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 992801f..2bc6cf9 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -5,4609 +5,5200 @@
#include "rust-path.h"
namespace Rust {
- namespace AST {
- /* TODO: if GCC moves to C++17 or allows boost, replace some boolean "has_whatever" pairs with
- * optional types (std::optional or boost::optional)? */
-
- // forward decls: defined in rust-path.h, rust-type.h, rust-pattern.h, and rust-stmt.h
- /*class PathInExpression;
- class QualifiedPathInExpression;
- class PathExprSegment;*/ // decls no longer required as "rust-path.h" is included
- /*class Type;
- class TypeNoBounds;
- class Lifetime;
- class Pattern;
- class Statement;*/ // decls no longer required as definitions moved to rust-ast.h
-
- // Decl as definition moved to rust-ast.h
- class ExprWithoutBlock;
-
- // AST node for an expression with an accompanying block - abstract
- class ExprWithBlock : public Expr {
- // TODO: should this mean that a BlockExpr should be a member variable?
- protected:
- ExprWithBlock(::std::vector<Attribute> outer_attrs = ::std::vector<Attribute>()) :
- Expr(::std::move(outer_attrs)) {}
-
- // pure virtual clone implementation
- virtual ExprWithBlock* clone_expr_with_block_impl() const = 0;
-
- // prevent having to define multiple clone expressions
- virtual ExprWithBlock* clone_expr_impl() const OVERRIDE {
- return clone_expr_with_block_impl();
- }
-
- public:
- // Unique pointer custom clone function
- ::std::unique_ptr<ExprWithBlock> clone_expr_with_block() const {
- return ::std::unique_ptr<ExprWithBlock>(clone_expr_with_block_impl());
- }
- };
-
- // Literals? Or literal base?
- class LiteralExpr : public ExprWithoutBlock {
- /*public:
- enum LitType {
- CHAR,
- STRING,
- RAW_STRING,
- BYTE,
- BYTE_STRING,
- RAW_BYTE_STRING,
- INT,
- FLOAT,
- BOOL
- };
-
- private:
- // TODO: maybe make subclasses of each type of literal with their typed values (or
- // generics)
- ::std::string value_as_string;
- LitType type;*/
- // moved to Literal
- Literal literal;
-
- Location locus;
-
- public:
- ::std::string as_string() const {
- return literal.as_string();
- }
-
- inline Literal::LitType get_lit_type() const {
- return literal.get_lit_type();
- }
-
- LiteralExpr(::std::string value_as_string, Literal::LitType type, Location locus,
- ::std::vector<Attribute> outer_attrs = ::std::vector<Attribute>()) :
- ExprWithoutBlock(::std::move(outer_attrs)),
- literal(::std::move(value_as_string), type), locus(locus) {}
-
- LiteralExpr(Literal literal, Location locus,
- ::std::vector<Attribute> outer_attrs = ::std::vector<Attribute>()) :
- ExprWithoutBlock(::std::move(outer_attrs)),
- literal(::std::move(literal)), locus(locus) {}
-
- // Unique pointer custom clone function
- ::std::unique_ptr<LiteralExpr> clone_literal_expr() const {
- return ::std::unique_ptr<LiteralExpr>(clone_literal_expr_impl());
- }
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual LiteralExpr* clone_expr_impl() const OVERRIDE {
- return new LiteralExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual LiteralExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new LiteralExpr(*this);
- }
-
- // not virtual as currently no subclasses of LiteralExpr, but could be in future
- /*virtual*/ LiteralExpr* clone_literal_expr_impl() const {
- return new LiteralExpr(*this);
- }
- };
-
- // Literal expression attribute body (non-macro attribute)
- class AttrInputLiteral : public AttrInput {
- // Literal expression WITHOUT SUFFIX
- // LiteralExpr* literal_expr;
- //::std::unique_ptr<LiteralExpr> literal_expr;
- LiteralExpr literal_expr; // as not using polymorphic behaviour, doesn't require pointer
- // TODO: will require pointer if LiteralExpr is changed to have subclassing
-
- // TODO: should this store location data?
-
- public:
- AttrInputLiteral(LiteralExpr lit_expr) : literal_expr(::std::move(lit_expr)) {}
- /*~AttrInputLiteral() {
- delete literal_expr;
- }*/
-
- ::std::string as_string() const {
- return " = " + literal_expr.as_string();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- // this can never be a cfg predicate - cfg and cfg_attr require a token-tree cfg
- virtual bool check_cfg_predicate(const Session& session ATTRIBUTE_UNUSED) const OVERRIDE {
- // TODO: ensure this is true
- // DEBUG
- fprintf(
- stderr, "check_cfg_predicate call went to AttrInputLiteral - should not happen?\n");
-
- return false;
- }
-
- protected:
- // Use covariance to implement clone function as returning an AttrInputLiteral object
- virtual AttrInputLiteral* clone_attr_input_impl() const OVERRIDE {
- return new AttrInputLiteral(*this);
- }
- };
-
- // literal expr only meta item inner - TODO possibly replace with inheritance of LiteralExpr
- // itself?
- class MetaItemLitExpr : public MetaItemInner {
- LiteralExpr lit_expr;
-
- public:
- MetaItemLitExpr(LiteralExpr lit_expr) : lit_expr(::std::move(lit_expr)) {}
-
- ::std::string as_string() const OVERRIDE {
- return lit_expr.as_string();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- virtual bool check_cfg_predicate(const Session& session) const OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this type
- virtual MetaItemLitExpr* clone_meta_item_inner_impl() const OVERRIDE {
- return new MetaItemLitExpr(*this);
- }
- };
-
- // more generic meta item "path = lit" form
- class MetaItemPathLit : public MetaItem {
- SimplePath path;
- LiteralExpr lit;
-
- public:
- MetaItemPathLit(SimplePath path, LiteralExpr lit_expr) :
- path(::std::move(path)), lit(::std::move(lit_expr)) {}
-
- ::std::string as_string() const OVERRIDE {
- return path.as_string() + " = " + lit.as_string();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- virtual bool check_cfg_predicate(const Session& session) const OVERRIDE;
- // TODO: return true if "ident" is defined and value of it is "lit", return false
- // otherwise
-
- protected:
- // Use covariance to implement clone function as returning this type
- virtual MetaItemPathLit* clone_meta_item_inner_impl() const OVERRIDE {
- return new MetaItemPathLit(*this);
- }
- };
-
- // AST node for a non-qualified path expression - FIXME: should this be inheritance instead?
- /*class PathExprNonQual : public PathExpr {
- PathInExpression path;
-
- public:
- ::std::string as_string() const {
- return path.as_string();
- }
-
- PathExprNonQual(PathInExpression path, ::std::vector<Attribute> outer_attribs) :
- PathExpr(::std::move(outer_attribs)), path(::std::move(path)) {}
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual PathExprNonQual* clone_expr_impl() const OVERRIDE {
- return new PathExprNonQual(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual PathExprNonQual* clone_expr_without_block_impl() const OVERRIDE {
- return new PathExprNonQual(*this);
- }
- };*/
- // converted to inheritance
-
- // AST node for a qualified path expression - FIXME: should this be inheritance instead?
- /*class PathExprQual : public PathExpr {
- QualifiedPathInExpression path;
-
- public:
- ::std::string as_string() const {
- return path.as_string();
- }
-
- PathExprQual(QualifiedPathInExpression path, ::std::vector<Attribute> outer_attribs) :
- PathExpr(::std::move(outer_attribs)), path(::std::move(path)) {}
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual PathExprQual* clone_expr_impl() const OVERRIDE {
- return new PathExprQual(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual PathExprQual* clone_expr_without_block_impl() const OVERRIDE {
- return new PathExprQual(*this);
- }
- };*/
- // replaced with inheritance
-
- // Represents an expression using unary or binary operators as AST node. Can be overloaded.
- class OperatorExpr : public ExprWithoutBlock {
- // TODO: create binary and unary operator subclasses?
-
- Location locus;
-
- protected:
- // Variable must be protected to allow derived classes to use it as a first class citizen
- // Expr* main_or_left_expr;
- ::std::unique_ptr<Expr> main_or_left_expr;
-
- // Constructor (only for initialisation of expr purposes)
- OperatorExpr(::std::unique_ptr<Expr> main_or_left_expr,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- locus(locus), main_or_left_expr(::std::move(main_or_left_expr)) {}
-
- // Copy constructor (only for initialisation of expr purposes)
- OperatorExpr(OperatorExpr const& other) :
- ExprWithoutBlock(other),
- locus(other.locus) /*, main_or_left_expr(other.main_or_left_expr->clone_expr())*/ {
- // DEBUG: moved main_or_left_expr into body - move back later
-
- if (other.main_or_left_expr == NULL) {
- fprintf(stderr, "other operator expr's main_or_left_expr is null!\n");
- }
-
- fprintf(stderr,
- "called operator expr copy constructor - about to clone main_or_left_expr\n");
- main_or_left_expr = other.main_or_left_expr->clone_expr();
- fprintf(stderr, "successfully cloned main_or_left_expr\n");
- // this occurred successfully, so something else must be the issue
- }
-
- // Overload assignment operator to deep copy expr
- OperatorExpr& operator=(OperatorExpr const& other) {
- ExprWithoutBlock::operator=(other);
- main_or_left_expr = other.main_or_left_expr->clone_expr();
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- OperatorExpr(OperatorExpr&& other) = default;
- OperatorExpr& operator=(OperatorExpr&& other) = default;
-
- public:
- /*virtual ~OperatorExpr() {
- delete main_or_left_expr;
- }*/
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
- };
-
- // Unary prefix & or &mut (or && and &&mut) borrow operator. Cannot be overloaded.
- class BorrowExpr : public OperatorExpr {
- bool is_mut;
- bool double_borrow;
-
- public:
- ::std::string as_string() const;
-
- BorrowExpr(::std::unique_ptr<Expr> borrow_lvalue, bool is_mut_borrow,
- bool is_double_borrow, ::std::vector<Attribute> outer_attribs, Location locus) :
- OperatorExpr(::std::move(borrow_lvalue), ::std::move(outer_attribs), locus),
- is_mut(is_mut_borrow), double_borrow(is_double_borrow) {}
-
- // Copy constructor - define here if required
-
- // Destructor - define here if required
-
- // Overload assignment operator here if required
-
- // Move semantics here if required
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual BorrowExpr* clone_expr_impl() const OVERRIDE {
- return new BorrowExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual BorrowExpr* clone_expr_without_block_impl() const OVERRIDE {
- // DEBUG
- fprintf(stderr, "called clone_expr_without_block_impl() on borrowexpr\n");
-
- return new BorrowExpr(*this);
- }
- };
-
- // Unary prefix * deference operator
- class DereferenceExpr : public OperatorExpr {
- public:
- ::std::string as_string() const;
-
- // Constructor calls OperatorExpr's protected constructor
- DereferenceExpr(::std::unique_ptr<Expr> deref_lvalue,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- OperatorExpr(::std::move(deref_lvalue), ::std::move(outer_attribs), locus) {}
-
- // Copy constructor - define here if required
-
- // Destructor - define here if required
-
- // Overload assignment operator here if required
-
- // Move semantics here if required
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual DereferenceExpr* clone_expr_impl() const OVERRIDE {
- return new DereferenceExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual DereferenceExpr* clone_expr_without_block_impl() const OVERRIDE {
- // DEBUG
- fprintf(stderr, "called clone_expr_without_block_impl() on dereferenceexpr\n");
-
- return new DereferenceExpr(*this);
- }
- };
-
- // Unary postfix ? error propogation operator. Cannot be overloaded.
- class ErrorPropagationExpr : public OperatorExpr {
- public:
- ::std::string as_string() const;
-
- // Constructor calls OperatorExpr's protected constructor
- ErrorPropagationExpr(::std::unique_ptr<Expr> potential_error_value,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- OperatorExpr(::std::move(potential_error_value), ::std::move(outer_attribs), locus) {}
-
- // Copy constructor - define here if required
-
- // Destructor - define here if required
-
- // Overload assignment operator here if required
-
- // Move semantics here if required
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ErrorPropagationExpr* clone_expr_impl() const OVERRIDE {
- return new ErrorPropagationExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ErrorPropagationExpr* clone_expr_without_block_impl() const OVERRIDE {
- // DEBUG
- fprintf(stderr, "called clone_expr_without_block_impl() on errorpropagationexpr\n");
-
- return new ErrorPropagationExpr(*this);
- }
- };
-
- // Unary prefix - or ! negation or NOT operators.
- class NegationExpr : public OperatorExpr {
- public:
- enum NegationType { NEGATE, NOT };
-
- private:
- // Note: overload negation via std::ops::Neg and not via std::ops::Not
- // Negation only works for signed integer and floating-point types, NOT only works for
- // boolean and integer types (via bitwise NOT)
- NegationType negation_type;
-
- public:
- ::std::string as_string() const;
-
- inline NegationType get_negation_type() const {
- return negation_type;
- }
-
- // Constructor calls OperatorExpr's protected constructor
- NegationExpr(::std::unique_ptr<Expr> negated_value, NegationType negation_kind,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- OperatorExpr(::std::move(negated_value), ::std::move(outer_attribs), locus),
- negation_type(negation_kind) {}
-
- // Copy constructor - define here if required
-
- // Destructor - define here if required
-
- // Overload assignment operator here if required
-
- // Move semantics here if required
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual NegationExpr* clone_expr_impl() const OVERRIDE {
- return new NegationExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual NegationExpr* clone_expr_without_block_impl() const OVERRIDE {
- // DEBUG
- fprintf(stderr, "called clone_expr_without_block_impl() on negationexpr\n");
-
- return new NegationExpr(*this);
- }
- };
-
- // Infix binary operators. +, -, *, /, %, &, |, ^, <<, >>
- class ArithmeticOrLogicalExpr : public OperatorExpr {
- public:
- enum ExprType {
- ADD, // std::ops::Add
- SUBTRACT, // std::ops::Sub
- MULTIPLY, // std::ops::Mul
- DIVIDE, // std::ops::Div
- MODULUS, // std::ops::Rem
- BITWISE_AND, // std::ops::BitAnd
- BITWISE_OR, // std::ops::BitOr
- BITWISE_XOR, // std::ops::BitXor
- LEFT_SHIFT, // std::ops::Shl
- RIGHT_SHIFT // std::ops::Shr
- };
-
- private:
- // Note: overloading trait specified in comments
- ExprType expr_type;
-
- // Expr* right_expr;
- ::std::unique_ptr<Expr> right_expr;
-
- public:
- /*~ArithmeticOrLogicalExpr() {
- delete right_expr;
- }*/
-
- ::std::string as_string() const;
-
- inline ExprType get_expr_type() const {
- return expr_type;
- }
-
- // Constructor calls OperatorExpr's protected constructor
- ArithmeticOrLogicalExpr(::std::unique_ptr<Expr> left_value,
- ::std::unique_ptr<Expr> right_value, ExprType expr_kind, Location locus) :
- OperatorExpr(::std::move(left_value), ::std::vector<Attribute>(), locus),
- expr_type(expr_kind), right_expr(::std::move(right_value)) {}
- // outer attributes not allowed
-
- // Copy constructor - probably required due to unique pointer
- ArithmeticOrLogicalExpr(ArithmeticOrLogicalExpr const& other) :
- OperatorExpr(other), expr_type(other.expr_type),
- right_expr(other.right_expr->clone_expr()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator
- ArithmeticOrLogicalExpr& operator=(ArithmeticOrLogicalExpr const& other) {
- OperatorExpr::operator=(other);
- // main_or_left_expr = other.main_or_left_expr->clone_expr();
- right_expr = other.right_expr->clone_expr();
- expr_type = other.expr_type;
-
- return *this;
- }
-
- // move constructors
- ArithmeticOrLogicalExpr(ArithmeticOrLogicalExpr&& other) = default;
- ArithmeticOrLogicalExpr& operator=(ArithmeticOrLogicalExpr&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ArithmeticOrLogicalExpr* clone_expr_impl() const OVERRIDE {
- return new ArithmeticOrLogicalExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ArithmeticOrLogicalExpr* clone_expr_without_block_impl() const OVERRIDE {
- // DEBUG
- fprintf(
- stderr, "called clone_expr_without_block_impl() on arithmeticorlogicalexpr\n");
-
- return new ArithmeticOrLogicalExpr(*this);
- }
- };
-
- // Infix binary comparison operators. ==, !=, <, <=, >, >=
- class ComparisonExpr : public OperatorExpr {
- public:
- enum ExprType {
- EQUAL, // std::cmp::PartialEq::eq
- NOT_EQUAL, // std::cmp::PartialEq::ne
- GREATER_THAN, // std::cmp::PartialEq::gt
- LESS_THAN, // std::cmp::PartialEq::lt
- GREATER_OR_EQUAL, // std::cmp::PartialEq::ge
- LESS_OR_EQUAL // std::cmp::PartialEq::le
- };
-
- private:
- // Note: overloading trait specified in comments
- ExprType expr_type;
-
- // Expr* right_expr;
- ::std::unique_ptr<Expr> right_expr;
-
- public:
- /*~ComparisonExpr() {
- delete right_expr;
- }*/
-
- ::std::string as_string() const;
-
- inline ExprType get_expr_type() const {
- return expr_type;
- }
-
- // Constructor requires pointers for polymorphism
- ComparisonExpr(::std::unique_ptr<Expr> left_value, ::std::unique_ptr<Expr> right_value,
- ExprType comparison_kind, Location locus) :
- OperatorExpr(::std::move(left_value), ::std::vector<Attribute>(), locus),
- expr_type(comparison_kind), right_expr(::std::move(right_value)) {}
- // outer attributes not allowed
-
- // Copy constructor also calls OperatorExpr's protected constructor
- ComparisonExpr(ComparisonExpr const& other) :
- OperatorExpr(other), expr_type(other.expr_type),
- right_expr(other.right_expr->clone_expr()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to deep copy
- ComparisonExpr& operator=(ComparisonExpr const& other) {
- OperatorExpr::operator=(other);
- // main_or_left_expr = other.main_or_left_expr->clone_expr();
- right_expr = other.right_expr->clone_expr();
- expr_type = other.expr_type;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- ComparisonExpr(ComparisonExpr&& other) = default;
- ComparisonExpr& operator=(ComparisonExpr&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- // TODO: implement via a function call to std::cmp::PartialEq::eq(&op1, &op2) maybe?
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ComparisonExpr* clone_expr_impl() const OVERRIDE {
- return new ComparisonExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ComparisonExpr* clone_expr_without_block_impl() const OVERRIDE {
- // DEBUG
- fprintf(stderr, "called clone_expr_without_block_impl() on comparisonexpr\n");
-
- return new ComparisonExpr(*this);
- }
- };
-
- // Infix binary lazy boolean logical operators && and ||.
- class LazyBooleanExpr : public OperatorExpr {
- public:
- enum ExprType { LOGICAL_OR, LOGICAL_AND };
-
- private:
- ExprType expr_type;
-
- // Expr* right_expr;
- ::std::unique_ptr<Expr> right_expr;
-
- public:
- /*~LazyBooleanExpr() {
- delete right_expr;
- }*/
-
- // Constructor calls OperatorExpr's protected constructor
- LazyBooleanExpr(::std::unique_ptr<Expr> left_bool_expr,
- ::std::unique_ptr<Expr> right_bool_expr, ExprType expr_kind, Location locus) :
- OperatorExpr(::std::move(left_bool_expr), ::std::vector<Attribute>(), locus),
- expr_type(expr_kind), right_expr(::std::move(right_bool_expr)) {}
- // outer attributes not allowed
-
- // Copy constructor also calls OperatorExpr's protected constructor
- LazyBooleanExpr(LazyBooleanExpr const& other) :
- OperatorExpr(other), expr_type(other.expr_type),
- right_expr(other.right_expr->clone_expr()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to deep copy
- LazyBooleanExpr& operator=(LazyBooleanExpr const& other) {
- OperatorExpr::operator=(other);
- // main_or_left_expr = other.main_or_left_expr->clone_expr();
- right_expr = other.right_expr->clone_expr();
- expr_type = other.expr_type;
-
- return *this;
- }
-
- // move constructors
- LazyBooleanExpr(LazyBooleanExpr&& other) = default;
- LazyBooleanExpr& operator=(LazyBooleanExpr&& other) = default;
-
- ::std::string as_string() const;
-
- inline ExprType get_expr_type() const {
- return expr_type;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual LazyBooleanExpr* clone_expr_impl() const OVERRIDE {
- return new LazyBooleanExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual LazyBooleanExpr* clone_expr_without_block_impl() const OVERRIDE {
- // DEBUG
- fprintf(stderr, "called clone_expr_without_block_impl() on lazybooleanexpr\n");
-
- return new LazyBooleanExpr(*this);
- }
- };
-
- // Binary infix "as" cast expression.
- class TypeCastExpr : public OperatorExpr {
- // TypeNoBounds type_to_convert_to;
- ::std::unique_ptr<TypeNoBounds> type_to_convert_to;
-
- // Note: only certain type casts allowed, outlined in reference
- public:
- ::std::string as_string() const;
-
- // Constructor requires calling protected constructor of OperatorExpr
- TypeCastExpr(::std::unique_ptr<Expr> expr_to_cast,
- ::std::unique_ptr<TypeNoBounds> type_to_cast_to, Location locus) :
- OperatorExpr(::std::move(expr_to_cast), ::std::vector<Attribute>(), locus),
- type_to_convert_to(::std::move(type_to_cast_to)) {}
- // outer attributes not allowed
-
- // Copy constructor also requires calling protected constructor
- TypeCastExpr(TypeCastExpr const& other) :
- OperatorExpr(other),
- type_to_convert_to(other.type_to_convert_to->clone_type_no_bounds()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to deep copy
- TypeCastExpr& operator=(TypeCastExpr const& other) {
- OperatorExpr::operator=(other);
- // main_or_left_expr = other.main_or_left_expr->clone_expr();
- type_to_convert_to = other.type_to_convert_to->clone_type_no_bounds();
-
- return *this;
- }
-
- // move constructors as not supported in c++03
- TypeCastExpr(TypeCastExpr&& other) = default;
- TypeCastExpr& operator=(TypeCastExpr&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TypeCastExpr* clone_expr_impl() const OVERRIDE {
- return new TypeCastExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual TypeCastExpr* clone_expr_without_block_impl() const OVERRIDE {
- // DEBUG
- fprintf(stderr, "called clone_expr_without_block_impl() on typecastexpr\n");
-
- return new TypeCastExpr(*this);
- }
- };
-
- // Binary assignment expression.
- class AssignmentExpr : public OperatorExpr {
- // Expr* right_expr;
- ::std::unique_ptr<Expr> right_expr;
-
- public:
- /*~AssignmentExpr() {
- delete right_expr;
- }*/
-
- ::std::string as_string() const;
-
- // Call OperatorExpr constructor to initialise left_expr
- AssignmentExpr(::std::unique_ptr<Expr> value_to_assign_to,
- ::std::unique_ptr<Expr> value_to_assign, Location locus) :
- OperatorExpr(::std::move(value_to_assign_to), ::std::vector<Attribute>(), locus),
- right_expr(::std::move(value_to_assign)) {}
- // outer attributes not allowed
-
- // Call OperatorExpr constructor in copy constructor, as well as clone
- AssignmentExpr(AssignmentExpr const& other) :
- OperatorExpr(other) /*, right_expr(other.right_expr->clone_expr())*/ {
- // DEBUG: moved cloning right expr into body
- fprintf(stderr,
- "assignment expr copy constructor successfully cloned base operator expr\n");
- if (other.right_expr == NULL) {
- fprintf(stderr, "other expr's right expr (in assignment) is null!!!");
- }
- fprintf(stderr, "test other's right expr as string: %s\n",
- other.right_expr->as_string().c_str());
- // apparently, despite not being null, cloning still fails
- right_expr = other.right_expr->clone_expr();
- fprintf(stderr, "assignment expr copy constructor successfully cloned right expr\n");
-
- // DEBUG
- fprintf(stderr, "assignment expr copy constructor called successfully\n");
- }
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone unique_ptr right_expr
- AssignmentExpr& operator=(AssignmentExpr const& other) {
- OperatorExpr::operator=(other);
- // main_or_left_expr = other.main_or_left_expr->clone_expr();
- right_expr = other.right_expr->clone_expr();
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- AssignmentExpr(AssignmentExpr&& other) = default;
- AssignmentExpr& operator=(AssignmentExpr&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual AssignmentExpr* clone_expr_impl() const OVERRIDE {
- return new AssignmentExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual AssignmentExpr* clone_expr_without_block_impl() const OVERRIDE {
- // DEBUG
- fprintf(stderr, "called clone_expr_without_block_impl() on assignmentexpr\n");
-
- return new AssignmentExpr(*this);
- }
- };
-
- // Binary infix compound assignment (arithmetic or logic then assignment) expressions.
- class CompoundAssignmentExpr : public OperatorExpr {
- public:
- enum ExprType {
- ADD, // std::ops::AddAssign
- SUBTRACT, // std::ops::SubAssign
- MULTIPLY, // std::ops::MulAssign
- DIVIDE, // std::ops::DivAssign
- MODULUS, // std::ops::RemAssign
- BITWISE_AND, // std::ops::BitAndAssign
- BITWISE_OR, // std::ops::BitOrAssign
- BITWISE_XOR, // std::ops::BitXorAssign
- LEFT_SHIFT, // std::ops::ShlAssign
- RIGHT_SHIFT // std::ops::ShrAssign
- };
-
- private:
- // Note: overloading trait specified in comments
- ExprType expr_type;
-
- // Expr* right_expr;
- ::std::unique_ptr<Expr> right_expr;
-
- public:
- /*~CompoundAssignmentExpr() {
- delete right_expr;
- }*/
-
- ::std::string as_string() const;
-
- inline ExprType get_expr_type() const {
- return expr_type;
- }
-
- // Use pointers in constructor to enable polymorphism
- CompoundAssignmentExpr(::std::unique_ptr<Expr> value_to_assign_to,
- ::std::unique_ptr<Expr> value_to_assign, ExprType expr_kind, Location locus) :
- OperatorExpr(::std::move(value_to_assign_to), ::std::vector<Attribute>(), locus),
- expr_type(expr_kind), right_expr(::std::move(value_to_assign)) {}
- // outer attributes not allowed
-
- // Have clone in copy constructor
- CompoundAssignmentExpr(CompoundAssignmentExpr const& other) :
- OperatorExpr(other), expr_type(other.expr_type),
- right_expr(other.right_expr->clone_expr()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone
- CompoundAssignmentExpr& operator=(CompoundAssignmentExpr const& other) {
- OperatorExpr::operator=(other);
- // main_or_left_expr = other.main_or_left_expr->clone_expr();
- right_expr = other.right_expr->clone_expr();
- expr_type = other.expr_type;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- CompoundAssignmentExpr(CompoundAssignmentExpr&& other) = default;
- CompoundAssignmentExpr& operator=(CompoundAssignmentExpr&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual CompoundAssignmentExpr* clone_expr_impl() const OVERRIDE {
- return new CompoundAssignmentExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual CompoundAssignmentExpr* clone_expr_without_block_impl() const OVERRIDE {
- // DEBUG
- fprintf(stderr, "called clone_expr_without_block_impl() on compoundassignmentexpr\n");
-
- return new CompoundAssignmentExpr(*this);
- }
- };
-
- // Expression in parentheses (i.e. like literally just any 3 + (2 * 6))
- class GroupedExpr : public ExprWithoutBlock {
- ::std::vector<Attribute> inner_attrs;
- // Expr* expr_in_parens;
- ::std::unique_ptr<Expr> expr_in_parens;
-
- Location locus;
-
- public:
- /*~GroupedExpr() {
- delete expr_in_parens;
- }*/
-
- ::std::string as_string() const;
-
- inline ::std::vector<Attribute> get_inner_attrs() const {
- return inner_attrs;
- }
-
- GroupedExpr(::std::unique_ptr<Expr> parenthesised_expr,
- ::std::vector<Attribute> inner_attribs, ::std::vector<Attribute> outer_attribs,
- Location locus) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- inner_attrs(::std::move(inner_attribs)),
- expr_in_parens(::std::move(parenthesised_expr)), locus(locus) {}
-
- // Copy constructor includes clone for expr_in_parens
- GroupedExpr(GroupedExpr const& other) :
- ExprWithoutBlock(other), inner_attrs(other.inner_attrs),
- expr_in_parens(other.expr_in_parens->clone_expr()), locus(other.locus) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone expr_in_parens
- GroupedExpr& operator=(GroupedExpr const& other) {
- ExprWithoutBlock::operator=(other);
- inner_attrs = other.inner_attrs;
- expr_in_parens = other.expr_in_parens->clone_expr();
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- GroupedExpr(GroupedExpr&& other) = default;
- GroupedExpr& operator=(GroupedExpr&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual GroupedExpr* clone_expr_impl() const OVERRIDE {
- return new GroupedExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual GroupedExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new GroupedExpr(*this);
- }
- };
-
- // Base array initialisation internal element representation thing (abstract)
- // aka ArrayElements
- class ArrayElems {
- public:
- virtual ~ArrayElems() {}
-
- // Unique pointer custom clone ArrayElems function
- ::std::unique_ptr<ArrayElems> clone_array_elems() const {
- return ::std::unique_ptr<ArrayElems>(clone_array_elems_impl());
- }
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- protected:
- // pure virtual clone implementation
- virtual ArrayElems* clone_array_elems_impl() const = 0;
- };
-
- // Value array elements
- class ArrayElemsValues : public ArrayElems {
- //::std::vector<Expr> values;
- ::std::vector< ::std::unique_ptr<Expr> > values;
-
- // TODO: should this store location data?
-
- public:
- /*inline ::std::vector< ::std::unique_ptr<Expr> > get_values() const {
- return values;
- }*/
-
- ArrayElemsValues(::std::vector< ::std::unique_ptr<Expr> > elems) :
- values(::std::move(elems)) {}
-
- // copy constructor with vector clone
- ArrayElemsValues(ArrayElemsValues const& other) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- values.reserve(other.values.size());
-
- for (const auto& e : other.values) {
- values.push_back(e->clone_expr());
- }
- }
-
- // overloaded assignment operator with vector clone
- ArrayElemsValues& operator=(ArrayElemsValues const& other) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- values.reserve(other.values.size());
-
- for (const auto& e : other.values) {
- values.push_back(e->clone_expr());
- }
-
- return *this;
- }
-
- // move constructors
- ArrayElemsValues(ArrayElemsValues&& other) = default;
- ArrayElemsValues& operator=(ArrayElemsValues&& other) = default;
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- virtual ArrayElemsValues* clone_array_elems_impl() const OVERRIDE {
- return new ArrayElemsValues(*this);
- }
- };
-
- // Copied array element and number of copies
- class ArrayElemsCopied : public ArrayElems {
- // Expr* elem_to_copy;
- ::std::unique_ptr<Expr> elem_to_copy;
- // Expr* num_copies;
- ::std::unique_ptr<Expr> num_copies;
-
- // TODO: should this store location data?
-
- public:
- /*~ArrayElemsCopied() {
- delete num_copies;
- delete elem_to_copy;
- }*/
-
- // Constructor requires pointers for polymorphism
- ArrayElemsCopied(
- ::std::unique_ptr<Expr> copied_elem, ::std::unique_ptr<Expr> copy_amount) :
- elem_to_copy(::std::move(copied_elem)),
- num_copies(::std::move(copy_amount)) {}
-
- // Copy constructor required due to unique_ptr - uses custom clone
- ArrayElemsCopied(ArrayElemsCopied const& other) :
- elem_to_copy(other.elem_to_copy->clone_expr()),
- num_copies(other.num_copies->clone_expr()) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator for deep copying
- ArrayElemsCopied& operator=(ArrayElemsCopied const& other) {
- elem_to_copy = other.elem_to_copy->clone_expr();
- num_copies = other.num_copies->clone_expr();
-
- return *this;
- }
-
- // move constructors
- ArrayElemsCopied(ArrayElemsCopied&& other) = default;
- ArrayElemsCopied& operator=(ArrayElemsCopied&& other) = default;
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- virtual ArrayElemsCopied* clone_array_elems_impl() const OVERRIDE {
- return new ArrayElemsCopied(*this);
- }
- };
-
- // Array definition-ish expression
- class ArrayExpr : public ExprWithoutBlock {
- ::std::vector<Attribute> inner_attrs;
- // ArrayElems internal_elements;
- ::std::unique_ptr<ArrayElems> internal_elements;
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- inline ::std::vector<Attribute> get_inner_attrs() const {
- return inner_attrs;
- }
-
- // Returns whether array expr has array elems or if it is just empty.
- inline bool has_array_elems() const {
- return internal_elements != NULL;
- }
-
- // Constructor requires ArrayElems pointer
- ArrayExpr(::std::unique_ptr<ArrayElems> array_elems,
- ::std::vector<Attribute> inner_attribs, ::std::vector<Attribute> outer_attribs,
- Location locus) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- inner_attrs(::std::move(inner_attribs)), internal_elements(::std::move(array_elems)),
- locus(locus) {}
-
- // Copy constructor requires cloning ArrayElems for polymorphism to hold
- ArrayExpr(ArrayExpr const& other) :
- ExprWithoutBlock(other), inner_attrs(other.inner_attrs), locus(other.locus) {
- if (other.has_array_elems()) {
- internal_elements = other.internal_elements->clone_array_elems();
- }
- }
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone internal_elements
- ArrayExpr& operator=(ArrayExpr const& other) {
- ExprWithoutBlock::operator=(other);
- inner_attrs = other.inner_attrs;
- if (other.has_array_elems()) {
- internal_elements = other.internal_elements->clone_array_elems();
- }
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- ArrayExpr(ArrayExpr&& other) = default;
- ArrayExpr& operator=(ArrayExpr&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ArrayExpr* clone_expr_impl() const OVERRIDE {
- return new ArrayExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ArrayExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new ArrayExpr(*this);
- }
- };
-
- // Aka IndexExpr (also applies to slices)
- // Apparently a[b] is equivalent to *std::ops::Index::index(&a, b) or
- // *std::ops::Index::index_mut(&mut a, b)
- // Also apparently deref operations on a will be repeatedly applied to find an implementation
- class ArrayIndexExpr : public ExprWithoutBlock {
- /*Expr* array_expr;
- Expr* index_expr;*/
- ::std::unique_ptr<Expr> array_expr;
- ::std::unique_ptr<Expr> index_expr;
-
- Location locus;
-
- public:
- /*~ArrayIndexExpr() {
- delete index_expr;
- delete array_expr;
- }*/
-
- ::std::string as_string() const;
-
- ArrayIndexExpr(::std::unique_ptr<Expr> array_expr,
- ::std::unique_ptr<Expr> array_index_expr, ::std::vector<Attribute> outer_attribs,
- Location locus) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- array_expr(::std::move(array_expr)), index_expr(::std::move(array_index_expr)),
- locus(locus) {}
-
- // Copy constructor requires special cloning due to unique_ptr
- ArrayIndexExpr(ArrayIndexExpr const& other) :
- ExprWithoutBlock(other), array_expr(other.array_expr->clone_expr()),
- index_expr(other.index_expr->clone_expr()), locus(other.locus) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone unique_ptrs
- ArrayIndexExpr& operator=(ArrayIndexExpr const& other) {
- ExprWithoutBlock::operator=(other);
- array_expr = other.array_expr->clone_expr();
- index_expr = other.index_expr->clone_expr();
- // outer_attrs = other.outer_attrs;
- locus = other.locus;
-
- return *this;
- }
-
- // move constructors
- ArrayIndexExpr(ArrayIndexExpr&& other) = default;
- ArrayIndexExpr& operator=(ArrayIndexExpr&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ArrayIndexExpr* clone_expr_impl() const OVERRIDE {
- return new ArrayIndexExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ArrayIndexExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new ArrayIndexExpr(*this);
- }
- };
-
- // AST representation of a tuple
- class TupleExpr : public ExprWithoutBlock {
- ::std::vector<Attribute> inner_attrs;
-
- //::std::vector<Expr> tuple_elems;
- ::std::vector< ::std::unique_ptr<Expr> > tuple_elems;
- // replaces (inlined version of) TupleElements
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- inline ::std::vector<Attribute> get_inner_attrs() const {
- return inner_attrs;
- }
-
- TupleExpr(::std::vector< ::std::unique_ptr<Expr> > tuple_elements,
- ::std::vector<Attribute> inner_attribs, ::std::vector<Attribute> outer_attribs,
- Location locus) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- inner_attrs(::std::move(inner_attribs)), tuple_elems(::std::move(tuple_elements)),
- locus(locus) {}
-
- // copy constructor with vector clone
- TupleExpr(TupleExpr const& other) :
- ExprWithoutBlock(other), inner_attrs(other.inner_attrs), locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- tuple_elems.reserve(other.tuple_elems.size());
-
- for (const auto& e : other.tuple_elems) {
- tuple_elems.push_back(e->clone_expr());
- }
- }
-
- // overloaded assignment operator to vector clone
- TupleExpr& operator=(TupleExpr const& other) {
- ExprWithoutBlock::operator=(other);
- inner_attrs = other.inner_attrs;
- locus = other.locus;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- tuple_elems.reserve(other.tuple_elems.size());
-
- for (const auto& e : other.tuple_elems) {
- tuple_elems.push_back(e->clone_expr());
- }
-
- return *this;
- }
-
- // move constructors
- TupleExpr(TupleExpr&& other) = default;
- TupleExpr& operator=(TupleExpr&& other) = default;
-
- // Note: syntactically, can disambiguate single-element tuple from parens with comma, i.e.
- // (0,) rather than (0)
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TupleExpr* clone_expr_impl() const OVERRIDE {
- return new TupleExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual TupleExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new TupleExpr(*this);
- }
- };
-
- // aka TupleIndexingExpr
- // AST representation of a tuple indexing expression
- class TupleIndexExpr : public ExprWithoutBlock {
- // Expr* tuple_expr;
- ::std::unique_ptr<Expr> tuple_expr;
- // TupleIndex is a decimal int literal with no underscores or suffix
- TupleIndex tuple_index;
-
- Location locus;
-
- // i.e. pair.0
-
- public:
- /*~TupleIndexExpr() {
- delete tuple_expr;
- }*/
-
- ::std::string as_string() const;
-
- inline TupleIndex get_tuple_index() const {
- return tuple_index;
- }
-
- TupleIndexExpr(::std::unique_ptr<Expr> tuple_expr, TupleIndex index,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- tuple_expr(::std::move(tuple_expr)), tuple_index(index), locus(locus) {}
-
- // Copy constructor requires a clone for tuple_expr
- TupleIndexExpr(TupleIndexExpr const& other) :
- ExprWithoutBlock(other), tuple_expr(other.tuple_expr->clone_expr()),
- tuple_index(other.tuple_index), locus(other.locus) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator in order to clone
- TupleIndexExpr& operator=(TupleIndexExpr const& other) {
- ExprWithoutBlock::operator=(other);
- tuple_expr = other.tuple_expr->clone_expr();
- tuple_index = other.tuple_index;
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- TupleIndexExpr(TupleIndexExpr&& other) = default;
- TupleIndexExpr& operator=(TupleIndexExpr&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TupleIndexExpr* clone_expr_impl() const OVERRIDE {
- return new TupleIndexExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual TupleIndexExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new TupleIndexExpr(*this);
- }
- };
-
- // Base struct/tuple/union value creator AST node (abstract)
- class StructExpr : public ExprWithoutBlock {
- PathInExpression struct_name;
-
- protected:
- // Protected constructor to allow initialising struct_name
- StructExpr(PathInExpression struct_path, ::std::vector<Attribute> outer_attribs) :
- ExprWithoutBlock(::std::move(outer_attribs)), struct_name(::std::move(struct_path)) {}
-
- public:
- inline const PathInExpression& get_struct_name() const {
- return struct_name;
- }
-
- virtual ::std::string as_string() const;
- };
-
- // Actual AST node of the struct creator (with no fields). Not abstract!
- class StructExprStruct : public StructExpr {
- ::std::vector<Attribute> inner_attrs;
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- inline ::std::vector<Attribute> get_inner_attrs() const {
- return inner_attrs;
- }
-
- // Constructor has to call protected constructor of base class
- StructExprStruct(PathInExpression struct_path, ::std::vector<Attribute> inner_attribs,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- StructExpr(::std::move(struct_path), ::std::move(outer_attribs)),
- inner_attrs(::std::move(inner_attribs)), locus(locus) {}
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructExprStruct* clone_expr_impl() const OVERRIDE {
- return new StructExprStruct(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructExprStruct* clone_expr_without_block_impl() const OVERRIDE {
- return new StructExprStruct(*this);
- }
- };
-
- // AST node representing expression used to fill a struct's fields from another struct
- struct StructBase {
- private:
- // Expr* base_struct;
- ::std::unique_ptr<Expr> base_struct;
-
- // TODO: should this store location data?
-
- public:
- StructBase(::std::unique_ptr<Expr> base_struct_ptr) :
- base_struct(::std::move(base_struct_ptr)) {}
-
- // Copy constructor requires clone
- StructBase(StructBase const& other) {
- // HACK: gets around base_struct pointer being null (e.g. if no struct base exists)
- if (other.base_struct != NULL) {
- other.base_struct->clone_expr();
- }
-
- // DEBUG:
- fprintf(stderr, "struct base copy constructor called successfully\n");
- }
-
- // Destructor
- ~StructBase() = default;
-
- // Overload assignment operator to clone base_struct
- StructBase& operator=(StructBase const& other) {
- base_struct = other.base_struct->clone_expr();
-
- return *this;
- }
-
- // move constructors
- StructBase(StructBase&& other) = default;
- StructBase& operator=(StructBase&& other) = default;
-
- /*~StructBase() {
- delete base_struct;
- }*/
-
- // Returns a null expr-ed StructBase - error state
- static StructBase error() {
- return StructBase(NULL);
- }
-
- // Returns whether StructBase is in error state
- inline bool is_invalid() const {
- return base_struct == NULL;
- }
-
- ::std::string as_string() const;
- };
-
- // Base AST node for a single struct expression field (in struct instance creation) - abstract
- class StructExprField {
- public:
- virtual ~StructExprField() {}
-
- // Unique pointer custom clone function
- ::std::unique_ptr<StructExprField> clone_struct_expr_field() const {
- return ::std::unique_ptr<StructExprField>(clone_struct_expr_field_impl());
- }
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- protected:
- // pure virtual clone implementation
- virtual StructExprField* clone_struct_expr_field_impl() const = 0;
- };
-
- // Identifier-only variant of StructExprField AST node
- class StructExprFieldIdentifier : public StructExprField {
- Identifier field_name;
-
- // TODO: should this store location data?
-
- public:
- StructExprFieldIdentifier(Identifier field_identifier) :
- field_name(::std::move(field_identifier)) {}
-
- ::std::string as_string() const {
- return field_name;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this rather than base
- virtual StructExprFieldIdentifier* clone_struct_expr_field_impl() const OVERRIDE {
- return new StructExprFieldIdentifier(*this);
- }
- };
-
- // Base AST node for a single struct expression field with an assigned value - abstract
- class StructExprFieldWithVal : public StructExprField {
- // Expr* value;
- ::std::unique_ptr<Expr> value;
-
- protected:
- StructExprFieldWithVal(::std::unique_ptr<Expr> field_value) :
- value(::std::move(field_value)) {}
-
- // Copy constructor requires clone
- StructExprFieldWithVal(StructExprFieldWithVal const& other) :
- value(other.value->clone_expr()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone unique_ptr
- StructExprFieldWithVal& operator=(StructExprFieldWithVal const& other) {
- value = other.value->clone_expr();
-
- return *this;
- }
-
- // move constructors
- StructExprFieldWithVal(StructExprFieldWithVal&& other) = default;
- StructExprFieldWithVal& operator=(StructExprFieldWithVal&& other) = default;
-
- public:
- /*~StructExprFieldWithVal() {
- delete value;
- }*/
-
- ::std::string as_string() const;
- };
-
- // Identifier and value variant of StructExprField AST node
- class StructExprFieldIdentifierValue : public StructExprFieldWithVal {
- Identifier field_name;
-
- // TODO: should this store location data?
-
- public:
- StructExprFieldIdentifierValue(
- Identifier field_identifier, ::std::unique_ptr<Expr> field_value) :
- StructExprFieldWithVal(::std::move(field_value)),
- field_name(::std::move(field_identifier)) {}
-
- // copy constructor, destructor, and overloaded assignment operator should carry through
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this rather than base
- virtual StructExprFieldIdentifierValue* clone_struct_expr_field_impl() const OVERRIDE {
- return new StructExprFieldIdentifierValue(*this);
- }
- };
-
- // Tuple index and value variant of StructExprField AST node
- class StructExprFieldIndexValue : public StructExprFieldWithVal {
- TupleIndex index;
-
- // TODO: should this store location data?
-
- public:
- StructExprFieldIndexValue(TupleIndex tuple_index, ::std::unique_ptr<Expr> field_value) :
- StructExprFieldWithVal(::std::move(field_value)), index(tuple_index) {}
-
- // copy constructor, destructor, and overloaded assignment operator should carry through
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this rather than base
- virtual StructExprFieldIndexValue* clone_struct_expr_field_impl() const OVERRIDE {
- return new StructExprFieldIndexValue(*this);
- }
- };
-
- // AST node of a struct creator with fields
- class StructExprStructFields : public StructExprStruct {
- //::std::vector<StructExprField> fields;
- ::std::vector< ::std::unique_ptr<StructExprField> > fields;
-
- // bool has_struct_base;
- StructBase struct_base;
-
- public:
- ::std::string as_string() const;
-
- inline bool has_struct_base() const {
- return !struct_base.is_invalid();
- }
-
- /*inline ::std::vector< ::std::unique_ptr<StructExprField> > get_fields() const {
- return fields;
- }*/
-
- /*inline StructBase get_struct_base() const {
- return has_struct_base ? struct_base : StructBase::error();
- }*/
-
- // Constructor for StructExprStructFields when no struct base is used
- StructExprStructFields(PathInExpression struct_path,
- ::std::vector< ::std::unique_ptr<StructExprField> > expr_fields, Location locus,
- StructBase base_struct = StructBase::error(),
- ::std::vector<Attribute> inner_attribs = ::std::vector<Attribute>(),
- ::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- StructExprStruct(::std::move(struct_path), ::std::move(inner_attribs),
- ::std::move(outer_attribs), locus),
- fields(::std::move(expr_fields)), struct_base(::std::move(base_struct)) {}
-
- // copy constructor with vector clone
- StructExprStructFields(StructExprStructFields const& other) :
- StructExprStruct(other), struct_base(other.struct_base) {
- // DEBUG
- fprintf(stderr, "got past the initialisation list part of copy constructor\n");
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- fields.reserve(other.fields.size());
-
- // DEBUG
- fprintf(stderr, "reserved space in fields\n");
-
- for (const auto& e : other.fields) {
- // DEBUG
- fprintf(stderr, "about to clone a field\n");
-
- fields.push_back(e->clone_struct_expr_field());
-
- // DEBUG
- fprintf(stderr, "cloned a field successfully\n");
- }
-
- // DEBUG
- fprintf(stderr, "finished cloning fields\n");
- }
-
- // overloaded assignment operator with vector clone
- StructExprStructFields& operator=(StructExprStructFields const& other) {
- StructExprStruct::operator=(other);
- struct_base = other.struct_base;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- fields.reserve(other.fields.size());
-
- for (const auto& e : other.fields) {
- fields.push_back(e->clone_struct_expr_field());
- }
-
- return *this;
- }
-
- // move constructors
- StructExprStructFields(StructExprStructFields&& other) = default;
- StructExprStructFields& operator=(StructExprStructFields&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructExprStructFields* clone_expr_impl() const OVERRIDE {
- return new StructExprStructFields(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructExprStructFields* clone_expr_without_block_impl() const OVERRIDE {
- // DEBUG
- fprintf(stderr, "called structexprstructfields clone expr without block impl - about "
- "to return new structexprstructfields\n");
-
- // DEBUG - test creation of a base from this
- fprintf(stderr, "about to try to create and allocate structexprstruct \n");
- StructExprStruct* test_DELETE = new StructExprStruct(*this);
- delete test_DELETE;
- fprintf(stderr, "managed to create and allocate structexprstruct \n");
- // very weird: can create and allocate structexpstruct but not structexprstructfields
-
- // DEBUG - test creation of a non-returned class from this
- fprintf(stderr,
- "about to try to create and allocate structexprstructfields (but not return)\n");
- StructExprStructFields* test_DELETE2 = new StructExprStructFields(*this);
- delete test_DELETE2;
- fprintf(stderr,
- "managed to create and allocate structexprstructfields (if not returned) \n");
- // ok this fails. fair enough.
-
- return new StructExprStructFields(*this);
- }
- };
-
- // AST node of the functional update struct creator
- class StructExprStructBase : public StructExprStruct {
- StructBase struct_base;
-
- public:
- ::std::string as_string() const;
-
- /*inline StructBase get_struct_base() const {
- return struct_base;
- }*/
-
- StructExprStructBase(PathInExpression struct_path, StructBase base_struct,
- ::std::vector<Attribute> inner_attribs, ::std::vector<Attribute> outer_attribs,
- Location locus) :
- StructExprStruct(::std::move(struct_path), ::std::move(inner_attribs),
- ::std::move(outer_attribs), locus),
- struct_base(::std::move(base_struct)) {}
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructExprStructBase* clone_expr_impl() const OVERRIDE {
- return new StructExprStructBase(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructExprStructBase* clone_expr_without_block_impl() const OVERRIDE {
- return new StructExprStructBase(*this);
- }
- };
-
- // AST node of a tuple struct creator
- class StructExprTuple : public StructExpr {
- ::std::vector<Attribute> inner_attrs;
- //::std::vector<Expr> exprs;
- ::std::vector< ::std::unique_ptr<Expr> > exprs;
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- inline const ::std::vector<Attribute>& get_inner_attrs() const {
- return inner_attrs;
- }
-
- /*inline ::std::vector< ::std::unique_ptr<Expr> > get_exprs() const {
- return exprs;
- }*/
-
- StructExprTuple(PathInExpression struct_path,
- ::std::vector< ::std::unique_ptr<Expr> > tuple_exprs,
- ::std::vector<Attribute> inner_attribs, ::std::vector<Attribute> outer_attribs,
- Location locus) :
- StructExpr(::std::move(struct_path), ::std::move(outer_attribs)),
- inner_attrs(::std::move(inner_attribs)), exprs(::std::move(tuple_exprs)), locus(locus) {
- }
-
- // copy constructor with vector clone
- StructExprTuple(StructExprTuple const& other) :
- StructExpr(other), inner_attrs(other.inner_attrs), locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- exprs.reserve(other.exprs.size());
-
- for (const auto& e : other.exprs) {
- exprs.push_back(e->clone_expr());
- }
- }
-
- // overloaded assignment operator with vector clone
- StructExprTuple& operator=(StructExprTuple const& other) {
- StructExpr::operator=(other);
- inner_attrs = other.inner_attrs;
- locus = other.locus;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- exprs.reserve(other.exprs.size());
-
- for (const auto& e : other.exprs) {
- exprs.push_back(e->clone_expr());
- }
-
- return *this;
- }
-
- // move constructors
- StructExprTuple(StructExprTuple&& other) = default;
- StructExprTuple& operator=(StructExprTuple&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructExprTuple* clone_expr_impl() const OVERRIDE {
- return new StructExprTuple(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructExprTuple* clone_expr_without_block_impl() const OVERRIDE {
- return new StructExprTuple(*this);
- }
- };
-
- // AST node of a "unit" struct creator (no fields and no braces)
- class StructExprUnit : public StructExpr {
- Location locus;
-
- public:
- ::std::string as_string() const {
- return get_struct_name().as_string();
- // return struct_name.as_string();
- }
-
- StructExprUnit(
- PathInExpression struct_path, ::std::vector<Attribute> outer_attribs, Location locus) :
- StructExpr(::std::move(struct_path), ::std::move(outer_attribs)),
- locus(locus) {}
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructExprUnit* clone_expr_impl() const OVERRIDE {
- return new StructExprUnit(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructExprUnit* clone_expr_without_block_impl() const OVERRIDE {
- return new StructExprUnit(*this);
- }
- };
-
- // aka EnumerationVariantExpr
- // Base AST node representing creation of an enum variant instance - abstract
- class EnumVariantExpr : public ExprWithoutBlock {
- PathInExpression enum_variant_path;
-
- protected:
- // Protected constructor for initialising enum_variant_path
- EnumVariantExpr(
- PathInExpression path_to_enum_variant, ::std::vector<Attribute> outer_attribs) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- enum_variant_path(::std::move(path_to_enum_variant)) {}
-
- public:
- // TODO: maybe remove and have string version gotten here directly
- inline PathInExpression get_enum_variant_path() const {
- return enum_variant_path;
- }
- };
-
- // Base AST node for a single enum expression field (in enum instance creation) - abstract
- class EnumExprField {
- public:
- virtual ~EnumExprField() {}
-
- // Unique pointer custom clone function
- ::std::unique_ptr<EnumExprField> clone_enum_expr_field() const {
- return ::std::unique_ptr<EnumExprField>(clone_enum_expr_field_impl());
- }
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- protected:
- // Clone function implementation as pure virtual method
- virtual EnumExprField* clone_enum_expr_field_impl() const = 0;
- };
-
- // Identifier-only variant of EnumExprField AST node
- class EnumExprFieldIdentifier : public EnumExprField {
- Identifier field_name;
-
- // TODO: should this store location data?
-
- public:
- EnumExprFieldIdentifier(Identifier field_identifier) :
- field_name(::std::move(field_identifier)) {}
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual EnumExprFieldIdentifier* clone_enum_expr_field_impl() const OVERRIDE {
- return new EnumExprFieldIdentifier(*this);
- }
- };
-
- // Base AST node for a single enum expression field with an assigned value - abstract
- class EnumExprFieldWithVal : public EnumExprField {
- // Expr* value;
- ::std::unique_ptr<Expr> value;
-
- // TODO: should this store location data?
-
- protected:
- EnumExprFieldWithVal(::std::unique_ptr<Expr> field_value) :
- value(::std::move(field_value)) {}
-
- // Copy constructor must clone unique_ptr value
- EnumExprFieldWithVal(EnumExprFieldWithVal const& other) :
- value(other.value->clone_expr()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone
- EnumExprFieldWithVal& operator=(EnumExprFieldWithVal const& other) {
- value = other.value->clone_expr();
-
- return *this;
- }
-
- // move constructors
- EnumExprFieldWithVal(EnumExprFieldWithVal&& other) = default;
- EnumExprFieldWithVal& operator=(EnumExprFieldWithVal&& other) = default;
- };
-
- // Identifier and value variant of EnumExprField AST node
- class EnumExprFieldIdentifierValue : public EnumExprFieldWithVal {
- Identifier field_name;
-
- // TODO: should this store location data?
-
- public:
- EnumExprFieldIdentifierValue(Identifier field_name, ::std::unique_ptr<Expr> field_value) :
- EnumExprFieldWithVal(::std::move(field_value)), field_name(::std::move(field_name)) {}
-
- // copy constructor, destructor, and assignment operator should not need defining
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual EnumExprFieldIdentifierValue* clone_enum_expr_field_impl() const OVERRIDE {
- return new EnumExprFieldIdentifierValue(*this);
- }
- };
-
- // Tuple index and value variant of EnumExprField AST node
- class EnumExprFieldIndexValue : public EnumExprFieldWithVal {
- TupleIndex index;
- // TODO: implement "with val" as a template with EnumExprField as type param?
-
- // TODO: should this store location data?
-
- public:
- EnumExprFieldIndexValue(TupleIndex field_index, ::std::unique_ptr<Expr> field_value) :
- EnumExprFieldWithVal(::std::move(field_value)), index(field_index) {}
-
- // copy constructor, destructor, and assignment operator should not need defining
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual EnumExprFieldIndexValue* clone_enum_expr_field_impl() const OVERRIDE {
- return new EnumExprFieldIndexValue(*this);
- }
- };
-
- // Struct-like syntax enum variant instance creation AST node
- class EnumExprStruct : public EnumVariantExpr {
- //::std::vector<EnumExprField> fields;
- ::std::vector< ::std::unique_ptr<EnumExprField> > fields;
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- /*inline ::std::vector< ::std::unique_ptr<EnumExprField> > get_fields() const {
- return fields;
- }*/
-
- EnumExprStruct(PathInExpression enum_variant_path,
- ::std::vector< ::std::unique_ptr<EnumExprField> > variant_fields,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- EnumVariantExpr(::std::move(enum_variant_path), ::std::move(outer_attribs)),
- fields(::std::move(variant_fields)), locus(locus) {}
-
- // copy constructor with vector clone
- EnumExprStruct(EnumExprStruct const& other) : EnumVariantExpr(other), locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- fields.reserve(other.fields.size());
-
- for (const auto& e : other.fields) {
- fields.push_back(e->clone_enum_expr_field());
- }
- }
-
- // overloaded assignment operator with vector clone
- EnumExprStruct& operator=(EnumExprStruct const& other) {
- EnumVariantExpr::operator=(other);
- locus = other.locus;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- fields.reserve(other.fields.size());
-
- for (const auto& e : other.fields) {
- fields.push_back(e->clone_enum_expr_field());
- }
-
- return *this;
- }
-
- // move constructors
- EnumExprStruct(EnumExprStruct&& other) = default;
- EnumExprStruct& operator=(EnumExprStruct&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual EnumExprStruct* clone_expr_impl() const OVERRIDE {
- return new EnumExprStruct(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual EnumExprStruct* clone_expr_without_block_impl() const OVERRIDE {
- return new EnumExprStruct(*this);
- }
- };
-
- // Tuple-like syntax enum variant instance creation AST node
- class EnumExprTuple : public EnumVariantExpr {
- //::std::vector<Expr> values;
- ::std::vector< ::std::unique_ptr<Expr> > values;
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- /*inline ::std::vector< ::std::unique_ptr<Expr> > get_values() const {
- return values;
- }*/
-
- EnumExprTuple(PathInExpression enum_variant_path,
- ::std::vector< ::std::unique_ptr<Expr> > variant_values,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- EnumVariantExpr(::std::move(enum_variant_path), ::std::move(outer_attribs)),
- values(::std::move(variant_values)), locus(locus) {}
-
- // copy constructor with vector clone
- EnumExprTuple(EnumExprTuple const& other) : EnumVariantExpr(other), locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- values.reserve(other.values.size());
-
- for (const auto& e : other.values) {
- values.push_back(e->clone_expr());
- }
- }
-
- // overloaded assignment operator with vector clone
- EnumExprTuple& operator=(EnumExprTuple const& other) {
- EnumVariantExpr::operator=(other);
- locus = other.locus;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- values.reserve(other.values.size());
-
- for (const auto& e : other.values) {
- values.push_back(e->clone_expr());
- }
-
- return *this;
- }
-
- // move constructors
- EnumExprTuple(EnumExprTuple&& other) = default;
- EnumExprTuple& operator=(EnumExprTuple&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual EnumExprTuple* clone_expr_impl() const OVERRIDE {
- return new EnumExprTuple(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual EnumExprTuple* clone_expr_without_block_impl() const OVERRIDE {
- return new EnumExprTuple(*this);
- }
- };
-
- // No-field enum variant instance creation AST node
- class EnumExprFieldless : public EnumVariantExpr {
- Location locus;
-
- public:
- ::std::string as_string() const {
- // return enum_variant_path.as_string();
- return get_enum_variant_path().as_string();
- }
-
- EnumExprFieldless(PathInExpression enum_variant_path,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- EnumVariantExpr(::std::move(enum_variant_path), ::std::move(outer_attribs)),
- locus(locus) {}
-
- // copy constructor, destructor, and assignment operator should not need defining
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual EnumExprFieldless* clone_expr_impl() const OVERRIDE {
- return new EnumExprFieldless(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual EnumExprFieldless* clone_expr_without_block_impl() const OVERRIDE {
- return new EnumExprFieldless(*this);
- }
- };
-
- // Function call expression AST node
- class CallExpr : public ExprWithoutBlock {
- // Expr* function;
- ::std::unique_ptr<Expr> function;
- //::std::vector<Expr> params; // inlined form of CallParams
- ::std::vector< ::std::unique_ptr<Expr> > params;
-
- Location locus;
-
- public:
- /*~CallExpr() {
- delete function;
- }*/
-
- ::std::string as_string() const;
-
- /*inline ::std::vector< ::std::unique_ptr<Expr> > get_params() const {
- return params;
- }*/
-
- CallExpr(::std::unique_ptr<Expr> function_expr,
- ::std::vector< ::std::unique_ptr<Expr> > function_params,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- function(::std::move(function_expr)), params(::std::move(function_params)),
- locus(locus) {}
-
- // copy constructor requires clone
- CallExpr(CallExpr const& other) :
- ExprWithoutBlock(other), function(other.function->clone_expr()), locus(other.locus)
- /*, params(other.params),*/ {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- params.reserve(other.params.size());
-
- for (const auto& e : other.params) {
- params.push_back(e->clone_expr());
- }
- }
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone
- CallExpr& operator=(CallExpr const& other) {
- ExprWithoutBlock::operator=(other);
- function = other.function->clone_expr();
- locus = other.locus;
- // params = other.params;
- // outer_attrs = other.outer_attrs;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- params.reserve(other.params.size());
-
- for (const auto& e : other.params) {
- params.push_back(e->clone_expr());
- }
-
- return *this;
- }
-
- // move constructors
- CallExpr(CallExpr&& other) = default;
- CallExpr& operator=(CallExpr&& other) = default;
-
- // Returns whether function call has parameters.
- inline bool has_params() const {
- return !params.empty();
- }
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual CallExpr* clone_expr_impl() const OVERRIDE {
- return new CallExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual CallExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new CallExpr(*this);
- }
- };
-
- // Method call expression AST node
- class MethodCallExpr : public ExprWithoutBlock {
- // Expr* receiver;
- ::std::unique_ptr<Expr> receiver;
- PathExprSegment method_name;
- //::std::vector<Expr> params; // inlined form of CallParams
- ::std::vector< ::std::unique_ptr<Expr> > params;
-
- Location locus;
-
- public:
- /*~MethodCallExpr() {
- delete receiver;
- }*/
-
- ::std::string as_string() const;
-
- /*inline ::std::vector< ::std::unique_ptr<Expr> > get_params() const {
- return params;
- }*/
-
- MethodCallExpr(::std::unique_ptr<Expr> call_receiver, PathExprSegment method_path,
- ::std::vector< ::std::unique_ptr<Expr> > method_params,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- receiver(::std::move(call_receiver)), method_name(::std::move(method_path)),
- params(::std::move(method_params)), locus(locus) {}
-
- // copy constructor required due to cloning
- MethodCallExpr(MethodCallExpr const& other) :
- ExprWithoutBlock(other), receiver(other.receiver->clone_expr()),
- method_name(other.method_name), locus(other.locus)
- /*, params(other.params),*/ {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- params.reserve(other.params.size());
-
- for (const auto& e : other.params) {
- params.push_back(e->clone_expr());
- }
- }
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone receiver object
- MethodCallExpr& operator=(MethodCallExpr const& other) {
- ExprWithoutBlock::operator=(other);
- receiver = other.receiver->clone_expr();
- method_name = other.method_name;
- locus = other.locus;
- // params = other.params;
- // outer_attrs = other.outer_attrs;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- params.reserve(other.params.size());
-
- for (const auto& e : other.params) {
- params.push_back(e->clone_expr());
- }
-
- return *this;
- }
-
- // move constructors
- MethodCallExpr(MethodCallExpr&& other) = default;
- MethodCallExpr& operator=(MethodCallExpr&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual MethodCallExpr* clone_expr_impl() const OVERRIDE {
- return new MethodCallExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual MethodCallExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new MethodCallExpr(*this);
- }
- };
-
- // aka FieldExpression
- // Struct or union field access expression AST node
- class FieldAccessExpr : public ExprWithoutBlock {
- // Expr* receiver;
- ::std::unique_ptr<Expr> receiver;
- Identifier field;
-
- Location locus;
-
- public:
- /*~FieldAccessExpr() {
- delete receiver;
- }*/
-
- ::std::string as_string() const;
-
- FieldAccessExpr(::std::unique_ptr<Expr> field_access_receiver, Identifier field_name,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- receiver(::std::move(field_access_receiver)), field(::std::move(field_name)),
- locus(locus) {}
-
- // Copy constructor required due to unique_ptr cloning
- FieldAccessExpr(FieldAccessExpr const& other) :
- ExprWithoutBlock(other), receiver(other.receiver->clone_expr()), field(other.field),
- locus(other.locus) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone unique_ptr
- FieldAccessExpr& operator=(FieldAccessExpr const& other) {
- ExprWithoutBlock::operator=(other);
- receiver = other.receiver->clone_expr();
- field = other.field;
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- FieldAccessExpr(FieldAccessExpr&& other) = default;
- FieldAccessExpr& operator=(FieldAccessExpr&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual FieldAccessExpr* clone_expr_impl() const OVERRIDE {
- return new FieldAccessExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual FieldAccessExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new FieldAccessExpr(*this);
- }
- };
-
- // Closure parameter data structure
- struct ClosureParam {
- private:
- // Pattern pattern;
- ::std::unique_ptr<Pattern> pattern;
-
- // bool has_type_given;
- // Type type;
- ::std::unique_ptr<Type> type;
-
- // TODO: should this store location data?
-
- public:
- // Returns whether the type of the parameter has been given.
- inline bool has_type_given() const {
- return type != NULL;
- }
-
- // Constructor for closure parameter
- ClosureParam(
- ::std::unique_ptr<Pattern> param_pattern, ::std::unique_ptr<Type> param_type = NULL) :
- pattern(::std::move(param_pattern)),
- type(::std::move(param_type)) {}
-
- // Copy constructor required due to cloning as a result of unique_ptrs
- ClosureParam(ClosureParam const& other) : pattern(other.pattern->clone_pattern()) {
- // guard to protect from null pointer dereference
- if (other.type != NULL) {
- type = other.type->clone_type();
- }
- }
-
- ~ClosureParam() = default;
-
- // Assignment operator must be overloaded to clone as well
- ClosureParam& operator=(ClosureParam const& other) {
- pattern = other.pattern->clone_pattern();
- type = other.type->clone_type();
-
- return *this;
- }
-
- // move constructors
- ClosureParam(ClosureParam&& other) = default;
- ClosureParam& operator=(ClosureParam&& other) = default;
-
- // Returns whether closure parameter is in an error state.
- inline bool is_error() const {
- return pattern == NULL;
- }
-
- // Creates an error state closure parameter.
- static ClosureParam create_error() {
- return ClosureParam(NULL);
- }
-
- ::std::string as_string() const;
- };
-
- // Base closure definition expression AST node - abstract
- class ClosureExpr : public ExprWithoutBlock {
- bool has_move;
- ::std::vector<ClosureParam> params; // may be empty
- // also note a double pipe "||" can be used for empty params - does not need a space
-
- Location locus;
-
- protected:
- ClosureExpr(::std::vector<ClosureParam> closure_params, bool has_move,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- has_move(has_move), params(::std::move(closure_params)), locus(locus) {}
-
- // Copy constructor, destructor, and assignment operator override should not be needed
- public:
- virtual ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
- };
-
- // Represents a non-type-specified closure expression AST node
- class ClosureExprInner : public ClosureExpr {
- // Expr* closure_inner;
- ::std::unique_ptr<Expr> closure_inner;
-
- public:
- /*~ClosureExprInner() {
- delete closure_inner;
- }*/
-
- ::std::string as_string() const;
-
- // Constructor for a ClosureExprInner
- ClosureExprInner(::std::unique_ptr<Expr> closure_inner_expr,
- ::std::vector<ClosureParam> closure_params, Location locus, bool is_move = false,
- ::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- ClosureExpr(::std::move(closure_params), is_move, ::std::move(outer_attribs), locus),
- closure_inner(::std::move(closure_inner_expr)) {}
-
- // Copy constructor must be defined to allow copying via cloning of unique_ptr
- ClosureExprInner(ClosureExprInner const& other) :
- ClosureExpr(other), closure_inner(other.closure_inner->clone_expr()) {}
- // TODO: ensure that this actually constructs properly
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone closure_inner
- ClosureExprInner& operator=(ClosureExprInner const& other) {
- ClosureExpr::operator=(other);
- closure_inner = other.closure_inner->clone_expr();
- // params = other.params;
- // has_move = other.has_move;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- ClosureExprInner(ClosureExprInner&& other) = default;
- ClosureExprInner& operator=(ClosureExprInner&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ClosureExprInner* clone_expr_impl() const OVERRIDE {
- return new ClosureExprInner(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ClosureExprInner* clone_expr_without_block_impl() const OVERRIDE {
- return new ClosureExprInner(*this);
- }
- };
-
- // Forward decl BlockExpr for ClosureExprInnerTyped
- // class BlockExpr;
-
- // A block AST node
- class BlockExpr : public ExprWithBlock {
- ::std::vector<Attribute> inner_attrs;
-
- /*bool has_statements;
- Statements statements;*/
-
- // bool has_statements;
- ::std::vector< ::std::unique_ptr<Stmt> > statements;
- // bool has_expr;
- ::std::unique_ptr<ExprWithoutBlock> expr; // inlined from Statements
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- // Returns whether the block contains statements.
- inline bool has_statements() const {
- return !statements.empty();
- }
-
- // Returns whether the block contains an expression
- inline bool has_expr() const {
- return expr != NULL;
- }
-
- BlockExpr(::std::vector< ::std::unique_ptr<Stmt> > block_statements,
- ::std::unique_ptr<ExprWithoutBlock> block_expr, ::std::vector<Attribute> inner_attribs,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- ExprWithBlock(::std::move(outer_attribs)),
- inner_attrs(::std::move(inner_attribs)), statements(::std::move(block_statements)),
- expr(::std::move(block_expr)), locus(locus) {}
-
- // Copy constructor with clone
- BlockExpr(BlockExpr const& other) :
- ExprWithBlock(other), /*statements(other.statements),*/
- inner_attrs(other.inner_attrs), locus(other.locus) {
- // guard to protect from null pointer dereference
- if (other.expr != NULL) {
- expr = other.expr->clone_expr_without_block();
- }
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- statements.reserve(other.statements.size());
-
- for (const auto& e : other.statements) {
- statements.push_back(e->clone_stmt());
- }
- }
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone pointer
- BlockExpr& operator=(BlockExpr const& other) {
- ExprWithBlock::operator=(other);
- // statements = other.statements;
- expr = other.expr->clone_expr_without_block();
- inner_attrs = other.inner_attrs;
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- statements.reserve(other.statements.size());
-
- for (const auto& e : other.statements) {
- statements.push_back(e->clone_stmt());
- }
-
- return *this;
- }
-
- // move constructors
- BlockExpr(BlockExpr&& other) = default;
- BlockExpr& operator=(BlockExpr&& other) = default;
-
- // Unique pointer custom clone function
- ::std::unique_ptr<BlockExpr> clone_block_expr() const {
- return ::std::unique_ptr<BlockExpr>(clone_block_expr_impl());
- }
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual BlockExpr* clone_expr_impl() const OVERRIDE {
- return new BlockExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual BlockExpr* clone_expr_with_block_impl() const OVERRIDE {
- return new BlockExpr(*this);
- }
-
- /* This is the base method as not an abstract class - not virtual but could be in future
- * if required. */
- /*virtual*/ BlockExpr* clone_block_expr_impl() const {
- return new BlockExpr(*this);
- }
- };
-
- // Represents a type-specified closure expression AST node
- class ClosureExprInnerTyped : public ClosureExpr {
- // Type return_type;
- ::std::unique_ptr<Type> return_type;
- // BlockExpr* expr;
- ::std::unique_ptr<BlockExpr> expr; // only used because may be polymorphic in future
-
- public:
- /*~ClosureExprInnerTyped() {
- delete expr;
- }*/
-
- ::std::string as_string() const;
-
- // Constructor potentially with a move
- ClosureExprInnerTyped(::std::unique_ptr<Type> closure_return_type,
- ::std::unique_ptr<BlockExpr> closure_expr, ::std::vector<ClosureParam> closure_params,
- Location locus, bool is_move = false,
- ::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- ClosureExpr(::std::move(closure_params), is_move, ::std::move(outer_attribs), locus),
- return_type(::std::move(closure_return_type)), expr(::std::move(closure_expr)) {}
-
- // Copy constructor requires cloning
- ClosureExprInnerTyped(ClosureExprInnerTyped const& other) :
- ClosureExpr(other), return_type(other.return_type->clone_type()),
- expr(other.expr->clone_block_expr()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone unique_ptrs
- ClosureExprInnerTyped& operator=(ClosureExprInnerTyped const& other) {
- ClosureExpr::operator=(other);
- return_type = other.return_type->clone_type();
- expr = other.expr->clone_block_expr();
- // params = other.params;
- // has_move = other.has_move;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- ClosureExprInnerTyped(ClosureExprInnerTyped&& other) = default;
- ClosureExprInnerTyped& operator=(ClosureExprInnerTyped&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ClosureExprInnerTyped* clone_expr_impl() const OVERRIDE {
- return new ClosureExprInnerTyped(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ClosureExprInnerTyped* clone_expr_without_block_impl() const OVERRIDE {
- return new ClosureExprInnerTyped(*this);
- }
- };
-
- // AST node representing continue expression within loops
- class ContinueExpr : public ExprWithoutBlock {
- // bool has_label;
- Lifetime label;
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- // Returns true if the continue expr has a label.
- inline bool has_label() const {
- return !label.is_error();
- }
-
- // Constructor for a ContinueExpr with a label.
- ContinueExpr(Location locus, Lifetime label = Lifetime::error(),
- ::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- label(::std::move(label)), locus(locus) {}
-
- // copy constructor, destructor, and assignment operator should not need defining
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ContinueExpr* clone_expr_impl() const OVERRIDE {
- return new ContinueExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ContinueExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new ContinueExpr(*this);
- }
- };
- // TODO: merge "break" and "continue"? Or even merge in "return"?
-
- // AST node representing break expression within loops
- class BreakExpr : public ExprWithoutBlock {
- // bool has_label;
- Lifetime label;
-
- // bool has_break_expr;
- // Expr* break_expr; // may be uninitialised
- ::std::unique_ptr<Expr> break_expr;
-
- Location locus;
-
- public:
- /*~BreakExpr() {
- if (has_break_expr) {
- delete break_expr;
- }
- }*/
-
- ::std::string as_string() const;
-
- // Returns whether the break expression has a label or not.
- inline bool has_label() const {
- return !label.is_error();
- }
-
- // Returns whether the break expression has an expression used in the break or not.
- inline bool has_break_expr() const {
- return break_expr != NULL;
- }
-
- // Constructor for a break expression
- BreakExpr(Location locus, Lifetime break_label = Lifetime::error(),
- ::std::unique_ptr<Expr> expr_in_break = NULL,
- ::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- label(::std::move(break_label)), break_expr(::std::move(expr_in_break)), locus(locus) {}
-
- // Copy constructor defined to use clone for unique pointer
- BreakExpr(BreakExpr const& other) :
- ExprWithoutBlock(other), label(other.label), locus(other.locus) {
- // guard to protect from null pointer dereference
- if (other.break_expr != NULL) {
- break_expr = other.break_expr->clone_expr();
- }
- }
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone unique pointer
- BreakExpr& operator=(BreakExpr const& other) {
- ExprWithoutBlock::operator=(other);
- label = other.label;
- break_expr = other.break_expr->clone_expr();
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- BreakExpr(BreakExpr&& other) = default;
- BreakExpr& operator=(BreakExpr&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual BreakExpr* clone_expr_impl() const OVERRIDE {
- return new BreakExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual BreakExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new BreakExpr(*this);
- }
- };
-
- // Base range expression AST node object - abstract
- class RangeExpr : public ExprWithoutBlock {
- Location locus;
-
- protected:
- // outer attributes not allowed before range expressions
- RangeExpr(Location locus) : ExprWithoutBlock(::std::vector<Attribute>()), locus(locus) {}
-
- public:
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
- };
-
- // Range from (inclusive) and to (exclusive) expression AST node object
- // aka RangeExpr; constructs a std::ops::Range object
- class RangeFromToExpr : public RangeExpr {
- /*Expr* from;
- Expr* to;*/
- ::std::unique_ptr<Expr> from;
- ::std::unique_ptr<Expr> to;
-
- public:
- /*~RangeFromToExpr() {
- delete from;
- delete to;
- }*/
-
- ::std::string as_string() const;
-
- RangeFromToExpr(
- ::std::unique_ptr<Expr> range_from, ::std::unique_ptr<Expr> range_to, Location locus) :
- RangeExpr(locus),
- from(::std::move(range_from)), to(::std::move(range_to)) {}
-
- // Copy constructor with cloning
- RangeFromToExpr(RangeFromToExpr const& other) :
- RangeExpr(other), from(other.from->clone_expr()), to(other.to->clone_expr()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone unique pointers
- RangeFromToExpr& operator=(RangeFromToExpr const& other) {
- RangeExpr::operator=(other);
- from = other.from->clone_expr();
- to = other.to->clone_expr();
-
- return *this;
- }
-
- // move constructors
- RangeFromToExpr(RangeFromToExpr&& other) = default;
- RangeFromToExpr& operator=(RangeFromToExpr&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangeFromToExpr* clone_expr_impl() const OVERRIDE {
- return new RangeFromToExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangeFromToExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new RangeFromToExpr(*this);
- }
- };
-
- // Range from (inclusive) expression AST node object
- // constructs a std::ops::RangeFrom object
- class RangeFromExpr : public RangeExpr {
- // Expr* from;
- ::std::unique_ptr<Expr> from;
-
- public:
- /*~RangeFromExpr() {
- delete from;
- }*/
-
- ::std::string as_string() const;
-
- RangeFromExpr(::std::unique_ptr<Expr> range_from, Location locus) :
- RangeExpr(locus), from(::std::move(range_from)) {}
-
- // Copy constructor with clone
- RangeFromExpr(RangeFromExpr const& other) :
- RangeExpr(other), from(other.from->clone_expr()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone unique_ptr
- RangeFromExpr& operator=(RangeFromExpr const& other) {
- RangeExpr::operator=(other);
- from = other.from->clone_expr();
-
- return *this;
- }
-
- // move constructors
- RangeFromExpr(RangeFromExpr&& other) = default;
- RangeFromExpr& operator=(RangeFromExpr&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangeFromExpr* clone_expr_impl() const OVERRIDE {
- return new RangeFromExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangeFromExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new RangeFromExpr(*this);
- }
- };
-
- // Range to (exclusive) expression AST node object
- // constructs a std::ops::RangeTo object
- class RangeToExpr : public RangeExpr {
- // Expr* to;
- ::std::unique_ptr<Expr> to;
-
- public:
- /*~RangeToExpr() {
- delete to;
- }*/
-
- ::std::string as_string() const;
-
- // outer attributes not allowed
- RangeToExpr(::std::unique_ptr<Expr> range_to, Location locus) :
- RangeExpr(locus), to(::std::move(range_to)) {}
-
- // Copy constructor with clone
- RangeToExpr(RangeToExpr const& other) : RangeExpr(other), to(other.to->clone_expr()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone unique_ptr
- RangeToExpr& operator=(RangeToExpr const& other) {
- RangeExpr::operator=(other);
- to = other.to->clone_expr();
-
- return *this;
- }
-
- // move constructors
- RangeToExpr(RangeToExpr&& other) = default;
- RangeToExpr& operator=(RangeToExpr&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangeToExpr* clone_expr_impl() const OVERRIDE {
- return new RangeToExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangeToExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new RangeToExpr(*this);
- }
- };
-
- // Full range expression AST node object
- // constructs a std::ops::RangeFull object
- class RangeFullExpr : public RangeExpr {
- public:
- ::std::string as_string() const;
-
- RangeFullExpr(Location locus) : RangeExpr(locus) {}
- // outer attributes not allowed
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangeFullExpr* clone_expr_impl() const OVERRIDE {
- return new RangeFullExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangeFullExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new RangeFullExpr(*this);
- }
- };
-
- // Range from (inclusive) and to (inclusive) expression AST node object
- // aka RangeInclusiveExpr; constructs a std::ops::RangeInclusive object
- class RangeFromToInclExpr : public RangeExpr {
- /*Expr* from;
- Expr* to;*/
- ::std::unique_ptr<Expr> from;
- ::std::unique_ptr<Expr> to;
-
- public:
- /*~RangeFromToInclExpr() {
- delete from;
- delete to;
- }*/
-
- ::std::string as_string() const;
-
- RangeFromToInclExpr(
- ::std::unique_ptr<Expr> range_from, ::std::unique_ptr<Expr> range_to, Location locus) :
- RangeExpr(locus),
- from(::std::move(range_from)), to(::std::move(range_to)) {}
- // outer attributes not allowed
-
- // Copy constructor with clone
- RangeFromToInclExpr(RangeFromToInclExpr const& other) :
- RangeExpr(other), from(other.from->clone_expr()), to(other.to->clone_expr()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to use clone
- RangeFromToInclExpr& operator=(RangeFromToInclExpr const& other) {
- RangeExpr::operator=(other);
- from = other.from->clone_expr();
- to = other.to->clone_expr();
-
- return *this;
- }
-
- // move constructors
- RangeFromToInclExpr(RangeFromToInclExpr&& other) = default;
- RangeFromToInclExpr& operator=(RangeFromToInclExpr&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangeFromToInclExpr* clone_expr_impl() const OVERRIDE {
- return new RangeFromToInclExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangeFromToInclExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new RangeFromToInclExpr(*this);
- }
- };
-
- // Range to (inclusive) expression AST node object
- // aka RangeToInclusiveExpr; constructs a std::ops::RangeToInclusive object
- class RangeToInclExpr : public RangeExpr {
- // Expr* to;
- ::std::unique_ptr<Expr> to;
-
- public:
- /*~RangeToInclExpr() {
- delete to;
- }*/
-
- ::std::string as_string() const;
-
- RangeToInclExpr(::std::unique_ptr<Expr> range_to, Location locus) :
- RangeExpr(locus), to(::std::move(range_to)) {}
- // outer attributes not allowed
-
- // Copy constructor with clone
- RangeToInclExpr(RangeToInclExpr const& other) :
- RangeExpr(other), to(other.to->clone_expr()) {}
-
- // Define destructor here if required
-
- // Overload assignment operator to clone pointer
- RangeToInclExpr& operator=(RangeToInclExpr const& other) {
- RangeExpr::operator=(other);
- to = other.to->clone_expr();
-
- return *this;
- }
-
- // move constructors
- RangeToInclExpr(RangeToInclExpr&& other) = default;
- RangeToInclExpr& operator=(RangeToInclExpr&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangeToInclExpr* clone_expr_impl() const OVERRIDE {
- return new RangeToInclExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangeToInclExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new RangeToInclExpr(*this);
- }
- };
-
- // Return expression AST node representation
- class ReturnExpr : public ExprWithoutBlock {
- // bool has_return_expr;
- // Expr* return_expr;
- ::std::unique_ptr<Expr> return_expr;
-
- Location locus;
-
- public:
- /*~ReturnExpr() {
- if (has_return_expr) {
- delete return_expr;
- }
- }*/
-
- ::std::string as_string() const;
-
- // Returns whether the object has an expression returned (i.e. not void return type).
- inline bool has_return_expr() const {
- return return_expr != NULL;
- }
-
- // Constructor for ReturnExpr.
- ReturnExpr(Location locus, ::std::unique_ptr<Expr> returned_expr = NULL,
- ::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- ExprWithoutBlock(::std::move(outer_attribs)),
- return_expr(::std::move(returned_expr)), locus(locus) {}
-
- // Copy constructor with clone
- ReturnExpr(ReturnExpr const& other) : ExprWithoutBlock(other), locus(other.locus) {
- // guard to protect from null pointer dereference
- if (other.return_expr != NULL) {
- return_expr = other.return_expr->clone_expr();
- }
- }
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone return_expr pointer
- ReturnExpr& operator=(ReturnExpr const& other) {
- ExprWithoutBlock::operator=(other);
- return_expr = other.return_expr->clone_expr();
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- ReturnExpr(ReturnExpr&& other) = default;
- ReturnExpr& operator=(ReturnExpr&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ReturnExpr* clone_expr_impl() const OVERRIDE {
- return new ReturnExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ReturnExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new ReturnExpr(*this);
- }
- };
-
- // Forward decl - defined in rust-macro.h
- class MacroInvocation;
- /*class MacroInvocation : public ExprWithoutBlock {
- public:
- ::std::string as_string() const;
- };*/
-
- // An unsafe block AST node
- class UnsafeBlockExpr : public ExprWithBlock {
- // Or just have it extend BlockExpr
- // BlockExpr* expr;
- ::std::unique_ptr<BlockExpr> expr;
-
- Location locus;
-
- public:
- /*~UnsafeBlockExpr() {
- delete expr;
- }*/
-
- ::std::string as_string() const;
-
- UnsafeBlockExpr(::std::unique_ptr<BlockExpr> block_expr,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- ExprWithBlock(::std::move(outer_attribs)),
- expr(::std::move(block_expr)), locus(locus) {}
-
- // Copy constructor with clone
- UnsafeBlockExpr(UnsafeBlockExpr const& other) :
- ExprWithBlock(other), expr(other.expr->clone_block_expr()), locus(other.locus) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone
- UnsafeBlockExpr& operator=(UnsafeBlockExpr const& other) {
- ExprWithBlock::operator=(other);
- expr = other.expr->clone_block_expr();
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- UnsafeBlockExpr(UnsafeBlockExpr&& other) = default;
- UnsafeBlockExpr& operator=(UnsafeBlockExpr&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual UnsafeBlockExpr* clone_expr_impl() const OVERRIDE {
- return new UnsafeBlockExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual UnsafeBlockExpr* clone_expr_with_block_impl() const OVERRIDE {
- return new UnsafeBlockExpr(*this);
- }
- };
-
- // Loop label expression AST node used with break and continue expressions
- // TODO: inline?
- class LoopLabel /*: public Node*/ {
- Lifetime label; // or type LIFETIME_OR_LABEL
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- LoopLabel(Lifetime loop_label, Location locus = Location()) :
- label(::std::move(loop_label)), locus(locus) {}
-
- // Returns whether the LoopLabel is in an error state.
- inline bool is_error() const {
- return label.is_error();
- }
-
- // Creates an error state LoopLabel.
- static LoopLabel error() {
- return LoopLabel(Lifetime::error());
- }
-
- Location get_locus() const {
- return locus;
- }
- };
-
- // Base loop expression AST node - aka LoopExpr
- class BaseLoopExpr : public ExprWithBlock {
- protected:
- // protected to allow subclasses better use of them
- // bool has_loop_label;
- LoopLabel loop_label;
-
- // BlockExpr* loop_block;
- ::std::unique_ptr<BlockExpr> loop_block;
-
- private:
- Location locus;
-
- protected:
- // Constructor for BaseLoopExpr
- BaseLoopExpr(::std::unique_ptr<BlockExpr> loop_block, Location locus,
- LoopLabel loop_label = LoopLabel::error(),
- ::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- ExprWithBlock(::std::move(outer_attribs)),
- loop_label(::std::move(loop_label)), loop_block(::std::move(loop_block)), locus(locus) {
- }
-
- // Copy constructor for BaseLoopExpr with clone
- BaseLoopExpr(BaseLoopExpr const& other) :
- ExprWithBlock(other), loop_label(other.loop_label),
- loop_block(other.loop_block->clone_block_expr()), locus(other.locus) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone
- BaseLoopExpr& operator=(BaseLoopExpr const& other) {
- ExprWithBlock::operator=(other);
- loop_block = other.loop_block->clone_block_expr();
- loop_label = other.loop_label;
- locus = other.locus;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- BaseLoopExpr(BaseLoopExpr&& other) = default;
- BaseLoopExpr& operator=(BaseLoopExpr&& other) = default;
-
- public:
- /*~BaseLoopExpr() {
- delete loop_block;
- }*/
-
- inline bool has_loop_label() const {
- return !loop_label.is_error();
- }
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
- };
-
- // 'Loop' expression (i.e. the infinite loop) AST node
- class LoopExpr : public BaseLoopExpr {
- public:
- ::std::string as_string() const;
-
- // Constructor for LoopExpr
- LoopExpr(::std::unique_ptr<BlockExpr> loop_block, Location locus,
- LoopLabel loop_label = LoopLabel::error(),
- ::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- BaseLoopExpr(::std::move(loop_block), locus, ::std::move(loop_label),
- ::std::move(outer_attribs)) {}
-
- // copy constructor, destructor, and assignment operator should not need modification
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual LoopExpr* clone_expr_impl() const OVERRIDE {
- return new LoopExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual LoopExpr* clone_expr_with_block_impl() const OVERRIDE {
- return new LoopExpr(*this);
- }
- };
-
- // While loop expression AST node (predicate loop)
- class WhileLoopExpr : public BaseLoopExpr {
- // Expr* condition;
- ::std::unique_ptr<Expr> condition;
-
- public:
- /*~WhileLoopExpr() {
- delete condition;
- }*/
-
- ::std::string as_string() const;
-
- // Constructor for while loop with loop label
- WhileLoopExpr(::std::unique_ptr<Expr> loop_condition,
- ::std::unique_ptr<BlockExpr> loop_block, Location locus,
- LoopLabel loop_label = LoopLabel::error(),
- ::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- BaseLoopExpr(
- ::std::move(loop_block), locus, ::std::move(loop_label), ::std::move(outer_attribs)),
- condition(::std::move(loop_condition)) {}
-
- // Copy constructor with clone
- WhileLoopExpr(WhileLoopExpr const& other) :
- BaseLoopExpr(other), condition(other.condition->clone_expr()) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone
- WhileLoopExpr& operator=(WhileLoopExpr const& other) {
- BaseLoopExpr::operator=(other);
- condition = other.condition->clone_expr();
- // loop_block = other.loop_block->clone_block_expr();
- // loop_label = other.loop_label;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- WhileLoopExpr(WhileLoopExpr&& other) = default;
- WhileLoopExpr& operator=(WhileLoopExpr&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual WhileLoopExpr* clone_expr_impl() const OVERRIDE {
- return new WhileLoopExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual WhileLoopExpr* clone_expr_with_block_impl() const OVERRIDE {
- return new WhileLoopExpr(*this);
- }
- };
-
- // Forward decl MatchArmPatterns
- // struct MatchArmPatterns;
-
- // While let loop expression AST node (predicate pattern loop)
- class WhileLetLoopExpr : public BaseLoopExpr {
- // MatchArmPatterns patterns;
- ::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns; // inlined
- // Expr* condition;
- ::std::unique_ptr<Expr> condition;
-
- public:
- /*~WhileLetLoopExpr() {
- delete condition;
- }*/
-
- ::std::string as_string() const;
-
- // Constructor with a loop label
- WhileLetLoopExpr(::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns,
- ::std::unique_ptr<Expr> condition, ::std::unique_ptr<BlockExpr> loop_block,
- Location locus, LoopLabel loop_label = LoopLabel::error(),
- ::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- BaseLoopExpr(
- ::std::move(loop_block), locus, ::std::move(loop_label), ::std::move(outer_attribs)),
- match_arm_patterns(::std::move(match_arm_patterns)), condition(::std::move(condition)) {
- }
-
- // Copy constructor with clone
- WhileLetLoopExpr(WhileLetLoopExpr const& other) :
- BaseLoopExpr(other), /*match_arm_patterns(other.match_arm_patterns),*/ condition(
- other.condition->clone_expr()) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- match_arm_patterns.reserve(other.match_arm_patterns.size());
-
- for (const auto& e : other.match_arm_patterns) {
- match_arm_patterns.push_back(e->clone_pattern());
- }
- }
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone pointers
- WhileLetLoopExpr& operator=(WhileLetLoopExpr const& other) {
- BaseLoopExpr::operator=(other);
- // match_arm_patterns = other.match_arm_patterns;
- condition = other.condition->clone_expr();
- // loop_block = other.loop_block->clone_block_expr();
- // loop_label = other.loop_label;
- // outer_attrs = other.outer_attrs;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- match_arm_patterns.reserve(other.match_arm_patterns.size());
-
- for (const auto& e : other.match_arm_patterns) {
- match_arm_patterns.push_back(e->clone_pattern());
- }
-
- return *this;
- }
-
- // move constructors
- WhileLetLoopExpr(WhileLetLoopExpr&& other) = default;
- WhileLetLoopExpr& operator=(WhileLetLoopExpr&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual WhileLetLoopExpr* clone_expr_impl() const OVERRIDE {
- return new WhileLetLoopExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual WhileLetLoopExpr* clone_expr_with_block_impl() const OVERRIDE {
- return new WhileLetLoopExpr(*this);
- }
- };
-
- // For loop expression AST node (iterator loop)
- class ForLoopExpr : public BaseLoopExpr {
- // Pattern pattern;
- ::std::unique_ptr<Pattern> pattern;
- // Expr* iterator_expr;
- ::std::unique_ptr<Expr> iterator_expr;
-
- public:
- /*~ForLoopExpr() {
- delete iterator_expr;
- }*/
-
- ::std::string as_string() const;
-
- // Constructor with loop label
- ForLoopExpr(::std::unique_ptr<Pattern> loop_pattern,
- ::std::unique_ptr<Expr> iterator_expr, ::std::unique_ptr<BlockExpr> loop_body,
- Location locus, LoopLabel loop_label = LoopLabel::error(),
- ::std::vector<Attribute> outer_attribs = ::std::vector<Attribute>()) :
- BaseLoopExpr(
- ::std::move(loop_body), locus, ::std::move(loop_label), ::std::move(outer_attribs)),
- pattern(::std::move(loop_pattern)), iterator_expr(::std::move(iterator_expr)) {}
-
- // Copy constructor with clone
- ForLoopExpr(ForLoopExpr const& other) :
- BaseLoopExpr(other), pattern(other.pattern->clone_pattern()),
- iterator_expr(other.iterator_expr->clone_expr()) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone
- ForLoopExpr& operator=(ForLoopExpr const& other) {
- BaseLoopExpr::operator=(other);
- pattern = other.pattern->clone_pattern();
- iterator_expr = other.iterator_expr->clone_expr();
- /*loop_block = other.loop_block->clone_block_expr();
- loop_label = other.loop_label;
- outer_attrs = other.outer_attrs;*/
-
- return *this;
- }
-
- // move constructors
- ForLoopExpr(ForLoopExpr&& other) = default;
- ForLoopExpr& operator=(ForLoopExpr&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ForLoopExpr* clone_expr_impl() const OVERRIDE {
- return new ForLoopExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ForLoopExpr* clone_expr_with_block_impl() const OVERRIDE {
- return new ForLoopExpr(*this);
- }
- };
-
- // forward decl for IfExpr
- class IfLetExpr;
-
- // Base if expression with no "else" or "if let" AST node
- class IfExpr : public ExprWithBlock {
- /*Expr* condition;
- BlockExpr* if_block;*/
- ::std::unique_ptr<Expr> condition;
- ::std::unique_ptr<BlockExpr> if_block;
- /*union {
- BlockExpr else_block;
- IfExpr* if_expr;
- IfLetExpr if_let_expr;
- } consequent_block;*/
-
- Location locus;
-
- public:
- /*virtual ~IfExpr() {
- delete condition;
- delete if_block;
- }*/
-
- ::std::string as_string() const;
-
- IfExpr(::std::unique_ptr<Expr> condition, ::std::unique_ptr<BlockExpr> if_block,
- Location locus) :
- ExprWithBlock(::std::vector<Attribute>()),
- condition(::std::move(condition)), if_block(::std::move(if_block)), locus(locus) {}
- // outer attributes are never allowed on IfExprs
-
- // Copy constructor with clone
- IfExpr(IfExpr const& other) :
- ExprWithBlock(other), condition(other.condition->clone_expr()),
- if_block(other.if_block->clone_block_expr()), locus(other.locus) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone expressions
- IfExpr& operator=(IfExpr const& other) {
- ExprWithBlock::operator=(other);
- condition = other.condition->clone_expr();
- if_block = other.if_block->clone_block_expr();
- locus = other.locus;
-
- return *this;
- }
-
- // move constructors
- IfExpr(IfExpr&& other) = default;
- IfExpr& operator=(IfExpr&& other) = default;
-
- // Unique pointer custom clone function
- ::std::unique_ptr<IfExpr> clone_if_expr() const {
- return ::std::unique_ptr<IfExpr>(clone_if_expr_impl());
- }
-
- /* Note that multiple "else if"s are handled via nested ASTs rather than a vector of
- * else ifs - i.e. not like a switch statement. TODO - is this a better approach? or
- * does it not parse correctly and have downsides? */
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfExpr* clone_expr_impl() const OVERRIDE {
- return new IfExpr(*this);
- }
-
- // Base clone function but still concrete as concrete base class
- virtual IfExpr* clone_if_expr_impl() const {
- return new IfExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfExpr* clone_expr_with_block_impl() const OVERRIDE {
- return new IfExpr(*this);
- }
- };
-
- // If expression with an ending "else" expression AST node (trailing)
- class IfExprConseqElse : public IfExpr {
- // BlockExpr* else_block;
- ::std::unique_ptr<BlockExpr> else_block;
-
- public:
- /*~IfExprConseqElse() {
- delete else_block;
- }*/
-
- ::std::string as_string() const;
-
- IfExprConseqElse(::std::unique_ptr<Expr> condition, ::std::unique_ptr<BlockExpr> if_block,
- ::std::unique_ptr<BlockExpr> else_block, Location locus) :
- IfExpr(::std::move(condition), ::std::move(if_block), locus),
- else_block(::std::move(else_block)) {}
- // again, outer attributes not allowed
-
- // Copy constructor with clone
- IfExprConseqElse(IfExprConseqElse const& other) :
- IfExpr(other), else_block(other.else_block->clone_block_expr()) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator with cloning
- IfExprConseqElse& operator=(IfExprConseqElse const& other) {
- IfExpr::operator=(other);
- // condition = other.condition->clone_expr();
- // if_block = other.if_block->clone_block_expr();
- else_block = other.else_block->clone_block_expr();
-
- return *this;
- }
-
- // move constructors
- IfExprConseqElse(IfExprConseqElse&& other) = default;
- IfExprConseqElse& operator=(IfExprConseqElse&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfExprConseqElse* clone_expr_impl() const OVERRIDE {
- return new IfExprConseqElse(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfExprConseqElse* clone_expr_with_block_impl() const OVERRIDE {
- return new IfExprConseqElse(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfExprConseqElse* clone_if_expr_impl() const OVERRIDE {
- return new IfExprConseqElse(*this);
- }
- };
-
- // If expression with an ending "else if" expression AST node
- class IfExprConseqIf : public IfExpr {
- // IfExpr* if_expr;
- ::std::unique_ptr<IfExpr> if_expr;
-
- public:
- /*~IfExprConseqIf() {
- delete if_expr;
- }*/
-
- ::std::string as_string() const;
-
- IfExprConseqIf(::std::unique_ptr<Expr> condition, ::std::unique_ptr<BlockExpr> if_block,
- ::std::unique_ptr<IfExpr> conseq_if_expr, Location locus) :
- IfExpr(::std::move(condition), ::std::move(if_block), locus),
- if_expr(::std::move(conseq_if_expr)) {}
- // outer attributes not allowed
-
- // Copy constructor with clone
- IfExprConseqIf(IfExprConseqIf const& other) :
- IfExpr(other), if_expr(other.if_expr->clone_if_expr()) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to use clone
- IfExprConseqIf& operator=(IfExprConseqIf const& other) {
- IfExpr::operator=(other);
- // condition = other.condition->clone_expr();
- // if_block = other.if_block->clone_block_expr();
- if_expr = other.if_expr->clone_if_expr();
-
- return *this;
- }
-
- // move constructors
- IfExprConseqIf(IfExprConseqIf&& other) = default;
- IfExprConseqIf& operator=(IfExprConseqIf&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfExprConseqIf* clone_expr_impl() const OVERRIDE {
- return new IfExprConseqIf(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfExprConseqIf* clone_expr_with_block_impl() const OVERRIDE {
- return new IfExprConseqIf(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfExprConseqIf* clone_if_expr_impl() const OVERRIDE {
- return new IfExprConseqIf(*this);
- }
- };
-
- // Basic "if let" expression AST node with no else
- class IfLetExpr : public ExprWithBlock {
- // MatchArmPatterns patterns;
- ::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns; // inlined
- /*Expr* value;
- BlockExpr* if_block;*/
- ::std::unique_ptr<Expr> value;
- ::std::unique_ptr<BlockExpr> if_block;
- /*union {
- BlockExpr else_block;
- IfExpr if_expr;
- IfLetExpr* if_let_expr;
- } consequent_block;*/
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- IfLetExpr(::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns,
- ::std::unique_ptr<Expr> value, ::std::unique_ptr<BlockExpr> if_block, Location locus) :
- ExprWithBlock(::std::vector<Attribute>()),
- match_arm_patterns(::std::move(match_arm_patterns)), value(::std::move(value)),
- if_block(::std::move(if_block)), locus(locus) {}
- // outer attributes not allowed on if let exprs either
-
- // copy constructor with clone
- IfLetExpr(IfLetExpr const& other) :
- ExprWithBlock(other),
- /*match_arm_patterns(other.match_arm_patterns),*/ value(other.value->clone_expr()),
- if_block(other.if_block->clone_block_expr()), locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- match_arm_patterns.reserve(other.match_arm_patterns.size());
-
- for (const auto& e : other.match_arm_patterns) {
- match_arm_patterns.push_back(e->clone_pattern());
- }
- }
-
- // destructor - define here if required
-
- // overload assignment operator to clone
- IfLetExpr& operator=(IfLetExpr const& other) {
- ExprWithBlock::operator=(other);
- // match_arm_patterns = other.match_arm_patterns;
- value = other.value->clone_expr();
- if_block = other.if_block->clone_block_expr();
- locus = other.locus;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- match_arm_patterns.reserve(other.match_arm_patterns.size());
-
- for (const auto& e : other.match_arm_patterns) {
- match_arm_patterns.push_back(e->clone_pattern());
- }
-
- return *this;
- }
-
- // move constructors
- IfLetExpr(IfLetExpr&& other) = default;
- IfLetExpr& operator=(IfLetExpr&& other) = default;
-
- // Unique pointer custom clone function
- ::std::unique_ptr<IfLetExpr> clone_if_let_expr() const {
- return ::std::unique_ptr<IfLetExpr>(clone_if_let_expr_impl());
- }
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfLetExpr* clone_expr_impl() const OVERRIDE {
- return new IfLetExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfLetExpr* clone_expr_with_block_impl() const OVERRIDE {
- return new IfLetExpr(*this);
- }
-
- // Base clone function but still concrete as concrete base class
- virtual IfLetExpr* clone_if_let_expr_impl() const {
- return new IfLetExpr(*this);
- }
- };
-
- // If expression with an ending "else if let" expression AST node
- class IfExprConseqIfLet : public IfExpr {
- // IfLetExpr* if_let_expr;
- ::std::unique_ptr<IfLetExpr> if_let_expr;
-
- public:
- /*~IfExprIfConseqIfLet() {
- delete if_let_expr;
- }*/
-
- ::std::string as_string() const;
-
- IfExprConseqIfLet(::std::unique_ptr<Expr> condition,
- ::std::unique_ptr<BlockExpr> if_block, ::std::unique_ptr<IfLetExpr> conseq_if_let_expr,
- Location locus) :
- IfExpr(::std::move(condition), ::std::move(if_block), locus),
- if_let_expr(::std::move(conseq_if_let_expr)) {}
- // outer attributes not allowed
-
- // Copy constructor with clone
- IfExprConseqIfLet(IfExprConseqIfLet const& other) :
- IfExpr(other), if_let_expr(other.if_let_expr->clone_if_let_expr()) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to use clone
- IfExprConseqIfLet& operator=(IfExprConseqIfLet const& other) {
- IfExpr::operator=(other);
- // condition = other.condition->clone_expr();
- // if_block = other.if_block->clone_block_expr();
- if_let_expr = other.if_let_expr->clone_if_let_expr();
-
- return *this;
- }
-
- // move constructors
- IfExprConseqIfLet(IfExprConseqIfLet&& other) = default;
- IfExprConseqIfLet& operator=(IfExprConseqIfLet&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfExprConseqIfLet* clone_expr_impl() const OVERRIDE {
- return new IfExprConseqIfLet(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfExprConseqIfLet* clone_expr_with_block_impl() const OVERRIDE {
- return new IfExprConseqIfLet(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfExprConseqIfLet* clone_if_expr_impl() const OVERRIDE {
- return new IfExprConseqIfLet(*this);
- }
- };
-
- // AST node representing "if let" expression with an "else" expression at the end
- class IfLetExprConseqElse : public IfLetExpr {
- // BlockExpr* else_block;
- ::std::unique_ptr<BlockExpr> else_block;
-
- public:
- /*~IfLetExprConseqElse() {
- delete else_block;
- }*/
-
- ::std::string as_string() const;
-
- IfLetExprConseqElse(::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns,
- ::std::unique_ptr<Expr> value, ::std::unique_ptr<BlockExpr> if_block,
- ::std::unique_ptr<BlockExpr> else_block, Location locus) :
- IfLetExpr(
- ::std::move(match_arm_patterns), ::std::move(value), ::std::move(if_block), locus),
- else_block(::std::move(else_block)) {}
- // outer attributes not allowed
-
- // copy constructor with clone
- IfLetExprConseqElse(IfLetExprConseqElse const& other) :
- IfLetExpr(other), else_block(other.else_block->clone_block_expr()) {}
-
- // destructor - define here if required
-
- // overload assignment operator to clone
- IfLetExprConseqElse& operator=(IfLetExprConseqElse const& other) {
- IfLetExpr::operator=(other);
- // match_arm_patterns = other.match_arm_patterns;
- // value = other.value->clone_expr();
- // if_block = other.if_block->clone_block_expr();
- else_block = other.else_block->clone_block_expr();
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- IfLetExprConseqElse(IfLetExprConseqElse&& other) = default;
- IfLetExprConseqElse& operator=(IfLetExprConseqElse&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfLetExprConseqElse* clone_expr_impl() const OVERRIDE {
- return new IfLetExprConseqElse(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfLetExprConseqElse* clone_expr_with_block_impl() const OVERRIDE {
- return new IfLetExprConseqElse(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfLetExprConseqElse* clone_if_let_expr_impl() const OVERRIDE {
- return new IfLetExprConseqElse(*this);
- }
- };
-
- // AST node representing "if let" expression with an "else if" expression at the end
- class IfLetExprConseqIf : public IfLetExpr {
- // IfExpr* if_expr;
- ::std::unique_ptr<IfExpr> if_expr;
-
- public:
- /*~IfLetExprConseqIf() {
- delete if_expr;
- }*/
-
- ::std::string as_string() const;
-
- IfLetExprConseqIf(::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns,
- ::std::unique_ptr<Expr> value, ::std::unique_ptr<BlockExpr> if_block,
- ::std::unique_ptr<IfExpr> if_expr, Location locus) :
- IfLetExpr(
- ::std::move(match_arm_patterns), ::std::move(value), ::std::move(if_block), locus),
- if_expr(::std::move(if_expr)) {}
- // again, outer attributes not allowed
-
- // copy constructor with clone
- IfLetExprConseqIf(IfLetExprConseqIf const& other) :
- IfLetExpr(other), if_expr(other.if_expr->clone_if_expr()) {}
-
- // destructor - define here if required
-
- // overload assignment operator to clone
- IfLetExprConseqIf& operator=(IfLetExprConseqIf const& other) {
- IfLetExpr::operator=(other);
- // match_arm_patterns = other.match_arm_patterns;
- // value = other.value->clone_expr();
- // if_block = other.if_block->clone_block_expr();
- if_expr = other.if_expr->clone_if_expr();
-
- return *this;
- }
-
- // move constructors
- IfLetExprConseqIf(IfLetExprConseqIf&& other) = default;
- IfLetExprConseqIf& operator=(IfLetExprConseqIf&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfLetExprConseqIf* clone_expr_impl() const OVERRIDE {
- return new IfLetExprConseqIf(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfLetExprConseqIf* clone_expr_with_block_impl() const OVERRIDE {
- return new IfLetExprConseqIf(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfLetExprConseqIf* clone_if_let_expr_impl() const OVERRIDE {
- return new IfLetExprConseqIf(*this);
- }
- };
-
- // AST node representing "if let" expression with an "else if let" expression at the end
- class IfLetExprConseqIfLet : public IfLetExpr {
- // IfLetExpr* if_let_expr;
- ::std::unique_ptr<IfLetExpr> if_let_expr;
-
- public:
- /*~IfLetExprConseqIfLet() {
- delete if_let_expr;
- }*/
-
- ::std::string as_string() const;
-
- IfLetExprConseqIfLet(::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns,
- ::std::unique_ptr<Expr> value, ::std::unique_ptr<BlockExpr> if_block,
- ::std::unique_ptr<IfLetExpr> if_let_expr, Location locus) :
- IfLetExpr(
- ::std::move(match_arm_patterns), ::std::move(value), ::std::move(if_block), locus),
- if_let_expr(::std::move(if_let_expr)) {}
- // outer attributes not allowed
-
- // copy constructor with clone
- IfLetExprConseqIfLet(IfLetExprConseqIfLet const& other) :
- IfLetExpr(other), if_let_expr(other.if_let_expr->clone_if_let_expr()) {}
-
- // destructor - define here if required
-
- // overload assignment operator to clone
- IfLetExprConseqIfLet& operator=(IfLetExprConseqIfLet const& other) {
- IfLetExpr::operator=(other);
- // match_arm_patterns = other.match_arm_patterns;
- // value = other.value->clone_expr();
- // if_block = other.if_block->clone_block_expr();
- if_let_expr = other.if_let_expr->clone_if_let_expr();
-
- return *this;
- }
-
- // move constructors
- IfLetExprConseqIfLet(IfLetExprConseqIfLet&& other) = default;
- IfLetExprConseqIfLet& operator=(IfLetExprConseqIfLet&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfLetExprConseqIfLet* clone_expr_impl() const OVERRIDE {
- return new IfLetExprConseqIfLet(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfLetExprConseqIfLet* clone_expr_with_block_impl() const OVERRIDE {
- return new IfLetExprConseqIfLet(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual IfLetExprConseqIfLet* clone_if_let_expr_impl() const OVERRIDE {
- return new IfLetExprConseqIfLet(*this);
- }
- };
-
- // Match arm expression
- struct MatchArm {
- private:
- ::std::vector<Attribute> outer_attrs;
- // MatchArmPatterns patterns;
- ::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns; // inlined
-
- // bool has_match_arm_guard;
- // Expr* match_arm_guard; // inlined from MatchArmGuard
- ::std::unique_ptr<Expr> guard_expr;
-
- // TODO: should this store location data?
-
- public:
- /*~MatchArm() {
- if (has_match_arm_guard) {
- delete match_arm_guard;
- }
- }*/
-
- // Returns whether the MatchArm has a match arm guard expression
- inline bool has_match_arm_guard() const {
- return guard_expr != NULL;
- }
-
- // Constructor for match arm with a guard expression
- MatchArm(::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns,
- ::std::unique_ptr<Expr> guard_expr = NULL,
- ::std::vector<Attribute> outer_attrs = ::std::vector<Attribute>()) :
- outer_attrs(::std::move(outer_attrs)),
- match_arm_patterns(::std::move(match_arm_patterns)),
- guard_expr(::std::move(guard_expr)) {}
-
- // Copy constructor with clone
- MatchArm(MatchArm const& other) :
- /*match_arm_patterns(other.match_arm_patterns),*/ outer_attrs(other.outer_attrs) {
- // guard to protect from null pointer dereference
- if (other.guard_expr != NULL) {
- guard_expr = other.guard_expr->clone_expr();
- }
-
- // DEBUG
- fprintf(
- stderr, "started copy-constructing match arm (outer attrs, guard expr done)\n");
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- match_arm_patterns.reserve(other.match_arm_patterns.size());
-
- for (const auto& e : other.match_arm_patterns) {
- match_arm_patterns.push_back(e->clone_pattern());
-
- // DEBUG
- fprintf(stderr, "successfully pushed back a match arm pattern\n");
- }
-
- // DEBUG
- fprintf(stderr, "successfully copy-constructed match arm\n");
- }
-
- ~MatchArm() = default;
-
- // Overload assignment operator to clone
- MatchArm& operator=(MatchArm const& other) {
- // match_arm_patterns = other.match_arm_patterns;
- outer_attrs = other.outer_attrs;
- guard_expr = other.guard_expr->clone_expr();
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- match_arm_patterns.reserve(other.match_arm_patterns.size());
-
- for (const auto& e : other.match_arm_patterns) {
- match_arm_patterns.push_back(e->clone_pattern());
- }
-
- return *this;
- }
-
- // move constructors
- MatchArm(MatchArm&& other) = default;
- MatchArm& operator=(MatchArm&& other) = default;
-
- // Returns whether match arm is in an error state.
- inline bool is_error() const {
- return match_arm_patterns.empty();
- }
-
- // Creates a match arm in an error state.
- static MatchArm create_error() {
- return MatchArm(::std::vector< ::std::unique_ptr<Pattern> >());
- }
-
- ::std::string as_string() const;
- };
-
- // Base "match case" for a match expression - abstract
- class MatchCase {
- MatchArm arm;
-
- protected:
- MatchCase(MatchArm arm) : arm(::std::move(arm)) {}
-
- // Should not require copy constructor or assignment operator overloading
-
- // Clone function implementation as pure virtual method
- virtual MatchCase* clone_match_case_impl() const = 0;
-
- public:
- virtual ~MatchCase() {}
-
- // Unique pointer custom clone function
- ::std::unique_ptr<MatchCase> clone_match_case() const {
- // DEBUG
- fprintf(stderr, "about to call clone match case impl\n");
-
- return ::std::unique_ptr<MatchCase>(clone_match_case_impl());
- }
-
- virtual ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
- };
-
- // Block expression match case
- class MatchCaseBlockExpr : public MatchCase {
- // BlockExpr* block_expr;
- ::std::unique_ptr<BlockExpr> block_expr;
-
- // TODO: should this store location data?
-
- public:
- /*~MatchCaseBlockExpr() {
- delete block_expr;
- }*/
-
- MatchCaseBlockExpr(MatchArm arm, ::std::unique_ptr<BlockExpr> block_expr) :
- MatchCase(::std::move(arm)), block_expr(::std::move(block_expr)) {}
-
- // Copy constructor requires clone
- MatchCaseBlockExpr(MatchCaseBlockExpr const& other) :
- MatchCase(other), block_expr(other.block_expr->clone_block_expr()) {
- // DEBUG
- fprintf(stderr, "successfully copy constructed match case expr\n");
- }
-
- // Destructor - define here if required
-
- // Overload assignment operator to have clone
- MatchCaseBlockExpr& operator=(MatchCaseBlockExpr const& other) {
- MatchCase::operator=(other);
- block_expr = other.block_expr->clone_block_expr();
- // arm = other.arm;
-
- return *this;
- }
-
- // move constructors
- MatchCaseBlockExpr(MatchCaseBlockExpr&& other) = default;
- MatchCaseBlockExpr& operator=(MatchCaseBlockExpr&& other) = default;
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual MatchCaseBlockExpr* clone_match_case_impl() const OVERRIDE {
- // DEBUG
- fprintf(stderr, "about to copy construct match case block expr\n");
-
- return new MatchCaseBlockExpr(*this);
- }
- };
-
- // Expression (except block expression) match case
- class MatchCaseExpr : public MatchCase {
- // Expr* expr;
- ::std::unique_ptr<Expr> expr;
-
- // TODO: should this store location data?
-
- public:
- /*~MatchCaseExpr() {
- delete expr;
- }*/
-
- MatchCaseExpr(MatchArm arm, ::std::unique_ptr<Expr> expr) :
- MatchCase(::std::move(arm)), expr(::std::move(expr)) {}
-
- // Copy constructor requires clone
- MatchCaseExpr(MatchCaseExpr const& other) :
- MatchCase(other), expr(other.expr->clone_expr()) {
- // DEBUG
- fprintf(stderr, "successfully copy constructed match case expr\n");
- }
-
- // Destructor - define here if required
+namespace AST {
+/* TODO: if GCC moves to C++17 or allows boost, replace some boolean
+ * "has_whatever" pairs with
+ * optional types (std::optional or boost::optional)? */
+
+// forward decls: defined in rust-path.h, rust-type.h, rust-pattern.h, and
+// rust-stmt.h
+/*class PathInExpression;
+class QualifiedPathInExpression;
+class PathExprSegment;*/ // decls no longer required as "rust-path.h" is included
+/*class Type;
+class TypeNoBounds;
+class Lifetime;
+class Pattern;
+class Statement;*/ // decls no longer required as definitions moved to rust-ast.h
+
+// Decl as definition moved to rust-ast.h
+class ExprWithoutBlock;
+
+// AST node for an expression with an accompanying block - abstract
+class ExprWithBlock : public Expr
+{
+ // TODO: should this mean that a BlockExpr should be a member variable?
+protected:
+ ExprWithBlock (::std::vector<Attribute> outer_attrs
+ = ::std::vector<Attribute> ())
+ : Expr (::std::move (outer_attrs))
+ {}
+
+ // pure virtual clone implementation
+ virtual ExprWithBlock *clone_expr_with_block_impl () const = 0;
+
+ // prevent having to define multiple clone expressions
+ virtual ExprWithBlock *clone_expr_impl () const OVERRIDE
+ {
+ return clone_expr_with_block_impl ();
+ }
+
+public:
+ // Unique pointer custom clone function
+ ::std::unique_ptr<ExprWithBlock> clone_expr_with_block () const
+ {
+ return ::std::unique_ptr<ExprWithBlock> (clone_expr_with_block_impl ());
+ }
+};
+
+// Literals? Or literal base?
+class LiteralExpr : public ExprWithoutBlock
+{
+ /*public:
+ enum LitType {
+ CHAR,
+ STRING,
+ RAW_STRING,
+ BYTE,
+ BYTE_STRING,
+ RAW_BYTE_STRING,
+ INT,
+ FLOAT,
+ BOOL
+ };
+
+ private:
+ // TODO: maybe make subclasses of each type of literal with their typed
+ values (or
+ // generics)
+ ::std::string value_as_string;
+ LitType type;*/
+ // moved to Literal
+ Literal literal;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const { return literal.as_string (); }
+
+ inline Literal::LitType get_lit_type () const
+ {
+ return literal.get_lit_type ();
+ }
+
+ LiteralExpr (::std::string value_as_string, Literal::LitType type,
+ Location locus,
+ ::std::vector<Attribute> outer_attrs
+ = ::std::vector<Attribute> ())
+ : ExprWithoutBlock (::std::move (outer_attrs)),
+ literal (::std::move (value_as_string), type), locus (locus)
+ {}
+
+ LiteralExpr (Literal literal, Location locus,
+ ::std::vector<Attribute> outer_attrs
+ = ::std::vector<Attribute> ())
+ : ExprWithoutBlock (::std::move (outer_attrs)),
+ literal (::std::move (literal)), locus (locus)
+ {}
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<LiteralExpr> clone_literal_expr () const
+ {
+ return ::std::unique_ptr<LiteralExpr> (clone_literal_expr_impl ());
+ }
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual LiteralExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new LiteralExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual LiteralExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new LiteralExpr (*this);
+ }
+
+ // not virtual as currently no subclasses of LiteralExpr, but could be in
+ // future
+ /*virtual*/ LiteralExpr *clone_literal_expr_impl () const
+ {
+ return new LiteralExpr (*this);
+ }
+};
+
+// Literal expression attribute body (non-macro attribute)
+class AttrInputLiteral : public AttrInput
+{
+ // Literal expression WITHOUT SUFFIX
+ // LiteralExpr* literal_expr;
+ //::std::unique_ptr<LiteralExpr> literal_expr;
+ LiteralExpr
+ literal_expr; // as not using polymorphic behaviour, doesn't require pointer
+ // TODO: will require pointer if LiteralExpr is changed to have subclassing
+
+ // TODO: should this store location data?
+
+public:
+ AttrInputLiteral (LiteralExpr lit_expr)
+ : literal_expr (::std::move (lit_expr))
+ {}
+ /*~AttrInputLiteral() {
+ delete literal_expr;
+ }*/
+
+ ::std::string as_string () const { return " = " + literal_expr.as_string (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ // this can never be a cfg predicate - cfg and cfg_attr require a token-tree
+ // cfg
+ virtual bool
+ check_cfg_predicate (const Session &session ATTRIBUTE_UNUSED) const OVERRIDE
+ {
+ // TODO: ensure this is true
+ // DEBUG
+ fprintf (stderr, "check_cfg_predicate call went to AttrInputLiteral - "
+ "should not happen?\n");
+
+ return false;
+ }
+
+protected:
+ // Use covariance to implement clone function as returning an AttrInputLiteral
+ // object
+ virtual AttrInputLiteral *clone_attr_input_impl () const OVERRIDE
+ {
+ return new AttrInputLiteral (*this);
+ }
+};
+
+// literal expr only meta item inner - TODO possibly replace with inheritance of
+// LiteralExpr itself?
+class MetaItemLitExpr : public MetaItemInner
+{
+ LiteralExpr lit_expr;
+
+public:
+ MetaItemLitExpr (LiteralExpr lit_expr) : lit_expr (::std::move (lit_expr)) {}
+
+ ::std::string as_string () const OVERRIDE { return lit_expr.as_string (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ virtual bool check_cfg_predicate (const Session &session) const OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this type
+ virtual MetaItemLitExpr *clone_meta_item_inner_impl () const OVERRIDE
+ {
+ return new MetaItemLitExpr (*this);
+ }
+};
+
+// more generic meta item "path = lit" form
+class MetaItemPathLit : public MetaItem
+{
+ SimplePath path;
+ LiteralExpr lit;
+
+public:
+ MetaItemPathLit (SimplePath path, LiteralExpr lit_expr)
+ : path (::std::move (path)), lit (::std::move (lit_expr))
+ {}
+
+ ::std::string as_string () const OVERRIDE
+ {
+ return path.as_string () + " = " + lit.as_string ();
+ }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ virtual bool check_cfg_predicate (const Session &session) const OVERRIDE;
+ // TODO: return true if "ident" is defined and value of it is "lit", return
+ // false otherwise
+
+protected:
+ // Use covariance to implement clone function as returning this type
+ virtual MetaItemPathLit *clone_meta_item_inner_impl () const OVERRIDE
+ {
+ return new MetaItemPathLit (*this);
+ }
+};
+
+// AST node for a non-qualified path expression - FIXME: should this be
+// inheritance instead?
+/*class PathExprNonQual : public PathExpr {
+ PathInExpression path;
+
+ public:
+ ::std::string as_string() const {
+ return path.as_string();
+ }
- // Overload assignment operator to have clone
- MatchCaseExpr& operator=(MatchCaseExpr const& other) {
- MatchCase::operator=(other);
- expr = other.expr->clone_expr();
- // arm = other.arm;
+ PathExprNonQual(PathInExpression path, ::std::vector<Attribute>
+outer_attribs) : PathExpr(::std::move(outer_attribs)), path(::std::move(path))
+{}
- return *this;
- }
+ protected:
+ // Use covariance to implement clone function as returning this object
+rather than base virtual PathExprNonQual* clone_expr_impl() const OVERRIDE {
+ return new PathExprNonQual(*this);
+ }
- // move constructors
- MatchCaseExpr(MatchCaseExpr&& other) = default;
- MatchCaseExpr& operator=(MatchCaseExpr&& other) = default;
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
+ // Use covariance to implement clone function as returning this object
+rather than base virtual PathExprNonQual* clone_expr_without_block_impl() const
+OVERRIDE { return new PathExprNonQual(*this);
+ }
+};*/
+// converted to inheritance
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual MatchCaseExpr* clone_match_case_impl() const OVERRIDE {
- // DEBUG
- fprintf(stderr, "about to copy construct match case expr\n");
- if (expr == NULL) {
- fprintf(
- stderr, "warning: match case expr to be copy constructed has null expr!\n");
- }
-
- return new MatchCaseExpr(*this);
- }
- };
-
- // Match expression AST node
- class MatchExpr : public ExprWithBlock {
- // Expr* branch_value;
- ::std::unique_ptr<Expr> branch_value;
- ::std::vector<Attribute> inner_attrs;
-
- // bool has_match_arms;
- // MatchArms match_arms;
- ::std::vector< ::std::unique_ptr<MatchCase> > match_arms; // inlined from MatchArms
-
- Location locus;
-
- public:
- /*~MatchExpr() {
- delete branch_value;
- }*/
-
- ::std::string as_string() const;
-
- // Returns whether the match expression has any match arms.
- inline bool has_match_arms() const {
- return !match_arms.empty();
- }
-
- MatchExpr(::std::unique_ptr<Expr> branch_value,
- ::std::vector< ::std::unique_ptr<MatchCase> > match_arms,
- ::std::vector<Attribute> inner_attrs, ::std::vector<Attribute> outer_attrs,
- Location locus) :
- ExprWithBlock(::std::move(outer_attrs)),
- branch_value(::std::move(branch_value)), inner_attrs(::std::move(inner_attrs)),
- match_arms(::std::move(match_arms)), locus(locus) {}
-
- // Copy constructor requires clone due to unique_ptr
- MatchExpr(MatchExpr const& other) :
- ExprWithBlock(other),
- branch_value(other.branch_value->clone_expr()), /*match_arms(other.match_arms),*/
- inner_attrs(other.inner_attrs), locus(other.locus) {
- fprintf(stderr, "copy constructor for matchexpr called - only match arm vector "
- "copying after this\n");
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- match_arms.reserve(other.match_arms.size());
-
- fprintf(stderr, "match expr: successfully reserved size\n");
-
- for (const auto& e : other.match_arms) {
- match_arms.push_back(e->clone_match_case());
- fprintf(stderr, "match expr: successfully pushed back a match case\n");
- }
-
- fprintf(stderr, "match expr: successfully pushed back all match cases\n");
- }
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone due to unique_ptr
- MatchExpr& operator=(MatchExpr const& other) {
- ExprWithBlock::operator=(other);
- branch_value = other.branch_value->clone_expr();
- // match_arms = other.match_arms;
- inner_attrs = other.inner_attrs;
- // outer_attrs = other.outer_attrs;
- locus = other.locus;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- match_arms.reserve(other.match_arms.size());
-
- for (const auto& e : other.match_arms) {
- match_arms.push_back(e->clone_match_case());
- }
-
- return *this;
- }
-
- // move constructors
- MatchExpr(MatchExpr&& other) = default;
- MatchExpr& operator=(MatchExpr&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual MatchExpr* clone_expr_impl() const OVERRIDE {
- return new MatchExpr(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual MatchExpr* clone_expr_with_block_impl() const OVERRIDE {
- return new MatchExpr(*this);
- }
- };
-
- // Await expression AST node (pseudo-member variable access)
- class AwaitExpr : public ExprWithoutBlock {
- ::std::unique_ptr<Expr> awaited_expr;
-
- Location locus;
-
- public:
- // TODO: ensure outer attributes are actually allowed
- AwaitExpr(::std::unique_ptr<Expr> awaited_expr, ::std::vector<Attribute> outer_attrs,
- Location locus) :
- ExprWithoutBlock(::std::move(outer_attrs)),
- awaited_expr(::std::move(awaited_expr)), locus(locus) {}
-
- // copy constructor with clone
- AwaitExpr(AwaitExpr const& other) :
- ExprWithoutBlock(other), awaited_expr(other.awaited_expr->clone_expr()),
- locus(other.locus) {}
-
- // destructor - define here if required
-
- // overloaded assignment operator with clone
- AwaitExpr& operator=(AwaitExpr const& other) {
- ExprWithoutBlock::operator=(other);
- awaited_expr = other.awaited_expr->clone_expr();
- locus = other.locus;
-
- return *this;
- }
-
- // move constructors
- AwaitExpr(AwaitExpr&& other) = default;
- AwaitExpr& operator=(AwaitExpr&& other) = default;
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
+// AST node for a qualified path expression - FIXME: should this be inheritance
+// instead?
+/*class PathExprQual : public PathExpr {
+ QualifiedPathInExpression path;
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
+ public:
+ ::std::string as_string() const {
+ return path.as_string();
+ }
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual AwaitExpr* clone_expr_without_block_impl() const OVERRIDE {
- return new AwaitExpr(*this);
- }
- };
-
- // Async block expression AST node (block expr that evaluates to a future)
- class AsyncBlockExpr : public ExprWithBlock {
- // TODO: should this extend BlockExpr rather than be a composite of it?
- bool has_move;
- ::std::unique_ptr<BlockExpr> block_expr;
-
- Location locus;
-
- public:
- AsyncBlockExpr(::std::unique_ptr<BlockExpr> block_expr, bool has_move,
- ::std::vector<Attribute> outer_attrs, Location locus) :
- ExprWithBlock(::std::move(outer_attrs)),
- has_move(has_move), block_expr(::std::move(block_expr)), locus(locus) {}
-
- // copy constructor with clone
- AsyncBlockExpr(AsyncBlockExpr const& other) :
- ExprWithBlock(other), has_move(other.has_move),
- block_expr(other.block_expr->clone_block_expr()), locus(other.locus) {}
+ PathExprQual(QualifiedPathInExpression path, ::std::vector<Attribute>
+outer_attribs) : PathExpr(::std::move(outer_attribs)), path(::std::move(path))
+{}
- // destructor - define if required
-
- // overloaded assignment operator to clone
- AsyncBlockExpr& operator=(AsyncBlockExpr const& other) {
- ExprWithBlock::operator=(other);
- has_move = other.has_move;
- block_expr = other.block_expr->clone_block_expr();
- locus = other.locus;
-
- return *this;
- }
-
- // move constructors
- AsyncBlockExpr(AsyncBlockExpr&& other) = default;
- AsyncBlockExpr& operator=(AsyncBlockExpr&& other) = default;
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
+ protected:
+ // Use covariance to implement clone function as returning this object
+rather than base virtual PathExprQual* clone_expr_impl() const OVERRIDE { return
+new PathExprQual(*this);
+ }
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual AsyncBlockExpr* clone_expr_with_block_impl() const OVERRIDE {
- return new AsyncBlockExpr(*this);
- }
- };
+ // Use covariance to implement clone function as returning this object
+rather than base virtual PathExprQual* clone_expr_without_block_impl() const
+OVERRIDE { return new PathExprQual(*this);
}
-}
+};*/
+// replaced with inheritance
+
+// Represents an expression using unary or binary operators as AST node. Can be
+// overloaded.
+class OperatorExpr : public ExprWithoutBlock
+{
+ // TODO: create binary and unary operator subclasses?
+
+ Location locus;
+
+protected:
+ // Variable must be protected to allow derived classes to use it as a first
+ // class citizen Expr* main_or_left_expr;
+ ::std::unique_ptr<Expr> main_or_left_expr;
+
+ // Constructor (only for initialisation of expr purposes)
+ OperatorExpr (::std::unique_ptr<Expr> main_or_left_expr,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : ExprWithoutBlock (::std::move (outer_attribs)), locus (locus),
+ main_or_left_expr (::std::move (main_or_left_expr))
+ {}
+
+ // Copy constructor (only for initialisation of expr purposes)
+ OperatorExpr (OperatorExpr const &other)
+ : ExprWithoutBlock (other),
+ locus (
+ other
+ .locus) /*, main_or_left_expr(other.main_or_left_expr->clone_expr())*/
+ {
+ // DEBUG: moved main_or_left_expr into body - move back later
+
+ if (other.main_or_left_expr == NULL)
+ {
+ fprintf (stderr, "other operator expr's main_or_left_expr is null!\n");
+ }
+
+ fprintf (stderr, "called operator expr copy constructor - about to clone "
+ "main_or_left_expr\n");
+ main_or_left_expr = other.main_or_left_expr->clone_expr ();
+ fprintf (stderr, "successfully cloned main_or_left_expr\n");
+ // this occurred successfully, so something else must be the issue
+ }
+
+ // Overload assignment operator to deep copy expr
+ OperatorExpr &operator= (OperatorExpr const &other)
+ {
+ ExprWithoutBlock::operator= (other);
+ main_or_left_expr = other.main_or_left_expr->clone_expr ();
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ OperatorExpr (OperatorExpr &&other) = default;
+ OperatorExpr &operator= (OperatorExpr &&other) = default;
+
+public:
+ /*virtual ~OperatorExpr() {
+ delete main_or_left_expr;
+ }*/
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+};
+
+// Unary prefix & or &mut (or && and &&mut) borrow operator. Cannot be
+// overloaded.
+class BorrowExpr : public OperatorExpr
+{
+ bool is_mut;
+ bool double_borrow;
+
+public:
+ ::std::string as_string () const;
+
+ BorrowExpr (::std::unique_ptr<Expr> borrow_lvalue, bool is_mut_borrow,
+ bool is_double_borrow, ::std::vector<Attribute> outer_attribs,
+ Location locus)
+ : OperatorExpr (::std::move (borrow_lvalue), ::std::move (outer_attribs),
+ locus),
+ is_mut (is_mut_borrow), double_borrow (is_double_borrow)
+ {}
+
+ // Copy constructor - define here if required
+
+ // Destructor - define here if required
+
+ // Overload assignment operator here if required
+
+ // Move semantics here if required
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual BorrowExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new BorrowExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual BorrowExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (stderr, "called clone_expr_without_block_impl() on borrowexpr\n");
+
+ return new BorrowExpr (*this);
+ }
+};
+
+// Unary prefix * deference operator
+class DereferenceExpr : public OperatorExpr
+{
+public:
+ ::std::string as_string () const;
+
+ // Constructor calls OperatorExpr's protected constructor
+ DereferenceExpr (::std::unique_ptr<Expr> deref_lvalue,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : OperatorExpr (::std::move (deref_lvalue), ::std::move (outer_attribs),
+ locus)
+ {}
+
+ // Copy constructor - define here if required
+
+ // Destructor - define here if required
+
+ // Overload assignment operator here if required
+
+ // Move semantics here if required
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual DereferenceExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new DereferenceExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual DereferenceExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (stderr,
+ "called clone_expr_without_block_impl() on dereferenceexpr\n");
+
+ return new DereferenceExpr (*this);
+ }
+};
+
+// Unary postfix ? error propogation operator. Cannot be overloaded.
+class ErrorPropagationExpr : public OperatorExpr
+{
+public:
+ ::std::string as_string () const;
+
+ // Constructor calls OperatorExpr's protected constructor
+ ErrorPropagationExpr (::std::unique_ptr<Expr> potential_error_value,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : OperatorExpr (::std::move (potential_error_value),
+ ::std::move (outer_attribs), locus)
+ {}
+
+ // Copy constructor - define here if required
+
+ // Destructor - define here if required
+
+ // Overload assignment operator here if required
+
+ // Move semantics here if required
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ErrorPropagationExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new ErrorPropagationExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ErrorPropagationExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (
+ stderr,
+ "called clone_expr_without_block_impl() on errorpropagationexpr\n");
+
+ return new ErrorPropagationExpr (*this);
+ }
+};
+
+// Unary prefix - or ! negation or NOT operators.
+class NegationExpr : public OperatorExpr
+{
+public:
+ enum NegationType
+ {
+ NEGATE,
+ NOT
+ };
+
+private:
+ // Note: overload negation via std::ops::Neg and not via std::ops::Not
+ // Negation only works for signed integer and floating-point types, NOT only
+ // works for boolean and integer types (via bitwise NOT)
+ NegationType negation_type;
+
+public:
+ ::std::string as_string () const;
+
+ inline NegationType get_negation_type () const { return negation_type; }
+
+ // Constructor calls OperatorExpr's protected constructor
+ NegationExpr (::std::unique_ptr<Expr> negated_value,
+ NegationType negation_kind,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : OperatorExpr (::std::move (negated_value), ::std::move (outer_attribs),
+ locus),
+ negation_type (negation_kind)
+ {}
+
+ // Copy constructor - define here if required
+
+ // Destructor - define here if required
+
+ // Overload assignment operator here if required
+
+ // Move semantics here if required
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual NegationExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new NegationExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual NegationExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (stderr,
+ "called clone_expr_without_block_impl() on negationexpr\n");
+
+ return new NegationExpr (*this);
+ }
+};
+
+// Infix binary operators. +, -, *, /, %, &, |, ^, <<, >>
+class ArithmeticOrLogicalExpr : public OperatorExpr
+{
+public:
+ enum ExprType
+ {
+ ADD, // std::ops::Add
+ SUBTRACT, // std::ops::Sub
+ MULTIPLY, // std::ops::Mul
+ DIVIDE, // std::ops::Div
+ MODULUS, // std::ops::Rem
+ BITWISE_AND, // std::ops::BitAnd
+ BITWISE_OR, // std::ops::BitOr
+ BITWISE_XOR, // std::ops::BitXor
+ LEFT_SHIFT, // std::ops::Shl
+ RIGHT_SHIFT // std::ops::Shr
+ };
+
+private:
+ // Note: overloading trait specified in comments
+ ExprType expr_type;
+
+ // Expr* right_expr;
+ ::std::unique_ptr<Expr> right_expr;
+
+public:
+ /*~ArithmeticOrLogicalExpr() {
+ delete right_expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ inline ExprType get_expr_type () const { return expr_type; }
+
+ // Constructor calls OperatorExpr's protected constructor
+ ArithmeticOrLogicalExpr (::std::unique_ptr<Expr> left_value,
+ ::std::unique_ptr<Expr> right_value,
+ ExprType expr_kind, Location locus)
+ : OperatorExpr (::std::move (left_value), ::std::vector<Attribute> (),
+ locus),
+ expr_type (expr_kind), right_expr (::std::move (right_value))
+ {}
+ // outer attributes not allowed
+
+ // Copy constructor - probably required due to unique pointer
+ ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr const &other)
+ : OperatorExpr (other), expr_type (other.expr_type),
+ right_expr (other.right_expr->clone_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator
+ ArithmeticOrLogicalExpr &operator= (ArithmeticOrLogicalExpr const &other)
+ {
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ right_expr = other.right_expr->clone_expr ();
+ expr_type = other.expr_type;
+
+ return *this;
+ }
+
+ // move constructors
+ ArithmeticOrLogicalExpr (ArithmeticOrLogicalExpr &&other) = default;
+ ArithmeticOrLogicalExpr &operator= (ArithmeticOrLogicalExpr &&other)
+ = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ArithmeticOrLogicalExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new ArithmeticOrLogicalExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ArithmeticOrLogicalExpr *
+ clone_expr_without_block_impl () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (
+ stderr,
+ "called clone_expr_without_block_impl() on arithmeticorlogicalexpr\n");
+
+ return new ArithmeticOrLogicalExpr (*this);
+ }
+};
+
+// Infix binary comparison operators. ==, !=, <, <=, >, >=
+class ComparisonExpr : public OperatorExpr
+{
+public:
+ enum ExprType
+ {
+ EQUAL, // std::cmp::PartialEq::eq
+ NOT_EQUAL, // std::cmp::PartialEq::ne
+ GREATER_THAN, // std::cmp::PartialEq::gt
+ LESS_THAN, // std::cmp::PartialEq::lt
+ GREATER_OR_EQUAL, // std::cmp::PartialEq::ge
+ LESS_OR_EQUAL // std::cmp::PartialEq::le
+ };
+
+private:
+ // Note: overloading trait specified in comments
+ ExprType expr_type;
+
+ // Expr* right_expr;
+ ::std::unique_ptr<Expr> right_expr;
+
+public:
+ /*~ComparisonExpr() {
+ delete right_expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ inline ExprType get_expr_type () const { return expr_type; }
+
+ // Constructor requires pointers for polymorphism
+ ComparisonExpr (::std::unique_ptr<Expr> left_value,
+ ::std::unique_ptr<Expr> right_value, ExprType comparison_kind,
+ Location locus)
+ : OperatorExpr (::std::move (left_value), ::std::vector<Attribute> (),
+ locus),
+ expr_type (comparison_kind), right_expr (::std::move (right_value))
+ {}
+ // outer attributes not allowed
+
+ // Copy constructor also calls OperatorExpr's protected constructor
+ ComparisonExpr (ComparisonExpr const &other)
+ : OperatorExpr (other), expr_type (other.expr_type),
+ right_expr (other.right_expr->clone_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to deep copy
+ ComparisonExpr &operator= (ComparisonExpr const &other)
+ {
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ right_expr = other.right_expr->clone_expr ();
+ expr_type = other.expr_type;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ ComparisonExpr (ComparisonExpr &&other) = default;
+ ComparisonExpr &operator= (ComparisonExpr &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ // TODO: implement via a function call to std::cmp::PartialEq::eq(&op1, &op2)
+ // maybe?
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ComparisonExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new ComparisonExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ComparisonExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (stderr,
+ "called clone_expr_without_block_impl() on comparisonexpr\n");
+
+ return new ComparisonExpr (*this);
+ }
+};
+
+// Infix binary lazy boolean logical operators && and ||.
+class LazyBooleanExpr : public OperatorExpr
+{
+public:
+ enum ExprType
+ {
+ LOGICAL_OR,
+ LOGICAL_AND
+ };
+
+private:
+ ExprType expr_type;
+
+ // Expr* right_expr;
+ ::std::unique_ptr<Expr> right_expr;
+
+public:
+ /*~LazyBooleanExpr() {
+ delete right_expr;
+ }*/
+
+ // Constructor calls OperatorExpr's protected constructor
+ LazyBooleanExpr (::std::unique_ptr<Expr> left_bool_expr,
+ ::std::unique_ptr<Expr> right_bool_expr, ExprType expr_kind,
+ Location locus)
+ : OperatorExpr (::std::move (left_bool_expr), ::std::vector<Attribute> (),
+ locus),
+ expr_type (expr_kind), right_expr (::std::move (right_bool_expr))
+ {}
+ // outer attributes not allowed
+
+ // Copy constructor also calls OperatorExpr's protected constructor
+ LazyBooleanExpr (LazyBooleanExpr const &other)
+ : OperatorExpr (other), expr_type (other.expr_type),
+ right_expr (other.right_expr->clone_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to deep copy
+ LazyBooleanExpr &operator= (LazyBooleanExpr const &other)
+ {
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ right_expr = other.right_expr->clone_expr ();
+ expr_type = other.expr_type;
+
+ return *this;
+ }
+
+ // move constructors
+ LazyBooleanExpr (LazyBooleanExpr &&other) = default;
+ LazyBooleanExpr &operator= (LazyBooleanExpr &&other) = default;
+
+ ::std::string as_string () const;
+
+ inline ExprType get_expr_type () const { return expr_type; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual LazyBooleanExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new LazyBooleanExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual LazyBooleanExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (stderr,
+ "called clone_expr_without_block_impl() on lazybooleanexpr\n");
+
+ return new LazyBooleanExpr (*this);
+ }
+};
+
+// Binary infix "as" cast expression.
+class TypeCastExpr : public OperatorExpr
+{
+ // TypeNoBounds type_to_convert_to;
+ ::std::unique_ptr<TypeNoBounds> type_to_convert_to;
+
+ // Note: only certain type casts allowed, outlined in reference
+public:
+ ::std::string as_string () const;
+
+ // Constructor requires calling protected constructor of OperatorExpr
+ TypeCastExpr (::std::unique_ptr<Expr> expr_to_cast,
+ ::std::unique_ptr<TypeNoBounds> type_to_cast_to, Location locus)
+ : OperatorExpr (::std::move (expr_to_cast), ::std::vector<Attribute> (),
+ locus),
+ type_to_convert_to (::std::move (type_to_cast_to))
+ {}
+ // outer attributes not allowed
+
+ // Copy constructor also requires calling protected constructor
+ TypeCastExpr (TypeCastExpr const &other)
+ : OperatorExpr (other),
+ type_to_convert_to (other.type_to_convert_to->clone_type_no_bounds ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to deep copy
+ TypeCastExpr &operator= (TypeCastExpr const &other)
+ {
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ type_to_convert_to = other.type_to_convert_to->clone_type_no_bounds ();
+
+ return *this;
+ }
+
+ // move constructors as not supported in c++03
+ TypeCastExpr (TypeCastExpr &&other) = default;
+ TypeCastExpr &operator= (TypeCastExpr &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TypeCastExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new TypeCastExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TypeCastExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (stderr,
+ "called clone_expr_without_block_impl() on typecastexpr\n");
+
+ return new TypeCastExpr (*this);
+ }
+};
+
+// Binary assignment expression.
+class AssignmentExpr : public OperatorExpr
+{
+ // Expr* right_expr;
+ ::std::unique_ptr<Expr> right_expr;
+
+public:
+ /*~AssignmentExpr() {
+ delete right_expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ // Call OperatorExpr constructor to initialise left_expr
+ AssignmentExpr (::std::unique_ptr<Expr> value_to_assign_to,
+ ::std::unique_ptr<Expr> value_to_assign, Location locus)
+ : OperatorExpr (::std::move (value_to_assign_to),
+ ::std::vector<Attribute> (), locus),
+ right_expr (::std::move (value_to_assign))
+ {}
+ // outer attributes not allowed
+
+ // Call OperatorExpr constructor in copy constructor, as well as clone
+ AssignmentExpr (AssignmentExpr const &other)
+ : OperatorExpr (other) /*, right_expr(other.right_expr->clone_expr())*/
+ {
+ // DEBUG: moved cloning right expr into body
+ fprintf (stderr, "assignment expr copy constructor successfully cloned "
+ "base operator expr\n");
+ if (other.right_expr == NULL)
+ {
+ fprintf (stderr, "other expr's right expr (in assignment) is null!!!");
+ }
+ fprintf (stderr, "test other's right expr as string: %s\n",
+ other.right_expr->as_string ().c_str ());
+ // apparently, despite not being null, cloning still fails
+ right_expr = other.right_expr->clone_expr ();
+ fprintf (
+ stderr,
+ "assignment expr copy constructor successfully cloned right expr\n");
+
+ // DEBUG
+ fprintf (stderr, "assignment expr copy constructor called successfully\n");
+ }
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone unique_ptr right_expr
+ AssignmentExpr &operator= (AssignmentExpr const &other)
+ {
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ right_expr = other.right_expr->clone_expr ();
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ AssignmentExpr (AssignmentExpr &&other) = default;
+ AssignmentExpr &operator= (AssignmentExpr &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual AssignmentExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new AssignmentExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual AssignmentExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (stderr,
+ "called clone_expr_without_block_impl() on assignmentexpr\n");
+
+ return new AssignmentExpr (*this);
+ }
+};
+
+// Binary infix compound assignment (arithmetic or logic then assignment)
+// expressions.
+class CompoundAssignmentExpr : public OperatorExpr
+{
+public:
+ enum ExprType
+ {
+ ADD, // std::ops::AddAssign
+ SUBTRACT, // std::ops::SubAssign
+ MULTIPLY, // std::ops::MulAssign
+ DIVIDE, // std::ops::DivAssign
+ MODULUS, // std::ops::RemAssign
+ BITWISE_AND, // std::ops::BitAndAssign
+ BITWISE_OR, // std::ops::BitOrAssign
+ BITWISE_XOR, // std::ops::BitXorAssign
+ LEFT_SHIFT, // std::ops::ShlAssign
+ RIGHT_SHIFT // std::ops::ShrAssign
+ };
+
+private:
+ // Note: overloading trait specified in comments
+ ExprType expr_type;
+
+ // Expr* right_expr;
+ ::std::unique_ptr<Expr> right_expr;
+
+public:
+ /*~CompoundAssignmentExpr() {
+ delete right_expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ inline ExprType get_expr_type () const { return expr_type; }
+
+ // Use pointers in constructor to enable polymorphism
+ CompoundAssignmentExpr (::std::unique_ptr<Expr> value_to_assign_to,
+ ::std::unique_ptr<Expr> value_to_assign,
+ ExprType expr_kind, Location locus)
+ : OperatorExpr (::std::move (value_to_assign_to),
+ ::std::vector<Attribute> (), locus),
+ expr_type (expr_kind), right_expr (::std::move (value_to_assign))
+ {}
+ // outer attributes not allowed
+
+ // Have clone in copy constructor
+ CompoundAssignmentExpr (CompoundAssignmentExpr const &other)
+ : OperatorExpr (other), expr_type (other.expr_type),
+ right_expr (other.right_expr->clone_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone
+ CompoundAssignmentExpr &operator= (CompoundAssignmentExpr const &other)
+ {
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ right_expr = other.right_expr->clone_expr ();
+ expr_type = other.expr_type;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ CompoundAssignmentExpr (CompoundAssignmentExpr &&other) = default;
+ CompoundAssignmentExpr &operator= (CompoundAssignmentExpr &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual CompoundAssignmentExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new CompoundAssignmentExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual CompoundAssignmentExpr *
+ clone_expr_without_block_impl () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (
+ stderr,
+ "called clone_expr_without_block_impl() on compoundassignmentexpr\n");
+
+ return new CompoundAssignmentExpr (*this);
+ }
+};
+
+// Expression in parentheses (i.e. like literally just any 3 + (2 * 6))
+class GroupedExpr : public ExprWithoutBlock
+{
+ ::std::vector<Attribute> inner_attrs;
+ // Expr* expr_in_parens;
+ ::std::unique_ptr<Expr> expr_in_parens;
+
+ Location locus;
+
+public:
+ /*~GroupedExpr() {
+ delete expr_in_parens;
+ }*/
+
+ ::std::string as_string () const;
+
+ inline ::std::vector<Attribute> get_inner_attrs () const
+ {
+ return inner_attrs;
+ }
+
+ GroupedExpr (::std::unique_ptr<Expr> parenthesised_expr,
+ ::std::vector<Attribute> inner_attribs,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : ExprWithoutBlock (::std::move (outer_attribs)),
+ inner_attrs (::std::move (inner_attribs)),
+ expr_in_parens (::std::move (parenthesised_expr)), locus (locus)
+ {}
+
+ // Copy constructor includes clone for expr_in_parens
+ GroupedExpr (GroupedExpr const &other)
+ : ExprWithoutBlock (other), inner_attrs (other.inner_attrs),
+ expr_in_parens (other.expr_in_parens->clone_expr ()), locus (other.locus)
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone expr_in_parens
+ GroupedExpr &operator= (GroupedExpr const &other)
+ {
+ ExprWithoutBlock::operator= (other);
+ inner_attrs = other.inner_attrs;
+ expr_in_parens = other.expr_in_parens->clone_expr ();
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ GroupedExpr (GroupedExpr &&other) = default;
+ GroupedExpr &operator= (GroupedExpr &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual GroupedExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new GroupedExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual GroupedExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new GroupedExpr (*this);
+ }
+};
+
+// Base array initialisation internal element representation thing (abstract)
+// aka ArrayElements
+class ArrayElems
+{
+public:
+ virtual ~ArrayElems () {}
+
+ // Unique pointer custom clone ArrayElems function
+ ::std::unique_ptr<ArrayElems> clone_array_elems () const
+ {
+ return ::std::unique_ptr<ArrayElems> (clone_array_elems_impl ());
+ }
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+protected:
+ // pure virtual clone implementation
+ virtual ArrayElems *clone_array_elems_impl () const = 0;
+};
+
+// Value array elements
+class ArrayElemsValues : public ArrayElems
+{
+ //::std::vector<Expr> values;
+ ::std::vector< ::std::unique_ptr<Expr> > values;
+
+ // TODO: should this store location data?
+
+public:
+ /*inline ::std::vector< ::std::unique_ptr<Expr> > get_values() const {
+ return values;
+ }*/
+
+ ArrayElemsValues (::std::vector< ::std::unique_ptr<Expr> > elems)
+ : values (::std::move (elems))
+ {}
+
+ // copy constructor with vector clone
+ ArrayElemsValues (ArrayElemsValues const &other)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ values.reserve (other.values.size ());
+
+ for (const auto &e : other.values)
+ {
+ values.push_back (e->clone_expr ());
+ }
+ }
+
+ // overloaded assignment operator with vector clone
+ ArrayElemsValues &operator= (ArrayElemsValues const &other)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ values.reserve (other.values.size ());
+
+ for (const auto &e : other.values)
+ {
+ values.push_back (e->clone_expr ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ ArrayElemsValues (ArrayElemsValues &&other) = default;
+ ArrayElemsValues &operator= (ArrayElemsValues &&other) = default;
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ virtual ArrayElemsValues *clone_array_elems_impl () const OVERRIDE
+ {
+ return new ArrayElemsValues (*this);
+ }
+};
+
+// Copied array element and number of copies
+class ArrayElemsCopied : public ArrayElems
+{
+ // Expr* elem_to_copy;
+ ::std::unique_ptr<Expr> elem_to_copy;
+ // Expr* num_copies;
+ ::std::unique_ptr<Expr> num_copies;
+
+ // TODO: should this store location data?
+
+public:
+ /*~ArrayElemsCopied() {
+ delete num_copies;
+ delete elem_to_copy;
+ }*/
+
+ // Constructor requires pointers for polymorphism
+ ArrayElemsCopied (::std::unique_ptr<Expr> copied_elem,
+ ::std::unique_ptr<Expr> copy_amount)
+ : elem_to_copy (::std::move (copied_elem)),
+ num_copies (::std::move (copy_amount))
+ {}
+
+ // Copy constructor required due to unique_ptr - uses custom clone
+ ArrayElemsCopied (ArrayElemsCopied const &other)
+ : elem_to_copy (other.elem_to_copy->clone_expr ()),
+ num_copies (other.num_copies->clone_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator for deep copying
+ ArrayElemsCopied &operator= (ArrayElemsCopied const &other)
+ {
+ elem_to_copy = other.elem_to_copy->clone_expr ();
+ num_copies = other.num_copies->clone_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ ArrayElemsCopied (ArrayElemsCopied &&other) = default;
+ ArrayElemsCopied &operator= (ArrayElemsCopied &&other) = default;
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ virtual ArrayElemsCopied *clone_array_elems_impl () const OVERRIDE
+ {
+ return new ArrayElemsCopied (*this);
+ }
+};
+
+// Array definition-ish expression
+class ArrayExpr : public ExprWithoutBlock
+{
+ ::std::vector<Attribute> inner_attrs;
+ // ArrayElems internal_elements;
+ ::std::unique_ptr<ArrayElems> internal_elements;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ inline ::std::vector<Attribute> get_inner_attrs () const
+ {
+ return inner_attrs;
+ }
+
+ // Returns whether array expr has array elems or if it is just empty.
+ inline bool has_array_elems () const { return internal_elements != NULL; }
+
+ // Constructor requires ArrayElems pointer
+ ArrayExpr (::std::unique_ptr<ArrayElems> array_elems,
+ ::std::vector<Attribute> inner_attribs,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : ExprWithoutBlock (::std::move (outer_attribs)),
+ inner_attrs (::std::move (inner_attribs)),
+ internal_elements (::std::move (array_elems)), locus (locus)
+ {}
+
+ // Copy constructor requires cloning ArrayElems for polymorphism to hold
+ ArrayExpr (ArrayExpr const &other)
+ : ExprWithoutBlock (other), inner_attrs (other.inner_attrs),
+ locus (other.locus)
+ {
+ if (other.has_array_elems ())
+ {
+ internal_elements = other.internal_elements->clone_array_elems ();
+ }
+ }
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone internal_elements
+ ArrayExpr &operator= (ArrayExpr const &other)
+ {
+ ExprWithoutBlock::operator= (other);
+ inner_attrs = other.inner_attrs;
+ if (other.has_array_elems ())
+ {
+ internal_elements = other.internal_elements->clone_array_elems ();
+ }
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ ArrayExpr (ArrayExpr &&other) = default;
+ ArrayExpr &operator= (ArrayExpr &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ArrayExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new ArrayExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ArrayExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new ArrayExpr (*this);
+ }
+};
+
+// Aka IndexExpr (also applies to slices)
+// Apparently a[b] is equivalent to *std::ops::Index::index(&a, b) or
+// *std::ops::Index::index_mut(&mut a, b)
+// Also apparently deref operations on a will be repeatedly applied to find an
+// implementation
+class ArrayIndexExpr : public ExprWithoutBlock
+{
+ /*Expr* array_expr;
+ Expr* index_expr;*/
+ ::std::unique_ptr<Expr> array_expr;
+ ::std::unique_ptr<Expr> index_expr;
+
+ Location locus;
+
+public:
+ /*~ArrayIndexExpr() {
+ delete index_expr;
+ delete array_expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ ArrayIndexExpr (::std::unique_ptr<Expr> array_expr,
+ ::std::unique_ptr<Expr> array_index_expr,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : ExprWithoutBlock (::std::move (outer_attribs)),
+ array_expr (::std::move (array_expr)),
+ index_expr (::std::move (array_index_expr)), locus (locus)
+ {}
+
+ // Copy constructor requires special cloning due to unique_ptr
+ ArrayIndexExpr (ArrayIndexExpr const &other)
+ : ExprWithoutBlock (other), array_expr (other.array_expr->clone_expr ()),
+ index_expr (other.index_expr->clone_expr ()), locus (other.locus)
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone unique_ptrs
+ ArrayIndexExpr &operator= (ArrayIndexExpr const &other)
+ {
+ ExprWithoutBlock::operator= (other);
+ array_expr = other.array_expr->clone_expr ();
+ index_expr = other.index_expr->clone_expr ();
+ // outer_attrs = other.outer_attrs;
+ locus = other.locus;
+
+ return *this;
+ }
+
+ // move constructors
+ ArrayIndexExpr (ArrayIndexExpr &&other) = default;
+ ArrayIndexExpr &operator= (ArrayIndexExpr &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ArrayIndexExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new ArrayIndexExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ArrayIndexExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new ArrayIndexExpr (*this);
+ }
+};
+
+// AST representation of a tuple
+class TupleExpr : public ExprWithoutBlock
+{
+ ::std::vector<Attribute> inner_attrs;
+
+ //::std::vector<Expr> tuple_elems;
+ ::std::vector< ::std::unique_ptr<Expr> > tuple_elems;
+ // replaces (inlined version of) TupleElements
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ inline ::std::vector<Attribute> get_inner_attrs () const
+ {
+ return inner_attrs;
+ }
+
+ TupleExpr (::std::vector< ::std::unique_ptr<Expr> > tuple_elements,
+ ::std::vector<Attribute> inner_attribs,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : ExprWithoutBlock (::std::move (outer_attribs)),
+ inner_attrs (::std::move (inner_attribs)),
+ tuple_elems (::std::move (tuple_elements)), locus (locus)
+ {}
+
+ // copy constructor with vector clone
+ TupleExpr (TupleExpr const &other)
+ : ExprWithoutBlock (other), inner_attrs (other.inner_attrs),
+ locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ tuple_elems.reserve (other.tuple_elems.size ());
+
+ for (const auto &e : other.tuple_elems)
+ {
+ tuple_elems.push_back (e->clone_expr ());
+ }
+ }
+
+ // overloaded assignment operator to vector clone
+ TupleExpr &operator= (TupleExpr const &other)
+ {
+ ExprWithoutBlock::operator= (other);
+ inner_attrs = other.inner_attrs;
+ locus = other.locus;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ tuple_elems.reserve (other.tuple_elems.size ());
+
+ for (const auto &e : other.tuple_elems)
+ {
+ tuple_elems.push_back (e->clone_expr ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ TupleExpr (TupleExpr &&other) = default;
+ TupleExpr &operator= (TupleExpr &&other) = default;
+
+ // Note: syntactically, can disambiguate single-element tuple from parens with
+ // comma, i.e. (0,) rather than (0)
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TupleExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new TupleExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TupleExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new TupleExpr (*this);
+ }
+};
+
+// aka TupleIndexingExpr
+// AST representation of a tuple indexing expression
+class TupleIndexExpr : public ExprWithoutBlock
+{
+ // Expr* tuple_expr;
+ ::std::unique_ptr<Expr> tuple_expr;
+ // TupleIndex is a decimal int literal with no underscores or suffix
+ TupleIndex tuple_index;
+
+ Location locus;
+
+ // i.e. pair.0
+
+public:
+ /*~TupleIndexExpr() {
+ delete tuple_expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ inline TupleIndex get_tuple_index () const { return tuple_index; }
+
+ TupleIndexExpr (::std::unique_ptr<Expr> tuple_expr, TupleIndex index,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : ExprWithoutBlock (::std::move (outer_attribs)),
+ tuple_expr (::std::move (tuple_expr)), tuple_index (index), locus (locus)
+ {}
+
+ // Copy constructor requires a clone for tuple_expr
+ TupleIndexExpr (TupleIndexExpr const &other)
+ : ExprWithoutBlock (other), tuple_expr (other.tuple_expr->clone_expr ()),
+ tuple_index (other.tuple_index), locus (other.locus)
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator in order to clone
+ TupleIndexExpr &operator= (TupleIndexExpr const &other)
+ {
+ ExprWithoutBlock::operator= (other);
+ tuple_expr = other.tuple_expr->clone_expr ();
+ tuple_index = other.tuple_index;
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ TupleIndexExpr (TupleIndexExpr &&other) = default;
+ TupleIndexExpr &operator= (TupleIndexExpr &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TupleIndexExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new TupleIndexExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TupleIndexExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new TupleIndexExpr (*this);
+ }
+};
+
+// Base struct/tuple/union value creator AST node (abstract)
+class StructExpr : public ExprWithoutBlock
+{
+ PathInExpression struct_name;
+
+protected:
+ // Protected constructor to allow initialising struct_name
+ StructExpr (PathInExpression struct_path,
+ ::std::vector<Attribute> outer_attribs)
+ : ExprWithoutBlock (::std::move (outer_attribs)),
+ struct_name (::std::move (struct_path))
+ {}
+
+public:
+ inline const PathInExpression &get_struct_name () const
+ {
+ return struct_name;
+ }
+
+ virtual ::std::string as_string () const;
+};
+
+// Actual AST node of the struct creator (with no fields). Not abstract!
+class StructExprStruct : public StructExpr
+{
+ ::std::vector<Attribute> inner_attrs;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ inline ::std::vector<Attribute> get_inner_attrs () const
+ {
+ return inner_attrs;
+ }
+
+ // Constructor has to call protected constructor of base class
+ StructExprStruct (PathInExpression struct_path,
+ ::std::vector<Attribute> inner_attribs,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : StructExpr (::std::move (struct_path), ::std::move (outer_attribs)),
+ inner_attrs (::std::move (inner_attribs)), locus (locus)
+ {}
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructExprStruct *clone_expr_impl () const OVERRIDE
+ {
+ return new StructExprStruct (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructExprStruct *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new StructExprStruct (*this);
+ }
+};
+
+// AST node representing expression used to fill a struct's fields from another
+// struct
+struct StructBase
+{
+private:
+ // Expr* base_struct;
+ ::std::unique_ptr<Expr> base_struct;
+
+ // TODO: should this store location data?
+
+public:
+ StructBase (::std::unique_ptr<Expr> base_struct_ptr)
+ : base_struct (::std::move (base_struct_ptr))
+ {}
+
+ // Copy constructor requires clone
+ StructBase (StructBase const &other)
+ {
+ // HACK: gets around base_struct pointer being null (e.g. if no struct base
+ // exists)
+ if (other.base_struct != NULL)
+ {
+ other.base_struct->clone_expr ();
+ }
+
+ // DEBUG:
+ fprintf (stderr, "struct base copy constructor called successfully\n");
+ }
+
+ // Destructor
+ ~StructBase () = default;
+
+ // Overload assignment operator to clone base_struct
+ StructBase &operator= (StructBase const &other)
+ {
+ base_struct = other.base_struct->clone_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ StructBase (StructBase &&other) = default;
+ StructBase &operator= (StructBase &&other) = default;
+
+ /*~StructBase() {
+ delete base_struct;
+ }*/
+
+ // Returns a null expr-ed StructBase - error state
+ static StructBase error () { return StructBase (NULL); }
+
+ // Returns whether StructBase is in error state
+ inline bool is_invalid () const { return base_struct == NULL; }
+
+ ::std::string as_string () const;
+};
+
+// Base AST node for a single struct expression field (in struct instance
+// creation) - abstract
+class StructExprField
+{
+public:
+ virtual ~StructExprField () {}
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<StructExprField> clone_struct_expr_field () const
+ {
+ return ::std::unique_ptr<StructExprField> (clone_struct_expr_field_impl ());
+ }
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+protected:
+ // pure virtual clone implementation
+ virtual StructExprField *clone_struct_expr_field_impl () const = 0;
+};
+
+// Identifier-only variant of StructExprField AST node
+class StructExprFieldIdentifier : public StructExprField
+{
+ Identifier field_name;
+
+ // TODO: should this store location data?
+
+public:
+ StructExprFieldIdentifier (Identifier field_identifier)
+ : field_name (::std::move (field_identifier))
+ {}
+
+ ::std::string as_string () const { return field_name; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this rather than
+ // base
+ virtual StructExprFieldIdentifier *
+ clone_struct_expr_field_impl () const OVERRIDE
+ {
+ return new StructExprFieldIdentifier (*this);
+ }
+};
+
+// Base AST node for a single struct expression field with an assigned value -
+// abstract
+class StructExprFieldWithVal : public StructExprField
+{
+ // Expr* value;
+ ::std::unique_ptr<Expr> value;
+
+protected:
+ StructExprFieldWithVal (::std::unique_ptr<Expr> field_value)
+ : value (::std::move (field_value))
+ {}
+
+ // Copy constructor requires clone
+ StructExprFieldWithVal (StructExprFieldWithVal const &other)
+ : value (other.value->clone_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone unique_ptr
+ StructExprFieldWithVal &operator= (StructExprFieldWithVal const &other)
+ {
+ value = other.value->clone_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ StructExprFieldWithVal (StructExprFieldWithVal &&other) = default;
+ StructExprFieldWithVal &operator= (StructExprFieldWithVal &&other) = default;
+
+public:
+ /*~StructExprFieldWithVal() {
+ delete value;
+ }*/
+
+ ::std::string as_string () const;
+};
+
+// Identifier and value variant of StructExprField AST node
+class StructExprFieldIdentifierValue : public StructExprFieldWithVal
+{
+ Identifier field_name;
+
+ // TODO: should this store location data?
+
+public:
+ StructExprFieldIdentifierValue (Identifier field_identifier,
+ ::std::unique_ptr<Expr> field_value)
+ : StructExprFieldWithVal (::std::move (field_value)),
+ field_name (::std::move (field_identifier))
+ {}
+
+ // copy constructor, destructor, and overloaded assignment operator should
+ // carry through
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this rather than
+ // base
+ virtual StructExprFieldIdentifierValue *
+ clone_struct_expr_field_impl () const OVERRIDE
+ {
+ return new StructExprFieldIdentifierValue (*this);
+ }
+};
+
+// Tuple index and value variant of StructExprField AST node
+class StructExprFieldIndexValue : public StructExprFieldWithVal
+{
+ TupleIndex index;
+
+ // TODO: should this store location data?
+
+public:
+ StructExprFieldIndexValue (TupleIndex tuple_index,
+ ::std::unique_ptr<Expr> field_value)
+ : StructExprFieldWithVal (::std::move (field_value)), index (tuple_index)
+ {}
+
+ // copy constructor, destructor, and overloaded assignment operator should
+ // carry through
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this rather than
+ // base
+ virtual StructExprFieldIndexValue *
+ clone_struct_expr_field_impl () const OVERRIDE
+ {
+ return new StructExprFieldIndexValue (*this);
+ }
+};
+
+// AST node of a struct creator with fields
+class StructExprStructFields : public StructExprStruct
+{
+ //::std::vector<StructExprField> fields;
+ ::std::vector< ::std::unique_ptr<StructExprField> > fields;
+
+ // bool has_struct_base;
+ StructBase struct_base;
+
+public:
+ ::std::string as_string () const;
+
+ inline bool has_struct_base () const { return !struct_base.is_invalid (); }
+
+ /*inline ::std::vector< ::std::unique_ptr<StructExprField> > get_fields()
+ const { return fields;
+ }*/
+
+ /*inline StructBase get_struct_base() const {
+ return has_struct_base ? struct_base : StructBase::error();
+ }*/
+
+ // Constructor for StructExprStructFields when no struct base is used
+ StructExprStructFields (
+ PathInExpression struct_path,
+ ::std::vector< ::std::unique_ptr<StructExprField> > expr_fields,
+ Location locus, StructBase base_struct = StructBase::error (),
+ ::std::vector<Attribute> inner_attribs = ::std::vector<Attribute> (),
+ ::std::vector<Attribute> outer_attribs = ::std::vector<Attribute> ())
+ : StructExprStruct (::std::move (struct_path), ::std::move (inner_attribs),
+ ::std::move (outer_attribs), locus),
+ fields (::std::move (expr_fields)),
+ struct_base (::std::move (base_struct))
+ {}
+
+ // copy constructor with vector clone
+ StructExprStructFields (StructExprStructFields const &other)
+ : StructExprStruct (other), struct_base (other.struct_base)
+ {
+ // DEBUG
+ fprintf (stderr,
+ "got past the initialisation list part of copy constructor\n");
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ fields.reserve (other.fields.size ());
+
+ // DEBUG
+ fprintf (stderr, "reserved space in fields\n");
+
+ for (const auto &e : other.fields)
+ {
+ // DEBUG
+ fprintf (stderr, "about to clone a field\n");
+
+ fields.push_back (e->clone_struct_expr_field ());
+
+ // DEBUG
+ fprintf (stderr, "cloned a field successfully\n");
+ }
+
+ // DEBUG
+ fprintf (stderr, "finished cloning fields\n");
+ }
+
+ // overloaded assignment operator with vector clone
+ StructExprStructFields &operator= (StructExprStructFields const &other)
+ {
+ StructExprStruct::operator= (other);
+ struct_base = other.struct_base;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ fields.reserve (other.fields.size ());
+
+ for (const auto &e : other.fields)
+ {
+ fields.push_back (e->clone_struct_expr_field ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ StructExprStructFields (StructExprStructFields &&other) = default;
+ StructExprStructFields &operator= (StructExprStructFields &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructExprStructFields *clone_expr_impl () const OVERRIDE
+ {
+ return new StructExprStructFields (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructExprStructFields *
+ clone_expr_without_block_impl () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (
+ stderr,
+ "called structexprstructfields clone expr without block impl - about "
+ "to return new structexprstructfields\n");
+
+ // DEBUG - test creation of a base from this
+ fprintf (stderr, "about to try to create and allocate structexprstruct \n");
+ StructExprStruct *test_DELETE = new StructExprStruct (*this);
+ delete test_DELETE;
+ fprintf (stderr, "managed to create and allocate structexprstruct \n");
+ // very weird: can create and allocate structexpstruct but not
+ // structexprstructfields
+
+ // DEBUG - test creation of a non-returned class from this
+ fprintf (stderr, "about to try to create and allocate "
+ "structexprstructfields (but not return)\n");
+ StructExprStructFields *test_DELETE2 = new StructExprStructFields (*this);
+ delete test_DELETE2;
+ fprintf (stderr, "managed to create and allocate structexprstructfields "
+ "(if not returned) \n");
+ // ok this fails. fair enough.
+
+ return new StructExprStructFields (*this);
+ }
+};
+
+// AST node of the functional update struct creator
+class StructExprStructBase : public StructExprStruct
+{
+ StructBase struct_base;
+
+public:
+ ::std::string as_string () const;
+
+ /*inline StructBase get_struct_base() const {
+ return struct_base;
+ }*/
+
+ StructExprStructBase (PathInExpression struct_path, StructBase base_struct,
+ ::std::vector<Attribute> inner_attribs,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : StructExprStruct (::std::move (struct_path), ::std::move (inner_attribs),
+ ::std::move (outer_attribs), locus),
+ struct_base (::std::move (base_struct))
+ {}
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructExprStructBase *clone_expr_impl () const OVERRIDE
+ {
+ return new StructExprStructBase (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructExprStructBase *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new StructExprStructBase (*this);
+ }
+};
+
+// AST node of a tuple struct creator
+class StructExprTuple : public StructExpr
+{
+ ::std::vector<Attribute> inner_attrs;
+ //::std::vector<Expr> exprs;
+ ::std::vector< ::std::unique_ptr<Expr> > exprs;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ inline const ::std::vector<Attribute> &get_inner_attrs () const
+ {
+ return inner_attrs;
+ }
+
+ /*inline ::std::vector< ::std::unique_ptr<Expr> > get_exprs() const {
+ return exprs;
+ }*/
+
+ StructExprTuple (PathInExpression struct_path,
+ ::std::vector< ::std::unique_ptr<Expr> > tuple_exprs,
+ ::std::vector<Attribute> inner_attribs,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : StructExpr (::std::move (struct_path), ::std::move (outer_attribs)),
+ inner_attrs (::std::move (inner_attribs)),
+ exprs (::std::move (tuple_exprs)), locus (locus)
+ {}
+
+ // copy constructor with vector clone
+ StructExprTuple (StructExprTuple const &other)
+ : StructExpr (other), inner_attrs (other.inner_attrs), locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ exprs.reserve (other.exprs.size ());
+
+ for (const auto &e : other.exprs)
+ {
+ exprs.push_back (e->clone_expr ());
+ }
+ }
+
+ // overloaded assignment operator with vector clone
+ StructExprTuple &operator= (StructExprTuple const &other)
+ {
+ StructExpr::operator= (other);
+ inner_attrs = other.inner_attrs;
+ locus = other.locus;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ exprs.reserve (other.exprs.size ());
+
+ for (const auto &e : other.exprs)
+ {
+ exprs.push_back (e->clone_expr ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ StructExprTuple (StructExprTuple &&other) = default;
+ StructExprTuple &operator= (StructExprTuple &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructExprTuple *clone_expr_impl () const OVERRIDE
+ {
+ return new StructExprTuple (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructExprTuple *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new StructExprTuple (*this);
+ }
+};
+
+// AST node of a "unit" struct creator (no fields and no braces)
+class StructExprUnit : public StructExpr
+{
+ Location locus;
+
+public:
+ ::std::string as_string () const
+ {
+ return get_struct_name ().as_string ();
+ // return struct_name.as_string();
+ }
+
+ StructExprUnit (PathInExpression struct_path,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : StructExpr (::std::move (struct_path), ::std::move (outer_attribs)),
+ locus (locus)
+ {}
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructExprUnit *clone_expr_impl () const OVERRIDE
+ {
+ return new StructExprUnit (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructExprUnit *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new StructExprUnit (*this);
+ }
+};
+
+// aka EnumerationVariantExpr
+// Base AST node representing creation of an enum variant instance - abstract
+class EnumVariantExpr : public ExprWithoutBlock
+{
+ PathInExpression enum_variant_path;
+
+protected:
+ // Protected constructor for initialising enum_variant_path
+ EnumVariantExpr (PathInExpression path_to_enum_variant,
+ ::std::vector<Attribute> outer_attribs)
+ : ExprWithoutBlock (::std::move (outer_attribs)),
+ enum_variant_path (::std::move (path_to_enum_variant))
+ {}
+
+public:
+ // TODO: maybe remove and have string version gotten here directly
+ inline PathInExpression get_enum_variant_path () const
+ {
+ return enum_variant_path;
+ }
+};
+
+// Base AST node for a single enum expression field (in enum instance creation)
+// - abstract
+class EnumExprField
+{
+public:
+ virtual ~EnumExprField () {}
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<EnumExprField> clone_enum_expr_field () const
+ {
+ return ::std::unique_ptr<EnumExprField> (clone_enum_expr_field_impl ());
+ }
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+protected:
+ // Clone function implementation as pure virtual method
+ virtual EnumExprField *clone_enum_expr_field_impl () const = 0;
+};
+
+// Identifier-only variant of EnumExprField AST node
+class EnumExprFieldIdentifier : public EnumExprField
+{
+ Identifier field_name;
+
+ // TODO: should this store location data?
+
+public:
+ EnumExprFieldIdentifier (Identifier field_identifier)
+ : field_name (::std::move (field_identifier))
+ {}
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual EnumExprFieldIdentifier *clone_enum_expr_field_impl () const OVERRIDE
+ {
+ return new EnumExprFieldIdentifier (*this);
+ }
+};
+
+// Base AST node for a single enum expression field with an assigned value -
+// abstract
+class EnumExprFieldWithVal : public EnumExprField
+{
+ // Expr* value;
+ ::std::unique_ptr<Expr> value;
+
+ // TODO: should this store location data?
+
+protected:
+ EnumExprFieldWithVal (::std::unique_ptr<Expr> field_value)
+ : value (::std::move (field_value))
+ {}
+
+ // Copy constructor must clone unique_ptr value
+ EnumExprFieldWithVal (EnumExprFieldWithVal const &other)
+ : value (other.value->clone_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone
+ EnumExprFieldWithVal &operator= (EnumExprFieldWithVal const &other)
+ {
+ value = other.value->clone_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ EnumExprFieldWithVal (EnumExprFieldWithVal &&other) = default;
+ EnumExprFieldWithVal &operator= (EnumExprFieldWithVal &&other) = default;
+};
+
+// Identifier and value variant of EnumExprField AST node
+class EnumExprFieldIdentifierValue : public EnumExprFieldWithVal
+{
+ Identifier field_name;
+
+ // TODO: should this store location data?
+
+public:
+ EnumExprFieldIdentifierValue (Identifier field_name,
+ ::std::unique_ptr<Expr> field_value)
+ : EnumExprFieldWithVal (::std::move (field_value)),
+ field_name (::std::move (field_name))
+ {}
+
+ // copy constructor, destructor, and assignment operator should not need
+ // defining
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual EnumExprFieldIdentifierValue *
+ clone_enum_expr_field_impl () const OVERRIDE
+ {
+ return new EnumExprFieldIdentifierValue (*this);
+ }
+};
+
+// Tuple index and value variant of EnumExprField AST node
+class EnumExprFieldIndexValue : public EnumExprFieldWithVal
+{
+ TupleIndex index;
+ // TODO: implement "with val" as a template with EnumExprField as type param?
+
+ // TODO: should this store location data?
+
+public:
+ EnumExprFieldIndexValue (TupleIndex field_index,
+ ::std::unique_ptr<Expr> field_value)
+ : EnumExprFieldWithVal (::std::move (field_value)), index (field_index)
+ {}
+
+ // copy constructor, destructor, and assignment operator should not need
+ // defining
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual EnumExprFieldIndexValue *clone_enum_expr_field_impl () const OVERRIDE
+ {
+ return new EnumExprFieldIndexValue (*this);
+ }
+};
+
+// Struct-like syntax enum variant instance creation AST node
+class EnumExprStruct : public EnumVariantExpr
+{
+ //::std::vector<EnumExprField> fields;
+ ::std::vector< ::std::unique_ptr<EnumExprField> > fields;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ /*inline ::std::vector< ::std::unique_ptr<EnumExprField> > get_fields() const
+ { return fields;
+ }*/
+
+ EnumExprStruct (
+ PathInExpression enum_variant_path,
+ ::std::vector< ::std::unique_ptr<EnumExprField> > variant_fields,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : EnumVariantExpr (::std::move (enum_variant_path),
+ ::std::move (outer_attribs)),
+ fields (::std::move (variant_fields)), locus (locus)
+ {}
+
+ // copy constructor with vector clone
+ EnumExprStruct (EnumExprStruct const &other)
+ : EnumVariantExpr (other), locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ fields.reserve (other.fields.size ());
+
+ for (const auto &e : other.fields)
+ {
+ fields.push_back (e->clone_enum_expr_field ());
+ }
+ }
+
+ // overloaded assignment operator with vector clone
+ EnumExprStruct &operator= (EnumExprStruct const &other)
+ {
+ EnumVariantExpr::operator= (other);
+ locus = other.locus;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ fields.reserve (other.fields.size ());
+
+ for (const auto &e : other.fields)
+ {
+ fields.push_back (e->clone_enum_expr_field ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ EnumExprStruct (EnumExprStruct &&other) = default;
+ EnumExprStruct &operator= (EnumExprStruct &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual EnumExprStruct *clone_expr_impl () const OVERRIDE
+ {
+ return new EnumExprStruct (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual EnumExprStruct *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new EnumExprStruct (*this);
+ }
+};
+
+// Tuple-like syntax enum variant instance creation AST node
+class EnumExprTuple : public EnumVariantExpr
+{
+ //::std::vector<Expr> values;
+ ::std::vector< ::std::unique_ptr<Expr> > values;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ /*inline ::std::vector< ::std::unique_ptr<Expr> > get_values() const {
+ return values;
+ }*/
+
+ EnumExprTuple (PathInExpression enum_variant_path,
+ ::std::vector< ::std::unique_ptr<Expr> > variant_values,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : EnumVariantExpr (::std::move (enum_variant_path),
+ ::std::move (outer_attribs)),
+ values (::std::move (variant_values)), locus (locus)
+ {}
+
+ // copy constructor with vector clone
+ EnumExprTuple (EnumExprTuple const &other)
+ : EnumVariantExpr (other), locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ values.reserve (other.values.size ());
+
+ for (const auto &e : other.values)
+ {
+ values.push_back (e->clone_expr ());
+ }
+ }
+
+ // overloaded assignment operator with vector clone
+ EnumExprTuple &operator= (EnumExprTuple const &other)
+ {
+ EnumVariantExpr::operator= (other);
+ locus = other.locus;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ values.reserve (other.values.size ());
+
+ for (const auto &e : other.values)
+ {
+ values.push_back (e->clone_expr ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ EnumExprTuple (EnumExprTuple &&other) = default;
+ EnumExprTuple &operator= (EnumExprTuple &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual EnumExprTuple *clone_expr_impl () const OVERRIDE
+ {
+ return new EnumExprTuple (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual EnumExprTuple *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new EnumExprTuple (*this);
+ }
+};
+
+// No-field enum variant instance creation AST node
+class EnumExprFieldless : public EnumVariantExpr
+{
+ Location locus;
+
+public:
+ ::std::string as_string () const
+ {
+ // return enum_variant_path.as_string();
+ return get_enum_variant_path ().as_string ();
+ }
+
+ EnumExprFieldless (PathInExpression enum_variant_path,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : EnumVariantExpr (::std::move (enum_variant_path),
+ ::std::move (outer_attribs)),
+ locus (locus)
+ {}
+
+ // copy constructor, destructor, and assignment operator should not need
+ // defining
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual EnumExprFieldless *clone_expr_impl () const OVERRIDE
+ {
+ return new EnumExprFieldless (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual EnumExprFieldless *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new EnumExprFieldless (*this);
+ }
+};
+
+// Function call expression AST node
+class CallExpr : public ExprWithoutBlock
+{
+ // Expr* function;
+ ::std::unique_ptr<Expr> function;
+ //::std::vector<Expr> params; // inlined form of CallParams
+ ::std::vector< ::std::unique_ptr<Expr> > params;
+
+ Location locus;
+
+public:
+ /*~CallExpr() {
+ delete function;
+ }*/
+
+ ::std::string as_string () const;
+
+ /*inline ::std::vector< ::std::unique_ptr<Expr> > get_params() const {
+ return params;
+ }*/
+
+ CallExpr (::std::unique_ptr<Expr> function_expr,
+ ::std::vector< ::std::unique_ptr<Expr> > function_params,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : ExprWithoutBlock (::std::move (outer_attribs)),
+ function (::std::move (function_expr)),
+ params (::std::move (function_params)), locus (locus)
+ {}
+
+ // copy constructor requires clone
+ CallExpr (CallExpr const &other)
+ : ExprWithoutBlock (other), function (other.function->clone_expr ()),
+ locus (other.locus)
+ /*, params(other.params),*/ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ params.reserve (other.params.size ());
+
+ for (const auto &e : other.params)
+ {
+ params.push_back (e->clone_expr ());
+ }
+ }
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone
+ CallExpr &operator= (CallExpr const &other)
+ {
+ ExprWithoutBlock::operator= (other);
+ function = other.function->clone_expr ();
+ locus = other.locus;
+ // params = other.params;
+ // outer_attrs = other.outer_attrs;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ params.reserve (other.params.size ());
+
+ for (const auto &e : other.params)
+ {
+ params.push_back (e->clone_expr ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ CallExpr (CallExpr &&other) = default;
+ CallExpr &operator= (CallExpr &&other) = default;
+
+ // Returns whether function call has parameters.
+ inline bool has_params () const { return !params.empty (); }
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual CallExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new CallExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual CallExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new CallExpr (*this);
+ }
+};
+
+// Method call expression AST node
+class MethodCallExpr : public ExprWithoutBlock
+{
+ // Expr* receiver;
+ ::std::unique_ptr<Expr> receiver;
+ PathExprSegment method_name;
+ //::std::vector<Expr> params; // inlined form of CallParams
+ ::std::vector< ::std::unique_ptr<Expr> > params;
+
+ Location locus;
+
+public:
+ /*~MethodCallExpr() {
+ delete receiver;
+ }*/
+
+ ::std::string as_string () const;
+
+ /*inline ::std::vector< ::std::unique_ptr<Expr> > get_params() const {
+ return params;
+ }*/
+
+ MethodCallExpr (::std::unique_ptr<Expr> call_receiver,
+ PathExprSegment method_path,
+ ::std::vector< ::std::unique_ptr<Expr> > method_params,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : ExprWithoutBlock (::std::move (outer_attribs)),
+ receiver (::std::move (call_receiver)),
+ method_name (::std::move (method_path)),
+ params (::std::move (method_params)), locus (locus)
+ {}
+
+ // copy constructor required due to cloning
+ MethodCallExpr (MethodCallExpr const &other)
+ : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()),
+ method_name (other.method_name), locus (other.locus)
+ /*, params(other.params),*/ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ params.reserve (other.params.size ());
+
+ for (const auto &e : other.params)
+ {
+ params.push_back (e->clone_expr ());
+ }
+ }
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone receiver object
+ MethodCallExpr &operator= (MethodCallExpr const &other)
+ {
+ ExprWithoutBlock::operator= (other);
+ receiver = other.receiver->clone_expr ();
+ method_name = other.method_name;
+ locus = other.locus;
+ // params = other.params;
+ // outer_attrs = other.outer_attrs;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ params.reserve (other.params.size ());
+
+ for (const auto &e : other.params)
+ {
+ params.push_back (e->clone_expr ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ MethodCallExpr (MethodCallExpr &&other) = default;
+ MethodCallExpr &operator= (MethodCallExpr &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MethodCallExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new MethodCallExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MethodCallExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new MethodCallExpr (*this);
+ }
+};
+
+// aka FieldExpression
+// Struct or union field access expression AST node
+class FieldAccessExpr : public ExprWithoutBlock
+{
+ // Expr* receiver;
+ ::std::unique_ptr<Expr> receiver;
+ Identifier field;
+
+ Location locus;
+
+public:
+ /*~FieldAccessExpr() {
+ delete receiver;
+ }*/
+
+ ::std::string as_string () const;
+
+ FieldAccessExpr (::std::unique_ptr<Expr> field_access_receiver,
+ Identifier field_name,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : ExprWithoutBlock (::std::move (outer_attribs)),
+ receiver (::std::move (field_access_receiver)),
+ field (::std::move (field_name)), locus (locus)
+ {}
+
+ // Copy constructor required due to unique_ptr cloning
+ FieldAccessExpr (FieldAccessExpr const &other)
+ : ExprWithoutBlock (other), receiver (other.receiver->clone_expr ()),
+ field (other.field), locus (other.locus)
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone unique_ptr
+ FieldAccessExpr &operator= (FieldAccessExpr const &other)
+ {
+ ExprWithoutBlock::operator= (other);
+ receiver = other.receiver->clone_expr ();
+ field = other.field;
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ FieldAccessExpr (FieldAccessExpr &&other) = default;
+ FieldAccessExpr &operator= (FieldAccessExpr &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual FieldAccessExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new FieldAccessExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual FieldAccessExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new FieldAccessExpr (*this);
+ }
+};
+
+// Closure parameter data structure
+struct ClosureParam
+{
+private:
+ // Pattern pattern;
+ ::std::unique_ptr<Pattern> pattern;
+
+ // bool has_type_given;
+ // Type type;
+ ::std::unique_ptr<Type> type;
+
+ // TODO: should this store location data?
+
+public:
+ // Returns whether the type of the parameter has been given.
+ inline bool has_type_given () const { return type != NULL; }
+
+ // Constructor for closure parameter
+ ClosureParam (::std::unique_ptr<Pattern> param_pattern,
+ ::std::unique_ptr<Type> param_type = NULL)
+ : pattern (::std::move (param_pattern)), type (::std::move (param_type))
+ {}
+
+ // Copy constructor required due to cloning as a result of unique_ptrs
+ ClosureParam (ClosureParam const &other)
+ : pattern (other.pattern->clone_pattern ())
+ {
+ // guard to protect from null pointer dereference
+ if (other.type != NULL)
+ {
+ type = other.type->clone_type ();
+ }
+ }
+
+ ~ClosureParam () = default;
+
+ // Assignment operator must be overloaded to clone as well
+ ClosureParam &operator= (ClosureParam const &other)
+ {
+ pattern = other.pattern->clone_pattern ();
+ type = other.type->clone_type ();
+
+ return *this;
+ }
+
+ // move constructors
+ ClosureParam (ClosureParam &&other) = default;
+ ClosureParam &operator= (ClosureParam &&other) = default;
+
+ // Returns whether closure parameter is in an error state.
+ inline bool is_error () const { return pattern == NULL; }
+
+ // Creates an error state closure parameter.
+ static ClosureParam create_error () { return ClosureParam (NULL); }
+
+ ::std::string as_string () const;
+};
+
+// Base closure definition expression AST node - abstract
+class ClosureExpr : public ExprWithoutBlock
+{
+ bool has_move;
+ ::std::vector<ClosureParam> params; // may be empty
+ // also note a double pipe "||" can be used for empty params - does not need a
+ // space
+
+ Location locus;
+
+protected:
+ ClosureExpr (::std::vector<ClosureParam> closure_params, bool has_move,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : ExprWithoutBlock (::std::move (outer_attribs)), has_move (has_move),
+ params (::std::move (closure_params)), locus (locus)
+ {}
+
+ // Copy constructor, destructor, and assignment operator override should not
+ // be needed
+public:
+ virtual ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+};
+
+// Represents a non-type-specified closure expression AST node
+class ClosureExprInner : public ClosureExpr
+{
+ // Expr* closure_inner;
+ ::std::unique_ptr<Expr> closure_inner;
+
+public:
+ /*~ClosureExprInner() {
+ delete closure_inner;
+ }*/
+
+ ::std::string as_string () const;
+
+ // Constructor for a ClosureExprInner
+ ClosureExprInner (::std::unique_ptr<Expr> closure_inner_expr,
+ ::std::vector<ClosureParam> closure_params, Location locus,
+ bool is_move = false,
+ ::std::vector<Attribute> outer_attribs
+ = ::std::vector<Attribute> ())
+ : ClosureExpr (::std::move (closure_params), is_move,
+ ::std::move (outer_attribs), locus),
+ closure_inner (::std::move (closure_inner_expr))
+ {}
+
+ // Copy constructor must be defined to allow copying via cloning of unique_ptr
+ ClosureExprInner (ClosureExprInner const &other)
+ : ClosureExpr (other), closure_inner (other.closure_inner->clone_expr ())
+ {}
+ // TODO: ensure that this actually constructs properly
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone closure_inner
+ ClosureExprInner &operator= (ClosureExprInner const &other)
+ {
+ ClosureExpr::operator= (other);
+ closure_inner = other.closure_inner->clone_expr ();
+ // params = other.params;
+ // has_move = other.has_move;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ ClosureExprInner (ClosureExprInner &&other) = default;
+ ClosureExprInner &operator= (ClosureExprInner &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ClosureExprInner *clone_expr_impl () const OVERRIDE
+ {
+ return new ClosureExprInner (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ClosureExprInner *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new ClosureExprInner (*this);
+ }
+};
+
+// Forward decl BlockExpr for ClosureExprInnerTyped
+// class BlockExpr;
+
+// A block AST node
+class BlockExpr : public ExprWithBlock
+{
+ ::std::vector<Attribute> inner_attrs;
+
+ /*bool has_statements;
+ Statements statements;*/
+
+ // bool has_statements;
+ ::std::vector< ::std::unique_ptr<Stmt> > statements;
+ // bool has_expr;
+ ::std::unique_ptr<ExprWithoutBlock> expr; // inlined from Statements
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ // Returns whether the block contains statements.
+ inline bool has_statements () const { return !statements.empty (); }
+
+ // Returns whether the block contains an expression
+ inline bool has_expr () const { return expr != NULL; }
+
+ BlockExpr (::std::vector< ::std::unique_ptr<Stmt> > block_statements,
+ ::std::unique_ptr<ExprWithoutBlock> block_expr,
+ ::std::vector<Attribute> inner_attribs,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : ExprWithBlock (::std::move (outer_attribs)),
+ inner_attrs (::std::move (inner_attribs)),
+ statements (::std::move (block_statements)),
+ expr (::std::move (block_expr)), locus (locus)
+ {}
+
+ // Copy constructor with clone
+ BlockExpr (BlockExpr const &other)
+ : ExprWithBlock (other), /*statements(other.statements),*/
+ inner_attrs (other.inner_attrs), locus (other.locus)
+ {
+ // guard to protect from null pointer dereference
+ if (other.expr != NULL)
+ {
+ expr = other.expr->clone_expr_without_block ();
+ }
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ statements.reserve (other.statements.size ());
+
+ for (const auto &e : other.statements)
+ {
+ statements.push_back (e->clone_stmt ());
+ }
+ }
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone pointer
+ BlockExpr &operator= (BlockExpr const &other)
+ {
+ ExprWithBlock::operator= (other);
+ // statements = other.statements;
+ expr = other.expr->clone_expr_without_block ();
+ inner_attrs = other.inner_attrs;
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ statements.reserve (other.statements.size ());
+
+ for (const auto &e : other.statements)
+ {
+ statements.push_back (e->clone_stmt ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ BlockExpr (BlockExpr &&other) = default;
+ BlockExpr &operator= (BlockExpr &&other) = default;
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<BlockExpr> clone_block_expr () const
+ {
+ return ::std::unique_ptr<BlockExpr> (clone_block_expr_impl ());
+ }
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual BlockExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new BlockExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual BlockExpr *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new BlockExpr (*this);
+ }
+
+ /* This is the base method as not an abstract class - not virtual but could be
+ * in future if required. */
+ /*virtual*/ BlockExpr *clone_block_expr_impl () const
+ {
+ return new BlockExpr (*this);
+ }
+};
+
+// Represents a type-specified closure expression AST node
+class ClosureExprInnerTyped : public ClosureExpr
+{
+ // Type return_type;
+ ::std::unique_ptr<Type> return_type;
+ // BlockExpr* expr;
+ ::std::unique_ptr<BlockExpr>
+ expr; // only used because may be polymorphic in future
+
+public:
+ /*~ClosureExprInnerTyped() {
+ delete expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ // Constructor potentially with a move
+ ClosureExprInnerTyped (::std::unique_ptr<Type> closure_return_type,
+ ::std::unique_ptr<BlockExpr> closure_expr,
+ ::std::vector<ClosureParam> closure_params,
+ Location locus, bool is_move = false,
+ ::std::vector<Attribute> outer_attribs
+ = ::std::vector<Attribute> ())
+ : ClosureExpr (::std::move (closure_params), is_move,
+ ::std::move (outer_attribs), locus),
+ return_type (::std::move (closure_return_type)),
+ expr (::std::move (closure_expr))
+ {}
+
+ // Copy constructor requires cloning
+ ClosureExprInnerTyped (ClosureExprInnerTyped const &other)
+ : ClosureExpr (other), return_type (other.return_type->clone_type ()),
+ expr (other.expr->clone_block_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone unique_ptrs
+ ClosureExprInnerTyped &operator= (ClosureExprInnerTyped const &other)
+ {
+ ClosureExpr::operator= (other);
+ return_type = other.return_type->clone_type ();
+ expr = other.expr->clone_block_expr ();
+ // params = other.params;
+ // has_move = other.has_move;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ ClosureExprInnerTyped (ClosureExprInnerTyped &&other) = default;
+ ClosureExprInnerTyped &operator= (ClosureExprInnerTyped &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ClosureExprInnerTyped *clone_expr_impl () const OVERRIDE
+ {
+ return new ClosureExprInnerTyped (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ClosureExprInnerTyped *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new ClosureExprInnerTyped (*this);
+ }
+};
+
+// AST node representing continue expression within loops
+class ContinueExpr : public ExprWithoutBlock
+{
+ // bool has_label;
+ Lifetime label;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ // Returns true if the continue expr has a label.
+ inline bool has_label () const { return !label.is_error (); }
+
+ // Constructor for a ContinueExpr with a label.
+ ContinueExpr (Location locus, Lifetime label = Lifetime::error (),
+ ::std::vector<Attribute> outer_attribs
+ = ::std::vector<Attribute> ())
+ : ExprWithoutBlock (::std::move (outer_attribs)),
+ label (::std::move (label)), locus (locus)
+ {}
+
+ // copy constructor, destructor, and assignment operator should not need
+ // defining
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ContinueExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new ContinueExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ContinueExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new ContinueExpr (*this);
+ }
+};
+// TODO: merge "break" and "continue"? Or even merge in "return"?
+
+// AST node representing break expression within loops
+class BreakExpr : public ExprWithoutBlock
+{
+ // bool has_label;
+ Lifetime label;
+
+ // bool has_break_expr;
+ // Expr* break_expr; // may be uninitialised
+ ::std::unique_ptr<Expr> break_expr;
+
+ Location locus;
+
+public:
+ /*~BreakExpr() {
+ if (has_break_expr) {
+ delete break_expr;
+ }
+ }*/
+
+ ::std::string as_string () const;
+
+ // Returns whether the break expression has a label or not.
+ inline bool has_label () const { return !label.is_error (); }
+
+ // Returns whether the break expression has an expression used in the break or
+ // not.
+ inline bool has_break_expr () const { return break_expr != NULL; }
+
+ // Constructor for a break expression
+ BreakExpr (Location locus, Lifetime break_label = Lifetime::error (),
+ ::std::unique_ptr<Expr> expr_in_break = NULL,
+ ::std::vector<Attribute> outer_attribs
+ = ::std::vector<Attribute> ())
+ : ExprWithoutBlock (::std::move (outer_attribs)),
+ label (::std::move (break_label)),
+ break_expr (::std::move (expr_in_break)), locus (locus)
+ {}
+
+ // Copy constructor defined to use clone for unique pointer
+ BreakExpr (BreakExpr const &other)
+ : ExprWithoutBlock (other), label (other.label), locus (other.locus)
+ {
+ // guard to protect from null pointer dereference
+ if (other.break_expr != NULL)
+ {
+ break_expr = other.break_expr->clone_expr ();
+ }
+ }
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone unique pointer
+ BreakExpr &operator= (BreakExpr const &other)
+ {
+ ExprWithoutBlock::operator= (other);
+ label = other.label;
+ break_expr = other.break_expr->clone_expr ();
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ BreakExpr (BreakExpr &&other) = default;
+ BreakExpr &operator= (BreakExpr &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual BreakExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new BreakExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual BreakExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new BreakExpr (*this);
+ }
+};
+
+// Base range expression AST node object - abstract
+class RangeExpr : public ExprWithoutBlock
+{
+ Location locus;
+
+protected:
+ // outer attributes not allowed before range expressions
+ RangeExpr (Location locus)
+ : ExprWithoutBlock (::std::vector<Attribute> ()), locus (locus)
+ {}
+
+public:
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+};
+
+// Range from (inclusive) and to (exclusive) expression AST node object
+// aka RangeExpr; constructs a std::ops::Range object
+class RangeFromToExpr : public RangeExpr
+{
+ /*Expr* from;
+ Expr* to;*/
+ ::std::unique_ptr<Expr> from;
+ ::std::unique_ptr<Expr> to;
+
+public:
+ /*~RangeFromToExpr() {
+ delete from;
+ delete to;
+ }*/
+
+ ::std::string as_string () const;
+
+ RangeFromToExpr (::std::unique_ptr<Expr> range_from,
+ ::std::unique_ptr<Expr> range_to, Location locus)
+ : RangeExpr (locus), from (::std::move (range_from)),
+ to (::std::move (range_to))
+ {}
+
+ // Copy constructor with cloning
+ RangeFromToExpr (RangeFromToExpr const &other)
+ : RangeExpr (other), from (other.from->clone_expr ()),
+ to (other.to->clone_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone unique pointers
+ RangeFromToExpr &operator= (RangeFromToExpr const &other)
+ {
+ RangeExpr::operator= (other);
+ from = other.from->clone_expr ();
+ to = other.to->clone_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ RangeFromToExpr (RangeFromToExpr &&other) = default;
+ RangeFromToExpr &operator= (RangeFromToExpr &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangeFromToExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new RangeFromToExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangeFromToExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new RangeFromToExpr (*this);
+ }
+};
+
+// Range from (inclusive) expression AST node object
+// constructs a std::ops::RangeFrom object
+class RangeFromExpr : public RangeExpr
+{
+ // Expr* from;
+ ::std::unique_ptr<Expr> from;
+
+public:
+ /*~RangeFromExpr() {
+ delete from;
+ }*/
+
+ ::std::string as_string () const;
+
+ RangeFromExpr (::std::unique_ptr<Expr> range_from, Location locus)
+ : RangeExpr (locus), from (::std::move (range_from))
+ {}
+
+ // Copy constructor with clone
+ RangeFromExpr (RangeFromExpr const &other)
+ : RangeExpr (other), from (other.from->clone_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone unique_ptr
+ RangeFromExpr &operator= (RangeFromExpr const &other)
+ {
+ RangeExpr::operator= (other);
+ from = other.from->clone_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ RangeFromExpr (RangeFromExpr &&other) = default;
+ RangeFromExpr &operator= (RangeFromExpr &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangeFromExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new RangeFromExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangeFromExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new RangeFromExpr (*this);
+ }
+};
+
+// Range to (exclusive) expression AST node object
+// constructs a std::ops::RangeTo object
+class RangeToExpr : public RangeExpr
+{
+ // Expr* to;
+ ::std::unique_ptr<Expr> to;
+
+public:
+ /*~RangeToExpr() {
+ delete to;
+ }*/
+
+ ::std::string as_string () const;
+
+ // outer attributes not allowed
+ RangeToExpr (::std::unique_ptr<Expr> range_to, Location locus)
+ : RangeExpr (locus), to (::std::move (range_to))
+ {}
+
+ // Copy constructor with clone
+ RangeToExpr (RangeToExpr const &other)
+ : RangeExpr (other), to (other.to->clone_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone unique_ptr
+ RangeToExpr &operator= (RangeToExpr const &other)
+ {
+ RangeExpr::operator= (other);
+ to = other.to->clone_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ RangeToExpr (RangeToExpr &&other) = default;
+ RangeToExpr &operator= (RangeToExpr &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangeToExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new RangeToExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangeToExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new RangeToExpr (*this);
+ }
+};
+
+// Full range expression AST node object
+// constructs a std::ops::RangeFull object
+class RangeFullExpr : public RangeExpr
+{
+public:
+ ::std::string as_string () const;
+
+ RangeFullExpr (Location locus) : RangeExpr (locus) {}
+ // outer attributes not allowed
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangeFullExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new RangeFullExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangeFullExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new RangeFullExpr (*this);
+ }
+};
+
+// Range from (inclusive) and to (inclusive) expression AST node object
+// aka RangeInclusiveExpr; constructs a std::ops::RangeInclusive object
+class RangeFromToInclExpr : public RangeExpr
+{
+ /*Expr* from;
+ Expr* to;*/
+ ::std::unique_ptr<Expr> from;
+ ::std::unique_ptr<Expr> to;
+
+public:
+ /*~RangeFromToInclExpr() {
+ delete from;
+ delete to;
+ }*/
+
+ ::std::string as_string () const;
+
+ RangeFromToInclExpr (::std::unique_ptr<Expr> range_from,
+ ::std::unique_ptr<Expr> range_to, Location locus)
+ : RangeExpr (locus), from (::std::move (range_from)),
+ to (::std::move (range_to))
+ {}
+ // outer attributes not allowed
+
+ // Copy constructor with clone
+ RangeFromToInclExpr (RangeFromToInclExpr const &other)
+ : RangeExpr (other), from (other.from->clone_expr ()),
+ to (other.to->clone_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to use clone
+ RangeFromToInclExpr &operator= (RangeFromToInclExpr const &other)
+ {
+ RangeExpr::operator= (other);
+ from = other.from->clone_expr ();
+ to = other.to->clone_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ RangeFromToInclExpr (RangeFromToInclExpr &&other) = default;
+ RangeFromToInclExpr &operator= (RangeFromToInclExpr &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangeFromToInclExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new RangeFromToInclExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangeFromToInclExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new RangeFromToInclExpr (*this);
+ }
+};
+
+// Range to (inclusive) expression AST node object
+// aka RangeToInclusiveExpr; constructs a std::ops::RangeToInclusive object
+class RangeToInclExpr : public RangeExpr
+{
+ // Expr* to;
+ ::std::unique_ptr<Expr> to;
+
+public:
+ /*~RangeToInclExpr() {
+ delete to;
+ }*/
+
+ ::std::string as_string () const;
+
+ RangeToInclExpr (::std::unique_ptr<Expr> range_to, Location locus)
+ : RangeExpr (locus), to (::std::move (range_to))
+ {}
+ // outer attributes not allowed
+
+ // Copy constructor with clone
+ RangeToInclExpr (RangeToInclExpr const &other)
+ : RangeExpr (other), to (other.to->clone_expr ())
+ {}
+
+ // Define destructor here if required
+
+ // Overload assignment operator to clone pointer
+ RangeToInclExpr &operator= (RangeToInclExpr const &other)
+ {
+ RangeExpr::operator= (other);
+ to = other.to->clone_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ RangeToInclExpr (RangeToInclExpr &&other) = default;
+ RangeToInclExpr &operator= (RangeToInclExpr &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangeToInclExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new RangeToInclExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangeToInclExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new RangeToInclExpr (*this);
+ }
+};
+
+// Return expression AST node representation
+class ReturnExpr : public ExprWithoutBlock
+{
+ // bool has_return_expr;
+ // Expr* return_expr;
+ ::std::unique_ptr<Expr> return_expr;
+
+ Location locus;
+
+public:
+ /*~ReturnExpr() {
+ if (has_return_expr) {
+ delete return_expr;
+ }
+ }*/
+
+ ::std::string as_string () const;
+
+ // Returns whether the object has an expression returned (i.e. not void return
+ // type).
+ inline bool has_return_expr () const { return return_expr != NULL; }
+
+ // Constructor for ReturnExpr.
+ ReturnExpr (Location locus, ::std::unique_ptr<Expr> returned_expr = NULL,
+ ::std::vector<Attribute> outer_attribs
+ = ::std::vector<Attribute> ())
+ : ExprWithoutBlock (::std::move (outer_attribs)),
+ return_expr (::std::move (returned_expr)), locus (locus)
+ {}
+
+ // Copy constructor with clone
+ ReturnExpr (ReturnExpr const &other)
+ : ExprWithoutBlock (other), locus (other.locus)
+ {
+ // guard to protect from null pointer dereference
+ if (other.return_expr != NULL)
+ {
+ return_expr = other.return_expr->clone_expr ();
+ }
+ }
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone return_expr pointer
+ ReturnExpr &operator= (ReturnExpr const &other)
+ {
+ ExprWithoutBlock::operator= (other);
+ return_expr = other.return_expr->clone_expr ();
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ ReturnExpr (ReturnExpr &&other) = default;
+ ReturnExpr &operator= (ReturnExpr &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ReturnExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new ReturnExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ReturnExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new ReturnExpr (*this);
+ }
+};
+
+// Forward decl - defined in rust-macro.h
+class MacroInvocation;
+/*class MacroInvocation : public ExprWithoutBlock {
+ public:
+ ::std::string as_string() const;
+};*/
+
+// An unsafe block AST node
+class UnsafeBlockExpr : public ExprWithBlock
+{
+ // Or just have it extend BlockExpr
+ // BlockExpr* expr;
+ ::std::unique_ptr<BlockExpr> expr;
+
+ Location locus;
+
+public:
+ /*~UnsafeBlockExpr() {
+ delete expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ UnsafeBlockExpr (::std::unique_ptr<BlockExpr> block_expr,
+ ::std::vector<Attribute> outer_attribs, Location locus)
+ : ExprWithBlock (::std::move (outer_attribs)),
+ expr (::std::move (block_expr)), locus (locus)
+ {}
+
+ // Copy constructor with clone
+ UnsafeBlockExpr (UnsafeBlockExpr const &other)
+ : ExprWithBlock (other), expr (other.expr->clone_block_expr ()),
+ locus (other.locus)
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone
+ UnsafeBlockExpr &operator= (UnsafeBlockExpr const &other)
+ {
+ ExprWithBlock::operator= (other);
+ expr = other.expr->clone_block_expr ();
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ UnsafeBlockExpr (UnsafeBlockExpr &&other) = default;
+ UnsafeBlockExpr &operator= (UnsafeBlockExpr &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual UnsafeBlockExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new UnsafeBlockExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual UnsafeBlockExpr *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new UnsafeBlockExpr (*this);
+ }
+};
+
+// Loop label expression AST node used with break and continue expressions
+// TODO: inline?
+class LoopLabel /*: public Node*/
+{
+ Lifetime label; // or type LIFETIME_OR_LABEL
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ LoopLabel (Lifetime loop_label, Location locus = Location ())
+ : label (::std::move (loop_label)), locus (locus)
+ {}
+
+ // Returns whether the LoopLabel is in an error state.
+ inline bool is_error () const { return label.is_error (); }
+
+ // Creates an error state LoopLabel.
+ static LoopLabel error () { return LoopLabel (Lifetime::error ()); }
+
+ Location get_locus () const { return locus; }
+};
+
+// Base loop expression AST node - aka LoopExpr
+class BaseLoopExpr : public ExprWithBlock
+{
+protected:
+ // protected to allow subclasses better use of them
+ // bool has_loop_label;
+ LoopLabel loop_label;
+
+ // BlockExpr* loop_block;
+ ::std::unique_ptr<BlockExpr> loop_block;
+
+private:
+ Location locus;
+
+protected:
+ // Constructor for BaseLoopExpr
+ BaseLoopExpr (::std::unique_ptr<BlockExpr> loop_block, Location locus,
+ LoopLabel loop_label = LoopLabel::error (),
+ ::std::vector<Attribute> outer_attribs
+ = ::std::vector<Attribute> ())
+ : ExprWithBlock (::std::move (outer_attribs)),
+ loop_label (::std::move (loop_label)),
+ loop_block (::std::move (loop_block)), locus (locus)
+ {}
+
+ // Copy constructor for BaseLoopExpr with clone
+ BaseLoopExpr (BaseLoopExpr const &other)
+ : ExprWithBlock (other), loop_label (other.loop_label),
+ loop_block (other.loop_block->clone_block_expr ()), locus (other.locus)
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone
+ BaseLoopExpr &operator= (BaseLoopExpr const &other)
+ {
+ ExprWithBlock::operator= (other);
+ loop_block = other.loop_block->clone_block_expr ();
+ loop_label = other.loop_label;
+ locus = other.locus;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ BaseLoopExpr (BaseLoopExpr &&other) = default;
+ BaseLoopExpr &operator= (BaseLoopExpr &&other) = default;
+
+public:
+ /*~BaseLoopExpr() {
+ delete loop_block;
+ }*/
+
+ inline bool has_loop_label () const { return !loop_label.is_error (); }
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+};
+
+// 'Loop' expression (i.e. the infinite loop) AST node
+class LoopExpr : public BaseLoopExpr
+{
+public:
+ ::std::string as_string () const;
+
+ // Constructor for LoopExpr
+ LoopExpr (::std::unique_ptr<BlockExpr> loop_block, Location locus,
+ LoopLabel loop_label = LoopLabel::error (),
+ ::std::vector<Attribute> outer_attribs
+ = ::std::vector<Attribute> ())
+ : BaseLoopExpr (::std::move (loop_block), locus, ::std::move (loop_label),
+ ::std::move (outer_attribs))
+ {}
+
+ // copy constructor, destructor, and assignment operator should not need
+ // modification
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual LoopExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new LoopExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual LoopExpr *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new LoopExpr (*this);
+ }
+};
+
+// While loop expression AST node (predicate loop)
+class WhileLoopExpr : public BaseLoopExpr
+{
+ // Expr* condition;
+ ::std::unique_ptr<Expr> condition;
+
+public:
+ /*~WhileLoopExpr() {
+ delete condition;
+ }*/
+
+ ::std::string as_string () const;
+
+ // Constructor for while loop with loop label
+ WhileLoopExpr (::std::unique_ptr<Expr> loop_condition,
+ ::std::unique_ptr<BlockExpr> loop_block, Location locus,
+ LoopLabel loop_label = LoopLabel::error (),
+ ::std::vector<Attribute> outer_attribs
+ = ::std::vector<Attribute> ())
+ : BaseLoopExpr (::std::move (loop_block), locus, ::std::move (loop_label),
+ ::std::move (outer_attribs)),
+ condition (::std::move (loop_condition))
+ {}
+
+ // Copy constructor with clone
+ WhileLoopExpr (WhileLoopExpr const &other)
+ : BaseLoopExpr (other), condition (other.condition->clone_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone
+ WhileLoopExpr &operator= (WhileLoopExpr const &other)
+ {
+ BaseLoopExpr::operator= (other);
+ condition = other.condition->clone_expr ();
+ // loop_block = other.loop_block->clone_block_expr();
+ // loop_label = other.loop_label;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ WhileLoopExpr (WhileLoopExpr &&other) = default;
+ WhileLoopExpr &operator= (WhileLoopExpr &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual WhileLoopExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new WhileLoopExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual WhileLoopExpr *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new WhileLoopExpr (*this);
+ }
+};
+
+// Forward decl MatchArmPatterns
+// struct MatchArmPatterns;
+
+// While let loop expression AST node (predicate pattern loop)
+class WhileLetLoopExpr : public BaseLoopExpr
+{
+ // MatchArmPatterns patterns;
+ ::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns; // inlined
+ // Expr* condition;
+ ::std::unique_ptr<Expr> condition;
+
+public:
+ /*~WhileLetLoopExpr() {
+ delete condition;
+ }*/
+
+ ::std::string as_string () const;
+
+ // Constructor with a loop label
+ WhileLetLoopExpr (
+ ::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns,
+ ::std::unique_ptr<Expr> condition, ::std::unique_ptr<BlockExpr> loop_block,
+ Location locus, LoopLabel loop_label = LoopLabel::error (),
+ ::std::vector<Attribute> outer_attribs = ::std::vector<Attribute> ())
+ : BaseLoopExpr (::std::move (loop_block), locus, ::std::move (loop_label),
+ ::std::move (outer_attribs)),
+ match_arm_patterns (::std::move (match_arm_patterns)),
+ condition (::std::move (condition))
+ {}
+
+ // Copy constructor with clone
+ WhileLetLoopExpr (WhileLetLoopExpr const &other)
+ : BaseLoopExpr (other),
+ /*match_arm_patterns(other.match_arm_patterns),*/ condition (
+ other.condition->clone_expr ())
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ match_arm_patterns.reserve (other.match_arm_patterns.size ());
+
+ for (const auto &e : other.match_arm_patterns)
+ {
+ match_arm_patterns.push_back (e->clone_pattern ());
+ }
+ }
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone pointers
+ WhileLetLoopExpr &operator= (WhileLetLoopExpr const &other)
+ {
+ BaseLoopExpr::operator= (other);
+ // match_arm_patterns = other.match_arm_patterns;
+ condition = other.condition->clone_expr ();
+ // loop_block = other.loop_block->clone_block_expr();
+ // loop_label = other.loop_label;
+ // outer_attrs = other.outer_attrs;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ match_arm_patterns.reserve (other.match_arm_patterns.size ());
+
+ for (const auto &e : other.match_arm_patterns)
+ {
+ match_arm_patterns.push_back (e->clone_pattern ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ WhileLetLoopExpr (WhileLetLoopExpr &&other) = default;
+ WhileLetLoopExpr &operator= (WhileLetLoopExpr &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual WhileLetLoopExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new WhileLetLoopExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual WhileLetLoopExpr *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new WhileLetLoopExpr (*this);
+ }
+};
+
+// For loop expression AST node (iterator loop)
+class ForLoopExpr : public BaseLoopExpr
+{
+ // Pattern pattern;
+ ::std::unique_ptr<Pattern> pattern;
+ // Expr* iterator_expr;
+ ::std::unique_ptr<Expr> iterator_expr;
+
+public:
+ /*~ForLoopExpr() {
+ delete iterator_expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ // Constructor with loop label
+ ForLoopExpr (::std::unique_ptr<Pattern> loop_pattern,
+ ::std::unique_ptr<Expr> iterator_expr,
+ ::std::unique_ptr<BlockExpr> loop_body, Location locus,
+ LoopLabel loop_label = LoopLabel::error (),
+ ::std::vector<Attribute> outer_attribs
+ = ::std::vector<Attribute> ())
+ : BaseLoopExpr (::std::move (loop_body), locus, ::std::move (loop_label),
+ ::std::move (outer_attribs)),
+ pattern (::std::move (loop_pattern)),
+ iterator_expr (::std::move (iterator_expr))
+ {}
+
+ // Copy constructor with clone
+ ForLoopExpr (ForLoopExpr const &other)
+ : BaseLoopExpr (other), pattern (other.pattern->clone_pattern ()),
+ iterator_expr (other.iterator_expr->clone_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone
+ ForLoopExpr &operator= (ForLoopExpr const &other)
+ {
+ BaseLoopExpr::operator= (other);
+ pattern = other.pattern->clone_pattern ();
+ iterator_expr = other.iterator_expr->clone_expr ();
+ /*loop_block = other.loop_block->clone_block_expr();
+ loop_label = other.loop_label;
+ outer_attrs = other.outer_attrs;*/
+
+ return *this;
+ }
+
+ // move constructors
+ ForLoopExpr (ForLoopExpr &&other) = default;
+ ForLoopExpr &operator= (ForLoopExpr &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ForLoopExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new ForLoopExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ForLoopExpr *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new ForLoopExpr (*this);
+ }
+};
+
+// forward decl for IfExpr
+class IfLetExpr;
+
+// Base if expression with no "else" or "if let" AST node
+class IfExpr : public ExprWithBlock
+{
+ /*Expr* condition;
+ BlockExpr* if_block;*/
+ ::std::unique_ptr<Expr> condition;
+ ::std::unique_ptr<BlockExpr> if_block;
+ /*union {
+ BlockExpr else_block;
+ IfExpr* if_expr;
+ IfLetExpr if_let_expr;
+ } consequent_block;*/
+
+ Location locus;
+
+public:
+ /*virtual ~IfExpr() {
+ delete condition;
+ delete if_block;
+ }*/
+
+ ::std::string as_string () const;
+
+ IfExpr (::std::unique_ptr<Expr> condition,
+ ::std::unique_ptr<BlockExpr> if_block, Location locus)
+ : ExprWithBlock (::std::vector<Attribute> ()),
+ condition (::std::move (condition)), if_block (::std::move (if_block)),
+ locus (locus)
+ {}
+ // outer attributes are never allowed on IfExprs
+
+ // Copy constructor with clone
+ IfExpr (IfExpr const &other)
+ : ExprWithBlock (other), condition (other.condition->clone_expr ()),
+ if_block (other.if_block->clone_block_expr ()), locus (other.locus)
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone expressions
+ IfExpr &operator= (IfExpr const &other)
+ {
+ ExprWithBlock::operator= (other);
+ condition = other.condition->clone_expr ();
+ if_block = other.if_block->clone_block_expr ();
+ locus = other.locus;
+
+ return *this;
+ }
+
+ // move constructors
+ IfExpr (IfExpr &&other) = default;
+ IfExpr &operator= (IfExpr &&other) = default;
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<IfExpr> clone_if_expr () const
+ {
+ return ::std::unique_ptr<IfExpr> (clone_if_expr_impl ());
+ }
+
+ /* Note that multiple "else if"s are handled via nested ASTs rather than a
+ * vector of else ifs - i.e. not like a switch statement. TODO - is this a
+ * better approach? or does it not parse correctly and have downsides? */
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new IfExpr (*this);
+ }
+
+ // Base clone function but still concrete as concrete base class
+ virtual IfExpr *clone_if_expr_impl () const { return new IfExpr (*this); }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfExpr *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new IfExpr (*this);
+ }
+};
+
+// If expression with an ending "else" expression AST node (trailing)
+class IfExprConseqElse : public IfExpr
+{
+ // BlockExpr* else_block;
+ ::std::unique_ptr<BlockExpr> else_block;
+
+public:
+ /*~IfExprConseqElse() {
+ delete else_block;
+ }*/
+
+ ::std::string as_string () const;
+
+ IfExprConseqElse (::std::unique_ptr<Expr> condition,
+ ::std::unique_ptr<BlockExpr> if_block,
+ ::std::unique_ptr<BlockExpr> else_block, Location locus)
+ : IfExpr (::std::move (condition), ::std::move (if_block), locus),
+ else_block (::std::move (else_block))
+ {}
+ // again, outer attributes not allowed
+
+ // Copy constructor with clone
+ IfExprConseqElse (IfExprConseqElse const &other)
+ : IfExpr (other), else_block (other.else_block->clone_block_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator with cloning
+ IfExprConseqElse &operator= (IfExprConseqElse const &other)
+ {
+ IfExpr::operator= (other);
+ // condition = other.condition->clone_expr();
+ // if_block = other.if_block->clone_block_expr();
+ else_block = other.else_block->clone_block_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ IfExprConseqElse (IfExprConseqElse &&other) = default;
+ IfExprConseqElse &operator= (IfExprConseqElse &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfExprConseqElse *clone_expr_impl () const OVERRIDE
+ {
+ return new IfExprConseqElse (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfExprConseqElse *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new IfExprConseqElse (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfExprConseqElse *clone_if_expr_impl () const OVERRIDE
+ {
+ return new IfExprConseqElse (*this);
+ }
+};
+
+// If expression with an ending "else if" expression AST node
+class IfExprConseqIf : public IfExpr
+{
+ // IfExpr* if_expr;
+ ::std::unique_ptr<IfExpr> if_expr;
+
+public:
+ /*~IfExprConseqIf() {
+ delete if_expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ IfExprConseqIf (::std::unique_ptr<Expr> condition,
+ ::std::unique_ptr<BlockExpr> if_block,
+ ::std::unique_ptr<IfExpr> conseq_if_expr, Location locus)
+ : IfExpr (::std::move (condition), ::std::move (if_block), locus),
+ if_expr (::std::move (conseq_if_expr))
+ {}
+ // outer attributes not allowed
+
+ // Copy constructor with clone
+ IfExprConseqIf (IfExprConseqIf const &other)
+ : IfExpr (other), if_expr (other.if_expr->clone_if_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to use clone
+ IfExprConseqIf &operator= (IfExprConseqIf const &other)
+ {
+ IfExpr::operator= (other);
+ // condition = other.condition->clone_expr();
+ // if_block = other.if_block->clone_block_expr();
+ if_expr = other.if_expr->clone_if_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ IfExprConseqIf (IfExprConseqIf &&other) = default;
+ IfExprConseqIf &operator= (IfExprConseqIf &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfExprConseqIf *clone_expr_impl () const OVERRIDE
+ {
+ return new IfExprConseqIf (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfExprConseqIf *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new IfExprConseqIf (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfExprConseqIf *clone_if_expr_impl () const OVERRIDE
+ {
+ return new IfExprConseqIf (*this);
+ }
+};
+
+// Basic "if let" expression AST node with no else
+class IfLetExpr : public ExprWithBlock
+{
+ // MatchArmPatterns patterns;
+ ::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns; // inlined
+ /*Expr* value;
+ BlockExpr* if_block;*/
+ ::std::unique_ptr<Expr> value;
+ ::std::unique_ptr<BlockExpr> if_block;
+ /*union {
+ BlockExpr else_block;
+ IfExpr if_expr;
+ IfLetExpr* if_let_expr;
+ } consequent_block;*/
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ IfLetExpr (::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns,
+ ::std::unique_ptr<Expr> value,
+ ::std::unique_ptr<BlockExpr> if_block, Location locus)
+ : ExprWithBlock (::std::vector<Attribute> ()),
+ match_arm_patterns (::std::move (match_arm_patterns)),
+ value (::std::move (value)), if_block (::std::move (if_block)),
+ locus (locus)
+ {}
+ // outer attributes not allowed on if let exprs either
+
+ // copy constructor with clone
+ IfLetExpr (IfLetExpr const &other)
+ : ExprWithBlock (other),
+ /*match_arm_patterns(other.match_arm_patterns),*/ value (
+ other.value->clone_expr ()),
+ if_block (other.if_block->clone_block_expr ()), locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ match_arm_patterns.reserve (other.match_arm_patterns.size ());
+
+ for (const auto &e : other.match_arm_patterns)
+ {
+ match_arm_patterns.push_back (e->clone_pattern ());
+ }
+ }
+
+ // destructor - define here if required
+
+ // overload assignment operator to clone
+ IfLetExpr &operator= (IfLetExpr const &other)
+ {
+ ExprWithBlock::operator= (other);
+ // match_arm_patterns = other.match_arm_patterns;
+ value = other.value->clone_expr ();
+ if_block = other.if_block->clone_block_expr ();
+ locus = other.locus;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ match_arm_patterns.reserve (other.match_arm_patterns.size ());
+
+ for (const auto &e : other.match_arm_patterns)
+ {
+ match_arm_patterns.push_back (e->clone_pattern ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ IfLetExpr (IfLetExpr &&other) = default;
+ IfLetExpr &operator= (IfLetExpr &&other) = default;
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<IfLetExpr> clone_if_let_expr () const
+ {
+ return ::std::unique_ptr<IfLetExpr> (clone_if_let_expr_impl ());
+ }
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfLetExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new IfLetExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfLetExpr *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new IfLetExpr (*this);
+ }
+
+ // Base clone function but still concrete as concrete base class
+ virtual IfLetExpr *clone_if_let_expr_impl () const
+ {
+ return new IfLetExpr (*this);
+ }
+};
+
+// If expression with an ending "else if let" expression AST node
+class IfExprConseqIfLet : public IfExpr
+{
+ // IfLetExpr* if_let_expr;
+ ::std::unique_ptr<IfLetExpr> if_let_expr;
+
+public:
+ /*~IfExprIfConseqIfLet() {
+ delete if_let_expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ IfExprConseqIfLet (::std::unique_ptr<Expr> condition,
+ ::std::unique_ptr<BlockExpr> if_block,
+ ::std::unique_ptr<IfLetExpr> conseq_if_let_expr,
+ Location locus)
+ : IfExpr (::std::move (condition), ::std::move (if_block), locus),
+ if_let_expr (::std::move (conseq_if_let_expr))
+ {}
+ // outer attributes not allowed
+
+ // Copy constructor with clone
+ IfExprConseqIfLet (IfExprConseqIfLet const &other)
+ : IfExpr (other), if_let_expr (other.if_let_expr->clone_if_let_expr ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to use clone
+ IfExprConseqIfLet &operator= (IfExprConseqIfLet const &other)
+ {
+ IfExpr::operator= (other);
+ // condition = other.condition->clone_expr();
+ // if_block = other.if_block->clone_block_expr();
+ if_let_expr = other.if_let_expr->clone_if_let_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ IfExprConseqIfLet (IfExprConseqIfLet &&other) = default;
+ IfExprConseqIfLet &operator= (IfExprConseqIfLet &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfExprConseqIfLet *clone_expr_impl () const OVERRIDE
+ {
+ return new IfExprConseqIfLet (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfExprConseqIfLet *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new IfExprConseqIfLet (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfExprConseqIfLet *clone_if_expr_impl () const OVERRIDE
+ {
+ return new IfExprConseqIfLet (*this);
+ }
+};
+
+// AST node representing "if let" expression with an "else" expression at the
+// end
+class IfLetExprConseqElse : public IfLetExpr
+{
+ // BlockExpr* else_block;
+ ::std::unique_ptr<BlockExpr> else_block;
+
+public:
+ /*~IfLetExprConseqElse() {
+ delete else_block;
+ }*/
+
+ ::std::string as_string () const;
+
+ IfLetExprConseqElse (
+ ::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns,
+ ::std::unique_ptr<Expr> value, ::std::unique_ptr<BlockExpr> if_block,
+ ::std::unique_ptr<BlockExpr> else_block, Location locus)
+ : IfLetExpr (::std::move (match_arm_patterns), ::std::move (value),
+ ::std::move (if_block), locus),
+ else_block (::std::move (else_block))
+ {}
+ // outer attributes not allowed
+
+ // copy constructor with clone
+ IfLetExprConseqElse (IfLetExprConseqElse const &other)
+ : IfLetExpr (other), else_block (other.else_block->clone_block_expr ())
+ {}
+
+ // destructor - define here if required
+
+ // overload assignment operator to clone
+ IfLetExprConseqElse &operator= (IfLetExprConseqElse const &other)
+ {
+ IfLetExpr::operator= (other);
+ // match_arm_patterns = other.match_arm_patterns;
+ // value = other.value->clone_expr();
+ // if_block = other.if_block->clone_block_expr();
+ else_block = other.else_block->clone_block_expr ();
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ IfLetExprConseqElse (IfLetExprConseqElse &&other) = default;
+ IfLetExprConseqElse &operator= (IfLetExprConseqElse &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfLetExprConseqElse *clone_expr_impl () const OVERRIDE
+ {
+ return new IfLetExprConseqElse (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfLetExprConseqElse *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new IfLetExprConseqElse (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfLetExprConseqElse *clone_if_let_expr_impl () const OVERRIDE
+ {
+ return new IfLetExprConseqElse (*this);
+ }
+};
+
+// AST node representing "if let" expression with an "else if" expression at the
+// end
+class IfLetExprConseqIf : public IfLetExpr
+{
+ // IfExpr* if_expr;
+ ::std::unique_ptr<IfExpr> if_expr;
+
+public:
+ /*~IfLetExprConseqIf() {
+ delete if_expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ IfLetExprConseqIf (
+ ::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns,
+ ::std::unique_ptr<Expr> value, ::std::unique_ptr<BlockExpr> if_block,
+ ::std::unique_ptr<IfExpr> if_expr, Location locus)
+ : IfLetExpr (::std::move (match_arm_patterns), ::std::move (value),
+ ::std::move (if_block), locus),
+ if_expr (::std::move (if_expr))
+ {}
+ // again, outer attributes not allowed
+
+ // copy constructor with clone
+ IfLetExprConseqIf (IfLetExprConseqIf const &other)
+ : IfLetExpr (other), if_expr (other.if_expr->clone_if_expr ())
+ {}
+
+ // destructor - define here if required
+
+ // overload assignment operator to clone
+ IfLetExprConseqIf &operator= (IfLetExprConseqIf const &other)
+ {
+ IfLetExpr::operator= (other);
+ // match_arm_patterns = other.match_arm_patterns;
+ // value = other.value->clone_expr();
+ // if_block = other.if_block->clone_block_expr();
+ if_expr = other.if_expr->clone_if_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ IfLetExprConseqIf (IfLetExprConseqIf &&other) = default;
+ IfLetExprConseqIf &operator= (IfLetExprConseqIf &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfLetExprConseqIf *clone_expr_impl () const OVERRIDE
+ {
+ return new IfLetExprConseqIf (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfLetExprConseqIf *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new IfLetExprConseqIf (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfLetExprConseqIf *clone_if_let_expr_impl () const OVERRIDE
+ {
+ return new IfLetExprConseqIf (*this);
+ }
+};
+
+// AST node representing "if let" expression with an "else if let" expression at
+// the end
+class IfLetExprConseqIfLet : public IfLetExpr
+{
+ // IfLetExpr* if_let_expr;
+ ::std::unique_ptr<IfLetExpr> if_let_expr;
+
+public:
+ /*~IfLetExprConseqIfLet() {
+ delete if_let_expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ IfLetExprConseqIfLet (
+ ::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns,
+ ::std::unique_ptr<Expr> value, ::std::unique_ptr<BlockExpr> if_block,
+ ::std::unique_ptr<IfLetExpr> if_let_expr, Location locus)
+ : IfLetExpr (::std::move (match_arm_patterns), ::std::move (value),
+ ::std::move (if_block), locus),
+ if_let_expr (::std::move (if_let_expr))
+ {}
+ // outer attributes not allowed
+
+ // copy constructor with clone
+ IfLetExprConseqIfLet (IfLetExprConseqIfLet const &other)
+ : IfLetExpr (other), if_let_expr (other.if_let_expr->clone_if_let_expr ())
+ {}
+
+ // destructor - define here if required
+
+ // overload assignment operator to clone
+ IfLetExprConseqIfLet &operator= (IfLetExprConseqIfLet const &other)
+ {
+ IfLetExpr::operator= (other);
+ // match_arm_patterns = other.match_arm_patterns;
+ // value = other.value->clone_expr();
+ // if_block = other.if_block->clone_block_expr();
+ if_let_expr = other.if_let_expr->clone_if_let_expr ();
+
+ return *this;
+ }
+
+ // move constructors
+ IfLetExprConseqIfLet (IfLetExprConseqIfLet &&other) = default;
+ IfLetExprConseqIfLet &operator= (IfLetExprConseqIfLet &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfLetExprConseqIfLet *clone_expr_impl () const OVERRIDE
+ {
+ return new IfLetExprConseqIfLet (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfLetExprConseqIfLet *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new IfLetExprConseqIfLet (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IfLetExprConseqIfLet *clone_if_let_expr_impl () const OVERRIDE
+ {
+ return new IfLetExprConseqIfLet (*this);
+ }
+};
+
+// Match arm expression
+struct MatchArm
+{
+private:
+ ::std::vector<Attribute> outer_attrs;
+ // MatchArmPatterns patterns;
+ ::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns; // inlined
+
+ // bool has_match_arm_guard;
+ // Expr* match_arm_guard; // inlined from MatchArmGuard
+ ::std::unique_ptr<Expr> guard_expr;
+
+ // TODO: should this store location data?
+
+public:
+ /*~MatchArm() {
+ if (has_match_arm_guard) {
+ delete match_arm_guard;
+ }
+ }*/
+
+ // Returns whether the MatchArm has a match arm guard expression
+ inline bool has_match_arm_guard () const { return guard_expr != NULL; }
+
+ // Constructor for match arm with a guard expression
+ MatchArm (::std::vector< ::std::unique_ptr<Pattern> > match_arm_patterns,
+ ::std::unique_ptr<Expr> guard_expr = NULL,
+ ::std::vector<Attribute> outer_attrs = ::std::vector<Attribute> ())
+ : outer_attrs (::std::move (outer_attrs)),
+ match_arm_patterns (::std::move (match_arm_patterns)),
+ guard_expr (::std::move (guard_expr))
+ {}
+
+ // Copy constructor with clone
+ MatchArm (MatchArm const &other)
+ : /*match_arm_patterns(other.match_arm_patterns),*/ outer_attrs (
+ other.outer_attrs)
+ {
+ // guard to protect from null pointer dereference
+ if (other.guard_expr != NULL)
+ {
+ guard_expr = other.guard_expr->clone_expr ();
+ }
+
+ // DEBUG
+ fprintf (
+ stderr,
+ "started copy-constructing match arm (outer attrs, guard expr done)\n");
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ match_arm_patterns.reserve (other.match_arm_patterns.size ());
+
+ for (const auto &e : other.match_arm_patterns)
+ {
+ match_arm_patterns.push_back (e->clone_pattern ());
+
+ // DEBUG
+ fprintf (stderr, "successfully pushed back a match arm pattern\n");
+ }
+
+ // DEBUG
+ fprintf (stderr, "successfully copy-constructed match arm\n");
+ }
+
+ ~MatchArm () = default;
+
+ // Overload assignment operator to clone
+ MatchArm &operator= (MatchArm const &other)
+ {
+ // match_arm_patterns = other.match_arm_patterns;
+ outer_attrs = other.outer_attrs;
+ guard_expr = other.guard_expr->clone_expr ();
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ match_arm_patterns.reserve (other.match_arm_patterns.size ());
+
+ for (const auto &e : other.match_arm_patterns)
+ {
+ match_arm_patterns.push_back (e->clone_pattern ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ MatchArm (MatchArm &&other) = default;
+ MatchArm &operator= (MatchArm &&other) = default;
+
+ // Returns whether match arm is in an error state.
+ inline bool is_error () const { return match_arm_patterns.empty (); }
+
+ // Creates a match arm in an error state.
+ static MatchArm create_error ()
+ {
+ return MatchArm (::std::vector< ::std::unique_ptr<Pattern> > ());
+ }
+
+ ::std::string as_string () const;
+};
+
+// Base "match case" for a match expression - abstract
+class MatchCase
+{
+ MatchArm arm;
+
+protected:
+ MatchCase (MatchArm arm) : arm (::std::move (arm)) {}
+
+ // Should not require copy constructor or assignment operator overloading
+
+ // Clone function implementation as pure virtual method
+ virtual MatchCase *clone_match_case_impl () const = 0;
+
+public:
+ virtual ~MatchCase () {}
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<MatchCase> clone_match_case () const
+ {
+ // DEBUG
+ fprintf (stderr, "about to call clone match case impl\n");
+
+ return ::std::unique_ptr<MatchCase> (clone_match_case_impl ());
+ }
+
+ virtual ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+};
+
+// Block expression match case
+class MatchCaseBlockExpr : public MatchCase
+{
+ // BlockExpr* block_expr;
+ ::std::unique_ptr<BlockExpr> block_expr;
+
+ // TODO: should this store location data?
+
+public:
+ /*~MatchCaseBlockExpr() {
+ delete block_expr;
+ }*/
+
+ MatchCaseBlockExpr (MatchArm arm, ::std::unique_ptr<BlockExpr> block_expr)
+ : MatchCase (::std::move (arm)), block_expr (::std::move (block_expr))
+ {}
+
+ // Copy constructor requires clone
+ MatchCaseBlockExpr (MatchCaseBlockExpr const &other)
+ : MatchCase (other), block_expr (other.block_expr->clone_block_expr ())
+ {
+ // DEBUG
+ fprintf (stderr, "successfully copy constructed match case expr\n");
+ }
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to have clone
+ MatchCaseBlockExpr &operator= (MatchCaseBlockExpr const &other)
+ {
+ MatchCase::operator= (other);
+ block_expr = other.block_expr->clone_block_expr ();
+ // arm = other.arm;
+
+ return *this;
+ }
+
+ // move constructors
+ MatchCaseBlockExpr (MatchCaseBlockExpr &&other) = default;
+ MatchCaseBlockExpr &operator= (MatchCaseBlockExpr &&other) = default;
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MatchCaseBlockExpr *clone_match_case_impl () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (stderr, "about to copy construct match case block expr\n");
+
+ return new MatchCaseBlockExpr (*this);
+ }
+};
+
+// Expression (except block expression) match case
+class MatchCaseExpr : public MatchCase
+{
+ // Expr* expr;
+ ::std::unique_ptr<Expr> expr;
+
+ // TODO: should this store location data?
+
+public:
+ /*~MatchCaseExpr() {
+ delete expr;
+ }*/
+
+ MatchCaseExpr (MatchArm arm, ::std::unique_ptr<Expr> expr)
+ : MatchCase (::std::move (arm)), expr (::std::move (expr))
+ {}
+
+ // Copy constructor requires clone
+ MatchCaseExpr (MatchCaseExpr const &other)
+ : MatchCase (other), expr (other.expr->clone_expr ())
+ {
+ // DEBUG
+ fprintf (stderr, "successfully copy constructed match case expr\n");
+ }
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to have clone
+ MatchCaseExpr &operator= (MatchCaseExpr const &other)
+ {
+ MatchCase::operator= (other);
+ expr = other.expr->clone_expr ();
+ // arm = other.arm;
+
+ return *this;
+ }
+
+ // move constructors
+ MatchCaseExpr (MatchCaseExpr &&other) = default;
+ MatchCaseExpr &operator= (MatchCaseExpr &&other) = default;
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MatchCaseExpr *clone_match_case_impl () const OVERRIDE
+ {
+ // DEBUG
+ fprintf (stderr, "about to copy construct match case expr\n");
+ if (expr == NULL)
+ {
+ fprintf (
+ stderr,
+ "warning: match case expr to be copy constructed has null expr!\n");
+ }
+
+ return new MatchCaseExpr (*this);
+ }
+};
+
+// Match expression AST node
+class MatchExpr : public ExprWithBlock
+{
+ // Expr* branch_value;
+ ::std::unique_ptr<Expr> branch_value;
+ ::std::vector<Attribute> inner_attrs;
+
+ // bool has_match_arms;
+ // MatchArms match_arms;
+ ::std::vector< ::std::unique_ptr<MatchCase> >
+ match_arms; // inlined from MatchArms
+
+ Location locus;
+
+public:
+ /*~MatchExpr() {
+ delete branch_value;
+ }*/
+
+ ::std::string as_string () const;
+
+ // Returns whether the match expression has any match arms.
+ inline bool has_match_arms () const { return !match_arms.empty (); }
+
+ MatchExpr (::std::unique_ptr<Expr> branch_value,
+ ::std::vector< ::std::unique_ptr<MatchCase> > match_arms,
+ ::std::vector<Attribute> inner_attrs,
+ ::std::vector<Attribute> outer_attrs, Location locus)
+ : ExprWithBlock (::std::move (outer_attrs)),
+ branch_value (::std::move (branch_value)),
+ inner_attrs (::std::move (inner_attrs)),
+ match_arms (::std::move (match_arms)), locus (locus)
+ {}
+
+ // Copy constructor requires clone due to unique_ptr
+ MatchExpr (MatchExpr const &other)
+ : ExprWithBlock (other),
+ branch_value (
+ other.branch_value->clone_expr ()), /*match_arms(other.match_arms),*/
+ inner_attrs (other.inner_attrs), locus (other.locus)
+ {
+ fprintf (stderr,
+ "copy constructor for matchexpr called - only match arm vector "
+ "copying after this\n");
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ match_arms.reserve (other.match_arms.size ());
+
+ fprintf (stderr, "match expr: successfully reserved size\n");
+
+ for (const auto &e : other.match_arms)
+ {
+ match_arms.push_back (e->clone_match_case ());
+ fprintf (stderr, "match expr: successfully pushed back a match case\n");
+ }
+
+ fprintf (stderr, "match expr: successfully pushed back all match cases\n");
+ }
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone due to unique_ptr
+ MatchExpr &operator= (MatchExpr const &other)
+ {
+ ExprWithBlock::operator= (other);
+ branch_value = other.branch_value->clone_expr ();
+ // match_arms = other.match_arms;
+ inner_attrs = other.inner_attrs;
+ // outer_attrs = other.outer_attrs;
+ locus = other.locus;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ match_arms.reserve (other.match_arms.size ());
+
+ for (const auto &e : other.match_arms)
+ {
+ match_arms.push_back (e->clone_match_case ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ MatchExpr (MatchExpr &&other) = default;
+ MatchExpr &operator= (MatchExpr &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MatchExpr *clone_expr_impl () const OVERRIDE
+ {
+ return new MatchExpr (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MatchExpr *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new MatchExpr (*this);
+ }
+};
+
+// Await expression AST node (pseudo-member variable access)
+class AwaitExpr : public ExprWithoutBlock
+{
+ ::std::unique_ptr<Expr> awaited_expr;
+
+ Location locus;
+
+public:
+ // TODO: ensure outer attributes are actually allowed
+ AwaitExpr (::std::unique_ptr<Expr> awaited_expr,
+ ::std::vector<Attribute> outer_attrs, Location locus)
+ : ExprWithoutBlock (::std::move (outer_attrs)),
+ awaited_expr (::std::move (awaited_expr)), locus (locus)
+ {}
+
+ // copy constructor with clone
+ AwaitExpr (AwaitExpr const &other)
+ : ExprWithoutBlock (other),
+ awaited_expr (other.awaited_expr->clone_expr ()), locus (other.locus)
+ {}
+
+ // destructor - define here if required
+
+ // overloaded assignment operator with clone
+ AwaitExpr &operator= (AwaitExpr const &other)
+ {
+ ExprWithoutBlock::operator= (other);
+ awaited_expr = other.awaited_expr->clone_expr ();
+ locus = other.locus;
+
+ return *this;
+ }
+
+ // move constructors
+ AwaitExpr (AwaitExpr &&other) = default;
+ AwaitExpr &operator= (AwaitExpr &&other) = default;
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual AwaitExpr *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new AwaitExpr (*this);
+ }
+};
+
+// Async block expression AST node (block expr that evaluates to a future)
+class AsyncBlockExpr : public ExprWithBlock
+{
+ // TODO: should this extend BlockExpr rather than be a composite of it?
+ bool has_move;
+ ::std::unique_ptr<BlockExpr> block_expr;
+
+ Location locus;
+
+public:
+ AsyncBlockExpr (::std::unique_ptr<BlockExpr> block_expr, bool has_move,
+ ::std::vector<Attribute> outer_attrs, Location locus)
+ : ExprWithBlock (::std::move (outer_attrs)), has_move (has_move),
+ block_expr (::std::move (block_expr)), locus (locus)
+ {}
+
+ // copy constructor with clone
+ AsyncBlockExpr (AsyncBlockExpr const &other)
+ : ExprWithBlock (other), has_move (other.has_move),
+ block_expr (other.block_expr->clone_block_expr ()), locus (other.locus)
+ {}
+
+ // destructor - define if required
+
+ // overloaded assignment operator to clone
+ AsyncBlockExpr &operator= (AsyncBlockExpr const &other)
+ {
+ ExprWithBlock::operator= (other);
+ has_move = other.has_move;
+ block_expr = other.block_expr->clone_block_expr ();
+ locus = other.locus;
+
+ return *this;
+ }
+
+ // move constructors
+ AsyncBlockExpr (AsyncBlockExpr &&other) = default;
+ AsyncBlockExpr &operator= (AsyncBlockExpr &&other) = default;
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual AsyncBlockExpr *clone_expr_with_block_impl () const OVERRIDE
+ {
+ return new AsyncBlockExpr (*this);
+ }
+};
+} // namespace AST
+} // namespace Rust
#endif
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index 727b195..fe5b5d8 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -4,584 +4,647 @@
#include "rust-ast.h"
namespace Rust {
- namespace AST {
- // Decls as definitions moved to rust-ast.h
- class MacroItem;
- class MacroInvocationSemi;
-
- enum MacroFragSpec {
- BLOCK,
- EXPR,
- IDENT,
- ITEM,
- LIFETIME,
- LITERAL,
- META,
- PAT,
- PATH,
- STMT,
- TT,
- TY,
- VIS,
- INVALID // not really a specifier, but used to mark invalid one passed in
- };
-
- inline MacroFragSpec get_frag_spec_from_str(::std::string str) {
- if (str == "block")
- return BLOCK;
- else if (str == "expr")
- return EXPR;
- else if (str == "ident")
- return IDENT;
- else if (str == "item")
- return ITEM;
- else if (str == "lifetime")
- return LIFETIME;
- else if (str == "literal")
- return LITERAL;
- else if (str == "meta")
- return META;
- else if (str == "pat")
- return PAT;
- else if (str == "path")
- return PATH;
- else if (str == "stmt")
- return STMT;
- else if (str == "tt")
- return TT;
- else if (str == "ty")
- return TY;
- else if (str == "vis")
- return VIS;
- else {
- // error_at("invalid string '%s' used as fragment specifier", str->c_str());
- return INVALID;
- }
- }
-
- // A macro match that has an identifier and fragment spec
- class MacroMatchFragment : public MacroMatch {
- Identifier ident;
- MacroFragSpec frag_spec;
-
- // TODO: should store location information?
-
- public:
- MacroMatchFragment(Identifier ident, MacroFragSpec frag_spec) :
- ident(::std::move(ident)), frag_spec(frag_spec) {}
-
- // Returns whether macro match fragment is in an error state.
- inline bool is_error() const {
- return frag_spec == INVALID;
- }
-
- // Creates an error state macro match fragment.
- static MacroMatchFragment create_error() {
- return MacroMatchFragment(::std::string(""), INVALID);
- }
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual MacroMatchFragment* clone_macro_match_impl() const OVERRIDE {
- return new MacroMatchFragment(*this);
- }
- };
-
- // A repetition macro match
- class MacroMatchRepetition : public MacroMatch {
- public:
- enum MacroRepOp { NONE, ASTERISK, PLUS, QUESTION_MARK };
-
- private:
- //::std::vector<MacroMatch> matches;
- ::std::vector< ::std::unique_ptr<MacroMatch> > matches;
- MacroRepOp op;
-
- // bool has_sep;
- typedef Token MacroRepSep;
- // any token except delimiters and repetition operators
- ::std::unique_ptr<MacroRepSep> sep;
-
- // TODO: should store location information?
-
- public:
- // Returns whether macro match repetition has separator token.
- inline bool has_sep() const {
- return sep != NULL;
- }
-
- MacroMatchRepetition(::std::vector< ::std::unique_ptr<MacroMatch> > matches,
- MacroRepOp op, ::std::unique_ptr<MacroRepSep> sep) :
- matches(::std::move(matches)),
- op(op), sep(::std::move(sep)) {}
-
- // Copy constructor with clone
- MacroMatchRepetition(MacroMatchRepetition const& other) :
- /*matches(other.matches),*/ op(other.op), sep(other.sep->clone_token()) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- matches.reserve(other.matches.size());
-
- for (const auto& e : other.matches) {
- matches.push_back(e->clone_macro_match());
- }
- }
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone
- MacroMatchRepetition& operator=(MacroMatchRepetition const& other) {
- // matches = other.matches; // TODO: this needs to clone somehow?
- op = other.op;
- sep = other.sep->clone_token();
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- matches.reserve(other.matches.size());
-
- for (const auto& e : other.matches) {
- matches.push_back(e->clone_macro_match());
- }
-
- return *this;
- }
-
- // move constructors
- MacroMatchRepetition(MacroMatchRepetition&& other) = default;
- MacroMatchRepetition& operator=(MacroMatchRepetition&& other) = default;
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual MacroMatchRepetition* clone_macro_match_impl() const OVERRIDE {
- return new MacroMatchRepetition(*this);
- }
- };
-
- // can't inline due to polymorphism
- class MacroMatcher : public MacroMatch {
- DelimType delim_type;
- //::std::vector<MacroMatch> matches;
- ::std::vector< ::std::unique_ptr<MacroMatch> > matches;
-
- // TODO: think of way to mark invalid that doesn't take up more space
- bool is_invalid;
-
- // TODO: should store location information?
-
- public:
- MacroMatcher(
- DelimType delim_type, ::std::vector< ::std::unique_ptr<MacroMatch> > matches) :
- delim_type(delim_type),
- matches(::std::move(matches)), is_invalid(false) {}
-
- // copy constructor with vector clone
- MacroMatcher(MacroMatcher const& other) : delim_type(other.delim_type) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- matches.reserve(other.matches.size());
-
- for (const auto& e : other.matches) {
- matches.push_back(e->clone_macro_match());
- }
- }
-
- // overloaded assignment operator with vector clone
- MacroMatcher& operator=(MacroMatcher const& other) {
- delim_type = other.delim_type;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- matches.reserve(other.matches.size());
-
- for (const auto& e : other.matches) {
- matches.push_back(e->clone_macro_match());
- }
-
- return *this;
- }
-
- // move constructors
- MacroMatcher(MacroMatcher&& other) = default;
- MacroMatcher& operator=(MacroMatcher&& other) = default;
-
- // Creates an error state macro matcher.
- static MacroMatcher create_error() {
- return MacroMatcher(true);
- }
-
- // Returns whether MacroMatcher is in an error state.
- inline bool is_error() const {
- return is_invalid;
- }
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual MacroMatcher* clone_macro_match_impl() const OVERRIDE {
- return new MacroMatcher(*this);
- }
-
- // constructor only used to create error matcher
- MacroMatcher(bool is_invalid) : delim_type(PARENS), is_invalid(is_invalid) {}
- };
-
- // TODO: inline?
- struct MacroTranscriber {
- private:
- DelimTokenTree token_tree;
-
- // TODO: should store location information?
-
- public:
- MacroTranscriber(DelimTokenTree token_tree) : token_tree(::std::move(token_tree)) {}
-
- ::std::string as_string() const {
- return token_tree.as_string();
- }
- };
-
- // A macro rule? Matcher and transcriber pair?
- struct MacroRule {
- private:
- MacroMatcher matcher;
- MacroTranscriber transcriber;
-
- // TODO: should store location information?
-
- public:
- MacroRule(MacroMatcher matcher, MacroTranscriber transcriber) :
- matcher(::std::move(matcher)), transcriber(::std::move(transcriber)) {}
-
- // Returns whether macro rule is in error state.
- inline bool is_error() const {
- return matcher.is_error();
- }
-
- // Creates an error state macro rule.
- static MacroRule create_error() {
- return MacroRule(
- MacroMatcher::create_error(), MacroTranscriber(DelimTokenTree::create_empty()));
- }
-
- ::std::string as_string() const;
- };
-
- // A macro rules definition item AST node
- class MacroRulesDefinition : public MacroItem {
- Identifier rule_name;
- // MacroRulesDef rules_def; // TODO: inline
- // only curly without required semicolon at end
- DelimType delim_type;
- // MacroRules rules;
- ::std::vector<MacroRule> rules; // inlined form
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- MacroRulesDefinition(Identifier rule_name, DelimType delim_type,
- ::std::vector<MacroRule> rules, ::std::vector<Attribute> outer_attrs, Location locus) :
- MacroItem(::std::move(outer_attrs)),
- rule_name(::std::move(rule_name)), delim_type(delim_type), rules(::std::move(rules)),
- locus(locus) {}
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual MacroRulesDefinition* clone_item_impl() const OVERRIDE {
- return new MacroRulesDefinition(*this);
- }
- };
-
- // AST node of a macro invocation, which is replaced by the macro result at compile time
- class MacroInvocation
- : public TypeNoBounds
- , public Pattern
- , public ExprWithoutBlock {
- SimplePath path;
- DelimTokenTree token_tree;
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- MacroInvocation(SimplePath path, DelimTokenTree token_tree,
- ::std::vector<Attribute> outer_attrs, Location locus) :
- ExprWithoutBlock(::std::move(outer_attrs)),
- path(::std::move(path)), token_tree(::std::move(token_tree)), locus(locus) {}
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual MacroInvocation* clone_pattern_impl() const OVERRIDE {
- return new MacroInvocation(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual MacroInvocation* clone_expr_impl() const OVERRIDE {
- return new MacroInvocation(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual MacroInvocation* clone_expr_without_block_impl() const OVERRIDE {
- return new MacroInvocation(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual MacroInvocation* clone_type_impl() const OVERRIDE {
- return new MacroInvocation(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual MacroInvocation* clone_type_no_bounds_impl() const OVERRIDE {
- return new MacroInvocation(*this);
- }
- };
-
- // more generic meta item path-only form
- class MetaItemPath : public MetaItem {
- SimplePath path;
-
- public:
- MetaItemPath(SimplePath path) : path(::std::move(path)) {}
-
- ::std::string as_string() const OVERRIDE {
- return path.as_string();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- // HACK: used to simplify parsing - returns non-empty only in this case
- virtual SimplePath to_path_item() const OVERRIDE {
- // this should copy construct - TODO ensure it does
- return path;
- }
-
- virtual bool check_cfg_predicate(const Session& session) const OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this type
- virtual MetaItemPath* clone_meta_item_inner_impl() const OVERRIDE {
- return new MetaItemPath(*this);
- }
- };
-
- // more generic meta item sequence form
- class MetaItemSeq : public MetaItem {
- SimplePath path;
- ::std::vector< ::std::unique_ptr<MetaItemInner> > seq;
-
- public:
- MetaItemSeq(SimplePath path, ::std::vector< ::std::unique_ptr<MetaItemInner> > seq) :
- path(::std::move(path)), seq(::std::move(seq)) {}
-
- // copy constructor with vector clone
- MetaItemSeq(const MetaItemSeq& other) : path(other.path) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- seq.reserve(other.seq.size());
-
- for (const auto& e : other.seq) {
- seq.push_back(e->clone_meta_item_inner());
- }
- }
-
- // destructor definition not required
-
- // overloaded assignment operator with vector clone
- MetaItemSeq& operator=(const MetaItemSeq& other) {
- MetaItem::operator=(other);
- path = other.path;
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- seq.reserve(other.seq.size());
-
- for (const auto& e : other.seq) {
- seq.push_back(e->clone_meta_item_inner());
- }
-
- return *this;
- }
-
- // default move constructors
- MetaItemSeq(MetaItemSeq&& other) = default;
- MetaItemSeq& operator=(MetaItemSeq&& other) = default;
-
- ::std::string as_string() const OVERRIDE;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- virtual bool check_cfg_predicate(const Session& session) const OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this type
- virtual MetaItemSeq* clone_meta_item_inner_impl() const OVERRIDE {
- return new MetaItemSeq(*this);
- }
- };
-
- // Preferred specialisation for single-identifier meta items.
- class MetaWord : public MetaItem {
- Identifier ident;
-
- public:
- MetaWord(Identifier ident) : ident(::std::move(ident)) {}
-
- ::std::string as_string() const OVERRIDE {
- return ident;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- virtual bool check_cfg_predicate(const Session& session) const OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this type
- virtual MetaWord* clone_meta_item_inner_impl() const OVERRIDE {
- return new MetaWord(*this);
- }
- };
-
- // Preferred specialisation for "identifier '=' string literal" meta items.
- class MetaNameValueStr : public MetaItem {
- Identifier ident;
- ::std::string str;
-
- public:
- MetaNameValueStr(Identifier ident, ::std::string str) :
- ident(::std::move(ident)), str(::std::move(str)) {}
-
- ::std::string as_string() const OVERRIDE {
- return ident + " = " + str;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- // HACK: used to simplify parsing - creates a copy of this
- virtual MetaNameValueStr* to_meta_name_value_str() const OVERRIDE {
- return clone_meta_item_inner_impl();
- }
-
- virtual bool check_cfg_predicate(const Session& session) const OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this type
- virtual MetaNameValueStr* clone_meta_item_inner_impl() const OVERRIDE {
- return new MetaNameValueStr(*this);
- }
- };
-
- // doubles up as MetaListIdents - determine via iterating through each path?
- // Preferred specialisation for "identifier '(' SimplePath, SimplePath, ... ')'"
- class MetaListPaths : public MetaItem {
- Identifier ident;
- ::std::vector<SimplePath> paths;
-
- public:
- MetaListPaths(Identifier ident, ::std::vector<SimplePath> paths) :
- ident(::std::move(ident)), paths(::std::move(paths)) {}
-
- ::std::string as_string() const OVERRIDE;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- virtual bool check_cfg_predicate(const Session& session) const OVERRIDE;
-
- private:
- bool check_path_exists_in_cfg(const Session& session, const SimplePath& path) const;
-
- protected:
- // Use covariance to implement clone function as returning this type
- virtual MetaListPaths* clone_meta_item_inner_impl() const OVERRIDE {
- return new MetaListPaths(*this);
- }
- };
-
- // Preferred specialisation for "identifier '(' MetaNameValueStr, ... ')'"
- class MetaListNameValueStr : public MetaItem {
- Identifier ident;
- ::std::vector<MetaNameValueStr> strs;
-
- public:
- MetaListNameValueStr(Identifier ident, ::std::vector<MetaNameValueStr> strs) :
- ident(::std::move(ident)), strs(::std::move(strs)) {}
-
- ::std::string as_string() const OVERRIDE;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- virtual bool check_cfg_predicate(const Session& session) const OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this type
- virtual MetaListNameValueStr* clone_meta_item_inner_impl() const OVERRIDE {
- return new MetaListNameValueStr(*this);
- }
- };
-
- // Object that parses macros from a token stream.
- struct MacroParser {
- private:
- ::std::vector< ::std::unique_ptr<Token> > token_stream;
- // probably have to make this mutable (mutable int stream_pos) otherwise const has to be
- // removed up to DelimTokenTree or further ok since this changing would have an effect on
- // the results of the methods run (i.e. not logically const), the parsing methods
- // shouldn't be const
- int stream_pos;
-
- public:
- MacroParser(
- ::std::vector< ::std::unique_ptr<Token> > token_stream, int stream_start_pos = 0) :
- token_stream(::std::move(token_stream)),
- stream_pos(stream_start_pos) {}
-
- ~MacroParser() = default;
-
- ::std::vector< ::std::unique_ptr<MetaItemInner> > parse_meta_item_seq();
-
- private:
- // Parses a MetaItemInner.
- ::std::unique_ptr<MetaItemInner> parse_meta_item_inner();
- // Returns whether token can end a meta item.
- bool is_end_meta_item_tok(TokenId id) const;
- // Parses a simple path.
- SimplePath parse_simple_path();
- // Parses a segment of a simple path (but not scope resolution operator).
- SimplePathSegment parse_simple_path_segment();
- // Parses a MetaItemLitExpr.
- ::std::unique_ptr<MetaItemLitExpr> parse_meta_item_lit();
- // Parses a literal.
- Literal parse_literal();
- // Parses a meta item that begins with a simple path.
- ::std::unique_ptr<MetaItem> parse_path_meta_item();
-
- // TODO: should this be const?
- ::std::unique_ptr<Token>& peek_token(int i = 0) {
- return token_stream[stream_pos + i];
- }
-
- void skip_token(int i = 0) {
- stream_pos += 1 + i;
- }
- };
+namespace AST {
+// Decls as definitions moved to rust-ast.h
+class MacroItem;
+class MacroInvocationSemi;
+
+enum MacroFragSpec
+{
+ BLOCK,
+ EXPR,
+ IDENT,
+ ITEM,
+ LIFETIME,
+ LITERAL,
+ META,
+ PAT,
+ PATH,
+ STMT,
+ TT,
+ TY,
+ VIS,
+ INVALID // not really a specifier, but used to mark invalid one passed in
+};
+
+inline MacroFragSpec
+get_frag_spec_from_str (::std::string str)
+{
+ if (str == "block")
+ return BLOCK;
+ else if (str == "expr")
+ return EXPR;
+ else if (str == "ident")
+ return IDENT;
+ else if (str == "item")
+ return ITEM;
+ else if (str == "lifetime")
+ return LIFETIME;
+ else if (str == "literal")
+ return LITERAL;
+ else if (str == "meta")
+ return META;
+ else if (str == "pat")
+ return PAT;
+ else if (str == "path")
+ return PATH;
+ else if (str == "stmt")
+ return STMT;
+ else if (str == "tt")
+ return TT;
+ else if (str == "ty")
+ return TY;
+ else if (str == "vis")
+ return VIS;
+ else
+ {
+ // error_at("invalid string '%s' used as fragment specifier",
+ // str->c_str());
+ return INVALID;
}
}
+// A macro match that has an identifier and fragment spec
+class MacroMatchFragment : public MacroMatch
+{
+ Identifier ident;
+ MacroFragSpec frag_spec;
+
+ // TODO: should store location information?
+
+public:
+ MacroMatchFragment (Identifier ident, MacroFragSpec frag_spec)
+ : ident (::std::move (ident)), frag_spec (frag_spec)
+ {}
+
+ // Returns whether macro match fragment is in an error state.
+ inline bool is_error () const { return frag_spec == INVALID; }
+
+ // Creates an error state macro match fragment.
+ static MacroMatchFragment create_error ()
+ {
+ return MacroMatchFragment (::std::string (""), INVALID);
+ }
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MacroMatchFragment *clone_macro_match_impl () const OVERRIDE
+ {
+ return new MacroMatchFragment (*this);
+ }
+};
+
+// A repetition macro match
+class MacroMatchRepetition : public MacroMatch
+{
+public:
+ enum MacroRepOp
+ {
+ NONE,
+ ASTERISK,
+ PLUS,
+ QUESTION_MARK
+ };
+
+private:
+ //::std::vector<MacroMatch> matches;
+ ::std::vector< ::std::unique_ptr<MacroMatch> > matches;
+ MacroRepOp op;
+
+ // bool has_sep;
+ typedef Token MacroRepSep;
+ // any token except delimiters and repetition operators
+ ::std::unique_ptr<MacroRepSep> sep;
+
+ // TODO: should store location information?
+
+public:
+ // Returns whether macro match repetition has separator token.
+ inline bool has_sep () const { return sep != NULL; }
+
+ MacroMatchRepetition (::std::vector< ::std::unique_ptr<MacroMatch> > matches,
+ MacroRepOp op, ::std::unique_ptr<MacroRepSep> sep)
+ : matches (::std::move (matches)), op (op), sep (::std::move (sep))
+ {}
+
+ // Copy constructor with clone
+ MacroMatchRepetition (MacroMatchRepetition const &other)
+ : /*matches(other.matches),*/ op (other.op), sep (other.sep->clone_token ())
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ matches.reserve (other.matches.size ());
+
+ for (const auto &e : other.matches)
+ {
+ matches.push_back (e->clone_macro_match ());
+ }
+ }
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone
+ MacroMatchRepetition &operator= (MacroMatchRepetition const &other)
+ {
+ // matches = other.matches; // TODO: this needs to clone somehow?
+ op = other.op;
+ sep = other.sep->clone_token ();
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ matches.reserve (other.matches.size ());
+
+ for (const auto &e : other.matches)
+ {
+ matches.push_back (e->clone_macro_match ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ MacroMatchRepetition (MacroMatchRepetition &&other) = default;
+ MacroMatchRepetition &operator= (MacroMatchRepetition &&other) = default;
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MacroMatchRepetition *clone_macro_match_impl () const OVERRIDE
+ {
+ return new MacroMatchRepetition (*this);
+ }
+};
+
+// can't inline due to polymorphism
+class MacroMatcher : public MacroMatch
+{
+ DelimType delim_type;
+ //::std::vector<MacroMatch> matches;
+ ::std::vector< ::std::unique_ptr<MacroMatch> > matches;
+
+ // TODO: think of way to mark invalid that doesn't take up more space
+ bool is_invalid;
+
+ // TODO: should store location information?
+
+public:
+ MacroMatcher (DelimType delim_type,
+ ::std::vector< ::std::unique_ptr<MacroMatch> > matches)
+ : delim_type (delim_type), matches (::std::move (matches)),
+ is_invalid (false)
+ {}
+
+ // copy constructor with vector clone
+ MacroMatcher (MacroMatcher const &other) : delim_type (other.delim_type)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ matches.reserve (other.matches.size ());
+
+ for (const auto &e : other.matches)
+ {
+ matches.push_back (e->clone_macro_match ());
+ }
+ }
+
+ // overloaded assignment operator with vector clone
+ MacroMatcher &operator= (MacroMatcher const &other)
+ {
+ delim_type = other.delim_type;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ matches.reserve (other.matches.size ());
+
+ for (const auto &e : other.matches)
+ {
+ matches.push_back (e->clone_macro_match ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ MacroMatcher (MacroMatcher &&other) = default;
+ MacroMatcher &operator= (MacroMatcher &&other) = default;
+
+ // Creates an error state macro matcher.
+ static MacroMatcher create_error () { return MacroMatcher (true); }
+
+ // Returns whether MacroMatcher is in an error state.
+ inline bool is_error () const { return is_invalid; }
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MacroMatcher *clone_macro_match_impl () const OVERRIDE
+ {
+ return new MacroMatcher (*this);
+ }
+
+ // constructor only used to create error matcher
+ MacroMatcher (bool is_invalid) : delim_type (PARENS), is_invalid (is_invalid)
+ {}
+};
+
+// TODO: inline?
+struct MacroTranscriber
+{
+private:
+ DelimTokenTree token_tree;
+
+ // TODO: should store location information?
+
+public:
+ MacroTranscriber (DelimTokenTree token_tree)
+ : token_tree (::std::move (token_tree))
+ {}
+
+ ::std::string as_string () const { return token_tree.as_string (); }
+};
+
+// A macro rule? Matcher and transcriber pair?
+struct MacroRule
+{
+private:
+ MacroMatcher matcher;
+ MacroTranscriber transcriber;
+
+ // TODO: should store location information?
+
+public:
+ MacroRule (MacroMatcher matcher, MacroTranscriber transcriber)
+ : matcher (::std::move (matcher)), transcriber (::std::move (transcriber))
+ {}
+
+ // Returns whether macro rule is in error state.
+ inline bool is_error () const { return matcher.is_error (); }
+
+ // Creates an error state macro rule.
+ static MacroRule create_error ()
+ {
+ return MacroRule (MacroMatcher::create_error (),
+ MacroTranscriber (DelimTokenTree::create_empty ()));
+ }
+
+ ::std::string as_string () const;
+};
+
+// A macro rules definition item AST node
+class MacroRulesDefinition : public MacroItem
+{
+ Identifier rule_name;
+ // MacroRulesDef rules_def; // TODO: inline
+ // only curly without required semicolon at end
+ DelimType delim_type;
+ // MacroRules rules;
+ ::std::vector<MacroRule> rules; // inlined form
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ MacroRulesDefinition (Identifier rule_name, DelimType delim_type,
+ ::std::vector<MacroRule> rules,
+ ::std::vector<Attribute> outer_attrs, Location locus)
+ : MacroItem (::std::move (outer_attrs)),
+ rule_name (::std::move (rule_name)), delim_type (delim_type),
+ rules (::std::move (rules)), locus (locus)
+ {}
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MacroRulesDefinition *clone_item_impl () const OVERRIDE
+ {
+ return new MacroRulesDefinition (*this);
+ }
+};
+
+// AST node of a macro invocation, which is replaced by the macro result at
+// compile time
+class MacroInvocation : public TypeNoBounds,
+ public Pattern,
+ public ExprWithoutBlock
+{
+ SimplePath path;
+ DelimTokenTree token_tree;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ MacroInvocation (SimplePath path, DelimTokenTree token_tree,
+ ::std::vector<Attribute> outer_attrs, Location locus)
+ : ExprWithoutBlock (::std::move (outer_attrs)), path (::std::move (path)),
+ token_tree (::std::move (token_tree)), locus (locus)
+ {}
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MacroInvocation *clone_pattern_impl () const OVERRIDE
+ {
+ return new MacroInvocation (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MacroInvocation *clone_expr_impl () const OVERRIDE
+ {
+ return new MacroInvocation (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MacroInvocation *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new MacroInvocation (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MacroInvocation *clone_type_impl () const OVERRIDE
+ {
+ return new MacroInvocation (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual MacroInvocation *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new MacroInvocation (*this);
+ }
+};
+
+// more generic meta item path-only form
+class MetaItemPath : public MetaItem
+{
+ SimplePath path;
+
+public:
+ MetaItemPath (SimplePath path) : path (::std::move (path)) {}
+
+ ::std::string as_string () const OVERRIDE { return path.as_string (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ // HACK: used to simplify parsing - returns non-empty only in this case
+ virtual SimplePath to_path_item () const OVERRIDE
+ {
+ // this should copy construct - TODO ensure it does
+ return path;
+ }
+
+ virtual bool check_cfg_predicate (const Session &session) const OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this type
+ virtual MetaItemPath *clone_meta_item_inner_impl () const OVERRIDE
+ {
+ return new MetaItemPath (*this);
+ }
+};
+
+// more generic meta item sequence form
+class MetaItemSeq : public MetaItem
+{
+ SimplePath path;
+ ::std::vector< ::std::unique_ptr<MetaItemInner> > seq;
+
+public:
+ MetaItemSeq (SimplePath path,
+ ::std::vector< ::std::unique_ptr<MetaItemInner> > seq)
+ : path (::std::move (path)), seq (::std::move (seq))
+ {}
+
+ // copy constructor with vector clone
+ MetaItemSeq (const MetaItemSeq &other) : path (other.path)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ seq.reserve (other.seq.size ());
+
+ for (const auto &e : other.seq)
+ {
+ seq.push_back (e->clone_meta_item_inner ());
+ }
+ }
+
+ // destructor definition not required
+
+ // overloaded assignment operator with vector clone
+ MetaItemSeq &operator= (const MetaItemSeq &other)
+ {
+ MetaItem::operator= (other);
+ path = other.path;
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ seq.reserve (other.seq.size ());
+
+ for (const auto &e : other.seq)
+ {
+ seq.push_back (e->clone_meta_item_inner ());
+ }
+
+ return *this;
+ }
+
+ // default move constructors
+ MetaItemSeq (MetaItemSeq &&other) = default;
+ MetaItemSeq &operator= (MetaItemSeq &&other) = default;
+
+ ::std::string as_string () const OVERRIDE;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ virtual bool check_cfg_predicate (const Session &session) const OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this type
+ virtual MetaItemSeq *clone_meta_item_inner_impl () const OVERRIDE
+ {
+ return new MetaItemSeq (*this);
+ }
+};
+
+// Preferred specialisation for single-identifier meta items.
+class MetaWord : public MetaItem
+{
+ Identifier ident;
+
+public:
+ MetaWord (Identifier ident) : ident (::std::move (ident)) {}
+
+ ::std::string as_string () const OVERRIDE { return ident; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ virtual bool check_cfg_predicate (const Session &session) const OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this type
+ virtual MetaWord *clone_meta_item_inner_impl () const OVERRIDE
+ {
+ return new MetaWord (*this);
+ }
+};
+
+// Preferred specialisation for "identifier '=' string literal" meta items.
+class MetaNameValueStr : public MetaItem
+{
+ Identifier ident;
+ ::std::string str;
+
+public:
+ MetaNameValueStr (Identifier ident, ::std::string str)
+ : ident (::std::move (ident)), str (::std::move (str))
+ {}
+
+ ::std::string as_string () const OVERRIDE { return ident + " = " + str; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ // HACK: used to simplify parsing - creates a copy of this
+ virtual MetaNameValueStr *to_meta_name_value_str () const OVERRIDE
+ {
+ return clone_meta_item_inner_impl ();
+ }
+
+ virtual bool check_cfg_predicate (const Session &session) const OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this type
+ virtual MetaNameValueStr *clone_meta_item_inner_impl () const OVERRIDE
+ {
+ return new MetaNameValueStr (*this);
+ }
+};
+
+// doubles up as MetaListIdents - determine via iterating through each path?
+// Preferred specialisation for "identifier '(' SimplePath, SimplePath, ... ')'"
+class MetaListPaths : public MetaItem
+{
+ Identifier ident;
+ ::std::vector<SimplePath> paths;
+
+public:
+ MetaListPaths (Identifier ident, ::std::vector<SimplePath> paths)
+ : ident (::std::move (ident)), paths (::std::move (paths))
+ {}
+
+ ::std::string as_string () const OVERRIDE;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ virtual bool check_cfg_predicate (const Session &session) const OVERRIDE;
+
+private:
+ bool check_path_exists_in_cfg (const Session &session,
+ const SimplePath &path) const;
+
+protected:
+ // Use covariance to implement clone function as returning this type
+ virtual MetaListPaths *clone_meta_item_inner_impl () const OVERRIDE
+ {
+ return new MetaListPaths (*this);
+ }
+};
+
+// Preferred specialisation for "identifier '(' MetaNameValueStr, ... ')'"
+class MetaListNameValueStr : public MetaItem
+{
+ Identifier ident;
+ ::std::vector<MetaNameValueStr> strs;
+
+public:
+ MetaListNameValueStr (Identifier ident, ::std::vector<MetaNameValueStr> strs)
+ : ident (::std::move (ident)), strs (::std::move (strs))
+ {}
+
+ ::std::string as_string () const OVERRIDE;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ virtual bool check_cfg_predicate (const Session &session) const OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this type
+ virtual MetaListNameValueStr *clone_meta_item_inner_impl () const OVERRIDE
+ {
+ return new MetaListNameValueStr (*this);
+ }
+};
+
+// Object that parses macros from a token stream.
+struct MacroParser
+{
+private:
+ ::std::vector< ::std::unique_ptr<Token> > token_stream;
+ // probably have to make this mutable (mutable int stream_pos) otherwise const
+ // has to be removed up to DelimTokenTree or further ok since this changing
+ // would have an effect on the results of the methods run (i.e. not logically
+ // const), the parsing methods shouldn't be const
+ int stream_pos;
+
+public:
+ MacroParser (::std::vector< ::std::unique_ptr<Token> > token_stream,
+ int stream_start_pos = 0)
+ : token_stream (::std::move (token_stream)), stream_pos (stream_start_pos)
+ {}
+
+ ~MacroParser () = default;
+
+ ::std::vector< ::std::unique_ptr<MetaItemInner> > parse_meta_item_seq ();
+
+private:
+ // Parses a MetaItemInner.
+ ::std::unique_ptr<MetaItemInner> parse_meta_item_inner ();
+ // Returns whether token can end a meta item.
+ bool is_end_meta_item_tok (TokenId id) const;
+ // Parses a simple path.
+ SimplePath parse_simple_path ();
+ // Parses a segment of a simple path (but not scope resolution operator).
+ SimplePathSegment parse_simple_path_segment ();
+ // Parses a MetaItemLitExpr.
+ ::std::unique_ptr<MetaItemLitExpr> parse_meta_item_lit ();
+ // Parses a literal.
+ Literal parse_literal ();
+ // Parses a meta item that begins with a simple path.
+ ::std::unique_ptr<MetaItem> parse_path_meta_item ();
+
+ // TODO: should this be const?
+ ::std::unique_ptr<Token> &peek_token (int i = 0)
+ {
+ return token_stream[stream_pos + i];
+ }
+
+ void skip_token (int i = 0) { stream_pos += 1 + i; }
+};
+} // namespace AST
+} // namespace Rust
+
#endif
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 6845603f..434ed62 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -1,7 +1,7 @@
#ifndef RUST_AST_PATH_H
#define RUST_AST_PATH_H
-/* "Path" (identifier within namespaces, essentially) handling. Required include for virtually all
- * AST-related functionality. */
+/* "Path" (identifier within namespaces, essentially) handling. Required include
+ * for virtually all AST-related functionality. */
#include "rust-ast.h"
@@ -9,795 +9,872 @@
#include <vector>
namespace Rust {
- namespace AST {
- // make intellisense calm
- /*typedef ::std::string Symbol;
- typedef int Lifetime;
- typedef int Type;
- typedef int Binding;*/
-
- // The "identifier" (not generic args) aspect of each path expression segment
- class PathIdentSegment {
- ::std::string segment_name;
-
- // TODO: should this have location info stored?
-
- // only allow identifiers, "super", "self", "Self", "crate", or "$crate"
- public:
- PathIdentSegment(::std::string segment_name) : segment_name(::std::move(segment_name)) {}
-
- /* TODO: insert check in constructor for this? Or is this a semantic error best handled
- * then? */
-
- // TODO: does this require visitor. pretty sure this isn't polymorphic, but not entirely
- // sure
-
- // Creates an error PathIdentSegment.
- static PathIdentSegment create_error() {
- return PathIdentSegment("");
- }
-
- // Returns whether PathIdentSegment is in an error state.
- inline bool is_error() const {
- return segment_name.empty();
- }
-
- ::std::string as_string() const {
- return segment_name;
- }
- };
-
- // A binding of an identifier to a type used in generic arguments in paths
- struct GenericArgsBinding {
- private:
- Identifier identifier;
- // Type type;
- ::std::unique_ptr<Type> type;
-
- Location locus;
-
- public:
- // Returns whether binding is in an error state.
- inline bool is_error() const {
- return type == NULL; // and also identifier is empty, but cheaper computation
- }
-
- // Creates an error state generic args binding.
- static GenericArgsBinding create_error() {
- return GenericArgsBinding("", NULL);
- }
-
- // Pointer type for type in constructor to enable polymorphism
- GenericArgsBinding(
- Identifier ident, ::std::unique_ptr<Type> type_ptr, Location locus = Location()) :
- identifier(::std::move(ident)),
- type(::std::move(type_ptr)), locus(locus) {}
-
- // Copy constructor has to deep copy the type as it is a unique pointer
- GenericArgsBinding(GenericArgsBinding const& other) :
- identifier(other.identifier), type(other.type->clone_type()), locus(other.locus) {}
-
- // default destructor
- ~GenericArgsBinding() = default;
-
- // Overload assignment operator to deep copy the pointed-to type
- GenericArgsBinding& operator=(GenericArgsBinding const& other) {
- identifier = other.identifier;
- type = other.type->clone_type();
- locus = other.locus;
- return *this;
- }
-
- // move constructors
- GenericArgsBinding(GenericArgsBinding&& other) = default;
- GenericArgsBinding& operator=(GenericArgsBinding&& other) = default;
-
- ::std::string as_string() const;
- };
-
- // Generic arguments allowed in each path expression segment - inline?
- struct GenericArgs {
- ::std::vector<Lifetime> lifetime_args;
- //::std::vector<Type> type_args;
- ::std::vector< ::std::unique_ptr<Type> > type_args;
- ::std::vector<GenericArgsBinding> binding_args;
-
- Location locus;
-
- public:
- // Returns true if there are any generic arguments
- inline bool has_generic_args() const {
- return !(lifetime_args.empty() && type_args.empty() && binding_args.empty());
- }
-
- GenericArgs(::std::vector<Lifetime> lifetime_args,
- ::std::vector< ::std::unique_ptr<Type> > type_args,
- ::std::vector<GenericArgsBinding> binding_args, Location locus = Location()) :
- lifetime_args(::std::move(lifetime_args)),
- type_args(::std::move(type_args)), binding_args(::std::move(binding_args)),
- locus(locus) {}
-
- // copy constructor with vector clone
- GenericArgs(GenericArgs const& other) :
- lifetime_args(other.lifetime_args), binding_args(other.binding_args),
- locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- type_args.reserve(other.type_args.size());
-
- for (const auto& e : other.type_args) {
- type_args.push_back(e->clone_type());
- }
- }
-
- ~GenericArgs() = default;
-
- // overloaded assignment operator to vector clone
- GenericArgs& operator=(GenericArgs const& other) {
- lifetime_args = other.lifetime_args;
- binding_args = other.binding_args;
- locus = other.locus;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- type_args.reserve(other.type_args.size());
-
- for (const auto& e : other.type_args) {
- type_args.push_back(e->clone_type());
- }
-
- return *this;
- }
-
- // move constructors
- GenericArgs(GenericArgs&& other) = default;
- GenericArgs& operator=(GenericArgs&& other) = default;
-
- // Creates an empty GenericArgs (no arguments)
- static GenericArgs create_empty() {
- return GenericArgs(::std::vector<Lifetime>(),
- ::std::vector< ::std::unique_ptr<Type> >(), ::std::vector<GenericArgsBinding>());
- }
-
- ::std::string as_string() const;
- };
-
- // A segment of a path in expression, including an identifier aspect and maybe generic args
- class PathExprSegment { // or should this extend PathIdentSegment?
- private:
- PathIdentSegment segment_name;
-
- // bool has_generic_args;
- GenericArgs generic_args;
-
- Location locus;
-
- // TODO: does this require visitor? pretty sure not polymorphic
-
- public:
- // Returns true if there are any generic arguments
- inline bool has_generic_args() const {
- return generic_args.has_generic_args();
- }
-
- // Constructor for segment (from IdentSegment and GenericArgs)
- PathExprSegment(PathIdentSegment segment_name, Location locus = Location(),
- GenericArgs generic_args = GenericArgs::create_empty()) :
- segment_name(::std::move(segment_name)),
- generic_args(::std::move(generic_args)), locus(locus) {}
-
- // Constructor for segment with generic arguments (from segment name and all args)
- PathExprSegment(::std::string segment_name, Location locus,
- ::std::vector<Lifetime> lifetime_args = ::std::vector<Lifetime>(),
- ::std::vector< ::std::unique_ptr<Type> > type_args
- = ::std::vector< ::std::unique_ptr<Type> >(),
- ::std::vector<GenericArgsBinding> binding_args = ::std::vector<GenericArgsBinding>()) :
- segment_name(PathIdentSegment(::std::move(segment_name))),
- generic_args(GenericArgs(
- ::std::move(lifetime_args), ::std::move(type_args), ::std::move(binding_args))),
- locus(locus) {}
-
- // Returns whether path expression segment is in an error state.
- inline bool is_error() const {
- return segment_name.is_error();
- }
-
- // Creates an error-state path expression segment.
- static PathExprSegment create_error() {
- return PathExprSegment(PathIdentSegment::create_error());
- }
-
- ::std::string as_string() const;
-
- inline Location get_locus() const {
- return locus;
- }
- };
-
- // AST node representing a pattern that involves a "path" - abstract base class
- class PathPattern : public Pattern {
- ::std::vector<PathExprSegment> segments;
-
- protected:
- PathPattern(::std::vector<PathExprSegment> segments) : segments(::std::move(segments)) {}
-
- // Returns whether path has segments.
- inline bool has_segments() const {
- return !segments.empty();
- }
-
- /* Converts path segments to their equivalent SimplePath segments if possible, and creates
- * a SimplePath from them. */
- SimplePath convert_to_simple_path(bool with_opening_scope_resolution) const;
-
- public:
- /* Returns whether the path is a single segment (excluding qualified path initial as
- * segment). */
- inline bool is_single_segment() const {
- return segments.size() == 1;
- }
-
- virtual ::std::string as_string() const;
- };
-
- // AST node representing a path-in-expression pattern (path that allows generic arguments)
- class PathInExpression
- : public PathPattern
- , public PathExpr {
- bool has_opening_scope_resolution;
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- // Constructor
- PathInExpression(::std::vector<PathExprSegment> path_segments,
- Location locus = Location(), bool has_opening_scope_resolution = false,
- ::std::vector<Attribute> outer_attrs = ::std::vector<Attribute>()) :
- PathPattern(::std::move(path_segments)),
- PathExpr(::std::move(outer_attrs)),
- has_opening_scope_resolution(has_opening_scope_resolution), locus(locus) {}
-
- // Creates an error state path in expression.
- static PathInExpression create_error() {
- return PathInExpression(::std::vector<PathExprSegment>());
- }
-
- // Returns whether path in expression is in an error state.
- inline bool is_error() const {
- return !has_segments();
- }
-
- /* Converts PathInExpression to SimplePath if possible (i.e. no generic arguments).
- * Otherwise returns an empty SimplePath. */
- inline SimplePath as_simple_path() const {
- /* delegate to parent class as can't access segments. however,
- * QualifiedPathInExpression conversion to simple path wouldn't make sense, so the
- * method in the parent class should be protected, not public.
- * Have to pass in opening scope resolution as parent class has no access to it. */
- return convert_to_simple_path(has_opening_scope_resolution);
- }
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual PathInExpression* clone_pattern_impl() const OVERRIDE {
- return new PathInExpression(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual PathInExpression* clone_expr_without_block_impl() const OVERRIDE {
- return new PathInExpression(*this);
- }
- };
-
- // Base class for segments used in type paths - not abstract (represents an ident-only
- // segment)
- class TypePathSegment {
- /* TODO: may have to unify TypePathSegment and PathExprSegment (which are mostly the
- * same anyway) in order to resolve goddamn syntax ambiguities.
- * One difference is that function on TypePathSegment is not allowed if GenericArgs are,
- * so could disallow that in constructor, which won't give that much size overhead. */
- PathIdentSegment ident_segment;
-
- Location locus;
-
- protected:
- // This is protected because it is only really used by derived classes, not the base.
- bool has_separating_scope_resolution;
-
- // Clone function implementation - not pure virtual as overrided by subclasses
- virtual TypePathSegment* clone_type_path_segment_impl() const {
- return new TypePathSegment(*this);
- }
-
- public:
- virtual ~TypePathSegment() {}
-
- // Unique pointer custom clone function
- ::std::unique_ptr<TypePathSegment> clone_type_path_segment() const {
- return ::std::unique_ptr<TypePathSegment>(clone_type_path_segment_impl());
- }
-
- TypePathSegment(
- PathIdentSegment ident_segment, bool has_separating_scope_resolution, Location locus) :
- ident_segment(::std::move(ident_segment)),
- locus(locus), has_separating_scope_resolution(has_separating_scope_resolution) {}
-
- TypePathSegment(
- ::std::string segment_name, bool has_separating_scope_resolution, Location locus) :
- ident_segment(PathIdentSegment(::std::move(segment_name))),
- locus(locus), has_separating_scope_resolution(has_separating_scope_resolution) {}
-
- virtual ::std::string as_string() const {
- return ident_segment.as_string();
- }
-
- // Returns whether the type path segment is in an error state. May be virtual in future.
- inline bool is_error() const {
- return ident_segment.is_error();
- }
-
- /* Returns whether segment is identifier only (as opposed to generic args or function).
- Overriden in derived classes with other segments. */
- virtual bool is_ident_only() const {
- return true;
- }
-
- inline Location get_locus() const {
- return locus;
- }
-
- // not pure virtual as class not abstract
- virtual void accept_vis(ASTVisitor& vis);
- };
-
- // Segment used in type path with generic args
- class TypePathSegmentGeneric : public TypePathSegment {
- GenericArgs generic_args;
-
- public:
- inline bool has_generic_args() const {
- return generic_args.has_generic_args();
- }
-
- bool is_ident_only() const {
- return false;
- }
-
- // Constructor with PathIdentSegment and GenericArgs
- TypePathSegmentGeneric(PathIdentSegment ident_segment,
- bool has_separating_scope_resolution, GenericArgs generic_args, Location locus) :
- TypePathSegment(::std::move(ident_segment), has_separating_scope_resolution, locus),
- generic_args(::std::move(generic_args)) {}
-
- // Constructor from segment name and all args
- TypePathSegmentGeneric(::std::string segment_name, bool has_separating_scope_resolution,
- ::std::vector<Lifetime> lifetime_args,
- ::std::vector< ::std::unique_ptr<Type> > type_args,
- ::std::vector<GenericArgsBinding> binding_args, Location locus) :
- TypePathSegment(::std::move(segment_name), has_separating_scope_resolution, locus),
- generic_args(GenericArgs(
- ::std::move(lifetime_args), ::std::move(type_args), ::std::move(binding_args))) {}
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to override base class method
- virtual TypePathSegmentGeneric* clone_type_path_segment_impl() const OVERRIDE {
- return new TypePathSegmentGeneric(*this);
- }
- };
-
- // A function as represented in a type path
- struct TypePathFunction {
- private:
- // TODO: remove
- /*bool has_inputs;
- TypePathFnInputs inputs;*/
- //::std::vector<Type> inputs; // inlined from TypePathFnInputs
- ::std::vector< ::std::unique_ptr<Type> > inputs;
-
- // bool has_type;
- // Type type;
- ::std::unique_ptr<Type> return_type;
-
- // FIXME: think of better way to mark as invalid than taking up storage
- bool is_invalid;
-
- // TODO: should this have location info?
-
- protected:
- // Constructor only used to create invalid type path functions.
- TypePathFunction(bool is_invalid) : is_invalid(is_invalid) {}
-
- public:
- // Returns whether the return type of the function has been specified.
- inline bool has_return_type() const {
- return return_type != NULL;
- }
-
- // Returns whether the function has inputs.
- inline bool has_inputs() const {
- return !inputs.empty();
- }
-
- // Returns whether function is in an error state.
- inline bool is_error() const {
- return is_invalid;
- }
-
- // Creates an error state function.
- static TypePathFunction create_error() {
- return TypePathFunction(true);
- }
-
- // Constructor
- TypePathFunction(::std::vector< ::std::unique_ptr<Type> > inputs, Type* type = NULL) :
- inputs(::std::move(inputs)), return_type(type), is_invalid(false) {}
- // FIXME: deprecated
-
- // Constructor
- TypePathFunction(
- ::std::vector< ::std::unique_ptr<Type> > inputs, ::std::unique_ptr<Type> type = NULL) :
- inputs(::std::move(inputs)),
- return_type(::std::move(type)), is_invalid(false) {}
-
- // Copy constructor with clone
- TypePathFunction(TypePathFunction const& other) :
- /*inputs(other.inputs),*/ return_type(other.return_type->clone_type()),
- is_invalid(other.is_invalid) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- inputs.reserve(other.inputs.size());
-
- for (const auto& e : other.inputs) {
- inputs.push_back(e->clone_type());
- }
- }
-
- ~TypePathFunction() = default;
-
- // Overloaded assignment operator to clone type
- TypePathFunction& operator=(TypePathFunction const& other) {
- // inputs = other.inputs;
- return_type = other.return_type->clone_type();
- is_invalid = other.is_invalid;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- inputs.reserve(other.inputs.size());
-
- for (const auto& e : other.inputs) {
- inputs.push_back(e->clone_type());
- }
-
- return *this;
- }
-
- // move constructors
- TypePathFunction(TypePathFunction&& other) = default;
- TypePathFunction& operator=(TypePathFunction&& other) = default;
-
- ::std::string as_string() const;
- };
-
- // Segment used in type path with a function argument
- class TypePathSegmentFunction : public TypePathSegment {
- TypePathFunction function_path;
-
- public:
- // Constructor with PathIdentSegment and TypePathFn
- TypePathSegmentFunction(PathIdentSegment ident_segment,
- bool has_separating_scope_resolution, TypePathFunction function_path, Location locus) :
- TypePathSegment(::std::move(ident_segment), has_separating_scope_resolution, locus),
- function_path(::std::move(function_path)) {}
-
- // Constructor with segment name and TypePathFn
- TypePathSegmentFunction(::std::string segment_name, bool has_separating_scope_resolution,
- TypePathFunction function_path, Location locus) :
- TypePathSegment(::std::move(segment_name), has_separating_scope_resolution, locus),
- function_path(::std::move(function_path)) {}
-
- ::std::string as_string() const;
-
- bool is_ident_only() const {
- return false;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to override base class method
- virtual TypePathSegmentFunction* clone_type_path_segment_impl() const OVERRIDE {
- return new TypePathSegmentFunction(*this);
- }
- };
-
- // Path used inside types
- class TypePath : public TypeNoBounds {
- bool has_opening_scope_resolution;
- ::std::vector< ::std::unique_ptr<TypePathSegment> > segments;
-
- Location locus;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TypePath* clone_type_impl() const OVERRIDE {
- return new TypePath(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual TypePath* clone_type_no_bounds_impl() const OVERRIDE {
- return new TypePath(*this);
- }
-
- public:
- /* Returns whether the TypePath has an opening scope resolution operator (i.e. is global
- * path or crate-relative path, not module-relative) */
- inline bool has_opening_scope_resolution_op() const {
- return has_opening_scope_resolution;
- }
-
- // Returns whether the TypePath is in an invalid state.
- inline bool is_error() const {
- return segments.empty();
- }
-
- // Creates an error state TypePath.
- static TypePath create_error() {
- return TypePath(::std::vector< ::std::unique_ptr<TypePathSegment> >(), Location());
- }
-
- // Constructor
- TypePath(::std::vector< ::std::unique_ptr<TypePathSegment> > segments, Location locus,
- bool has_opening_scope_resolution = false) :
- has_opening_scope_resolution(has_opening_scope_resolution),
- segments(::std::move(segments)), locus(locus) {}
-
- // Copy constructor with vector clone
- TypePath(TypePath const& other) :
- has_opening_scope_resolution(other.has_opening_scope_resolution), locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- segments.reserve(other.segments.size());
-
- for (const auto& e : other.segments) {
- segments.push_back(e->clone_type_path_segment());
- }
- }
-
- // Overloaded assignment operator with clone
- TypePath& operator=(TypePath const& other) {
- has_opening_scope_resolution = other.has_opening_scope_resolution;
- locus = other.locus;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- segments.reserve(other.segments.size());
-
- for (const auto& e : other.segments) {
- segments.push_back(e->clone_type_path_segment());
- }
-
- return *this;
- }
-
- // move constructors
- TypePath(TypePath&& other) = default;
- TypePath& operator=(TypePath&& other) = default;
-
- ::std::string as_string() const;
-
- /* Converts TypePath to SimplePath if possible (i.e. no generic or function arguments).
- * Otherwise returns an empty SimplePath. */
- SimplePath as_simple_path() const;
-
- // Creates a trait bound with a clone of this type path as its only element.
- virtual TraitBound* to_trait_bound(bool in_parens) const OVERRIDE;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
- };
-
- struct QualifiedPathType {
- private:
- // Type type_to_invoke_on;
- ::std::unique_ptr<Type> type_to_invoke_on;
-
- // bool has_as_clause;
- TypePath trait_path;
-
- Location locus;
-
- public:
- // Constructor
- QualifiedPathType(::std::unique_ptr<Type> invoke_on_type, Location locus = Location(),
- TypePath trait_path = TypePath::create_error()) :
- type_to_invoke_on(::std::move(invoke_on_type)),
- trait_path(::std::move(trait_path)), locus(locus) {}
-
- // Copy constructor uses custom deep copy for Type to preserve polymorphism
- QualifiedPathType(QualifiedPathType const& other) :
- type_to_invoke_on(other.type_to_invoke_on->clone_type()), trait_path(other.trait_path),
- locus(other.locus) {}
-
- // default destructor
- ~QualifiedPathType() = default;
-
- // overload assignment operator to use custom clone method
- QualifiedPathType& operator=(QualifiedPathType const& other) {
- type_to_invoke_on = other.type_to_invoke_on->clone_type();
- trait_path = other.trait_path;
- locus = other.locus;
- return *this;
- }
-
- // move constructor
- QualifiedPathType(QualifiedPathType&& other) = default;
- QualifiedPathType& operator=(QualifiedPathType&& other) = default;
-
- // Returns whether the qualified path type has a rebind as clause.
- inline bool has_as_clause() const {
- return !trait_path.is_error();
- }
-
- // Returns whether the qualified path type is in an error state.
- inline bool is_error() const {
- return type_to_invoke_on == NULL;
- }
-
- // Creates an error state qualified path type.
- static QualifiedPathType create_error() {
- return QualifiedPathType(NULL);
- }
-
- ::std::string as_string() const;
-
- inline Location get_locus() const {
- return locus;
- }
- };
-
- /* AST node representing a qualified path-in-expression pattern (path that allows specifying
- * trait functions) */
- class QualifiedPathInExpression
- : public PathPattern
- , public PathExpr {
- QualifiedPathType path_type;
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- QualifiedPathInExpression(QualifiedPathType qual_path_type,
- ::std::vector<PathExprSegment> path_segments, Location locus = Location(),
- ::std::vector<Attribute> outer_attrs = ::std::vector<Attribute>()) :
- PathPattern(::std::move(path_segments)),
- PathExpr(::std::move(outer_attrs)), path_type(::std::move(qual_path_type)),
- locus(locus) {}
-
- // TODO: maybe make a shortcut constructor that has QualifiedPathType elements as params
-
- // Copy constructor, destructor, and assignment operator overload shouldn't be required
-
- // Returns whether qualified path in expression is in an error state.
- inline bool is_error() const {
- return path_type.is_error();
- }
-
- // Creates an error qualified path in expression.
- static QualifiedPathInExpression create_error() {
- return QualifiedPathInExpression(
- QualifiedPathType::create_error(), ::std::vector<PathExprSegment>());
- }
-
- Location get_locus() const {
- return locus;
- }
-
- Location get_locus_slow() const OVERRIDE {
- return get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual QualifiedPathInExpression* clone_pattern_impl() const OVERRIDE {
- return new QualifiedPathInExpression(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual QualifiedPathInExpression* clone_expr_without_block_impl() const OVERRIDE {
- return new QualifiedPathInExpression(*this);
- }
- };
-
- // Represents a qualified path in a type; used for disambiguating trait function calls
- class QualifiedPathInType : public TypeNoBounds {
- QualifiedPathType path_type;
- // ::std::vector<TypePathSegment> segments;
- ::std::vector< ::std::unique_ptr<TypePathSegment> > segments;
-
- Location locus;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual QualifiedPathInType* clone_type_impl() const OVERRIDE {
- return new QualifiedPathInType(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual QualifiedPathInType* clone_type_no_bounds_impl() const OVERRIDE {
- return new QualifiedPathInType(*this);
- }
-
- public:
- QualifiedPathInType(QualifiedPathType qual_path_type,
- ::std::vector< ::std::unique_ptr<TypePathSegment> > path_segments,
- Location locus = Location()) :
- path_type(::std::move(qual_path_type)),
- segments(::std::move(path_segments)), locus(locus) {}
-
- // TODO: maybe make a shortcut constructor that has QualifiedPathType elements as params
-
- // Copy constructor with vector clone
- QualifiedPathInType(QualifiedPathInType const& other) :
- path_type(other.path_type), locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- segments.reserve(other.segments.size());
-
- for (const auto& e : other.segments) {
- segments.push_back(e->clone_type_path_segment());
- }
- }
-
- // Overloaded assignment operator with vector clone
- QualifiedPathInType& operator=(QualifiedPathInType const& other) {
- path_type = other.path_type;
- locus = other.locus;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- segments.reserve(other.segments.size());
-
- for (const auto& e : other.segments) {
- segments.push_back(e->clone_type_path_segment());
- }
-
- return *this;
- }
-
- // move constructors
- QualifiedPathInType(QualifiedPathInType&& other) = default;
- QualifiedPathInType& operator=(QualifiedPathInType&& other) = default;
-
- // Returns whether qualified path in type is in an error state.
- inline bool is_error() const {
- return path_type.is_error();
- }
-
- // Creates an error state qualified path in type.
- static QualifiedPathInType create_error() {
- return QualifiedPathInType(QualifiedPathType::create_error(),
- ::std::vector< ::std::unique_ptr<TypePathSegment> >());
- }
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
- };
- }
-}
+namespace AST {
+// make intellisense calm
+/*typedef ::std::string Symbol;
+typedef int Lifetime;
+typedef int Type;
+typedef int Binding;*/
+
+// The "identifier" (not generic args) aspect of each path expression segment
+class PathIdentSegment
+{
+ ::std::string segment_name;
+
+ // TODO: should this have location info stored?
+
+ // only allow identifiers, "super", "self", "Self", "crate", or "$crate"
+public:
+ PathIdentSegment (::std::string segment_name)
+ : segment_name (::std::move (segment_name))
+ {}
+
+ /* TODO: insert check in constructor for this? Or is this a semantic error
+ * best handled then? */
+
+ // TODO: does this require visitor. pretty sure this isn't polymorphic, but
+ // not entirely sure
+
+ // Creates an error PathIdentSegment.
+ static PathIdentSegment create_error () { return PathIdentSegment (""); }
+
+ // Returns whether PathIdentSegment is in an error state.
+ inline bool is_error () const { return segment_name.empty (); }
+
+ ::std::string as_string () const { return segment_name; }
+};
+
+// A binding of an identifier to a type used in generic arguments in paths
+struct GenericArgsBinding
+{
+private:
+ Identifier identifier;
+ // Type type;
+ ::std::unique_ptr<Type> type;
+
+ Location locus;
+
+public:
+ // Returns whether binding is in an error state.
+ inline bool is_error () const
+ {
+ return type
+ == NULL; // and also identifier is empty, but cheaper computation
+ }
+
+ // Creates an error state generic args binding.
+ static GenericArgsBinding create_error ()
+ {
+ return GenericArgsBinding ("", NULL);
+ }
+
+ // Pointer type for type in constructor to enable polymorphism
+ GenericArgsBinding (Identifier ident, ::std::unique_ptr<Type> type_ptr,
+ Location locus = Location ())
+ : identifier (::std::move (ident)), type (::std::move (type_ptr)),
+ locus (locus)
+ {}
+
+ // Copy constructor has to deep copy the type as it is a unique pointer
+ GenericArgsBinding (GenericArgsBinding const &other)
+ : identifier (other.identifier), type (other.type->clone_type ()),
+ locus (other.locus)
+ {}
+
+ // default destructor
+ ~GenericArgsBinding () = default;
+
+ // Overload assignment operator to deep copy the pointed-to type
+ GenericArgsBinding &operator= (GenericArgsBinding const &other)
+ {
+ identifier = other.identifier;
+ type = other.type->clone_type ();
+ locus = other.locus;
+ return *this;
+ }
+
+ // move constructors
+ GenericArgsBinding (GenericArgsBinding &&other) = default;
+ GenericArgsBinding &operator= (GenericArgsBinding &&other) = default;
+
+ ::std::string as_string () const;
+};
+
+// Generic arguments allowed in each path expression segment - inline?
+struct GenericArgs
+{
+ ::std::vector<Lifetime> lifetime_args;
+ //::std::vector<Type> type_args;
+ ::std::vector< ::std::unique_ptr<Type> > type_args;
+ ::std::vector<GenericArgsBinding> binding_args;
+
+ Location locus;
+
+public:
+ // Returns true if there are any generic arguments
+ inline bool has_generic_args () const
+ {
+ return !(lifetime_args.empty () && type_args.empty ()
+ && binding_args.empty ());
+ }
+
+ GenericArgs (::std::vector<Lifetime> lifetime_args,
+ ::std::vector< ::std::unique_ptr<Type> > type_args,
+ ::std::vector<GenericArgsBinding> binding_args,
+ Location locus = Location ())
+ : lifetime_args (::std::move (lifetime_args)),
+ type_args (::std::move (type_args)),
+ binding_args (::std::move (binding_args)), locus (locus)
+ {}
+
+ // copy constructor with vector clone
+ GenericArgs (GenericArgs const &other)
+ : lifetime_args (other.lifetime_args), binding_args (other.binding_args),
+ locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ type_args.reserve (other.type_args.size ());
+
+ for (const auto &e : other.type_args)
+ {
+ type_args.push_back (e->clone_type ());
+ }
+ }
+
+ ~GenericArgs () = default;
+
+ // overloaded assignment operator to vector clone
+ GenericArgs &operator= (GenericArgs const &other)
+ {
+ lifetime_args = other.lifetime_args;
+ binding_args = other.binding_args;
+ locus = other.locus;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ type_args.reserve (other.type_args.size ());
+
+ for (const auto &e : other.type_args)
+ {
+ type_args.push_back (e->clone_type ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ GenericArgs (GenericArgs &&other) = default;
+ GenericArgs &operator= (GenericArgs &&other) = default;
+
+ // Creates an empty GenericArgs (no arguments)
+ static GenericArgs create_empty ()
+ {
+ return GenericArgs (::std::vector<Lifetime> (),
+ ::std::vector< ::std::unique_ptr<Type> > (),
+ ::std::vector<GenericArgsBinding> ());
+ }
+
+ ::std::string as_string () const;
+};
+
+// A segment of a path in expression, including an identifier aspect and maybe
+// generic args
+class PathExprSegment
+{ // or should this extend PathIdentSegment?
+private:
+ PathIdentSegment segment_name;
+
+ // bool has_generic_args;
+ GenericArgs generic_args;
+
+ Location locus;
+
+ // TODO: does this require visitor? pretty sure not polymorphic
+
+public:
+ // Returns true if there are any generic arguments
+ inline bool has_generic_args () const
+ {
+ return generic_args.has_generic_args ();
+ }
+
+ // Constructor for segment (from IdentSegment and GenericArgs)
+ PathExprSegment (PathIdentSegment segment_name, Location locus = Location (),
+ GenericArgs generic_args = GenericArgs::create_empty ())
+ : segment_name (::std::move (segment_name)),
+ generic_args (::std::move (generic_args)), locus (locus)
+ {}
+
+ // Constructor for segment with generic arguments (from segment name and all
+ // args)
+ PathExprSegment (::std::string segment_name, Location locus,
+ ::std::vector<Lifetime> lifetime_args
+ = ::std::vector<Lifetime> (),
+ ::std::vector< ::std::unique_ptr<Type> > type_args
+ = ::std::vector< ::std::unique_ptr<Type> > (),
+ ::std::vector<GenericArgsBinding> binding_args
+ = ::std::vector<GenericArgsBinding> ())
+ : segment_name (PathIdentSegment (::std::move (segment_name))),
+ generic_args (GenericArgs (::std::move (lifetime_args),
+ ::std::move (type_args),
+ ::std::move (binding_args))),
+ locus (locus)
+ {}
+
+ // Returns whether path expression segment is in an error state.
+ inline bool is_error () const { return segment_name.is_error (); }
+
+ // Creates an error-state path expression segment.
+ static PathExprSegment create_error ()
+ {
+ return PathExprSegment (PathIdentSegment::create_error ());
+ }
+
+ ::std::string as_string () const;
+
+ inline Location get_locus () const { return locus; }
+};
+
+// AST node representing a pattern that involves a "path" - abstract base class
+class PathPattern : public Pattern
+{
+ ::std::vector<PathExprSegment> segments;
+
+protected:
+ PathPattern (::std::vector<PathExprSegment> segments)
+ : segments (::std::move (segments))
+ {}
+
+ // Returns whether path has segments.
+ inline bool has_segments () const { return !segments.empty (); }
+
+ /* Converts path segments to their equivalent SimplePath segments if possible,
+ * and creates a SimplePath from them. */
+ SimplePath convert_to_simple_path (bool with_opening_scope_resolution) const;
+
+public:
+ /* Returns whether the path is a single segment (excluding qualified path
+ * initial as segment). */
+ inline bool is_single_segment () const { return segments.size () == 1; }
+
+ virtual ::std::string as_string () const;
+};
+
+// AST node representing a path-in-expression pattern (path that allows generic
+// arguments)
+class PathInExpression : public PathPattern, public PathExpr
+{
+ bool has_opening_scope_resolution;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ // Constructor
+ PathInExpression (::std::vector<PathExprSegment> path_segments,
+ Location locus = Location (),
+ bool has_opening_scope_resolution = false,
+ ::std::vector<Attribute> outer_attrs
+ = ::std::vector<Attribute> ())
+ : PathPattern (::std::move (path_segments)),
+ PathExpr (::std::move (outer_attrs)),
+ has_opening_scope_resolution (has_opening_scope_resolution), locus (locus)
+ {}
+
+ // Creates an error state path in expression.
+ static PathInExpression create_error ()
+ {
+ return PathInExpression (::std::vector<PathExprSegment> ());
+ }
+
+ // Returns whether path in expression is in an error state.
+ inline bool is_error () const { return !has_segments (); }
+
+ /* Converts PathInExpression to SimplePath if possible (i.e. no generic
+ * arguments). Otherwise returns an empty SimplePath. */
+ inline SimplePath as_simple_path () const
+ {
+ /* delegate to parent class as can't access segments. however,
+ * QualifiedPathInExpression conversion to simple path wouldn't make sense,
+ * so the method in the parent class should be protected, not public. Have
+ * to pass in opening scope resolution as parent class has no access to it.
+ */
+ return convert_to_simple_path (has_opening_scope_resolution);
+ }
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual PathInExpression *clone_pattern_impl () const OVERRIDE
+ {
+ return new PathInExpression (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual PathInExpression *clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new PathInExpression (*this);
+ }
+};
+
+// Base class for segments used in type paths - not abstract (represents an
+// ident-only segment)
+class TypePathSegment
+{
+ /* TODO: may have to unify TypePathSegment and PathExprSegment (which are
+ * mostly the same anyway) in order to resolve goddamn syntax ambiguities. One
+ * difference is that function on TypePathSegment is not allowed if
+ * GenericArgs are, so could disallow that in constructor, which won't give
+ * that much size overhead. */
+ PathIdentSegment ident_segment;
+
+ Location locus;
+
+protected:
+ // This is protected because it is only really used by derived classes, not
+ // the base.
+ bool has_separating_scope_resolution;
+
+ // Clone function implementation - not pure virtual as overrided by subclasses
+ virtual TypePathSegment *clone_type_path_segment_impl () const
+ {
+ return new TypePathSegment (*this);
+ }
+
+public:
+ virtual ~TypePathSegment () {}
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<TypePathSegment> clone_type_path_segment () const
+ {
+ return ::std::unique_ptr<TypePathSegment> (clone_type_path_segment_impl ());
+ }
+
+ TypePathSegment (PathIdentSegment ident_segment,
+ bool has_separating_scope_resolution, Location locus)
+ : ident_segment (::std::move (ident_segment)), locus (locus),
+ has_separating_scope_resolution (has_separating_scope_resolution)
+ {}
+
+ TypePathSegment (::std::string segment_name,
+ bool has_separating_scope_resolution, Location locus)
+ : ident_segment (PathIdentSegment (::std::move (segment_name))),
+ locus (locus),
+ has_separating_scope_resolution (has_separating_scope_resolution)
+ {}
+
+ virtual ::std::string as_string () const
+ {
+ return ident_segment.as_string ();
+ }
+
+ // Returns whether the type path segment is in an error state. May be virtual
+ // in future.
+ inline bool is_error () const { return ident_segment.is_error (); }
+
+ /* Returns whether segment is identifier only (as opposed to generic args or
+ function). Overriden in derived classes with other segments. */
+ virtual bool is_ident_only () const { return true; }
+
+ inline Location get_locus () const { return locus; }
+
+ // not pure virtual as class not abstract
+ virtual void accept_vis (ASTVisitor &vis);
+};
+
+// Segment used in type path with generic args
+class TypePathSegmentGeneric : public TypePathSegment
+{
+ GenericArgs generic_args;
+
+public:
+ inline bool has_generic_args () const
+ {
+ return generic_args.has_generic_args ();
+ }
+
+ bool is_ident_only () const { return false; }
+
+ // Constructor with PathIdentSegment and GenericArgs
+ TypePathSegmentGeneric (PathIdentSegment ident_segment,
+ bool has_separating_scope_resolution,
+ GenericArgs generic_args, Location locus)
+ : TypePathSegment (::std::move (ident_segment),
+ has_separating_scope_resolution, locus),
+ generic_args (::std::move (generic_args))
+ {}
+
+ // Constructor from segment name and all args
+ TypePathSegmentGeneric (::std::string segment_name,
+ bool has_separating_scope_resolution,
+ ::std::vector<Lifetime> lifetime_args,
+ ::std::vector< ::std::unique_ptr<Type> > type_args,
+ ::std::vector<GenericArgsBinding> binding_args,
+ Location locus)
+ : TypePathSegment (::std::move (segment_name),
+ has_separating_scope_resolution, locus),
+ generic_args (GenericArgs (::std::move (lifetime_args),
+ ::std::move (type_args),
+ ::std::move (binding_args)))
+ {}
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to override base class method
+ virtual TypePathSegmentGeneric *clone_type_path_segment_impl () const OVERRIDE
+ {
+ return new TypePathSegmentGeneric (*this);
+ }
+};
+
+// A function as represented in a type path
+struct TypePathFunction
+{
+private:
+ // TODO: remove
+ /*bool has_inputs;
+ TypePathFnInputs inputs;*/
+ //::std::vector<Type> inputs; // inlined from TypePathFnInputs
+ ::std::vector< ::std::unique_ptr<Type> > inputs;
+
+ // bool has_type;
+ // Type type;
+ ::std::unique_ptr<Type> return_type;
+
+ // FIXME: think of better way to mark as invalid than taking up storage
+ bool is_invalid;
+
+ // TODO: should this have location info?
+
+protected:
+ // Constructor only used to create invalid type path functions.
+ TypePathFunction (bool is_invalid) : is_invalid (is_invalid) {}
+
+public:
+ // Returns whether the return type of the function has been specified.
+ inline bool has_return_type () const { return return_type != NULL; }
+
+ // Returns whether the function has inputs.
+ inline bool has_inputs () const { return !inputs.empty (); }
+
+ // Returns whether function is in an error state.
+ inline bool is_error () const { return is_invalid; }
+
+ // Creates an error state function.
+ static TypePathFunction create_error () { return TypePathFunction (true); }
+
+ // Constructor
+ TypePathFunction (::std::vector< ::std::unique_ptr<Type> > inputs,
+ Type *type = NULL)
+ : inputs (::std::move (inputs)), return_type (type), is_invalid (false)
+ {}
+ // FIXME: deprecated
+
+ // Constructor
+ TypePathFunction (::std::vector< ::std::unique_ptr<Type> > inputs,
+ ::std::unique_ptr<Type> type = NULL)
+ : inputs (::std::move (inputs)), return_type (::std::move (type)),
+ is_invalid (false)
+ {}
+
+ // Copy constructor with clone
+ TypePathFunction (TypePathFunction const &other)
+ : /*inputs(other.inputs),*/ return_type (other.return_type->clone_type ()),
+ is_invalid (other.is_invalid)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ inputs.reserve (other.inputs.size ());
+
+ for (const auto &e : other.inputs)
+ {
+ inputs.push_back (e->clone_type ());
+ }
+ }
+
+ ~TypePathFunction () = default;
+
+ // Overloaded assignment operator to clone type
+ TypePathFunction &operator= (TypePathFunction const &other)
+ {
+ // inputs = other.inputs;
+ return_type = other.return_type->clone_type ();
+ is_invalid = other.is_invalid;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ inputs.reserve (other.inputs.size ());
+
+ for (const auto &e : other.inputs)
+ {
+ inputs.push_back (e->clone_type ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ TypePathFunction (TypePathFunction &&other) = default;
+ TypePathFunction &operator= (TypePathFunction &&other) = default;
+
+ ::std::string as_string () const;
+};
+
+// Segment used in type path with a function argument
+class TypePathSegmentFunction : public TypePathSegment
+{
+ TypePathFunction function_path;
+
+public:
+ // Constructor with PathIdentSegment and TypePathFn
+ TypePathSegmentFunction (PathIdentSegment ident_segment,
+ bool has_separating_scope_resolution,
+ TypePathFunction function_path, Location locus)
+ : TypePathSegment (::std::move (ident_segment),
+ has_separating_scope_resolution, locus),
+ function_path (::std::move (function_path))
+ {}
+
+ // Constructor with segment name and TypePathFn
+ TypePathSegmentFunction (::std::string segment_name,
+ bool has_separating_scope_resolution,
+ TypePathFunction function_path, Location locus)
+ : TypePathSegment (::std::move (segment_name),
+ has_separating_scope_resolution, locus),
+ function_path (::std::move (function_path))
+ {}
+
+ ::std::string as_string () const;
+
+ bool is_ident_only () const { return false; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to override base class method
+ virtual TypePathSegmentFunction *
+ clone_type_path_segment_impl () const OVERRIDE
+ {
+ return new TypePathSegmentFunction (*this);
+ }
+};
+
+// Path used inside types
+class TypePath : public TypeNoBounds
+{
+ bool has_opening_scope_resolution;
+ ::std::vector< ::std::unique_ptr<TypePathSegment> > segments;
+
+ Location locus;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TypePath *clone_type_impl () const OVERRIDE
+ {
+ return new TypePath (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TypePath *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new TypePath (*this);
+ }
+
+public:
+ /* Returns whether the TypePath has an opening scope resolution operator (i.e.
+ * is global path or crate-relative path, not module-relative) */
+ inline bool has_opening_scope_resolution_op () const
+ {
+ return has_opening_scope_resolution;
+ }
+
+ // Returns whether the TypePath is in an invalid state.
+ inline bool is_error () const { return segments.empty (); }
+
+ // Creates an error state TypePath.
+ static TypePath create_error ()
+ {
+ return TypePath (::std::vector< ::std::unique_ptr<TypePathSegment> > (),
+ Location ());
+ }
+
+ // Constructor
+ TypePath (::std::vector< ::std::unique_ptr<TypePathSegment> > segments,
+ Location locus, bool has_opening_scope_resolution = false)
+ : has_opening_scope_resolution (has_opening_scope_resolution),
+ segments (::std::move (segments)), locus (locus)
+ {}
+
+ // Copy constructor with vector clone
+ TypePath (TypePath const &other)
+ : has_opening_scope_resolution (other.has_opening_scope_resolution),
+ locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ segments.reserve (other.segments.size ());
+
+ for (const auto &e : other.segments)
+ {
+ segments.push_back (e->clone_type_path_segment ());
+ }
+ }
+
+ // Overloaded assignment operator with clone
+ TypePath &operator= (TypePath const &other)
+ {
+ has_opening_scope_resolution = other.has_opening_scope_resolution;
+ locus = other.locus;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ segments.reserve (other.segments.size ());
+
+ for (const auto &e : other.segments)
+ {
+ segments.push_back (e->clone_type_path_segment ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ TypePath (TypePath &&other) = default;
+ TypePath &operator= (TypePath &&other) = default;
+
+ ::std::string as_string () const;
+
+ /* Converts TypePath to SimplePath if possible (i.e. no generic or function
+ * arguments). Otherwise returns an empty SimplePath. */
+ SimplePath as_simple_path () const;
+
+ // Creates a trait bound with a clone of this type path as its only element.
+ virtual TraitBound *to_trait_bound (bool in_parens) const OVERRIDE;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+};
+
+struct QualifiedPathType
+{
+private:
+ // Type type_to_invoke_on;
+ ::std::unique_ptr<Type> type_to_invoke_on;
+
+ // bool has_as_clause;
+ TypePath trait_path;
+
+ Location locus;
+
+public:
+ // Constructor
+ QualifiedPathType (::std::unique_ptr<Type> invoke_on_type,
+ Location locus = Location (),
+ TypePath trait_path = TypePath::create_error ())
+ : type_to_invoke_on (::std::move (invoke_on_type)),
+ trait_path (::std::move (trait_path)), locus (locus)
+ {}
+
+ // Copy constructor uses custom deep copy for Type to preserve polymorphism
+ QualifiedPathType (QualifiedPathType const &other)
+ : type_to_invoke_on (other.type_to_invoke_on->clone_type ()),
+ trait_path (other.trait_path), locus (other.locus)
+ {}
+
+ // default destructor
+ ~QualifiedPathType () = default;
+
+ // overload assignment operator to use custom clone method
+ QualifiedPathType &operator= (QualifiedPathType const &other)
+ {
+ type_to_invoke_on = other.type_to_invoke_on->clone_type ();
+ trait_path = other.trait_path;
+ locus = other.locus;
+ return *this;
+ }
+
+ // move constructor
+ QualifiedPathType (QualifiedPathType &&other) = default;
+ QualifiedPathType &operator= (QualifiedPathType &&other) = default;
+
+ // Returns whether the qualified path type has a rebind as clause.
+ inline bool has_as_clause () const { return !trait_path.is_error (); }
+
+ // Returns whether the qualified path type is in an error state.
+ inline bool is_error () const { return type_to_invoke_on == NULL; }
+
+ // Creates an error state qualified path type.
+ static QualifiedPathType create_error () { return QualifiedPathType (NULL); }
+
+ ::std::string as_string () const;
+
+ inline Location get_locus () const { return locus; }
+};
+
+/* AST node representing a qualified path-in-expression pattern (path that
+ * allows specifying trait functions) */
+class QualifiedPathInExpression : public PathPattern, public PathExpr
+{
+ QualifiedPathType path_type;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ QualifiedPathInExpression (QualifiedPathType qual_path_type,
+ ::std::vector<PathExprSegment> path_segments,
+ Location locus = Location (),
+ ::std::vector<Attribute> outer_attrs
+ = ::std::vector<Attribute> ())
+ : PathPattern (::std::move (path_segments)),
+ PathExpr (::std::move (outer_attrs)),
+ path_type (::std::move (qual_path_type)), locus (locus)
+ {}
+
+ // TODO: maybe make a shortcut constructor that has QualifiedPathType elements
+ // as params
+
+ // Copy constructor, destructor, and assignment operator overload shouldn't be
+ // required
+
+ // Returns whether qualified path in expression is in an error state.
+ inline bool is_error () const { return path_type.is_error (); }
+
+ // Creates an error qualified path in expression.
+ static QualifiedPathInExpression create_error ()
+ {
+ return QualifiedPathInExpression (QualifiedPathType::create_error (),
+ ::std::vector<PathExprSegment> ());
+ }
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const OVERRIDE { return get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual QualifiedPathInExpression *clone_pattern_impl () const OVERRIDE
+ {
+ return new QualifiedPathInExpression (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual QualifiedPathInExpression *
+ clone_expr_without_block_impl () const OVERRIDE
+ {
+ return new QualifiedPathInExpression (*this);
+ }
+};
+
+// Represents a qualified path in a type; used for disambiguating trait function
+// calls
+class QualifiedPathInType : public TypeNoBounds
+{
+ QualifiedPathType path_type;
+ // ::std::vector<TypePathSegment> segments;
+ ::std::vector< ::std::unique_ptr<TypePathSegment> > segments;
+
+ Location locus;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual QualifiedPathInType *clone_type_impl () const OVERRIDE
+ {
+ return new QualifiedPathInType (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual QualifiedPathInType *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new QualifiedPathInType (*this);
+ }
+
+public:
+ QualifiedPathInType (
+ QualifiedPathType qual_path_type,
+ ::std::vector< ::std::unique_ptr<TypePathSegment> > path_segments,
+ Location locus = Location ())
+ : path_type (::std::move (qual_path_type)),
+ segments (::std::move (path_segments)), locus (locus)
+ {}
+
+ // TODO: maybe make a shortcut constructor that has QualifiedPathType elements
+ // as params
+
+ // Copy constructor with vector clone
+ QualifiedPathInType (QualifiedPathInType const &other)
+ : path_type (other.path_type), locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ segments.reserve (other.segments.size ());
+
+ for (const auto &e : other.segments)
+ {
+ segments.push_back (e->clone_type_path_segment ());
+ }
+ }
+
+ // Overloaded assignment operator with vector clone
+ QualifiedPathInType &operator= (QualifiedPathInType const &other)
+ {
+ path_type = other.path_type;
+ locus = other.locus;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ segments.reserve (other.segments.size ());
+
+ for (const auto &e : other.segments)
+ {
+ segments.push_back (e->clone_type_path_segment ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ QualifiedPathInType (QualifiedPathInType &&other) = default;
+ QualifiedPathInType &operator= (QualifiedPathInType &&other) = default;
+
+ // Returns whether qualified path in type is in an error state.
+ inline bool is_error () const { return path_type.is_error (); }
+
+ // Creates an error state qualified path in type.
+ static QualifiedPathInType create_error ()
+ {
+ return QualifiedPathInType (
+ QualifiedPathType::create_error (),
+ ::std::vector< ::std::unique_ptr<TypePathSegment> > ());
+ }
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+};
+} // namespace AST
+} // namespace Rust
#endif
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 5df0528..533a65f 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -4,1160 +4,1320 @@
#include "rust-ast.h"
namespace Rust {
- namespace AST {
- // Literal pattern AST node (comparing to a literal)
- class LiteralPattern : public Pattern {
- Literal lit; // make literal have a type given by enum, etc. rustc uses an extended form
- // of its literal token implementation
- // FIXME: literal representation - use LiteralExpr? or another thing?
-
- // Minus prefixed to literal (if integer or floating-point)
- bool has_minus;
- // Actually, this might be a good place to use a template.
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- // Constructor for a literal pattern
- LiteralPattern(Literal lit, Location locus, bool has_minus = false) :
- lit(::std::move(lit)), has_minus(has_minus), locus(locus) {}
-
- LiteralPattern(
- ::std::string val, Literal::LitType type, Location locus, bool has_minus = false) :
- lit(Literal(::std::move(val), type)),
- has_minus(has_minus), locus(locus) {}
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual LiteralPattern* clone_pattern_impl() const OVERRIDE {
- return new LiteralPattern(*this);
- }
- };
-
- // Identifier pattern AST node (bind value matched to a variable)
- class IdentifierPattern : public Pattern {
- Identifier variable_ident;
- bool is_ref;
- bool is_mut;
-
- // bool has_pattern;
- // Pattern* to_bind;
- ::std::unique_ptr<Pattern> to_bind;
-
- Location locus;
-
- public:
- /*~IdentifierPattern() {
- delete to_bind;
- }*/
-
- ::std::string as_string() const;
-
- // Returns whether the IdentifierPattern has a pattern to bind.
- inline bool has_pattern_to_bind() const {
- return to_bind != NULL;
- }
-
- // Constructor
- IdentifierPattern(Identifier ident, Location locus, bool is_ref = false,
- bool is_mut = false, ::std::unique_ptr<Pattern> to_bind = NULL) :
- variable_ident(::std::move(ident)),
- is_ref(is_ref), is_mut(is_mut), to_bind(::std::move(to_bind)), locus(locus) {}
-
- // Copy constructor with clone
- IdentifierPattern(IdentifierPattern const& other) :
- variable_ident(other.variable_ident), is_ref(other.is_ref), is_mut(other.is_mut),
- locus(other.locus) {
- // fix to get prevent null pointer dereference
- if (other.to_bind != NULL) {
- to_bind = other.to_bind->clone_pattern();
- }
- }
-
- // Destructor - define here if required
-
- // Overload assignment operator to use clone
- IdentifierPattern& operator=(IdentifierPattern const& other) {
- variable_ident = other.variable_ident;
- is_ref = other.is_ref;
- is_mut = other.is_mut;
- locus = other.locus;
- // fix to get prevent null pointer dereference
- if (other.to_bind != NULL) {
- to_bind = other.to_bind->clone_pattern();
- }
-
- return *this;
- }
-
- // default move semantics
- IdentifierPattern(IdentifierPattern&& other) = default;
- IdentifierPattern& operator=(IdentifierPattern&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual IdentifierPattern* clone_pattern_impl() const OVERRIDE {
- return new IdentifierPattern(*this);
- }
- };
-
- // AST node for using the '_' wildcard "match any value" pattern
- class WildcardPattern : public Pattern {
- Location locus;
-
- public:
- ::std::string as_string() const {
- return ::std::string(1, '_');
- }
-
- WildcardPattern(Location locus) : locus(locus) {}
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual WildcardPattern* clone_pattern_impl() const OVERRIDE {
- return new WildcardPattern(*this);
- }
- };
-
- // Base range pattern bound (lower or upper limit) - abstract
- class RangePatternBound {
- /*union {
- CharLiteral char_lit;
- ByteLiteral byte_lit;
- IntLiteral int_lit;
- FloatLiteral float_lit;
- PathInExpression path;
- QualifiedPathInExpression qual_path;
- } pattern;*/
- public:
- virtual ~RangePatternBound() {}
-
- // Unique pointer custom clone function
- ::std::unique_ptr<RangePatternBound> clone_range_pattern_bound() const {
- return ::std::unique_ptr<RangePatternBound>(clone_range_pattern_bound_impl());
- }
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- protected:
- // pure virtual as RangePatternBound is abstract
- virtual RangePatternBound* clone_range_pattern_bound_impl() const = 0;
- };
-
- // Literal-based pattern bound
- class RangePatternBoundLiteral : public RangePatternBound {
- Literal literal;
- // Can only be a char, byte, int, or float literal - same impl here as previously
-
- // Minus prefixed to literal (if integer or floating-point)
- bool has_minus;
-
- Location locus;
-
- public:
- // Constructor
- RangePatternBoundLiteral(Literal literal, Location locus, bool has_minus = false) :
- literal(literal), has_minus(has_minus), locus(locus) {}
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangePatternBoundLiteral* clone_range_pattern_bound_impl() const OVERRIDE {
- return new RangePatternBoundLiteral(*this);
- }
- };
-
- // Path-based pattern bound
- class RangePatternBoundPath : public RangePatternBound {
- PathInExpression path;
-
- // TODO: should this be refactored so that PathInExpression is a subclass of
- // RangePatternBound?
-
- public:
- RangePatternBoundPath(PathInExpression path) : path(::std::move(path)) {}
-
- ::std::string as_string() const {
- return path.as_string();
- }
-
- Location get_locus() const {
- return path.get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangePatternBoundPath* clone_range_pattern_bound_impl() const OVERRIDE {
- return new RangePatternBoundPath(*this);
- }
- };
-
- // Qualified path-based pattern bound
- class RangePatternBoundQualPath : public RangePatternBound {
- QualifiedPathInExpression path;
-
- /* TODO: should this be refactored so that QualifiedPathInExpression is a subclass of
- * RangePatternBound? */
-
- public:
- RangePatternBoundQualPath(QualifiedPathInExpression path) : path(::std::move(path)) {}
-
- ::std::string as_string() const {
- return path.as_string();
- }
-
- Location get_locus() const {
- return path.get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangePatternBoundQualPath* clone_range_pattern_bound_impl() const OVERRIDE {
- return new RangePatternBoundQualPath(*this);
- }
- };
+namespace AST {
+// Literal pattern AST node (comparing to a literal)
+class LiteralPattern : public Pattern
+{
+ Literal lit; // make literal have a type given by enum, etc. rustc uses an
+ // extended form
+ // of its literal token implementation
+ // FIXME: literal representation - use LiteralExpr? or another thing?
+
+ // Minus prefixed to literal (if integer or floating-point)
+ bool has_minus;
+ // Actually, this might be a good place to use a template.
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ // Constructor for a literal pattern
+ LiteralPattern (Literal lit, Location locus, bool has_minus = false)
+ : lit (::std::move (lit)), has_minus (has_minus), locus (locus)
+ {}
+
+ LiteralPattern (::std::string val, Literal::LitType type, Location locus,
+ bool has_minus = false)
+ : lit (Literal (::std::move (val), type)), has_minus (has_minus),
+ locus (locus)
+ {}
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual LiteralPattern *clone_pattern_impl () const OVERRIDE
+ {
+ return new LiteralPattern (*this);
+ }
+};
+
+// Identifier pattern AST node (bind value matched to a variable)
+class IdentifierPattern : public Pattern
+{
+ Identifier variable_ident;
+ bool is_ref;
+ bool is_mut;
+
+ // bool has_pattern;
+ // Pattern* to_bind;
+ ::std::unique_ptr<Pattern> to_bind;
+
+ Location locus;
+
+public:
+ /*~IdentifierPattern() {
+ delete to_bind;
+ }*/
+
+ ::std::string as_string () const;
+
+ // Returns whether the IdentifierPattern has a pattern to bind.
+ inline bool has_pattern_to_bind () const { return to_bind != NULL; }
+
+ // Constructor
+ IdentifierPattern (Identifier ident, Location locus, bool is_ref = false,
+ bool is_mut = false,
+ ::std::unique_ptr<Pattern> to_bind = NULL)
+ : variable_ident (::std::move (ident)), is_ref (is_ref), is_mut (is_mut),
+ to_bind (::std::move (to_bind)), locus (locus)
+ {}
+
+ // Copy constructor with clone
+ IdentifierPattern (IdentifierPattern const &other)
+ : variable_ident (other.variable_ident), is_ref (other.is_ref),
+ is_mut (other.is_mut), locus (other.locus)
+ {
+ // fix to get prevent null pointer dereference
+ if (other.to_bind != NULL)
+ {
+ to_bind = other.to_bind->clone_pattern ();
+ }
+ }
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to use clone
+ IdentifierPattern &operator= (IdentifierPattern const &other)
+ {
+ variable_ident = other.variable_ident;
+ is_ref = other.is_ref;
+ is_mut = other.is_mut;
+ locus = other.locus;
+ // fix to get prevent null pointer dereference
+ if (other.to_bind != NULL)
+ {
+ to_bind = other.to_bind->clone_pattern ();
+ }
+
+ return *this;
+ }
+
+ // default move semantics
+ IdentifierPattern (IdentifierPattern &&other) = default;
+ IdentifierPattern &operator= (IdentifierPattern &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual IdentifierPattern *clone_pattern_impl () const OVERRIDE
+ {
+ return new IdentifierPattern (*this);
+ }
+};
+
+// AST node for using the '_' wildcard "match any value" pattern
+class WildcardPattern : public Pattern
+{
+ Location locus;
+
+public:
+ ::std::string as_string () const { return ::std::string (1, '_'); }
+
+ WildcardPattern (Location locus) : locus (locus) {}
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual WildcardPattern *clone_pattern_impl () const OVERRIDE
+ {
+ return new WildcardPattern (*this);
+ }
+};
+
+// Base range pattern bound (lower or upper limit) - abstract
+class RangePatternBound
+{
+ /*union {
+ CharLiteral char_lit;
+ ByteLiteral byte_lit;
+ IntLiteral int_lit;
+ FloatLiteral float_lit;
+ PathInExpression path;
+ QualifiedPathInExpression qual_path;
+ } pattern;*/
+public:
+ virtual ~RangePatternBound () {}
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<RangePatternBound> clone_range_pattern_bound () const
+ {
+ return ::std::unique_ptr<RangePatternBound> (
+ clone_range_pattern_bound_impl ());
+ }
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+protected:
+ // pure virtual as RangePatternBound is abstract
+ virtual RangePatternBound *clone_range_pattern_bound_impl () const = 0;
+};
+
+// Literal-based pattern bound
+class RangePatternBoundLiteral : public RangePatternBound
+{
+ Literal literal;
+ // Can only be a char, byte, int, or float literal - same impl here as
+ // previously
+
+ // Minus prefixed to literal (if integer or floating-point)
+ bool has_minus;
+
+ Location locus;
+
+public:
+ // Constructor
+ RangePatternBoundLiteral (Literal literal, Location locus,
+ bool has_minus = false)
+ : literal (literal), has_minus (has_minus), locus (locus)
+ {}
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangePatternBoundLiteral *
+ clone_range_pattern_bound_impl () const OVERRIDE
+ {
+ return new RangePatternBoundLiteral (*this);
+ }
+};
+
+// Path-based pattern bound
+class RangePatternBoundPath : public RangePatternBound
+{
+ PathInExpression path;
+
+ // TODO: should this be refactored so that PathInExpression is a subclass of
+ // RangePatternBound?
+
+public:
+ RangePatternBoundPath (PathInExpression path) : path (::std::move (path)) {}
+
+ ::std::string as_string () const { return path.as_string (); }
+
+ Location get_locus () const { return path.get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangePatternBoundPath *
+ clone_range_pattern_bound_impl () const OVERRIDE
+ {
+ return new RangePatternBoundPath (*this);
+ }
+};
+
+// Qualified path-based pattern bound
+class RangePatternBoundQualPath : public RangePatternBound
+{
+ QualifiedPathInExpression path;
+
+ /* TODO: should this be refactored so that QualifiedPathInExpression is a
+ * subclass of RangePatternBound? */
+
+public:
+ RangePatternBoundQualPath (QualifiedPathInExpression path)
+ : path (::std::move (path))
+ {}
+
+ ::std::string as_string () const { return path.as_string (); }
+
+ Location get_locus () const { return path.get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangePatternBoundQualPath *
+ clone_range_pattern_bound_impl () const OVERRIDE
+ {
+ return new RangePatternBoundQualPath (*this);
+ }
+};
+
+// AST node for matching within a certain range (range pattern)
+class RangePattern : public Pattern
+{
+ /*RangePatternBound lower;
+ RangePatternBound upper;*/
+ ::std::unique_ptr<RangePatternBound> lower;
+ ::std::unique_ptr<RangePatternBound> upper;
+
+ bool has_ellipsis_syntax;
+
+ // location only stored to avoid a dereference - lower pattern should give
+ // correct location so maybe change in future
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ // Constructor
+ RangePattern (::std::unique_ptr<RangePatternBound> lower,
+ ::std::unique_ptr<RangePatternBound> upper, Location locus,
+ bool has_ellipsis_syntax = false)
+ : lower (::std::move (lower)), upper (::std::move (upper)),
+ has_ellipsis_syntax (has_ellipsis_syntax), locus (locus)
+ {}
+
+ // Copy constructor with clone
+ RangePattern (RangePattern const &other)
+ : lower (other.lower->clone_range_pattern_bound ()),
+ upper (other.upper->clone_range_pattern_bound ()),
+ has_ellipsis_syntax (other.has_ellipsis_syntax), locus (other.locus)
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone
+ RangePattern &operator= (RangePattern const &other)
+ {
+ lower = other.lower->clone_range_pattern_bound ();
+ upper = other.upper->clone_range_pattern_bound ();
+ has_ellipsis_syntax = other.has_ellipsis_syntax;
+ locus = other.locus;
+
+ return *this;
+ }
+
+ // default move semantics
+ RangePattern (RangePattern &&other) = default;
+ RangePattern &operator= (RangePattern &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RangePattern *clone_pattern_impl () const OVERRIDE
+ {
+ return new RangePattern (*this);
+ }
+};
+
+// AST node for pattern based on dereferencing the pointers given
+class ReferencePattern : public Pattern
+{
+ bool has_two_amps;
+ bool is_mut;
+ // Pattern* pattern;
+ ::std::unique_ptr<Pattern> pattern;
+
+ Location locus;
+
+public:
+ /*~ReferencePattern() {
+ delete pattern;
+ }*/
+
+ ::std::string as_string () const;
+
+ ReferencePattern (::std::unique_ptr<Pattern> pattern, bool is_mut_reference,
+ bool ref_has_two_amps, Location locus)
+ : has_two_amps (ref_has_two_amps), is_mut (is_mut_reference),
+ pattern (::std::move (pattern)), locus (locus)
+ {}
+
+ // Copy constructor requires clone
+ ReferencePattern (ReferencePattern const &other)
+ : has_two_amps (other.has_two_amps), is_mut (other.is_mut),
+ pattern (other.pattern->clone_pattern ()), locus (other.locus)
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone
+ ReferencePattern &operator= (ReferencePattern const &other)
+ {
+ pattern = other.pattern->clone_pattern ();
+ is_mut = other.is_mut;
+ has_two_amps = other.has_two_amps;
+ locus = other.locus;
+
+ return *this;
+ }
+
+ // default move semantics
+ ReferencePattern (ReferencePattern &&other) = default;
+ ReferencePattern &operator= (ReferencePattern &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ReferencePattern *clone_pattern_impl () const OVERRIDE
+ {
+ return new ReferencePattern (*this);
+ }
+};
+
+// aka StructPatternEtCetera; potential element in struct pattern
+struct StructPatternEtc
+{
+private:
+ ::std::vector<Attribute> outer_attrs;
+
+ // should this store location data?
+
+public:
+ StructPatternEtc (::std::vector<Attribute> outer_attribs)
+ : outer_attrs (::std::move (outer_attribs))
+ {}
+
+ // Creates an empty StructPatternEtc
+ static StructPatternEtc create_empty ()
+ {
+ return StructPatternEtc (::std::vector<Attribute> ());
+ }
+};
+
+// Base class for a single field in a struct pattern - abstract
+class StructPatternField
+{
+ ::std::vector<Attribute> outer_attrs;
+ /*union {
+ struct {
+ //TupleIndex index;
+ Pattern tuple_pattern;
+ } tuple_pattern;
+ struct {
+ //Identifier ident;
+ Pattern ident_pattern;
+ } ident_pattern;
+ struct {
+ bool has_ref;
+ bool has_mut;
+ //Identifier ident;
+ } ident;
+ } pattern;*/
+
+ Location locus;
+
+public:
+ virtual ~StructPatternField () {}
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<StructPatternField> clone_struct_pattern_field () const
+ {
+ return ::std::unique_ptr<StructPatternField> (
+ clone_struct_pattern_field_impl ());
+ }
+
+ virtual ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+protected:
+ StructPatternField (::std::vector<Attribute> outer_attribs, Location locus)
+ : outer_attrs (::std::move (outer_attribs)), locus (locus)
+ {}
+
+ // Clone function implementation as pure virtual method
+ virtual StructPatternField *clone_struct_pattern_field_impl () const = 0;
+};
+
+// Tuple pattern single field in a struct pattern
+class StructPatternFieldTuplePat : public StructPatternField
+{
+ TupleIndex index;
+ // Pattern* tuple_pattern;
+ ::std::unique_ptr<Pattern> tuple_pattern;
+
+public:
+ /*~StructPatternFieldTuplePat() {
+ delete tuple_pattern;
+ }*/
+
+ StructPatternFieldTuplePat (TupleIndex index,
+ ::std::unique_ptr<Pattern> tuple_pattern,
+ ::std::vector<Attribute> outer_attribs,
+ Location locus)
+ : StructPatternField (::std::move (outer_attribs), locus), index (index),
+ tuple_pattern (::std::move (tuple_pattern))
+ {}
+
+ // Copy constructor requires clone
+ StructPatternFieldTuplePat (StructPatternFieldTuplePat const &other)
+ : StructPatternField (other), index (other.index),
+ tuple_pattern (other.tuple_pattern->clone_pattern ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to perform clone
+ StructPatternFieldTuplePat &
+ operator= (StructPatternFieldTuplePat const &other)
+ {
+ StructPatternField::operator= (other);
+ tuple_pattern = other.tuple_pattern->clone_pattern ();
+ index = other.index;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // default move semantics
+ StructPatternFieldTuplePat (StructPatternFieldTuplePat &&other) = default;
+ StructPatternFieldTuplePat &operator= (StructPatternFieldTuplePat &&other)
+ = default;
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructPatternFieldTuplePat *
+ clone_struct_pattern_field_impl () const OVERRIDE
+ {
+ return new StructPatternFieldTuplePat (*this);
+ }
+};
+
+// Identifier pattern single field in a struct pattern
+class StructPatternFieldIdentPat : public StructPatternField
+{
+ Identifier ident;
+ // Pattern* ident_pattern;
+ ::std::unique_ptr<Pattern> ident_pattern;
+
+public:
+ /*~StructPatternFieldIdentPat() {
+ delete ident_pattern;
+ }*/
+
+ StructPatternFieldIdentPat (Identifier ident,
+ ::std::unique_ptr<Pattern> ident_pattern,
+ ::std::vector<Attribute> outer_attrs,
+ Location locus)
+ : StructPatternField (::std::move (outer_attrs), locus),
+ ident (::std::move (ident)), ident_pattern (::std::move (ident_pattern))
+ {}
+
+ // Copy constructor requires clone
+ StructPatternFieldIdentPat (StructPatternFieldIdentPat const &other)
+ : StructPatternField (other), ident (other.ident),
+ ident_pattern (other.ident_pattern->clone_pattern ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone
+ StructPatternFieldIdentPat &
+ operator= (StructPatternFieldIdentPat const &other)
+ {
+ StructPatternField::operator= (other);
+ ident = other.ident;
+ ident_pattern = other.ident_pattern->clone_pattern ();
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // default move semantics
+ StructPatternFieldIdentPat (StructPatternFieldIdentPat &&other) = default;
+ StructPatternFieldIdentPat &operator= (StructPatternFieldIdentPat &&other)
+ = default;
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructPatternFieldIdentPat *
+ clone_struct_pattern_field_impl () const OVERRIDE
+ {
+ return new StructPatternFieldIdentPat (*this);
+ }
+};
+
+// Identifier only (with no pattern) single field in a struct pattern
+class StructPatternFieldIdent : public StructPatternField
+{
+ bool has_ref;
+ bool has_mut;
+
+ Identifier ident;
+
+public:
+ StructPatternFieldIdent (Identifier ident, bool is_ref, bool is_mut,
+ ::std::vector<Attribute> outer_attrs, Location locus)
+ : StructPatternField (::std::move (outer_attrs), locus), has_ref (is_ref),
+ has_mut (is_mut), ident (::std::move (ident))
+ {}
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructPatternFieldIdent *
+ clone_struct_pattern_field_impl () const OVERRIDE
+ {
+ return new StructPatternFieldIdent (*this);
+ }
+};
+
+// Elements of a struct pattern
+struct StructPatternElements
+{
+private:
+ // bool has_struct_pattern_fields;
+ //::std::vector<StructPatternField> fields;
+ ::std::vector< ::std::unique_ptr<StructPatternField> > fields;
+
+ bool has_struct_pattern_etc;
+ StructPatternEtc etc;
+
+ // must have at least one of the two and maybe both
+
+ // should this store location data?
+
+public:
+ // Returns whether there are any struct pattern fields
+ inline bool has_struct_pattern_fields () const { return !fields.empty (); }
+
+ // Returns whether the struct pattern elements is entirely empty (no fields,
+ // no etc).
+ inline bool is_empty () const
+ {
+ return !has_struct_pattern_fields () && !has_struct_pattern_etc;
+ }
+
+ // Constructor for StructPatternElements with both (potentially)
+ StructPatternElements (
+ ::std::vector< ::std::unique_ptr<StructPatternField> > fields,
+ StructPatternEtc etc)
+ : fields (::std::move (fields)), has_struct_pattern_etc (true),
+ etc (::std::move (etc))
+ {}
+
+ // Constructor for StructPatternElements with no StructPatternEtc
+ StructPatternElements (
+ ::std::vector< ::std::unique_ptr<StructPatternField> > fields)
+ : fields (::std::move (fields)), has_struct_pattern_etc (false),
+ etc (StructPatternEtc::create_empty ())
+ {}
+
+ // Copy constructor with vector clone
+ StructPatternElements (StructPatternElements const &other)
+ : has_struct_pattern_etc (other.has_struct_pattern_etc), etc (other.etc)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ fields.reserve (other.fields.size ());
+
+ for (const auto &e : other.fields)
+ {
+ fields.push_back (e->clone_struct_pattern_field ());
+ }
+ }
+
+ // Overloaded assignment operator with vector clone
+ StructPatternElements &operator= (StructPatternElements const &other)
+ {
+ etc = other.etc;
+ has_struct_pattern_etc = other.has_struct_pattern_etc;
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ fields.reserve (other.fields.size ());
+
+ for (const auto &e : other.fields)
+ {
+ fields.push_back (e->clone_struct_pattern_field ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ StructPatternElements (StructPatternElements &&other) = default;
+ StructPatternElements &operator= (StructPatternElements &&other) = default;
+
+ // Creates an empty StructPatternElements
+ static StructPatternElements create_empty ()
+ {
+ return StructPatternElements (
+ ::std::vector< ::std::unique_ptr<StructPatternField> > ());
+ }
+
+ ::std::string as_string () const;
+};
+
+// Struct pattern AST node representation
+class StructPattern : public Pattern
+{
+ PathInExpression path;
+
+ // bool has_struct_pattern_elements;
+ StructPatternElements elems;
+
+ // TODO: should this store location data? Accessor uses path location data.
+
+public:
+ ::std::string as_string () const;
+
+ // Constructs a struct pattern from specified StructPatternElements
+ StructPattern (PathInExpression struct_path,
+ StructPatternElements elems
+ = StructPatternElements::create_empty ())
+ : path (::std::move (struct_path)), elems (::std::move (elems))
+ {}
+
+ // TODO: constructor to construct via elements included in
+ // StructPatternElements
+
+ // Returns whether struct pattern has any struct pattern elements (if not, it
+ // is empty).
+ inline bool has_struct_pattern_elems () const { return !elems.is_empty (); }
+
+ Location get_locus () const { return path.get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual StructPattern *clone_pattern_impl () const OVERRIDE
+ {
+ return new StructPattern (*this);
+ }
+};
+
+// Base abstract class for patterns used in TupleStructPattern
+class TupleStructItems
+{
+public:
+ virtual ~TupleStructItems () {}
+
+ // TODO: should this store location data?
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<TupleStructItems> clone_tuple_struct_items () const
+ {
+ return ::std::unique_ptr<TupleStructItems> (
+ clone_tuple_struct_items_impl ());
+ }
+
+ virtual ::std::string as_string () const = 0;
+
+ virtual void accept_vis (ASTVisitor &vis) = 0;
+
+protected:
+ // pure virtual clone implementation
+ virtual TupleStructItems *clone_tuple_struct_items_impl () const = 0;
+};
+
+// Class for non-ranged tuple struct pattern patterns
+class TupleStructItemsNoRange : public TupleStructItems
+{
+ //::std::vector<Pattern> patterns;
+ ::std::vector< ::std::unique_ptr<Pattern> > patterns;
+
+public:
+ TupleStructItemsNoRange (::std::vector< ::std::unique_ptr<Pattern> > patterns)
+ : patterns (::std::move (patterns))
+ {}
+
+ // Copy constructor with vector clone
+ TupleStructItemsNoRange (TupleStructItemsNoRange const &other)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ patterns.reserve (other.patterns.size ());
+
+ for (const auto &e : other.patterns)
+ {
+ patterns.push_back (e->clone_pattern ());
+ }
+ }
+
+ // Overloaded assignment operator with vector clone
+ TupleStructItemsNoRange &operator= (TupleStructItemsNoRange const &other)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ patterns.reserve (other.patterns.size ());
+
+ for (const auto &e : other.patterns)
+ {
+ patterns.push_back (e->clone_pattern ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ TupleStructItemsNoRange (TupleStructItemsNoRange &&other) = default;
+ TupleStructItemsNoRange &operator= (TupleStructItemsNoRange &&other)
+ = default;
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TupleStructItemsNoRange *
+ clone_tuple_struct_items_impl () const OVERRIDE
+ {
+ return new TupleStructItemsNoRange (*this);
+ }
+};
+
+// Class for ranged tuple struct pattern patterns
+class TupleStructItemsRange : public TupleStructItems
+{
+ /*::std::vector<Pattern> lower_patterns;
+ ::std::vector<Pattern> upper_patterns;*/
+ ::std::vector< ::std::unique_ptr<Pattern> > lower_patterns;
+ ::std::vector< ::std::unique_ptr<Pattern> > upper_patterns;
+
+public:
+ TupleStructItemsRange (
+ ::std::vector< ::std::unique_ptr<Pattern> > lower_patterns,
+ ::std::vector< ::std::unique_ptr<Pattern> > upper_patterns)
+ : lower_patterns (::std::move (lower_patterns)),
+ upper_patterns (::std::move (upper_patterns))
+ {}
+
+ // Copy constructor with vector clone
+ TupleStructItemsRange (TupleStructItemsRange const &other)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ lower_patterns.reserve (other.lower_patterns.size ());
+
+ for (const auto &e : other.lower_patterns)
+ {
+ lower_patterns.push_back (e->clone_pattern ());
+ }
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ upper_patterns.reserve (other.upper_patterns.size ());
+
+ for (const auto &e : other.upper_patterns)
+ {
+ upper_patterns.push_back (e->clone_pattern ());
+ }
+ }
+
+ // Overloaded assignment operator to clone
+ TupleStructItemsRange &operator= (TupleStructItemsRange const &other)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ lower_patterns.reserve (other.lower_patterns.size ());
+
+ for (const auto &e : other.lower_patterns)
+ {
+ lower_patterns.push_back (e->clone_pattern ());
+ }
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ upper_patterns.reserve (other.upper_patterns.size ());
+
+ for (const auto &e : other.upper_patterns)
+ {
+ upper_patterns.push_back (e->clone_pattern ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ TupleStructItemsRange (TupleStructItemsRange &&other) = default;
+ TupleStructItemsRange &operator= (TupleStructItemsRange &&other) = default;
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TupleStructItemsRange *clone_tuple_struct_items_impl () const OVERRIDE
+ {
+ return new TupleStructItemsRange (*this);
+ }
+};
+
+// AST node representing a tuple struct pattern
+class TupleStructPattern : public Pattern
+{
+ PathInExpression path;
+ // TupleStructItems items;
+ ::std::unique_ptr<TupleStructItems> items;
+
+ // TOOD: should this store location data? current accessor uses path location
+ // data
+
+public:
+ ::std::string as_string () const;
+
+ TupleStructPattern (PathInExpression tuple_struct_path,
+ ::std::unique_ptr<TupleStructItems> items)
+ : path (::std::move (tuple_struct_path)), items (::std::move (items))
+ {}
+
+ // Copy constructor required to clone
+ TupleStructPattern (TupleStructPattern const &other)
+ : path (other.path), items (other.items->clone_tuple_struct_items ())
+ {}
+
+ // Destructor - define here if required
+
+ // Operator overload assignment operator to clone
+ TupleStructPattern &operator= (TupleStructPattern const &other)
+ {
+ path = other.path;
+ items = other.items->clone_tuple_struct_items ();
+
+ return *this;
+ }
+
+ // move constructors
+ TupleStructPattern (TupleStructPattern &&other) = default;
+ TupleStructPattern &operator= (TupleStructPattern &&other) = default;
+
+ Location get_locus () const { return path.get_locus (); }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TupleStructPattern *clone_pattern_impl () const OVERRIDE
+ {
+ return new TupleStructPattern (*this);
+ }
+};
+
+// Base abstract class representing TuplePattern patterns
+class TuplePatternItems
+{
+public:
+ virtual ~TuplePatternItems () {}
+
+ // TODO: should this store location data?
+
+ // Unique pointer custom clone function
+ ::std::unique_ptr<TuplePatternItems> clone_tuple_pattern_items () const
+ {
+ return ::std::unique_ptr<TuplePatternItems> (
+ clone_tuple_pattern_items_impl ());
+ }
- // AST node for matching within a certain range (range pattern)
- class RangePattern : public Pattern {
- /*RangePatternBound lower;
- RangePatternBound upper;*/
- ::std::unique_ptr<RangePatternBound> lower;
- ::std::unique_ptr<RangePatternBound> upper;
+ virtual ::std::string as_string () const = 0;
- bool has_ellipsis_syntax;
+ virtual void accept_vis (ASTVisitor &vis) = 0;
- // location only stored to avoid a dereference - lower pattern should give correct
- // location so maybe change in future
- Location locus;
-
- public:
- ::std::string as_string() const;
+protected:
+ // pure virtual clone implementation
+ virtual TuplePatternItems *clone_tuple_pattern_items_impl () const = 0;
+};
- // Constructor
- RangePattern(::std::unique_ptr<RangePatternBound> lower,
- ::std::unique_ptr<RangePatternBound> upper, Location locus,
- bool has_ellipsis_syntax = false) :
- lower(::std::move(lower)),
- upper(::std::move(upper)), has_ellipsis_syntax(has_ellipsis_syntax), locus(locus) {}
-
- // Copy constructor with clone
- RangePattern(RangePattern const& other) :
- lower(other.lower->clone_range_pattern_bound()),
- upper(other.upper->clone_range_pattern_bound()),
- has_ellipsis_syntax(other.has_ellipsis_syntax), locus(other.locus) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone
- RangePattern& operator=(RangePattern const& other) {
- lower = other.lower->clone_range_pattern_bound();
- upper = other.upper->clone_range_pattern_bound();
- has_ellipsis_syntax = other.has_ellipsis_syntax;
- locus = other.locus;
-
- return *this;
- }
-
- // default move semantics
- RangePattern(RangePattern&& other) = default;
- RangePattern& operator=(RangePattern&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual RangePattern* clone_pattern_impl() const OVERRIDE {
- return new RangePattern(*this);
- }
- };
-
- // AST node for pattern based on dereferencing the pointers given
- class ReferencePattern : public Pattern {
- bool has_two_amps;
- bool is_mut;
- // Pattern* pattern;
- ::std::unique_ptr<Pattern> pattern;
-
- Location locus;
-
- public:
- /*~ReferencePattern() {
- delete pattern;
- }*/
-
- ::std::string as_string() const;
-
- ReferencePattern(::std::unique_ptr<Pattern> pattern, bool is_mut_reference,
- bool ref_has_two_amps, Location locus) :
- has_two_amps(ref_has_two_amps),
- is_mut(is_mut_reference), pattern(::std::move(pattern)), locus(locus) {}
-
- // Copy constructor requires clone
- ReferencePattern(ReferencePattern const& other) :
- has_two_amps(other.has_two_amps), is_mut(other.is_mut),
- pattern(other.pattern->clone_pattern()), locus(other.locus) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone
- ReferencePattern& operator=(ReferencePattern const& other) {
- pattern = other.pattern->clone_pattern();
- is_mut = other.is_mut;
- has_two_amps = other.has_two_amps;
- locus = other.locus;
-
- return *this;
- }
-
- // default move semantics
- ReferencePattern(ReferencePattern&& other) = default;
- ReferencePattern& operator=(ReferencePattern&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ReferencePattern* clone_pattern_impl() const OVERRIDE {
- return new ReferencePattern(*this);
- }
- };
-
- // aka StructPatternEtCetera; potential element in struct pattern
- struct StructPatternEtc {
- private:
- ::std::vector<Attribute> outer_attrs;
-
- // should this store location data?
-
- public:
- StructPatternEtc(::std::vector<Attribute> outer_attribs) :
- outer_attrs(::std::move(outer_attribs)) {}
-
- // Creates an empty StructPatternEtc
- static StructPatternEtc create_empty() {
- return StructPatternEtc(::std::vector<Attribute>());
- }
- };
-
- // Base class for a single field in a struct pattern - abstract
- class StructPatternField {
- ::std::vector<Attribute> outer_attrs;
- /*union {
- struct {
- //TupleIndex index;
- Pattern tuple_pattern;
- } tuple_pattern;
- struct {
- //Identifier ident;
- Pattern ident_pattern;
- } ident_pattern;
- struct {
- bool has_ref;
- bool has_mut;
- //Identifier ident;
- } ident;
- } pattern;*/
-
- Location locus;
-
- public:
- virtual ~StructPatternField() {}
-
- // Unique pointer custom clone function
- ::std::unique_ptr<StructPatternField> clone_struct_pattern_field() const {
- return ::std::unique_ptr<StructPatternField>(clone_struct_pattern_field_impl());
- }
-
- virtual ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- protected:
- StructPatternField(::std::vector<Attribute> outer_attribs, Location locus) :
- outer_attrs(::std::move(outer_attribs)), locus(locus) {}
-
- // Clone function implementation as pure virtual method
- virtual StructPatternField* clone_struct_pattern_field_impl() const = 0;
- };
-
- // Tuple pattern single field in a struct pattern
- class StructPatternFieldTuplePat : public StructPatternField {
- TupleIndex index;
- // Pattern* tuple_pattern;
- ::std::unique_ptr<Pattern> tuple_pattern;
-
- public:
- /*~StructPatternFieldTuplePat() {
- delete tuple_pattern;
- }*/
-
- StructPatternFieldTuplePat(TupleIndex index, ::std::unique_ptr<Pattern> tuple_pattern,
- ::std::vector<Attribute> outer_attribs, Location locus) :
- StructPatternField(::std::move(outer_attribs), locus),
- index(index), tuple_pattern(::std::move(tuple_pattern)) {}
-
- // Copy constructor requires clone
- StructPatternFieldTuplePat(StructPatternFieldTuplePat const& other) :
- StructPatternField(other), index(other.index),
- tuple_pattern(other.tuple_pattern->clone_pattern()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to perform clone
- StructPatternFieldTuplePat& operator=(StructPatternFieldTuplePat const& other) {
- StructPatternField::operator=(other);
- tuple_pattern = other.tuple_pattern->clone_pattern();
- index = other.index;
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // default move semantics
- StructPatternFieldTuplePat(StructPatternFieldTuplePat&& other) = default;
- StructPatternFieldTuplePat& operator=(StructPatternFieldTuplePat&& other) = default;
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructPatternFieldTuplePat* clone_struct_pattern_field_impl() const OVERRIDE {
- return new StructPatternFieldTuplePat(*this);
- }
- };
-
- // Identifier pattern single field in a struct pattern
- class StructPatternFieldIdentPat : public StructPatternField {
- Identifier ident;
- // Pattern* ident_pattern;
- ::std::unique_ptr<Pattern> ident_pattern;
-
- public:
- /*~StructPatternFieldIdentPat() {
- delete ident_pattern;
- }*/
-
- StructPatternFieldIdentPat(Identifier ident, ::std::unique_ptr<Pattern> ident_pattern,
- ::std::vector<Attribute> outer_attrs, Location locus) :
- StructPatternField(::std::move(outer_attrs), locus),
- ident(::std::move(ident)), ident_pattern(::std::move(ident_pattern)) {}
-
- // Copy constructor requires clone
- StructPatternFieldIdentPat(StructPatternFieldIdentPat const& other) :
- StructPatternField(other), ident(other.ident),
- ident_pattern(other.ident_pattern->clone_pattern()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone
- StructPatternFieldIdentPat& operator=(StructPatternFieldIdentPat const& other) {
- StructPatternField::operator=(other);
- ident = other.ident;
- ident_pattern = other.ident_pattern->clone_pattern();
- // outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // default move semantics
- StructPatternFieldIdentPat(StructPatternFieldIdentPat&& other) = default;
- StructPatternFieldIdentPat& operator=(StructPatternFieldIdentPat&& other) = default;
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructPatternFieldIdentPat* clone_struct_pattern_field_impl() const OVERRIDE {
- return new StructPatternFieldIdentPat(*this);
- }
- };
-
- // Identifier only (with no pattern) single field in a struct pattern
- class StructPatternFieldIdent : public StructPatternField {
- bool has_ref;
- bool has_mut;
-
- Identifier ident;
-
- public:
- StructPatternFieldIdent(Identifier ident, bool is_ref, bool is_mut,
- ::std::vector<Attribute> outer_attrs, Location locus) :
- StructPatternField(::std::move(outer_attrs), locus),
- has_ref(is_ref), has_mut(is_mut), ident(::std::move(ident)) {}
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructPatternFieldIdent* clone_struct_pattern_field_impl() const OVERRIDE {
- return new StructPatternFieldIdent(*this);
- }
- };
-
- // Elements of a struct pattern
- struct StructPatternElements {
- private:
- // bool has_struct_pattern_fields;
- //::std::vector<StructPatternField> fields;
- ::std::vector< ::std::unique_ptr<StructPatternField> > fields;
-
- bool has_struct_pattern_etc;
- StructPatternEtc etc;
-
- // must have at least one of the two and maybe both
-
- // should this store location data?
-
- public:
- // Returns whether there are any struct pattern fields
- inline bool has_struct_pattern_fields() const {
- return !fields.empty();
- }
-
- // Returns whether the struct pattern elements is entirely empty (no fields, no etc).
- inline bool is_empty() const {
- return !has_struct_pattern_fields() && !has_struct_pattern_etc;
- }
-
- // Constructor for StructPatternElements with both (potentially)
- StructPatternElements(
- ::std::vector< ::std::unique_ptr<StructPatternField> > fields, StructPatternEtc etc) :
- fields(::std::move(fields)),
- has_struct_pattern_etc(true), etc(::std::move(etc)) {}
-
- // Constructor for StructPatternElements with no StructPatternEtc
- StructPatternElements(::std::vector< ::std::unique_ptr<StructPatternField> > fields) :
- fields(::std::move(fields)), has_struct_pattern_etc(false),
- etc(StructPatternEtc::create_empty()) {}
-
- // Copy constructor with vector clone
- StructPatternElements(StructPatternElements const& other) :
- has_struct_pattern_etc(other.has_struct_pattern_etc), etc(other.etc) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- fields.reserve(other.fields.size());
-
- for (const auto& e : other.fields) {
- fields.push_back(e->clone_struct_pattern_field());
- }
- }
-
- // Overloaded assignment operator with vector clone
- StructPatternElements& operator=(StructPatternElements const& other) {
- etc = other.etc;
- has_struct_pattern_etc = other.has_struct_pattern_etc;
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- fields.reserve(other.fields.size());
-
- for (const auto& e : other.fields) {
- fields.push_back(e->clone_struct_pattern_field());
- }
-
- return *this;
- }
-
- // move constructors
- StructPatternElements(StructPatternElements&& other) = default;
- StructPatternElements& operator=(StructPatternElements&& other) = default;
-
- // Creates an empty StructPatternElements
- static StructPatternElements create_empty() {
- return StructPatternElements(
- ::std::vector< ::std::unique_ptr<StructPatternField> >());
- }
-
- ::std::string as_string() const;
- };
+// Class representing TuplePattern patterns where there is only a single pattern
+/*class TuplePatternItemsSingle : public TuplePatternItems {
+ // Pattern pattern;
+ ::std::unique_ptr<Pattern> pattern;
- // Struct pattern AST node representation
- class StructPattern : public Pattern {
- PathInExpression path;
-
- // bool has_struct_pattern_elements;
- StructPatternElements elems;
-
- // TODO: should this store location data? Accessor uses path location data.
-
- public:
- ::std::string as_string() const;
-
- // Constructs a struct pattern from specified StructPatternElements
- StructPattern(PathInExpression struct_path,
- StructPatternElements elems = StructPatternElements::create_empty()) :
- path(::std::move(struct_path)),
- elems(::std::move(elems)) {}
-
- // TODO: constructor to construct via elements included in StructPatternElements
-
- // Returns whether struct pattern has any struct pattern elements (if not, it is empty).
- inline bool has_struct_pattern_elems() const {
- return !elems.is_empty();
- }
-
- Location get_locus() const {
- return path.get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual StructPattern* clone_pattern_impl() const OVERRIDE {
- return new StructPattern(*this);
- }
- };
-
- // Base abstract class for patterns used in TupleStructPattern
- class TupleStructItems {
- public:
- virtual ~TupleStructItems() {}
-
- // TODO: should this store location data?
-
- // Unique pointer custom clone function
- ::std::unique_ptr<TupleStructItems> clone_tuple_struct_items() const {
- return ::std::unique_ptr<TupleStructItems>(clone_tuple_struct_items_impl());
- }
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- protected:
- // pure virtual clone implementation
- virtual TupleStructItems* clone_tuple_struct_items_impl() const = 0;
- };
-
- // Class for non-ranged tuple struct pattern patterns
- class TupleStructItemsNoRange : public TupleStructItems {
- //::std::vector<Pattern> patterns;
- ::std::vector< ::std::unique_ptr<Pattern> > patterns;
+ public:
+ TuplePatternItemsSingle(Pattern* pattern) : pattern(pattern) {}
- public:
- TupleStructItemsNoRange(::std::vector< ::std::unique_ptr<Pattern> > patterns) :
- patterns(::std::move(patterns)) {}
-
- // Copy constructor with vector clone
- TupleStructItemsNoRange(TupleStructItemsNoRange const& other) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- patterns.reserve(other.patterns.size());
-
- for (const auto& e : other.patterns) {
- patterns.push_back(e->clone_pattern());
- }
- }
+ // Copy constructor uses clone
+ TuplePatternItemsSingle(TuplePatternItemsSingle const& other) :
+ pattern(other.pattern->clone_pattern()) {}
- // Overloaded assignment operator with vector clone
- TupleStructItemsNoRange& operator=(TupleStructItemsNoRange const& other) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- patterns.reserve(other.patterns.size());
+ // Destructor - define here if required
- for (const auto& e : other.patterns) {
- patterns.push_back(e->clone_pattern());
- }
-
- return *this;
- }
-
- // move constructors
- TupleStructItemsNoRange(TupleStructItemsNoRange&& other) = default;
- TupleStructItemsNoRange& operator=(TupleStructItemsNoRange&& other) = default;
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TupleStructItemsNoRange* clone_tuple_struct_items_impl() const OVERRIDE {
- return new TupleStructItemsNoRange(*this);
- }
- };
-
- // Class for ranged tuple struct pattern patterns
- class TupleStructItemsRange : public TupleStructItems {
- /*::std::vector<Pattern> lower_patterns;
- ::std::vector<Pattern> upper_patterns;*/
- ::std::vector< ::std::unique_ptr<Pattern> > lower_patterns;
- ::std::vector< ::std::unique_ptr<Pattern> > upper_patterns;
-
- public:
- TupleStructItemsRange(::std::vector< ::std::unique_ptr<Pattern> > lower_patterns,
- ::std::vector< ::std::unique_ptr<Pattern> > upper_patterns) :
- lower_patterns(::std::move(lower_patterns)),
- upper_patterns(::std::move(upper_patterns)) {}
-
- // Copy constructor with vector clone
- TupleStructItemsRange(TupleStructItemsRange const& other) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- lower_patterns.reserve(other.lower_patterns.size());
-
- for (const auto& e : other.lower_patterns) {
- lower_patterns.push_back(e->clone_pattern());
- }
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- upper_patterns.reserve(other.upper_patterns.size());
-
- for (const auto& e : other.upper_patterns) {
- upper_patterns.push_back(e->clone_pattern());
- }
- }
-
- // Overloaded assignment operator to clone
- TupleStructItemsRange& operator=(TupleStructItemsRange const& other) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- lower_patterns.reserve(other.lower_patterns.size());
-
- for (const auto& e : other.lower_patterns) {
- lower_patterns.push_back(e->clone_pattern());
- }
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- upper_patterns.reserve(other.upper_patterns.size());
-
- for (const auto& e : other.upper_patterns) {
- upper_patterns.push_back(e->clone_pattern());
- }
-
- return *this;
- }
-
- // move constructors
- TupleStructItemsRange(TupleStructItemsRange&& other) = default;
- TupleStructItemsRange& operator=(TupleStructItemsRange&& other) = default;
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TupleStructItemsRange* clone_tuple_struct_items_impl() const OVERRIDE {
- return new TupleStructItemsRange(*this);
- }
- };
-
- // AST node representing a tuple struct pattern
- class TupleStructPattern : public Pattern {
- PathInExpression path;
- // TupleStructItems items;
- ::std::unique_ptr<TupleStructItems> items;
-
- // TOOD: should this store location data? current accessor uses path location data
-
- public:
- ::std::string as_string() const;
-
- TupleStructPattern(
- PathInExpression tuple_struct_path, ::std::unique_ptr<TupleStructItems> items) :
- path(::std::move(tuple_struct_path)),
- items(::std::move(items)) {}
-
- // Copy constructor required to clone
- TupleStructPattern(TupleStructPattern const& other) :
- path(other.path), items(other.items->clone_tuple_struct_items()) {}
-
- // Destructor - define here if required
-
- // Operator overload assignment operator to clone
- TupleStructPattern& operator=(TupleStructPattern const& other) {
- path = other.path;
- items = other.items->clone_tuple_struct_items();
-
- return *this;
- }
-
- // move constructors
- TupleStructPattern(TupleStructPattern&& other) = default;
- TupleStructPattern& operator=(TupleStructPattern&& other) = default;
-
- Location get_locus() const {
- return path.get_locus();
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TupleStructPattern* clone_pattern_impl() const OVERRIDE {
- return new TupleStructPattern(*this);
- }
- };
-
- // Base abstract class representing TuplePattern patterns
- class TuplePatternItems {
- public:
- virtual ~TuplePatternItems() {}
-
- // TODO: should this store location data?
-
- // Unique pointer custom clone function
- ::std::unique_ptr<TuplePatternItems> clone_tuple_pattern_items() const {
- return ::std::unique_ptr<TuplePatternItems>(clone_tuple_pattern_items_impl());
- }
-
- virtual ::std::string as_string() const = 0;
-
- virtual void accept_vis(ASTVisitor& vis) = 0;
-
- protected:
- // pure virtual clone implementation
- virtual TuplePatternItems* clone_tuple_pattern_items_impl() const = 0;
- };
-
- // Class representing TuplePattern patterns where there is only a single pattern
- /*class TuplePatternItemsSingle : public TuplePatternItems {
- // Pattern pattern;
- ::std::unique_ptr<Pattern> pattern;
-
- public:
- TuplePatternItemsSingle(Pattern* pattern) : pattern(pattern) {}
-
- // Copy constructor uses clone
- TuplePatternItemsSingle(TuplePatternItemsSingle const& other) :
- pattern(other.pattern->clone_pattern()) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone
- TuplePatternItemsSingle& operator=(TuplePatternItemsSingle const& other) {
- pattern = other.pattern->clone_pattern();
-
- return *this;
- }
-
- // move constructors
- TuplePatternItemsSingle(TuplePatternItemsSingle&& other) = default;
- TuplePatternItemsSingle& operator=(TuplePatternItemsSingle&& other) = default;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TuplePatternItemsSingle* clone_tuple_pattern_items_impl() const OVERRIDE {
- return new TuplePatternItemsSingle(*this);
- }
- };*/
- // removed in favour of single-element TuplePatternItemsMultiple
-
- // Class representing TuplePattern patterns where there are multiple patterns
- class TuplePatternItemsMultiple : public TuplePatternItems {
- //::std::vector<Pattern> patterns;
- ::std::vector< ::std::unique_ptr<Pattern> > patterns;
-
- public:
- TuplePatternItemsMultiple(::std::vector< ::std::unique_ptr<Pattern> > patterns) :
- patterns(::std::move(patterns)) {}
-
- // Copy constructor with vector clone
- TuplePatternItemsMultiple(TuplePatternItemsMultiple const& other) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- patterns.reserve(other.patterns.size());
-
- for (const auto& e : other.patterns) {
- patterns.push_back(e->clone_pattern());
- }
- }
-
- // Overloaded assignment operator to vector clone
- TuplePatternItemsMultiple& operator=(TuplePatternItemsMultiple const& other) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- patterns.reserve(other.patterns.size());
-
- for (const auto& e : other.patterns) {
- patterns.push_back(e->clone_pattern());
- }
-
- return *this;
- }
-
- // move constructors
- TuplePatternItemsMultiple(TuplePatternItemsMultiple&& other) = default;
- TuplePatternItemsMultiple& operator=(TuplePatternItemsMultiple&& other) = default;
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TuplePatternItemsMultiple* clone_tuple_pattern_items_impl() const OVERRIDE {
- return new TuplePatternItemsMultiple(*this);
- }
- };
-
- // Class representing TuplePattern patterns where there are a range of patterns
- class TuplePatternItemsRanged : public TuplePatternItems {
- /*::std::vector<Pattern> lower_patterns;
- ::std::vector<Pattern> upper_patterns;*/
- ::std::vector< ::std::unique_ptr<Pattern> > lower_patterns;
- ::std::vector< ::std::unique_ptr<Pattern> > upper_patterns;
-
- public:
- TuplePatternItemsRanged(::std::vector< ::std::unique_ptr<Pattern> > lower_patterns,
- ::std::vector< ::std::unique_ptr<Pattern> > upper_patterns) :
- lower_patterns(::std::move(lower_patterns)),
- upper_patterns(::std::move(upper_patterns)) {}
-
- // Copy constructor with vector clone
- TuplePatternItemsRanged(TuplePatternItemsRanged const& other) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- lower_patterns.reserve(other.lower_patterns.size());
-
- for (const auto& e : other.lower_patterns) {
- lower_patterns.push_back(e->clone_pattern());
- }
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- upper_patterns.reserve(other.upper_patterns.size());
-
- for (const auto& e : other.upper_patterns) {
- upper_patterns.push_back(e->clone_pattern());
- }
- }
-
- // Overloaded assignment operator to clone
- TuplePatternItemsRanged& operator=(TuplePatternItemsRanged const& other) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- lower_patterns.reserve(other.lower_patterns.size());
-
- for (const auto& e : other.lower_patterns) {
- lower_patterns.push_back(e->clone_pattern());
- }
-
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- upper_patterns.reserve(other.upper_patterns.size());
-
- for (const auto& e : other.upper_patterns) {
- upper_patterns.push_back(e->clone_pattern());
- }
-
- return *this;
- }
-
- // move constructors
- TuplePatternItemsRanged(TuplePatternItemsRanged&& other) = default;
- TuplePatternItemsRanged& operator=(TuplePatternItemsRanged&& other) = default;
-
- ::std::string as_string() const;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TuplePatternItemsRanged* clone_tuple_pattern_items_impl() const OVERRIDE {
- return new TuplePatternItemsRanged(*this);
- }
- };
-
- // AST node representing a tuple pattern
- class TuplePattern : public Pattern {
- // bool has_tuple_pattern_items;
- // TuplePatternItems items;
- ::std::unique_ptr<TuplePatternItems> items;
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- // Returns true if the tuple pattern has items
- inline bool has_tuple_pattern_items() const {
- return items != NULL;
- }
-
- TuplePattern(::std::unique_ptr<TuplePatternItems> items, Location locus) :
- items(::std::move(items)), locus(locus) {}
-
- // Copy constructor requires clone
- TuplePattern(TuplePattern const& other) :
- items(other.items->clone_tuple_pattern_items()), locus(other.locus) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone
- TuplePattern& operator=(TuplePattern const& other) {
- items = other.items->clone_tuple_pattern_items();
- locus = other.locus;
-
- return *this;
- }
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TuplePattern* clone_pattern_impl() const OVERRIDE {
- return new TuplePattern(*this);
- }
- };
-
- // AST node representing a pattern in parentheses, used to control precedence
- class GroupedPattern : public Pattern {
- // Pattern pattern_in_parens;
- ::std::unique_ptr<Pattern> pattern_in_parens;
-
- Location locus;
-
- public:
- ::std::string as_string() const {
- return "(" + pattern_in_parens->as_string() + ")";
- }
-
- GroupedPattern(::std::unique_ptr<Pattern> pattern_in_parens, Location locus) :
- pattern_in_parens(::std::move(pattern_in_parens)), locus(locus) {}
-
- // Copy constructor uses clone
- GroupedPattern(GroupedPattern const& other) :
- pattern_in_parens(other.pattern_in_parens->clone_pattern()), locus(other.locus) {}
-
- // Destructor - define here if required
-
- // Overload assignment operator to clone
- GroupedPattern& operator=(GroupedPattern const& other) {
- pattern_in_parens = other.pattern_in_parens->clone_pattern();
- locus = other.locus;
-
- return *this;
- }
-
- // default move semantics
- GroupedPattern(GroupedPattern&& other) = default;
- GroupedPattern& operator=(GroupedPattern&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual GroupedPattern* clone_pattern_impl() const OVERRIDE {
- return new GroupedPattern(*this);
- }
- };
-
- // AST node representing patterns that can match slices and arrays
- class SlicePattern : public Pattern {
- //::std::vector<Pattern> items;
- ::std::vector< ::std::unique_ptr<Pattern> > items;
-
- Location locus;
-
- public:
- ::std::string as_string() const;
-
- SlicePattern(::std::vector< ::std::unique_ptr<Pattern> > items, Location locus) :
- items(::std::move(items)), locus(locus) {}
-
- // Copy constructor with vector clone
- SlicePattern(SlicePattern const& other) : locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- items.reserve(other.items.size());
-
- for (const auto& e : other.items) {
- items.push_back(e->clone_pattern());
- }
- }
-
- // Overloaded assignment operator to vector clone
- SlicePattern& operator=(SlicePattern const& other) {
- locus = other.locus;
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- items.reserve(other.items.size());
-
- for (const auto& e : other.items) {
- items.push_back(e->clone_pattern());
- }
-
- return *this;
- }
-
- // move constructors
- SlicePattern(SlicePattern&& other) = default;
- SlicePattern& operator=(SlicePattern&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual SlicePattern* clone_pattern_impl() const OVERRIDE {
- return new SlicePattern(*this);
- }
- };
-
- // forward decl PathExprSegment
- // class PathExprSegment;
-
- // Moved definition to rust-path.h
- class PathPattern;
+ // Overload assignment operator to clone
+ TuplePatternItemsSingle& operator=(TuplePatternItemsSingle const& other) {
+ pattern = other.pattern->clone_pattern();
+
+ return *this;
+ }
- // Forward decls for paths (defined in rust-path.h)
- class PathInExpression;
- class QualifiedPathInExpression;
+ // move constructors
+ TuplePatternItemsSingle(TuplePatternItemsSingle&& other) = default;
+ TuplePatternItemsSingle& operator=(TuplePatternItemsSingle&& other) =
+default;
- // Replaced with forward decl - defined in rust-macro.h
- class MacroInvocation;
- /*class MacroInvocation : public Pattern {
- public:
- ::std::string as_string() const;
- };*/
+ protected:
+ // Use covariance to implement clone function as returning this object
+rather than base virtual TuplePatternItemsSingle*
+clone_tuple_pattern_items_impl() const OVERRIDE { return new
+TuplePatternItemsSingle(*this);
}
-}
+};*/
+// removed in favour of single-element TuplePatternItemsMultiple
+
+// Class representing TuplePattern patterns where there are multiple patterns
+class TuplePatternItemsMultiple : public TuplePatternItems
+{
+ //::std::vector<Pattern> patterns;
+ ::std::vector< ::std::unique_ptr<Pattern> > patterns;
+
+public:
+ TuplePatternItemsMultiple (
+ ::std::vector< ::std::unique_ptr<Pattern> > patterns)
+ : patterns (::std::move (patterns))
+ {}
+
+ // Copy constructor with vector clone
+ TuplePatternItemsMultiple (TuplePatternItemsMultiple const &other)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ patterns.reserve (other.patterns.size ());
+
+ for (const auto &e : other.patterns)
+ {
+ patterns.push_back (e->clone_pattern ());
+ }
+ }
+
+ // Overloaded assignment operator to vector clone
+ TuplePatternItemsMultiple &operator= (TuplePatternItemsMultiple const &other)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ patterns.reserve (other.patterns.size ());
+
+ for (const auto &e : other.patterns)
+ {
+ patterns.push_back (e->clone_pattern ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ TuplePatternItemsMultiple (TuplePatternItemsMultiple &&other) = default;
+ TuplePatternItemsMultiple &operator= (TuplePatternItemsMultiple &&other)
+ = default;
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TuplePatternItemsMultiple *
+ clone_tuple_pattern_items_impl () const OVERRIDE
+ {
+ return new TuplePatternItemsMultiple (*this);
+ }
+};
+
+// Class representing TuplePattern patterns where there are a range of patterns
+class TuplePatternItemsRanged : public TuplePatternItems
+{
+ /*::std::vector<Pattern> lower_patterns;
+ ::std::vector<Pattern> upper_patterns;*/
+ ::std::vector< ::std::unique_ptr<Pattern> > lower_patterns;
+ ::std::vector< ::std::unique_ptr<Pattern> > upper_patterns;
+
+public:
+ TuplePatternItemsRanged (
+ ::std::vector< ::std::unique_ptr<Pattern> > lower_patterns,
+ ::std::vector< ::std::unique_ptr<Pattern> > upper_patterns)
+ : lower_patterns (::std::move (lower_patterns)),
+ upper_patterns (::std::move (upper_patterns))
+ {}
+
+ // Copy constructor with vector clone
+ TuplePatternItemsRanged (TuplePatternItemsRanged const &other)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ lower_patterns.reserve (other.lower_patterns.size ());
+
+ for (const auto &e : other.lower_patterns)
+ {
+ lower_patterns.push_back (e->clone_pattern ());
+ }
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ upper_patterns.reserve (other.upper_patterns.size ());
+
+ for (const auto &e : other.upper_patterns)
+ {
+ upper_patterns.push_back (e->clone_pattern ());
+ }
+ }
+
+ // Overloaded assignment operator to clone
+ TuplePatternItemsRanged &operator= (TuplePatternItemsRanged const &other)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ lower_patterns.reserve (other.lower_patterns.size ());
+
+ for (const auto &e : other.lower_patterns)
+ {
+ lower_patterns.push_back (e->clone_pattern ());
+ }
+
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ upper_patterns.reserve (other.upper_patterns.size ());
+
+ for (const auto &e : other.upper_patterns)
+ {
+ upper_patterns.push_back (e->clone_pattern ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ TuplePatternItemsRanged (TuplePatternItemsRanged &&other) = default;
+ TuplePatternItemsRanged &operator= (TuplePatternItemsRanged &&other)
+ = default;
+
+ ::std::string as_string () const;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TuplePatternItemsRanged *
+ clone_tuple_pattern_items_impl () const OVERRIDE
+ {
+ return new TuplePatternItemsRanged (*this);
+ }
+};
+
+// AST node representing a tuple pattern
+class TuplePattern : public Pattern
+{
+ // bool has_tuple_pattern_items;
+ // TuplePatternItems items;
+ ::std::unique_ptr<TuplePatternItems> items;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ // Returns true if the tuple pattern has items
+ inline bool has_tuple_pattern_items () const { return items != NULL; }
+
+ TuplePattern (::std::unique_ptr<TuplePatternItems> items, Location locus)
+ : items (::std::move (items)), locus (locus)
+ {}
+
+ // Copy constructor requires clone
+ TuplePattern (TuplePattern const &other)
+ : items (other.items->clone_tuple_pattern_items ()), locus (other.locus)
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone
+ TuplePattern &operator= (TuplePattern const &other)
+ {
+ items = other.items->clone_tuple_pattern_items ();
+ locus = other.locus;
+
+ return *this;
+ }
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TuplePattern *clone_pattern_impl () const OVERRIDE
+ {
+ return new TuplePattern (*this);
+ }
+};
+
+// AST node representing a pattern in parentheses, used to control precedence
+class GroupedPattern : public Pattern
+{
+ // Pattern pattern_in_parens;
+ ::std::unique_ptr<Pattern> pattern_in_parens;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const
+ {
+ return "(" + pattern_in_parens->as_string () + ")";
+ }
+
+ GroupedPattern (::std::unique_ptr<Pattern> pattern_in_parens, Location locus)
+ : pattern_in_parens (::std::move (pattern_in_parens)), locus (locus)
+ {}
+
+ // Copy constructor uses clone
+ GroupedPattern (GroupedPattern const &other)
+ : pattern_in_parens (other.pattern_in_parens->clone_pattern ()),
+ locus (other.locus)
+ {}
+
+ // Destructor - define here if required
+
+ // Overload assignment operator to clone
+ GroupedPattern &operator= (GroupedPattern const &other)
+ {
+ pattern_in_parens = other.pattern_in_parens->clone_pattern ();
+ locus = other.locus;
+
+ return *this;
+ }
+
+ // default move semantics
+ GroupedPattern (GroupedPattern &&other) = default;
+ GroupedPattern &operator= (GroupedPattern &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual GroupedPattern *clone_pattern_impl () const OVERRIDE
+ {
+ return new GroupedPattern (*this);
+ }
+};
+
+// AST node representing patterns that can match slices and arrays
+class SlicePattern : public Pattern
+{
+ //::std::vector<Pattern> items;
+ ::std::vector< ::std::unique_ptr<Pattern> > items;
+
+ Location locus;
+
+public:
+ ::std::string as_string () const;
+
+ SlicePattern (::std::vector< ::std::unique_ptr<Pattern> > items,
+ Location locus)
+ : items (::std::move (items)), locus (locus)
+ {}
+
+ // Copy constructor with vector clone
+ SlicePattern (SlicePattern const &other) : locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ items.reserve (other.items.size ());
+
+ for (const auto &e : other.items)
+ {
+ items.push_back (e->clone_pattern ());
+ }
+ }
+
+ // Overloaded assignment operator to vector clone
+ SlicePattern &operator= (SlicePattern const &other)
+ {
+ locus = other.locus;
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ items.reserve (other.items.size ());
+
+ for (const auto &e : other.items)
+ {
+ items.push_back (e->clone_pattern ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ SlicePattern (SlicePattern &&other) = default;
+ SlicePattern &operator= (SlicePattern &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual SlicePattern *clone_pattern_impl () const OVERRIDE
+ {
+ return new SlicePattern (*this);
+ }
+};
+
+// forward decl PathExprSegment
+// class PathExprSegment;
+
+// Moved definition to rust-path.h
+class PathPattern;
+
+// Forward decls for paths (defined in rust-path.h)
+class PathInExpression;
+class QualifiedPathInExpression;
+
+// Replaced with forward decl - defined in rust-macro.h
+class MacroInvocation;
+/*class MacroInvocation : public Pattern {
+ public:
+ ::std::string as_string() const;
+};*/
+} // namespace AST
+} // namespace Rust
#endif
diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
index 767b620..08d5ff8 100644
--- a/gcc/rust/ast/rust-stmt.h
+++ b/gcc/rust/ast/rust-stmt.h
@@ -6,240 +6,254 @@
#include "rust-expr.h"
namespace Rust {
- namespace AST {
- // Just a semi-colon, which apparently is a statement.
- class EmptyStmt : public Stmt {
- Location locus;
-
- public:
- ::std::string as_string() const {
- return ::std::string(1, ';');
- }
-
- EmptyStmt(Location locus) : locus(locus) {}
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual EmptyStmt* clone_stmt_impl() const OVERRIDE {
- return new EmptyStmt(*this);
- }
- };
-
- /* This is syntactically identical to declaring an item inside a module BUT it has block
- * scope. Type of "declaration statement" as it introduces new name into scope */
- /*class ItemStatement : public Statement {
- // TODO: put in same params as regular item
- // maybe even merge data structure with module item?
-
- public:
- ::std::string as_string() const;
- };*/
- // removed - just made item inherit from statement
-
- /* Variable assignment let statement - type of "declaration statement" as it introduces new
- * name into scope */
- class LetStmt : public Stmt {
- // bool has_outer_attrs;
- ::std::vector<Attribute> outer_attrs;
-
- // Pattern variables_pattern;
- ::std::unique_ptr<Pattern> variables_pattern;
-
- // bool has_type;
- // Type type;
- ::std::unique_ptr<Type> type;
-
- // bool has_init_expr;
- // Expr* init_expr;
- ::std::unique_ptr<Expr> init_expr;
-
- Location locus;
-
- public:
- // Returns whether let statement has outer attributes.
- inline bool has_outer_attrs() const {
- return !outer_attrs.empty();
- }
-
- // Returns whether let statement has a given return type.
- inline bool has_type() const {
- return type != NULL;
- }
-
- // Returns whether let statement has an initialisation expression.
- inline bool has_init_expr() const {
- return init_expr != NULL;
- }
-
- /*~LetStatement() {
- if (has_init_expr) {
- delete init_expr;
- }
- }*/
-
- ::std::string as_string() const;
-
- LetStmt(::std::unique_ptr<Pattern> variables_pattern, ::std::unique_ptr<Expr> init_expr,
- ::std::unique_ptr<Type> type, ::std::vector<Attribute> outer_attrs, Location locus) :
- outer_attrs(::std::move(outer_attrs)),
- variables_pattern(::std::move(variables_pattern)), type(::std::move(type)),
- init_expr(::std::move(init_expr)), locus(locus) {}
-
- // Copy constructor with clone
- LetStmt(LetStmt const& other) :
- outer_attrs(other.outer_attrs),
- variables_pattern(other.variables_pattern->clone_pattern()),
- type(other.type->clone_type()), init_expr(other.init_expr->clone_expr()),
- locus(other.locus) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone
- LetStmt& operator=(LetStmt const& other) {
- variables_pattern = other.variables_pattern->clone_pattern();
- init_expr = other.init_expr->clone_expr();
- type = other.type->clone_type();
- outer_attrs = other.outer_attrs;
- locus = other.locus;
-
- return *this;
- }
-
- // move constructors
- LetStmt(LetStmt&& other) = default;
- LetStmt& operator=(LetStmt&& other) = default;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual LetStmt* clone_stmt_impl() const OVERRIDE {
- return new LetStmt(*this);
- }
- };
-
- // Abstract base class for expression statements (statements containing an expression)
- class ExprStmt : public Stmt {
- // TODO: add any useful virtual functions
-
- Location locus;
-
- public:
- Location get_locus() const {
- return locus;
- }
-
- protected:
- ExprStmt(Location locus) : locus(locus) {}
- };
-
- /* Statement containing an expression without a block (or, due to technical difficulties, can
- * only be guaranteed to hold an expression). */
- class ExprStmtWithoutBlock : public ExprStmt {
- // ExprWithoutBlock* expr;
- /* HACK: cannot ensure type safety of ExprWithoutBlock due to Pratt parsing, so have to
- * store more general type of Expr. FIXME: fix this issue somehow or redesign AST. */
- //::std::unique_ptr<ExprWithoutBlock> expr;
- ::std::unique_ptr<Expr> expr;
-
- public:
- /*~ExpressionStatementWithoutBlock() {
- delete expr;
- }*/
-
- ::std::string as_string() const;
-
- // ExprStmtWithoutBlock(::std::unique_ptr<ExprWithoutBlock> expr) :
- // expr(::std::move(expr)) {}
- ExprStmtWithoutBlock(::std::unique_ptr<Expr> expr, Location locus) :
- ExprStmt(locus), expr(::std::move(expr)) {}
-
- // Copy constructor with clone
- ExprStmtWithoutBlock(ExprStmtWithoutBlock const& other) :
- ExprStmt(other), expr(other.expr->clone_expr /*_without_block*/ ()) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone
- ExprStmtWithoutBlock& operator=(ExprStmtWithoutBlock const& other) {
- ExprStmt::operator=(other);
- expr = other.expr->clone_expr /*_without_block*/ ();
-
- return *this;
- }
-
- // move constructors
- ExprStmtWithoutBlock(ExprStmtWithoutBlock&& other) = default;
- ExprStmtWithoutBlock& operator=(ExprStmtWithoutBlock&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ExprStmtWithoutBlock* clone_stmt_impl() const OVERRIDE {
- return new ExprStmtWithoutBlock(*this);
- }
- };
-
- // Statement containing an expression with a block
- class ExprStmtWithBlock : public ExprStmt {
- // ExprWithBlock* expr;
- ::std::unique_ptr<ExprWithBlock> expr;
-
- public:
- /*~ExpressionStatementWithBlock() {
- delete expr;
- }*/
-
- ::std::string as_string() const;
-
- ExprStmtWithBlock(::std::unique_ptr<ExprWithBlock> expr, Location locus) :
- ExprStmt(locus), expr(::std::move(expr)) {}
-
- // Copy constructor with clone
- ExprStmtWithBlock(ExprStmtWithBlock const& other) :
- ExprStmt(other), expr(other.expr->clone_expr_with_block()) {}
-
- // Destructor - define here if required
-
- // Overloaded assignment operator to clone
- ExprStmtWithBlock& operator=(ExprStmtWithBlock const& other) {
- ExprStmt::operator=(other);
- expr = other.expr->clone_expr_with_block();
-
- return *this;
- }
-
- // move constructors
- ExprStmtWithBlock(ExprStmtWithBlock&& other) = default;
- ExprStmtWithBlock& operator=(ExprStmtWithBlock&& other) = default;
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ExprStmtWithBlock* clone_stmt_impl() const OVERRIDE {
- return new ExprStmtWithBlock(*this);
- }
- };
-
- // Replaced definition of MacroInvocationSemi with forward decl - defined in rust-macro.h
- class MacroInvocationSemi;
- /*class MacroInvocationSemi : public Statement {
- public:
- ::std::string as_string() const;
- };*/
- }
-}
+namespace AST {
+// Just a semi-colon, which apparently is a statement.
+class EmptyStmt : public Stmt
+{
+ Location locus;
+
+public:
+ ::std::string as_string () const { return ::std::string (1, ';'); }
+
+ EmptyStmt (Location locus) : locus (locus) {}
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual EmptyStmt *clone_stmt_impl () const OVERRIDE
+ {
+ return new EmptyStmt (*this);
+ }
+};
+
+/* This is syntactically identical to declaring an item inside a module BUT it
+ * has block scope. Type of "declaration statement" as it introduces new name
+ * into scope */
+/*class ItemStatement : public Statement {
+ // TODO: put in same params as regular item
+ // maybe even merge data structure with module item?
+
+ public:
+ ::std::string as_string() const;
+};*/
+// removed - just made item inherit from statement
+
+/* Variable assignment let statement - type of "declaration statement" as it
+ * introduces new name into scope */
+class LetStmt : public Stmt
+{
+ // bool has_outer_attrs;
+ ::std::vector<Attribute> outer_attrs;
+
+ // Pattern variables_pattern;
+ ::std::unique_ptr<Pattern> variables_pattern;
+
+ // bool has_type;
+ // Type type;
+ ::std::unique_ptr<Type> type;
+
+ // bool has_init_expr;
+ // Expr* init_expr;
+ ::std::unique_ptr<Expr> init_expr;
+
+ Location locus;
+
+public:
+ // Returns whether let statement has outer attributes.
+ inline bool has_outer_attrs () const { return !outer_attrs.empty (); }
+
+ // Returns whether let statement has a given return type.
+ inline bool has_type () const { return type != NULL; }
+
+ // Returns whether let statement has an initialisation expression.
+ inline bool has_init_expr () const { return init_expr != NULL; }
+
+ /*~LetStatement() {
+ if (has_init_expr) {
+ delete init_expr;
+ }
+ }*/
+
+ ::std::string as_string () const;
+
+ LetStmt (::std::unique_ptr<Pattern> variables_pattern,
+ ::std::unique_ptr<Expr> init_expr, ::std::unique_ptr<Type> type,
+ ::std::vector<Attribute> outer_attrs, Location locus)
+ : outer_attrs (::std::move (outer_attrs)),
+ variables_pattern (::std::move (variables_pattern)),
+ type (::std::move (type)), init_expr (::std::move (init_expr)),
+ locus (locus)
+ {}
+
+ // Copy constructor with clone
+ LetStmt (LetStmt const &other)
+ : outer_attrs (other.outer_attrs),
+ variables_pattern (other.variables_pattern->clone_pattern ()),
+ type (other.type->clone_type ()),
+ init_expr (other.init_expr->clone_expr ()), locus (other.locus)
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone
+ LetStmt &operator= (LetStmt const &other)
+ {
+ variables_pattern = other.variables_pattern->clone_pattern ();
+ init_expr = other.init_expr->clone_expr ();
+ type = other.type->clone_type ();
+ outer_attrs = other.outer_attrs;
+ locus = other.locus;
+
+ return *this;
+ }
+
+ // move constructors
+ LetStmt (LetStmt &&other) = default;
+ LetStmt &operator= (LetStmt &&other) = default;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual LetStmt *clone_stmt_impl () const OVERRIDE
+ {
+ return new LetStmt (*this);
+ }
+};
+
+// Abstract base class for expression statements (statements containing an
+// expression)
+class ExprStmt : public Stmt
+{
+ // TODO: add any useful virtual functions
+
+ Location locus;
+
+public:
+ Location get_locus () const { return locus; }
+
+protected:
+ ExprStmt (Location locus) : locus (locus) {}
+};
+
+/* Statement containing an expression without a block (or, due to technical
+ * difficulties, can only be guaranteed to hold an expression). */
+class ExprStmtWithoutBlock : public ExprStmt
+{
+ // ExprWithoutBlock* expr;
+ /* HACK: cannot ensure type safety of ExprWithoutBlock due to Pratt parsing,
+ * so have to store more general type of Expr. FIXME: fix this issue somehow
+ * or redesign AST. */
+ //::std::unique_ptr<ExprWithoutBlock> expr;
+ ::std::unique_ptr<Expr> expr;
+
+public:
+ /*~ExpressionStatementWithoutBlock() {
+ delete expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ // ExprStmtWithoutBlock(::std::unique_ptr<ExprWithoutBlock> expr) :
+ // expr(::std::move(expr)) {}
+ ExprStmtWithoutBlock (::std::unique_ptr<Expr> expr, Location locus)
+ : ExprStmt (locus), expr (::std::move (expr))
+ {}
+
+ // Copy constructor with clone
+ ExprStmtWithoutBlock (ExprStmtWithoutBlock const &other)
+ : ExprStmt (other), expr (other.expr->clone_expr /*_without_block*/ ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone
+ ExprStmtWithoutBlock &operator= (ExprStmtWithoutBlock const &other)
+ {
+ ExprStmt::operator= (other);
+ expr = other.expr->clone_expr /*_without_block*/ ();
+
+ return *this;
+ }
+
+ // move constructors
+ ExprStmtWithoutBlock (ExprStmtWithoutBlock &&other) = default;
+ ExprStmtWithoutBlock &operator= (ExprStmtWithoutBlock &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ExprStmtWithoutBlock *clone_stmt_impl () const OVERRIDE
+ {
+ return new ExprStmtWithoutBlock (*this);
+ }
+};
+
+// Statement containing an expression with a block
+class ExprStmtWithBlock : public ExprStmt
+{
+ // ExprWithBlock* expr;
+ ::std::unique_ptr<ExprWithBlock> expr;
+
+public:
+ /*~ExpressionStatementWithBlock() {
+ delete expr;
+ }*/
+
+ ::std::string as_string () const;
+
+ ExprStmtWithBlock (::std::unique_ptr<ExprWithBlock> expr, Location locus)
+ : ExprStmt (locus), expr (::std::move (expr))
+ {}
+
+ // Copy constructor with clone
+ ExprStmtWithBlock (ExprStmtWithBlock const &other)
+ : ExprStmt (other), expr (other.expr->clone_expr_with_block ())
+ {}
+
+ // Destructor - define here if required
+
+ // Overloaded assignment operator to clone
+ ExprStmtWithBlock &operator= (ExprStmtWithBlock const &other)
+ {
+ ExprStmt::operator= (other);
+ expr = other.expr->clone_expr_with_block ();
+
+ return *this;
+ }
+
+ // move constructors
+ ExprStmtWithBlock (ExprStmtWithBlock &&other) = default;
+ ExprStmtWithBlock &operator= (ExprStmtWithBlock &&other) = default;
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ExprStmtWithBlock *clone_stmt_impl () const OVERRIDE
+ {
+ return new ExprStmtWithBlock (*this);
+ }
+};
+
+// Replaced definition of MacroInvocationSemi with forward decl - defined in
+// rust-macro.h
+class MacroInvocationSemi;
+/*class MacroInvocationSemi : public Statement {
+ public:
+ ::std::string as_string() const;
+};*/
+} // namespace AST
+} // namespace Rust
#endif
diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h
index 2ca973a..cacdd55 100644
--- a/gcc/rust/ast/rust-type.h
+++ b/gcc/rust/ast/rust-type.h
@@ -5,824 +5,916 @@
#include "rust-path.h"
namespace Rust {
- namespace AST {
- // definitions moved to rust-ast.h
- class TypeParamBound;
- class Lifetime;
-
- // A trait bound
- class TraitBound : public TypeParamBound {
- bool in_parens;
- bool opening_question_mark;
-
- // bool has_for_lifetimes;
- // LifetimeParams for_lifetimes;
- ::std::vector<LifetimeParam> for_lifetimes; // inlined LifetimeParams
-
- TypePath type_path;
-
- Location locus;
-
- public:
- // Returns whether trait bound has "for" lifetimes
- inline bool has_for_lifetimes() const {
- return !for_lifetimes.empty();
- }
-
- TraitBound(TypePath type_path, Location locus, bool in_parens = false,
- bool opening_question_mark = false,
- ::std::vector<LifetimeParam> for_lifetimes = ::std::vector<LifetimeParam>()) :
- in_parens(in_parens),
- opening_question_mark(opening_question_mark), for_lifetimes(::std::move(for_lifetimes)),
- type_path(::std::move(type_path)), locus(locus) {}
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Clone function implementation as (not pure) virtual method
- virtual TraitBound* clone_type_param_bound_impl() const {
- return new TraitBound(*this);
- }
- };
-
- // definition moved to rust-ast.h
- class TypeNoBounds;
-
- // An impl trait? Poor reference material here.
- class ImplTraitType : public Type {
- // TypeParamBounds type_param_bounds;
- ::std::vector< ::std::unique_ptr<TypeParamBound> > type_param_bounds; // inlined form
-
- Location locus;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ImplTraitType* clone_type_impl() const OVERRIDE {
- return new ImplTraitType(*this);
- }
-
- public:
- ImplTraitType(
- ::std::vector< ::std::unique_ptr<TypeParamBound> > type_param_bounds, Location locus) :
- type_param_bounds(::std::move(type_param_bounds)),
- locus(locus) {}
-
- // copy constructor with vector clone
- ImplTraitType(ImplTraitType const& other) : locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- type_param_bounds.reserve(other.type_param_bounds.size());
-
- for (const auto& e : other.type_param_bounds) {
- type_param_bounds.push_back(e->clone_type_param_bound());
- }
- }
-
- // overloaded assignment operator to clone
- ImplTraitType& operator=(ImplTraitType const& other) {
- locus = other.locus;
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- type_param_bounds.reserve(other.type_param_bounds.size());
-
- for (const auto& e : other.type_param_bounds) {
- type_param_bounds.push_back(e->clone_type_param_bound());
- }
-
- return *this;
- }
-
- // move constructors
- ImplTraitType(ImplTraitType&& other) = default;
- ImplTraitType& operator=(ImplTraitType&& other) = default;
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
- };
-
- // An opaque value of another type that implements a set of traits
- class TraitObjectType : public Type {
- bool has_dyn;
- // TypeParamBounds type_param_bounds;
- ::std::vector< ::std::unique_ptr<TypeParamBound> > type_param_bounds; // inlined form
-
- Location locus;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TraitObjectType* clone_type_impl() const OVERRIDE {
- return new TraitObjectType(*this);
- }
-
- public:
- TraitObjectType(::std::vector< ::std::unique_ptr<TypeParamBound> > type_param_bounds,
- Location locus, bool is_dyn_dispatch = false) :
- has_dyn(is_dyn_dispatch),
- type_param_bounds(::std::move(type_param_bounds)), locus(locus) {}
-
- // copy constructor with vector clone
- TraitObjectType(TraitObjectType const& other) :
- has_dyn(other.has_dyn), locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- type_param_bounds.reserve(other.type_param_bounds.size());
-
- for (const auto& e : other.type_param_bounds) {
- type_param_bounds.push_back(e->clone_type_param_bound());
- }
- }
-
- // overloaded assignment operator to clone
- TraitObjectType& operator=(TraitObjectType const& other) {
- has_dyn = other.has_dyn;
- locus = other.locus;
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- type_param_bounds.reserve(other.type_param_bounds.size());
-
- for (const auto& e : other.type_param_bounds) {
- type_param_bounds.push_back(e->clone_type_param_bound());
- }
-
- return *this;
- }
-
- // move constructors
- TraitObjectType(TraitObjectType&& other) = default;
- TraitObjectType& operator=(TraitObjectType&& other) = default;
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
- };
-
- // A type with parentheses around it, used to avoid ambiguity.
- class ParenthesisedType : public TypeNoBounds {
- // Type type_in_parens;
- ::std::unique_ptr<Type> type_in_parens;
-
- Location locus;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ParenthesisedType* clone_type_impl() const OVERRIDE {
- return new ParenthesisedType(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ParenthesisedType* clone_type_no_bounds_impl() const OVERRIDE {
- return new ParenthesisedType(*this);
- }
-
- public:
- // Constructor uses Type pointer for polymorphism
- ParenthesisedType(::std::unique_ptr<Type> type_inside_parens, Location locus) :
- type_in_parens(::std::move(type_inside_parens)), locus(locus) {}
-
- // Copy constructor uses custom deep copy method for type to preserve polymorphism
- ParenthesisedType(ParenthesisedType const& other) :
- type_in_parens(other.type_in_parens->clone_type()), locus(other.locus) {}
-
- // define destructor here if required
-
- // overload assignment operator to use custom clone method
- ParenthesisedType& operator=(ParenthesisedType const& other) {
- type_in_parens = other.type_in_parens->clone_type();
- locus = other.locus;
- return *this;
- }
-
- // default move semantics
- ParenthesisedType(ParenthesisedType&& other) = default;
- ParenthesisedType& operator=(ParenthesisedType&& other) = default;
-
- ::std::string as_string() const {
- return "(" + type_in_parens->as_string() + ")";
- }
-
- // Creates a trait bound (clone of this one's trait bound) - HACK
- virtual TraitBound* to_trait_bound(bool in_parens ATTRIBUTE_UNUSED) const OVERRIDE {
- /* NOTE: obviously it is unknown whether the internal type is a trait bound due to
- * polymorphism, so just let the internal type handle it. As parenthesised type, it
- * must be in parentheses. */
- return type_in_parens->to_trait_bound(true);
- }
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
- };
-
- // Impl trait with a single bound? Poor reference material here.
- class ImplTraitTypeOneBound : public TypeNoBounds {
- TraitBound trait_bound;
-
- Location locus;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ImplTraitTypeOneBound* clone_type_impl() const OVERRIDE {
- return new ImplTraitTypeOneBound(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ImplTraitTypeOneBound* clone_type_no_bounds_impl() const OVERRIDE {
- return new ImplTraitTypeOneBound(*this);
- }
-
- public:
- ImplTraitTypeOneBound(TraitBound trait_bound, Location locus) :
- trait_bound(::std::move(trait_bound)), locus(locus) {}
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
- };
-
- /* A trait object with a single trait bound. The "trait bound" is really just the trait.
- * Basically like using an interface as a type in an OOP language. */
- class TraitObjectTypeOneBound : public TypeNoBounds {
- bool has_dyn;
- TraitBound trait_bound;
-
- Location locus;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TraitObjectTypeOneBound* clone_type_impl() const OVERRIDE {
- return new TraitObjectTypeOneBound(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual TraitObjectTypeOneBound* clone_type_no_bounds_impl() const OVERRIDE {
- return new TraitObjectTypeOneBound(*this);
- }
-
- public:
- TraitObjectTypeOneBound(
- TraitBound trait_bound, Location locus, bool is_dyn_dispatch = false) :
- has_dyn(is_dyn_dispatch),
- trait_bound(::std::move(trait_bound)), locus(locus) {}
-
- ::std::string as_string() const;
-
- // Creates a trait bound (clone of this one's trait bound) - HACK
- virtual TraitBound* to_trait_bound(bool in_parens ATTRIBUTE_UNUSED) const OVERRIDE {
- /* NOTE: this assumes there is no dynamic dispatch specified- if there was, this
- * cloning would not be required as parsing is unambiguous. */
- return new AST::TraitBound(trait_bound);
- }
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
- };
-
- class TypePath; // definition moved to "rust-path.h"
-
- // A type consisting of the "product" of others (the tuple's elements) in a specific order
- class TupleType : public TypeNoBounds {
- //::std::vector<Type> elems;
- ::std::vector< ::std::unique_ptr<Type> > elems;
-
- Location locus;
-
- public:
- // Returns whether the tuple type is the unit type, i.e. has no elements.
- inline bool is_unit_type() const {
- return elems.empty();
- }
-
- TupleType(::std::vector< ::std::unique_ptr<Type> > elems, Location locus) :
- elems(::std::move(elems)), locus(locus) {}
-
- // copy constructor with vector clone
- TupleType(TupleType const& other) : locus(other.locus) {
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- elems.reserve(other.elems.size());
-
- for (const auto& e : other.elems) {
- elems.push_back(e->clone_type());
- }
- }
-
- // overloaded assignment operator to clone
- TupleType& operator=(TupleType const& other) {
- locus = other.locus;
- // crappy vector unique pointer clone - TODO is there a better way of doing this?
- elems.reserve(other.elems.size());
-
- for (const auto& e : other.elems) {
- elems.push_back(e->clone_type());
- }
-
- return *this;
- }
-
- // move constructors
- TupleType(TupleType&& other) = default;
- TupleType& operator=(TupleType&& other) = default;
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual TupleType* clone_type_impl() const OVERRIDE {
- return new TupleType(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual TupleType* clone_type_no_bounds_impl() const OVERRIDE {
- return new TupleType(*this);
- }
- };
-
- /* A type with no values, representing the result of computations that never complete.
- * Expressions of NeverType can be coerced into any other types. Represented as "!". */
- class NeverType : public TypeNoBounds {
- Location locus;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual NeverType* clone_type_impl() const OVERRIDE {
- return new NeverType(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual NeverType* clone_type_no_bounds_impl() const OVERRIDE {
- return new NeverType(*this);
- }
-
- public:
- NeverType(Location locus) : locus(locus) {}
-
- ::std::string as_string() const {
- return "! (never type)";
- }
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
- };
-
- // A type consisting of a pointer without safety or liveness guarantees
- class RawPointerType : public TypeNoBounds {
- public:
- enum PointerType { MUT, CONST };
-
- private:
- PointerType pointer_type;
-
- // TypeNoBounds type;
- ::std::unique_ptr<TypeNoBounds> type;
-
- Location locus;
-
- public:
- // Returns whether the pointer is mutable or constant.
- inline PointerType get_pointer_type() const {
- return pointer_type;
- }
-
- // Constructor requires pointer for polymorphism reasons
- RawPointerType(PointerType pointer_type, ::std::unique_ptr<TypeNoBounds> type_no_bounds,
- Location locus) :
- pointer_type(pointer_type),
- type(::std::move(type_no_bounds)), locus(locus) {}
-
- // Copy constructor calls custom polymorphic clone function
- RawPointerType(RawPointerType const& other) :
- pointer_type(other.pointer_type), type(other.type->clone_type_no_bounds()),
- locus(other.locus) {}
-
- // no destructor required?
-
- // overload assignment operator to use custom clone method
- RawPointerType& operator=(RawPointerType const& other) {
- pointer_type = other.pointer_type;
- type = other.type->clone_type_no_bounds();
- locus = other.locus;
- return *this;
- }
-
- // default move semantics
- RawPointerType(RawPointerType&& other) = default;
- RawPointerType& operator=(RawPointerType&& other) = default;
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual RawPointerType* clone_type_impl() const OVERRIDE {
- return new RawPointerType(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual RawPointerType* clone_type_no_bounds_impl() const OVERRIDE {
- return new RawPointerType(*this);
- }
- };
-
- // A type pointing to memory owned by another value
- class ReferenceType : public TypeNoBounds {
- // bool has_lifetime; // TODO: handle in lifetime or something?
- Lifetime lifetime;
-
- bool has_mut;
-
- // TypeNoBounds type;
- ::std::unique_ptr<TypeNoBounds> type;
-
- Location locus;
-
- public:
- // Returns whether the reference is mutable or immutable.
- inline bool is_mut() const {
- return has_mut;
- }
-
- // Returns whether the reference has a lifetime.
- inline bool has_lifetime() const {
- return !lifetime.is_error();
- }
-
- // Constructor
- ReferenceType(bool is_mut, ::std::unique_ptr<TypeNoBounds> type_no_bounds, Location locus,
- Lifetime lifetime = Lifetime::error()) :
- lifetime(::std::move(lifetime)),
- has_mut(is_mut), type(::std::move(type_no_bounds)), locus(locus) {}
-
- // Copy constructor with custom clone method
- ReferenceType(ReferenceType const& other) :
- lifetime(other.lifetime), has_mut(other.has_mut),
- type(other.type->clone_type_no_bounds()), locus(other.locus) {}
-
- // Destructor not required?
-
- // Operator overload assignment operator to custom clone the unique pointer
- ReferenceType& operator=(ReferenceType const& other) {
- lifetime = other.lifetime;
- has_mut = other.has_mut;
- type = other.type->clone_type_no_bounds();
- locus = other.locus;
-
- return *this;
- }
-
- // move constructors
- ReferenceType(ReferenceType&& other) = default;
- ReferenceType& operator=(ReferenceType&& other) = default;
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ReferenceType* clone_type_impl() const OVERRIDE {
- return new ReferenceType(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ReferenceType* clone_type_no_bounds_impl() const OVERRIDE {
- return new ReferenceType(*this);
- }
- };
-
- // A fixed-size sequence of elements of a specified type
- class ArrayType : public TypeNoBounds {
- // Type elem_type;
- ::std::unique_ptr<Type> elem_type;
- // Expr* size;
- ::std::unique_ptr<Expr> size;
-
- Location locus;
-
- public:
- // Constructor requires pointers for polymorphism
- ArrayType(
- ::std::unique_ptr<Type> type, ::std::unique_ptr<Expr> array_size, Location locus) :
- elem_type(::std::move(type)),
- size(::std::move(array_size)), locus(locus) {}
-
- // Copy constructor requires deep copies of both unique pointers
- ArrayType(ArrayType const& other) :
- elem_type(other.elem_type->clone_type()), size(other.size->clone_expr()),
- locus(other.locus) {}
-
- // destructor not required?
-
- // Overload assignment operator to deep copy pointers
- ArrayType& operator=(ArrayType const& other) {
- elem_type = other.elem_type->clone_type();
- size = other.size->clone_expr();
- locus = other.locus;
- return *this;
- }
-
- // move constructors
- ArrayType(ArrayType&& other) = default;
- ArrayType& operator=(ArrayType&& other) = default;
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- /*~ArrayType() {
- delete size;
- }*/
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual ArrayType* clone_type_impl() const OVERRIDE {
- return new ArrayType(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual ArrayType* clone_type_no_bounds_impl() const OVERRIDE {
- return new ArrayType(*this);
- }
- };
-
- // A dynamically-sized type representing a "view" into a sequence of elements of a type
- class SliceType : public TypeNoBounds {
- // Type elem_type;
- ::std::unique_ptr<Type> elem_type;
-
- Location locus;
-
- public:
- // Constructor requires pointer for polymorphism
- SliceType(::std::unique_ptr<Type> type, Location locus) :
- elem_type(::std::move(type)), locus(locus) {}
-
- // Copy constructor requires deep copy of Type smart pointer
- SliceType(SliceType const& other) :
- elem_type(other.elem_type->clone_type()), locus(other.locus) {}
-
- // destructor not required?
-
- // Overload assignment operator to deep copy
- SliceType& operator=(SliceType const& other) {
- elem_type = other.elem_type->clone_type();
- locus = other.locus;
-
- return *this;
- }
-
- // move constructors
- SliceType(SliceType&& other) = default;
- SliceType& operator=(SliceType&& other) = default;
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual SliceType* clone_type_impl() const OVERRIDE {
- return new SliceType(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual SliceType* clone_type_no_bounds_impl() const OVERRIDE {
- return new SliceType(*this);
- }
- };
-
- // Type used in generic arguments to explicitly request type inference (wildcard pattern)
- class InferredType : public TypeNoBounds {
- Location locus;
-
- // e.g. Vec<_> = whatever
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual InferredType* clone_type_impl() const OVERRIDE {
- return new InferredType(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual InferredType* clone_type_no_bounds_impl() const OVERRIDE {
- return new InferredType(*this);
- }
-
- public:
- InferredType(Location locus) : locus(locus) {}
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
- };
-
- class QualifiedPathInType; // definition moved to "rust-path.h"
-
- // A possibly named param used in a BaseFunctionType
- struct MaybeNamedParam {
- public:
- enum ParamKind { UNNAMED, IDENTIFIER, WILDCARD };
-
- private:
- // Type param_type;
- ::std::unique_ptr<Type> param_type;
-
- ParamKind param_kind;
- Identifier name; // technically, can be an identifier or '_'
-
- Location locus;
-
- public:
- MaybeNamedParam(Identifier name, ParamKind param_kind, ::std::unique_ptr<Type> param_type,
- Location locus) :
- param_type(::std::move(param_type)),
- param_kind(param_kind), name(::std::move(name)), locus(locus) {}
-
- // Copy constructor with clone
- MaybeNamedParam(MaybeNamedParam const& other) :
- param_type(other.param_type->clone_type()), param_kind(other.param_kind),
- name(other.name), locus(other.locus) {}
-
- ~MaybeNamedParam() = default;
-
- // Overloaded assignment operator with clone
- MaybeNamedParam& operator=(MaybeNamedParam const& other) {
- name = other.name;
- param_kind = other.param_kind;
- param_type = other.param_type->clone_type();
- locus = other.locus;
-
- return *this;
- }
-
- // move constructors
- MaybeNamedParam(MaybeNamedParam&& other) = default;
- MaybeNamedParam& operator=(MaybeNamedParam&& other) = default;
-
- ::std::string as_string() const;
-
- // Returns whether the param is in an error state.
- inline bool is_error() const {
- return param_type == NULL;
- }
-
- // Creates an error state param.
- static MaybeNamedParam create_error() {
- return MaybeNamedParam("", UNNAMED, NULL, Location());
- }
-
- Location get_locus() const {
- return locus;
- }
- };
-
- /* A function pointer type - can be created via coercion from function items and non-
- * capturing closures. */
- class BareFunctionType : public TypeNoBounds {
- // bool has_for_lifetimes;
- // ForLifetimes for_lifetimes;
- ::std::vector<LifetimeParam> for_lifetimes; // inlined version
-
- FunctionQualifiers function_qualifiers;
- ::std::vector<MaybeNamedParam> params;
- bool is_variadic;
-
- // bool has_return_type;
- // BareFunctionReturnType return_type;
- ::std::unique_ptr<TypeNoBounds> return_type; // inlined version
-
- Location locus;
-
- public:
- // Whether a return type is defined with the function.
- inline bool has_return_type() const {
- return return_type != NULL;
- }
-
- // Whether the function has ForLifetimes.
- inline bool has_for_lifetimes() const {
- return !for_lifetimes.empty();
- }
-
- BareFunctionType(::std::vector<LifetimeParam> lifetime_params,
- FunctionQualifiers qualifiers, ::std::vector<MaybeNamedParam> named_params,
- bool is_variadic, ::std::unique_ptr<TypeNoBounds> type, Location locus) :
- for_lifetimes(::std::move(lifetime_params)),
- function_qualifiers(::std::move(qualifiers)), params(::std::move(named_params)),
- is_variadic(is_variadic), return_type(::std::move(type)), locus(locus) {}
-
- // Copy constructor with clone
- BareFunctionType(BareFunctionType const& other) :
- for_lifetimes(other.for_lifetimes), function_qualifiers(other.function_qualifiers),
- params(other.params), is_variadic(other.is_variadic),
- return_type(other.return_type->clone_type_no_bounds()), locus(other.locus) {}
-
- // destructor - define here if required
-
- // Overload assignment operator to deep copy
- BareFunctionType& operator=(BareFunctionType const& other) {
- for_lifetimes = other.for_lifetimes;
- function_qualifiers = other.function_qualifiers;
- params = other.params;
- is_variadic = other.is_variadic;
- return_type = other.return_type->clone_type_no_bounds();
- locus = other.locus;
-
- return *this;
- }
-
- // move constructors
- BareFunctionType(BareFunctionType&& other) = default;
- BareFunctionType& operator=(BareFunctionType&& other) = default;
-
- ::std::string as_string() const;
-
- Location get_locus() const {
- return locus;
- }
-
- virtual void accept_vis(ASTVisitor& vis) OVERRIDE;
-
- protected:
- // Use covariance to implement clone function as returning this object rather than base
- virtual BareFunctionType* clone_type_impl() const OVERRIDE {
- return new BareFunctionType(*this);
- }
-
- // Use covariance to implement clone function as returning this object rather than base
- virtual BareFunctionType* clone_type_no_bounds_impl() const OVERRIDE {
- return new BareFunctionType(*this);
- }
- };
-
- // Forward decl - defined in rust-macro.h
- class MacroInvocation;
-
- /*// AST node of a macro invocation, which is replaced by the macro result at compile time
- class MacroInvocation : public TypeNoBounds, public Pattern, public ExprWithoutBlock {
- SimplePath path;
- DelimTokenTree token_tree;
- };*/
-
- /* TODO: possible types
- * struct type?
- * "enum" (tagged union) type?
- * C-like union type?
- * function item type?
- * closure expression types?
- * primitive types (bool, int, float, char, str (the slice))
- * Although supposedly TypePaths are used to reference these types (including primitives) */
-
- /* FIXME: Incomplete spec references:
- * anonymous type parameters, aka "impl Trait in argument position" - impl then trait bounds
- * abstract return types, aka "impl Trait in return position" - impl then trait bounds */
- }
-}
+namespace AST {
+// definitions moved to rust-ast.h
+class TypeParamBound;
+class Lifetime;
+
+// A trait bound
+class TraitBound : public TypeParamBound
+{
+ bool in_parens;
+ bool opening_question_mark;
+
+ // bool has_for_lifetimes;
+ // LifetimeParams for_lifetimes;
+ ::std::vector<LifetimeParam> for_lifetimes; // inlined LifetimeParams
+
+ TypePath type_path;
+
+ Location locus;
+
+public:
+ // Returns whether trait bound has "for" lifetimes
+ inline bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
+
+ TraitBound (TypePath type_path, Location locus, bool in_parens = false,
+ bool opening_question_mark = false,
+ ::std::vector<LifetimeParam> for_lifetimes
+ = ::std::vector<LifetimeParam> ())
+ : in_parens (in_parens), opening_question_mark (opening_question_mark),
+ for_lifetimes (::std::move (for_lifetimes)),
+ type_path (::std::move (type_path)), locus (locus)
+ {}
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Clone function implementation as (not pure) virtual method
+ virtual TraitBound *clone_type_param_bound_impl () const
+ {
+ return new TraitBound (*this);
+ }
+};
+
+// definition moved to rust-ast.h
+class TypeNoBounds;
+
+// An impl trait? Poor reference material here.
+class ImplTraitType : public Type
+{
+ // TypeParamBounds type_param_bounds;
+ ::std::vector< ::std::unique_ptr<TypeParamBound> >
+ type_param_bounds; // inlined form
+
+ Location locus;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ImplTraitType *clone_type_impl () const OVERRIDE
+ {
+ return new ImplTraitType (*this);
+ }
+
+public:
+ ImplTraitType (
+ ::std::vector< ::std::unique_ptr<TypeParamBound> > type_param_bounds,
+ Location locus)
+ : type_param_bounds (::std::move (type_param_bounds)), locus (locus)
+ {}
+
+ // copy constructor with vector clone
+ ImplTraitType (ImplTraitType const &other) : locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+
+ for (const auto &e : other.type_param_bounds)
+ {
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+ }
+ }
+
+ // overloaded assignment operator to clone
+ ImplTraitType &operator= (ImplTraitType const &other)
+ {
+ locus = other.locus;
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+
+ for (const auto &e : other.type_param_bounds)
+ {
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ ImplTraitType (ImplTraitType &&other) = default;
+ ImplTraitType &operator= (ImplTraitType &&other) = default;
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+};
+
+// An opaque value of another type that implements a set of traits
+class TraitObjectType : public Type
+{
+ bool has_dyn;
+ // TypeParamBounds type_param_bounds;
+ ::std::vector< ::std::unique_ptr<TypeParamBound> >
+ type_param_bounds; // inlined form
+
+ Location locus;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TraitObjectType *clone_type_impl () const OVERRIDE
+ {
+ return new TraitObjectType (*this);
+ }
+
+public:
+ TraitObjectType (
+ ::std::vector< ::std::unique_ptr<TypeParamBound> > type_param_bounds,
+ Location locus, bool is_dyn_dispatch = false)
+ : has_dyn (is_dyn_dispatch),
+ type_param_bounds (::std::move (type_param_bounds)), locus (locus)
+ {}
+
+ // copy constructor with vector clone
+ TraitObjectType (TraitObjectType const &other)
+ : has_dyn (other.has_dyn), locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+
+ for (const auto &e : other.type_param_bounds)
+ {
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+ }
+ }
+
+ // overloaded assignment operator to clone
+ TraitObjectType &operator= (TraitObjectType const &other)
+ {
+ has_dyn = other.has_dyn;
+ locus = other.locus;
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ type_param_bounds.reserve (other.type_param_bounds.size ());
+
+ for (const auto &e : other.type_param_bounds)
+ {
+ type_param_bounds.push_back (e->clone_type_param_bound ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ TraitObjectType (TraitObjectType &&other) = default;
+ TraitObjectType &operator= (TraitObjectType &&other) = default;
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+};
+
+// A type with parentheses around it, used to avoid ambiguity.
+class ParenthesisedType : public TypeNoBounds
+{
+ // Type type_in_parens;
+ ::std::unique_ptr<Type> type_in_parens;
+
+ Location locus;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ParenthesisedType *clone_type_impl () const OVERRIDE
+ {
+ return new ParenthesisedType (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ParenthesisedType *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new ParenthesisedType (*this);
+ }
+
+public:
+ // Constructor uses Type pointer for polymorphism
+ ParenthesisedType (::std::unique_ptr<Type> type_inside_parens, Location locus)
+ : type_in_parens (::std::move (type_inside_parens)), locus (locus)
+ {}
+
+ // Copy constructor uses custom deep copy method for type to preserve
+ // polymorphism
+ ParenthesisedType (ParenthesisedType const &other)
+ : type_in_parens (other.type_in_parens->clone_type ()), locus (other.locus)
+ {}
+
+ // define destructor here if required
+
+ // overload assignment operator to use custom clone method
+ ParenthesisedType &operator= (ParenthesisedType const &other)
+ {
+ type_in_parens = other.type_in_parens->clone_type ();
+ locus = other.locus;
+ return *this;
+ }
+
+ // default move semantics
+ ParenthesisedType (ParenthesisedType &&other) = default;
+ ParenthesisedType &operator= (ParenthesisedType &&other) = default;
+
+ ::std::string as_string () const
+ {
+ return "(" + type_in_parens->as_string () + ")";
+ }
+
+ // Creates a trait bound (clone of this one's trait bound) - HACK
+ virtual TraitBound *
+ to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const OVERRIDE
+ {
+ /* NOTE: obviously it is unknown whether the internal type is a trait bound
+ * due to polymorphism, so just let the internal type handle it. As
+ * parenthesised type, it must be in parentheses. */
+ return type_in_parens->to_trait_bound (true);
+ }
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+};
+
+// Impl trait with a single bound? Poor reference material here.
+class ImplTraitTypeOneBound : public TypeNoBounds
+{
+ TraitBound trait_bound;
+
+ Location locus;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ImplTraitTypeOneBound *clone_type_impl () const OVERRIDE
+ {
+ return new ImplTraitTypeOneBound (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ImplTraitTypeOneBound *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new ImplTraitTypeOneBound (*this);
+ }
+
+public:
+ ImplTraitTypeOneBound (TraitBound trait_bound, Location locus)
+ : trait_bound (::std::move (trait_bound)), locus (locus)
+ {}
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+};
+
+/* A trait object with a single trait bound. The "trait bound" is really just
+ * the trait. Basically like using an interface as a type in an OOP language. */
+class TraitObjectTypeOneBound : public TypeNoBounds
+{
+ bool has_dyn;
+ TraitBound trait_bound;
+
+ Location locus;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TraitObjectTypeOneBound *clone_type_impl () const OVERRIDE
+ {
+ return new TraitObjectTypeOneBound (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TraitObjectTypeOneBound *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new TraitObjectTypeOneBound (*this);
+ }
+
+public:
+ TraitObjectTypeOneBound (TraitBound trait_bound, Location locus,
+ bool is_dyn_dispatch = false)
+ : has_dyn (is_dyn_dispatch), trait_bound (::std::move (trait_bound)),
+ locus (locus)
+ {}
+
+ ::std::string as_string () const;
+
+ // Creates a trait bound (clone of this one's trait bound) - HACK
+ virtual TraitBound *
+ to_trait_bound (bool in_parens ATTRIBUTE_UNUSED) const OVERRIDE
+ {
+ /* NOTE: this assumes there is no dynamic dispatch specified- if there was,
+ * this cloning would not be required as parsing is unambiguous. */
+ return new AST::TraitBound (trait_bound);
+ }
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+};
+
+class TypePath; // definition moved to "rust-path.h"
+
+// A type consisting of the "product" of others (the tuple's elements) in a
+// specific order
+class TupleType : public TypeNoBounds
+{
+ //::std::vector<Type> elems;
+ ::std::vector< ::std::unique_ptr<Type> > elems;
+
+ Location locus;
+
+public:
+ // Returns whether the tuple type is the unit type, i.e. has no elements.
+ inline bool is_unit_type () const { return elems.empty (); }
+
+ TupleType (::std::vector< ::std::unique_ptr<Type> > elems, Location locus)
+ : elems (::std::move (elems)), locus (locus)
+ {}
+
+ // copy constructor with vector clone
+ TupleType (TupleType const &other) : locus (other.locus)
+ {
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ elems.reserve (other.elems.size ());
+
+ for (const auto &e : other.elems)
+ {
+ elems.push_back (e->clone_type ());
+ }
+ }
+
+ // overloaded assignment operator to clone
+ TupleType &operator= (TupleType const &other)
+ {
+ locus = other.locus;
+ // crappy vector unique pointer clone - TODO is there a better way of doing
+ // this?
+ elems.reserve (other.elems.size ());
+
+ for (const auto &e : other.elems)
+ {
+ elems.push_back (e->clone_type ());
+ }
+
+ return *this;
+ }
+
+ // move constructors
+ TupleType (TupleType &&other) = default;
+ TupleType &operator= (TupleType &&other) = default;
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TupleType *clone_type_impl () const OVERRIDE
+ {
+ return new TupleType (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual TupleType *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new TupleType (*this);
+ }
+};
+
+/* A type with no values, representing the result of computations that never
+ * complete. Expressions of NeverType can be coerced into any other types.
+ * Represented as "!". */
+class NeverType : public TypeNoBounds
+{
+ Location locus;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual NeverType *clone_type_impl () const OVERRIDE
+ {
+ return new NeverType (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual NeverType *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new NeverType (*this);
+ }
+
+public:
+ NeverType (Location locus) : locus (locus) {}
+
+ ::std::string as_string () const { return "! (never type)"; }
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+};
+
+// A type consisting of a pointer without safety or liveness guarantees
+class RawPointerType : public TypeNoBounds
+{
+public:
+ enum PointerType
+ {
+ MUT,
+ CONST
+ };
+
+private:
+ PointerType pointer_type;
+
+ // TypeNoBounds type;
+ ::std::unique_ptr<TypeNoBounds> type;
+
+ Location locus;
+
+public:
+ // Returns whether the pointer is mutable or constant.
+ inline PointerType get_pointer_type () const { return pointer_type; }
+
+ // Constructor requires pointer for polymorphism reasons
+ RawPointerType (PointerType pointer_type,
+ ::std::unique_ptr<TypeNoBounds> type_no_bounds,
+ Location locus)
+ : pointer_type (pointer_type), type (::std::move (type_no_bounds)),
+ locus (locus)
+ {}
+
+ // Copy constructor calls custom polymorphic clone function
+ RawPointerType (RawPointerType const &other)
+ : pointer_type (other.pointer_type),
+ type (other.type->clone_type_no_bounds ()), locus (other.locus)
+ {}
+
+ // no destructor required?
+
+ // overload assignment operator to use custom clone method
+ RawPointerType &operator= (RawPointerType const &other)
+ {
+ pointer_type = other.pointer_type;
+ type = other.type->clone_type_no_bounds ();
+ locus = other.locus;
+ return *this;
+ }
+
+ // default move semantics
+ RawPointerType (RawPointerType &&other) = default;
+ RawPointerType &operator= (RawPointerType &&other) = default;
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RawPointerType *clone_type_impl () const OVERRIDE
+ {
+ return new RawPointerType (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual RawPointerType *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new RawPointerType (*this);
+ }
+};
+
+// A type pointing to memory owned by another value
+class ReferenceType : public TypeNoBounds
+{
+ // bool has_lifetime; // TODO: handle in lifetime or something?
+ Lifetime lifetime;
+
+ bool has_mut;
+
+ // TypeNoBounds type;
+ ::std::unique_ptr<TypeNoBounds> type;
+
+ Location locus;
+
+public:
+ // Returns whether the reference is mutable or immutable.
+ inline bool is_mut () const { return has_mut; }
+
+ // Returns whether the reference has a lifetime.
+ inline bool has_lifetime () const { return !lifetime.is_error (); }
+
+ // Constructor
+ ReferenceType (bool is_mut, ::std::unique_ptr<TypeNoBounds> type_no_bounds,
+ Location locus, Lifetime lifetime = Lifetime::error ())
+ : lifetime (::std::move (lifetime)), has_mut (is_mut),
+ type (::std::move (type_no_bounds)), locus (locus)
+ {}
+
+ // Copy constructor with custom clone method
+ ReferenceType (ReferenceType const &other)
+ : lifetime (other.lifetime), has_mut (other.has_mut),
+ type (other.type->clone_type_no_bounds ()), locus (other.locus)
+ {}
+
+ // Destructor not required?
+
+ // Operator overload assignment operator to custom clone the unique pointer
+ ReferenceType &operator= (ReferenceType const &other)
+ {
+ lifetime = other.lifetime;
+ has_mut = other.has_mut;
+ type = other.type->clone_type_no_bounds ();
+ locus = other.locus;
+
+ return *this;
+ }
+
+ // move constructors
+ ReferenceType (ReferenceType &&other) = default;
+ ReferenceType &operator= (ReferenceType &&other) = default;
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ReferenceType *clone_type_impl () const OVERRIDE
+ {
+ return new ReferenceType (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ReferenceType *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new ReferenceType (*this);
+ }
+};
+
+// A fixed-size sequence of elements of a specified type
+class ArrayType : public TypeNoBounds
+{
+ // Type elem_type;
+ ::std::unique_ptr<Type> elem_type;
+ // Expr* size;
+ ::std::unique_ptr<Expr> size;
+
+ Location locus;
+
+public:
+ // Constructor requires pointers for polymorphism
+ ArrayType (::std::unique_ptr<Type> type, ::std::unique_ptr<Expr> array_size,
+ Location locus)
+ : elem_type (::std::move (type)), size (::std::move (array_size)),
+ locus (locus)
+ {}
+
+ // Copy constructor requires deep copies of both unique pointers
+ ArrayType (ArrayType const &other)
+ : elem_type (other.elem_type->clone_type ()),
+ size (other.size->clone_expr ()), locus (other.locus)
+ {}
+
+ // destructor not required?
+
+ // Overload assignment operator to deep copy pointers
+ ArrayType &operator= (ArrayType const &other)
+ {
+ elem_type = other.elem_type->clone_type ();
+ size = other.size->clone_expr ();
+ locus = other.locus;
+ return *this;
+ }
+
+ // move constructors
+ ArrayType (ArrayType &&other) = default;
+ ArrayType &operator= (ArrayType &&other) = default;
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+ /*~ArrayType() {
+ delete size;
+ }*/
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ArrayType *clone_type_impl () const OVERRIDE
+ {
+ return new ArrayType (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual ArrayType *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new ArrayType (*this);
+ }
+};
+
+// A dynamically-sized type representing a "view" into a sequence of elements of
+// a type
+class SliceType : public TypeNoBounds
+{
+ // Type elem_type;
+ ::std::unique_ptr<Type> elem_type;
+
+ Location locus;
+
+public:
+ // Constructor requires pointer for polymorphism
+ SliceType (::std::unique_ptr<Type> type, Location locus)
+ : elem_type (::std::move (type)), locus (locus)
+ {}
+
+ // Copy constructor requires deep copy of Type smart pointer
+ SliceType (SliceType const &other)
+ : elem_type (other.elem_type->clone_type ()), locus (other.locus)
+ {}
+
+ // destructor not required?
+
+ // Overload assignment operator to deep copy
+ SliceType &operator= (SliceType const &other)
+ {
+ elem_type = other.elem_type->clone_type ();
+ locus = other.locus;
+
+ return *this;
+ }
+
+ // move constructors
+ SliceType (SliceType &&other) = default;
+ SliceType &operator= (SliceType &&other) = default;
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual SliceType *clone_type_impl () const OVERRIDE
+ {
+ return new SliceType (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual SliceType *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new SliceType (*this);
+ }
+};
+
+// Type used in generic arguments to explicitly request type inference (wildcard
+// pattern)
+class InferredType : public TypeNoBounds
+{
+ Location locus;
+
+ // e.g. Vec<_> = whatever
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual InferredType *clone_type_impl () const OVERRIDE
+ {
+ return new InferredType (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual InferredType *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new InferredType (*this);
+ }
+
+public:
+ InferredType (Location locus) : locus (locus) {}
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+};
+
+class QualifiedPathInType; // definition moved to "rust-path.h"
+
+// A possibly named param used in a BaseFunctionType
+struct MaybeNamedParam
+{
+public:
+ enum ParamKind
+ {
+ UNNAMED,
+ IDENTIFIER,
+ WILDCARD
+ };
+
+private:
+ // Type param_type;
+ ::std::unique_ptr<Type> param_type;
+
+ ParamKind param_kind;
+ Identifier name; // technically, can be an identifier or '_'
+
+ Location locus;
+
+public:
+ MaybeNamedParam (Identifier name, ParamKind param_kind,
+ ::std::unique_ptr<Type> param_type, Location locus)
+ : param_type (::std::move (param_type)), param_kind (param_kind),
+ name (::std::move (name)), locus (locus)
+ {}
+
+ // Copy constructor with clone
+ MaybeNamedParam (MaybeNamedParam const &other)
+ : param_type (other.param_type->clone_type ()),
+ param_kind (other.param_kind), name (other.name), locus (other.locus)
+ {}
+
+ ~MaybeNamedParam () = default;
+
+ // Overloaded assignment operator with clone
+ MaybeNamedParam &operator= (MaybeNamedParam const &other)
+ {
+ name = other.name;
+ param_kind = other.param_kind;
+ param_type = other.param_type->clone_type ();
+ locus = other.locus;
+
+ return *this;
+ }
+
+ // move constructors
+ MaybeNamedParam (MaybeNamedParam &&other) = default;
+ MaybeNamedParam &operator= (MaybeNamedParam &&other) = default;
+
+ ::std::string as_string () const;
+
+ // Returns whether the param is in an error state.
+ inline bool is_error () const { return param_type == NULL; }
+
+ // Creates an error state param.
+ static MaybeNamedParam create_error ()
+ {
+ return MaybeNamedParam ("", UNNAMED, NULL, Location ());
+ }
+
+ Location get_locus () const { return locus; }
+};
+
+/* A function pointer type - can be created via coercion from function items and
+ * non- capturing closures. */
+class BareFunctionType : public TypeNoBounds
+{
+ // bool has_for_lifetimes;
+ // ForLifetimes for_lifetimes;
+ ::std::vector<LifetimeParam> for_lifetimes; // inlined version
+
+ FunctionQualifiers function_qualifiers;
+ ::std::vector<MaybeNamedParam> params;
+ bool is_variadic;
+
+ // bool has_return_type;
+ // BareFunctionReturnType return_type;
+ ::std::unique_ptr<TypeNoBounds> return_type; // inlined version
+
+ Location locus;
+
+public:
+ // Whether a return type is defined with the function.
+ inline bool has_return_type () const { return return_type != NULL; }
+
+ // Whether the function has ForLifetimes.
+ inline bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
+
+ BareFunctionType (::std::vector<LifetimeParam> lifetime_params,
+ FunctionQualifiers qualifiers,
+ ::std::vector<MaybeNamedParam> named_params,
+ bool is_variadic, ::std::unique_ptr<TypeNoBounds> type,
+ Location locus)
+ : for_lifetimes (::std::move (lifetime_params)),
+ function_qualifiers (::std::move (qualifiers)),
+ params (::std::move (named_params)), is_variadic (is_variadic),
+ return_type (::std::move (type)), locus (locus)
+ {}
+
+ // Copy constructor with clone
+ BareFunctionType (BareFunctionType const &other)
+ : for_lifetimes (other.for_lifetimes),
+ function_qualifiers (other.function_qualifiers), params (other.params),
+ is_variadic (other.is_variadic),
+ return_type (other.return_type->clone_type_no_bounds ()),
+ locus (other.locus)
+ {}
+
+ // destructor - define here if required
+
+ // Overload assignment operator to deep copy
+ BareFunctionType &operator= (BareFunctionType const &other)
+ {
+ for_lifetimes = other.for_lifetimes;
+ function_qualifiers = other.function_qualifiers;
+ params = other.params;
+ is_variadic = other.is_variadic;
+ return_type = other.return_type->clone_type_no_bounds ();
+ locus = other.locus;
+
+ return *this;
+ }
+
+ // move constructors
+ BareFunctionType (BareFunctionType &&other) = default;
+ BareFunctionType &operator= (BareFunctionType &&other) = default;
+
+ ::std::string as_string () const;
+
+ Location get_locus () const { return locus; }
+
+ virtual void accept_vis (ASTVisitor &vis) OVERRIDE;
+
+protected:
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual BareFunctionType *clone_type_impl () const OVERRIDE
+ {
+ return new BareFunctionType (*this);
+ }
+
+ // Use covariance to implement clone function as returning this object rather
+ // than base
+ virtual BareFunctionType *clone_type_no_bounds_impl () const OVERRIDE
+ {
+ return new BareFunctionType (*this);
+ }
+};
+
+// Forward decl - defined in rust-macro.h
+class MacroInvocation;
+
+/*// AST node of a macro invocation, which is replaced by the macro result at
+compile time class MacroInvocation : public TypeNoBounds, public Pattern, public
+ExprWithoutBlock { SimplePath path; DelimTokenTree token_tree;
+};*/
+
+/* TODO: possible types
+ * struct type?
+ * "enum" (tagged union) type?
+ * C-like union type?
+ * function item type?
+ * closure expression types?
+ * primitive types (bool, int, float, char, str (the slice))
+ * Although supposedly TypePaths are used to reference these types (including
+ * primitives) */
+
+/* FIXME: Incomplete spec references:
+ * anonymous type parameters, aka "impl Trait in argument position" - impl then
+ * trait bounds abstract return types, aka "impl Trait in return position" -
+ * impl then trait bounds */
+} // namespace AST
+} // namespace Rust
#endif
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 613d94f..5e5f8fe 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -3,67 +3,83 @@
// is full really required?
namespace Rust {
- void MacroExpander::expand_invoc(::std::unique_ptr<AST::MacroInvocation>& invoc) {
- // if current expansion depth > recursion limit, create an error (maybe fatal error) and return
-
- /* switch on type of macro:
- - '!' syntax macro (inner switch)
- - procedural macro - "A token-based function-like macro"
- - 'macro_rules' (by example/pattern-match) macro? or not? "an AST-based function-like macro"
- - else is unreachable
- - attribute syntax macro (inner switch)
- - procedural macro attribute syntax - "A token-based attribute macro"
- - legacy macro attribute syntax? - "an AST-based attribute macro"
- - non-macro attribute: mark known
- - else is unreachable
- - derive macro (inner switch)
- - derive or legacy derive - "token-based" vs "AST-based"
- - else is unreachable
- - derive container macro - unreachable*/
-
- }
-
- // Determines whether cfg predicate is true and item with attribute should not be stripped.
- bool check_cfg_predicate() {}
-
- // Determines whether cfg predicate is true and item with attribute should not be stripped.
- bool check_cfg(AST::Attribute& attr) {
-
+void
+MacroExpander::expand_invoc (::std::unique_ptr<AST::MacroInvocation> &invoc)
+{
+ // if current expansion depth > recursion limit, create an error (maybe fatal
+ // error) and return
+
+ /* switch on type of macro:
+ - '!' syntax macro (inner switch)
+ - procedural macro - "A token-based function-like macro"
+ - 'macro_rules' (by example/pattern-match) macro? or not? "an
+ AST-based function-like macro"
+ - else is unreachable
+ - attribute syntax macro (inner switch)
+ - procedural macro attribute syntax - "A token-based attribute macro"
+ - legacy macro attribute syntax? - "an AST-based attribute macro"
+ - non-macro attribute: mark known
+ - else is unreachable
+ - derive macro (inner switch)
+ - derive or legacy derive - "token-based" vs "AST-based"
+ - else is unreachable
+ - derive container macro - unreachable*/
+}
+
+// Determines whether cfg predicate is true and item with attribute should not
+// be stripped.
+bool
+check_cfg_predicate ()
+{}
+
+// Determines whether cfg predicate is true and item with attribute should not
+// be stripped.
+bool
+check_cfg (AST::Attribute &attr)
+{}
+
+// Expands cfg_attr attributes.
+void
+expand_attrs_cfgattr (::std::vector<AST::Attribute> &attrs)
+{
+ for (auto it = attrs.begin (); it != attrs.end ();)
+ {
+ auto &attr = *it;
+ if (attr.get_path () == "cfg_attr")
+ {
+ if (check_cfg (attr))
+ {
+ }
+
+ /* do something - if feature (first token in tree) is in fact enabled,
+ * make tokens listed afterwards into attributes. i.e.: for
+ * [cfg_attr(feature = "wow", wow1, wow2)], if "wow" is true, then add
+ * attributes [wow1] and [wow2] to attribute list. This can also be
+ * recursive, so check for expanded attributes being recursive and
+ * possibly recursively call the expand_attrs? */
+ }
+ else
+ {
+ ++it;
+ }
}
+}
- // Expands cfg_attr attributes.
- void expand_attrs_cfgattr(::std::vector<AST::Attribute>& attrs) {
- for (auto it = attrs.begin(); it != attrs.end(); ) {
- auto& attr = *it;
- if (attr.get_path() == "cfg_attr") {
- if (check_cfg(attr)) {}
+void
+MacroExpander::expand_crate (AST::Crate &crate)
+{
+ // fill macro/decorator map from init list? not sure where init list comes
+ // from?
- /* do something - if feature (first token in tree) is in fact enabled, make tokens listed
- * afterwards into attributes.
- * i.e.: for [cfg_attr(feature = "wow", wow1, wow2)], if "wow" is true, then add attributes
- * [wow1] and [wow2] to attribute list.
- * This can also be recursive, so check for expanded attributes being recursive and
- * possibly recursively call the expand_attrs? */
- } else {
- ++it;
- }
- }
- }
-
- void MacroExpander::expand_crate(AST::Crate& crate) {
- // fill macro/decorator map from init list? not sure where init list comes from?
-
- // expand crate attributes
- expand_attrs_cfgattr(crate.inner_attrs);
+ // expand crate attributes
+ expand_attrs_cfgattr (crate.inner_attrs);
- // expand module attributes?
+ // expand module attributes?
- // expand module tree recursively
+ // expand module tree recursively
- // post-process
+ // post-process
- // extract exported macros?
-
-
- }
-} \ No newline at end of file
+ // extract exported macros?
+}
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index a252a41..543c76f 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -6,42 +6,46 @@
// Provides objects and method prototypes for macro expansion
namespace Rust {
- // forward decls for AST
- namespace AST {
- class MacroInvocation;
- }
-
- // Object used to store configuration data for macro expansion.
- struct ExpansionCfg {
- // features?
- unsigned int recursion_limit; // TODO: determine default recursion limit
- // trace macros?
- // should test?
- // more default stuff?
- };
-
- // Object used to store shared data (between functions) for macro expansion.
- struct MacroExpander {
- ExpansionCfg cfg;
- unsigned int expansion_depth = 0;
-
- MacroExpander(AST::Crate& crate, ExpansionCfg cfg) : cfg(cfg), crate(crate) {}
-
- ~MacroExpander() = default;
-
- // Expands all macros in the crate passed in.
- void expand_crate(AST::Crate& crate);
-
- /* Expands a macro invocation (not macro invocation semi) - possibly make both have similar
- * duck-typed interface and use templates?*/
- // should this be public or private?
- void expand_invoc(::std::unique_ptr<AST::MacroInvocation>& invoc);
-
- // TODO: make it extend ASTVisitor so that individual items can be accessed properly?
-
- private:
- AST::Crate& crate;
- };
+// forward decls for AST
+namespace AST {
+class MacroInvocation;
}
-#endif \ No newline at end of file
+// Object used to store configuration data for macro expansion.
+struct ExpansionCfg
+{
+ // features?
+ unsigned int recursion_limit; // TODO: determine default recursion limit
+ // trace macros?
+ // should test?
+ // more default stuff?
+};
+
+// Object used to store shared data (between functions) for macro expansion.
+struct MacroExpander
+{
+ ExpansionCfg cfg;
+ unsigned int expansion_depth = 0;
+
+ MacroExpander (AST::Crate &crate, ExpansionCfg cfg) : cfg (cfg), crate (crate)
+ {}
+
+ ~MacroExpander () = default;
+
+ // Expands all macros in the crate passed in.
+ void expand_crate (AST::Crate &crate);
+
+ /* Expands a macro invocation (not macro invocation semi) - possibly make both
+ * have similar duck-typed interface and use templates?*/
+ // should this be public or private?
+ void expand_invoc (::std::unique_ptr<AST::MacroInvocation> &invoc);
+
+ // TODO: make it extend ASTVisitor so that individual items can be accessed
+ // properly?
+
+private:
+ AST::Crate &crate;
+};
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/lang-specs.h b/gcc/rust/lang-specs.h
index 513e951..bfd4dda 100644
--- a/gcc/rust/lang-specs.h
+++ b/gcc/rust/lang-specs.h
@@ -1,21 +1,21 @@
/* lang-specs.h -- gcc driver specs for Rust frontend.
- Copyright (C) 2009-2019 Free Software Foundation, Inc.
+ Copyright (C) 2009-2020 Free Software Foundation, Inc.
-This file is part of GCC.
+ 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 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.
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
/* This is the contribution to the `default_compilers' array in gcc.c
for the Rust language. */
diff --git a/gcc/rust/lex/rust-codepoint.h b/gcc/rust/lex/rust-codepoint.h
index a00edb3..0f2e5bd 100644
--- a/gcc/rust/lex/rust-codepoint.h
+++ b/gcc/rust/lex/rust-codepoint.h
@@ -9,18 +9,19 @@
#include <string>
namespace Rust {
- struct Codepoint {
- uint32_t value;
+struct Codepoint
+{
+ uint32_t value;
- // Creates a zero codepoint.
- Codepoint() : value(0) {}
+ // Creates a zero codepoint.
+ Codepoint () : value (0) {}
- // Creates a codepoint from UTF-8 value.
- Codepoint(uint32_t value_) : value(value_) {}
+ // Creates a codepoint from UTF-8 value.
+ Codepoint (uint32_t value_) : value (value_) {}
- // Returns a C++ string containing value of codepoint.
- ::std::string as_string();
- };
-}
+ // Returns a C++ string containing value of codepoint.
+ ::std::string as_string ();
+};
+} // namespace Rust
-#endif \ No newline at end of file
+#endif
diff --git a/gcc/rust/lex/rust-lex.h b/gcc/rust/lex/rust-lex.h
index a705367..8dc3e31 100644
--- a/gcc/rust/lex/rust-lex.h
+++ b/gcc/rust/lex/rust-lex.h
@@ -6,127 +6,131 @@
#include "rust-token.h"
namespace Rust {
- class Lexer {
- private:
- // Request new Location for current column in line_table
- Location get_current_location();
-
- // Skips the current input char.
- void skip_input();
- // Advances current input char to n + 1 chars ahead of current position.
- void skip_input(int n);
-
- // Returns char n chars ahead of current position.
- int peek_input();
- // Peeks the current char.
- int peek_input(int n);
-
- // Classifies keyword (i.e. gets id for keyword).
- TokenId classify_keyword(const std::string& str);
-
- // Builds a token from the input queue.
- TokenPtr build_token();
-
- // ok maybe all these may mean the lexer structure needs to be rethought
- /* separated into functions because main method was too long, but they rely on and change
- * state in the lexer, so variables must be passed by reference. */
- inline void parse_in_decimal(/*char& current_char, */ std::string& str, int& length);
- inline void parse_in_exponent_part(/*char& current_char, */ std::string& str, int& length);
- inline bool parse_in_type_suffix(
- /*char& current_char, */ PrimitiveCoreType& type_hint, int& length);
- inline bool parse_ascii_escape(/*char& current_char, */ int& length, char& output_char);
- inline bool parse_quote_escape(/*char& current_char, */ int& length, char& output_char);
- inline bool parse_unicode_escape(
- /*char& current_char, */ int& length, Codepoint& output_char);
- inline bool parse_byte_escape(/*char& current_char, */ int& length, char& output_char);
- inline bool parse_escape(int& length, char& output_char, char opening_char);
- inline bool parse_utf8_escape(int& length, Codepoint& output_char, char opening_char);
- inline int test_get_input_codepoint_length();
- inline int test_get_input_codepoint_n_length(int n_start_offset);
- inline Codepoint test_peek_codepoint_input();
- inline Codepoint test_peek_codepoint_input(
- int n); // maybe can use get_input_codepoint_length to get starting index
- inline void test_skip_codepoint_input();
-
- public:
- // Construct lexer with input file and filename provided
- Lexer(const char* filename, FILE* input, Linemap* linemap);
- ~Lexer();
-
- // Returns token n tokens ahead of current position.
- const_TokenPtr peek_token(int n);
- // Peeks the current token.
- const_TokenPtr peek_token();
-
- // Advances current token to n + 1 tokens ahead of current position.
- void skip_token(int n);
- // Skips the current token.
- void skip_token();
-
- // Replaces the current token with a specified token.
- void replace_current_token(TokenPtr replacement);
-
- Linemap* get_line_map() {
- return line_map;
- }
-
- private:
- // File for use as input.
- FILE* input;
-
- // Current line number.
- int current_line;
- // Current column number.
- int current_column;
- // Line map.
- Linemap* line_map;
-
- // Max column number that can be quickly allocated - higher may require allocating new linemap
- static const int max_column_hint = 80;
-
- // Input source wrapper thing.
- struct InputSource {
- // Input source file.
- FILE* input;
-
- // Create new input source from file.
- InputSource(FILE* input) : input(input) {}
-
- // Overload operator () to return next char from input stream.
- int operator()() {
- return fgetc(input);
- }
- };
-
- // The input source for the lexer.
- InputSource input_source;
- // Input file queue.
- buffered_queue<int, InputSource> input_queue;
-
- // Token source wrapper thing.
- struct TokenSource {
- // The lexer object that will use this TokenSource.
- Lexer* lexer;
-
- // Create a new TokenSource with given lexer.
- TokenSource(Lexer* parLexer) : lexer(parLexer) {}
-
- // Overload operator () to build token in lexer.
- TokenPtr operator()() {
- return lexer->build_token();
- }
- };
-
- // The token source for the lexer.
- TokenSource token_source;
- // Token stream queue.
- buffered_queue<std::shared_ptr<Token>, TokenSource> token_queue;
-
- // START CRAPPY CHANGES
- int current_char;
-
- // END CRAPPY CHANGES
- };
-}
+class Lexer
+{
+private:
+ // Request new Location for current column in line_table
+ Location get_current_location ();
+
+ // Skips the current input char.
+ void skip_input ();
+ // Advances current input char to n + 1 chars ahead of current position.
+ void skip_input (int n);
+
+ // Returns char n chars ahead of current position.
+ int peek_input ();
+ // Peeks the current char.
+ int peek_input (int n);
+
+ // Classifies keyword (i.e. gets id for keyword).
+ TokenId classify_keyword (const std::string &str);
+
+ // Builds a token from the input queue.
+ TokenPtr build_token ();
+
+ // ok maybe all these may mean the lexer structure needs to be rethought
+ /* separated into functions because main method was too long, but they rely on
+ * and change state in the lexer, so variables must be passed by reference. */
+ inline void parse_in_decimal (/*char& current_char, */ std::string &str,
+ int &length);
+ inline void parse_in_exponent_part (/*char& current_char, */ std::string &str,
+ int &length);
+ inline bool parse_in_type_suffix (
+ /*char& current_char, */ PrimitiveCoreType &type_hint, int &length);
+ inline bool parse_ascii_escape (/*char& current_char, */ int &length,
+ char &output_char);
+ inline bool parse_quote_escape (/*char& current_char, */ int &length,
+ char &output_char);
+ inline bool parse_unicode_escape (
+ /*char& current_char, */ int &length, Codepoint &output_char);
+ inline bool parse_byte_escape (/*char& current_char, */ int &length,
+ char &output_char);
+ inline bool parse_escape (int &length, char &output_char, char opening_char);
+ inline bool parse_utf8_escape (int &length, Codepoint &output_char,
+ char opening_char);
+ inline int test_get_input_codepoint_length ();
+ inline int test_get_input_codepoint_n_length (int n_start_offset);
+ inline Codepoint test_peek_codepoint_input ();
+ inline Codepoint test_peek_codepoint_input (
+ int n); // maybe can use get_input_codepoint_length to get starting index
+ inline void test_skip_codepoint_input ();
+
+public:
+ // Construct lexer with input file and filename provided
+ Lexer (const char *filename, FILE *input, Linemap *linemap);
+ ~Lexer ();
+
+ // Returns token n tokens ahead of current position.
+ const_TokenPtr peek_token (int n);
+ // Peeks the current token.
+ const_TokenPtr peek_token ();
+
+ // Advances current token to n + 1 tokens ahead of current position.
+ void skip_token (int n);
+ // Skips the current token.
+ void skip_token ();
+
+ // Replaces the current token with a specified token.
+ void replace_current_token (TokenPtr replacement);
+
+ Linemap *get_line_map () { return line_map; }
+
+private:
+ // File for use as input.
+ FILE *input;
+
+ // Current line number.
+ int current_line;
+ // Current column number.
+ int current_column;
+ // Line map.
+ Linemap *line_map;
+
+ // Max column number that can be quickly allocated - higher may require
+ // allocating new linemap
+ static const int max_column_hint = 80;
+
+ // Input source wrapper thing.
+ struct InputSource
+ {
+ // Input source file.
+ FILE *input;
+
+ // Create new input source from file.
+ InputSource (FILE *input) : input (input) {}
+
+ // Overload operator () to return next char from input stream.
+ int operator() () { return fgetc (input); }
+ };
+
+ // The input source for the lexer.
+ InputSource input_source;
+ // Input file queue.
+ buffered_queue<int, InputSource> input_queue;
+
+ // Token source wrapper thing.
+ struct TokenSource
+ {
+ // The lexer object that will use this TokenSource.
+ Lexer *lexer;
+
+ // Create a new TokenSource with given lexer.
+ TokenSource (Lexer *parLexer) : lexer (parLexer) {}
+
+ // Overload operator () to build token in lexer.
+ TokenPtr operator() () { return lexer->build_token (); }
+ };
+
+ // The token source for the lexer.
+ TokenSource token_source;
+ // Token stream queue.
+ buffered_queue<std::shared_ptr<Token>, TokenSource> token_queue;
+
+ // START CRAPPY CHANGES
+ int current_char;
+
+ // END CRAPPY CHANGES
+};
+} // namespace Rust
#endif
diff --git a/gcc/rust/lex/rust-token.cc b/gcc/rust/lex/rust-token.cc
index 4b71dd8..d8bd661 100644
--- a/gcc/rust/lex/rust-token.cc
+++ b/gcc/rust/lex/rust-token.cc
@@ -3,98 +3,114 @@
#include "rust-diagnostics.h" // for error_at
namespace Rust {
- // Hackily defined way to get token description for enum value using x-macros
- const char* get_token_description(TokenId id) {
- switch (id) {
-#define RS_TOKEN(name, descr) \
- case name: \
- return descr;
-#define RS_TOKEN_KEYWORD(x, y) RS_TOKEN(x, y)
- RS_TOKEN_LIST
+// Hackily defined way to get token description for enum value using x-macros
+const char *
+get_token_description (TokenId id)
+{
+ switch (id)
+ {
+#define RS_TOKEN(name, descr) \
+ case name: \
+ return descr;
+#define RS_TOKEN_KEYWORD(x, y) RS_TOKEN (x, y)
+ RS_TOKEN_LIST
#undef RS_TOKEN_KEYWORD
#undef RS_TOKEN
- default:
- gcc_unreachable();
- }
+ default:
+ gcc_unreachable ();
}
+}
- // Hackily defined way to get token description as a string for enum value using x-macros
- const char* token_id_to_str(TokenId id) {
- switch (id) {
-#define RS_TOKEN(name, _) \
- case name: \
- return #name;
-#define RS_TOKEN_KEYWORD(x, y) RS_TOKEN(x, y)
- RS_TOKEN_LIST
+// Hackily defined way to get token description as a string for enum value using
+// x-macros
+const char *
+token_id_to_str (TokenId id)
+{
+ switch (id)
+ {
+#define RS_TOKEN(name, _) \
+ case name: \
+ return #name;
+#define RS_TOKEN_KEYWORD(x, y) RS_TOKEN (x, y)
+ RS_TOKEN_LIST
#undef RS_TOKEN_KEYWORD
#undef RS_TOKEN
- default:
- gcc_unreachable();
- }
+ default:
+ gcc_unreachable ();
}
+}
- const char* get_type_hint_string(PrimitiveCoreType type) {
- switch (type) {
- case CORETYPE_BOOL:
- return "bool";
- case CORETYPE_CHAR:
- return "char";
- case CORETYPE_STR:
- return "str";
- // case CORETYPE_INT:
- case CORETYPE_ISIZE:
- return "isize";
- // case CORETYPE_UINT:
- case CORETYPE_USIZE:
- return "usize";
- case CORETYPE_F32:
- return "f32";
- case CORETYPE_F64:
- return "f64";
- case CORETYPE_I8:
- return "i8";
- case CORETYPE_I16:
- return "i16";
- case CORETYPE_I32:
- return "i32";
- case CORETYPE_I64:
- return "i64";
- case CORETYPE_I128:
- return "i128";
- case CORETYPE_U8:
- return "u8";
- case CORETYPE_U16:
- return "u16";
- case CORETYPE_U32:
- return "u32";
- case CORETYPE_U64:
- return "u64";
- case CORETYPE_U128:
- return "u128";
- case CORETYPE_UNKNOWN:
- default:
- return "unknown";
- }
+const char *
+get_type_hint_string (PrimitiveCoreType type)
+{
+ switch (type)
+ {
+ case CORETYPE_BOOL:
+ return "bool";
+ case CORETYPE_CHAR:
+ return "char";
+ case CORETYPE_STR:
+ return "str";
+ // case CORETYPE_INT:
+ case CORETYPE_ISIZE:
+ return "isize";
+ // case CORETYPE_UINT:
+ case CORETYPE_USIZE:
+ return "usize";
+ case CORETYPE_F32:
+ return "f32";
+ case CORETYPE_F64:
+ return "f64";
+ case CORETYPE_I8:
+ return "i8";
+ case CORETYPE_I16:
+ return "i16";
+ case CORETYPE_I32:
+ return "i32";
+ case CORETYPE_I64:
+ return "i64";
+ case CORETYPE_I128:
+ return "i128";
+ case CORETYPE_U8:
+ return "u8";
+ case CORETYPE_U16:
+ return "u16";
+ case CORETYPE_U32:
+ return "u32";
+ case CORETYPE_U64:
+ return "u64";
+ case CORETYPE_U128:
+ return "u128";
+ case CORETYPE_UNKNOWN:
+ default:
+ return "unknown";
}
+}
- const char* Token::get_type_hint_str() const {
- return get_type_hint_string(type_hint);
- }
+const char *
+Token::get_type_hint_str () const
+{
+ return get_type_hint_string (type_hint);
+}
- const ::std::string& Token::get_str() const {
- // FIXME: attempt to return null again
- // gcc_assert(str != NULL);
+const ::std::string &
+Token::get_str () const
+{
+ // FIXME: attempt to return null again
+ // gcc_assert(str != NULL);
- // HACK: allow referencing an empty string
- static const ::std::string empty = "";
+ // HACK: allow referencing an empty string
+ static const ::std::string empty = "";
- if (str == NULL) {
- rust_error_at(get_locus(),
- "attempted to get string for '%s', which has no string. returning empty string "
- "instead.",
- get_token_description());
- return empty;
- }
- return *str;
+ if (str == NULL)
+ {
+ rust_error_at (get_locus (),
+ "attempted to get string for '%s', which has no string. "
+ "returning empty string "
+ "instead.",
+ get_token_description ());
+ return empty;
}
+ return *str;
}
+} // namespace Rust
diff --git a/gcc/rust/lex/rust-token.h b/gcc/rust/lex/rust-token.h
index 13f4a18..2270fa2 100644
--- a/gcc/rust/lex/rust-token.h
+++ b/gcc/rust/lex/rust-token.h
@@ -16,371 +16,402 @@
#include "rust-codepoint.h"
namespace Rust {
- // "Primitive core types" in Rust - the different int and float types, as well as some others
- enum PrimitiveCoreType {
- CORETYPE_UNKNOWN,
- // named primitives
- CORETYPE_BOOL,
- CORETYPE_CHAR,
- CORETYPE_STR,
- // okay technically int and uint are arch-dependent (pointer size)
- CORETYPE_INT,
- CORETYPE_UINT,
- // numbered number primitives
- CORETYPE_F32,
- CORETYPE_F64,
- CORETYPE_I8,
- CORETYPE_I16,
- CORETYPE_I32,
- CORETYPE_I64,
- CORETYPE_I128,
- CORETYPE_U8,
- CORETYPE_U16,
- CORETYPE_U32,
- CORETYPE_U64,
- CORETYPE_U128,
- // arch-dependent pointer sizes
- CORETYPE_ISIZE = CORETYPE_INT,
- CORETYPE_USIZE = CORETYPE_UINT
- };
+// "Primitive core types" in Rust - the different int and float types, as well
+// as some others
+enum PrimitiveCoreType
+{
+ CORETYPE_UNKNOWN,
+ // named primitives
+ CORETYPE_BOOL,
+ CORETYPE_CHAR,
+ CORETYPE_STR,
+ // okay technically int and uint are arch-dependent (pointer size)
+ CORETYPE_INT,
+ CORETYPE_UINT,
+ // numbered number primitives
+ CORETYPE_F32,
+ CORETYPE_F64,
+ CORETYPE_I8,
+ CORETYPE_I16,
+ CORETYPE_I32,
+ CORETYPE_I64,
+ CORETYPE_I128,
+ CORETYPE_U8,
+ CORETYPE_U16,
+ CORETYPE_U32,
+ CORETYPE_U64,
+ CORETYPE_U128,
+ // arch-dependent pointer sizes
+ CORETYPE_ISIZE = CORETYPE_INT,
+ CORETYPE_USIZE = CORETYPE_UINT
+};
// RS_TOKEN(name, description)
// RS_TOKEN_KEYWORD(name, identifier)
//
// Keep RS_TOKEN_KEYWORD sorted
-// note that abstract, async, become, box, do, final, macro, override, priv, try, typeof, unsized,
-// virtual, and yield are unused
+// note that abstract, async, become, box, do, final, macro, override, priv,
+// try, typeof, unsized, virtual, and yield are unused
// TODO finish converting to rust keywords
-#define RS_TOKEN_LIST \
- RS_TOKEN(FIRST_TOKEN, "<first-token-marker>") \
- RS_TOKEN(END_OF_FILE, "end of file") \
- RS_TOKEN(EXCLAM, "!") \
- RS_TOKEN(NOT_EQUAL, "!=") \
- RS_TOKEN(PERCENT, "%") \
- RS_TOKEN(PERCENT_EQ, "%=") \
- RS_TOKEN(AMP, "&") \
- RS_TOKEN(AMP_EQ, "&=") \
- RS_TOKEN(LOGICAL_AND, "&&") \
- RS_TOKEN(ASTERISK, "*") \
- RS_TOKEN(ASTERISK_EQ, "*=") \
- RS_TOKEN(PLUS, "+") \
- RS_TOKEN(PLUS_EQ, "+=") \
- RS_TOKEN(COMMA, ",") \
- RS_TOKEN(MINUS, "-") \
- RS_TOKEN(MINUS_EQ, "-=") \
- RS_TOKEN(RETURN_TYPE, "->") \
- RS_TOKEN(DOT, ".") \
- RS_TOKEN(DOT_DOT, "..") \
- RS_TOKEN(DOT_DOT_EQ, "..=") \
- RS_TOKEN(ELLIPSIS, "...") \
- RS_TOKEN(DIV, "/") \
- RS_TOKEN(DIV_EQ, "/=") \
- RS_TOKEN(COLON, ":") \
- RS_TOKEN(SEMICOLON, ";") \
- RS_TOKEN(LEFT_SHIFT, "<<") \
- RS_TOKEN(LEFT_SHIFT_EQ, "<<=") \
- RS_TOKEN(LEFT_ANGLE, "<") \
- RS_TOKEN(LESS_OR_EQUAL, "<=") \
- RS_TOKEN(EQUAL, "=") \
- RS_TOKEN(EQUAL_EQUAL, "==") \
- RS_TOKEN(MATCH_ARROW, "=>") \
- RS_TOKEN(RIGHT_ANGLE, ">") \
- RS_TOKEN(GREATER_OR_EQUAL, ">=") \
- RS_TOKEN(RIGHT_SHIFT, ">>") \
- RS_TOKEN(RIGHT_SHIFT_EQ, ">>=") \
- RS_TOKEN(PATTERN_BIND, "@") \
- RS_TOKEN(TILDE, "~") \
- RS_TOKEN(BACKSLASH, "\\") \
- RS_TOKEN(BACKTICK, "`") \
- RS_TOKEN(CARET, "^") \
- RS_TOKEN(CARET_EQ, "^=") \
- RS_TOKEN(PIPE, "|") \
- RS_TOKEN(PIPE_EQ, "|=") \
- RS_TOKEN(OR, "||") \
- RS_TOKEN(QUESTION_MARK, "?") \
- RS_TOKEN(HASH, "#") \
- /* from here on, dodgy and may not be correct. not operators and may be symbols */ \
- /* RS_TOKEN(SPACE, " ") probably too dodgy */ \
- /* RS_TOKEN(NEWLINE, "\n")*/ \
- RS_TOKEN(SCOPE_RESOLUTION, "::") /* dodgy */ \
- RS_TOKEN(SINGLE_QUOTE, "'") /* should i differentiate from lifetime? */ \
- RS_TOKEN(DOUBLE_QUOTE, "\"") \
- RS_TOKEN(UNDERSCORE, "_") /* TODO: treat as reserved word like mrustc instead? */ \
- RS_TOKEN(IDENTIFIER, "identifier") \
- RS_TOKEN(INT_LITERAL, \
- "integer literal") /* do different int and float types need different literal types? */ \
- RS_TOKEN(FLOAT_LITERAL, "float literal") \
- RS_TOKEN(STRING_LITERAL, "string literal") \
- RS_TOKEN(CHAR_LITERAL, "character literal") \
- RS_TOKEN(BYTE_STRING_LITERAL, "byte string literal") \
- RS_TOKEN(BYTE_CHAR_LITERAL, "byte character literal") \
- RS_TOKEN(LIFETIME, "lifetime") /* TODO: improve token type */ \
- /* Have "interpolated" tokens (whatever that means)? identifer, path, type, pattern, */ \
- /* expression, statement, block, meta, item in mrustc (but not directly in lexer). */ \
- RS_TOKEN(LEFT_PAREN, "(") \
- RS_TOKEN(RIGHT_PAREN, ")") \
- RS_TOKEN(LEFT_CURLY, "{") \
- RS_TOKEN(RIGHT_CURLY, "}") \
- RS_TOKEN(LEFT_SQUARE, "[") \
- RS_TOKEN(RIGHT_SQUARE, "]") \
- /* Macros */ \
- RS_TOKEN(DOLLAR_SIGN, "$") \
- /* Comments */ \
- RS_TOKEN(LINE_COMMENT, "//") \
- RS_TOKEN(INNER_LINE_DOC, "//!") \
- RS_TOKEN(OUTER_LINE_DOC, "///") \
- RS_TOKEN(BLOCK_COMMENT_START, "/*") \
- RS_TOKEN(BLOCK_COMMENT_END, "*/") \
- RS_TOKEN(INNER_BLOCK_DOC_START, "/*!") \
- RS_TOKEN(OUTER_BLOCK_DOC_START, "/**") /* have "weak" union and 'static keywords? */ \
- \
- RS_TOKEN_KEYWORD(ABSTRACT, "abstract") /* unused */ \
- RS_TOKEN_KEYWORD(AS, "as") \
- RS_TOKEN_KEYWORD(ASYNC, "async") /* unused */ \
- RS_TOKEN_KEYWORD(BECOME, "become") /* unused */ \
- RS_TOKEN_KEYWORD(BOX, "box") /* unused */ \
- RS_TOKEN_KEYWORD(BREAK, "break") \
- RS_TOKEN_KEYWORD(CONST, "const") \
- RS_TOKEN_KEYWORD(CONTINUE, "continue") \
- RS_TOKEN_KEYWORD(CRATE, "crate") \
- RS_TOKEN_KEYWORD(DO, "do") /* unused */ \
- RS_TOKEN_KEYWORD(DYN, "dyn") \
- RS_TOKEN_KEYWORD(ELSE, "else") \
- RS_TOKEN_KEYWORD(ENUM_TOK, "enum") \
- RS_TOKEN_KEYWORD(EXTERN_TOK, "extern") \
- RS_TOKEN_KEYWORD(FALSE_LITERAL, "false") \
- RS_TOKEN_KEYWORD(FINAL_TOK, "final") /* unused */ \
- RS_TOKEN_KEYWORD(FN_TOK, "fn") \
- RS_TOKEN_KEYWORD(FOR, "for") \
- RS_TOKEN_KEYWORD(IF, "if") \
- RS_TOKEN_KEYWORD(IMPL, "impl") \
- RS_TOKEN_KEYWORD(IN, "in") \
- RS_TOKEN_KEYWORD(LET, "let") \
- RS_TOKEN_KEYWORD(LOOP, "loop") \
- RS_TOKEN_KEYWORD(MACRO, "macro") /* unused */ \
- RS_TOKEN_KEYWORD(MATCH_TOK, "match") \
- RS_TOKEN_KEYWORD(MOD, "mod") \
- RS_TOKEN_KEYWORD(MOVE, "move") \
- RS_TOKEN_KEYWORD(MUT, "mut") \
- RS_TOKEN_KEYWORD(OVERRIDE_TOK, "override") /* unused */ \
- RS_TOKEN_KEYWORD(PRIV, "priv") /* unused */ \
- RS_TOKEN_KEYWORD(PUB, "pub") \
- RS_TOKEN_KEYWORD(REF, "ref") \
- RS_TOKEN_KEYWORD(RETURN_TOK, "return") \
- RS_TOKEN_KEYWORD(SELF_ALIAS, "Self") /* mrustc does not treat this as a reserved word*/ \
- RS_TOKEN_KEYWORD(SELF, "self") \
- RS_TOKEN_KEYWORD(STATIC_TOK, "static") \
- RS_TOKEN_KEYWORD(STRUCT_TOK, "struct") \
- RS_TOKEN_KEYWORD(SUPER, "super") \
- RS_TOKEN_KEYWORD(TRAIT, "trait") \
- RS_TOKEN_KEYWORD(TRUE_LITERAL, "true") \
- RS_TOKEN_KEYWORD(TRY, "try") /* unused */ \
- RS_TOKEN_KEYWORD(TYPE, "type") \
- RS_TOKEN_KEYWORD(TYPEOF, "typeof") /* unused */ \
- RS_TOKEN_KEYWORD(UNSAFE, "unsafe") \
- RS_TOKEN_KEYWORD(UNSIZED, "unsized") /* unused */ \
- RS_TOKEN_KEYWORD(USE, "use") \
- RS_TOKEN_KEYWORD(VIRTUAL, "virtual") /* unused */ \
- RS_TOKEN_KEYWORD(WHERE, "where") \
- RS_TOKEN_KEYWORD(WHILE, "while") \
- RS_TOKEN_KEYWORD(YIELD, "yield") /* unused */ \
- \
- RS_TOKEN(LAST_TOKEN, "<last-token-marker>")
-
- // Contains all token types. Crappy implementation via x-macros.
- enum TokenId {
+#define RS_TOKEN_LIST \
+ RS_TOKEN (FIRST_TOKEN, "<first-token-marker>") \
+ RS_TOKEN (END_OF_FILE, "end of file") \
+ RS_TOKEN (EXCLAM, "!") \
+ RS_TOKEN (NOT_EQUAL, "!=") \
+ RS_TOKEN (PERCENT, "%") \
+ RS_TOKEN (PERCENT_EQ, "%=") \
+ RS_TOKEN (AMP, "&") \
+ RS_TOKEN (AMP_EQ, "&=") \
+ RS_TOKEN (LOGICAL_AND, "&&") \
+ RS_TOKEN (ASTERISK, "*") \
+ RS_TOKEN (ASTERISK_EQ, "*=") \
+ RS_TOKEN (PLUS, "+") \
+ RS_TOKEN (PLUS_EQ, "+=") \
+ RS_TOKEN (COMMA, ",") \
+ RS_TOKEN (MINUS, "-") \
+ RS_TOKEN (MINUS_EQ, "-=") \
+ RS_TOKEN (RETURN_TYPE, "->") \
+ RS_TOKEN (DOT, ".") \
+ RS_TOKEN (DOT_DOT, "..") \
+ RS_TOKEN (DOT_DOT_EQ, "..=") \
+ RS_TOKEN (ELLIPSIS, "...") \
+ RS_TOKEN (DIV, "/") \
+ RS_TOKEN (DIV_EQ, "/=") \
+ RS_TOKEN (COLON, ":") \
+ RS_TOKEN (SEMICOLON, ";") \
+ RS_TOKEN (LEFT_SHIFT, "<<") \
+ RS_TOKEN (LEFT_SHIFT_EQ, "<<=") \
+ RS_TOKEN (LEFT_ANGLE, "<") \
+ RS_TOKEN (LESS_OR_EQUAL, "<=") \
+ RS_TOKEN (EQUAL, "=") \
+ RS_TOKEN (EQUAL_EQUAL, "==") \
+ RS_TOKEN (MATCH_ARROW, "=>") \
+ RS_TOKEN (RIGHT_ANGLE, ">") \
+ RS_TOKEN (GREATER_OR_EQUAL, ">=") \
+ RS_TOKEN (RIGHT_SHIFT, ">>") \
+ RS_TOKEN (RIGHT_SHIFT_EQ, ">>=") \
+ RS_TOKEN (PATTERN_BIND, "@") \
+ RS_TOKEN (TILDE, "~") \
+ RS_TOKEN (BACKSLASH, "\\") \
+ RS_TOKEN (BACKTICK, "`") \
+ RS_TOKEN (CARET, "^") \
+ RS_TOKEN (CARET_EQ, "^=") \
+ RS_TOKEN (PIPE, "|") \
+ RS_TOKEN (PIPE_EQ, "|=") \
+ RS_TOKEN (OR, "||") \
+ RS_TOKEN (QUESTION_MARK, "?") \
+ RS_TOKEN (HASH, "#") \
+ /* from here on, dodgy and may not be correct. not operators and may be \
+ * symbols */ \
+ /* RS_TOKEN(SPACE, " ") probably too dodgy */ \
+ /* RS_TOKEN(NEWLINE, "\n")*/ \
+ RS_TOKEN (SCOPE_RESOLUTION, "::") /* dodgy */ \
+ RS_TOKEN (SINGLE_QUOTE, "'") /* should i differentiate from lifetime? */ \
+ RS_TOKEN (DOUBLE_QUOTE, "\"") \
+ RS_TOKEN (UNDERSCORE, \
+ "_") /* TODO: treat as reserved word like mrustc instead? */ \
+ RS_TOKEN (IDENTIFIER, "identifier") \
+ RS_TOKEN (INT_LITERAL, \
+ "integer literal") /* do different int and float types need \
+ different literal types? */ \
+ RS_TOKEN (FLOAT_LITERAL, "float literal") \
+ RS_TOKEN (STRING_LITERAL, "string literal") \
+ RS_TOKEN (CHAR_LITERAL, "character literal") \
+ RS_TOKEN (BYTE_STRING_LITERAL, "byte string literal") \
+ RS_TOKEN (BYTE_CHAR_LITERAL, "byte character literal") \
+ RS_TOKEN (LIFETIME, "lifetime") /* TODO: improve token type */ \
+ /* Have "interpolated" tokens (whatever that means)? identifer, path, type, \
+ * pattern, */ \
+ /* expression, statement, block, meta, item in mrustc (but not directly in \
+ * lexer). */ \
+ RS_TOKEN (LEFT_PAREN, "(") \
+ RS_TOKEN (RIGHT_PAREN, ")") \
+ RS_TOKEN (LEFT_CURLY, "{") \
+ RS_TOKEN (RIGHT_CURLY, "}") \
+ RS_TOKEN (LEFT_SQUARE, "[") \
+ RS_TOKEN (RIGHT_SQUARE, "]") \
+ /* Macros */ \
+ RS_TOKEN (DOLLAR_SIGN, "$") \
+ /* Comments */ \
+ RS_TOKEN (LINE_COMMENT, "//") \
+ RS_TOKEN (INNER_LINE_DOC, "//!") \
+ RS_TOKEN (OUTER_LINE_DOC, "///") \
+ RS_TOKEN (BLOCK_COMMENT_START, "/*") \
+ RS_TOKEN (BLOCK_COMMENT_END, "*/") \
+ RS_TOKEN (INNER_BLOCK_DOC_START, "/*!") \
+ RS_TOKEN (OUTER_BLOCK_DOC_START, \
+ "/**") /* have "weak" union and 'static keywords? */ \
+ \
+ RS_TOKEN_KEYWORD (ABSTRACT, "abstract") /* unused */ \
+ RS_TOKEN_KEYWORD (AS, "as") \
+ RS_TOKEN_KEYWORD (ASYNC, "async") /* unused */ \
+ RS_TOKEN_KEYWORD (BECOME, "become") /* unused */ \
+ RS_TOKEN_KEYWORD (BOX, "box") /* unused */ \
+ RS_TOKEN_KEYWORD (BREAK, "break") \
+ RS_TOKEN_KEYWORD (CONST, "const") \
+ RS_TOKEN_KEYWORD (CONTINUE, "continue") \
+ RS_TOKEN_KEYWORD (CRATE, "crate") \
+ RS_TOKEN_KEYWORD (DO, "do") /* unused */ \
+ RS_TOKEN_KEYWORD (DYN, "dyn") \
+ RS_TOKEN_KEYWORD (ELSE, "else") \
+ RS_TOKEN_KEYWORD (ENUM_TOK, "enum") \
+ RS_TOKEN_KEYWORD (EXTERN_TOK, "extern") \
+ RS_TOKEN_KEYWORD (FALSE_LITERAL, "false") \
+ RS_TOKEN_KEYWORD (FINAL_TOK, "final") /* unused */ \
+ RS_TOKEN_KEYWORD (FN_TOK, "fn") \
+ RS_TOKEN_KEYWORD (FOR, "for") \
+ RS_TOKEN_KEYWORD (IF, "if") \
+ RS_TOKEN_KEYWORD (IMPL, "impl") \
+ RS_TOKEN_KEYWORD (IN, "in") \
+ RS_TOKEN_KEYWORD (LET, "let") \
+ RS_TOKEN_KEYWORD (LOOP, "loop") \
+ RS_TOKEN_KEYWORD (MACRO, "macro") /* unused */ \
+ RS_TOKEN_KEYWORD (MATCH_TOK, "match") \
+ RS_TOKEN_KEYWORD (MOD, "mod") \
+ RS_TOKEN_KEYWORD (MOVE, "move") \
+ RS_TOKEN_KEYWORD (MUT, "mut") \
+ RS_TOKEN_KEYWORD (OVERRIDE_TOK, "override") /* unused */ \
+ RS_TOKEN_KEYWORD (PRIV, "priv") /* unused */ \
+ RS_TOKEN_KEYWORD (PUB, "pub") \
+ RS_TOKEN_KEYWORD (REF, "ref") \
+ RS_TOKEN_KEYWORD (RETURN_TOK, "return") \
+ RS_TOKEN_KEYWORD (SELF_ALIAS, \
+ "Self") /* mrustc does not treat this as a reserved word*/ \
+ RS_TOKEN_KEYWORD (SELF, "self") \
+ RS_TOKEN_KEYWORD (STATIC_TOK, "static") \
+ RS_TOKEN_KEYWORD (STRUCT_TOK, "struct") \
+ RS_TOKEN_KEYWORD (SUPER, "super") \
+ RS_TOKEN_KEYWORD (TRAIT, "trait") \
+ RS_TOKEN_KEYWORD (TRUE_LITERAL, "true") \
+ RS_TOKEN_KEYWORD (TRY, "try") /* unused */ \
+ RS_TOKEN_KEYWORD (TYPE, "type") \
+ RS_TOKEN_KEYWORD (TYPEOF, "typeof") /* unused */ \
+ RS_TOKEN_KEYWORD (UNSAFE, "unsafe") \
+ RS_TOKEN_KEYWORD (UNSIZED, "unsized") /* unused */ \
+ RS_TOKEN_KEYWORD (USE, "use") \
+ RS_TOKEN_KEYWORD (VIRTUAL, "virtual") /* unused */ \
+ RS_TOKEN_KEYWORD (WHERE, "where") \
+ RS_TOKEN_KEYWORD (WHILE, "while") \
+ RS_TOKEN_KEYWORD (YIELD, "yield") /* unused */ \
+ \
+ RS_TOKEN (LAST_TOKEN, "<last-token-marker>")
+
+// Contains all token types. Crappy implementation via x-macros.
+enum TokenId
+{
#define RS_TOKEN(name, _) name,
-#define RS_TOKEN_KEYWORD(x, y) RS_TOKEN(x, y)
- RS_TOKEN_LIST
+#define RS_TOKEN_KEYWORD(x, y) RS_TOKEN (x, y)
+ RS_TOKEN_LIST
#undef RS_TOKEN_KEYWORD
#undef RS_TOKEN
- };
-
- // dodgy "TokenPtr" declaration with Token forward declaration
- class Token;
- // A smart pointer (shared_ptr) to Token.
- typedef ::std::shared_ptr<Token> TokenPtr;
- // A smart pointer (shared_ptr) to a constant Token.
- typedef ::std::shared_ptr<const Token> const_TokenPtr;
-
- // Hackily defined way to get token description for enum value using x-macros
- const char* get_token_description(TokenId id);
- // Hackily defined way to get token description as a string for enum value using x-macros
- const char* token_id_to_str(TokenId id);
- // Get type hint description as a string.
- const char* get_type_hint_string(PrimitiveCoreType type);
-
- // Represents a single token. Create using factory static methods.
- class Token {
- private:
- // Token kind.
- TokenId token_id;
- // Token location.
- Location locus;
- // Associated text (if any) of token.
- ::std::string* str;
- // Type hint for token based on lexer data (e.g. type suffix). Does not exist for most tokens.
- PrimitiveCoreType type_hint;
-
- // Token constructor from token id and location. Has a null string.
- Token(TokenId token_id, Location location) :
- token_id(token_id), locus(location), str(NULL), type_hint(CORETYPE_UNKNOWN) {}
-
- // Token constructor from token id, location, and a string.
- Token(TokenId token_id, Location location, const ::std::string& paramStr) :
- token_id(token_id), locus(location), str(new ::std::string(paramStr)),
- type_hint(CORETYPE_UNKNOWN) {}
-
- // Token constructor from token id, location, and a char.
- Token(TokenId token_id, Location location, char paramChar) :
- token_id(token_id), locus(location), str(new ::std::string(1, paramChar)),
- type_hint(CORETYPE_UNKNOWN) {}
-
- // Token constructor from token id, location, and a "codepoint".
- Token(TokenId token_id, Location location, Codepoint paramCodepoint) :
- token_id(token_id), locus(location), str(new ::std::string(paramCodepoint.as_string())),
- type_hint(CORETYPE_UNKNOWN) {}
-
- // Token constructor from token id, location, a string, and type hint.
- Token(TokenId token_id, Location location, const ::std::string& paramStr,
- PrimitiveCoreType parType) :
- token_id(token_id),
- locus(location), str(new ::std::string(paramStr)), type_hint(parType) {}
-
- // No default initialiser.
- Token();
- // Do not copy/assign tokens.
- Token(const Token&);
- Token& operator=(const Token&);
-
- public:
- ~Token() {
- delete str;
- }
-
- // Makes and returns a new TokenPtr (with null string).
- static TokenPtr make(TokenId token_id, Location locus) {
- return TokenPtr(new Token(token_id, locus));
- }
-
- // Makes and returns a new TokenPtr of type IDENTIFIER.
- static TokenPtr make_identifier(Location locus, const ::std::string& str) {
- return TokenPtr(new Token(IDENTIFIER, locus, str));
- }
-
- // Makes and returns a new TokenPtr of type INT_LITERAL.
- static TokenPtr make_int(Location locus, const ::std::string& str) {
- return TokenPtr(new Token(INT_LITERAL, locus, str));
- }
-
- // Makes and returns a new TokenPtr of type INT_LITERAL.
- static TokenPtr make_int(
- Location locus, const ::std::string& str, PrimitiveCoreType type_hint) {
- return TokenPtr(new Token(INT_LITERAL, locus, str, type_hint));
- }
-
- // Makes and returns a new TokenPtr of type FLOAT_LITERAL.
- static TokenPtr make_float(Location locus, const ::std::string& str) {
- return TokenPtr(new Token(FLOAT_LITERAL, locus, str));
- }
-
- // Makes and returns a new TokenPtr of type FLOAT_LITERAL.
- static TokenPtr make_float(
- Location locus, const ::std::string& str, PrimitiveCoreType type_hint) {
- return TokenPtr(new Token(FLOAT_LITERAL, locus, str, type_hint));
- }
-
- // Makes and returns a new TokenPtr of type STRING_LITERAL.
- static TokenPtr make_string(Location locus, const ::std::string& str) {
- return TokenPtr(new Token(STRING_LITERAL, locus, str, CORETYPE_STR));
- }
-
- // Makes and returns a new TokenPtr of type CHAR_LITERAL (fix).
- static TokenPtr make_char(Location locus, Codepoint char_lit) {
- return TokenPtr(new Token(CHAR_LITERAL, locus, char_lit));
- }
-
- // Makes and returns a new TokenPtr of type BYTE_CHAR_LITERAL (fix).
- static TokenPtr make_byte_char(Location locus, char byte_char) {
- return TokenPtr(new Token(BYTE_CHAR_LITERAL, locus, byte_char));
- }
-
- // Makes and returns a new TokenPtr of type BYTE_STRING_LITERAL (fix).
- static TokenPtr make_byte_string(Location locus, const ::std::string& str) {
- return TokenPtr(new Token(BYTE_STRING_LITERAL, locus, str));
- }
-
- // Makes and returns a new TokenPtr of type LIFETIME.
- static TokenPtr make_lifetime(Location locus, const ::std::string& str) {
- return TokenPtr(new Token(LIFETIME, locus, str));
- }
-
- // Gets id of the token.
- TokenId get_id() const {
- return token_id;
- }
-
- // Gets location of the token.
- Location get_locus() const {
- return locus;
- }
-
- // Gets string description of the token.
- const ::std::string& get_str() const; /*{
- // FIXME: put in header again when fix null problem
- //gcc_assert(str != NULL);
- if (str == NULL) {
- error_at(get_locus(), "attempted to get string for '%s', which has no string. returning empty string instead.", get_token_description());
- return "";
- }
- return *str;
- }*/
-
- // Gets token's type hint info.
- PrimitiveCoreType get_type_hint() const {
- return type_hint;
- }
-
- // diagnostics (error reporting)
- const char* get_token_description() const {
- return Rust::get_token_description(token_id);
- }
-
- // debugging
- const char* token_id_to_str() const {
- return Rust::token_id_to_str(token_id);
- }
-
- // debugging
- const char* get_type_hint_str() const;
-
- /* Returns whether the token is a literal of any type (int, float, char, string, byte char,
- * byte string). */
- inline bool is_literal() const {
- switch (token_id) {
- case INT_LITERAL:
- case FLOAT_LITERAL:
- case CHAR_LITERAL:
- case STRING_LITERAL:
- case BYTE_CHAR_LITERAL:
- case BYTE_STRING_LITERAL:
- return true;
- default:
- return false;
- }
- }
-
- // Returns whether the token actually has a string (regardless of whether it should or not).
- inline bool has_str() const {
- return str != NULL;
- }
-
- // Returns whether the token should have a string.
- inline bool should_have_str() const {
- return is_literal() || token_id == IDENTIFIER || token_id == LIFETIME;
- }
- };
+};
+
+// dodgy "TokenPtr" declaration with Token forward declaration
+class Token;
+// A smart pointer (shared_ptr) to Token.
+typedef ::std::shared_ptr<Token> TokenPtr;
+// A smart pointer (shared_ptr) to a constant Token.
+typedef ::std::shared_ptr<const Token> const_TokenPtr;
+
+// Hackily defined way to get token description for enum value using x-macros
+const char *
+get_token_description (TokenId id);
+// Hackily defined way to get token description as a string for enum value using
+// x-macros
+const char *
+token_id_to_str (TokenId id);
+// Get type hint description as a string.
+const char *
+get_type_hint_string (PrimitiveCoreType type);
+
+// Represents a single token. Create using factory static methods.
+class Token
+{
+private:
+ // Token kind.
+ TokenId token_id;
+ // Token location.
+ Location locus;
+ // Associated text (if any) of token.
+ ::std::string *str;
+ // Type hint for token based on lexer data (e.g. type suffix). Does not exist
+ // for most tokens.
+ PrimitiveCoreType type_hint;
+
+ // Token constructor from token id and location. Has a null string.
+ Token (TokenId token_id, Location location)
+ : token_id (token_id), locus (location), str (NULL),
+ type_hint (CORETYPE_UNKNOWN)
+ {}
+
+ // Token constructor from token id, location, and a string.
+ Token (TokenId token_id, Location location, const ::std::string &paramStr)
+ : token_id (token_id), locus (location), str (new ::std::string (paramStr)),
+ type_hint (CORETYPE_UNKNOWN)
+ {}
+
+ // Token constructor from token id, location, and a char.
+ Token (TokenId token_id, Location location, char paramChar)
+ : token_id (token_id), locus (location),
+ str (new ::std::string (1, paramChar)), type_hint (CORETYPE_UNKNOWN)
+ {}
+
+ // Token constructor from token id, location, and a "codepoint".
+ Token (TokenId token_id, Location location, Codepoint paramCodepoint)
+ : token_id (token_id), locus (location),
+ str (new ::std::string (paramCodepoint.as_string ())),
+ type_hint (CORETYPE_UNKNOWN)
+ {}
+
+ // Token constructor from token id, location, a string, and type hint.
+ Token (TokenId token_id, Location location, const ::std::string &paramStr,
+ PrimitiveCoreType parType)
+ : token_id (token_id), locus (location), str (new ::std::string (paramStr)),
+ type_hint (parType)
+ {}
+
+ // No default initialiser.
+ Token ();
+ // Do not copy/assign tokens.
+ Token (const Token &);
+ Token &operator= (const Token &);
+
+public:
+ ~Token () { delete str; }
+
+ // Makes and returns a new TokenPtr (with null string).
+ static TokenPtr make (TokenId token_id, Location locus)
+ {
+ return TokenPtr (new Token (token_id, locus));
+ }
+
+ // Makes and returns a new TokenPtr of type IDENTIFIER.
+ static TokenPtr make_identifier (Location locus, const ::std::string &str)
+ {
+ return TokenPtr (new Token (IDENTIFIER, locus, str));
+ }
+
+ // Makes and returns a new TokenPtr of type INT_LITERAL.
+ static TokenPtr make_int (Location locus, const ::std::string &str)
+ {
+ return TokenPtr (new Token (INT_LITERAL, locus, str));
+ }
+
+ // Makes and returns a new TokenPtr of type INT_LITERAL.
+ static TokenPtr make_int (Location locus, const ::std::string &str,
+ PrimitiveCoreType type_hint)
+ {
+ return TokenPtr (new Token (INT_LITERAL, locus, str, type_hint));
+ }
+
+ // Makes and returns a new TokenPtr of type FLOAT_LITERAL.
+ static TokenPtr make_float (Location locus, const ::std::string &str)
+ {
+ return TokenPtr (new Token (FLOAT_LITERAL, locus, str));
+ }
+
+ // Makes and returns a new TokenPtr of type FLOAT_LITERAL.
+ static TokenPtr make_float (Location locus, const ::std::string &str,
+ PrimitiveCoreType type_hint)
+ {
+ return TokenPtr (new Token (FLOAT_LITERAL, locus, str, type_hint));
+ }
+
+ // Makes and returns a new TokenPtr of type STRING_LITERAL.
+ static TokenPtr make_string (Location locus, const ::std::string &str)
+ {
+ return TokenPtr (new Token (STRING_LITERAL, locus, str, CORETYPE_STR));
+ }
+
+ // Makes and returns a new TokenPtr of type CHAR_LITERAL (fix).
+ static TokenPtr make_char (Location locus, Codepoint char_lit)
+ {
+ return TokenPtr (new Token (CHAR_LITERAL, locus, char_lit));
+ }
+
+ // Makes and returns a new TokenPtr of type BYTE_CHAR_LITERAL (fix).
+ static TokenPtr make_byte_char (Location locus, char byte_char)
+ {
+ return TokenPtr (new Token (BYTE_CHAR_LITERAL, locus, byte_char));
+ }
+
+ // Makes and returns a new TokenPtr of type BYTE_STRING_LITERAL (fix).
+ static TokenPtr make_byte_string (Location locus, const ::std::string &str)
+ {
+ return TokenPtr (new Token (BYTE_STRING_LITERAL, locus, str));
+ }
+
+ // Makes and returns a new TokenPtr of type LIFETIME.
+ static TokenPtr make_lifetime (Location locus, const ::std::string &str)
+ {
+ return TokenPtr (new Token (LIFETIME, locus, str));
+ }
+
+ // Gets id of the token.
+ TokenId get_id () const { return token_id; }
+
+ // Gets location of the token.
+ Location get_locus () const { return locus; }
+
+ // Gets string description of the token.
+ const ::std::string &
+ get_str () const; /*{
+// FIXME: put in header again when fix null problem
+//gcc_assert(str != NULL);
+if (str == NULL) {
+error_at(get_locus(), "attempted to get string for '%s', which has no string.
+returning empty string instead.", get_token_description()); return "";
}
+return *str;
+}*/
+
+ // Gets token's type hint info.
+ PrimitiveCoreType get_type_hint () const { return type_hint; }
+
+ // diagnostics (error reporting)
+ const char *get_token_description () const
+ {
+ return Rust::get_token_description (token_id);
+ }
+
+ // debugging
+ const char *token_id_to_str () const
+ {
+ return Rust::token_id_to_str (token_id);
+ }
+
+ // debugging
+ const char *get_type_hint_str () const;
+
+ /* Returns whether the token is a literal of any type (int, float, char,
+ * string, byte char, byte string). */
+ inline bool is_literal () const
+ {
+ switch (token_id)
+ {
+ case INT_LITERAL:
+ case FLOAT_LITERAL:
+ case CHAR_LITERAL:
+ case STRING_LITERAL:
+ case BYTE_CHAR_LITERAL:
+ case BYTE_STRING_LITERAL:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ // Returns whether the token actually has a string (regardless of whether it
+ // should or not).
+ inline bool has_str () const { return str != NULL; }
+
+ // Returns whether the token should have a string.
+ inline bool should_have_str () const
+ {
+ return is_literal () || token_id == IDENTIFIER || token_id == LIFETIME;
+ }
+};
+} // namespace Rust
#endif
diff --git a/gcc/rust/operator.h b/gcc/rust/operator.h
index 560f4bb..49add60 100644
--- a/gcc/rust/operator.h
+++ b/gcc/rust/operator.h
@@ -9,60 +9,61 @@
// The operators.
-// TODO: Will have to be significantly modified to work with Rust and current setup of gccrs
+// TODO: Will have to be significantly modified to work with Rust and current
+// setup of gccrs
enum Operator
{
OPERATOR_INVALID,
- OPERATOR_OROR, // ||
- OPERATOR_ANDAND, // &&
- OPERATOR_EQEQ, // ==
- OPERATOR_NOTEQ, // !=
- OPERATOR_LT, // <
- OPERATOR_LE, // <=
- OPERATOR_GT, // >
- OPERATOR_GE, // >=
- OPERATOR_PLUS, // +
- OPERATOR_MINUS, // -
- OPERATOR_OR, // |
- OPERATOR_XOR, // ^
- OPERATOR_MULT, // *
- OPERATOR_DIV, // /
- OPERATOR_MOD, // %
- OPERATOR_LSHIFT, // <<
- OPERATOR_RSHIFT, // >>
- OPERATOR_AND, // &
- OPERATOR_NOT, // !
- OPERATOR_BITCLEAR, // &^
- OPERATOR_CHANOP, // <-
+ OPERATOR_OROR, // ||
+ OPERATOR_ANDAND, // &&
+ OPERATOR_EQEQ, // ==
+ OPERATOR_NOTEQ, // !=
+ OPERATOR_LT, // <
+ OPERATOR_LE, // <=
+ OPERATOR_GT, // >
+ OPERATOR_GE, // >=
+ OPERATOR_PLUS, // +
+ OPERATOR_MINUS, // -
+ OPERATOR_OR, // |
+ OPERATOR_XOR, // ^
+ OPERATOR_MULT, // *
+ OPERATOR_DIV, // /
+ OPERATOR_MOD, // %
+ OPERATOR_LSHIFT, // <<
+ OPERATOR_RSHIFT, // >>
+ OPERATOR_AND, // &
+ OPERATOR_NOT, // !
+ OPERATOR_BITCLEAR, // &^
+ OPERATOR_CHANOP, // <-
- OPERATOR_EQ, // =
- OPERATOR_PLUSEQ, // +=
- OPERATOR_MINUSEQ, // -=
- OPERATOR_OREQ, // |=
- OPERATOR_XOREQ, // ^=
- OPERATOR_MULTEQ, // *=
- OPERATOR_DIVEQ, // /=
- OPERATOR_MODEQ, // %=
- OPERATOR_LSHIFTEQ, // <<=
- OPERATOR_RSHIFTEQ, // >>=
- OPERATOR_ANDEQ, // &=
- OPERATOR_BITCLEAREQ, // &^=
- OPERATOR_PLUSPLUS, // ++
- OPERATOR_MINUSMINUS, // --
+ OPERATOR_EQ, // =
+ OPERATOR_PLUSEQ, // +=
+ OPERATOR_MINUSEQ, // -=
+ OPERATOR_OREQ, // |=
+ OPERATOR_XOREQ, // ^=
+ OPERATOR_MULTEQ, // *=
+ OPERATOR_DIVEQ, // /=
+ OPERATOR_MODEQ, // %=
+ OPERATOR_LSHIFTEQ, // <<=
+ OPERATOR_RSHIFTEQ, // >>=
+ OPERATOR_ANDEQ, // &=
+ OPERATOR_BITCLEAREQ, // &^=
+ OPERATOR_PLUSPLUS, // ++
+ OPERATOR_MINUSMINUS, // --
- OPERATOR_COLON, // :
- OPERATOR_COLONEQ, // :=
- OPERATOR_SEMICOLON, // ;
- OPERATOR_DOT, // .
- OPERATOR_ELLIPSIS, // ...
- OPERATOR_COMMA, // ,
- OPERATOR_LPAREN, // (
- OPERATOR_RPAREN, // )
- OPERATOR_LCURLY, // {
- OPERATOR_RCURLY, // }
- OPERATOR_LSQUARE, // [
- OPERATOR_RSQUARE // ]
+ OPERATOR_COLON, // :
+ OPERATOR_COLONEQ, // :=
+ OPERATOR_SEMICOLON, // ;
+ OPERATOR_DOT, // .
+ OPERATOR_ELLIPSIS, // ...
+ OPERATOR_COMMA, // ,
+ OPERATOR_LPAREN, // (
+ OPERATOR_RPAREN, // )
+ OPERATOR_LCURLY, // {
+ OPERATOR_RCURLY, // }
+ OPERATOR_LSQUARE, // [
+ OPERATOR_RSQUARE // ]
};
#endif // !defined(GO_OPERATOR_H)
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index ca84659..5bc62d3 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -5,455 +5,563 @@
#include "rust-ast-full.h"
namespace Rust {
- /* HACK: used to resolve the expression-or-statement problem at the end of a block by allowing
- * either to be returned (technically). Tagged union would probably take up the same amount of
- * space. */
- struct ExprOrStmt {
- ::std::unique_ptr<AST::ExprWithoutBlock> expr;
- ::std::unique_ptr<AST::Stmt> stmt;
-
- /* I was going to resist the urge to make this a real class and make it POD, but construction
- * in steps is too difficult. So it'll just also have a constructor. */
-
- // expression constructor
- ExprOrStmt(::std::unique_ptr<AST::ExprWithoutBlock> expr) : expr(::std::move(expr)) {}
-
- // statement constructor
- ExprOrStmt(::std::unique_ptr<AST::Stmt> stmt) : stmt(::std::move(stmt)) {}
-
- // Returns whether this object is in an error state.
- inline bool is_error() const {
- return (expr == NULL && stmt == NULL) || (expr != NULL && stmt != NULL);
- }
-
- // Returns an error state object.
- static ExprOrStmt create_error() {
- return ExprOrStmt(NULL, NULL);
- }
-
- ~ExprOrStmt() = default;
-
- // no copy constructors/assignment copy as simple object like this shouldn't require it
-
- // move constructors
- ExprOrStmt(ExprOrStmt&& other) = default;
- ExprOrStmt& operator=(ExprOrStmt&& other) = default;
-
- private:
- // private constructor only used for creating error state expr or stmt objects
- ExprOrStmt(AST::ExprWithoutBlock* expr, AST::Stmt* stmt) : expr(expr), stmt(stmt) {}
-
- // make this work: have a disambiguation specifically for known statements (i.e. ';' and
- // 'let'). then, have a special "parse expr or stmt" function that returns this type. inside
- // it, it parses an expression, and then determines whether to return expr or stmt via whether
- // the next token is a semicolon. should be able to disambiguate inside that function between
- // stmts with blocks and without blocks.
- };
-
- /* Restrictions on parsing used to signal that certain ambiguous grammar features should be parsed
- * in a certain way.*/
- struct ParseRestrictions {
- bool can_be_struct_expr = true;
- /* Whether the expression was entered from a unary expression - prevents stuff like struct
- * exprs being parsed from a dereference. */
- bool entered_from_unary = false;
- };
-
- // Parser implementation for gccrs.
- class Parser {
- private:
- void skip_after_semicolon();
- void skip_after_end();
- void skip_after_end_block();
- void skip_after_next_block();
- void skip_after_end_attribute();
-
- bool skip_token(TokenId t);
- const_TokenPtr expect_token(TokenId t);
- void unexpected_token(const_TokenPtr t);
- bool skip_generics_right_angle();
-
- void parse_statement_seq(bool (Parser::*done)());
-
- // AST-related stuff - maybe move or something?
- ::std::vector<AST::Attribute> parse_inner_attributes();
- AST::Attribute parse_inner_attribute();
- ::std::vector<AST::Attribute> parse_outer_attributes();
- AST::Attribute parse_outer_attribute();
- AST::Attribute parse_attribute_body();
- ::std::unique_ptr<AST::AttrInput> parse_attr_input();
-
- // Path-related
- AST::SimplePath parse_simple_path();
- AST::SimplePathSegment parse_simple_path_segment();
- AST::TypePath parse_type_path();
- ::std::unique_ptr<AST::TypePathSegment> parse_type_path_segment();
- AST::PathIdentSegment parse_path_ident_segment();
- AST::GenericArgs parse_path_generic_args();
- AST::GenericArgsBinding parse_generic_args_binding();
- AST::TypePathFunction parse_type_path_function();
- AST::PathInExpression parse_path_in_expression();
- AST::PathExprSegment parse_path_expr_segment();
- AST::QualifiedPathInExpression parse_qualified_path_in_expression(bool pratt_parse = false);
- AST::QualifiedPathType parse_qualified_path_type(bool pratt_parse = false);
- AST::QualifiedPathInType parse_qualified_path_in_type();
-
- // Token tree or macro related
- AST::DelimTokenTree parse_delim_token_tree();
- ::std::unique_ptr<AST::TokenTree> parse_token_tree();
- ::std::unique_ptr<AST::MacroRulesDefinition> parse_macro_rules_def(
- ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::MacroInvocationSemi> parse_macro_invocation_semi(
- ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::MacroInvocation> parse_macro_invocation(
- ::std::vector<AST::Attribute> outer_attrs);
- AST::MacroRule parse_macro_rule();
- AST::MacroMatcher parse_macro_matcher();
- ::std::unique_ptr<AST::MacroMatch> parse_macro_match();
- ::std::unique_ptr<AST::MacroMatchFragment> parse_macro_match_fragment();
- ::std::unique_ptr<AST::MacroMatchRepetition> parse_macro_match_repetition();
-
- // Top-level item-related
- ::std::vector< ::std::unique_ptr<AST::Item> > parse_items();
- ::std::unique_ptr<AST::Item> parse_item(bool called_from_statement);
- ::std::unique_ptr<AST::VisItem> parse_vis_item(::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::MacroItem> parse_macro_item(::std::vector<AST::Attribute> outer_attrs);
- AST::Visibility parse_visibility();
-
- // VisItem subclass-related
- ::std::unique_ptr<AST::Module> parse_module(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::ExternCrate> parse_extern_crate(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::UseDeclaration> parse_use_decl(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::UseTree> parse_use_tree();
- ::std::unique_ptr<AST::Function> parse_function(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- AST::FunctionQualifiers parse_function_qualifiers();
- ::std::vector< ::std::unique_ptr<AST::GenericParam> > parse_generic_params_in_angles();
- ::std::vector< ::std::unique_ptr<AST::GenericParam> > parse_generic_params();
- ::std::vector< ::std::unique_ptr<AST::LifetimeParam> > parse_lifetime_params();
- ::std::vector<AST::LifetimeParam> parse_lifetime_params_objs();
- AST::LifetimeParam parse_lifetime_param();
- ::std::vector< ::std::unique_ptr<AST::TypeParam> > parse_type_params();
- ::std::unique_ptr<AST::TypeParam> parse_type_param();
- ::std::vector<AST::FunctionParam> parse_function_params();
- AST::FunctionParam parse_function_param();
- ::std::unique_ptr<AST::Type> parse_function_return_type();
- AST::WhereClause parse_where_clause();
- ::std::unique_ptr<AST::WhereClauseItem> parse_where_clause_item();
- ::std::unique_ptr<AST::LifetimeWhereClauseItem> parse_lifetime_where_clause_item();
- ::std::unique_ptr<AST::TypeBoundWhereClauseItem> parse_type_bound_where_clause_item();
- ::std::vector<AST::LifetimeParam> parse_for_lifetimes();
- ::std::vector< ::std::unique_ptr<AST::TypeParamBound> > parse_type_param_bounds();
- ::std::unique_ptr<AST::TypeParamBound> parse_type_param_bound();
- ::std::unique_ptr<AST::TraitBound> parse_trait_bound();
- ::std::vector<AST::Lifetime> parse_lifetime_bounds();
- AST::Lifetime parse_lifetime();
- ::std::unique_ptr<AST::TypeAlias> parse_type_alias(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::Struct> parse_struct(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::vector<AST::StructField> parse_struct_fields();
- AST::StructField parse_struct_field();
- ::std::vector<AST::TupleField> parse_tuple_fields();
- AST::TupleField parse_tuple_field();
- ::std::unique_ptr<AST::Enum> parse_enum(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::vector< ::std::unique_ptr<AST::EnumItem> > parse_enum_items();
- ::std::unique_ptr<AST::EnumItem> parse_enum_item();
- ::std::unique_ptr<AST::Union> parse_union(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::ConstantItem> parse_const_item(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::StaticItem> parse_static_item(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::Trait> parse_trait(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::TraitItem> parse_trait_item();
- ::std::unique_ptr<AST::TraitItemType> parse_trait_type(
- ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::TraitItemConst> parse_trait_const(
- ::std::vector<AST::Attribute> outer_attrs);
- AST::SelfParam parse_self_param();
- ::std::unique_ptr<AST::Impl> parse_impl(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::InherentImplItem> parse_inherent_impl_item();
- ::std::unique_ptr<AST::InherentImplItem> parse_inherent_impl_function_or_method(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::TraitImplItem> parse_trait_impl_item();
- ::std::unique_ptr<AST::TraitImplItem> parse_trait_impl_function_or_method(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::ExternBlock> parse_extern_block(
- AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::ExternalItem> parse_external_item();
- AST::NamedFunctionParam parse_named_function_param();
- AST::Method parse_method();
-
- // Expression-related (Pratt parsed)
- ::std::unique_ptr<AST::Expr> parse_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::Expr> parse_expr(int right_binding_power,
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::Expr> null_denotation_NEW(const_TokenPtr t,
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::Expr> left_denotation(const_TokenPtr t,
- ::std::unique_ptr<AST::Expr> left,
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ArithmeticOrLogicalExpr> parse_binary_plus_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ArithmeticOrLogicalExpr> parse_binary_minus_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ArithmeticOrLogicalExpr> parse_binary_mult_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ArithmeticOrLogicalExpr> parse_binary_div_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ArithmeticOrLogicalExpr> parse_binary_mod_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ArithmeticOrLogicalExpr> parse_bitwise_and_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ArithmeticOrLogicalExpr> parse_bitwise_or_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ArithmeticOrLogicalExpr> parse_bitwise_xor_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ArithmeticOrLogicalExpr> parse_left_shift_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ArithmeticOrLogicalExpr> parse_right_shift_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ComparisonExpr> parse_binary_equal_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ComparisonExpr> parse_binary_not_equal_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ComparisonExpr> parse_binary_greater_than_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ComparisonExpr> parse_binary_less_than_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ComparisonExpr> parse_binary_greater_equal_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ComparisonExpr> parse_binary_less_equal_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::LazyBooleanExpr> parse_lazy_or_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::LazyBooleanExpr> parse_lazy_and_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::TypeCastExpr> parse_type_cast_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> expr_to_cast, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::AssignmentExpr> parse_assig_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::CompoundAssignmentExpr> parse_plus_assig_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::CompoundAssignmentExpr> parse_minus_assig_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::CompoundAssignmentExpr> parse_mult_assig_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::CompoundAssignmentExpr> parse_div_assig_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::CompoundAssignmentExpr> parse_mod_assig_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::CompoundAssignmentExpr> parse_and_assig_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::CompoundAssignmentExpr> parse_or_assig_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::CompoundAssignmentExpr> parse_xor_assig_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::CompoundAssignmentExpr> parse_left_shift_assig_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::CompoundAssignmentExpr> parse_right_shift_assig_expr(
- const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
- ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::AwaitExpr> parse_await_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> expr_to_await, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::MethodCallExpr> parse_method_call_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> receiver_expr, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::CallExpr> parse_function_call_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> function_expr, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::RangeExpr> parse_led_range_exclusive_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::RangeExpr> parse_nud_range_exclusive_expr(
- const_TokenPtr tok, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::RangeFromToInclExpr> parse_range_inclusive_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> left, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::RangeToInclExpr> parse_range_to_inclusive_expr(
- const_TokenPtr tok, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::TupleIndexExpr> parse_tuple_index_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> tuple_expr, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::FieldAccessExpr> parse_field_access_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> struct_expr, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::ArrayIndexExpr> parse_index_expr(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> array_expr, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
- ::std::unique_ptr<AST::MacroInvocation> parse_macro_invocation_partial(
- AST::PathInExpression path, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::StructExprStruct> parse_struct_expr_struct_partial(
- AST::PathInExpression path, ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::StructExprTuple> parse_struct_expr_tuple_partial(
- AST::PathInExpression path, ::std::vector<AST::Attribute> outer_attrs);
- AST::PathInExpression parse_path_in_expression_pratt(const_TokenPtr tok);
- ::std::unique_ptr<AST::ClosureExpr> parse_closure_expr_pratt(const_TokenPtr tok,
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>());
- ::std::unique_ptr<AST::TupleIndexExpr> parse_tuple_index_expr_float(const_TokenPtr tok,
- ::std::unique_ptr<AST::Expr> tuple_expr, ::std::vector<AST::Attribute> outer_attrs,
- ParseRestrictions restrictions = ParseRestrictions());
-
- // Expression-related (non-Pratt parsed)
- ::std::unique_ptr<AST::ExprWithoutBlock> parse_expr_without_block(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>());
- ::std::unique_ptr<AST::BlockExpr> parse_block_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- bool pratt_parse = false);
- ::std::unique_ptr<AST::IfExpr> parse_if_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>());
- ::std::unique_ptr<AST::IfLetExpr> parse_if_let_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>());
- ::std::unique_ptr<AST::LoopExpr> parse_loop_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- AST::LoopLabel label = AST::LoopLabel::error());
- ::std::unique_ptr<AST::WhileLoopExpr> parse_while_loop_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- AST::LoopLabel label = AST::LoopLabel::error());
- ::std::unique_ptr<AST::WhileLetLoopExpr> parse_while_let_loop_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- AST::LoopLabel label = AST::LoopLabel::error());
- ::std::unique_ptr<AST::ForLoopExpr> parse_for_loop_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- AST::LoopLabel label = AST::LoopLabel::error());
- ::std::unique_ptr<AST::MatchExpr> parse_match_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- bool pratt_parse = false);
- AST::MatchArm parse_match_arm();
- ::std::vector< ::std::unique_ptr<AST::Pattern> > parse_match_arm_patterns(
- TokenId end_token_id);
- ::std::unique_ptr<AST::BaseLoopExpr> parse_labelled_loop_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>());
- AST::LoopLabel parse_loop_label();
- ::std::unique_ptr<AST::AsyncBlockExpr> parse_async_block_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>());
- ::std::unique_ptr<AST::UnsafeBlockExpr> parse_unsafe_block_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>());
- ::std::unique_ptr<AST::GroupedExpr> parse_grouped_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>());
- ::std::unique_ptr<AST::ClosureExpr> parse_closure_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>());
- AST::ClosureParam parse_closure_param();
- ::std::unique_ptr<AST::LiteralExpr> parse_literal_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>());
- ::std::unique_ptr<AST::ReturnExpr> parse_return_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- bool pratt_parse = false);
- ::std::unique_ptr<AST::BreakExpr> parse_break_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- bool pratt_parse = false);
- ::std::unique_ptr<AST::ContinueExpr> parse_continue_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- bool pratt_parse = false);
- ::std::unique_ptr<AST::ArrayExpr> parse_array_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- bool pratt_parse = false);
- ::std::unique_ptr<AST::ExprWithoutBlock> parse_grouped_or_tuple_expr(
- ::std::vector<AST::Attribute> outer_attrs = ::std::vector<AST::Attribute>(),
- bool pratt_parse = false);
- ::std::unique_ptr<AST::StructExprField> parse_struct_expr_field();
-
- // Type-related
- ::std::unique_ptr<AST::Type> parse_type();
- ::std::unique_ptr<AST::TypeNoBounds> parse_type_no_bounds();
- ::std::unique_ptr<AST::TypeNoBounds> parse_slice_or_array_type();
- ::std::unique_ptr<AST::RawPointerType> parse_raw_pointer_type();
- ::std::unique_ptr<AST::ReferenceType> parse_reference_type();
- ::std::unique_ptr<AST::BareFunctionType> parse_bare_function_type(
- ::std::vector<AST::LifetimeParam> for_lifetimes);
- ::std::unique_ptr<AST::Type> parse_paren_prefixed_type();
- ::std::unique_ptr<AST::TypeNoBounds> parse_paren_prefixed_type_no_bounds();
- ::std::unique_ptr<AST::Type> parse_for_prefixed_type();
- AST::MaybeNamedParam parse_maybe_named_param();
-
- // Statement-related
- ::std::unique_ptr<AST::Stmt> parse_stmt();
- ::std::unique_ptr<AST::LetStmt> parse_let_stmt(::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::ExprStmt> parse_expr_stmt(::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::ExprStmtWithBlock> parse_expr_stmt_with_block(
- ::std::vector<AST::Attribute> outer_attrs);
- ::std::unique_ptr<AST::ExprStmtWithoutBlock> parse_expr_stmt_without_block(
- ::std::vector<AST::Attribute> outer_attrs);
- ExprOrStmt parse_stmt_or_expr_without_block();
- ExprOrStmt parse_macro_invocation_maybe_semi(::std::vector<AST::Attribute> outer_attrs);
- ExprOrStmt parse_path_based_stmt_or_expr(::std::vector<AST::Attribute> outer_attrs);
-
- // Pattern-related
- ::std::unique_ptr<AST::Pattern> parse_pattern();
- ::std::unique_ptr<AST::Pattern> parse_literal_or_range_pattern();
- ::std::unique_ptr<AST::RangePatternBound> parse_range_pattern_bound();
- ::std::unique_ptr<AST::ReferencePattern> parse_reference_pattern();
- ::std::unique_ptr<AST::Pattern> parse_grouped_or_tuple_pattern();
- ::std::unique_ptr<AST::SlicePattern> parse_slice_pattern();
- ::std::unique_ptr<AST::IdentifierPattern> parse_identifier_pattern();
- ::std::unique_ptr<AST::Pattern> parse_ident_leading_pattern();
- ::std::unique_ptr<AST::TupleStructItems> parse_tuple_struct_items();
- AST::StructPatternElements parse_struct_pattern_elems();
- ::std::unique_ptr<AST::StructPatternField> parse_struct_pattern_field();
-
- int left_binding_power(const_TokenPtr token);
-
- bool done_end();
- bool done_end_or_else();
- bool done_end_of_file();
-
- public:
- // Construct parser with specified lexer reference.
- Parser(Lexer& parLexer) : lexer(parLexer) {}
-
- // Main entry point for parser.
- AST::Crate parse_crate();
-
- // Dumps all lexer output.
- void debug_dump_lex_output();
- void debug_dump_ast_output();
-
- private:
- // The lexer associated with the parser.
- Lexer& lexer;
- };
-}
+/* HACK: used to resolve the expression-or-statement problem at the end of a
+ * block by allowing either to be returned (technically). Tagged union would
+ * probably take up the same amount of space. */
+struct ExprOrStmt
+{
+ ::std::unique_ptr<AST::ExprWithoutBlock> expr;
+ ::std::unique_ptr<AST::Stmt> stmt;
+
+ /* I was going to resist the urge to make this a real class and make it POD,
+ * but construction in steps is too difficult. So it'll just also have a
+ * constructor. */
+
+ // expression constructor
+ ExprOrStmt (::std::unique_ptr<AST::ExprWithoutBlock> expr)
+ : expr (::std::move (expr))
+ {}
+
+ // statement constructor
+ ExprOrStmt (::std::unique_ptr<AST::Stmt> stmt) : stmt (::std::move (stmt)) {}
+
+ // Returns whether this object is in an error state.
+ inline bool is_error () const
+ {
+ return (expr == NULL && stmt == NULL) || (expr != NULL && stmt != NULL);
+ }
+
+ // Returns an error state object.
+ static ExprOrStmt create_error () { return ExprOrStmt (NULL, NULL); }
+
+ ~ExprOrStmt () = default;
+
+ // no copy constructors/assignment copy as simple object like this shouldn't
+ // require it
+
+ // move constructors
+ ExprOrStmt (ExprOrStmt &&other) = default;
+ ExprOrStmt &operator= (ExprOrStmt &&other) = default;
+
+private:
+ // private constructor only used for creating error state expr or stmt objects
+ ExprOrStmt (AST::ExprWithoutBlock *expr, AST::Stmt *stmt)
+ : expr (expr), stmt (stmt)
+ {}
+
+ // make this work: have a disambiguation specifically for known statements
+ // (i.e. ';' and 'let'). then, have a special "parse expr or stmt" function
+ // that returns this type. inside it, it parses an expression, and then
+ // determines whether to return expr or stmt via whether the next token is a
+ // semicolon. should be able to disambiguate inside that function between
+ // stmts with blocks and without blocks.
+};
+
+/* Restrictions on parsing used to signal that certain ambiguous grammar
+ * features should be parsed in a certain way.*/
+struct ParseRestrictions
+{
+ bool can_be_struct_expr = true;
+ /* Whether the expression was entered from a unary expression - prevents stuff
+ * like struct exprs being parsed from a dereference. */
+ bool entered_from_unary = false;
+};
+
+// Parser implementation for gccrs.
+class Parser
+{
+private:
+ void skip_after_semicolon ();
+ void skip_after_end ();
+ void skip_after_end_block ();
+ void skip_after_next_block ();
+ void skip_after_end_attribute ();
+
+ bool skip_token (TokenId t);
+ const_TokenPtr expect_token (TokenId t);
+ void unexpected_token (const_TokenPtr t);
+ bool skip_generics_right_angle ();
+
+ void parse_statement_seq (bool (Parser::*done) ());
+
+ // AST-related stuff - maybe move or something?
+ ::std::vector<AST::Attribute> parse_inner_attributes ();
+ AST::Attribute parse_inner_attribute ();
+ ::std::vector<AST::Attribute> parse_outer_attributes ();
+ AST::Attribute parse_outer_attribute ();
+ AST::Attribute parse_attribute_body ();
+ ::std::unique_ptr<AST::AttrInput> parse_attr_input ();
+
+ // Path-related
+ AST::SimplePath parse_simple_path ();
+ AST::SimplePathSegment parse_simple_path_segment ();
+ AST::TypePath parse_type_path ();
+ ::std::unique_ptr<AST::TypePathSegment> parse_type_path_segment ();
+ AST::PathIdentSegment parse_path_ident_segment ();
+ AST::GenericArgs parse_path_generic_args ();
+ AST::GenericArgsBinding parse_generic_args_binding ();
+ AST::TypePathFunction parse_type_path_function ();
+ AST::PathInExpression parse_path_in_expression ();
+ AST::PathExprSegment parse_path_expr_segment ();
+ AST::QualifiedPathInExpression
+ parse_qualified_path_in_expression (bool pratt_parse = false);
+ AST::QualifiedPathType parse_qualified_path_type (bool pratt_parse = false);
+ AST::QualifiedPathInType parse_qualified_path_in_type ();
+
+ // Token tree or macro related
+ AST::DelimTokenTree parse_delim_token_tree ();
+ ::std::unique_ptr<AST::TokenTree> parse_token_tree ();
+ ::std::unique_ptr<AST::MacroRulesDefinition>
+ parse_macro_rules_def (::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::MacroInvocationSemi>
+ parse_macro_invocation_semi (::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::MacroInvocation>
+ parse_macro_invocation (::std::vector<AST::Attribute> outer_attrs);
+ AST::MacroRule parse_macro_rule ();
+ AST::MacroMatcher parse_macro_matcher ();
+ ::std::unique_ptr<AST::MacroMatch> parse_macro_match ();
+ ::std::unique_ptr<AST::MacroMatchFragment> parse_macro_match_fragment ();
+ ::std::unique_ptr<AST::MacroMatchRepetition> parse_macro_match_repetition ();
+
+ // Top-level item-related
+ ::std::vector< ::std::unique_ptr<AST::Item> > parse_items ();
+ ::std::unique_ptr<AST::Item> parse_item (bool called_from_statement);
+ ::std::unique_ptr<AST::VisItem>
+ parse_vis_item (::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::MacroItem>
+ parse_macro_item (::std::vector<AST::Attribute> outer_attrs);
+ AST::Visibility parse_visibility ();
+
+ // VisItem subclass-related
+ ::std::unique_ptr<AST::Module>
+ parse_module (AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::ExternCrate>
+ parse_extern_crate (AST::Visibility vis,
+ ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::UseDeclaration>
+ parse_use_decl (AST::Visibility vis,
+ ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::UseTree> parse_use_tree ();
+ ::std::unique_ptr<AST::Function>
+ parse_function (AST::Visibility vis,
+ ::std::vector<AST::Attribute> outer_attrs);
+ AST::FunctionQualifiers parse_function_qualifiers ();
+ ::std::vector< ::std::unique_ptr<AST::GenericParam> >
+ parse_generic_params_in_angles ();
+ ::std::vector< ::std::unique_ptr<AST::GenericParam> > parse_generic_params ();
+ ::std::vector< ::std::unique_ptr<AST::LifetimeParam> >
+ parse_lifetime_params ();
+ ::std::vector<AST::LifetimeParam> parse_lifetime_params_objs ();
+ AST::LifetimeParam parse_lifetime_param ();
+ ::std::vector< ::std::unique_ptr<AST::TypeParam> > parse_type_params ();
+ ::std::unique_ptr<AST::TypeParam> parse_type_param ();
+ ::std::vector<AST::FunctionParam> parse_function_params ();
+ AST::FunctionParam parse_function_param ();
+ ::std::unique_ptr<AST::Type> parse_function_return_type ();
+ AST::WhereClause parse_where_clause ();
+ ::std::unique_ptr<AST::WhereClauseItem> parse_where_clause_item ();
+ ::std::unique_ptr<AST::LifetimeWhereClauseItem>
+ parse_lifetime_where_clause_item ();
+ ::std::unique_ptr<AST::TypeBoundWhereClauseItem>
+ parse_type_bound_where_clause_item ();
+ ::std::vector<AST::LifetimeParam> parse_for_lifetimes ();
+ ::std::vector< ::std::unique_ptr<AST::TypeParamBound> >
+ parse_type_param_bounds ();
+ ::std::unique_ptr<AST::TypeParamBound> parse_type_param_bound ();
+ ::std::unique_ptr<AST::TraitBound> parse_trait_bound ();
+ ::std::vector<AST::Lifetime> parse_lifetime_bounds ();
+ AST::Lifetime parse_lifetime ();
+ ::std::unique_ptr<AST::TypeAlias>
+ parse_type_alias (AST::Visibility vis,
+ ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::Struct>
+ parse_struct (AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
+ ::std::vector<AST::StructField> parse_struct_fields ();
+ AST::StructField parse_struct_field ();
+ ::std::vector<AST::TupleField> parse_tuple_fields ();
+ AST::TupleField parse_tuple_field ();
+ ::std::unique_ptr<AST::Enum>
+ parse_enum (AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
+ ::std::vector< ::std::unique_ptr<AST::EnumItem> > parse_enum_items ();
+ ::std::unique_ptr<AST::EnumItem> parse_enum_item ();
+ ::std::unique_ptr<AST::Union>
+ parse_union (AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::ConstantItem>
+ parse_const_item (AST::Visibility vis,
+ ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::StaticItem>
+ parse_static_item (AST::Visibility vis,
+ ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::Trait>
+ parse_trait (AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::TraitItem> parse_trait_item ();
+ ::std::unique_ptr<AST::TraitItemType>
+ parse_trait_type (::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::TraitItemConst>
+ parse_trait_const (::std::vector<AST::Attribute> outer_attrs);
+ AST::SelfParam parse_self_param ();
+ ::std::unique_ptr<AST::Impl>
+ parse_impl (AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::InherentImplItem> parse_inherent_impl_item ();
+ ::std::unique_ptr<AST::InherentImplItem>
+ parse_inherent_impl_function_or_method (
+ AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::TraitImplItem> parse_trait_impl_item ();
+ ::std::unique_ptr<AST::TraitImplItem> parse_trait_impl_function_or_method (
+ AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::ExternBlock>
+ parse_extern_block (AST::Visibility vis,
+ ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::ExternalItem> parse_external_item ();
+ AST::NamedFunctionParam parse_named_function_param ();
+ AST::Method parse_method ();
+
+ // Expression-related (Pratt parsed)
+ ::std::unique_ptr<AST::Expr>
+ parse_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::Expr>
+ parse_expr (int right_binding_power,
+ ::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::Expr>
+ null_denotation_NEW (const_TokenPtr t,
+ ::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::Expr>
+ left_denotation (const_TokenPtr t, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ parse_binary_plus_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ ::std::unique_ptr<AST::ArithmeticOrLogicalExpr> parse_binary_minus_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ parse_binary_mult_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ ::std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ parse_binary_div_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ parse_binary_mod_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ parse_bitwise_and_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ ::std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ parse_bitwise_or_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ parse_bitwise_xor_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ ::std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ parse_left_shift_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::ArithmeticOrLogicalExpr>
+ parse_right_shift_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ ::std::unique_ptr<AST::ComparisonExpr> parse_binary_equal_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::ComparisonExpr> parse_binary_not_equal_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::ComparisonExpr> parse_binary_greater_than_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::ComparisonExpr> parse_binary_less_than_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::ComparisonExpr> parse_binary_greater_equal_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::ComparisonExpr> parse_binary_less_equal_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::LazyBooleanExpr>
+ parse_lazy_or_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::LazyBooleanExpr>
+ parse_lazy_and_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::TypeCastExpr>
+ parse_type_cast_expr (const_TokenPtr tok,
+ ::std::unique_ptr<AST::Expr> expr_to_cast,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::AssignmentExpr>
+ parse_assig_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::CompoundAssignmentExpr>
+ parse_plus_assig_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::CompoundAssignmentExpr>
+ parse_minus_assig_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions
+ = ParseRestrictions ());
+ ::std::unique_ptr<AST::CompoundAssignmentExpr>
+ parse_mult_assig_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::CompoundAssignmentExpr>
+ parse_div_assig_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::CompoundAssignmentExpr>
+ parse_mod_assig_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::CompoundAssignmentExpr>
+ parse_and_assig_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::CompoundAssignmentExpr>
+ parse_or_assig_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::CompoundAssignmentExpr>
+ parse_xor_assig_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::CompoundAssignmentExpr> parse_left_shift_assig_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::CompoundAssignmentExpr> parse_right_shift_assig_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::AwaitExpr>
+ parse_await_expr (const_TokenPtr tok,
+ ::std::unique_ptr<AST::Expr> expr_to_await,
+ ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::MethodCallExpr> parse_method_call_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> receiver_expr,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::CallExpr> parse_function_call_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> function_expr,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::RangeExpr> parse_led_range_exclusive_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::RangeExpr>
+ parse_nud_range_exclusive_expr (const_TokenPtr tok,
+ ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::RangeFromToInclExpr> parse_range_inclusive_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::RangeToInclExpr>
+ parse_range_to_inclusive_expr (const_TokenPtr tok,
+ ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::TupleIndexExpr> parse_tuple_index_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> tuple_expr,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::FieldAccessExpr> parse_field_access_expr (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> struct_expr,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::ArrayIndexExpr>
+ parse_index_expr (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> array_expr,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+ ::std::unique_ptr<AST::MacroInvocation>
+ parse_macro_invocation_partial (AST::PathInExpression path,
+ ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::StructExprStruct>
+ parse_struct_expr_struct_partial (AST::PathInExpression path,
+ ::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::StructExprTuple>
+ parse_struct_expr_tuple_partial (AST::PathInExpression path,
+ ::std::vector<AST::Attribute> outer_attrs);
+ AST::PathInExpression parse_path_in_expression_pratt (const_TokenPtr tok);
+ ::std::unique_ptr<AST::ClosureExpr>
+ parse_closure_expr_pratt (const_TokenPtr tok,
+ ::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> ());
+ ::std::unique_ptr<AST::TupleIndexExpr> parse_tuple_index_expr_float (
+ const_TokenPtr tok, ::std::unique_ptr<AST::Expr> tuple_expr,
+ ::std::vector<AST::Attribute> outer_attrs,
+ ParseRestrictions restrictions = ParseRestrictions ());
+
+ // Expression-related (non-Pratt parsed)
+ ::std::unique_ptr<AST::ExprWithoutBlock>
+ parse_expr_without_block (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> ());
+ ::std::unique_ptr<AST::BlockExpr>
+ parse_block_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ bool pratt_parse = false);
+ ::std::unique_ptr<AST::IfExpr>
+ parse_if_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> ());
+ ::std::unique_ptr<AST::IfLetExpr>
+ parse_if_let_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> ());
+ ::std::unique_ptr<AST::LoopExpr>
+ parse_loop_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ AST::LoopLabel label = AST::LoopLabel::error ());
+ ::std::unique_ptr<AST::WhileLoopExpr>
+ parse_while_loop_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ AST::LoopLabel label = AST::LoopLabel::error ());
+ ::std::unique_ptr<AST::WhileLetLoopExpr>
+ parse_while_let_loop_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ AST::LoopLabel label = AST::LoopLabel::error ());
+ ::std::unique_ptr<AST::ForLoopExpr>
+ parse_for_loop_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ AST::LoopLabel label = AST::LoopLabel::error ());
+ ::std::unique_ptr<AST::MatchExpr>
+ parse_match_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ bool pratt_parse = false);
+ AST::MatchArm parse_match_arm ();
+ ::std::vector< ::std::unique_ptr<AST::Pattern> >
+ parse_match_arm_patterns (TokenId end_token_id);
+ ::std::unique_ptr<AST::BaseLoopExpr>
+ parse_labelled_loop_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> ());
+ AST::LoopLabel parse_loop_label ();
+ ::std::unique_ptr<AST::AsyncBlockExpr>
+ parse_async_block_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> ());
+ ::std::unique_ptr<AST::UnsafeBlockExpr>
+ parse_unsafe_block_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> ());
+ ::std::unique_ptr<AST::GroupedExpr>
+ parse_grouped_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> ());
+ ::std::unique_ptr<AST::ClosureExpr>
+ parse_closure_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> ());
+ AST::ClosureParam parse_closure_param ();
+ ::std::unique_ptr<AST::LiteralExpr>
+ parse_literal_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> ());
+ ::std::unique_ptr<AST::ReturnExpr>
+ parse_return_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ bool pratt_parse = false);
+ ::std::unique_ptr<AST::BreakExpr>
+ parse_break_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ bool pratt_parse = false);
+ ::std::unique_ptr<AST::ContinueExpr>
+ parse_continue_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ bool pratt_parse = false);
+ ::std::unique_ptr<AST::ArrayExpr>
+ parse_array_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ bool pratt_parse = false);
+ ::std::unique_ptr<AST::ExprWithoutBlock>
+ parse_grouped_or_tuple_expr (::std::vector<AST::Attribute> outer_attrs
+ = ::std::vector<AST::Attribute> (),
+ bool pratt_parse = false);
+ ::std::unique_ptr<AST::StructExprField> parse_struct_expr_field ();
+
+ // Type-related
+ ::std::unique_ptr<AST::Type> parse_type ();
+ ::std::unique_ptr<AST::TypeNoBounds> parse_type_no_bounds ();
+ ::std::unique_ptr<AST::TypeNoBounds> parse_slice_or_array_type ();
+ ::std::unique_ptr<AST::RawPointerType> parse_raw_pointer_type ();
+ ::std::unique_ptr<AST::ReferenceType> parse_reference_type ();
+ ::std::unique_ptr<AST::BareFunctionType>
+ parse_bare_function_type (::std::vector<AST::LifetimeParam> for_lifetimes);
+ ::std::unique_ptr<AST::Type> parse_paren_prefixed_type ();
+ ::std::unique_ptr<AST::TypeNoBounds> parse_paren_prefixed_type_no_bounds ();
+ ::std::unique_ptr<AST::Type> parse_for_prefixed_type ();
+ AST::MaybeNamedParam parse_maybe_named_param ();
+
+ // Statement-related
+ ::std::unique_ptr<AST::Stmt> parse_stmt ();
+ ::std::unique_ptr<AST::LetStmt>
+ parse_let_stmt (::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::ExprStmt>
+ parse_expr_stmt (::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::ExprStmtWithBlock>
+ parse_expr_stmt_with_block (::std::vector<AST::Attribute> outer_attrs);
+ ::std::unique_ptr<AST::ExprStmtWithoutBlock>
+ parse_expr_stmt_without_block (::std::vector<AST::Attribute> outer_attrs);
+ ExprOrStmt parse_stmt_or_expr_without_block ();
+ ExprOrStmt
+ parse_macro_invocation_maybe_semi (::std::vector<AST::Attribute> outer_attrs);
+ ExprOrStmt
+ parse_path_based_stmt_or_expr (::std::vector<AST::Attribute> outer_attrs);
+
+ // Pattern-related
+ ::std::unique_ptr<AST::Pattern> parse_pattern ();
+ ::std::unique_ptr<AST::Pattern> parse_literal_or_range_pattern ();
+ ::std::unique_ptr<AST::RangePatternBound> parse_range_pattern_bound ();
+ ::std::unique_ptr<AST::ReferencePattern> parse_reference_pattern ();
+ ::std::unique_ptr<AST::Pattern> parse_grouped_or_tuple_pattern ();
+ ::std::unique_ptr<AST::SlicePattern> parse_slice_pattern ();
+ ::std::unique_ptr<AST::IdentifierPattern> parse_identifier_pattern ();
+ ::std::unique_ptr<AST::Pattern> parse_ident_leading_pattern ();
+ ::std::unique_ptr<AST::TupleStructItems> parse_tuple_struct_items ();
+ AST::StructPatternElements parse_struct_pattern_elems ();
+ ::std::unique_ptr<AST::StructPatternField> parse_struct_pattern_field ();
+
+ int left_binding_power (const_TokenPtr token);
+
+ bool done_end ();
+ bool done_end_or_else ();
+ bool done_end_of_file ();
+
+public:
+ // Construct parser with specified lexer reference.
+ Parser (Lexer &parLexer) : lexer (parLexer) {}
+
+ // Main entry point for parser.
+ AST::Crate parse_crate ();
+
+ // Dumps all lexer output.
+ void debug_dump_lex_output ();
+ void debug_dump_ast_output ();
+
+private:
+ // The lexer associated with the parser.
+ Lexer &lexer;
+};
+} // namespace Rust
#endif // RUST_PARSE_H
diff --git a/gcc/rust/rust-backend.c b/gcc/rust/rust-backend.c
index fb701ce..49c7ebd 100644
--- a/gcc/rust/rust-backend.c
+++ b/gcc/rust/rust-backend.c
@@ -1,21 +1,21 @@
/* rust-backend.c -- Rust frontend interface to gcc backend.
- Copyright (C) 2010-2019 Free Software Foundation, Inc.
+ Copyright (C) 2010-2020 Free Software Foundation, Inc.
-This file is part of GCC.
+ 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 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.
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
@@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "simple-object.h"
#include "stor-layout.h"
#include "intl.h"
-#include "output.h" /* for assemble_string */
+#include "output.h" /* for assemble_string */
#include "common/common-target.h"
//#include "rust-c.h" // import no longer exists, so hopefully not broken
@@ -110,8 +110,8 @@ rust_write_export_data (const char *bytes, unsigned int size)
{
gcc_assert (targetm_common.have_named_sections);
sec = get_section (RUST_EXPORT_SECTION_NAME,
- TARGET_AIX ? SECTION_EXCLUDE : SECTION_DEBUG,
- NULL);
+ TARGET_AIX ? SECTION_EXCLUDE : SECTION_DEBUG,
+ NULL);
}
switch_to_section (sec);
@@ -131,7 +131,7 @@ rust_write_export_data (const char *bytes, unsigned int size)
const char *
rust_read_export_data (int fd, off_t offset, char **pbuf, size_t *plen,
- int *perr)
+ int *perr)
{
simple_object_read *sobj;
const char *errmsg;
@@ -145,20 +145,20 @@ rust_read_export_data (int fd, off_t offset, char **pbuf, size_t *plen,
*plen = 0;
sobj = simple_object_start_read (fd, offset, RUST_EXPORT_SEGMENT_NAME,
- &errmsg, perr);
+ &errmsg, perr);
if (sobj == NULL)
{
/* If we get an error here, just pretend that we didn't find any
- export data. This is the right thing to do if the error is
- that the file was not recognized as an object file. This
- will ignore file I/O errors, but it's not too big a deal
- because we will wind up giving some other error later. */
+ export data. This is the right thing to do if the error is
+ that the file was not recognized as an object file. This
+ will ignore file I/O errors, but it's not too big a deal
+ because we will wind up giving some other error later. */
return NULL;
}
found = simple_object_find_section (sobj, RUST_EXPORT_SECTION_NAME,
- &sec_offset, &sec_length,
- &errmsg, perr);
+ &sec_offset, &sec_length,
+ &errmsg, perr);
simple_object_release_read (sobj);
if (!found)
return errmsg;
diff --git a/gcc/rust/rust-buffered-queue.h b/gcc/rust/rust-buffered-queue.h
index ac0ea1a..f56aaff 100644
--- a/gcc/rust/rust-buffered-queue.h
+++ b/gcc/rust/rust-buffered-queue.h
@@ -8,123 +8,138 @@
// order: config, system
namespace Rust {
- // Buffered queue implementation. Items are of type T, queue source is of type Source.
- template<typename T, typename Source>
- class buffered_queue {
- public:
- // Construct empty queue from Source& src.
- buffered_queue(Source& src) : source(src), start(0), end(0), buffer() {}
-
- // Returns token at position start + n (i.e. n tokens ahead).
- T peek(int n) {
- // n should not be behind
- gcc_assert(n >= 0);
-
- int num_queued_items = end - start;
- int num_items_required = n + 1;
-
- // if required items go past end of queue, add them to queue
- if (num_items_required > num_queued_items) {
- int num_items_to_read = num_items_required - num_queued_items;
-
- // if queue length + extra items is larger than buffer size, expand buffer
- if (end + num_items_to_read > (int)buffer.size()) {
- // Resize the buffer by 1.5x
- int new_size = (buffer.size() + num_items_to_read);
- new_size += (new_size >> 1);
-
- // create new queue buffer with new size
- std::vector<T> new_queue(new_size);
- std::copy(buffer.begin() + start, buffer.begin() + end, new_queue.begin());
- start = 0;
- end = num_queued_items;
-
- // swap member buffer and new queue buffer
- std::swap(buffer, new_queue);
-
- // validate that buffer is large enough now
- gcc_assert(end + num_queued_items < (int)buffer.size());
- }
-
- // iterate through buffer and invoke operator () on source on values past original end
- for (int i = 0; i < num_items_to_read; i++) {
- buffer[end + i] = source();
- }
-
- // move end based on additional items added
- end += num_items_to_read;
- }
-
- gcc_assert(0 <= start);
- gcc_assert(start <= end);
- gcc_assert(end <= (int)buffer.size());
-
- gcc_assert(start + n < end);
-
- // return value at start + n in buffer
- return buffer[start + n];
- }
-
- // TODO: add faster peek current token to remove overhead of conditional branches?
-
- // Advances start by n + 1.
- void skip(int n) {
- // Call peek to ensure requested n is actually in queue.
- peek(n);
-
- // Clear values from start to n (inclusive).
- for (int i = 0; i < (n + 1); i++) {
- // Clear value at index
- buffer[start + i] = T();
- }
-
- // Move start forward by n + 1.
- start += (n + 1);
-
- // Ensure start is not impossible somehow
- gcc_assert(0 <= start);
- gcc_assert(start <= end);
-
- // Compact buffer if empty
- if (start == end) {
- start = end = 0;
- }
- }
-
- /* Inserts element at front of vector. Really dirty hack with terrible performance, only use
- * when really needed. */
- void insert_at_front(T elem_to_insert) {
- // TODO: test as this may not work properly
-
- // Insert actual element in buffer at start.
- buffer.insert(buffer.begin(), 1, elem_to_insert);
-
- // Increase the end number since added element means all others have shifted one along
- end++;
- }
-
- // Replaces the current value in the buffer. Total HACK.
- void replace_current_value(T replacement) {
- // call peek to ensure value exists
- peek(0);
-
- buffer[start] = replacement;
-
- // don't move start or end
- }
-
- private:
- // Source of tokens for queue.
- Source& source;
-
- // Begin of range in buffer, inclusive.
- int start;
- // End of range in buffer, exclusive.
- int end;
-
- // Queue buffer.
- std::vector<T> buffer;
- };
-}
-
-#endif \ No newline at end of file
+// Buffered queue implementation. Items are of type T, queue source is of type
+// Source.
+template <typename T, typename Source> class buffered_queue
+{
+public:
+ // Construct empty queue from Source& src.
+ buffered_queue (Source &src) : source (src), start (0), end (0), buffer () {}
+
+ // Returns token at position start + n (i.e. n tokens ahead).
+ T peek (int n)
+ {
+ // n should not be behind
+ gcc_assert (n >= 0);
+
+ int num_queued_items = end - start;
+ int num_items_required = n + 1;
+
+ // if required items go past end of queue, add them to queue
+ if (num_items_required > num_queued_items)
+ {
+ int num_items_to_read = num_items_required - num_queued_items;
+
+ // if queue length + extra items is larger than buffer size, expand
+ // buffer
+ if (end + num_items_to_read > (int) buffer.size ())
+ {
+ // Resize the buffer by 1.5x
+ int new_size = (buffer.size () + num_items_to_read);
+ new_size += (new_size >> 1);
+
+ // create new queue buffer with new size
+ std::vector<T> new_queue (new_size);
+ std::copy (buffer.begin () + start, buffer.begin () + end,
+ new_queue.begin ());
+ start = 0;
+ end = num_queued_items;
+
+ // swap member buffer and new queue buffer
+ std::swap (buffer, new_queue);
+
+ // validate that buffer is large enough now
+ gcc_assert (end + num_queued_items < (int) buffer.size ());
+ }
+
+ // iterate through buffer and invoke operator () on source on values
+ // past original end
+ for (int i = 0; i < num_items_to_read; i++)
+ {
+ buffer[end + i] = source ();
+ }
+
+ // move end based on additional items added
+ end += num_items_to_read;
+ }
+
+ gcc_assert (0 <= start);
+ gcc_assert (start <= end);
+ gcc_assert (end <= (int) buffer.size ());
+
+ gcc_assert (start + n < end);
+
+ // return value at start + n in buffer
+ return buffer[start + n];
+ }
+
+ // TODO: add faster peek current token to remove overhead of conditional
+ // branches?
+
+ // Advances start by n + 1.
+ void skip (int n)
+ {
+ // Call peek to ensure requested n is actually in queue.
+ peek (n);
+
+ // Clear values from start to n (inclusive).
+ for (int i = 0; i < (n + 1); i++)
+ {
+ // Clear value at index
+ buffer[start + i] = T ();
+ }
+
+ // Move start forward by n + 1.
+ start += (n + 1);
+
+ // Ensure start is not impossible somehow
+ gcc_assert (0 <= start);
+ gcc_assert (start <= end);
+
+ // Compact buffer if empty
+ if (start == end)
+ {
+ start = end = 0;
+ }
+ }
+
+ /* Inserts element at front of vector. Really dirty hack with terrible
+ * performance, only use when really needed. */
+ void insert_at_front (T elem_to_insert)
+ {
+ // TODO: test as this may not work properly
+
+ // Insert actual element in buffer at start.
+ buffer.insert (buffer.begin (), 1, elem_to_insert);
+
+ // Increase the end number since added element means all others have shifted
+ // one along
+ end++;
+ }
+
+ // Replaces the current value in the buffer. Total HACK.
+ void replace_current_value (T replacement)
+ {
+ // call peek to ensure value exists
+ peek (0);
+
+ buffer[start] = replacement;
+
+ // don't move start or end
+ }
+
+private:
+ // Source of tokens for queue.
+ Source &source;
+
+ // Begin of range in buffer, inclusive.
+ int start;
+ // End of range in buffer, exclusive.
+ int end;
+
+ // Queue buffer.
+ std::vector<T> buffer;
+};
+} // namespace Rust
+
+#endif
diff --git a/gcc/rust/rust-diagnostics.cc b/gcc/rust/rust-diagnostics.cc
index d7c6475..8e32f78ae 100644
--- a/gcc/rust/rust-diagnostics.cc
+++ b/gcc/rust/rust-diagnostics.cc
@@ -1,5 +1,5 @@
// rust-diagnostics.cc -- GCC implementation of rust diagnostics interface.
-// Copyright (C) 2016-2019 Free Software Foundation, Inc.
+// Copyright (C) 2016-2020 Free Software Foundation, Inc.
// Contributed by Than McIntosh, Google.
// This file is part of GCC.
@@ -22,9 +22,9 @@
#include "rust-diagnostics.h"
static std::string
-mformat_value()
+mformat_value ()
{
- return std::string(xstrerror(errno));
+ return std::string (xstrerror (errno));
}
// Rewrite a format string to expand any extensions not
@@ -32,66 +32,66 @@ mformat_value()
// for list of supported format specifiers.
static std::string
-expand_format(const char* fmt)
+expand_format (const char *fmt)
{
std::stringstream ss;
- for (const char* c = fmt; *c; ++c)
+ for (const char *c = fmt; *c; ++c)
{
if (*c != '%')
- {
- ss << *c;
- continue;
- }
+ {
+ ss << *c;
+ continue;
+ }
c++;
switch (*c)
- {
- case '\0':
- {
- // malformed format string
- rust_unreachable();
- }
- case '%':
- {
- ss << "%";
- break;
- }
- case 'm':
- {
- ss << mformat_value();
- break;
- }
- case '<':
- {
- ss << rust_open_quote();
- break;
- }
- case '>':
- {
- ss << rust_close_quote();
- break;
- }
- case 'q':
- {
- ss << rust_open_quote();
- c++;
- if (*c == 'm')
- {
- ss << mformat_value();
- }
- else
- {
- ss << "%" << *c;
- }
- ss << rust_close_quote();
- break;
- }
- default:
- {
- ss << "%" << *c;
- }
- }
+ {
+ case '\0':
+ {
+ // malformed format string
+ rust_unreachable ();
+ }
+ case '%':
+ {
+ ss << "%";
+ break;
+ }
+ case 'm':
+ {
+ ss << mformat_value ();
+ break;
+ }
+ case '<':
+ {
+ ss << rust_open_quote ();
+ break;
+ }
+ case '>':
+ {
+ ss << rust_close_quote ();
+ break;
+ }
+ case 'q':
+ {
+ ss << rust_open_quote ();
+ c++;
+ if (*c == 'm')
+ {
+ ss << mformat_value ();
+ }
+ else
+ {
+ ss << "%" << *c;
+ }
+ ss << rust_close_quote ();
+ break;
+ }
+ default:
+ {
+ ss << "%" << *c;
+ }
+ }
}
- return ss.str();
+ return ss.str ();
}
// Expand message format specifiers, using a combination of
@@ -99,7 +99,9 @@ expand_format(const char* fmt)
// to handle regular printf-style formatting. A pragma is being used here to
// suppress this warning:
//
-// warning: function ‘std::__cxx11::string expand_message(const char*, __va_list_tag*)’ might be a candidate for ‘gnu_printf’ format attribute [-Wsuggest-attribute=format]
+// warning: function ‘std::__cxx11::string expand_message(const char*,
+// __va_list_tag*)’ might be a candidate for ‘gnu_printf’ format attribute
+// [-Wsuggest-attribute=format]
//
// What appears to be happening here is that the checker is deciding that
// because of the call to vasprintf() (which has attribute gnu_printf), the
@@ -107,109 +109,108 @@ expand_format(const char* fmt)
// though there is already an attribute declaration for it.
static std::string
-expand_message(const char* fmt, va_list ap) RUST_ATTRIBUTE_GCC_DIAG(1,0);
+expand_message (const char *fmt, va_list ap) RUST_ATTRIBUTE_GCC_DIAG (1, 0);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
static std::string
-expand_message(const char* fmt, va_list ap)
+expand_message (const char *fmt, va_list ap)
{
- char* mbuf = 0;
- std::string expanded_fmt = expand_format(fmt);
- int nwr = vasprintf(&mbuf, expanded_fmt.c_str(), ap);
+ char *mbuf = 0;
+ std::string expanded_fmt = expand_format (fmt);
+ int nwr = vasprintf (&mbuf, expanded_fmt.c_str (), ap);
if (nwr == -1)
{
// memory allocation failed
- rust_be_error_at(Linemap::unknown_location(),
- "memory allocation failed in vasprintf");
- rust_assert(0);
+ rust_be_error_at (Linemap::unknown_location (),
+ "memory allocation failed in vasprintf");
+ rust_assert (0);
}
- std::string rval = std::string(mbuf);
- free(mbuf);
+ std::string rval = std::string (mbuf);
+ free (mbuf);
return rval;
}
#pragma GCC diagnostic pop
-static const char* cached_open_quote = NULL;
-static const char* cached_close_quote = NULL;
+static const char *cached_open_quote = NULL;
+static const char *cached_close_quote = NULL;
-const char*
-rust_open_quote()
+const char *
+rust_open_quote ()
{
if (cached_open_quote == NULL)
- rust_be_get_quotechars(&cached_open_quote, &cached_close_quote);
+ rust_be_get_quotechars (&cached_open_quote, &cached_close_quote);
return cached_open_quote;
}
-const char*
-rust_close_quote()
+const char *
+rust_close_quote ()
{
if (cached_close_quote == NULL)
- rust_be_get_quotechars(&cached_open_quote, &cached_close_quote);
+ rust_be_get_quotechars (&cached_open_quote, &cached_close_quote);
return cached_close_quote;
}
void
-rust_error_at(const Location location, const char* fmt, ...)
+rust_error_at (const Location location, const char *fmt, ...)
{
va_list ap;
- va_start(ap, fmt);
- rust_be_error_at(location, expand_message(fmt, ap));
- va_end(ap);
+ va_start (ap, fmt);
+ rust_be_error_at (location, expand_message (fmt, ap));
+ va_end (ap);
}
void
-rust_warning_at(const Location location, int opt, const char* fmt, ...)
+rust_warning_at (const Location location, int opt, const char *fmt, ...)
{
va_list ap;
- va_start(ap, fmt);
- rust_be_warning_at(location, opt, expand_message(fmt, ap));
- va_end(ap);
+ va_start (ap, fmt);
+ rust_be_warning_at (location, opt, expand_message (fmt, ap));
+ va_end (ap);
}
void
-rust_fatal_error(const Location location, const char* fmt, ...)
+rust_fatal_error (const Location location, const char *fmt, ...)
{
va_list ap;
- va_start(ap, fmt);
- rust_be_fatal_error(location, expand_message(fmt, ap));
- va_end(ap);
+ va_start (ap, fmt);
+ rust_be_fatal_error (location, expand_message (fmt, ap));
+ va_end (ap);
}
void
-rust_inform(const Location location, const char* fmt, ...)
+rust_inform (const Location location, const char *fmt, ...)
{
va_list ap;
- va_start(ap, fmt);
- rust_be_inform(location, expand_message(fmt, ap));
- va_end(ap);
+ va_start (ap, fmt);
+ rust_be_inform (location, expand_message (fmt, ap));
+ va_end (ap);
}
// rust_debug uses normal printf formatting, not GCC diagnostic formatting.
void
-rust_debug(const Location location, const char* fmt, ...)
+rust_debug (const Location location, const char *fmt, ...)
{
va_list ap;
- va_start(ap, fmt);
- char* mbuf = NULL;
- int nwr = vasprintf(&mbuf, fmt, ap);
- va_end(ap);
+ va_start (ap, fmt);
+ char *mbuf = NULL;
+ int nwr = vasprintf (&mbuf, fmt, ap);
+ va_end (ap);
if (nwr == -1)
{
- rust_be_error_at(Linemap::unknown_location(),
- "memory allocation failed in vasprintf");
- rust_assert(0);
+ rust_be_error_at (Linemap::unknown_location (),
+ "memory allocation failed in vasprintf");
+ rust_assert (0);
}
- std::string rval = std::string(mbuf);
- free(mbuf);
- rust_be_inform(location, rval);
+ std::string rval = std::string (mbuf);
+ free (mbuf);
+ rust_be_inform (location, rval);
}
-
diff --git a/gcc/rust/rust-diagnostics.h b/gcc/rust/rust-diagnostics.h
index 0cfbe69..04d48c8 100644
--- a/gcc/rust/rust-diagnostics.h
+++ b/gcc/rust/rust-diagnostics.h
@@ -6,9 +6,11 @@
#include "rust-linemap.h"
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
-#define RUST_ATTRIBUTE_GCC_DIAG(m, n) __attribute__ ((__format__ (__gcc_tdiag__, m, n))) __attribute__ ((__nonnull__ (m)))
+#define RUST_ATTRIBUTE_GCC_DIAG(m, n) \
+ __attribute__ ((__format__ (__gcc_tdiag__, m, n))) \
+ __attribute__ ((__nonnull__ (m)))
#else
-#define RUST_ATTRIBUTE_GCC_DIAG(m, n)
+#define RUST_ATTRIBUTE_GCC_DIAG(m, n)
#endif
// These declarations define the interface through which the frontend
@@ -28,20 +30,26 @@
// All other format specifiers are as defined by 'sprintf'. The final resulting
// message is then sent to the back end via rust_be_error_at/rust_be_warning_at.
-extern void rust_error_at(const Location, const char* fmt, ...)
- RUST_ATTRIBUTE_GCC_DIAG(2,3);
-extern void rust_warning_at(const Location, int opt, const char* fmt, ...)
- RUST_ATTRIBUTE_GCC_DIAG(3,4);
-extern void rust_fatal_error(const Location, const char* fmt, ...)
- RUST_ATTRIBUTE_GCC_DIAG(2,3);
-extern void rust_inform(const Location, const char* fmt, ...)
- RUST_ATTRIBUTE_GCC_DIAG(2,3);
+extern void
+rust_error_at (const Location, const char *fmt, ...)
+ RUST_ATTRIBUTE_GCC_DIAG (2, 3);
+extern void
+rust_warning_at (const Location, int opt, const char *fmt, ...)
+ RUST_ATTRIBUTE_GCC_DIAG (3, 4);
+extern void
+rust_fatal_error (const Location, const char *fmt, ...)
+ RUST_ATTRIBUTE_GCC_DIAG (2, 3);
+extern void
+rust_inform (const Location, const char *fmt, ...)
+ RUST_ATTRIBUTE_GCC_DIAG (2, 3);
// These interfaces provide a way for the front end to ask for
// the open/close quote characters it should use when formatting
// diagnostics (warnings, errors).
-extern const char* rust_open_quote();
-extern const char* rust_close_quote();
+extern const char *
+rust_open_quote ();
+extern const char *
+rust_close_quote ();
// These interfaces are used by utilities above to pass warnings and
// errors (once format specifiers have been expanded) to the back end,
@@ -49,12 +57,15 @@ extern const char* rust_close_quote();
// instead use the equivalent routines above. The back end is required to
// implement these routines.
-extern void rust_be_error_at(const Location, const std::string& errmsg);
-extern void rust_be_warning_at(const Location, int opt,
- const std::string& warningmsg);
-extern void rust_be_fatal_error(const Location, const std::string& errmsg);
-extern void rust_be_inform(const Location, const std::string& infomsg);
-extern void rust_be_get_quotechars(const char** open_quote,
- const char** close_quote);
+extern void
+rust_be_error_at (const Location, const std::string &errmsg);
+extern void
+rust_be_warning_at (const Location, int opt, const std::string &warningmsg);
+extern void
+rust_be_fatal_error (const Location, const std::string &errmsg);
+extern void
+rust_be_inform (const Location, const std::string &infomsg);
+extern void
+rust_be_get_quotechars (const char **open_quote, const char **close_quote);
#endif // !defined(RUST_DIAGNOSTICS_H)
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 47c3657..6699b47 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1,5 +1,5 @@
// rust-gcc.cc -- Rust frontend to gcc IR.
-// Copyright (C) 2011-2019 Free Software Foundation, Inc.
+// Copyright (C) 2011-2020 Free Software Foundation, Inc.
// Contributed by Ian Lance Taylor, Google.
// forked from gccgo
@@ -428,6 +428,7 @@ private:
tree convert_tree (tree, tree, Location);
private:
+<<<<<<< HEAD
static const int builtin_const = 1 << 0;
static const int builtin_noreturn = 1 << 1;
static const int builtin_novops = 1 << 2;
@@ -436,6 +437,13 @@ private:
const char *libname, tree fntype, int flags);
// A mapping of the GCC built-ins exposed to GCCRust.
+=======
+ void define_builtin (built_in_function bcode, const char *name,
+ const char *libname, tree fntype, bool const_p,
+ bool noreturn_p);
+
+ // A mapping of the GCC built-ins exposed to GCCGo.
+>>>>>>> 12e994a7967... Fix indentation
std::map<std::string, Bfunction *> builtin_functions_;
};
@@ -456,22 +464,42 @@ Gcc_backend::Gcc_backend ()
tree t = this->integer_type (true, BITS_PER_UNIT)->get_tree ();
tree p = build_pointer_type (build_qualified_type (t, TYPE_QUAL_VOLATILE));
this->define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_1, "__sync_fetch_and_add_1",
+<<<<<<< HEAD
NULL, build_function_type_list (t, p, t, NULL_TREE), 0);
+=======
+ NULL, build_function_type_list (t, p, t, NULL_TREE),
+ false, false);
+>>>>>>> 12e994a7967... Fix indentation
t = this->integer_type (true, BITS_PER_UNIT * 2)->get_tree ();
p = build_pointer_type (build_qualified_type (t, TYPE_QUAL_VOLATILE));
this->define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_2, "__sync_fetch_and_add_2",
+<<<<<<< HEAD
NULL, build_function_type_list (t, p, t, NULL_TREE), 0);
+=======
+ NULL, build_function_type_list (t, p, t, NULL_TREE),
+ false, false);
+>>>>>>> 12e994a7967... Fix indentation
t = this->integer_type (true, BITS_PER_UNIT * 4)->get_tree ();
p = build_pointer_type (build_qualified_type (t, TYPE_QUAL_VOLATILE));
this->define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_4, "__sync_fetch_and_add_4",
+<<<<<<< HEAD
NULL, build_function_type_list (t, p, t, NULL_TREE), 0);
+=======
+ NULL, build_function_type_list (t, p, t, NULL_TREE),
+ false, false);
+>>>>>>> 12e994a7967... Fix indentation
t = this->integer_type (true, BITS_PER_UNIT * 8)->get_tree ();
p = build_pointer_type (build_qualified_type (t, TYPE_QUAL_VOLATILE));
this->define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_8, "__sync_fetch_and_add_8",
+<<<<<<< HEAD
NULL, build_function_type_list (t, p, t, NULL_TREE), 0);
+=======
+ NULL, build_function_type_list (t, p, t, NULL_TREE),
+ false, false);
+>>>>>>> 12e994a7967... Fix indentation
// We use __builtin_expect for magic import functions.
this->define_builtin (BUILT_IN_EXPECT, "__builtin_expect", NULL,
@@ -479,7 +507,11 @@ Gcc_backend::Gcc_backend ()
long_integer_type_node,
long_integer_type_node,
NULL_TREE),
+<<<<<<< HEAD
builtin_const);
+=======
+ true, false);
+>>>>>>> 12e994a7967... Fix indentation
// We use __builtin_memcmp for struct comparisons.
this->define_builtin (BUILT_IN_MEMCMP, "__builtin_memcmp", "memcmp",
@@ -487,53 +519,86 @@ Gcc_backend::Gcc_backend ()
const_ptr_type_node,
const_ptr_type_node,
size_type_node, NULL_TREE),
+<<<<<<< HEAD
0);
+=======
+ false, false);
+>>>>>>> 12e994a7967... Fix indentation
// We use __builtin_memmove for copying data.
this->define_builtin (BUILT_IN_MEMMOVE, "__builtin_memmove", "memmove",
build_function_type_list (void_type_node, ptr_type_node,
const_ptr_type_node,
size_type_node, NULL_TREE),
+<<<<<<< HEAD
0);
+=======
+ false, false);
+>>>>>>> 12e994a7967... Fix indentation
// We use __builtin_memset for zeroing data.
this->define_builtin (BUILT_IN_MEMSET, "__builtin_memset", "memset",
build_function_type_list (void_type_node, ptr_type_node,
integer_type_node,
size_type_node, NULL_TREE),
+<<<<<<< HEAD
0);
+=======
+ false, false);
+>>>>>>> 12e994a7967... Fix indentation
// Used by runtime/internal/sys and math/bits.
this->define_builtin (BUILT_IN_CTZ, "__builtin_ctz", "ctz",
build_function_type_list (integer_type_node,
unsigned_type_node,
NULL_TREE),
+<<<<<<< HEAD
builtin_const);
+=======
+ true, false);
+>>>>>>> 12e994a7967... Fix indentation
this->define_builtin (BUILT_IN_CTZLL, "__builtin_ctzll", "ctzll",
build_function_type_list (integer_type_node,
long_long_unsigned_type_node,
NULL_TREE),
+<<<<<<< HEAD
builtin_const);
+=======
+ true, false);
+>>>>>>> 12e994a7967... Fix indentation
this->define_builtin (BUILT_IN_CLZ, "__builtin_clz", "clz",
build_function_type_list (integer_type_node,
unsigned_type_node,
NULL_TREE),
+<<<<<<< HEAD
builtin_const);
+=======
+ true, false);
+>>>>>>> 12e994a7967... Fix indentation
this->define_builtin (BUILT_IN_CLZLL, "__builtin_clzll", "clzll",
build_function_type_list (integer_type_node,
long_long_unsigned_type_node,
NULL_TREE),
+<<<<<<< HEAD
builtin_const);
+=======
+ true, false);
+>>>>>>> 12e994a7967... Fix indentation
this->define_builtin (BUILT_IN_POPCOUNT, "__builtin_popcount", "popcount",
build_function_type_list (integer_type_node,
unsigned_type_node,
NULL_TREE),
+<<<<<<< HEAD
builtin_const);
+=======
+ true, false);
+>>>>>>> 12e994a7967... Fix indentation
this->define_builtin (BUILT_IN_POPCOUNTLL, "__builtin_popcountll",
"popcountll",
build_function_type_list (integer_type_node,
long_long_unsigned_type_node,
NULL_TREE),
+<<<<<<< HEAD
builtin_const);
this->define_builtin (BUILT_IN_BSWAP16, "__builtin_bswap16", "bswap16",
build_function_type_list (uint16_type_node,
@@ -547,6 +612,21 @@ Gcc_backend::Gcc_backend ()
build_function_type_list (uint64_type_node,
uint64_type_node, NULL_TREE),
builtin_const);
+=======
+ true, false);
+ this->define_builtin (BUILT_IN_BSWAP16, "__builtin_bswap16", "bswap16",
+ build_function_type_list (uint16_type_node,
+ uint16_type_node, NULL_TREE),
+ true, false);
+ this->define_builtin (BUILT_IN_BSWAP32, "__builtin_bswap32", "bswap32",
+ build_function_type_list (uint32_type_node,
+ uint32_type_node, NULL_TREE),
+ true, false);
+ this->define_builtin (BUILT_IN_BSWAP64, "__builtin_bswap64", "bswap64",
+ build_function_type_list (uint64_type_node,
+ uint64_type_node, NULL_TREE),
+ true, false);
+>>>>>>> 12e994a7967... Fix indentation
// We provide some functions for the math library.
tree math_function_type
@@ -561,6 +641,7 @@ Gcc_backend::Gcc_backend ()
= build_function_type_list (long_double_type_node, long_double_type_node,
long_double_type_node, NULL_TREE);
this->define_builtin (BUILT_IN_ACOS, "__builtin_acos", "acos",
+<<<<<<< HEAD
math_function_type, builtin_const);
this->define_builtin (BUILT_IN_ACOSL, "__builtin_acosl", "acosl",
math_function_type_long, builtin_const);
@@ -604,15 +685,65 @@ Gcc_backend::Gcc_backend ()
math_function_type_two, builtin_const);
this->define_builtin (BUILT_IN_FMODL, "__builtin_fmodl", "fmodl",
math_function_type_long_two, builtin_const);
+=======
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_ACOSL, "__builtin_acosl", "acosl",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_ASIN, "__builtin_asin", "asin",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_ASINL, "__builtin_asinl", "asinl",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_ATAN, "__builtin_atan", "atan",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_ATANL, "__builtin_atanl", "atanl",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_ATAN2, "__builtin_atan2", "atan2",
+ math_function_type_two, true, false);
+ this->define_builtin (BUILT_IN_ATAN2L, "__builtin_atan2l", "atan2l",
+ math_function_type_long_two, true, false);
+ this->define_builtin (BUILT_IN_CEIL, "__builtin_ceil", "ceil",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_CEILL, "__builtin_ceill", "ceill",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_COS, "__builtin_cos", "cos",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_COSL, "__builtin_cosl", "cosl",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_EXP, "__builtin_exp", "exp",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_EXPL, "__builtin_expl", "expl",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_EXPM1, "__builtin_expm1", "expm1",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_EXPM1L, "__builtin_expm1l", "expm1l",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_FABS, "__builtin_fabs", "fabs",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_FABSL, "__builtin_fabsl", "fabsl",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_FLOOR, "__builtin_floor", "floor",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_FLOORL, "__builtin_floorl", "floorl",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_FMOD, "__builtin_fmod", "fmod",
+ math_function_type_two, true, false);
+ this->define_builtin (BUILT_IN_FMODL, "__builtin_fmodl", "fmodl",
+ math_function_type_long_two, true, false);
+>>>>>>> 12e994a7967... Fix indentation
this->define_builtin (BUILT_IN_LDEXP, "__builtin_ldexp", "ldexp",
build_function_type_list (double_type_node,
double_type_node,
integer_type_node, NULL_TREE),
+<<<<<<< HEAD
builtin_const);
+=======
+ true, false);
+>>>>>>> 12e994a7967... Fix indentation
this->define_builtin (BUILT_IN_LDEXPL, "__builtin_ldexpl", "ldexpl",
build_function_type_list (long_double_type_node,
long_double_type_node,
integer_type_node, NULL_TREE),
+<<<<<<< HEAD
builtin_const);
this->define_builtin (BUILT_IN_LOG, "__builtin_log", "log",
math_function_type, builtin_const);
@@ -646,11 +777,47 @@ Gcc_backend::Gcc_backend ()
math_function_type, builtin_const);
this->define_builtin (BUILT_IN_TRUNCL, "__builtin_truncl", "truncl",
math_function_type_long, builtin_const);
+=======
+ true, false);
+ this->define_builtin (BUILT_IN_LOG, "__builtin_log", "log",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_LOGL, "__builtin_logl", "logl",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_LOG1P, "__builtin_log1p", "log1p",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_LOG1PL, "__builtin_log1pl", "log1pl",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_LOG10, "__builtin_log10", "log10",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_LOG10L, "__builtin_log10l", "log10l",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_LOG2, "__builtin_log2", "log2",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_LOG2L, "__builtin_log2l", "log2l",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_SIN, "__builtin_sin", "sin",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_SINL, "__builtin_sinl", "sinl",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_SQRT, "__builtin_sqrt", "sqrt",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_TAN, "__builtin_tan", "tan",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_TANL, "__builtin_tanl", "tanl",
+ math_function_type_long, true, false);
+ this->define_builtin (BUILT_IN_TRUNC, "__builtin_trunc", "trunc",
+ math_function_type, true, false);
+ this->define_builtin (BUILT_IN_TRUNCL, "__builtin_truncl", "truncl",
+ math_function_type_long, true, false);
+>>>>>>> 12e994a7967... Fix indentation
// We use __builtin_return_address in the thunk we build for
// functions which call recover, and for runtime.getcallerpc.
t = build_function_type_list (ptr_type_node, unsigned_type_node, NULL_TREE);
this->define_builtin (BUILT_IN_RETURN_ADDRESS, "__builtin_return_address",
+<<<<<<< HEAD
NULL, t, 0);
// The runtime calls __builtin_dwarf_cfa for runtime.getcallersp.
@@ -662,94 +829,176 @@ Gcc_backend::Gcc_backend ()
this->define_builtin (
BUILT_IN_EXTRACT_RETURN_ADDR, "__builtin_extract_return_addr", NULL,
build_function_type_list (ptr_type_node, ptr_type_node, NULL_TREE), 0);
+=======
+ NULL, t, false, false);
+
+ // The runtime calls __builtin_dwarf_cfa for runtime.getcallersp.
+ t = build_function_type_list (ptr_type_node, NULL_TREE);
+ this->define_builtin (BUILT_IN_DWARF_CFA, "__builtin_dwarf_cfa", NULL, t,
+ false, false);
+
+ // The runtime calls __builtin_extract_return_addr when recording
+ // the address to which a function returns.
+ this->define_builtin (BUILT_IN_EXTRACT_RETURN_ADDR,
+ "__builtin_extract_return_addr", NULL,
+ build_function_type_list (ptr_type_node, ptr_type_node,
+ NULL_TREE),
+ false, false);
+>>>>>>> 12e994a7967... Fix indentation
// The compiler uses __builtin_trap for some exception handling
// cases.
this->define_builtin (BUILT_IN_TRAP, "__builtin_trap", NULL,
build_function_type (void_type_node, void_list_node),
+<<<<<<< HEAD
builtin_noreturn);
+=======
+ false, true);
+>>>>>>> 12e994a7967... Fix indentation
// The runtime uses __builtin_prefetch.
this->define_builtin (BUILT_IN_PREFETCH, "__builtin_prefetch", NULL,
build_varargs_function_type_list (void_type_node,
const_ptr_type_node,
NULL_TREE),
+<<<<<<< HEAD
builtin_novops);
+=======
+ false, false);
+>>>>>>> 12e994a7967... Fix indentation
// The compiler uses __builtin_unreachable for cases that cannot
// occur.
this->define_builtin (BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL,
build_function_type (void_type_node, void_list_node),
+<<<<<<< HEAD
builtin_const | builtin_noreturn);
+=======
+ true, true);
+>>>>>>> 12e994a7967... Fix indentation
// We provide some atomic functions.
t = build_function_type_list (uint32_type_node, ptr_type_node,
integer_type_node, NULL_TREE);
+<<<<<<< HEAD
this->define_builtin (BUILT_IN_ATOMIC_LOAD_4, "__atomic_load_4", NULL, t, 0);
t = build_function_type_list (uint64_type_node, ptr_type_node,
integer_type_node, NULL_TREE);
this->define_builtin (BUILT_IN_ATOMIC_LOAD_8, "__atomic_load_8", NULL, t, 0);
+=======
+ this->define_builtin (BUILT_IN_ATOMIC_LOAD_4, "__atomic_load_4", NULL, t,
+ false, false);
+
+ t = build_function_type_list (uint64_type_node, ptr_type_node,
+ integer_type_node, NULL_TREE);
+ this->define_builtin (BUILT_IN_ATOMIC_LOAD_8, "__atomic_load_8", NULL, t,
+ false, false);
+>>>>>>> 12e994a7967... Fix indentation
t = build_function_type_list (void_type_node, ptr_type_node, uint32_type_node,
integer_type_node, NULL_TREE);
this->define_builtin (BUILT_IN_ATOMIC_STORE_4, "__atomic_store_4", NULL, t,
+<<<<<<< HEAD
0);
+=======
+ false, false);
+>>>>>>> 12e994a7967... Fix indentation
t = build_function_type_list (void_type_node, ptr_type_node, uint64_type_node,
integer_type_node, NULL_TREE);
this->define_builtin (BUILT_IN_ATOMIC_STORE_8, "__atomic_store_8", NULL, t,
+<<<<<<< HEAD
0);
+=======
+ false, false);
+>>>>>>> 12e994a7967... Fix indentation
t = build_function_type_list (uint32_type_node, ptr_type_node,
uint32_type_node, integer_type_node, NULL_TREE);
this->define_builtin (BUILT_IN_ATOMIC_EXCHANGE_4, "__atomic_exchange_4", NULL,
+<<<<<<< HEAD
t, 0);
+=======
+ t, false, false);
+>>>>>>> 12e994a7967... Fix indentation
t = build_function_type_list (uint64_type_node, ptr_type_node,
uint64_type_node, integer_type_node, NULL_TREE);
this->define_builtin (BUILT_IN_ATOMIC_EXCHANGE_8, "__atomic_exchange_8", NULL,
+<<<<<<< HEAD
t, 0);
+=======
+ t, false, false);
+>>>>>>> 12e994a7967... Fix indentation
t = build_function_type_list (boolean_type_node, ptr_type_node, ptr_type_node,
uint32_type_node, boolean_type_node,
integer_type_node, integer_type_node,
NULL_TREE);
this->define_builtin (BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4,
+<<<<<<< HEAD
"__atomic_compare_exchange_4", NULL, t, 0);
+=======
+ "__atomic_compare_exchange_4", NULL, t, false, false);
+>>>>>>> 12e994a7967... Fix indentation
t = build_function_type_list (boolean_type_node, ptr_type_node, ptr_type_node,
uint64_type_node, boolean_type_node,
integer_type_node, integer_type_node,
NULL_TREE);
this->define_builtin (BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8,
+<<<<<<< HEAD
"__atomic_compare_exchange_8", NULL, t, 0);
+=======
+ "__atomic_compare_exchange_8", NULL, t, false, false);
+>>>>>>> 12e994a7967... Fix indentation
t = build_function_type_list (uint32_type_node, ptr_type_node,
uint32_type_node, integer_type_node, NULL_TREE);
this->define_builtin (BUILT_IN_ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4",
+<<<<<<< HEAD
NULL, t, 0);
+=======
+ NULL, t, false, false);
+>>>>>>> 12e994a7967... Fix indentation
t = build_function_type_list (uint64_type_node, ptr_type_node,
uint64_type_node, integer_type_node, NULL_TREE);
this->define_builtin (BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8",
+<<<<<<< HEAD
NULL, t, 0);
+=======
+ NULL, t, false, false);
+>>>>>>> 12e994a7967... Fix indentation
t = build_function_type_list (unsigned_char_type_node, ptr_type_node,
unsigned_char_type_node, integer_type_node,
NULL_TREE);
this->define_builtin (BUILT_IN_ATOMIC_AND_FETCH_1, "__atomic_and_fetch_1",
+<<<<<<< HEAD
NULL, t, 0);
this->define_builtin (BUILT_IN_ATOMIC_FETCH_AND_1, "__atomic_fetch_and_1",
NULL, t, 0);
+=======
+ NULL, t, false, false);
+ this->define_builtin (BUILT_IN_ATOMIC_FETCH_AND_1, "__atomic_fetch_and_1",
+ NULL, t, false, false);
+>>>>>>> 12e994a7967... Fix indentation
t = build_function_type_list (unsigned_char_type_node, ptr_type_node,
unsigned_char_type_node, integer_type_node,
NULL_TREE);
this->define_builtin (BUILT_IN_ATOMIC_OR_FETCH_1, "__atomic_or_fetch_1", NULL,
+<<<<<<< HEAD
t, 0);
this->define_builtin (BUILT_IN_ATOMIC_FETCH_OR_1, "__atomic_fetch_or_1", NULL,
t, 0);
+=======
+ t, false, false);
+ this->define_builtin (BUILT_IN_ATOMIC_FETCH_OR_1, "__atomic_fetch_or_1", NULL,
+ t, false, false);
+>>>>>>> 12e994a7967... Fix indentation
}
// Get an unnamed integer type.
@@ -1138,7 +1387,11 @@ Gcc_backend::named_type (const std::string &name, Btype *btype,
// The middle-end expects a basic type to have a name. In Rust every
// basic type will have a name. The first time we see a basic type,
+<<<<<<< HEAD
// give it whatever Rust name we have at this point.
+=======
+ // give it whatever Go name we have at this point.
+>>>>>>> 12e994a7967... Fix indentation
if (TYPE_NAME (type) == NULL_TREE
&& location.gcc_location () == BUILTINS_LOCATION
&& (TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == REAL_TYPE
@@ -1584,7 +1837,11 @@ Gcc_backend::unary_expression (Operator op, Bexpression *expr,
enum tree_code code;
switch (op)
{
+<<<<<<< HEAD
+ case OPERATOR_MINUS: {
+=======
case OPERATOR_MINUS: {
+>>>>>>> 12e994a7967... Fix indentation
tree computed_type = excess_precision_type (type_tree);
if (computed_type != NULL_TREE)
{
@@ -1916,8 +2173,13 @@ Gcc_backend::call_expression (Bfunction *, // containing fcn for call
// This is to support builtin math functions when using 80387 math.
tree excess_type = NULL_TREE;
if (optimize && TREE_CODE (fndecl) == FUNCTION_DECL
+<<<<<<< HEAD
&& fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
&& DECL_IS_UNDECLARED_BUILTIN (fndecl) && nargs > 0
+=======
+ && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL) && DECL_IS_BUILTIN (fndecl)
+ && nargs > 0
+>>>>>>> 12e994a7967... Fix indentation
&& ((SCALAR_FLOAT_TYPE_P (rettype)
&& SCALAR_FLOAT_TYPE_P (TREE_TYPE (args[0])))
|| (COMPLEX_FLOAT_TYPE_P (rettype)
@@ -2420,11 +2682,19 @@ Gcc_backend::non_zero_size_type (tree type)
DECL_CONTEXT (field) = type;
TYPE_FIELDS (type) = field;
layout_type (type);
+<<<<<<< HEAD
rust_non_zero_struct = type;
+=======
+ go_non_zero_struct = type;
+>>>>>>> 12e994a7967... Fix indentation
}
return rust_non_zero_struct;
+<<<<<<< HEAD
+ case ARRAY_TYPE: {
+=======
case ARRAY_TYPE: {
+>>>>>>> 12e994a7967... Fix indentation
tree element_type = non_zero_size_type (TREE_TYPE (type));
return build_array_type_nelts (element_type, 1);
}
@@ -2532,7 +2802,11 @@ Gcc_backend::global_variable_set_init (Bvariable *var, Bexpression *expr)
if (symtab_node::get (var_decl)
&& symtab_node::get (var_decl)->implicit_section)
{
+<<<<<<< HEAD
set_decl_section_name (var_decl, (const char *) NULL);
+=======
+ set_decl_section_name (var_decl, NULL);
+>>>>>>> 12e994a7967... Fix indentation
resolve_unique_section (var_decl, compute_reloc_for_constant (expr_tree),
1);
}
@@ -2647,14 +2921,22 @@ Gcc_backend::temporary_variable (Bfunction *function, Bblock *bblock,
else
push_cfun (DECL_STRUCT_FUNCTION (decl));
+<<<<<<< HEAD
var = create_tmp_var (type_tree, "RUSTTMP");
+=======
+ var = create_tmp_var (type_tree, "GOTMP");
+>>>>>>> 12e994a7967... Fix indentation
pop_cfun ();
}
else
{
gcc_assert (bblock != NULL);
var = build_decl (location.gcc_location (), VAR_DECL,
+<<<<<<< HEAD
create_tmp_var_name ("RUSTTMP"), type_tree);
+=======
+ create_tmp_var_name ("GOTMP"), type_tree);
+>>>>>>> 12e994a7967... Fix indentation
DECL_ARTIFICIAL (var) = 1;
DECL_IGNORED_P (var) = 1;
TREE_USED (var) = 1;
@@ -3048,15 +3330,24 @@ Gcc_backend::function (Btype *fntype, const std::string &name,
if (pos == name.length ())
{
struct cl_optimization cur_opts;
+<<<<<<< HEAD
cl_optimization_save (&cur_opts, &global_options,
&global_options_set);
+=======
+ cl_optimization_save (&cur_opts, &global_options);
+>>>>>>> 12e994a7967... Fix indentation
global_options.x_optimize_size = 1;
global_options.x_optimize_fast = 0;
global_options.x_optimize_debug = 0;
DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl)
+<<<<<<< HEAD
= build_optimization_node (&global_options, &global_options_set);
cl_optimization_restore (&global_options, &global_options_set,
&cur_opts);
+=======
+ = build_optimization_node (&global_options);
+ cl_optimization_restore (&global_options, &cur_opts);
+>>>>>>> 12e994a7967... Fix indentation
}
}
diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc
index c3ae4da..66895dc 100644
--- a/gcc/rust/rust-lang.cc
+++ b/gcc/rust/rust-lang.cc
@@ -16,27 +16,32 @@
#include "common/common-target.h"
#include <mpfr.h>
-// note: header files must be in this order or else forward declarations don't work properly. Kinda
-// dumb system, but have to live with it. clang-format seems to mess it up
-/* Order: config, system, coretypes, target, tree, gimple-expr, diagnostic, opts, fold-const,
- * gimplify, stor-layout, debug, convert, langhooks, langhooks-def, common-target */
+// note: header files must be in this order or else forward declarations don't
+// work properly. Kinda dumb system, but have to live with it. clang-format
+// seems to mess it up
+/* Order: config, system, coretypes, target, tree, gimple-expr, diagnostic,
+ * opts, fold-const, gimplify, stor-layout, debug, convert, langhooks,
+ * langhooks-def, common-target */
// FIXME: test saving intellisense
#include "options.h"
// version check to stop compiling if c++ isn't c++11 or higher
#if __cplusplus < 201103
-#error \
+#error \
"GCC Rust frontend requires C++11 or higher. You can compile the g++ frontend first and then compile the Rust frontend using that."
#endif
// TODO: is this best way to do it? Is it allowed? (should be)
/* General TODOs:
- * - maybe convert all raw pointer-returning/passing functions that conceptually return a unique
- * pointer actually return a unique pointer. i.e. parse methods and constructors for AST objects.
- * make_unique should probably be avoided to keep C++11 compatibility.
- * - convert all copies of expensive-to-copy (deep copy) AST objects into moves, if possible. Don't
- * remove clone functionality - it may be required for e.g. HIR conversion. */
+ * - maybe convert all raw pointer-returning/passing functions that
+ * conceptually return a unique pointer actually return a unique pointer. i.e.
+ * parse methods and constructors for AST objects. make_unique should probably
+ * be avoided to keep C++11 compatibility.
+ * - convert all copies of expensive-to-copy (deep copy) AST objects into
+ * moves, if possible. Don't
+ * remove clone functionality - it may be required for e.g. HIR conversion.
+ */
#include "rust-system.h"
#include "rust-parse.h"
@@ -45,32 +50,40 @@
#include "rust-target.h"
// Language-dependent contents of a type. GTY() mark used for garbage collector.
-struct GTY(()) lang_type {
- char dummy;
+struct GTY (()) lang_type
+{
+ char dummy;
};
// Language-dependent contents of a decl.
-struct GTY(()) lang_decl {
- char dummy;
+struct GTY (()) lang_decl
+{
+ char dummy;
};
-// Language-dependent contents of an identifier. This must include a tree_identifier.
-struct GTY(()) lang_identifier {
- struct tree_identifier common;
+// Language-dependent contents of an identifier. This must include a
+// tree_identifier.
+struct GTY (()) lang_identifier
+{
+ struct tree_identifier common;
};
// The resulting tree type.
-union GTY((desc("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
- chain_next(
+union GTY ((
+ desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
+ chain_next (
"CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), "
- "TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL"))) lang_tree_node {
- union tree_node GTY((tag("0"), desc("tree_node_structure (&%h)"))) generic;
- struct lang_identifier GTY((tag("1"))) identifier;
+ "TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
+ lang_tree_node
+{
+ union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) generic;
+ struct lang_identifier GTY ((tag ("1"))) identifier;
};
// We don't use language_function.
-struct GTY(()) language_function {
- int dummy;
+struct GTY (()) language_function
+{
+ int dummy;
};
// Kinda HACK-ish - store parsing session as static variable
@@ -84,124 +97,153 @@ void rust_add_target_info(const char* key, const char* value) {
/* Language hooks. */
/* Initial lang hook called (possibly), used for initialisation.
- * Must call build_common_tree_nodes, set_sizetype, build_common_tree_nodes_2, and
- * build_common_builtin_nodes, as well as set global variable void_list_node.
- * Apparently called after option handling? */
-static bool grs_langhook_init(void) {
- /* Something to do with this:
- This allows the code in d-builtins.cc to not have to worry about
- converting (C signed char *) to (D char *) for string arguments of
- built-in functions. The parameter (signed_char = false) specifies
- whether char is signed. */
- build_common_tree_nodes(false);
-
- // Creates a new TREE_LIST node with purpose NULL_TREE and value void_type_node
- void_list_node = build_tree_list(NULL_TREE, void_type_node);
-
- // Builds built-ins for middle-end after all front-end built-ins are already instantiated
- build_common_builtin_nodes();
-
- mpfr_set_default_prec(128);
-
- using_eh_for_cleanups();
-
- // initialise compiler session
- session.init();
-
- return true;
+ * Must call build_common_tree_nodes, set_sizetype, build_common_tree_nodes_2,
+ * and build_common_builtin_nodes, as well as set global variable
+ * void_list_node. Apparently called after option handling? */
+static bool
+grs_langhook_init (void)
+{
+ /* Something to do with this:
+ This allows the code in d-builtins.cc to not have to worry about
+ converting (C signed char *) to (D char *) for string arguments of
+ built-in functions. The parameter (signed_char = false) specifies
+ whether char is signed. */
+ build_common_tree_nodes (false);
+
+ // Creates a new TREE_LIST node with purpose NULL_TREE and value
+ // void_type_node
+ void_list_node = build_tree_list (NULL_TREE, void_type_node);
+
+ // Builds built-ins for middle-end after all front-end built-ins are already
+ // instantiated
+ build_common_builtin_nodes ();
+
+ mpfr_set_default_prec (128);
+
+ using_eh_for_cleanups ();
+
+ // initialise compiler session
+ session.init ();
+
+ return true;
}
-/* The option mask (something to do with options for specific frontends or something). */
-static unsigned int grs_langhook_option_lang_mask(void) {
- return CL_Rust;
+/* The option mask (something to do with options for specific frontends or
+ * something). */
+static unsigned int
+grs_langhook_option_lang_mask (void)
+{
+ return CL_Rust;
}
/* Initialize the options structure. */
-static void grs_langhook_init_options_struct(struct gcc_options* opts) {
- // nothing yet - used by frontends to change specific options for the language
- session.init_options();
+static void
+grs_langhook_init_options_struct (struct gcc_options *opts)
+{
+ // nothing yet - used by frontends to change specific options for the language
+ session.init_options ();
}
-/* Main entry point for front-end, apparently. Finds input file names in global vars in_fnames and
- * num_in_fnames. From this, frontend can take over and do actual parsing and initial compilation.
- * This function must create a complete parse tree in a global var, and then return.
+/* Main entry point for front-end, apparently. Finds input file names in global
+ * vars in_fnames and num_in_fnames. From this, frontend can take over and do
+ * actual parsing and initial compilation. This function must create a complete
+ * parse tree in a global var, and then return.
*
* Some consider this the "start of compilation". */
-static void grs_langhook_parse_file(void) {
- fprintf(stderr, "Preparing to parse files. \n");
+static void
+grs_langhook_parse_file (void)
+{
+ fprintf (stderr, "Preparing to parse files. \n");
- // grs_parse_files(num_in_fnames, in_fnames);
- session.parse_files(num_in_fnames, in_fnames);
+ // grs_parse_files(num_in_fnames, in_fnames);
+ session.parse_files (num_in_fnames, in_fnames);
}
-/* Seems to get the exact type for a specific type - e.g. for scalar float with 32-bit bitsize, it
- * returns float, and for 64-bit bitsize, it returns double. Used to map RTL nodes to machine modes or
- * something like that. */
-static tree grs_langhook_type_for_mode(machine_mode mode, int unsignedp) {
- // TODO: change all this later to match rustc types
- if (mode == TYPE_MODE(float_type_node))
- return float_type_node;
-
- if (mode == TYPE_MODE(double_type_node))
- return double_type_node;
-
- if (mode == TYPE_MODE(intQI_type_node)) // quarter integer mode - single byte treated as integer
- return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
- if (mode == TYPE_MODE(intHI_type_node)) // half integer mode - two-byte integer
- return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
- if (mode == TYPE_MODE(intSI_type_node)) // single integer mode - four-byte integer
- return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
- if (mode == TYPE_MODE(intDI_type_node)) // double integer mode - eight-byte integer
- return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
- if (mode == TYPE_MODE(intTI_type_node)) // tetra integer mode - 16-byte integer
- return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
-
- if (mode == TYPE_MODE(integer_type_node))
- return unsignedp ? unsigned_type_node : integer_type_node;
-
- if (mode == TYPE_MODE(long_integer_type_node))
- return unsignedp ? long_unsigned_type_node : long_integer_type_node;
-
- if (mode == TYPE_MODE(long_long_integer_type_node))
- return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
-
- if (COMPLEX_MODE_P(mode)) {
- if (mode == TYPE_MODE(complex_float_type_node))
- return complex_float_type_node;
- if (mode == TYPE_MODE(complex_double_type_node))
- return complex_double_type_node;
- if (mode == TYPE_MODE(complex_long_double_type_node))
- return complex_long_double_type_node;
- if (mode == TYPE_MODE(complex_integer_type_node) && !unsignedp)
- return complex_integer_type_node;
+/* Seems to get the exact type for a specific type - e.g. for scalar float with
+ * 32-bit bitsize, it returns float, and for 64-bit bitsize, it returns double.
+ * Used to map RTL nodes to machine modes or something like that. */
+static tree
+grs_langhook_type_for_mode (machine_mode mode, int unsignedp)
+{
+ // TODO: change all this later to match rustc types
+ if (mode == TYPE_MODE (float_type_node))
+ return float_type_node;
+
+ if (mode == TYPE_MODE (double_type_node))
+ return double_type_node;
+
+ if (mode == TYPE_MODE (intQI_type_node)) // quarter integer mode - single byte
+ // treated as integer
+ return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
+ if (mode
+ == TYPE_MODE (intHI_type_node)) // half integer mode - two-byte integer
+ return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
+ if (mode
+ == TYPE_MODE (intSI_type_node)) // single integer mode - four-byte integer
+ return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
+ if (mode
+ == TYPE_MODE (
+ intDI_type_node)) // double integer mode - eight-byte integer
+ return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
+ if (mode
+ == TYPE_MODE (intTI_type_node)) // tetra integer mode - 16-byte integer
+ return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+
+ if (mode == TYPE_MODE (integer_type_node))
+ return unsignedp ? unsigned_type_node : integer_type_node;
+
+ if (mode == TYPE_MODE (long_integer_type_node))
+ return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+
+ if (mode == TYPE_MODE (long_long_integer_type_node))
+ return unsignedp ? long_long_unsigned_type_node
+ : long_long_integer_type_node;
+
+ if (COMPLEX_MODE_P (mode))
+ {
+ if (mode == TYPE_MODE (complex_float_type_node))
+ return complex_float_type_node;
+ if (mode == TYPE_MODE (complex_double_type_node))
+ return complex_double_type_node;
+ if (mode == TYPE_MODE (complex_long_double_type_node))
+ return complex_long_double_type_node;
+ if (mode == TYPE_MODE (complex_integer_type_node) && !unsignedp)
+ return complex_integer_type_node;
}
- /* gcc_unreachable */
- return NULL;
+ /* gcc_unreachable */
+ return NULL;
}
-/* This appears to be used for creating different types for different bit sizes (e.g. int and long).
- * Also, the Go frontend calls this from type_for_mode to determine the type from a specific bitsize
- * for integer types.
- * FIXME: change this when working on AST-GENERIC conversion to allow the full range of Rust type
- * sizes. */
-static tree grs_langhook_type_for_size(
- unsigned int bits ATTRIBUTE_UNUSED, int unsignedp ATTRIBUTE_UNUSED) {
- gcc_unreachable();
- return NULL_TREE;
- // nothing at the moment, but change later
+/* This appears to be used for creating different types for different bit sizes
+ * (e.g. int and long). Also, the Go frontend calls this from type_for_mode to
+ * determine the type from a specific bitsize for integer types.
+ * FIXME: change this when working on AST-GENERIC conversion to allow the full
+ * range of Rust type sizes. */
+static tree
+grs_langhook_type_for_size (unsigned int bits ATTRIBUTE_UNUSED,
+ int unsignedp ATTRIBUTE_UNUSED)
+{
+ gcc_unreachable ();
+ return NULL_TREE;
+ // nothing at the moment, but change later
}
// Record a builtin function. We just ignore builtin functions.
-static tree grs_langhook_builtin_function(tree decl ATTRIBUTE_UNUSED) {
- return decl;
+static tree
+grs_langhook_builtin_function (tree decl ATTRIBUTE_UNUSED)
+{
+ return decl;
}
-/* Return true if we are in the global binding level (which is never, apparently). */
-static bool grs_langhook_global_bindings_p(void) {
- // return current_function_decl == NULL_TREE;
- // gcc_unreachable();
- // return true;
- return false;
+/* Return true if we are in the global binding level (which is never,
+ * apparently). */
+static bool
+grs_langhook_global_bindings_p (void)
+{
+ // return current_function_decl == NULL_TREE;
+ // gcc_unreachable();
+ // return true;
+ return false;
}
/* Push a declaration into the current binding level. We can't
@@ -210,72 +252,85 @@ static bool grs_langhook_global_bindings_p(void) {
this is used is to record a decl which is to be returned by
getdecls, and we could implement it for that purpose if
necessary. */
-static tree grs_langhook_pushdecl(tree decl ATTRIBUTE_UNUSED) {
- gcc_unreachable();
- return NULL;
+static tree
+grs_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
+{
+ gcc_unreachable ();
+ return NULL;
}
/* This hook is used to get the current list of declarations as trees.
We don't support that; instead we use the write_globals hook. This
can't simply crash because it is called by -gstabs. */
-static tree grs_langhook_getdecls(void) {
- // gcc_unreachable();
- return NULL;
+static tree
+grs_langhook_getdecls (void)
+{
+ // gcc_unreachable();
+ return NULL;
}
// Handle Rust-specific options. Return false if nothing happened.
-static bool grs_langhook_handle_option(size_t scode, const char* arg, HOST_WIDE_INT value,
- int kind ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED,
- const struct cl_option_handlers* handlers ATTRIBUTE_UNUSED) {
- // Convert integer code to lang.opt enum codes with names.
- enum opt_code code = (enum opt_code)scode;
- // used to store whether results of various stuff are successful
- // bool ret = true;
-
- // delegate to session manager
- return session.handle_option(code, arg, value, kind, loc, handlers);
-
- // Handles options as listed in lang.opt.
- /*switch (code) {
- case OPT_I:
- // TODO: add search path
- break;
- case OPT_L:
- // TODO: add library link path or something
- break;
- case OPT_frust_dump:
- // enable dump and return whether this was successful
- ret = rust_enable_dump(arg) ? true : false;
- break;
- // no option handling for -o
- default:
- // return 1 to indicate option is valid
- break;
- }
-
- return ret;*/
+static bool
+grs_langhook_handle_option (
+ size_t scode, const char *arg, HOST_WIDE_INT value, int kind ATTRIBUTE_UNUSED,
+ location_t loc ATTRIBUTE_UNUSED,
+ const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
+{
+ // Convert integer code to lang.opt enum codes with names.
+ enum opt_code code = (enum opt_code) scode;
+ // used to store whether results of various stuff are successful
+ // bool ret = true;
+
+ // delegate to session manager
+ return session.handle_option (code, arg, value, kind, loc, handlers);
+
+ // Handles options as listed in lang.opt.
+ /*switch (code) {
+ case OPT_I:
+ // TODO: add search path
+ break;
+ case OPT_L:
+ // TODO: add library link path or something
+ break;
+ case OPT_frust_dump:
+ // enable dump and return whether this was successful
+ ret = rust_enable_dump(arg) ? true : false;
+ break;
+ // no option handling for -o
+ default:
+ // return 1 to indicate option is valid
+ break;
+ }
+
+ return ret;*/
}
/* Run after parsing options. */
-static bool grs_langhook_post_options(const char** pfilename ATTRIBUTE_UNUSED) {
- // can be used to override other options if required
+static bool
+grs_langhook_post_options (const char **pfilename ATTRIBUTE_UNUSED)
+{
+ // can be used to override other options if required
- // satisfies an assert in init_excess_precision in toplev.c
- if (flag_excess_precision/*_cmdline*/ == EXCESS_PRECISION_DEFAULT)
- flag_excess_precision/*_cmdline*/ = EXCESS_PRECISION_STANDARD;
+ // satisfies an assert in init_excess_precision in toplev.c
+ if (flag_excess_precision /*_cmdline*/ == EXCESS_PRECISION_DEFAULT)
+ flag_excess_precision /*_cmdline*/ = EXCESS_PRECISION_STANDARD;
- /* Returning false means that the backend should be used. */
- return false;
+ /* Returning false means that the backend should be used. */
+ return false;
}
-/* Rust-specific gimplification. May need to gimplify e.g. CALL_EXPR_STATIC_CHAIN */
-static int grs_langhook_gimplify_expr(tree* expr_p ATTRIBUTE_UNUSED,
- gimple_seq* pre_p ATTRIBUTE_UNUSED, gimple_seq* post_p ATTRIBUTE_UNUSED) {
- if (TREE_CODE (*expr_p) == CALL_EXPR
+/* Rust-specific gimplification. May need to gimplify e.g.
+ * CALL_EXPR_STATIC_CHAIN */
+static int
+grs_langhook_gimplify_expr (tree *expr_p ATTRIBUTE_UNUSED,
+ gimple_seq *pre_p ATTRIBUTE_UNUSED,
+ gimple_seq *post_p ATTRIBUTE_UNUSED)
+{
+ if (TREE_CODE (*expr_p) == CALL_EXPR
&& CALL_EXPR_STATIC_CHAIN (*expr_p) != NULL_TREE)
- gimplify_expr (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p, post_p,
- is_gimple_val, fb_rvalue);
- return GS_UNHANDLED;
+ gimplify_expr (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p, post_p,
+ is_gimple_val, fb_rvalue);
+ return GS_UNHANDLED;
}
static tree
@@ -293,8 +348,7 @@ grs_langhook_eh_personality (void)
tree
convert (tree type, tree expr)
{
- if (type == error_mark_node
- || expr == error_mark_node
+ if (type == error_mark_node || expr == error_mark_node
|| TREE_TYPE (expr) == error_mark_node)
return error_mark_node;
@@ -327,7 +381,7 @@ convert (tree type, tree expr)
/* FIXME: This is a hack to preserve trees that we create from the
garbage collector. */
-static GTY(()) tree rust_gc_root;
+static GTY (()) tree rust_gc_root;
void
rust_preserve_from_gc (tree t)
@@ -343,9 +397,9 @@ rust_localize_identifier (const char *ident)
return identifier_to_locale (ident);
}
-/* The language hooks data structure. This is the main interface between the GCC front-end
- * and the GCC middle-end/back-end. A list of language hooks could be found in
- * <gcc>/langhooks.h
+/* The language hooks data structure. This is the main interface between the GCC
+ * front-end and the GCC middle-end/back-end. A list of language hooks could be
+ * found in <gcc>/langhooks.h
*/
#undef LANG_HOOKS_NAME
#undef LANG_HOOKS_INIT
@@ -370,9 +424,11 @@ rust_localize_identifier (const char *ident)
#define LANG_HOOKS_INIT_OPTIONS_STRUCT grs_langhook_init_options_struct
#define LANG_HOOKS_HANDLE_OPTION grs_langhook_handle_option
#define LANG_HOOKS_POST_OPTIONS grs_langhook_post_options
-/* Main lang-hook, apparently. Finds input file names in global vars in_fnames and num_in_fnames
- * From this, frontend can take over and do actual parsing and initial compilation.
- * This hook must create a complete parse tree in a global var, and then return. */
+/* Main lang-hook, apparently. Finds input file names in global vars in_fnames
+ * and num_in_fnames From this, frontend can take over and do actual parsing and
+ * initial compilation.
+ * This hook must create a complete parse tree in a global var, and then return.
+ */
#define LANG_HOOKS_PARSE_FILE grs_langhook_parse_file
#define LANG_HOOKS_TYPE_FOR_MODE grs_langhook_type_for_mode
#define LANG_HOOKS_TYPE_FOR_SIZE grs_langhook_type_for_size
diff --git a/gcc/rust/rust-linemap.cc b/gcc/rust/rust-linemap.cc
index aa75c6e..fef4603 100644
--- a/gcc/rust/rust-linemap.cc
+++ b/gcc/rust/rust-linemap.cc
@@ -2,83 +2,68 @@
#include "rust-linemap.h"
-
// This class implements the Linemap interface defined by the
// frontend.
class Gcc_linemap : public Linemap
{
- public:
- Gcc_linemap()
- : Linemap(),
- in_file_(false)
- { }
+public:
+ Gcc_linemap () : Linemap (), in_file_ (false) {}
- void
- start_file(const char* file_name, unsigned int line_begin);
+ void start_file (const char *file_name, unsigned int line_begin);
- void
- start_line(unsigned int line_number, unsigned int line_size);
+ void start_line (unsigned int line_number, unsigned int line_size);
- Location
- get_location(unsigned int column);
+ Location get_location (unsigned int column);
- void
- stop();
+ void stop ();
- std::string
- to_string(Location);
+ std::string to_string (Location);
- std::string
- location_file(Location);
+ std::string location_file (Location);
- int
- location_line(Location);
+ int location_line (Location);
- protected:
- Location
- get_predeclared_location();
+protected:
+ Location get_predeclared_location ();
- Location
- get_unknown_location();
+ Location get_unknown_location ();
- bool
- is_predeclared(Location);
+ bool is_predeclared (Location);
- bool
- is_unknown(Location);
+ bool is_unknown (Location);
- private:
+private:
// Whether we are currently reading a file.
bool in_file_;
};
-Linemap* Linemap::instance_ = NULL;
+Linemap *Linemap::instance_ = NULL;
// Start getting locations from a new file.
void
-Gcc_linemap::start_file(const char *file_name, unsigned line_begin)
+Gcc_linemap::start_file (const char *file_name, unsigned line_begin)
{
if (this->in_file_)
- linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
- linemap_add(line_table, LC_ENTER, 0, file_name, line_begin);
+ linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
+ linemap_add (line_table, LC_ENTER, 0, file_name, line_begin);
this->in_file_ = true;
}
// Stringify a location
std::string
-Gcc_linemap::to_string(Location location)
+Gcc_linemap::to_string (Location location)
{
const line_map_ordinary *lmo;
location_t resolved_location;
// Screen out unknown and predeclared locations; produce output
// only for simple file:line locations.
- resolved_location =
- linemap_resolve_location (line_table, location.gcc_location(),
- LRK_SPELLING_LOCATION, &lmo);
+ resolved_location
+ = linemap_resolve_location (line_table, location.gcc_location (),
+ LRK_SPELLING_LOCATION, &lmo);
if (lmo == NULL || resolved_location < RESERVED_LOCATION_COUNT)
return "";
const char *path = LINEMAP_FILE (lmo);
@@ -87,87 +72,87 @@ Gcc_linemap::to_string(Location location)
// Strip the source file down to the base file, to reduce clutter.
std::stringstream ss;
- ss << lbasename(path) << ":" << SOURCE_LINE (lmo, location.gcc_location());
- return ss.str();
+ ss << lbasename (path) << ":" << SOURCE_LINE (lmo, location.gcc_location ());
+ return ss.str ();
}
// Return the file name for a given location.
std::string
-Gcc_linemap::location_file(Location loc)
+Gcc_linemap::location_file (Location loc)
{
- return LOCATION_FILE(loc.gcc_location());
+ return LOCATION_FILE (loc.gcc_location ());
}
// Return the line number for a given location.
int
-Gcc_linemap::location_line(Location loc)
+Gcc_linemap::location_line (Location loc)
{
- return LOCATION_LINE(loc.gcc_location());
+ return LOCATION_LINE (loc.gcc_location ());
}
// Stop getting locations.
void
-Gcc_linemap::stop()
+Gcc_linemap::stop ()
{
- linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
+ linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
this->in_file_ = false;
}
// Start a new line.
void
-Gcc_linemap::start_line(unsigned lineno, unsigned linesize)
+Gcc_linemap::start_line (unsigned lineno, unsigned linesize)
{
- linemap_line_start(line_table, lineno, linesize);
+ linemap_line_start (line_table, lineno, linesize);
}
// Get a location.
Location
-Gcc_linemap::get_location(unsigned column)
+Gcc_linemap::get_location (unsigned column)
{
- return Location(linemap_position_for_column(line_table, column));
+ return Location (linemap_position_for_column (line_table, column));
}
// Get the unknown location.
Location
-Gcc_linemap::get_unknown_location()
+Gcc_linemap::get_unknown_location ()
{
- return Location(UNKNOWN_LOCATION);
+ return Location (UNKNOWN_LOCATION);
}
// Get the predeclared location.
Location
-Gcc_linemap::get_predeclared_location()
+Gcc_linemap::get_predeclared_location ()
{
- return Location(BUILTINS_LOCATION);
+ return Location (BUILTINS_LOCATION);
}
// Return whether a location is the predeclared location.
bool
-Gcc_linemap::is_predeclared(Location loc)
+Gcc_linemap::is_predeclared (Location loc)
{
- return loc.gcc_location() == BUILTINS_LOCATION;
+ return loc.gcc_location () == BUILTINS_LOCATION;
}
// Return whether a location is the unknown location.
bool
-Gcc_linemap::is_unknown(Location loc)
+Gcc_linemap::is_unknown (Location loc)
{
- return loc.gcc_location() == UNKNOWN_LOCATION;
+ return loc.gcc_location () == UNKNOWN_LOCATION;
}
// Return the Linemap to use for the gcc backend.
-Linemap*
-rust_get_linemap()
+Linemap *
+rust_get_linemap ()
{
return new Gcc_linemap;
}
diff --git a/gcc/rust/rust-linemap.h b/gcc/rust/rust-linemap.h
index 03c60f5..73e6a0b 100644
--- a/gcc/rust/rust-linemap.h
+++ b/gcc/rust/rust-linemap.h
@@ -22,147 +22,130 @@
// The Linemap class is a pure abstract interface, plus some static
// convenience functions. The backend must implement the interface.
-/* TODO: probably better to replace linemap implementation as pure abstract interface with some sort of
- * compile-time switch (macros or maybe templates if doable without too much extra annoyance) as to the
- * definition of the methods or whatever. This is to improve performance, as virtual function calls would
+/* TODO: probably better to replace linemap implementation as pure abstract
+ * interface with some sort of compile-time switch (macros or maybe templates if
+ * doable without too much extra annoyance) as to the definition of the methods
+ * or whatever. This is to improve performance, as virtual function calls would
* otherwise have to be made in tight loops like in the lexer. */
class Linemap
{
- public:
- Linemap()
+public:
+ Linemap ()
{
// Only one instance of Linemap is allowed to exist.
- rust_assert(Linemap::instance_ == NULL);
+ rust_assert (Linemap::instance_ == NULL);
Linemap::instance_ = this;
}
- virtual
- ~Linemap() { Linemap::instance_ = NULL; }
+ virtual ~Linemap () { Linemap::instance_ = NULL; }
// Subsequent Location values will come from the file named
// FILE_NAME, starting at LINE_BEGIN. Normally LINE_BEGIN will be
// 0, but it will be non-zero if the Rust source has a //line comment.
- virtual void
- start_file(const char* file_name, unsigned int line_begin) = 0;
+ virtual void start_file (const char *file_name, unsigned int line_begin) = 0;
// Subsequent Location values will come from the line LINE_NUMBER,
// in the current file. LINE_SIZE is the size of the line in bytes.
// This will normally be called for every line in a source file.
- virtual void
- start_line(unsigned int line_number, unsigned int line_size) = 0;
+ virtual void start_line (unsigned int line_number, unsigned int line_size)
+ = 0;
// Get a Location representing column position COLUMN on the current
// line in the current file.
- virtual Location
- get_location(unsigned int column) = 0;
+ virtual Location get_location (unsigned int column) = 0;
// Stop generating Location values. This will be called after all
// input files have been read, in case any cleanup is required.
- virtual void
- stop() = 0;
+ virtual void stop () = 0;
// Produce a human-readable description of a Location, e.g.
// "foo.rust:10". Returns an empty string for predeclared, builtin or
// unknown locations.
- virtual std::string
- to_string(Location) = 0;
+ virtual std::string to_string (Location) = 0;
// Return the file name for a given location.
- virtual std::string
- location_file(Location) = 0;
+ virtual std::string location_file (Location) = 0;
// Return the line number for a given location.
- virtual int
- location_line(Location) = 0;
+ virtual int location_line (Location) = 0;
- protected:
+protected:
// Return a special Location used for predeclared identifiers. This
// Location should be different from that for any actual source
// file. This location will be used for various different types,
// functions, and objects created by the frontend.
- virtual Location
- get_predeclared_location() = 0;
+ virtual Location get_predeclared_location () = 0;
// Return a special Location which indicates that no actual location
// is known. This is used for undefined objects and for errors.
- virtual Location
- get_unknown_location() = 0;
+ virtual Location get_unknown_location () = 0;
// Return whether the argument is the Location returned by
// get_predeclared_location.
- virtual bool
- is_predeclared(Location) = 0;
+ virtual bool is_predeclared (Location) = 0;
// Return whether the argument is the Location returned by
// get_unknown_location.
- virtual bool
- is_unknown(Location) = 0;
+ virtual bool is_unknown (Location) = 0;
// The single existing instance of Linemap.
static Linemap *instance_;
- public:
+public:
// Following are convenience static functions, which allow us to
// access some virtual functions without explicitly passing around
// an instance of Linemap.
// Return the special Location used for predeclared identifiers.
- static Location
- predeclared_location()
+ static Location predeclared_location ()
{
- rust_assert(Linemap::instance_ != NULL);
- return Linemap::instance_->get_predeclared_location();
+ rust_assert (Linemap::instance_ != NULL);
+ return Linemap::instance_->get_predeclared_location ();
}
// Return the special Location used when no location is known.
- static Location
- unknown_location()
+ static Location unknown_location ()
{
- rust_assert(Linemap::instance_ != NULL);
- return Linemap::instance_->get_unknown_location();
+ rust_assert (Linemap::instance_ != NULL);
+ return Linemap::instance_->get_unknown_location ();
}
// Return whether the argument is the special location used for
// predeclared identifiers.
- static bool
- is_predeclared_location(Location loc)
+ static bool is_predeclared_location (Location loc)
{
- rust_assert(Linemap::instance_ != NULL);
- return Linemap::instance_->is_predeclared(loc);
+ rust_assert (Linemap::instance_ != NULL);
+ return Linemap::instance_->is_predeclared (loc);
}
// Return whether the argument is the special location used when no
// location is known.
- static bool
- is_unknown_location(Location loc)
+ static bool is_unknown_location (Location loc)
{
- rust_assert(Linemap::instance_ != NULL);
- return Linemap::instance_->is_unknown(loc);
+ rust_assert (Linemap::instance_ != NULL);
+ return Linemap::instance_->is_unknown (loc);
}
// Produce a human-readable description of a Location.
- static std::string
- location_to_string(Location loc)
+ static std::string location_to_string (Location loc)
{
- rust_assert(Linemap::instance_ != NULL);
- return Linemap::instance_->to_string(loc);
+ rust_assert (Linemap::instance_ != NULL);
+ return Linemap::instance_->to_string (loc);
}
// Return the file name of a location.
- static std::string
- location_to_file(Location loc)
+ static std::string location_to_file (Location loc)
{
- rust_assert(Linemap::instance_ != NULL);
- return Linemap::instance_->location_file(loc);
+ rust_assert (Linemap::instance_ != NULL);
+ return Linemap::instance_->location_file (loc);
}
// Return line number of a location.
- static int
- location_to_line(Location loc)
+ static int location_to_line (Location loc)
{
- rust_assert(Linemap::instance_ != NULL);
- return Linemap::instance_->location_line(loc);
+ rust_assert (Linemap::instance_ != NULL);
+ return Linemap::instance_->location_line (loc);
}
};
diff --git a/gcc/rust/rust-location.h b/gcc/rust/rust-location.h
index 0515f68..575fa83 100644
--- a/gcc/rust/rust-location.h
+++ b/gcc/rust/rust-location.h
@@ -9,63 +9,54 @@
class Location
{
- public:
- Location()
- : gcc_loc_(UNKNOWN_LOCATION)
- { }
+public:
+ Location () : gcc_loc_ (UNKNOWN_LOCATION) {}
- explicit Location(location_t loc)
- : gcc_loc_(loc)
- { }
+ explicit Location (location_t loc) : gcc_loc_ (loc) {}
- location_t
- gcc_location() const
- { return gcc_loc_; }
+ location_t gcc_location () const { return gcc_loc_; }
- Location
- operator+=(location_t rhs) {
+ Location operator+= (location_t rhs)
+ {
gcc_loc_ += rhs;
return *this;
}
- Location
- operator-=(location_t rhs) {
+ Location operator-= (location_t rhs)
+ {
gcc_loc_ -= rhs;
return *this;
}
- bool
- operator==(location_t rhs) {
- return rhs == gcc_loc_;
- }
+ bool operator== (location_t rhs) { return rhs == gcc_loc_; }
- private:
+private:
location_t gcc_loc_;
};
// The Rust frontend requires the ability to compare Locations.
inline bool
-operator<(Location loca, Location locb)
+operator< (Location loca, Location locb)
{
- return loca.gcc_location() < locb.gcc_location();
+ return loca.gcc_location () < locb.gcc_location ();
}
inline bool
-operator==(Location loca, Location locb)
+operator== (Location loca, Location locb)
{
- return loca.gcc_location() == locb.gcc_location();
+ return loca.gcc_location () == locb.gcc_location ();
}
-inline Location
-operator+(Location lhs, location_t rhs)
+inline Location
+operator+ (Location lhs, location_t rhs)
{
lhs += rhs;
return lhs;
}
-inline Location
-operator-(Location lhs, location_t rhs)
+inline Location
+operator- (Location lhs, location_t rhs)
{
lhs -= rhs;
return lhs;
diff --git a/gcc/rust/rust-object-export.c b/gcc/rust/rust-object-export.c
index c985035..e59d3fb 100644
--- a/gcc/rust/rust-object-export.c
+++ b/gcc/rust/rust-object-export.c
@@ -1,21 +1,21 @@
/* rust-backend.c -- Rust frontend interface to gcc backend.
- Copyright (C) 2010-2019 Free Software Foundation, Inc.
+ Copyright (C) 2010-2020 Free Software Foundation, Inc.
-This file is part of GCC.
+ 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 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.
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
// FIXME: doesn't this duplicate lots of code from rust-backend.c? Is one meant to be a replacement?
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "simple-object.h"
#include "stor-layout.h"
#include "intl.h"
-#include "output.h" /* for assemble_string */
+#include "output.h" /* for assemble_string */
#include "common/common-target.h"
// satisfy intellisense
@@ -111,8 +111,8 @@ rust_write_export_data (const char *bytes, unsigned int size)
{
gcc_assert (targetm_common.have_named_sections);
sec = get_section (RUST_EXPORT_SECTION_NAME,
- TARGET_AIX ? SECTION_EXCLUDE : SECTION_DEBUG,
- NULL);
+ TARGET_AIX ? SECTION_EXCLUDE : SECTION_DEBUG,
+ NULL);
}
switch_to_section (sec);
@@ -132,7 +132,7 @@ rust_write_export_data (const char *bytes, unsigned int size)
const char *
rust_read_export_data (int fd, off_t offset, char **pbuf, size_t *plen,
- int *perr)
+ int *perr)
{
simple_object_read *sobj;
const char *errmsg;
@@ -146,20 +146,20 @@ rust_read_export_data (int fd, off_t offset, char **pbuf, size_t *plen,
*plen = 0;
sobj = simple_object_start_read (fd, offset, RUST_EXPORT_SEGMENT_NAME,
- &errmsg, perr);
+ &errmsg, perr);
if (sobj == NULL)
{
/* If we get an error here, just pretend that we didn't find any
- export data. This is the right thing to do if the error is
- that the file was not recognized as an object file. This
- will ignore file I/O errors, but it's not too big a deal
- because we will wind up giving some other error later. */
+ export data. This is the right thing to do if the error is
+ that the file was not recognized as an object file. This
+ will ignore file I/O errors, but it's not too big a deal
+ because we will wind up giving some other error later. */
return NULL;
}
found = simple_object_find_section (sobj, RUST_EXPORT_SECTION_NAME,
- &sec_offset, &sec_length,
- &errmsg, perr);
+ &sec_offset, &sec_length,
+ &errmsg, perr);
simple_object_release_read (sobj);
if (!found)
return errmsg;
diff --git a/gcc/rust/rust-object-export.h b/gcc/rust/rust-object-export.h
index d511078..5ec63e8 100644
--- a/gcc/rust/rust-object-export.h
+++ b/gcc/rust/rust-object-export.h
@@ -9,4 +9,4 @@ rust_read_export_data (int fd, off_t offset, char **pbuf, size_t *plen,
extern void
rust_write_export_data (const char *bytes, unsigned int size);
-#endif // RUST_OBJECT_EXPORT_H \ No newline at end of file
+#endif // RUST_OBJECT_EXPORT_H
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index a52e1a5..2247519 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -13,656 +13,799 @@
#include <algorithm>
-extern Linemap* rust_get_linemap();
+extern Linemap *
+rust_get_linemap ();
namespace Rust {
- // Simple wrapper for FILE* that simplifies destruction.
- struct RAIIFile {
- FILE* file;
-
- RAIIFile(const char* filename) : file(fopen(filename, "r")) {}
-
- ~RAIIFile() {
- fclose(file);
- }
- };
-
- // Implicitly enable a target_feature (and recursively enable dependencies).
- void Session::implicitly_enable_feature(::std::string feature_name) {
- // TODO: is this really required since features added would be complete via target spec?
-
- if (!options.target_data.has_key_value_pair("target_data", feature_name)) {
- // if feature has dependencies, enable them
- if (feature_name == "aes") {
- implicitly_enable_feature("sse2");
- } else if (feature_name == "avx") {
- implicitly_enable_feature("sse4.2");
- } else if (feature_name == "avx2") {
- implicitly_enable_feature("avx");
- } else if (feature_name == "fma") {
- implicitly_enable_feature("avx");
- } else if (feature_name == "pclmulqdq") {
- implicitly_enable_feature("sse2");
- } else if (feature_name == "sha") {
- implicitly_enable_feature("sse2");
- } else if (feature_name == "sse2") {
- implicitly_enable_feature("sse");
- } else if (feature_name == "sse3") {
- implicitly_enable_feature("sse2");
- } else if (feature_name == "sse4.1") {
- implicitly_enable_feature("sse3");
- } else if (feature_name == "sse4.2") {
- implicitly_enable_feature("sse4.1");
- } else if (feature_name == "ssse3") {
- implicitly_enable_feature("sse3");
- }
-
- options.target_data.insert_key_value_pair("target_feature", ::std::move(feature_name));
- }
+// Simple wrapper for FILE* that simplifies destruction.
+struct RAIIFile
+{
+ FILE *file;
+
+ RAIIFile (const char *filename) : file (fopen (filename, "r")) {}
+
+ ~RAIIFile () { fclose (file); }
+};
+
+// Implicitly enable a target_feature (and recursively enable dependencies).
+void
+Session::implicitly_enable_feature (::std::string feature_name)
+{
+ // TODO: is this really required since features added would be complete via
+ // target spec?
+
+ if (!options.target_data.has_key_value_pair ("target_data", feature_name))
+ {
+ // if feature has dependencies, enable them
+ if (feature_name == "aes")
+ {
+ implicitly_enable_feature ("sse2");
+ }
+ else if (feature_name == "avx")
+ {
+ implicitly_enable_feature ("sse4.2");
+ }
+ else if (feature_name == "avx2")
+ {
+ implicitly_enable_feature ("avx");
+ }
+ else if (feature_name == "fma")
+ {
+ implicitly_enable_feature ("avx");
+ }
+ else if (feature_name == "pclmulqdq")
+ {
+ implicitly_enable_feature ("sse2");
+ }
+ else if (feature_name == "sha")
+ {
+ implicitly_enable_feature ("sse2");
+ }
+ else if (feature_name == "sse2")
+ {
+ implicitly_enable_feature ("sse");
+ }
+ else if (feature_name == "sse3")
+ {
+ implicitly_enable_feature ("sse2");
+ }
+ else if (feature_name == "sse4.1")
+ {
+ implicitly_enable_feature ("sse3");
+ }
+ else if (feature_name == "sse4.2")
+ {
+ implicitly_enable_feature ("sse4.1");
+ }
+ else if (feature_name == "ssse3")
+ {
+ implicitly_enable_feature ("sse3");
+ }
+
+ options.target_data.insert_key_value_pair ("target_feature",
+ ::std::move (feature_name));
}
+}
- // Meant to enable all target features. As this will be done by target hook, this method's
- // deprecated.
- void Session::enable_features() {
- bool has_target_crt_static = false;
- const char* target = "PLACEHOLDER";
-
- fprintf(stderr, "ERROR: Somewhere in call chain Session::enable_features is called.\n");
-
- if (has_target_crt_static) {
- // enable "crt-static" attribute
- }
-
- /* TODO: do this via target hook. have one for each target that implicitly enables the
- * features for that platform. Would probably have to make custom target hook. */
-
- /*
- if (target == "x86" || target == "x86_64") {
- if (TARGET_ISA_AES) {
- // enable aes, implicitly enable sse2
- implicitly_enable_feature("aes");
- }
-
- if (TARGET_ISA_AVX) {
- // enable avx, implicitly enable sse4.2
- implicitly_enable_feature("sse4.2");
- }
-
- if (TARGET_ISA_AVX2) {
- // enable avx2, implicitly enable avx
- implicitly_enable_feature("avx");
- }
-
- if (TARGET_ISA_BMI) {
- // enable bmi1
- implicitly_enable_feature("bmi1");
- }
-
- if (TARGET_ISA_BMI2) {
- // enable bmi2
- implicitly_enable_feature("bmi2");
- }
-
- if (TARGET_ISA_FMA) {
- // enable fma, implicitly enable avx
- implicitly_enable_feature("fma");
- }
-
- if (TARGET_ISA_FXSR) {
- // enable fxsr
- implicitly_enable_feature("fxsr");
- }
-
- if (TARGET_ISA_LZCNT) {
- // enable lzcnt
- implicitly_enable_feature("lzcnt");
- }
-
- if (TARGET_ISA_VPCLMULQDQ) {
- // enable pclmulqdq, implicitly enable sse2
- implicitly_enable_feature("pclmulqdq");
- }
-
- if (TARGET_ISA_POPCNT) {
- // enable popcnt
- implicitly_enable_feature("popcnt");
- }
-
- if (TARGET_ISA_RDRND) {
- // enable rdrand
- implicitly_enable_feature("rdrand");
- }
-
- if (TARGET_ISA_RDSEED) {
- // enable rdseed
- implicitly_enable_feature("rdseed");
- }
-
- if (TARGET_ISA_SHA) {
- // enable sha, implicitly enable sse2
- implicitly_enable_feature("sha");
- }
-
- if (TARGET_ISA_SSE) {
- // enable sse
- implicitly_enable_feature("sse");
- }
-
- if (TARGET_ISA_SSE2) {
- // enable sse2, implicitly enable sse
- implicitly_enable_feature("sse2");
- }
-
- if (TARGET_ISA_SSE3) {
- // enable sse3, implicitly enable sse2
- implicitly_enable_feature("sse3");
- }
-
- if (TARGET_ISA_SSE4_1) {
- // enable sse4.1, implicitly enable sse3
- implicitly_enable_feature("sse4.1");
- }
-
- if (TARGET_ISA_SSE4_2) {
- // enable sse4.2, implicitly enable sse4.1
- implicitly_enable_feature("sse4.2");
- }
-
- if (TARGET_ISA_SSSE3) {
- // enable ssse3, implicitly enable sse3
- implicitly_enable_feature("ssse3");
- }
-
- if (TARGET_ISA_XSAVE) {
- // enable xsave
- implicitly_enable_feature("xsave");
- }
-
- if (TARGET_ISA_XSAVEC) {
- // enable xsavec
- implicitly_enable_feature("xsavec");
- }
-
- if (TARGET_ISA_XSAVEOPT) {
- // enable xsaveopt
- implicitly_enable_feature("xsaveopt");
- }
-
- if (TARGET_ISA_XSAVES) {
- // enable xsaves
- implicitly_enable_feature("xsaves");
- }
- }
- options.target_data.features.shrink_to_fit();
- ::std::sort(options.target_data.features.begin(), options.target_data.features.end());*/
+// Meant to enable all target features. As this will be done by target hook,
+// this method's deprecated.
+void
+Session::enable_features ()
+{
+ bool has_target_crt_static = false;
+ const char *target = "PLACEHOLDER";
+
+ fprintf (
+ stderr,
+ "ERROR: Somewhere in call chain Session::enable_features is called.\n");
+
+ if (has_target_crt_static)
+ {
+ // enable "crt-static" attribute
}
- void Session::init() {
-# define builtin_rust_info(KEY, VALUE) rust_add_target_info (KEY, VALUE)
+ /* TODO: do this via target hook. have one for each target that implicitly
+ * enables the
+ * features for that platform. Would probably have to make custom target hook.
+ */
+
+ /*
+ if (target == "x86" || target == "x86_64") {
+ if (TARGET_ISA_AES) {
+ // enable aes, implicitly enable sse2
+ implicitly_enable_feature("aes");
+ }
+
+ if (TARGET_ISA_AVX) {
+ // enable avx, implicitly enable sse4.2
+ implicitly_enable_feature("sse4.2");
+ }
+
+ if (TARGET_ISA_AVX2) {
+ // enable avx2, implicitly enable avx
+ implicitly_enable_feature("avx");
+ }
+
+ if (TARGET_ISA_BMI) {
+ // enable bmi1
+ implicitly_enable_feature("bmi1");
+ }
+
+ if (TARGET_ISA_BMI2) {
+ // enable bmi2
+ implicitly_enable_feature("bmi2");
+ }
+
+ if (TARGET_ISA_FMA) {
+ // enable fma, implicitly enable avx
+ implicitly_enable_feature("fma");
+ }
+
+ if (TARGET_ISA_FXSR) {
+ // enable fxsr
+ implicitly_enable_feature("fxsr");
+ }
+
+ if (TARGET_ISA_LZCNT) {
+ // enable lzcnt
+ implicitly_enable_feature("lzcnt");
+ }
+
+ if (TARGET_ISA_VPCLMULQDQ) {
+ // enable pclmulqdq, implicitly enable sse2
+ implicitly_enable_feature("pclmulqdq");
+ }
+
+ if (TARGET_ISA_POPCNT) {
+ // enable popcnt
+ implicitly_enable_feature("popcnt");
+ }
+
+ if (TARGET_ISA_RDRND) {
+ // enable rdrand
+ implicitly_enable_feature("rdrand");
+ }
+
+ if (TARGET_ISA_RDSEED) {
+ // enable rdseed
+ implicitly_enable_feature("rdseed");
+ }
+
+ if (TARGET_ISA_SHA) {
+ // enable sha, implicitly enable sse2
+ implicitly_enable_feature("sha");
+ }
+
+ if (TARGET_ISA_SSE) {
+ // enable sse
+ implicitly_enable_feature("sse");
+ }
+
+ if (TARGET_ISA_SSE2) {
+ // enable sse2, implicitly enable sse
+ implicitly_enable_feature("sse2");
+ }
+
+ if (TARGET_ISA_SSE3) {
+ // enable sse3, implicitly enable sse2
+ implicitly_enable_feature("sse3");
+ }
+
+ if (TARGET_ISA_SSE4_1) {
+ // enable sse4.1, implicitly enable sse3
+ implicitly_enable_feature("sse4.1");
+ }
+
+ if (TARGET_ISA_SSE4_2) {
+ // enable sse4.2, implicitly enable sse4.1
+ implicitly_enable_feature("sse4.2");
+ }
+
+ if (TARGET_ISA_SSSE3) {
+ // enable ssse3, implicitly enable sse3
+ implicitly_enable_feature("ssse3");
+ }
+
+ if (TARGET_ISA_XSAVE) {
+ // enable xsave
+ implicitly_enable_feature("xsave");
+ }
+
+ if (TARGET_ISA_XSAVEC) {
+ // enable xsavec
+ implicitly_enable_feature("xsavec");
+ }
+
+ if (TARGET_ISA_XSAVEOPT) {
+ // enable xsaveopt
+ implicitly_enable_feature("xsaveopt");
+ }
+
+ if (TARGET_ISA_XSAVES) {
+ // enable xsaves
+ implicitly_enable_feature("xsaves");
+ }
+ }
+ options.target_data.features.shrink_to_fit();
+ ::std::sort(options.target_data.features.begin(),
+ options.target_data.features.end());*/
+}
+
+void
+Session::init ()
+{
+ // nothing yet
+}
+
+// Initialise default options. Actually called before handle_option, unlike init
+// itself.
+void
+Session::init_options ()
+{
+ options.dump_option = CompileOptions::NO_DUMP;
+}
- // initialise target hooks
- targetrustm.rust_cpu_info();
- targetrustm.rust_os_info();
-
-#undef builtin_rust_info
+// Handle option selection.
+bool
+Session::handle_option (
+ enum opt_code code, const char *arg, HOST_WIDE_INT value ATTRIBUTE_UNUSED,
+ int kind ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED,
+ const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
+{
+ // used to store whether results of various stuff are successful
+ bool ret = true;
+
+ // Handles options as listed in lang.opt.
+ switch (code)
+ {
+ case OPT_I:
+ // TODO: add search path
+ break;
+ case OPT_L:
+ // TODO: add library link path or something
+ break;
+ case OPT_frust_dump_:
+ // enable dump and return whether this was successful
+ if (arg != NULL)
+ {
+ ret = enable_dump (::std::string (arg));
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ // no option handling for -o
+ default:
+ // return 1 to indicate option is valid
+ break;
}
- // Initialise default options. Actually called before handle_option, unlike init itself.
- void Session::init_options() {
- options.dump_option = CompileOptions::NO_DUMP;
+ return ret;
+}
+
+/* Enables a certain dump depending on the name passed in. Returns true if name
+ * is valid, false otherwise. */
+bool
+Session::enable_dump (::std::string arg)
+{
+ // FIXME: change dumping algorithm when new non-inhibiting dump system is
+ // created
+ if (arg == "all")
+ {
+ error_at (
+ UNKNOWN_LOCATION,
+ "dumping all is not supported as of now. choose 'lex' or 'parse'");
+ return false;
+ }
+ else if (arg == "lex")
+ {
+ options.dump_option = CompileOptions::LEXER_DUMP;
+ }
+ else if (arg == "parse")
+ {
+ options.dump_option = CompileOptions::PARSER_AST_DUMP;
+ }
+ else if (arg == "register_plugins")
+ {
+ options.dump_option = CompileOptions::REGISTER_PLUGINS_DUMP;
+ }
+ else if (arg == "injection")
+ {
+ options.dump_option = CompileOptions::INJECTION_DUMP;
}
+ else if (arg == "expansion")
+ {
+ options.dump_option = CompileOptions::EXPANSION_DUMP;
+ }
+ else if (arg == "name_resolution")
+ {
+ options.dump_option = CompileOptions::NAME_RESOLUTION_DUMP;
+ }
+ else if (arg == "")
+ {
+ error_at (UNKNOWN_LOCATION,
+ "dump option was not given a name. choose 'lex' or 'parse'");
+ return false;
+ }
+ else
+ {
+ error_at (UNKNOWN_LOCATION,
+ "dump option '%s' was unrecognised. choose 'lex' or 'parse'",
+ arg.c_str ());
+ return false;
+ }
+ return true;
+}
- // Handle option selection.
- bool Session::handle_option(enum opt_code code, const char* arg,
- HOST_WIDE_INT value ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED,
- location_t loc ATTRIBUTE_UNUSED, const struct cl_option_handlers* handlers ATTRIBUTE_UNUSED) {
- // used to store whether results of various stuff are successful
- bool ret = true;
-
- // Handles options as listed in lang.opt.
- switch (code) {
- case OPT_I:
- // TODO: add search path
- break;
- case OPT_L:
- // TODO: add library link path or something
- break;
- case OPT_frust_dump_:
- // enable dump and return whether this was successful
- if (arg != NULL) {
- ret = enable_dump(::std::string(arg));
- } else {
- ret = false;
- }
- break;
- // no option handling for -o
- default:
- // return 1 to indicate option is valid
- break;
- }
-
- return ret;
+/* Actual main entry point for front-end. Called from langhook to parse files.
+ */
+void
+Session::parse_files (int num_files, const char **files)
+{
+ for (int i = 0; i < num_files; i++)
+ {
+ parse_file (files[i]);
}
+ // TODO: should semantic analysis be dealed with here? or per file? for now,
+ // per-file.
+}
- /* Enables a certain dump depending on the name passed in. Returns true if name is valid, false
- * otherwise. */
- bool Session::enable_dump(::std::string arg) {
- // FIXME: change dumping algorithm when new non-inhibiting dump system is created
- if (arg == "all") {
- error_at(
- UNKNOWN_LOCATION, "dumping all is not supported as of now. choose 'lex' or 'parse'");
- return false;
- } else if (arg == "lex") {
- options.dump_option = CompileOptions::LEXER_DUMP;
- } else if (arg == "parse") {
- options.dump_option = CompileOptions::PARSER_AST_DUMP;
- } else if (arg == "register_plugins") {
- options.dump_option = CompileOptions::REGISTER_PLUGINS_DUMP;
- } else if (arg == "injection") {
- options.dump_option = CompileOptions::INJECTION_DUMP;
- } else if (arg == "expansion") {
- options.dump_option = CompileOptions::EXPANSION_DUMP;
- } else if (arg == "name_resolution") {
- options.dump_option = CompileOptions::NAME_RESOLUTION_DUMP;
- } else if (arg == "") {
- error_at(UNKNOWN_LOCATION, "dump option was not given a name. choose 'lex' or 'parse'");
- return false;
- } else {
- error_at(UNKNOWN_LOCATION, "dump option '%s' was unrecognised. choose 'lex' or 'parse'",
- arg.c_str());
- return false;
- }
- return true;
+// Parses a single file with filename filename.
+void
+Session::parse_file (const char *filename)
+{
+ RAIIFile file_wrap (filename);
+
+ if (file_wrap.file == NULL)
+ {
+ fatal_error (UNKNOWN_LOCATION, "cannot open filename %s: %m", filename);
}
- /* Actual main entry point for front-end. Called from langhook to parse files. */
- void Session::parse_files(int num_files, const char** files) {
- for (int i = 0; i < num_files; i++) {
- parse_file(files[i]);
- }
- // TODO: should semantic analysis be dealed with here? or per file? for now, per-file.
+ // parse file here
+ // create lexer and parser - these are file-specific and so aren't instance
+ // variables
+ Rust::Lexer lex (filename, file_wrap.file, rust_get_linemap ());
+ Rust::Parser parser (lex);
+
+ // determine parsing method from options
+ /* FIXME: currently, the dump means that full compilation will not occur as of
+ * present. In future, dumps should not inhibit full compilation. */
+ switch (options.dump_option)
+ {
+ case CompileOptions::NO_DUMP:
+ fatal_error (UNKNOWN_LOCATION,
+ "no-dump parsing has not been enabled yet");
+ return;
+ case CompileOptions::LEXER_DUMP:
+ parser.debug_dump_lex_output ();
+ return;
+ case CompileOptions::PARSER_AST_DUMP:
+ parser.debug_dump_ast_output ();
+ return;
+ case CompileOptions::REGISTER_PLUGINS_DUMP:
+ case CompileOptions::INJECTION_DUMP:
+ case CompileOptions::EXPANSION_DUMP:
+ case CompileOptions::NAME_RESOLUTION_DUMP:
+ // will break later after more stages
+ break;
+ // semantic analysis when completed
+ default:
+ fatal_error (UNKNOWN_LOCATION, "unrecognised dump option: '%u'",
+ options.dump_option);
+ return;
}
- // Parses a single file with filename filename.
- void Session::parse_file(const char* filename) {
- RAIIFile file_wrap(filename);
-
- if (file_wrap.file == NULL) {
- fatal_error(UNKNOWN_LOCATION, "cannot open filename %s: %m", filename);
- }
-
- // parse file here
- // create lexer and parser - these are file-specific and so aren't instance variables
- Rust::Lexer lex(filename, file_wrap.file, rust_get_linemap());
- Rust::Parser parser(lex);
-
- // determine parsing method from options
- /* FIXME: currently, the dump means that full compilation will not occur as of present. In
- * future, dumps should not inhibit full compilation. */
- switch (options.dump_option) {
- case CompileOptions::NO_DUMP:
- fatal_error(UNKNOWN_LOCATION, "no-dump parsing has not been enabled yet");
- return;
- case CompileOptions::LEXER_DUMP:
- parser.debug_dump_lex_output();
- return;
- case CompileOptions::PARSER_AST_DUMP:
- parser.debug_dump_ast_output();
- return;
- case CompileOptions::REGISTER_PLUGINS_DUMP:
- case CompileOptions::INJECTION_DUMP:
- case CompileOptions::EXPANSION_DUMP:
- case CompileOptions::NAME_RESOLUTION_DUMP:
- // will break later after more stages
- break;
- // semantic analysis when completed
- default:
- fatal_error(UNKNOWN_LOCATION, "unrecognised dump option: '%u'", options.dump_option);
- return;
- }
-
- /* basic pipeline:
- * - lex
- * - parse
- * - register plugins (dummy stage for now) - attribute injection? what is this?
- * (attribute injection is injecting attributes specified in command line into crate root)
- * - injection (some lint checks or dummy, register builtin macros, crate injection)
- * - expansion (expands all macros, maybe build test harness, AST validation, maybe macro
- * crate)
- * - name resolution (name resolution, maybe feature checking, maybe buffered lints)
- * TODO not done */
-
- // generate crate from parser
- AST::Crate parsed_crate = parser.parse_crate();
-
- fprintf(stderr, "\033[0;31mSUCCESSFULLY PARSED CRATE \n\033[0m");
-
- // register plugins pipeline stage
- register_plugins(parsed_crate);
- fprintf(stderr, "\033[0;31mSUCCESSFULLY REGISTERED PLUGINS \n\033[0m");
-
- if (options.dump_option == CompileOptions::REGISTER_PLUGINS_DUMP) {
- // TODO: what do I dump here?
- return;
- }
-
- // injection pipeline stage
- injection(parsed_crate);
- fprintf(stderr, "\033[0;31mSUCCESSFULLY FINISHED INJECTION \n\033[0m");
-
- if (options.dump_option == CompileOptions::INJECTION_DUMP) {
- // TODO: what do I dump here? injected crate names?
- return;
- }
-
- // expansion pipeline stage
- expansion(parsed_crate);
- fprintf(stderr, "\033[0;31mSUCCESSFULLY FINISHED EXPANSION \n\033[0m");
-
- if (options.dump_option == CompileOptions::EXPANSION_DUMP) {
- // TODO: what do I dump here? expanded macros? AST with expanded macros?
- return;
- }
-
- // name resolution pipeline stage
- name_resolution(parsed_crate);
- fprintf(stderr, "\033[0;31mSUCCESSFULLY FINISHED NAME RESOLUTION \n\033[0m");
-
- if (options.dump_option == CompileOptions::NAME_RESOLUTION_DUMP) {
- // TODO: what do I dump here? resolved names? AST with resolved names?
- return;
- }
+ /* basic pipeline:
+ * - lex
+ * - parse
+ * - register plugins (dummy stage for now) - attribute injection? what is
+ * this? (attribute injection is injecting attributes specified in command
+ * line into crate root)
+ * - injection (some lint checks or dummy, register builtin macros, crate
+ * injection)
+ * - expansion (expands all macros, maybe build test harness, AST validation,
+ * maybe macro crate)
+ * - name resolution (name resolution, maybe feature checking, maybe buffered
+ * lints)
+ * TODO not done */
+
+ // generate crate from parser
+ AST::Crate parsed_crate = parser.parse_crate ();
+
+ fprintf (stderr, "\033[0;31mSUCCESSFULLY PARSED CRATE \n\033[0m");
+
+ // register plugins pipeline stage
+ register_plugins (parsed_crate);
+ fprintf (stderr, "\033[0;31mSUCCESSFULLY REGISTERED PLUGINS \n\033[0m");
+
+ if (options.dump_option == CompileOptions::REGISTER_PLUGINS_DUMP)
+ {
+ // TODO: what do I dump here?
+ return;
}
- // Checks whether 'cfg' attribute prevents compilation.
- bool check_cfg(const AST::Attribute& attr ATTRIBUTE_UNUSED) {
- // if "has sub items", and if 'cfg' attr, recursively call this on sub items?
+ // injection pipeline stage
+ injection (parsed_crate);
+ fprintf (stderr, "\033[0;31mSUCCESSFULLY FINISHED INJECTION \n\033[0m");
+
+ if (options.dump_option == CompileOptions::INJECTION_DUMP)
+ {
+ // TODO: what do I dump here? injected crate names?
+ return;
+ }
- // TODO: actually implement. assume true for now
+ // expansion pipeline stage
+ expansion (parsed_crate);
+ fprintf (stderr, "\033[0;31mSUCCESSFULLY FINISHED EXPANSION \n\033[0m");
- return true;
+ if (options.dump_option == CompileOptions::EXPANSION_DUMP)
+ {
+ // TODO: what do I dump here? expanded macros? AST with expanded macros?
+ return;
}
- // TODO: deprecated - don't use
- // Checks whether any 'cfg' attribute on the item prevents compilation of that item.
- bool check_item_cfg(::std::vector<AST::Attribute> attrs) {
- for (const auto& attr : attrs) {
- if (attr.get_path() == "cfg" && !check_cfg(attr)) {
- return false;
- }
- }
+ // name resolution pipeline stage
+ name_resolution (parsed_crate);
+ fprintf (stderr, "\033[0;31mSUCCESSFULLY FINISHED NAME RESOLUTION \n\033[0m");
- return true;
+ if (options.dump_option == CompileOptions::NAME_RESOLUTION_DUMP)
+ {
+ // TODO: what do I dump here? resolved names? AST with resolved names?
+ return;
}
- // TODO: deprecated - don't use
-
- // TODO: actually implement method
- void load_extern_crate(::std::string crate_name ATTRIBUTE_UNUSED) {}
- // TODO: deprecated - don't use
-
- // Parses up to the "load (external) crates" part of the frontend.
- // TODO: lots of this code is probably actually useful outside of dumping, so maybe split off
- // function
- void Session::debug_dump_load_crates(Parser& parser) {
- // parse crate as AST
- AST::Crate crate = parser.parse_crate();
-
- /* TODO: search through inner attrs and see whether any of those attr paths contain "no_core",
- * "no_std", "compiler_builtins". If so/not, save certain crate names. In these names, insert
- * items at beginning of crate items. This is crate injection. Also, inject prelude use decl
- * at beginning (first name is assumed to be prelude - prelude is a use decl automatically
- * generated to enable using Option and Copy without qualifying it or importing it via 'use'
- * manually) */
-
- ::std::vector< ::std::string> crate_names;
- for (const auto& item : crate.items) {
- // if item is extern crate, add name? to list of stuff ONLY IF config is checked
- // if item is module, iterate this loop inside it as well (recursive?) ONLY IF config is
- // checked
-
- // TODO: actually do the checks somewhere - probably in the items
-
- item->add_crate_name(crate_names);
- }
-
- /* loop through list of crate names/paths/whatever, attempting to load each one. save loaded
- * crates to a Session variable? Or save to current AST::Crate? */
- for (const auto& name : crate_names) {
- load_extern_crate(name /*, basename = ""?*/);
- }
- // for each loaded crate, load dependencies of it as well
+}
+
+// Checks whether 'cfg' attribute prevents compilation.
+bool
+check_cfg (const AST::Attribute &attr ATTRIBUTE_UNUSED)
+{
+ // if "has sub items", and if 'cfg' attr, recursively call this on sub items?
+
+ // TODO: actually implement. assume true for now
+
+ return true;
+}
+// TODO: deprecated - don't use
+
+// Checks whether any 'cfg' attribute on the item prevents compilation of that
+// item.
+bool
+check_item_cfg (::std::vector<AST::Attribute> attrs)
+{
+ for (const auto &attr : attrs)
+ {
+ if (attr.get_path () == "cfg" && !check_cfg (attr))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+// TODO: deprecated - don't use
+
+// TODO: actually implement method
+void
+load_extern_crate (::std::string crate_name ATTRIBUTE_UNUSED)
+{}
+// TODO: deprecated - don't use
+
+// Parses up to the "load (external) crates" part of the frontend.
+// TODO: lots of this code is probably actually useful outside of dumping, so
+// maybe split off function
+void
+Session::debug_dump_load_crates (Parser &parser)
+{
+ // parse crate as AST
+ AST::Crate crate = parser.parse_crate ();
+
+ /* TODO: search through inner attrs and see whether any of those attr paths
+ * contain "no_core", "no_std", "compiler_builtins". If so/not, save certain
+ * crate names. In these names, insert items at beginning of crate items. This
+ * is crate injection. Also, inject prelude use decl at beginning (first name
+ * is assumed to be prelude - prelude is a use decl automatically generated to
+ * enable using Option and Copy without qualifying it or importing it via
+ * 'use' manually) */
+
+ ::std::vector< ::std::string> crate_names;
+ for (const auto &item : crate.items)
+ {
+ // if item is extern crate, add name? to list of stuff ONLY IF config is
+ // checked if item is module, iterate this loop inside it as well
+ // (recursive?) ONLY IF config is checked
+
+ // TODO: actually do the checks somewhere - probably in the items
+
+ item->add_crate_name (crate_names);
+ }
+
+ /* loop through list of crate names/paths/whatever, attempting to load each
+ * one. save loaded crates to a Session variable? Or save to current
+ * AST::Crate? */
+ for (const auto &name : crate_names)
+ {
+ load_extern_crate (name /*, basename = ""?*/);
+ }
+ // for each loaded crate, load dependencies of it as well
+}
+// TODO: deprecated - don't use
+
+void
+Session::register_plugins (AST::Crate &crate ATTRIBUTE_UNUSED)
+{
+ fprintf (stderr, "ran register_plugins (with no body)\n");
+}
+
+// TODO: move somewhere else
+bool
+contains_name (::std::vector<AST::Attribute> attrs, ::std::string name)
+{
+ for (const auto &attr : attrs)
+ {
+ if (attr.get_path () == name)
+ {
+ return true;
+ }
}
- // TODO: deprecated - don't use
- void Session::register_plugins(AST::Crate& crate ATTRIBUTE_UNUSED) {
- fprintf(stderr, "ran register_plugins (with no body)\n");
+ return false;
+}
+
+void
+Session::injection (AST::Crate &crate)
+{
+ fprintf (stderr, "started injection\n");
+
+ // lint checks in future maybe?
+
+ // register builtin macros
+ /* In rustc, builtin macros are divided into 3 categories depending on use -
+ * "bang" macros, "attr" macros, and "derive" macros. I think the meanings of
+ * these categories should be fairly obvious to anyone who has used rust.
+ * Builtin macro list by category: Bang
+ * - asm
+ * - assert
+ * - cfg
+ * - column
+ * - compile_error
+ * - concat_idents
+ * - concat
+ * - env
+ * - file
+ * - format_args_nl
+ * - format_args
+ * - global_asm
+ * - include_bytes
+ * - include_str
+ * - include
+ * - line
+ * - log_syntax
+ * - module_path
+ * - option_env
+ * - stringify
+ * - trace_macros
+ * Attr
+ * - bench
+ * - global_allocator
+ * - test
+ * - test_case
+ * Derive
+ * - Clone
+ * - Copy
+ * - Debug
+ * - Default
+ * - Eq
+ * - Hash
+ * - Ord
+ * - PartialEq
+ * - PartialOrd
+ * - RustcDecodable
+ * - RustcEncodable
+ * rustc also has a "quote" macro that is defined differently and is
+ * supposedly not stable so eh. */
+ /* TODO: actually implement injection of these macros. In particular, derive
+ * macros, cfg, and
+ * test should be prioritised since they seem to be used the most. */
+
+ // crate injection
+ ::std::vector< ::std::string> names;
+ if (contains_name (crate.inner_attrs, "no_core"))
+ {
+ // no prelude
+ injected_crate_name = "";
}
+ else if (contains_name (crate.inner_attrs, "no_std"))
+ {
+ names.push_back ("core");
- // TODO: move somewhere else
- bool contains_name(const std::vector<AST::Attribute>& attrs, std::string name) {
- for (const auto& attr : attrs) {
- if (attr.get_path() == name) {
- return true;
- }
- }
+ if (!contains_name (crate.inner_attrs, "compiler_builtins"))
+ {
+ names.push_back ("compiler_builtins");
+ }
- return false;
+ injected_crate_name = "core";
}
+ else
+ {
+ names.push_back ("std");
- void Session::injection(AST::Crate& crate) {
- fprintf(stderr, "started injection\n");
-
- // lint checks in future maybe?
-
- // register builtin macros
- /* In rustc, builtin macros are divided into 3 categories depending on use - "bang" macros,
- * "attr" macros, and "derive" macros. I think the meanings of these categories should be
- * fairly obvious to anyone who has used rust. Builtin macro list by category: Bang
- * - asm
- * - assert
- * - cfg
- * - column
- * - compile_error
- * - concat_idents
- * - concat
- * - env
- * - file
- * - format_args_nl
- * - format_args
- * - global_asm
- * - include_bytes
- * - include_str
- * - include
- * - line
- * - log_syntax
- * - module_path
- * - option_env
- * - stringify
- * - trace_macros
- * Attr
- * - bench
- * - global_allocator
- * - test
- * - test_case
- * Derive
- * - Clone
- * - Copy
- * - Debug
- * - Default
- * - Eq
- * - Hash
- * - Ord
- * - PartialEq
- * - PartialOrd
- * - RustcDecodable
- * - RustcEncodable
- * rustc also has a "quote" macro that is defined differently and is supposedly not stable so
- * eh. */
- /* TODO: actually implement injection of these macros. In particular, derive macros, cfg, and
- * test should be prioritised since they seem to be used the most. */
-
- // crate injection
- ::std::vector< ::std::string> names;
- if (contains_name(crate.inner_attrs, "no_core")) {
- // no prelude
- injected_crate_name = "";
- } else if (contains_name(crate.inner_attrs, "no_std")) {
- names.push_back("core");
-
- if (!contains_name(crate.inner_attrs, "compiler_builtins")) {
- names.push_back("compiler_builtins");
- }
-
- injected_crate_name = "core";
- } else {
- names.push_back("std");
-
- injected_crate_name = "std";
- }
-
- // reverse iterate through names to insert crate items in "forward" order at beginning of
- // crate
- for (auto it = names.rbegin(); it != names.rend(); ++it) {
- // create "macro use" attribute for use on extern crate item to enable loading macros from
- // it
- AST::Attribute attr(AST::SimplePath::from_str("macro_use"), NULL);
-
- // create "extern crate" item with the name
- ::std::unique_ptr<AST::ExternCrate> extern_crate(
- new AST::ExternCrate(*it, AST::Visibility::create_error(), { ::std::move(attr) },
- Linemap::unknown_location()));
-
- // insert at beginning
- crate.items.insert(crate.items.begin(), ::std::move(extern_crate));
- }
-
- // create use tree path
- // prelude is injected_crate_name
- ::std::vector<AST::SimplePathSegment> segments
- = { AST::SimplePathSegment(injected_crate_name), AST::SimplePathSegment("prelude"),
- AST::SimplePathSegment("v1") };
- // create use tree and decl
- ::std::unique_ptr<AST::UseTreeGlob> use_tree(new AST::UseTreeGlob(
- AST::UseTreeGlob::PATH_PREFIXED, AST::SimplePath(::std::move(segments)), Location()));
- AST::Attribute prelude_attr(AST::SimplePath::from_str("prelude_import"), NULL);
- ::std::unique_ptr<AST::UseDeclaration> use_decl(new AST::UseDeclaration(::std::move(use_tree),
- AST::Visibility::create_error(), { ::std::move(prelude_attr) }, Location()));
-
- crate.items.insert(crate.items.begin(), ::std::move(use_decl));
-
- /* TODO: potentially add checking attribute crate type? I can't figure out what this does
- * currently comment says "Unconditionally collect crate types from attributes to make them
- * used", which presumably refers to checking the linkage info by "crate_type". It also seems
- * to ensure that an invalid crate type is not specified, so maybe just do that. Valid crate
- * types: bin lib dylib staticlib cdylib rlib proc-macro */
-
- fprintf(stderr, "finished injection\n");
+ injected_crate_name = "std";
}
- void Session::expansion(AST::Crate& crate ATTRIBUTE_UNUSED) {
- fprintf(stderr, "started expansion\n");
+ // reverse iterate through names to insert crate items in "forward" order
+ // at beginning of crate
+ for (auto it = names.rbegin (); it != names.rend (); ++it)
+ {
+ // create "macro use" attribute for use on extern crate item to enable
+ // loading macros from it
+ AST::Attribute attr (AST::SimplePath::from_str ("macro_use"), NULL);
+
+ // create "extern crate" item with the name
+ ::std::unique_ptr<AST::ExternCrate> extern_crate (
+ new AST::ExternCrate (*it, AST::Visibility::create_error (),
+ {::std::move (attr)},
+ Linemap::unknown_location ()));
+
+ // insert at beginning
+ crate.items.insert (crate.items.begin (), ::std::move (extern_crate));
+ }
- // rustc has a modification to windows PATH temporarily here, which may end up being required
+ // create use tree path
+ // prelude is injected_crate_name
+ ::std::vector<AST::SimplePathSegment> segments
+ = {AST::SimplePathSegment (injected_crate_name),
+ AST::SimplePathSegment ("prelude"), AST::SimplePathSegment ("v1")};
+ // create use tree and decl
+ ::std::unique_ptr<AST::UseTreeGlob> use_tree (
+ new AST::UseTreeGlob (AST::UseTreeGlob::PATH_PREFIXED,
+ AST::SimplePath (::std::move (segments)),
+ Location ()));
+ AST::Attribute prelude_attr (AST::SimplePath::from_str ("prelude_import"),
+ NULL);
+ ::std::unique_ptr<AST::UseDeclaration> use_decl (
+ new AST::UseDeclaration (::std::move (use_tree),
+ AST::Visibility::create_error (),
+ {::std::move (prelude_attr)}, Location ()));
+
+ crate.items.insert (crate.items.begin (), ::std::move (use_decl));
+
+ /* TODO: potentially add checking attribute crate type? I can't figure out
+ * what this does currently comment says "Unconditionally collect crate
+ * types from attributes to make them used", which presumably refers to
+ * checking the linkage info by "crate_type". It also seems to ensure that
+ * an invalid crate type is not specified, so maybe just do that. Valid
+ * crate types: bin lib dylib staticlib cdylib rlib proc-macro */
+
+ fprintf (stderr, "finished injection\n");
+}
- // create macro expansion config?
- // if not, would at least have to configure recursion_limit
+void
+Session::expansion (AST::Crate &crate ATTRIBUTE_UNUSED)
+{
+ fprintf (stderr, "started expansion\n");
- // create extctxt? from parse session, cfg, and resolver?
- // expand by calling cxtctxt object's monotonic_expander's expand_crate method.
+ // rustc has a modification to windows PATH temporarily here, which may end
+ // up being required
- // error reporting - check unused macros, get missing fragment specifiers
+ // create macro expansion config?
+ // if not, would at least have to configure recursion_limit
- // build test harness
+ // create extctxt? from parse session, cfg, and resolver?
+ // expand by calling cxtctxt object's monotonic_expander's expand_crate
+ // method.
- // ast validation (also with proc macro decls)
+ // error reporting - check unused macros, get missing fragment specifiers
- // maybe create macro crate if not rustdoc
+ // build test harness
- fprintf(stderr, "finished expansion\n");
- }
+ // ast validation (also with proc macro decls)
- void Session::name_resolution(AST::Crate& crate ATTRIBUTE_UNUSED) {
- fprintf(stderr, "started name resolution\n");
+ // maybe create macro crate if not rustdoc
- fprintf(stderr, "finished name resolution\n");
- }
+ fprintf (stderr, "finished expansion\n");
+}
- // NOTEs:
- /* mrustc compile pipeline:
- * - target load (pass target spec to parser?)
- * - parse (convert source to AST)
- * - load crates (load any explicitly mentioned extern crates [not all of them])
- * - expand (AST transformations from attributes and macros, loads remaining extern crates
- * [std/core and any triggered by macro expansion])
- * - implicit crates (test harness, allocator crate, panic crate)
- * - resolve use (annotate every 'use' item with source [supposedly handles nasty recursion])
- * - resolve index (generate index of visible items for every module [avoids recursion in next
- * pass])
- * - resolve absolute (resolve all paths into either variable names [types/values] or absolute
- * paths)
- * - HIR lower (convert modified AST to simpler HIR [both expressions and module tree])
- * - resolve type aliases (replace any usages of type aliases with actual type [except associated
- * types])
- * - resolve bind (iterate HIR tree and set binding annotations on all concrete types [avoids
- * path lookups later])
- * - resolve HIR markings (generate "markings" [e.g. for Copy/Send/Sync/...] for all types
- * - sort impls (small pass - sort impls into groups)
- * - resolve UFCS outer (determine source trait for all top-level <T>::Type [qualified] paths)
- * - resolve UFCS paths (do the same, but include for exprs this time. also normalises results of
- * previous pass [expanding known associated types])
- * - constant evaluate (evaluate all constants)
- * - typecheck outer (checks impls are sane)
- * - typecheck expressions (resolve and check types for all exprs)
- * - expand HIR annotate (annotate how exprs are used - used for closure extractions and
- * reborrows)
- * - expand HIR closures (extract closures into structs implementing Fn* traits)
- * - expand HIR vtables (generate vtables for types with dyn dispatch)
- * - expand HIR calls (converts method and callable calls into explicit function calls)
- * - expand HIR reborrows (apply reborrow rules [taking '&mut *v' instead of 'v'])
- * - expand HIR erasedtype (replace all erased types 'impl Trait' with the true type)
- * - typecheck expressions (validate - double check that previous passes haven't broke type
- * system rules)
- * - lower MIR (convert HIR exprs into a control-flow graph [MIR])
- * - MIR validate (check that the generated MIR is consistent)
- * - MIR cleanup (perform various transformations on MIR - replace reads of const items with the
- * item itself; convert casts to unsized types into 'MakeDst' operations)
- * - MIR optimise (perform various simple optimisations on the MIR - constant propagation, dead
- * code elimination, borrow elimination, some inlining)
- * - MIR validate PO (re-validate the MIR)
- * - MIR validate full (optionally: perform expensive state-tracking validation on MIR)
- * - trans enumerate (enumerate all items needed for code generation, primarily types used for
- * generics)
- * - trans auto impls (create magic trait impls as enumerated in previous pass)
- * - trans monomorph (generate monomorphised copies of all functions [with generics replaced with
- * real types])
- * - MIR optimise inline (run optimisation again, this time with full type info [primarily for
- * inlining])
- * - HIR serialise (write out HIR dump [module tree and generic/inline MIR])
- * - trans codegen (generate final output file: emit C source file and call C compiler) */
-
- /* rustc compile pipeline (basic, in way less detail):
- * - parse input (parse .rs to AST)
- * - name resolution, macro expansion, and configuration (process AST recursively, resolving
- * paths, expanding macros, processing #[cfg] nodes [i.e. maybe stripping stuff from AST])
- * - lower to HIR
- * - type check and other analyses (e.g. privacy checking)
- * - lower to MIR and post-processing (and do stuff like borrow checking)
- * - translation to LLVM IR and LLVM optimisations (produce the .o files)
- * - linking (link together .o files) */
-
- /* Pierced-together rustc compile pipeline (from source):
- * - parse input (parse file to crate)
- * - register plugins (attributes injection, set various options, register lints, load plugins)
- * - expansion/configure and expand (initial 'cfg' processing, 'loading compiler plugins',
- * syntax expansion, secondary 'cfg' expansion, synthesis of a test harness if required,
- * injection of any std lib dependency and prelude, and name resolution) - actually documented
- * inline
- * - seeming pierced-together order: pre-AST expansion lint checks, registering builtin
- * macros, crate injection, then expand all macros, then maybe build test harness, AST validation,
- * maybe create a macro crate (if not rustdoc), name resolution, complete gated feature
- * checking, add all buffered lints
- * - create global context (lower to HIR)
- * - analysis on global context (HIR optimisations? create MIR?)
- * - code generation
- * - link */
+void
+Session::name_resolution (AST::Crate &crate ATTRIBUTE_UNUSED)
+{
+ fprintf (stderr, "started name resolution\n");
+
+ fprintf (stderr, "finished name resolution\n");
}
+
+// NOTEs:
+/* mrustc compile pipeline:
+ * - target load (pass target spec to parser?)
+ * - parse (convert source to AST)
+ * - load crates (load any explicitly mentioned extern crates [not all of
+ * them])
+ * - expand (AST transformations from attributes and macros, loads remaining
+ * extern crates [std/core and any triggered by macro expansion])
+ * - implicit crates (test harness, allocator crate, panic crate)
+ * - resolve use (annotate every 'use' item with source [supposedly handles
+ * nasty recursion])
+ * - resolve index (generate index of visible items for every module [avoids
+ * recursion in next pass])
+ * - resolve absolute (resolve all paths into either variable names
+ * [types/values] or absolute paths)
+ * - HIR lower (convert modified AST to simpler HIR [both expressions and
+ * module tree])
+ * - resolve type aliases (replace any usages of type aliases with actual
+ * type [except associated types])
+ * - resolve bind (iterate HIR tree and set binding annotations on all
+ * concrete types [avoids path lookups later])
+ * - resolve HIR markings (generate "markings" [e.g. for Copy/Send/Sync/...]
+ * for all types
+ * - sort impls (small pass - sort impls into groups)
+ * - resolve UFCS outer (determine source trait for all top-level <T>::Type
+ * [qualified] paths)
+ * - resolve UFCS paths (do the same, but include for exprs this time. also
+ * normalises results of previous pass [expanding known associated types])
+ * - constant evaluate (evaluate all constants)
+ * - typecheck outer (checks impls are sane)
+ * - typecheck expressions (resolve and check types for all exprs)
+ * - expand HIR annotate (annotate how exprs are used - used for closure
+ * extractions and reborrows)
+ * - expand HIR closures (extract closures into structs implementing Fn*
+ * traits)
+ * - expand HIR vtables (generate vtables for types with dyn dispatch)
+ * - expand HIR calls (converts method and callable calls into explicit
+ * function calls)
+ * - expand HIR reborrows (apply reborrow rules [taking '&mut *v' instead of
+ * 'v'])
+ * - expand HIR erasedtype (replace all erased types 'impl Trait' with the
+ * true type)
+ * - typecheck expressions (validate - double check that previous passes
+ * haven't broke type system rules)
+ * - lower MIR (convert HIR exprs into a control-flow graph [MIR])
+ * - MIR validate (check that the generated MIR is consistent)
+ * - MIR cleanup (perform various transformations on MIR - replace reads of
+ * const items with the item itself; convert casts to unsized types into
+ * 'MakeDst' operations)
+ * - MIR optimise (perform various simple optimisations on the MIR - constant
+ * propagation, dead code elimination, borrow elimination, some inlining)
+ * - MIR validate PO (re-validate the MIR)
+ * - MIR validate full (optionally: perform expensive state-tracking
+ * validation on MIR)
+ * - trans enumerate (enumerate all items needed for code generation,
+ * primarily types used for generics)
+ * - trans auto impls (create magic trait impls as enumerated in previous
+ * pass)
+ * - trans monomorph (generate monomorphised copies of all functions [with
+ * generics replaced with real types])
+ * - MIR optimise inline (run optimisation again, this time with full type
+ * info [primarily for inlining])
+ * - HIR serialise (write out HIR dump [module tree and generic/inline MIR])
+ * - trans codegen (generate final output file: emit C source file and call C
+ * compiler) */
+
+/* rustc compile pipeline (basic, in way less detail):
+ * - parse input (parse .rs to AST)
+ * - name resolution, macro expansion, and configuration (process AST
+ * recursively, resolving paths, expanding macros, processing #[cfg] nodes
+ * [i.e. maybe stripping stuff from AST])
+ * - lower to HIR
+ * - type check and other analyses (e.g. privacy checking)
+ * - lower to MIR and post-processing (and do stuff like borrow checking)
+ * - translation to LLVM IR and LLVM optimisations (produce the .o files)
+ * - linking (link together .o files) */
+
+/* Pierced-together rustc compile pipeline (from source):
+ * - parse input (parse file to crate)
+ * - register plugins (attributes injection, set various options, register
+ * lints, load plugins)
+ * - expansion/configure and expand (initial 'cfg' processing, 'loading
+ * compiler plugins', syntax expansion, secondary 'cfg' expansion, synthesis
+ * of a test harness if required, injection of any std lib dependency and
+ * prelude, and name resolution) - actually documented inline
+ * - seeming pierced-together order: pre-AST expansion lint checks,
+ * registering builtin macros, crate injection, then expand all macros, then
+ * maybe build test harness, AST validation, maybe create a macro crate (if
+ * not rustdoc), name resolution, complete gated feature checking, add all
+ * buffered lints
+ * - create global context (lower to HIR)
+ * - analysis on global context (HIR optimisations? create MIR?)
+ * - code generation
+ * - link */
+} // namespace Rust
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index 84b5546..1ce3a92 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -18,174 +18,206 @@
#include <utility>
namespace Rust {
- // parser forward decl
- class Parser;
- // crate forward decl
- namespace AST {
- struct Crate;
- }
-
- // Data related to target, most useful for conditional compilation and whatever.
- struct TargetOptions {
- // TODO: maybe make private and access through helpers to allow changes to impl
- std::unordered_map<std::string, std::unordered_set<std::string>> features;
-
- public:
- // Returns whether a key is defined in the feature set.
- bool has_key(std::string key) const {
- return features.find(key) != features.end();
- }
-
- // Returns whether a key exists with the given value in the feature set.
- bool has_key_value_pair(std::string key, std::string value) const {
- auto it = features.find(key);
- if (it != features.end()) {
- auto set = it->second;
- auto it2 = set.find(value);
- if (it2 != set.end())
- return true;
- }
- return false;
- }
-
- // Returns the singular value from the key, or if the key has multiple, an empty string.
- std::string get_singular_value(std::string key) const {
- auto it = features.find(key);
- if (it != features.end()) {
- auto set = it->second;
- if (set.size() == 1)
- return *set.begin();
- }
- return "";
- }
-
- // Returns all values associated with a key (including none), or an empty set if no key is found.
- std::unordered_set< ::std::string> get_values_for_key(std::string key) const {
- auto it = features.find(key);
- if (it != features.end()) {
- return it->second;
- }
- return {};
- }
-
- /* Inserts a key (no value) into the feature set. This will do nothing if the key already exists.
- * This returns whether the insertion was successful (i.e. whether key already existed). */
- bool insert_key(std::string key) {
- return features.insert(std::make_pair(key, std::unordered_set<std::string>())).second;
- }
-
- // Inserts a key-value pair into the feature set.
- void insert_key_value_pair(std::string key, std::string value) {
- auto existing_set = get_values_for_key(key);
- existing_set.insert(std::move(value));
- features[std::move(key)] = std::move(existing_set);
- }
-
- /* According to reference, Rust uses either multi-map key-values or just values (although
- * values may be aliases for a key-value value). This seems like overkill. Thus, depending on
- * whether the attributes used in cfg are fixed or not, I think I'll either put each
- * non-multimap "key-value" as a separate field and have the multimap "key-values" in a
- * regular map for that one key, or actually use a multimap.
- *
- * rustc itself uses a set of key-value tuples where the second tuple element is optional.
- * This gets rid of the requirement to make a multi-map, I guess, but seems like it might make
- * search slow (unless all "is defined"-only ones have empty string as second element). */
- /* cfg attributes:
- * - target_arch: single value
- * - target_feature: multiple values possible
- * - target_os: single value
- * - target_family: single value (or no value?)
- * - unix: set when target_family = "unix"
- * - windows: set when target_family = "windows"
- * - if these are just syntactic sugar, then maybe have a separate set or map for this kind
- * of stuff
- * - target_env: set when needed for disambiguation about ABI - usually empty string for GNU,
- * complicated
- * - seems to be a single value (if any)
- * - target_endian: single value; "little" or "big"
- * - target_pointer_width: single value, "32" for 32-bit pointers, etc.
- * - target_vendor, single value
- * - test: set when testing is being done
- * - again, seems similar to a "is defined" rather than "is equal to" like unix
- * - debug_assertions: seems to "is defined"
- * - proc_macro: no idea, bad docs. seems to be boolean, so maybe "is defined" */
- };
-
- // Defines compiler options (e.g. dump, etc.).
- struct CompileOptions {
- // TODO: use bitfield for smaller memory requirements?
-
- // FIXME: this is set up for "instead of" dumping - in future, dumps should not inhibit
- // compilation
- enum DumpOptions {
- NO_DUMP,
- LEXER_DUMP,
- PARSER_AST_DUMP,
- REGISTER_PLUGINS_DUMP,
- INJECTION_DUMP,
- EXPANSION_DUMP,
- NAME_RESOLUTION_DUMP,
- // TODO: add more?
- } dump_option;
-
- // configuration options - actually useful for conditional compilation and whatever
- // data related to target arch, features, os, family, env, endian, pointer width, vendor
- TargetOptions target_data;
- bool enable_test = false;
- bool debug_assertions = false;
- bool proc_macro = false;
- };
-
- /* Defines a compiler session. This is for a single compiler invocation, so potentially includes
- * parsing multiple crates. */
- struct Session {
- CompileOptions options;
- // This should really be in a per-crate storage area but it is wiped with every file so eh.
- ::std::string injected_crate_name;
-
- // backend wrapper to GCC GENERIC
- Backend* backend;
-
- // backend linemap
- Linemap* linemap;
-
- // TODO: replace raw pointers with smart pointers?
-
- public:
- /* Initialise compiler session. Corresponds to langhook grs_langhook_init(). Note that this is
- * called after option handling. */
- void init();
- bool handle_option(enum opt_code code, const char* arg, HOST_WIDE_INT value, int kind,
- location_t loc, const struct cl_option_handlers* handlers);
- void parse_files(int num_files, const char** files);
- void init_options();
-
- private:
- // TODO: should this be private or public?
- void parse_file(const char* filename);
- bool enable_dump(::std::string arg);
-
- void debug_dump_load_crates(Parser& parser);
-
- void implicitly_enable_feature(::std::string feature_name);
- void enable_features();
-
- // pipeline stages - TODO maybe move?
- /* Register plugins pipeline stage. TODO maybe move to another object? Currently dummy stage.
- * In future will handle attribute injection (top-level inner attribute creation from command
- * line arguments), setting options maybe, registering lints maybe, loading plugins maybe. */
- void register_plugins(AST::Crate& crate);
- /* Injection pipeline stage. TODO maybe move to another object? Maybe have some lint checks
- * (in future, obviously), register builtin macros, crate injection. */
- void injection(AST::Crate& crate);
- /* Expansion pipeline stage. TODO maybe move to another object? Expands all macros, maybe
- * build test harness in future, AST validation, maybe create macro crate (if not rustdoc).*/
- void expansion(AST::Crate& crate);
- /* Name resolution pipeline stage. TODO maybe move to another object. Performs name
- * resolution, maybe complete gated feature checking, maybe create buffered lints in future.
- */
- void name_resolution(AST::Crate& crate);
- };
+// parser forward decl
+class Parser;
+// crate forward decl
+namespace AST {
+struct Crate;
}
+// Data related to target, most useful for conditional compilation and whatever.
+struct TargetOptions
+{
+ // TODO: maybe make private and access through helpers to allow changes to
+ // impl
+ std::unordered_map<std::string, std::unordered_set<std::string> > features;
+
+public:
+ // Returns whether a key is defined in the feature set.
+ bool has_key (std::string key) const
+ {
+ return features.find (key) != features.end ();
+ }
+
+ // Returns whether a key exists with the given value in the feature set.
+ bool has_key_value_pair (std::string key, std::string value) const
+ {
+ auto it = features.find (key);
+ if (it != features.end ())
+ {
+ auto set = it->second;
+ auto it2 = set.find (value);
+ if (it2 != set.end ())
+ return true;
+ }
+ return false;
+ }
+
+ // Returns the singular value from the key, or if the key has multiple, an
+ // empty string.
+ std::string get_singular_value (std::string key) const
+ {
+ auto it = features.find (key);
+ if (it != features.end ())
+ {
+ auto set = it->second;
+ if (set.size () == 1)
+ return *set.begin ();
+ }
+ return "";
+ }
+
+ // Returns all values associated with a key (including none), or an empty set
+ // if no key is found.
+ std::unordered_set< ::std::string> get_values_for_key (std::string key) const
+ {
+ auto it = features.find (key);
+ if (it != features.end ())
+ {
+ return it->second;
+ }
+ return {};
+ }
+
+ /* Inserts a key (no value) into the feature set. This will do nothing if the
+ * key already exists.
+ * This returns whether the insertion was successful (i.e. whether key already
+ * existed). */
+ bool insert_key (std::string key)
+ {
+ return features
+ .insert (std::make_pair (key, std::unordered_set<std::string> ()))
+ .second;
+ }
+
+ // Inserts a key-value pair into the feature set.
+ void insert_key_value_pair (std::string key, std::string value)
+ {
+ auto existing_set = get_values_for_key (key);
+ existing_set.insert (std::move (value));
+ features[std::move (key)] = std::move (existing_set);
+ }
+
+ /* According to reference, Rust uses either multi-map key-values or just
+ * values (although values may be aliases for a key-value value). This seems
+ * like overkill. Thus, depending on whether the attributes used in cfg are
+ * fixed or not, I think I'll either put each non-multimap "key-value" as a
+ * separate field and have the multimap "key-values" in a regular map for that
+ * one key, or actually use a multimap.
+ *
+ * rustc itself uses a set of key-value tuples where the second tuple element
+ * is optional. This gets rid of the requirement to make a multi-map, I guess,
+ * but seems like it might make
+ * search slow (unless all "is defined"-only ones have empty string as second
+ * element). */
+ /* cfg attributes:
+ * - target_arch: single value
+ * - target_feature: multiple values possible
+ * - target_os: single value
+ * - target_family: single value (or no value?)
+ * - unix: set when target_family = "unix"
+ * - windows: set when target_family = "windows"
+ * - if these are just syntactic sugar, then maybe have a separate set or map
+ * for this kind of stuff
+ * - target_env: set when needed for disambiguation about ABI - usually empty
+ * string for GNU, complicated
+ * - seems to be a single value (if any)
+ * - target_endian: single value; "little" or "big"
+ * - target_pointer_width: single value, "32" for 32-bit pointers, etc.
+ * - target_vendor, single value
+ * - test: set when testing is being done
+ * - again, seems similar to a "is defined" rather than "is equal to" like
+ * unix
+ * - debug_assertions: seems to "is defined"
+ * - proc_macro: no idea, bad docs. seems to be boolean, so maybe "is defined"
+ */
+};
+
+// Defines compiler options (e.g. dump, etc.).
+struct CompileOptions
+{
+ // TODO: use bitfield for smaller memory requirements?
+
+ // FIXME: this is set up for "instead of" dumping - in future, dumps should
+ // not inhibit compilation
+ enum DumpOptions
+ {
+ NO_DUMP,
+ LEXER_DUMP,
+ PARSER_AST_DUMP,
+ REGISTER_PLUGINS_DUMP,
+ INJECTION_DUMP,
+ EXPANSION_DUMP,
+ NAME_RESOLUTION_DUMP,
+ // TODO: add more?
+ } dump_option;
+
+ // configuration options - actually useful for conditional compilation and
+ // whatever data related to target arch, features, os, family, env, endian,
+ // pointer width, vendor
+ TargetOptions target_data;
+ bool enable_test = false;
+ bool debug_assertions = false;
+ bool proc_macro = false;
+};
+
+/* Defines a compiler session. This is for a single compiler invocation, so
+ * potentially includes parsing multiple crates. */
+struct Session
+{
+ CompileOptions options;
+ // This should really be in a per-crate storage area but it is wiped with
+ // every file so eh.
+ ::std::string injected_crate_name;
+
+ // backend wrapper to GCC GENERIC
+ Backend *backend;
+
+ // backend linemap
+ Linemap *linemap;
+
+ // TODO: replace raw pointers with smart pointers?
+
+public:
+ /* Initialise compiler session. Corresponds to langhook grs_langhook_init().
+ * Note that this is called after option handling. */
+ void init ();
+ bool handle_option (enum opt_code code, const char *arg, HOST_WIDE_INT value,
+ int kind, location_t loc,
+ const struct cl_option_handlers *handlers);
+ void parse_files (int num_files, const char **files);
+ void init_options ();
+
+private:
+ // TODO: should this be private or public?
+ void parse_file (const char *filename);
+ bool enable_dump (::std::string arg);
+
+ void debug_dump_load_crates (Parser &parser);
+
+ void implicitly_enable_feature (::std::string feature_name);
+ void enable_features ();
+
+ // pipeline stages - TODO maybe move?
+ /* Register plugins pipeline stage. TODO maybe move to another object?
+ * Currently dummy stage. In future will handle attribute injection (top-level
+ * inner attribute creation from command line arguments), setting options
+ * maybe, registering lints maybe, loading plugins maybe. */
+ void register_plugins (AST::Crate &crate);
+ /* Injection pipeline stage. TODO maybe move to another object? Maybe have
+ * some lint checks (in future, obviously), register builtin macros, crate
+ * injection. */
+ void injection (AST::Crate &crate);
+ /* Expansion pipeline stage. TODO maybe move to another object? Expands all
+ * macros, maybe build test harness in future, AST validation, maybe create
+ * macro crate (if not rustdoc).*/
+ void expansion (AST::Crate &crate);
+ /* Name resolution pipeline stage. TODO maybe move to another object. Performs
+ * name resolution, maybe complete gated feature checking, maybe create
+ * buffered lints in future.
+ */
+ void name_resolution (AST::Crate &crate);
+};
+} // namespace Rust
+
#endif
diff --git a/gcc/rust/rust-system.h b/gcc/rust/rust-system.h
index 84e66aa..da2454a 100644
--- a/gcc/rust/rust-system.h
+++ b/gcc/rust/rust-system.h
@@ -1,5 +1,5 @@
// rust-system.h -- Rust frontend inclusion of gcc header files -*- C++ -*-
-// Copyright (C) 2009-2019 Free Software Foundation, Inc.
+// Copyright (C) 2009-2020 Free Software Foundation, Inc.
// This file is part of GCC.
@@ -41,94 +41,84 @@
#include <deque>
#include <functional>
-/* TODO: strictly speaking, as AST move semantics make frontend C++11-and-up only, unordered map should
- * always be definable (i.e. don't have to resort to tr1 like in C++03), so don't need to have this
- * macro switch - just include <unordered_map> and <unordered_set>. */
+/* TODO: strictly speaking, as AST move semantics make frontend C++11-and-up
+ * only, unordered map should always be definable (i.e. don't have to resort to
+ * tr1 like in C++03), so don't need to have this macro switch - just include
+ * <unordered_map> and <unordered_set>. */
#if defined(HAVE_UNORDERED_MAP)
-# include <unordered_map>
-# include <unordered_set>
+#include <unordered_map>
+#include <unordered_set>
-# define Unordered_map(KEYTYPE, VALTYPE) \
- std::unordered_map<KEYTYPE, VALTYPE>
+#define Unordered_map(KEYTYPE, VALTYPE) std::unordered_map<KEYTYPE, VALTYPE>
-# define Unordered_map_hash(KEYTYPE, VALTYPE, HASHFN, EQFN) \
- std::unordered_map<KEYTYPE, VALTYPE, HASHFN, EQFN>
+#define Unordered_map_hash(KEYTYPE, VALTYPE, HASHFN, EQFN) \
+ std::unordered_map<KEYTYPE, VALTYPE, HASHFN, EQFN>
-# define Unordered_set(KEYTYPE) \
- std::unordered_set<KEYTYPE>
+#define Unordered_set(KEYTYPE) std::unordered_set<KEYTYPE>
-# define Unordered_set_hash(KEYTYPE, HASHFN, EQFN) \
- std::unordered_set<KEYTYPE, HASHFN, EQFN>
+#define Unordered_set_hash(KEYTYPE, HASHFN, EQFN) \
+ std::unordered_set<KEYTYPE, HASHFN, EQFN>
#elif defined(HAVE_TR1_UNORDERED_MAP)
-# include <tr1/unordered_map>
-# include <tr1/unordered_set>
+#include <tr1/unordered_map>
+#include <tr1/unordered_set>
-# define Unordered_map(KEYTYPE, VALTYPE) \
- std::tr1::unordered_map<KEYTYPE, VALTYPE>
+#define Unordered_map(KEYTYPE, VALTYPE) \
+ std::tr1::unordered_map<KEYTYPE, VALTYPE>
-# define Unordered_map_hash(KEYTYPE, VALTYPE, HASHFN, EQFN) \
- std::tr1::unordered_map<KEYTYPE, VALTYPE, HASHFN, EQFN>
+#define Unordered_map_hash(KEYTYPE, VALTYPE, HASHFN, EQFN) \
+ std::tr1::unordered_map<KEYTYPE, VALTYPE, HASHFN, EQFN>
-# define Unordered_set(KEYTYPE) \
- std::tr1::unordered_set<KEYTYPE>
+#define Unordered_set(KEYTYPE) std::tr1::unordered_set<KEYTYPE>
-# define Unordered_set_hash(KEYTYPE, HASHFN, EQFN) \
- std::tr1::unordered_set<KEYTYPE, HASHFN, EQFN>
+#define Unordered_set_hash(KEYTYPE, HASHFN, EQFN) \
+ std::tr1::unordered_set<KEYTYPE, HASHFN, EQFN>
#elif defined(HAVE_EXT_HASH_MAP)
-# include <ext/hash_map>
-# include <ext/hash_set>
+#include <ext/hash_map>
+#include <ext/hash_set>
-# define Unordered_map(KEYTYPE, VALTYPE) \
- __gnu_cxx::hash_map<KEYTYPE, VALTYPE>
+#define Unordered_map(KEYTYPE, VALTYPE) __gnu_cxx::hash_map<KEYTYPE, VALTYPE>
-# define Unordered_map_hash(KEYTYPE, VALTYPE, HASHFN, EQFN) \
- __gnu_cxx::hash_map<KEYTYPE, VALTYPE, HASHFN, EQFN>
+#define Unordered_map_hash(KEYTYPE, VALTYPE, HASHFN, EQFN) \
+ __gnu_cxx::hash_map<KEYTYPE, VALTYPE, HASHFN, EQFN>
-# define Unordered_set(KEYTYPE) \
- __gnu_cxx::hash_set<KEYTYPE>
+#define Unordered_set(KEYTYPE) __gnu_cxx::hash_set<KEYTYPE>
-# define Unordered_set_hash(KEYTYPE, HASHFN, EQFN) \
- __gnu_cxx::hash_set<KEYTYPE, HASHFN, EQFN>
+#define Unordered_set_hash(KEYTYPE, HASHFN, EQFN) \
+ __gnu_cxx::hash_set<KEYTYPE, HASHFN, EQFN>
// Provide hash functions for strings and pointers.
-namespace __gnu_cxx
-{
+namespace __gnu_cxx {
-template<>
-struct hash<std::string>
+template <> struct hash<std::string>
{
- size_t
- operator()(std::string s) const
- { return __stl_hash_string(s.c_str()); }
+ size_t operator() (std::string s) const
+ {
+ return __stl_hash_string (s.c_str ());
+ }
};
-template<typename T>
-struct hash<T*>
+template <typename T> struct hash<T *>
{
- size_t
- operator()(T* p) const
- { return reinterpret_cast<size_t>(p); }
+ size_t operator() (T *p) const { return reinterpret_cast<size_t> (p); }
};
-}
+} // namespace __gnu_cxx
#else
-# define Unordered_map(KEYTYPE, VALTYPE) \
- std::map<KEYTYPE, VALTYPE>
+#define Unordered_map(KEYTYPE, VALTYPE) std::map<KEYTYPE, VALTYPE>
-# define Unordered_set(KEYTYPE) \
- std::set<KEYTYPE>
+#define Unordered_set(KEYTYPE) std::set<KEYTYPE>
// We could make this work by writing an adapter class which
// implemented operator< in terms of the hash function.
-# error "requires hash table type"
+#error "requires hash table type"
#endif
@@ -142,17 +132,19 @@ struct hash<T*>
#include "ansidecl.h"
#include "coretypes.h"
-#include "diagnostic-core.h" /* For error_at and friends. */
-#include "intl.h" /* For _(). */
+#include "diagnostic-core.h" /* For error_at and friends. */
+#include "intl.h" /* For _(). */
// When using gcc, rust_assert is just gcc_assert.
-#define rust_assert(EXPR) gcc_assert(EXPR)
+#define rust_assert(EXPR) gcc_assert (EXPR)
// When using gcc, rust_unreachable is just gcc_unreachable.
-#define rust_unreachable() gcc_unreachable()
+#define rust_unreachable() gcc_unreachable ()
-extern void rust_preserve_from_gc (tree t);
+extern void
+rust_preserve_from_gc (tree t);
-extern const char* rust_localize_identifier (const char *ident);
+extern const char *
+rust_localize_identifier (const char *ident);
#endif // !defined(RUST_SYSTEM_H)
diff --git a/gcc/rust/rustspec.cc b/gcc/rust/rustspec.cc
index b61114f..28c2d9a 100644
--- a/gcc/rust/rustspec.cc
+++ b/gcc/rust/rustspec.cc
@@ -1,5 +1,5 @@
/* rustspec.c -- Specific flags and argument handling of the gcc Go front end.
- Copyright (C) 2009-2019 Free Software Foundation, Inc.
+ Copyright (C) 2009-2020 Free Software Foundation, Inc.
This file is part of GCC.
@@ -340,7 +340,7 @@ lang_specific_driver (struct cl_decoded_option **in_decoded_options,
if (library > 0)
{
// generate_option (OPT_l, LIBGOBEGIN, 1, CL_DRIVER,
- // &new_decoded_options[j]);
+ // &new_decoded_options[j]);
// added_libraries++;
// j++;