aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimplyTheOther <simplytheother@gmail.com>2020-04-17 14:50:21 +0800
committerPhilip Herron <philip.herron@embecosm.com>2020-11-27 17:04:31 +0000
commit5a2eebc2920ed96e509559e92e74a4af78d95eb6 (patch)
treef6b47c46ed28b73ccf44f9150868feb6ca17f18b
parent1ff5f98ee698fc4443c33254bc79fc3baab0d3cf (diff)
downloadgcc-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.cc26
-rw-r--r--gcc/rust/ast/rust-ast.h37
-rw-r--r--gcc/rust/ast/rust-cond-compilation.h15
-rw-r--r--gcc/rust/ast/rust-expr.h21
-rw-r--r--gcc/rust/ast/rust-item.h7
-rw-r--r--gcc/rust/ast/rust-macro.h9
-rw-r--r--gcc/rust/ast/rust-path.h28
-rw-r--r--gcc/rust/ast/rust-type.h8
-rw-r--r--gcc/rust/backend.h36
-rw-r--r--gcc/rust/lex/rust-lex.cc18
-rw-r--r--gcc/rust/lex/rust-lex.h22
-rw-r--r--gcc/rust/operator.h2
-rw-r--r--gcc/rust/parse/rust-parse.cc236
-rw-r--r--gcc/rust/rust-backend.c7
-rw-r--r--gcc/rust/rust-gcc.cc2
-rw-r--r--gcc/rust/rust-lang.cc4
-rw-r--r--gcc/rust/rust-linemap.h5
-rw-r--r--gcc/rust/rust-location.h33
-rw-r--r--gcc/rust/rust-object-export.c7
-rw-r--r--gcc/rust/rust-object-export.h5
-rw-r--r--gcc/rust/rust-session-manager.cc12
-rw-r--r--gcc/rust/rust-session-manager.h6
-rw-r--r--gcc/rust/rust-system.h3
-rw-r--r--gcc/rust/rustspec.cc3
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'. */