diff options
author | SimplyTheOther <simplytheother@gmail.com> | 2020-04-17 14:50:21 +0800 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2020-11-27 17:04:31 +0000 |
commit | 5a2eebc2920ed96e509559e92e74a4af78d95eb6 (patch) | |
tree | f6b47c46ed28b73ccf44f9150868feb6ca17f18b | |
parent | 1ff5f98ee698fc4443c33254bc79fc3baab0d3cf (diff) | |
download | gcc-5a2eebc2920ed96e509559e92e74a4af78d95eb6.zip gcc-5a2eebc2920ed96e509559e92e74a4af78d95eb6.tar.gz gcc-5a2eebc2920ed96e509559e92e74a4af78d95eb6.tar.bz2 |
Cleanup and fixes to retain desired behaviour
-rw-r--r-- | gcc/rust/ast/rust-ast-full-test.cc | 26 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 37 | ||||
-rw-r--r-- | gcc/rust/ast/rust-cond-compilation.h | 15 | ||||
-rw-r--r-- | gcc/rust/ast/rust-expr.h | 21 | ||||
-rw-r--r-- | gcc/rust/ast/rust-item.h | 7 | ||||
-rw-r--r-- | gcc/rust/ast/rust-macro.h | 9 | ||||
-rw-r--r-- | gcc/rust/ast/rust-path.h | 28 | ||||
-rw-r--r-- | gcc/rust/ast/rust-type.h | 8 | ||||
-rw-r--r-- | gcc/rust/backend.h | 36 | ||||
-rw-r--r-- | gcc/rust/lex/rust-lex.cc | 18 | ||||
-rw-r--r-- | gcc/rust/lex/rust-lex.h | 22 | ||||
-rw-r--r-- | gcc/rust/operator.h | 2 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse.cc | 236 | ||||
-rw-r--r-- | gcc/rust/rust-backend.c | 7 | ||||
-rw-r--r-- | gcc/rust/rust-gcc.cc | 2 | ||||
-rw-r--r-- | gcc/rust/rust-lang.cc | 4 | ||||
-rw-r--r-- | gcc/rust/rust-linemap.h | 5 | ||||
-rw-r--r-- | gcc/rust/rust-location.h | 33 | ||||
-rw-r--r-- | gcc/rust/rust-object-export.c | 7 | ||||
-rw-r--r-- | gcc/rust/rust-object-export.h | 5 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.cc | 12 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.h | 6 | ||||
-rw-r--r-- | gcc/rust/rust-system.h | 3 | ||||
-rw-r--r-- | gcc/rust/rustspec.cc | 3 |
24 files changed, 321 insertions, 231 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc index b68b770..77f1153 100644 --- a/gcc/rust/ast/rust-ast-full-test.cc +++ b/gcc/rust/ast/rust-ast-full-test.cc @@ -2128,7 +2128,7 @@ namespace Rust { // kind of a HACK to get locus depending on opening scope resolution Location locus = Linemap::unknown_location(); if (with_opening_scope_resolution) { - locus = simple_segments[0].get_locus()/* - 2*/; // minus 2 chars for :: + locus = simple_segments[0].get_locus() - 2; // minus 2 chars for :: } else { locus = simple_segments[0].get_locus(); } @@ -3455,7 +3455,8 @@ namespace Rust { return parse_path_meta_item(); } default: - rust_error_at(peek_token()->get_locus(), "unrecognised token '%s' in meta item", + rust_error_at(peek_token()->get_locus(), + "unrecognised token '%s' in meta item", get_token_description(peek_token()->get_id())); return NULL; } @@ -3578,7 +3579,8 @@ namespace Rust { Location locus = peek_token()->get_locus(); Literal lit = parse_literal(); if (lit.is_error()) { - rust_error_at(peek_token()->get_locus(), "failed to parse literal in attribute"); + rust_error_at( + peek_token()->get_locus(), "failed to parse literal in attribute"); return NULL; } LiteralExpr expr(::std::move(lit), locus); @@ -3916,25 +3918,11 @@ namespace Rust { } bool MetaNameValueStr::check_cfg_predicate(const Session& session) const { - auto it = session.options.target_data.features.find(ident); - if (it != session.options.target_data.features.end()) { - // value must also be the same, not just the name existing - if (it->second.find(str) != it->second.end()) { - return true; - } - } - return false; + return session.options.target_data.has_key_value_pair(ident, str); } bool MetaItemPathLit::check_cfg_predicate(const Session& session) const { - auto it = session.options.target_data.features.find(path.as_string()); - if (it != session.options.target_data.features.end()) { - // value must also be the same, not just the name existing - if (it->second.find(lit.as_string()) != it->second.end()) { - return true; - } - } - return false; + return session.options.target_data.has_key_value_pair(path.as_string(), lit.as_string()); } ::std::vector< ::std::unique_ptr<Token> > Token::to_token_stream() const { diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 0d50f59..54634ef 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -9,10 +9,13 @@ #include "system.h" #include "coretypes.h" // order: config, INCLUDE, system, coretypes -// STL imports #include "rust-system.h" + +// STL imports // with C++11, now can use actual std::unique_ptr #include <memory> +#include <string> +#include <vector> // gccrs imports // required for AST::Token @@ -156,10 +159,8 @@ namespace Rust { } // 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) {} + 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 @@ -276,11 +277,11 @@ namespace Rust { // 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< + // 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; + // 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; @@ -301,12 +302,12 @@ namespace Rust { 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) {} - + ::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) { @@ -468,8 +469,8 @@ namespace Rust { } // Constructor has pointer AttrInput for polymorphism reasons - Attribute(SimplePath path, ::std::unique_ptr<AttrInput> input, - Location locus = Location()) : + Attribute( + SimplePath path, ::std::unique_ptr<AttrInput> input, Location locus = Location()) : path(::std::move(path)), attr_input(::std::move(input)), locus(locus) {} @@ -1000,8 +1001,8 @@ namespace Rust { public: // Constructor - Lifetime(LifetimeType type, ::std::string name = ::std::string(), - Location locus = Location()) : + Lifetime( + LifetimeType type, ::std::string name = ::std::string(), Location locus = Location()) : lifetime_type(type), lifetime_name(::std::move(name)), locus(locus) {} diff --git a/gcc/rust/ast/rust-cond-compilation.h b/gcc/rust/ast/rust-cond-compilation.h index 4fa6a0b..02353d3 100644 --- a/gcc/rust/ast/rust-cond-compilation.h +++ b/gcc/rust/ast/rust-cond-compilation.h @@ -116,11 +116,11 @@ namespace Rust { return *this; } - // move constructors + // move constructors ConfigurationNot(ConfigurationNot&& other) = default; ConfigurationNot& operator=(ConfigurationNot&& other) = default; - virtual void accept_vis(ASTVisitor& vis) OVERRIDE; + virtual void accept_vis(ASTVisitor& vis) OVERRIDE; protected: // Use covariance to implement clone function as returning this object rather than base @@ -150,13 +150,14 @@ namespace Rust { return *this; } - // move constructors + // 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: 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 { @@ -189,7 +190,7 @@ namespace Rust { return *this; } - // move constructors + // move constructors CfgAttrAttribute(CfgAttrAttribute&& other) = default; CfgAttrAttribute& operator=(CfgAttrAttribute&& other) = default; }; diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index ea0ac20..992801f 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -198,7 +198,8 @@ namespace Rust { 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 + // 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 @@ -1865,8 +1866,8 @@ namespace Rust { // return struct_name.as_string(); } - StructExprUnit(PathInExpression struct_path, ::std::vector<Attribute> outer_attribs, - Location locus) : + StructExprUnit( + PathInExpression struct_path, ::std::vector<Attribute> outer_attribs, Location locus) : StructExpr(::std::move(struct_path), ::std::move(outer_attribs)), locus(locus) {} @@ -2893,8 +2894,7 @@ namespace Rust { protected: // outer attributes not allowed before range expressions - RangeExpr(Location locus) : - ExprWithoutBlock(::std::vector<Attribute>()), locus(locus) {} + RangeExpr(Location locus) : ExprWithoutBlock(::std::vector<Attribute>()), locus(locus) {} public: Location get_locus() const { @@ -2922,8 +2922,8 @@ namespace Rust { ::std::string as_string() const; - RangeFromToExpr(::std::unique_ptr<Expr> range_from, ::std::unique_ptr<Expr> range_to, - Location locus) : + 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)) {} @@ -3095,8 +3095,8 @@ namespace Rust { ::std::string as_string() const; - RangeFromToInclExpr(::std::unique_ptr<Expr> range_from, ::std::unique_ptr<Expr> range_to, - Location locus) : + 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 @@ -3860,8 +3860,7 @@ namespace Rust { ::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) : + ::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) {} diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index 7c69978..8d732a7 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -1697,10 +1697,9 @@ namespace Rust { return !outer_attrs.empty(); } - EnumItem( - Identifier variant_name, ::std::vector<Attribute> outer_attrs, Location locus) : - outer_attrs(::std::move(outer_attrs)), - variant_name(::std::move(variant_name)), locus(locus) {} + EnumItem(Identifier variant_name, ::std::vector<Attribute> outer_attrs, Location locus) : + outer_attrs(::std::move(outer_attrs)), variant_name(::std::move(variant_name)), + locus(locus) {} // Unique pointer custom clone function ::std::unique_ptr<EnumItem> clone_enum_item() const { diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h index 4b8e4d6..727b195 100644 --- a/gcc/rust/ast/rust-macro.h +++ b/gcc/rust/ast/rust-macro.h @@ -288,8 +288,7 @@ namespace Rust { ::std::string as_string() const; MacroRulesDefinition(Identifier rule_name, DelimType delim_type, - ::std::vector<MacroRule> rules, ::std::vector<Attribute> outer_attrs, - Location locus) : + ::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) {} @@ -377,7 +376,7 @@ namespace Rust { return path; } - virtual bool check_cfg_predicate(const Session& session) const OVERRIDE; + virtual bool check_cfg_predicate(const Session& session) const OVERRIDE; protected: // Use covariance to implement clone function as returning this type @@ -451,7 +450,7 @@ namespace Rust { virtual void accept_vis(ASTVisitor& vis) OVERRIDE; - virtual bool check_cfg_predicate(const Session& session) const OVERRIDE; + virtual bool check_cfg_predicate(const Session& session) const OVERRIDE; protected: // Use covariance to implement clone function as returning this type @@ -480,7 +479,7 @@ namespace Rust { return clone_meta_item_inner_impl(); } - virtual bool check_cfg_predicate(const Session& session) const OVERRIDE; + virtual bool check_cfg_predicate(const Session& session) const OVERRIDE; protected: // Use covariance to implement clone function as returning this type diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index 5fe7fd0..6845603f 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -29,7 +29,8 @@ namespace Rust { /* 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 + // TODO: does this require visitor. pretty sure this isn't polymorphic, but not entirely + // sure // Creates an error PathIdentSegment. static PathIdentSegment create_error() { @@ -67,8 +68,8 @@ namespace Rust { } // Pointer type for type in constructor to enable polymorphism - GenericArgsBinding(Identifier ident, ::std::unique_ptr<Type> type_ptr, - Location locus = Location()) : + GenericArgsBinding( + Identifier ident, ::std::unique_ptr<Type> type_ptr, Location locus = Location()) : identifier(::std::move(ident)), type(::std::move(type_ptr)), locus(locus) {} @@ -326,8 +327,8 @@ namespace Rust { return ::std::unique_ptr<TypePathSegment>(clone_type_path_segment_impl()); } - TypePathSegment(PathIdentSegment ident_segment, bool has_separating_scope_resolution, - Location locus) : + 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) {} @@ -496,8 +497,7 @@ namespace Rust { public: // Constructor with PathIdentSegment and TypePathFn TypePathSegmentFunction(PathIdentSegment ident_segment, - bool has_separating_scope_resolution, TypePathFunction function_path, - Location locus) : + 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)) {} @@ -554,16 +554,12 @@ namespace Rust { // Creates an error state TypePath. static TypePath create_error() { - return TypePath( - ::std::vector< ::std::unique_ptr<TypePathSegment> >(), - Linemap::unknown_location(), - false); + 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) : + 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) {} @@ -625,8 +621,8 @@ namespace Rust { public: // Constructor - QualifiedPathType(::std::unique_ptr<Type> invoke_on_type, - Location locus = Location(), TypePath trait_path = TypePath::create_error()) : + 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) {} diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h index d6bd2f4..2ca973a 100644 --- a/gcc/rust/ast/rust-type.h +++ b/gcc/rust/ast/rust-type.h @@ -68,8 +68,8 @@ namespace Rust { } public: - ImplTraitType(::std::vector< ::std::unique_ptr<TypeParamBound> > type_param_bounds, - Location locus) : + ImplTraitType( + ::std::vector< ::std::unique_ptr<TypeParamBound> > type_param_bounds, Location locus) : type_param_bounds(::std::move(type_param_bounds)), locus(locus) {} @@ -480,8 +480,8 @@ namespace Rust { } // Constructor - ReferenceType(bool is_mut, ::std::unique_ptr<TypeNoBounds> type_no_bounds, - Location locus, Lifetime lifetime = Lifetime::error()) : + 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) {} diff --git a/gcc/rust/backend.h b/gcc/rust/backend.h index e7c360f..8454847 100644 --- a/gcc/rust/backend.h +++ b/gcc/rust/backend.h @@ -1,11 +1,4 @@ -// backend.h -- Rust frontend interface to backend -*- C++ -*- - -// Copyright 2011 The Rust Authors. All rights reserved. -// Use of this source code is rustverned by a BSD-style -// license that can be found in the LICENSE file. - -#ifndef RUST_BACKEND_H -#define RUST_BACKEND_H +#pragma once #include <gmp.h> #include <mpfr.h> @@ -13,6 +6,9 @@ #include "operator.h" +// TODO: Will have to be significantly modified to work with Rust and current +// setup of gccrs + // Pointers to these types are created by the backend, passed to the // frontend, and passed back to the backend. The types must be // defined by the backend using these names. @@ -95,7 +91,7 @@ public: // Get a function type. The receiver, parameter, and results are // generated from the types in the Function_type. The Function_type // is provided so that the names are available. This should return - // not the type of a Rust function (which is a pointer to a struct) + // not the type of a Go function (which is a pointer to a struct) // but the type of a C function pointer (which will be used as the // type of the first field of the struct). If there is more than // one result, RESULT_STRUCT is a struct type to hold the results, @@ -115,12 +111,12 @@ public: virtual Btype *array_type (Btype *element_type, Bexpression *length) = 0; // Create a placeholder pointer type. This is used for a named - // pointer type, since in Rust a pointer type may refer to itself. + // pointer type, since in Go a pointer type may refer to itself. // NAME is the name of the type, and the location is where the named // type is defined. This function is also used for unnamed function // types with multiple results, in which case the type has no name // and NAME will be empty. FOR_FUNCTION is true if this is for a C - // pointer to function type. A Rust func type is represented as a + // pointer to function type. A Go func type is represented as a // pointer to a struct, and the first field of the struct is a C // pointer to function. The return value will later be passed as // the first parameter to set_placeholder_pointer_type or @@ -139,7 +135,7 @@ public: // Fill in a placeholder pointer type as a function. This takes a // type returned by placeholder_pointer_type and arranges for it to - // become a real Rust function type (which corresponds to a C/C++ + // become a real Go function type (which corresponds to a C/C++ // pointer to function type). FT will be something returned by the // function_type method. Returns true on success, false on failure. virtual bool set_placeholder_function_type (Btype *placeholder, Btype *ft) @@ -181,7 +177,7 @@ public: // struct, or array type in a case like "type P *byte; type Q P".) virtual Btype *named_type (const std::string &name, Btype *, Location) = 0; - // Create a marker for a circular pointer type. Rust pointer and + // Create a marker for a circular pointer type. Go pointer and // function types can refer to themselves in ways that are not // permitted in C/C++. When a circular type is found, this function // is called for the circular reference. This permits the backend @@ -228,7 +224,7 @@ public: // Create an error expression. This is used for cases which should // not occur in a correct program, in order to keep the compilation - // rusting without crashing. + // going without crashing. virtual Bexpression *error_expression () = 0; // Create a nil pointer expression. @@ -367,7 +363,7 @@ public: // Create an error statement. This is used for cases which should // not occur in a correct program, in order to keep the compilation - // rusting without crashing. + // going without crashing. virtual Bstatement *error_statement () = 0; // Create an expression statement within the specified function. @@ -419,7 +415,7 @@ public: // Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if // an exception occurs. EXCEPT_STMT may be NULL. FINALLY_STMT may be NULL and // if not NULL, it will always be executed. This is used for handling defers - // in Rust functions. In C++, the resulting code is of this form: + // in Go functions. In C++, the resulting code is of this form: // try { BSTAT; } catch { EXCEPT_STMT; } finally { FINALLY_STMT; } virtual Bstatement * exception_handler_statement (Bstatement *bstat, Bstatement *except_stmt, @@ -459,7 +455,7 @@ public: // Create an error variable. This is used for cases which should // not occur in a correct program, in order to keep the compilation - // rusting without crashing. + // going without crashing. virtual Bvariable *error_variable () = 0; // Create a global variable. NAME is the package-qualified name of @@ -672,7 +668,7 @@ public: // Create an error function. This is used for cases which should // not occur in a correct program, in order to keep the compilation - // rusting without crashing. + // going without crashing. virtual Bfunction *error_function () = 0; // Bit flags to pass to the function method. @@ -710,7 +706,7 @@ public: static const unsigned int function_only_inline = 1 << 6; // Declare or define a function of FNTYPE. - // NAME is the Rust name of the function. ASM_NAME, if not the empty + // NAME is the Go name of the function. ASM_NAME, if not the empty // string, is the name that should be used in the symbol table; this // will be non-empty if a magic extern comment is used. FLAGS is // bit flags described above. @@ -760,5 +756,3 @@ public: // section in the output object file. virtual void write_export_data (const char *bytes, unsigned int size) = 0; }; - -#endif // !defined(RUST_BACKEND_H) diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc index f3979f1..8b2a058 100644 --- a/gcc/rust/lex/rust-lex.cc +++ b/gcc/rust/lex/rust-lex.cc @@ -95,8 +95,21 @@ namespace Rust { } Lexer::~Lexer() { + /* ok apparently stop (which is equivalent of original code in destructor) is meant to be + * called after all files have finished parsing, for cleanup. On the other hand, actual code + * that it calls to leave a certain line map is mentioned in GCC docs as being useful for + * "just leaving an included header" and stuff like that, so this line mapping functionality + * may need fixing. + * FIXME: find out whether this occurs. */ + // line_map->stop(); } + // TODO: need to optimise somehow to avoid the virtual function call in the tight loop. + // Best idea at the moment is CRTP, but that might make lexer implementation annoying when storing + // the "base class" (i.e. would need template parameter everywhere), although in practice it would + // mostly just look ugly and make enclosing classes like Parser also require a type parameter. + // At this point a macro might be better. + // OK I guess macros can be replaced by constexpr if or something if possible. Location Lexer::get_current_location() { return line_map->get_location(current_column); } @@ -186,7 +199,7 @@ namespace Rust { } // detect shebang - if (current_line == 1 && current_char == '#') { + if (loc == 1 && current_line == 1 && current_char == '#') { current_char = peek_input(); if (current_char == '!') { @@ -1549,7 +1562,8 @@ namespace Rust { // ensure closing brace if (need_close_brace && current_char != '}') { // actually an error - rust_error_at(get_current_location(), "expected terminating '}' in unicode escape"); + rust_error_at( + get_current_location(), "expected terminating '}' in unicode escape"); return false; } diff --git a/gcc/rust/lex/rust-lex.h b/gcc/rust/lex/rust-lex.h index 14b369c..a705367 100644 --- a/gcc/rust/lex/rust-lex.h +++ b/gcc/rust/lex/rust-lex.h @@ -30,20 +30,22 @@ namespace Rust { // 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 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); + /*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 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: @@ -64,7 +66,9 @@ namespace Rust { // Replaces the current token with a specified token. void replace_current_token(TokenPtr replacement); - Linemap* get_line_map() { return line_map; } + Linemap* get_line_map() { + return line_map; + } private: // File for use as input. diff --git a/gcc/rust/operator.h b/gcc/rust/operator.h index f3e0fd0..560f4bb 100644 --- a/gcc/rust/operator.h +++ b/gcc/rust/operator.h @@ -9,6 +9,8 @@ // The operators. +// TODO: Will have to be significantly modified to work with Rust and current setup of gccrs + enum Operator { OPERATOR_INVALID, diff --git a/gcc/rust/parse/rust-parse.cc b/gcc/rust/parse/rust-parse.cc index abd8831..cef28f7 100644 --- a/gcc/rust/parse/rust-parse.cc +++ b/gcc/rust/parse/rust-parse.cc @@ -2,6 +2,29 @@ #include "rust-linemap.h" #include "rust-diagnostics.h" +#if 0 +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "target.h" +#include "tree.h" +#include "tree-iterator.h" +#include "input.h" +#include "diagnostic.h" +#include "stringpool.h" +#include "cgraph.h" +#include "gimplify.h" +#include "gimple-expr.h" +#include "convert.h" +#include "print-tree.h" +#include "stor-layout.h" +#include "fold-const.h" +/* order: config, system, coretypes, target, tree, tree-iterator, input, diagnostic, stringpool, + * cgraph, gimplify, gimple-expr, convert, print-tree, stor-layout, fold-const */ +// probably don't need all these +#endif +// maybe put these back in if compiling no longer works + #include <algorithm> // for std::find namespace Rust { @@ -159,7 +182,7 @@ namespace Rust { /* shit. preferred HACK would be to replace this token in stream with '>', but may not * be possible at this point. */ // FIXME: ensure locations aren't messed up - TokenPtr right_angle = Token::make(RIGHT_ANGLE, tok->get_locus()); + TokenPtr right_angle = Token::make(RIGHT_ANGLE, tok->get_locus() + 1); lexer.replace_current_token(right_angle); return true; } @@ -168,7 +191,7 @@ namespace Rust { /* FIXME: is this even required? how many people wouldn't leave a space? - apparently * rustc has this feature */ // FIXME: ensure locations aren't messed up - TokenPtr equal = Token::make(EQUAL, tok->get_locus()); + TokenPtr equal = Token::make(EQUAL, tok->get_locus() + 1); lexer.replace_current_token(equal); return true; } @@ -176,12 +199,13 @@ namespace Rust { // another HACK - replace with greater or equal // FIXME: again, is this really required? rustc has the feature, though // FIXME: ensure locations aren't messed up - TokenPtr greater_equal = Token::make(GREATER_OR_EQUAL, tok->get_locus()); + TokenPtr greater_equal = Token::make(GREATER_OR_EQUAL, tok->get_locus() + 1); lexer.replace_current_token(greater_equal); return true; } default: - rust_error_at(tok->get_locus(), "expected '>' at end of generic argument - found '%s'", + rust_error_at(tok->get_locus(), + "expected '>' at end of generic argument - found '%s'", tok->get_token_description()); return false; } @@ -329,7 +353,6 @@ namespace Rust { return (t->get_id() == END_OF_FILE); } - // Parses a crate (compilation unit) - entry point AST::Crate Parser::parse_crate() { /* TODO: determine if has utf8bom and shebang. Currently, they are eliminated by the lexing @@ -516,8 +539,8 @@ namespace Rust { gcc_fallthrough(); default: // do nothing but inactivates warning from gcc when compiling - // could put the rust_error_at thing here but fallthrough (from failing $crate condition) - // isn't completely obvious if it is. + // could put the rust_error_at thing here but fallthrough (from failing $crate + // condition) isn't completely obvious if it is. // test prevent error return AST::SimplePathSegment::create_error(); @@ -1406,7 +1429,8 @@ namespace Rust { ::std::unique_ptr<AST::MacroMatch> match = parse_macro_match(); if (match == NULL) { - rust_error_at(t->get_locus(), "failed to parse macro match for macro matcher - found '%s'", + rust_error_at(t->get_locus(), + "failed to parse macro match for macro matcher - found '%s'", t->get_token_description()); return AST::MacroMatcher::create_error(); } @@ -1499,7 +1523,8 @@ namespace Rust { const_TokenPtr ident_tok = expect_token(IDENTIFIER); if (ident_tok == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "missing identifier in macro match fragment"); + rust_error_at( + lexer.peek_token()->get_locus(), "missing identifier in macro match fragment"); return NULL; } Identifier ident = ident_tok->get_str(); @@ -1825,7 +1850,8 @@ namespace Rust { // parse use tree, which is required ::std::unique_ptr<AST::UseTree> use_tree = parse_use_tree(); if (use_tree == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "could not parse use tree in use declaration"); + rust_error_at( + lexer.peek_token()->get_locus(), "could not parse use tree in use declaration"); skip_after_semicolon(); return NULL; } @@ -2828,7 +2854,8 @@ namespace Rust { // TODO: use this token for identifier when finished that const_TokenPtr alias_name_tok = expect_token(IDENTIFIER); if (alias_name_tok == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "could not parse identifier in type alias"); + rust_error_at( + lexer.peek_token()->get_locus(), "could not parse identifier in type alias"); skip_after_semicolon(); return NULL; } @@ -3089,7 +3116,8 @@ namespace Rust { ::std::unique_ptr<AST::Type> field_type = parse_type(); if (field_type == NULL) { // error if null - rust_error_at(lexer.peek_token()->get_locus(), "could not parse type in tuple struct field"); + rust_error_at( + lexer.peek_token()->get_locus(), "could not parse type in tuple struct field"); // skip after something return AST::TupleField::create_error(); } @@ -3675,7 +3703,8 @@ namespace Rust { } // Type is required, so error if null if (type == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "could not parse type in inherent impl"); + rust_error_at( + lexer.peek_token()->get_locus(), "could not parse type in inherent impl"); skip_after_next_block(); return NULL; } @@ -3841,7 +3870,8 @@ namespace Rust { return NULL; } default: - rust_error_at(t->get_locus(), "unrecognised token '%s' for item in inherent impl", + rust_error_at(t->get_locus(), + "unrecognised token '%s' for item in inherent impl", t->get_token_description()); // skip? return NULL; @@ -3886,8 +3916,8 @@ namespace Rust { /* For internal use only by parse_inherent_impl_item() - splits giant method into smaller ones * and prevents duplication of logic. Strictly, this parses a function or method item inside an * inherent impl item block. */ - // TODO: make this a templated function with "return type" as type param - InherentImplItem is this - // specialisation of the template while TraitImplItem will be the other. + // TODO: make this a templated function with "return type" as type param - InherentImplItem is + // this specialisation of the template while TraitImplItem will be the other. ::std::unique_ptr<AST::InherentImplItem> Parser::parse_inherent_impl_function_or_method( AST::Visibility vis, ::std::vector<AST::Attribute> outer_attrs) { Location locus = lexer.peek_token()->get_locus(); @@ -4022,7 +4052,8 @@ namespace Rust { return NULL; } default: - rust_error_at(t->get_locus(), "unrecognised token '%s' for item in trait impl", + rust_error_at(t->get_locus(), + "unrecognised token '%s' for item in trait impl", t->get_token_description()); // skip? return NULL; @@ -4379,7 +4410,8 @@ namespace Rust { } default: // error - rust_error_at(t->get_locus(), "unrecognised token '%s' in extern block item declaration", + rust_error_at(t->get_locus(), + "unrecognised token '%s' in extern block item declaration", t->get_token_description()); skip_after_semicolon(); return NULL; @@ -4505,7 +4537,8 @@ namespace Rust { // parse pattern (required) ::std::unique_ptr<AST::Pattern> pattern = parse_pattern(); if (pattern == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "failed to parse pattern in let statement"); + rust_error_at( + lexer.peek_token()->get_locus(), "failed to parse pattern in let statement"); skip_after_semicolon(); return NULL; } @@ -4518,7 +4551,8 @@ namespace Rust { type = parse_type(); if (type == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "failed to parse type in let statement"); + rust_error_at( + lexer.peek_token()->get_locus(), "failed to parse type in let statement"); skip_after_semicolon(); return NULL; } @@ -4589,9 +4623,8 @@ namespace Rust { t = lexer.peek_token(); } - return AST::TypePath(::std::move(segments), - Linemap::unknown_location(), - has_opening_scope_resolution); + return AST::TypePath( + ::std::move(segments), Linemap::unknown_location(), has_opening_scope_resolution); } // Parses the generic arguments in each path segment. @@ -4963,13 +4996,14 @@ namespace Rust { } } else { // move back by 1 if pratt parsing due to skipping '<' - locus = lexer.peek_token()->get_locus(); + locus = lexer.peek_token()->get_locus() - 1; } // parse type (required) ::std::unique_ptr<AST::Type> type = parse_type(); if (type == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "could not parse type in qualified path type"); + rust_error_at( + lexer.peek_token()->get_locus(), "could not parse type in qualified path type"); // skip somewhere? return AST::QualifiedPathType::create_error(); } @@ -5183,7 +5217,8 @@ namespace Rust { // parse block expression ::std::unique_ptr<AST::BlockExpr> block_expr = parse_block_expr(); if (block_expr == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "method declaration missing block expression"); + rust_error_at( + lexer.peek_token()->get_locus(), "method declaration missing block expression"); skip_after_end_block(); return AST::Method::create_error(); } @@ -5319,7 +5354,8 @@ namespace Rust { // ensure expr parsed exists if (expr_parsed == NULL) { - rust_error_at(t->get_locus(), "failed to parse expr with block in parsing expr statement"); + rust_error_at( + t->get_locus(), "failed to parse expr with block in parsing expr statement"); skip_after_end_block(); return NULL; } @@ -5437,7 +5473,7 @@ namespace Rust { if (expr == NULL) { rust_error_at(t->get_locus(), "failed to parse expression for expression without " - "block (pratt-parsed expression is null)"); + "block (pratt-parsed expression is null)"); return NULL; } @@ -5474,7 +5510,7 @@ namespace Rust { return NULL; } } else { - locus = lexer.peek_token()->get_locus(); + locus = lexer.peek_token()->get_locus() - 1; } ::std::vector<AST::Attribute> inner_attrs = parse_inner_attributes(); @@ -5506,7 +5542,7 @@ namespace Rust { if (!skip_token(RIGHT_CURLY)) { rust_error_at(t->get_locus(), "error may be from having an expression (as opposed to " - "statement) in the body of the function but not last"); + "statement) in the body of the function but not last"); skip_after_end_block(); return NULL; } @@ -5621,7 +5657,8 @@ namespace Rust { ::std::unique_ptr<AST::BlockExpr> block = parse_block_expr(); if (block == NULL) { // error - rust_error_at(lexer.peek_token()->get_locus(), "failed to parse block expr in closure"); + rust_error_at( + lexer.peek_token()->get_locus(), "failed to parse block expr in closure"); // skip somewhere? return NULL; } @@ -5725,7 +5762,7 @@ namespace Rust { } else { // minus 7 chars for 6 in return and a space // or just TODO: pass in location data - locus = lexer.peek_token()->get_locus(); + locus = lexer.peek_token()->get_locus() - 7; } // parse expression to return, if it exists @@ -5747,7 +5784,7 @@ namespace Rust { } else { // minus 6 chars for 5 in return and a space // or just TODO: pass in location data - locus = lexer.peek_token()->get_locus(); + locus = lexer.peek_token()->get_locus() - 6; } // parse label (lifetime) if it exists - create dummy first @@ -5774,7 +5811,7 @@ namespace Rust { } else { // minus 9 chars for 8 in return and a space // or just TODO: pass in location data - locus = lexer.peek_token()->get_locus(); + locus = lexer.peek_token()->get_locus() - 9; } // parse label (lifetime) if it exists - create dummy first @@ -6034,7 +6071,8 @@ namespace Rust { } default: // error - invalid token - rust_error_at(t->get_locus(), "unexpected token '%s' after else in if let expression", + rust_error_at(t->get_locus(), + "unexpected token '%s' after else in if let expression", t->get_token_description()); // skip somewhere? return NULL; @@ -6190,7 +6228,8 @@ namespace Rust { // parse pattern, which is required ::std::unique_ptr<AST::Pattern> pattern = parse_pattern(); if (pattern == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "failed to parse iterator pattern in for loop"); + rust_error_at( + lexer.peek_token()->get_locus(), "failed to parse iterator pattern in for loop"); // skip somewhere? return NULL; } @@ -6283,7 +6322,7 @@ namespace Rust { } else { // TODO: probably just pass in location data as param // get current pos then move back 6 - 5 for match, 1 for space - locus = lexer.peek_token()->get_locus(); + locus = lexer.peek_token()->get_locus() - 6; } // parse scrutinee expression, which is required (and HACK to prevent struct expr) @@ -6409,7 +6448,8 @@ namespace Rust { ::std::vector< ::std::unique_ptr<AST::Pattern> > match_arm_patterns = parse_match_arm_patterns(RIGHT_CURLY); if (match_arm_patterns.empty()) { - rust_error_at(lexer.peek_token()->get_locus(), "failed to parse any patterns in match arm"); + rust_error_at( + lexer.peek_token()->get_locus(), "failed to parse any patterns in match arm"); // skip somewhere? return AST::MatchArm::create_error(); } @@ -6552,7 +6592,7 @@ namespace Rust { skip_token(LEFT_SQUARE); } else { - locus = lexer.peek_token()->get_locus(); + locus = lexer.peek_token()->get_locus() - 1; } // parse optional inner attributes @@ -6665,7 +6705,8 @@ namespace Rust { // parse type, which is now required type = parse_type(); if (type == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "failed to parse type in closure parameter"); + rust_error_at( + lexer.peek_token()->get_locus(), "failed to parse type in closure parameter"); // skip somewhere? return AST::ClosureParam::create_error(); } @@ -6684,7 +6725,7 @@ namespace Rust { skip_token(LEFT_PAREN); } else { - locus = lexer.peek_token()->get_locus(); + locus = lexer.peek_token()->get_locus() - 1; } // parse optional inner attributes @@ -6735,7 +6776,8 @@ namespace Rust { // parse expr, which is now required ::std::unique_ptr<AST::Expr> expr = parse_expr(); if (expr == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "failed to parse expr in tuple expr"); + rust_error_at( + lexer.peek_token()->get_locus(), "failed to parse expr in tuple expr"); // skip somewhere? return NULL; } @@ -7255,7 +7297,8 @@ namespace Rust { // parse type (required) ::std::unique_ptr<AST::Type> type = parse_type(); if (type == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "failed to parse type in maybe named param"); + rust_error_at( + lexer.peek_token()->get_locus(), "failed to parse type in maybe named param"); return AST::MaybeNamedParam::create_error(); } @@ -7300,7 +7343,8 @@ namespace Rust { // parse required param AST::MaybeNamedParam param = parse_maybe_named_param(); if (param.is_error()) { - rust_error_at(t->get_locus(), "failed to parse maybe named param in bare function type"); + rust_error_at( + t->get_locus(), "failed to parse maybe named param in bare function type"); return NULL; } params.push_back(::std::move(param)); @@ -7491,7 +7535,7 @@ namespace Rust { // probably a lifetime bound, so probably type param bounds in TraitObjectType // this is not allowed, but detection here for error message rust_error_at(t->get_locus(), "lifetime bounds (i.e. in type param bounds, in " - "TraitObjectType) are not allowed as TypeNoBounds"); + "TraitObjectType) are not allowed as TypeNoBounds"); return NULL; } case IDENTIFIER: @@ -7586,8 +7630,9 @@ namespace Rust { // ensure not a trait with multiple bounds t = lexer.peek_token(); if (t->get_id() == PLUS) { - rust_error_at(t->get_locus(), "plus after trait bound means an ImplTraitType, " - "which is not allowed as a TypeNoBounds"); + rust_error_at(t->get_locus(), + "plus after trait bound means an ImplTraitType, " + "which is not allowed as a TypeNoBounds"); return NULL; } @@ -7631,7 +7676,7 @@ namespace Rust { t = lexer.peek_token(); if (t->get_id() == PLUS) { rust_error_at(t->get_locus(), "plus after trait bound means a TraitObjectType, " - "which is not allowed as a TypeNoBounds"); + "which is not allowed as a TypeNoBounds"); return NULL; } @@ -7698,8 +7743,8 @@ namespace Rust { if (lexer.peek_token()->get_id() == PLUS) { // error - this is not allowed for type no bounds rust_error_at(lexer.peek_token()->get_locus(), - "plus (implying TraitObjectType as type param " - "bounds) is not allowed in type no bounds"); + "plus (implying TraitObjectType as type param " + "bounds) is not allowed in type no bounds"); return NULL; } else { // release vector pointer @@ -7794,17 +7839,13 @@ namespace Rust { if (next->get_id() == DOT_DOT_EQ || next->get_id() == ELLIPSIS) { // range pattern lexer.skip_token(); - ::std::unique_ptr<AST::RangePatternBound> lower( - new AST::RangePatternBoundLiteral( - AST::Literal(range_lower->get_str(), type), - range_lower->get_locus(), - has_minus) - ); + ::std::unique_ptr<AST::RangePatternBound> lower(new AST::RangePatternBoundLiteral( + AST::Literal(range_lower->get_str(), type), range_lower->get_locus(), has_minus)); ::std::unique_ptr<AST::RangePatternBound> upper = parse_range_pattern_bound(); if (upper == NULL) { - rust_error_at(next->get_locus(), - "failed to parse range pattern bound in range pattern"); + rust_error_at( + next->get_locus(), "failed to parse range pattern bound in range pattern"); return NULL; } @@ -8010,12 +8051,8 @@ namespace Rust { = parse_range_pattern_bound(); return ::std::unique_ptr<AST::RangePattern>( - new AST::RangePattern( - ::std::move(lower_bound), - ::std::move(upper_bound), - Linemap::unknown_location(), - has_ellipsis_syntax) - ); + new AST::RangePattern(::std::move(lower_bound), ::std::move(upper_bound), + Linemap::unknown_location(), has_ellipsis_syntax)); } case EXCLAM: return parse_macro_invocation_partial( @@ -8096,7 +8133,8 @@ namespace Rust { // parse pattern to get reference of (required) ::std::unique_ptr<AST::Pattern> pattern = parse_pattern(); if (pattern == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "failed to parse pattern in reference pattern"); + rust_error_at( + lexer.peek_token()->get_locus(), "failed to parse pattern in reference pattern"); // skip somewhere? return NULL; } @@ -8284,7 +8322,8 @@ namespace Rust { // parse pattern (required) ::std::unique_ptr<AST::Pattern> pattern = parse_pattern(); if (pattern == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "failed to parse pattern in slice pattern"); + rust_error_at( + lexer.peek_token()->get_locus(), "failed to parse pattern in slice pattern"); return NULL; } patterns.push_back(::std::move(pattern)); @@ -8383,7 +8422,8 @@ namespace Rust { // parse items ::std::unique_ptr<AST::TupleStructItems> items = parse_tuple_struct_items(); if (items == NULL) { - rust_error_at(lexer.peek_token()->get_locus(), "failed to parse tuple struct items"); + rust_error_at( + lexer.peek_token()->get_locus(), "failed to parse tuple struct items"); return NULL; } @@ -8429,12 +8469,8 @@ namespace Rust { ::std::unique_ptr<AST::RangePatternBound> upper_bound = parse_range_pattern_bound(); return ::std::unique_ptr<AST::RangePattern>( - new AST::RangePattern( - ::std::move(lower_bound), - ::std::move(upper_bound), - Linemap::unknown_location(), - has_ellipsis_syntax) - ); + new AST::RangePattern(::std::move(lower_bound), ::std::move(upper_bound), + Linemap::unknown_location(), has_ellipsis_syntax)); } case PATTERN_BIND: { // only allow on single-segment paths @@ -8452,7 +8488,8 @@ namespace Rust { new AST::IdentifierPattern(::std::move(initial_ident), initial_tok->get_locus(), false, false, ::std::move(bind_pattern))); } - rust_error_at(t->get_locus(), "failed to parse pattern bind to a path, not an identifier"); + rust_error_at( + t->get_locus(), "failed to parse pattern bind to a path, not an identifier"); return NULL; } default: @@ -8694,7 +8731,8 @@ namespace Rust { } default: // error - rust_error_at(t->get_locus(), "unrecognised token '%s' in struct pattern field", + rust_error_at(t->get_locus(), + "unrecognised token '%s' in struct pattern field", t->get_token_description()); return NULL; } @@ -8958,7 +8996,7 @@ namespace Rust { AST::SimplePath macro_path = path.as_simple_path(); if (macro_path.is_empty()) { rust_error_at(t2->get_locus(), "failed to convert parsed path to simple " - "path (for macro invocation or semi)"); + "path (for macro invocation or semi)"); return ExprOrStmt::create_error(); } @@ -9058,9 +9096,9 @@ namespace Rust { bool not_a_block = lexer.peek_token(1)->get_id() == IDENTIFIER && (lexer.peek_token(2)->get_id() == COMMA - || (lexer.peek_token(2)->get_id() == COLON - && (lexer.peek_token(4)->get_id() == COMMA - || !can_tok_start_type(lexer.peek_token(3)->get_id())))); + || (lexer.peek_token(2)->get_id() == COLON + && (lexer.peek_token(4)->get_id() == COMMA + || !can_tok_start_type(lexer.peek_token(3)->get_id())))); ::std::unique_ptr<AST::ExprWithoutBlock> expr = NULL; if (not_a_block) { @@ -9349,14 +9387,13 @@ namespace Rust { lexer.skip_token(); return t; } else { - rust_error_at(t->get_locus(), "expecting %s but %s found!\n", get_token_description(token_id), - t->get_token_description()); + rust_error_at(t->get_locus(), "expecting %s but %s found!\n", + get_token_description(token_id), t->get_token_description()); return const_TokenPtr(); } } - // Skips all tokens until EOF or }. Don't use. void Parser::skip_after_end() { const_TokenPtr t = lexer.peek_token(); @@ -9497,8 +9534,6 @@ namespace Rust { return parse_expr(LBP_LOWEST, ::std::move(outer_attrs), restrictions); } - - /* Determines action to take when finding token at beginning of expression. * FIXME: this may only apply to precedence-capable expressions (which are all expressions without * blocks), so make return type ExprWithoutBlock? It would simplify stuff. */ @@ -9548,9 +9583,9 @@ namespace Rust { bool not_a_block = lexer.peek_token(1)->get_id() == IDENTIFIER && (lexer.peek_token(2)->get_id() == COMMA - || (lexer.peek_token(2)->get_id() == COLON - && (lexer.peek_token(4)->get_id() == COMMA - || !can_tok_start_type(lexer.peek_token(3)->get_id())))); + || (lexer.peek_token(2)->get_id() == COLON + && (lexer.peek_token(4)->get_id() == COMMA + || !can_tok_start_type(lexer.peek_token(3)->get_id())))); /* definitely not a block: * path '{' ident ',' @@ -9790,8 +9825,9 @@ namespace Rust { } case SCOPE_RESOLUTION: { // TODO: fix: this is for global paths, i.e. ::std::string::whatever - rust_error_at(tok->get_locus(), "found null denotation scope resolution operator, and " - "haven't written handling for it."); + rust_error_at(tok->get_locus(), + "found null denotation scope resolution operator, and " + "haven't written handling for it."); return NULL; } case SELF: @@ -9835,9 +9871,9 @@ namespace Rust { bool not_a_block = lexer.peek_token(1)->get_id() == IDENTIFIER && (lexer.peek_token(2)->get_id() == COMMA - || (lexer.peek_token(2)->get_id() == COLON - && (lexer.peek_token(4)->get_id() == COMMA - || !can_tok_start_type(lexer.peek_token(3)->get_id())))); + || (lexer.peek_token(2)->get_id() == COLON + && (lexer.peek_token(4)->get_id() == COMMA + || !can_tok_start_type(lexer.peek_token(3)->get_id())))); if (!restrictions.can_be_struct_expr && !not_a_block) { // assume path is returned @@ -10061,8 +10097,9 @@ namespace Rust { tok, ::std::move(left), ::std::move(outer_attrs), restrictions); case SCOPE_RESOLUTION: // path expression - binary infix? FIXME should this even be parsed here? - rust_error_at(tok->get_locus(), "found scope resolution operator in left denotation " - "function - this should probably be handled elsewhere."); + rust_error_at(tok->get_locus(), + "found scope resolution operator in left denotation " + "function - this should probably be handled elsewhere."); return NULL; case DOT: { // field expression or method call - relies on parentheses after next identifier @@ -11020,7 +11057,7 @@ namespace Rust { ::std::unique_ptr<AST::Expr> expr = parse_expr(); if (expr == NULL) { rust_error_at(t->get_locus(), "failed to parse expression in struct " - "(or enum) expression tuple"); + "(or enum) expression tuple"); return NULL; } exprs.push_back(::std::move(expr)); @@ -11214,7 +11251,8 @@ namespace Rust { ::std::unique_ptr<AST::BlockExpr> block = parse_block_expr(); if (block == NULL) { // error - rust_error_at(lexer.peek_token()->get_locus(), "failed to parse block expr in closure"); + rust_error_at( + lexer.peek_token()->get_locus(), "failed to parse block expr in closure"); // skip somewhere? return NULL; } @@ -11291,10 +11329,10 @@ namespace Rust { fprintf(stderr, "<id=%s%s, %s\n", tok->token_id_to_str(), has_text ? (std::string(", text=") + tok->get_str() + std::string(", typehint=") - + std::string(tok->get_type_hint_str())) + + std::string(tok->get_type_hint_str())) .c_str() : "", - lexer.get_line_map()->to_string(loc).c_str()); + lexer.get_line_map()->to_string(loc).c_str()); if (tok->get_id() == Rust::END_OF_FILE) break; @@ -11312,5 +11350,3 @@ namespace Rust { fprintf(stderr, "%s", crate.as_string().c_str()); } } - - diff --git a/gcc/rust/rust-backend.c b/gcc/rust/rust-backend.c index 85e8454..fb701ce 100644 --- a/gcc/rust/rust-backend.c +++ b/gcc/rust/rust-backend.c @@ -30,7 +30,10 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "output.h" /* for assemble_string */ #include "common/common-target.h" -#include "rust-c.h" +//#include "rust-c.h" // import no longer exists, so hopefully not broken + +// satisfy intellisense +#include "options.h" /* The segment name we pass to simple_object_start_read to find Rust export data. */ @@ -84,7 +87,7 @@ rust_field_alignment (tree t) /* This is called by the Rust frontend proper if the unsafe package was imported. When that happens we cannot do type-based alias analysis. */ - +// TODO: this should be removed, as it only pertains to Go, not Rust void rust_imported_unsafe (void) { diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc index feecba9..47c3657 100644 --- a/gcc/rust/rust-gcc.cc +++ b/gcc/rust/rust-gcc.cc @@ -49,6 +49,8 @@ #include "backend.h" #include "rust-object-export.h" +// TODO: this will have to be significantly modified to work with Rust + // A class wrapping a tree. class Gcc_tree diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc index 28cddde..d82e6d8 100644 --- a/gcc/rust/rust-lang.cc +++ b/gcc/rust/rust-lang.cc @@ -265,9 +265,9 @@ static bool grs_langhook_post_options(const char** pfilename ATTRIBUTE_UNUSED) { 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) + && 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); + is_gimple_val, fb_rvalue); return GS_UNHANDLED; } diff --git a/gcc/rust/rust-linemap.h b/gcc/rust/rust-linemap.h index 0f2dc9b..03c60f5 100644 --- a/gcc/rust/rust-linemap.h +++ b/gcc/rust/rust-linemap.h @@ -22,6 +22,11 @@ // 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 + * otherwise have to be made in tight loops like in the lexer. */ + class Linemap { public: diff --git a/gcc/rust/rust-location.h b/gcc/rust/rust-location.h index 1c2c564..0515f68 100644 --- a/gcc/rust/rust-location.h +++ b/gcc/rust/rust-location.h @@ -20,7 +20,24 @@ class Location location_t gcc_location() const - { return this->gcc_loc_; } + { return gcc_loc_; } + + Location + operator+=(location_t rhs) { + gcc_loc_ += rhs; + return *this; + } + + Location + operator-=(location_t rhs) { + gcc_loc_ -= rhs; + return *this; + } + + bool + operator==(location_t rhs) { + return rhs == gcc_loc_; + } private: location_t gcc_loc_; @@ -40,4 +57,18 @@ operator==(Location loca, Location locb) return loca.gcc_location() == locb.gcc_location(); } +inline Location +operator+(Location lhs, location_t rhs) +{ + lhs += rhs; + return lhs; +} + +inline Location +operator-(Location lhs, location_t rhs) +{ + lhs -= rhs; + return lhs; +} + #endif // !defined(RUST_LOCATION_H) diff --git a/gcc/rust/rust-object-export.c b/gcc/rust/rust-object-export.c index 3d09aa7..c985035 100644 --- a/gcc/rust/rust-object-export.c +++ b/gcc/rust/rust-object-export.c @@ -17,6 +17,8 @@ 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? + #include "config.h" #include "system.h" #include "coretypes.h" @@ -31,6 +33,9 @@ along with GCC; see the file COPYING3. If not see #include "output.h" /* for assemble_string */ #include "common/common-target.h" +// satisfy intellisense +#include "options.h" + /* The segment name we pass to simple_object_start_read to find Rust export data. */ @@ -83,7 +88,7 @@ rust_field_alignment (tree t) /* This is called by the Rust frontend proper if the unsafe package was imported. When that happens we cannot do type-based alias analysis. */ - +// TODO: this should be removed, as it only pertains to Go, not Rust void rust_imported_unsafe (void) { diff --git a/gcc/rust/rust-object-export.h b/gcc/rust/rust-object-export.h index 4e84895..d511078 100644 --- a/gcc/rust/rust-object-export.h +++ b/gcc/rust/rust-object-export.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef RUST_OBJECT_EXPORT_H +#define RUST_OBJECT_EXPORT_H extern unsigned int rust_field_alignment (tree t); @@ -7,3 +8,5 @@ rust_read_export_data (int fd, off_t offset, char **pbuf, size_t *plen, int *perr); extern void rust_write_export_data (const char *bytes, unsigned int size); + +#endif // RUST_OBJECT_EXPORT_H
\ No newline at end of file diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index 1701999..471a7fa 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -518,12 +518,8 @@ namespace Rust { // 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()) - ); + 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)); @@ -536,10 +532,10 @@ namespace Rust { 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)), Linemap::unknown_location())); + 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) }, Linemap::unknown_location())); + AST::Visibility::create_error(), { ::std::move(prelude_attr) }, Location())); crate.items.insert(crate.items.begin(), ::std::move(use_decl)); diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h index 167d494..84b5546 100644 --- a/gcc/rust/rust-session-manager.h +++ b/gcc/rust/rust-session-manager.h @@ -11,6 +11,10 @@ #include "rust-linemap.h" #include "backend.h" +#include <string> +#include <unordered_map> +#include <unordered_set> +#include <vector> #include <utility> namespace Rust { @@ -145,6 +149,8 @@ namespace Rust { // 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. */ diff --git a/gcc/rust/rust-system.h b/gcc/rust/rust-system.h index f424a4b..84e66aa 100644 --- a/gcc/rust/rust-system.h +++ b/gcc/rust/rust-system.h @@ -41,6 +41,9 @@ #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>. */ #if defined(HAVE_UNORDERED_MAP) # include <unordered_map> diff --git a/gcc/rust/rustspec.cc b/gcc/rust/rustspec.cc index 8a765da..b61114f 100644 --- a/gcc/rust/rustspec.cc +++ b/gcc/rust/rustspec.cc @@ -23,6 +23,9 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "opts.h" +// satisfy intellisense +#include "options.h" + /* This bit is set if we saw a `-xfoo' language specification. */ #define LANGSPEC (1 << 1) /* This bit is set if they did `-lm' or `-lmath'. */ |