aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2020-04-20 18:47:22 +0100
committerPhilip Herron <philip.herron@embecosm.com>2020-11-28 19:09:39 +0000
commit16a1e8af9d848cb9864cb30476a6ed444538ecba (patch)
treea496ca4325daa7624e27efbe94e0bf4201e10792
parentc7c6f785c8e893ec7bcacd1a2319ce309d2450f2 (diff)
downloadgcc-16a1e8af9d848cb9864cb30476a6ed444538ecba.zip
gcc-16a1e8af9d848cb9864cb30476a6ed444538ecba.tar.gz
gcc-16a1e8af9d848cb9864cb30476a6ed444538ecba.tar.bz2
This setups an initial frame work for our resolution step for the pipeline
More work is required but it takes advantage of the vistior pattern from the AST so we can do this without RTTI and dynamic_casts. More passes on the AST AKA our HIR should follow this pattern. Addresses: #12
-rw-r--r--gcc/rust/Make-lang.in8
-rw-r--r--gcc/rust/analysis/rust-resolution.cc605
-rw-r--r--gcc/rust/analysis/rust-resolution.h235
-rw-r--r--gcc/rust/analysis/scope.h55
-rw-r--r--gcc/rust/ast/rust-ast-full-test.cc15
-rw-r--r--gcc/rust/ast/rust-ast.h4
-rw-r--r--gcc/rust/ast/rust-expr.h38
-rw-r--r--gcc/rust/ast/rust-item.h2
-rw-r--r--gcc/rust/ast/rust-pattern.h2
-rw-r--r--gcc/rust/ast/rust-stmt.h2
-rw-r--r--gcc/rust/parse/rust-parse.cc366
-rw-r--r--gcc/rust/parse/rust-parse.h2
-rw-r--r--gcc/rust/rust-session-manager.cc1557
13 files changed, 1923 insertions, 968 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 1a5622e..e35aa69 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -69,6 +69,7 @@ GRS_OBJS = \
rust/rust-parse.o \
rust/rust-ast-full-test.o \
rust/rust-session-manager.o \
+ rust/rust-resolution.o \
$(END)
# removed object files from here
@@ -208,7 +209,7 @@ CFLAGS-rust/rust-lang.o += -DDEFAULT_TARGET_VERSION=\"$(version)\" \
-DDEFAULT_TARGET_MACHINE=\"$(target_noncanonical)\"
# cross-folder includes - add new folders later
-RUST_INCLUDES = -I $(srcdir)/rust -I $(srcdir)/rust/lex -I $(srcdir)/rust/parse -I $(srcdir)/rust/ast
+RUST_INCLUDES = -I $(srcdir)/rust -I $(srcdir)/rust/lex -I $(srcdir)/rust/parse -I $(srcdir)/rust/ast -I $(srcdir)/rust/analysis
# add files that require cross-folder includes - currently rust-lang.o, rust-lex.o
CFLAGS-rust/rust-lang.o += $(RUST_INCLUDES)
@@ -232,3 +233,8 @@ rust/%.o: rust/parse/%.cc
rust/%.o: rust/ast/%.cc
$(COMPILE) -std=c++11 $(RUST_INCLUDES) $<
$(POSTCOMPILE)
+
+# build rust/analysis files in rust folder
+rust/%.o: rust/analysis/%.cc
+ $(COMPILE) -std=c++11 $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
diff --git a/gcc/rust/analysis/rust-resolution.cc b/gcc/rust/analysis/rust-resolution.cc
new file mode 100644
index 0000000..65fed90
--- /dev/null
+++ b/gcc/rust/analysis/rust-resolution.cc
@@ -0,0 +1,605 @@
+#include "rust-resolution.h"
+
+namespace Rust {
+namespace Analysis {
+
+TypeResolution::TypeResolution (AST::Crate &crate) : scope (), crate (crate) {}
+
+TypeResolution::~TypeResolution () {}
+
+bool
+TypeResolution::ResolveNamesAndTypes (AST::Crate &crate)
+{
+ TypeResolution resolver (crate);
+ return resolver.go ();
+}
+
+bool
+TypeResolution::go ()
+{
+ scope.Push ();
+ for (auto &item : crate.items)
+ {
+ item->accept_vis (*this);
+ }
+ scope.Pop ();
+ return true;
+}
+
+void
+TypeResolution::visit (AST::Token &tok)
+{}
+
+void
+TypeResolution::visit (AST::DelimTokenTree &delim_tok_tree)
+{}
+
+void
+TypeResolution::visit (AST::AttrInputMetaItemContainer &input)
+{}
+
+void
+TypeResolution::visit (AST::IdentifierExpr &ident_expr)
+{}
+
+void
+TypeResolution::visit (AST::Lifetime &lifetime)
+{}
+
+void
+TypeResolution::visit (AST::LifetimeParam &lifetime_param)
+{}
+
+void
+TypeResolution::visit (AST::MacroInvocationSemi &macro)
+{}
+
+// rust-path.h
+void
+TypeResolution::visit (AST::PathInExpression &path)
+{}
+void
+TypeResolution::visit (AST::TypePathSegment &segment)
+{}
+void
+TypeResolution::visit (AST::TypePathSegmentGeneric &segment)
+{}
+void
+TypeResolution::visit (AST::TypePathSegmentFunction &segment)
+{}
+void
+TypeResolution::visit (AST::TypePath &path)
+{}
+void
+TypeResolution::visit (AST::QualifiedPathInExpression &path)
+{}
+void
+TypeResolution::visit (AST::QualifiedPathInType &path)
+{}
+
+// rust-expr.h
+void
+TypeResolution::visit (AST::LiteralExpr &expr)
+{}
+void
+TypeResolution::visit (AST::AttrInputLiteral &attr_input)
+{}
+void
+TypeResolution::visit (AST::MetaItemLitExpr &meta_item)
+{}
+void
+TypeResolution::visit (AST::MetaItemPathLit &meta_item)
+{}
+void
+TypeResolution::visit (AST::BorrowExpr &expr)
+{}
+void
+TypeResolution::visit (AST::DereferenceExpr &expr)
+{}
+void
+TypeResolution::visit (AST::ErrorPropagationExpr &expr)
+{}
+void
+TypeResolution::visit (AST::NegationExpr &expr)
+{}
+void
+TypeResolution::visit (AST::ArithmeticOrLogicalExpr &expr)
+{}
+void
+TypeResolution::visit (AST::ComparisonExpr &expr)
+{}
+void
+TypeResolution::visit (AST::LazyBooleanExpr &expr)
+{}
+void
+TypeResolution::visit (AST::TypeCastExpr &expr)
+{}
+void
+TypeResolution::visit (AST::AssignmentExpr &expr)
+{}
+void
+TypeResolution::visit (AST::CompoundAssignmentExpr &expr)
+{}
+void
+TypeResolution::visit (AST::GroupedExpr &expr)
+{}
+// void TypeResolution::visit(ArrayElems& elems) {}
+void
+TypeResolution::visit (AST::ArrayElemsValues &elems)
+{}
+void
+TypeResolution::visit (AST::ArrayElemsCopied &elems)
+{}
+void
+TypeResolution::visit (AST::ArrayExpr &expr)
+{}
+void
+TypeResolution::visit (AST::ArrayIndexExpr &expr)
+{}
+void
+TypeResolution::visit (AST::TupleExpr &expr)
+{}
+void
+TypeResolution::visit (AST::TupleIndexExpr &expr)
+{}
+void
+TypeResolution::visit (AST::StructExprStruct &expr)
+{}
+// void TypeResolution::visit(StructExprField& field) {}
+void
+TypeResolution::visit (AST::StructExprFieldIdentifier &field)
+{}
+void
+TypeResolution::visit (AST::StructExprFieldIdentifierValue &field)
+{}
+void
+TypeResolution::visit (AST::StructExprFieldIndexValue &field)
+{}
+void
+TypeResolution::visit (AST::StructExprStructFields &expr)
+{}
+void
+TypeResolution::visit (AST::StructExprStructBase &expr)
+{}
+void
+TypeResolution::visit (AST::StructExprTuple &expr)
+{}
+void
+TypeResolution::visit (AST::StructExprUnit &expr)
+{}
+// void TypeResolution::visit(EnumExprField& field) {}
+void
+TypeResolution::visit (AST::EnumExprFieldIdentifier &field)
+{}
+void
+TypeResolution::visit (AST::EnumExprFieldIdentifierValue &field)
+{}
+void
+TypeResolution::visit (AST::EnumExprFieldIndexValue &field)
+{}
+void
+TypeResolution::visit (AST::EnumExprStruct &expr)
+{}
+void
+TypeResolution::visit (AST::EnumExprTuple &expr)
+{}
+void
+TypeResolution::visit (AST::EnumExprFieldless &expr)
+{}
+void
+TypeResolution::visit (AST::CallExpr &expr)
+{}
+void
+TypeResolution::visit (AST::MethodCallExpr &expr)
+{}
+void
+TypeResolution::visit (AST::FieldAccessExpr &expr)
+{}
+void
+TypeResolution::visit (AST::ClosureExprInner &expr)
+{}
+void
+TypeResolution::visit (AST::BlockExpr &expr)
+{}
+void
+TypeResolution::visit (AST::ClosureExprInnerTyped &expr)
+{}
+void
+TypeResolution::visit (AST::ContinueExpr &expr)
+{}
+void
+TypeResolution::visit (AST::BreakExpr &expr)
+{}
+void
+TypeResolution::visit (AST::RangeFromToExpr &expr)
+{}
+void
+TypeResolution::visit (AST::RangeFromExpr &expr)
+{}
+void
+TypeResolution::visit (AST::RangeToExpr &expr)
+{}
+void
+TypeResolution::visit (AST::RangeFullExpr &expr)
+{}
+void
+TypeResolution::visit (AST::RangeFromToInclExpr &expr)
+{}
+void
+TypeResolution::visit (AST::RangeToInclExpr &expr)
+{}
+void
+TypeResolution::visit (AST::ReturnExpr &expr)
+{}
+void
+TypeResolution::visit (AST::UnsafeBlockExpr &expr)
+{}
+void
+TypeResolution::visit (AST::LoopExpr &expr)
+{}
+void
+TypeResolution::visit (AST::WhileLoopExpr &expr)
+{}
+void
+TypeResolution::visit (AST::WhileLetLoopExpr &expr)
+{}
+void
+TypeResolution::visit (AST::ForLoopExpr &expr)
+{}
+void
+TypeResolution::visit (AST::IfExpr &expr)
+{}
+void
+TypeResolution::visit (AST::IfExprConseqElse &expr)
+{}
+void
+TypeResolution::visit (AST::IfExprConseqIf &expr)
+{}
+void
+TypeResolution::visit (AST::IfExprConseqIfLet &expr)
+{}
+void
+TypeResolution::visit (AST::IfLetExpr &expr)
+{}
+void
+TypeResolution::visit (AST::IfLetExprConseqElse &expr)
+{}
+void
+TypeResolution::visit (AST::IfLetExprConseqIf &expr)
+{}
+void
+TypeResolution::visit (AST::IfLetExprConseqIfLet &expr)
+{}
+// void TypeResolution::visit(MatchCase& match_case) {}
+void
+TypeResolution::visit (AST::MatchCaseBlockExpr &match_case)
+{}
+void
+TypeResolution::visit (AST::MatchCaseExpr &match_case)
+{}
+void
+TypeResolution::visit (AST::MatchExpr &expr)
+{}
+void
+TypeResolution::visit (AST::AwaitExpr &expr)
+{}
+void
+TypeResolution::visit (AST::AsyncBlockExpr &expr)
+{}
+
+// rust-item.h
+void
+TypeResolution::visit (AST::TypeParam &param)
+{}
+// void TypeResolution::visit(WhereClauseItem& item) {}
+void
+TypeResolution::visit (AST::LifetimeWhereClauseItem &item)
+{}
+void
+TypeResolution::visit (AST::TypeBoundWhereClauseItem &item)
+{}
+void
+TypeResolution::visit (AST::Method &method)
+{}
+void
+TypeResolution::visit (AST::ModuleBodied &module)
+{}
+void
+TypeResolution::visit (AST::ModuleNoBody &module)
+{}
+void
+TypeResolution::visit (AST::ExternCrate &crate)
+{}
+// void TypeResolution::visit(UseTree& use_tree) {}
+void
+TypeResolution::visit (AST::UseTreeGlob &use_tree)
+{}
+void
+TypeResolution::visit (AST::UseTreeList &use_tree)
+{}
+void
+TypeResolution::visit (AST::UseTreeRebind &use_tree)
+{}
+void
+TypeResolution::visit (AST::UseDeclaration &use_decl)
+{}
+
+void
+TypeResolution::visit (AST::Function &function)
+{
+ scope.Insert (function.function_name, function.return_type.get ());
+
+ scope.Push ();
+ printf ("INSIDE FUNCTION: %s\n", function.function_name.c_str ());
+
+ for (auto &param : function.function_params)
+ {
+ printf ("FUNC PARAM: %s\n", param.as_string ().c_str ());
+ }
+
+ // ensure return types
+ // TODO
+
+ // walk the expression body
+ for (auto &stmt : function.function_body->statements)
+ {
+ stmt->accept_vis (*this);
+ }
+
+ scope.Pop ();
+}
+
+void
+TypeResolution::visit (AST::TypeAlias &type_alias)
+{}
+void
+TypeResolution::visit (AST::StructStruct &struct_item)
+{}
+void
+TypeResolution::visit (AST::TupleStruct &tuple_struct)
+{}
+void
+TypeResolution::visit (AST::EnumItem &item)
+{}
+void
+TypeResolution::visit (AST::EnumItemTuple &item)
+{}
+void
+TypeResolution::visit (AST::EnumItemStruct &item)
+{}
+void
+TypeResolution::visit (AST::EnumItemDiscriminant &item)
+{}
+void
+TypeResolution::visit (AST::Enum &enum_item)
+{}
+void
+TypeResolution::visit (AST::Union &union_item)
+{}
+void
+TypeResolution::visit (AST::ConstantItem &const_item)
+{}
+void
+TypeResolution::visit (AST::StaticItem &static_item)
+{}
+void
+TypeResolution::visit (AST::TraitItemFunc &item)
+{}
+void
+TypeResolution::visit (AST::TraitItemMethod &item)
+{}
+void
+TypeResolution::visit (AST::TraitItemConst &item)
+{}
+void
+TypeResolution::visit (AST::TraitItemType &item)
+{}
+void
+TypeResolution::visit (AST::Trait &trait)
+{}
+void
+TypeResolution::visit (AST::InherentImpl &impl)
+{}
+void
+TypeResolution::visit (AST::TraitImpl &impl)
+{}
+// void TypeResolution::visit(ExternalItem& item) {}
+void
+TypeResolution::visit (AST::ExternalStaticItem &item)
+{}
+void
+TypeResolution::visit (AST::ExternalFunctionItem &item)
+{}
+void
+TypeResolution::visit (AST::ExternBlock &block)
+{}
+
+// rust-macro.h
+void
+TypeResolution::visit (AST::MacroMatchFragment &match)
+{}
+void
+TypeResolution::visit (AST::MacroMatchRepetition &match)
+{}
+void
+TypeResolution::visit (AST::MacroMatcher &matcher)
+{}
+void
+TypeResolution::visit (AST::MacroRulesDefinition &rules_def)
+{}
+void
+TypeResolution::visit (AST::MacroInvocation &macro_invoc)
+{}
+void
+TypeResolution::visit (AST::MetaItemPath &meta_item)
+{}
+void
+TypeResolution::visit (AST::MetaItemSeq &meta_item)
+{}
+void
+TypeResolution::visit (AST::MetaWord &meta_item)
+{}
+void
+TypeResolution::visit (AST::MetaNameValueStr &meta_item)
+{}
+void
+TypeResolution::visit (AST::MetaListPaths &meta_item)
+{}
+void
+TypeResolution::visit (AST::MetaListNameValueStr &meta_item)
+{}
+
+// rust-pattern.h
+void
+TypeResolution::visit (AST::LiteralPattern &pattern)
+{
+ printf ("LiteralPattern: %s\n", pattern.as_string ().c_str ());
+}
+
+void
+TypeResolution::visit (AST::IdentifierPattern &pattern)
+{
+ printf ("IdentifierPattern: %s\n", pattern.as_string ().c_str ());
+ letPatternBuffer.push_back (pattern);
+}
+
+void
+TypeResolution::visit (AST::WildcardPattern &pattern)
+{}
+// void TypeResolution::visit(RangePatternBound& bound) {}
+void
+TypeResolution::visit (AST::RangePatternBoundLiteral &bound)
+{}
+void
+TypeResolution::visit (AST::RangePatternBoundPath &bound)
+{}
+void
+TypeResolution::visit (AST::RangePatternBoundQualPath &bound)
+{}
+void
+TypeResolution::visit (AST::RangePattern &pattern)
+{}
+void
+TypeResolution::visit (AST::ReferencePattern &pattern)
+{}
+// void TypeResolution::visit(StructPatternField& field) {}
+void
+TypeResolution::visit (AST::StructPatternFieldTuplePat &field)
+{}
+void
+TypeResolution::visit (AST::StructPatternFieldIdentPat &field)
+{}
+void
+TypeResolution::visit (AST::StructPatternFieldIdent &field)
+{}
+void
+TypeResolution::visit (AST::StructPattern &pattern)
+{}
+// void TypeResolution::visit(TupleStructItems& tuple_items) {}
+void
+TypeResolution::visit (AST::TupleStructItemsNoRange &tuple_items)
+{}
+void
+TypeResolution::visit (AST::TupleStructItemsRange &tuple_items)
+{}
+void
+TypeResolution::visit (AST::TupleStructPattern &pattern)
+{}
+// void TypeResolution::visit(TuplePatternItems& tuple_items) {}
+void
+TypeResolution::visit (AST::TuplePatternItemsMultiple &tuple_items)
+{}
+void
+TypeResolution::visit (AST::TuplePatternItemsRanged &tuple_items)
+{}
+void
+TypeResolution::visit (AST::TuplePattern &pattern)
+{}
+void
+TypeResolution::visit (AST::GroupedPattern &pattern)
+{}
+void
+TypeResolution::visit (AST::SlicePattern &pattern)
+{}
+
+// rust-stmt.h
+void
+TypeResolution::visit (AST::EmptyStmt &stmt)
+{}
+void
+
+TypeResolution::visit (AST::LetStmt &stmt)
+{
+ printf ("Within LetStmt: %s\n", stmt.as_string ().c_str ());
+
+ if (!stmt.has_type ())
+ {
+ // infer the type
+ printf ("XXX UNKNOWN TYPE PLEASE INFER ME\n");
+ }
+
+ // TODO check we know what the type is
+
+ stmt.variables_pattern->accept_vis (*this);
+
+ for (auto it = letPatternBuffer.begin (); it != letPatternBuffer.end (); it++)
+ {
+ scope.Insert (it->variable_ident, stmt.type.get ());
+ }
+
+ letPatternBuffer.clear ();
+}
+
+void
+TypeResolution::visit (AST::ExprStmtWithoutBlock &stmt)
+{}
+void
+TypeResolution::visit (AST::ExprStmtWithBlock &stmt)
+{}
+
+// rust-type.h
+void
+TypeResolution::visit (AST::TraitBound &bound)
+{}
+void
+TypeResolution::visit (AST::ImplTraitType &type)
+{}
+void
+TypeResolution::visit (AST::TraitObjectType &type)
+{}
+void
+TypeResolution::visit (AST::ParenthesisedType &type)
+{}
+void
+TypeResolution::visit (AST::ImplTraitTypeOneBound &type)
+{}
+void
+TypeResolution::visit (AST::TraitObjectTypeOneBound &type)
+{}
+void
+TypeResolution::visit (AST::TupleType &type)
+{}
+void
+TypeResolution::visit (AST::NeverType &type)
+{}
+void
+TypeResolution::visit (AST::RawPointerType &type)
+{}
+void
+TypeResolution::visit (AST::ReferenceType &type)
+{}
+void
+TypeResolution::visit (AST::ArrayType &type)
+{}
+void
+TypeResolution::visit (AST::SliceType &type)
+{}
+void
+TypeResolution::visit (AST::InferredType &type)
+{}
+void
+TypeResolution::visit (AST::BareFunctionType &type)
+{}
+
+} // namespace Analysis
+} // namespace Rust
diff --git a/gcc/rust/analysis/rust-resolution.h b/gcc/rust/analysis/rust-resolution.h
new file mode 100644
index 0000000..940557e
--- /dev/null
+++ b/gcc/rust/analysis/rust-resolution.h
@@ -0,0 +1,235 @@
+#pragma once
+
+#include "rust-system.h"
+#include "rust-ast-full.h"
+#include "rust-ast-visitor.h"
+#include "scope.h"
+
+namespace Rust {
+namespace Analysis {
+
+class TypeResolution : public AST::ASTVisitor
+{
+public:
+ static bool ResolveNamesAndTypes (AST::Crate &crate);
+
+ ~TypeResolution ();
+
+ // visitor impl
+ // rust-ast.h
+ // virtual void visit(AttrInput& attr_input);
+ // virtual void visit(TokenTree& token_tree);
+ // virtual void visit(MacroMatch& macro_match);
+ virtual void visit (AST::Token &tok);
+ virtual void visit (AST::DelimTokenTree &delim_tok_tree);
+ virtual void visit (AST::AttrInputMetaItemContainer &input);
+ // virtual void visit(MetaItem& meta_item);
+ // virtual void vsit(Stmt& stmt);
+ // virtual void visit(Expr& expr);
+ virtual void visit (AST::IdentifierExpr &ident_expr);
+ // virtual void visit(Pattern& pattern);
+ // virtual void visit(Type& type);
+ // virtual void visit(TypeParamBound& type_param_bound);
+ virtual void visit (AST::Lifetime &lifetime);
+ // virtual void visit(GenericParam& generic_param);
+ virtual void visit (AST::LifetimeParam &lifetime_param);
+ // virtual void visit(TraitItem& trait_item);
+ // virtual void visit(InherentImplItem& inherent_impl_item);
+ // virtual void visit(TraitImplItem& trait_impl_item);
+ virtual void visit (AST::MacroInvocationSemi &macro);
+
+ // rust-path.h
+ virtual void visit (AST::PathInExpression &path);
+ virtual void visit (AST::TypePathSegment &segment);
+ virtual void visit (AST::TypePathSegmentGeneric &segment);
+ virtual void visit (AST::TypePathSegmentFunction &segment);
+ virtual void visit (AST::TypePath &path);
+ virtual void visit (AST::QualifiedPathInExpression &path);
+ virtual void visit (AST::QualifiedPathInType &path);
+
+ // rust-expr.h
+ virtual void visit (AST::LiteralExpr &expr);
+ virtual void visit (AST::AttrInputLiteral &attr_input);
+ virtual void visit (AST::MetaItemLitExpr &meta_item);
+ virtual void visit (AST::MetaItemPathLit &meta_item);
+ virtual void visit (AST::BorrowExpr &expr);
+ virtual void visit (AST::DereferenceExpr &expr);
+ virtual void visit (AST::ErrorPropagationExpr &expr);
+ virtual void visit (AST::NegationExpr &expr);
+ virtual void visit (AST::ArithmeticOrLogicalExpr &expr);
+ virtual void visit (AST::ComparisonExpr &expr);
+ virtual void visit (AST::LazyBooleanExpr &expr);
+ virtual void visit (AST::TypeCastExpr &expr);
+ virtual void visit (AST::AssignmentExpr &expr);
+ virtual void visit (AST::CompoundAssignmentExpr &expr);
+ virtual void visit (AST::GroupedExpr &expr);
+ // virtual void visit(ArrayElems& elems);
+ virtual void visit (AST::ArrayElemsValues &elems);
+ virtual void visit (AST::ArrayElemsCopied &elems);
+ virtual void visit (AST::ArrayExpr &expr);
+ virtual void visit (AST::ArrayIndexExpr &expr);
+ virtual void visit (AST::TupleExpr &expr);
+ virtual void visit (AST::TupleIndexExpr &expr);
+ virtual void visit (AST::StructExprStruct &expr);
+ // virtual void visit(StructExprField& field);
+ virtual void visit (AST::StructExprFieldIdentifier &field);
+ virtual void visit (AST::StructExprFieldIdentifierValue &field);
+ virtual void visit (AST::StructExprFieldIndexValue &field);
+ virtual void visit (AST::StructExprStructFields &expr);
+ virtual void visit (AST::StructExprStructBase &expr);
+ virtual void visit (AST::StructExprTuple &expr);
+ virtual void visit (AST::StructExprUnit &expr);
+ // virtual void visit(EnumExprField& field);
+ virtual void visit (AST::EnumExprFieldIdentifier &field);
+ virtual void visit (AST::EnumExprFieldIdentifierValue &field);
+ virtual void visit (AST::EnumExprFieldIndexValue &field);
+ virtual void visit (AST::EnumExprStruct &expr);
+ virtual void visit (AST::EnumExprTuple &expr);
+ virtual void visit (AST::EnumExprFieldless &expr);
+ virtual void visit (AST::CallExpr &expr);
+ virtual void visit (AST::MethodCallExpr &expr);
+ virtual void visit (AST::FieldAccessExpr &expr);
+ virtual void visit (AST::ClosureExprInner &expr);
+ virtual void visit (AST::BlockExpr &expr);
+ virtual void visit (AST::ClosureExprInnerTyped &expr);
+ virtual void visit (AST::ContinueExpr &expr);
+ virtual void visit (AST::BreakExpr &expr);
+ virtual void visit (AST::RangeFromToExpr &expr);
+ virtual void visit (AST::RangeFromExpr &expr);
+ virtual void visit (AST::RangeToExpr &expr);
+ virtual void visit (AST::RangeFullExpr &expr);
+ virtual void visit (AST::RangeFromToInclExpr &expr);
+ virtual void visit (AST::RangeToInclExpr &expr);
+ virtual void visit (AST::ReturnExpr &expr);
+ virtual void visit (AST::UnsafeBlockExpr &expr);
+ virtual void visit (AST::LoopExpr &expr);
+ virtual void visit (AST::WhileLoopExpr &expr);
+ virtual void visit (AST::WhileLetLoopExpr &expr);
+ virtual void visit (AST::ForLoopExpr &expr);
+ virtual void visit (AST::IfExpr &expr);
+ virtual void visit (AST::IfExprConseqElse &expr);
+ virtual void visit (AST::IfExprConseqIf &expr);
+ virtual void visit (AST::IfExprConseqIfLet &expr);
+ virtual void visit (AST::IfLetExpr &expr);
+ virtual void visit (AST::IfLetExprConseqElse &expr);
+ virtual void visit (AST::IfLetExprConseqIf &expr);
+ virtual void visit (AST::IfLetExprConseqIfLet &expr);
+ // virtual void visit(MatchCase& match_case);
+ virtual void visit (AST::MatchCaseBlockExpr &match_case);
+ virtual void visit (AST::MatchCaseExpr &match_case);
+ virtual void visit (AST::MatchExpr &expr);
+ virtual void visit (AST::AwaitExpr &expr);
+ virtual void visit (AST::AsyncBlockExpr &expr);
+
+ // rust-item.h
+ virtual void visit (AST::TypeParam &param);
+ // virtual void visit(WhereClauseItem& item);
+ virtual void visit (AST::LifetimeWhereClauseItem &item);
+ virtual void visit (AST::TypeBoundWhereClauseItem &item);
+ virtual void visit (AST::Method &method);
+ virtual void visit (AST::ModuleBodied &module);
+ virtual void visit (AST::ModuleNoBody &module);
+ virtual void visit (AST::ExternCrate &crate);
+ // virtual void visit(UseTree& use_tree);
+ virtual void visit (AST::UseTreeGlob &use_tree);
+ virtual void visit (AST::UseTreeList &use_tree);
+ virtual void visit (AST::UseTreeRebind &use_tree);
+ virtual void visit (AST::UseDeclaration &use_decl);
+ virtual void visit (AST::Function &function);
+ virtual void visit (AST::TypeAlias &type_alias);
+ virtual void visit (AST::StructStruct &struct_item);
+ virtual void visit (AST::TupleStruct &tuple_struct);
+ virtual void visit (AST::EnumItem &item);
+ virtual void visit (AST::EnumItemTuple &item);
+ virtual void visit (AST::EnumItemStruct &item);
+ virtual void visit (AST::EnumItemDiscriminant &item);
+ virtual void visit (AST::Enum &enum_item);
+ virtual void visit (AST::Union &union_item);
+ virtual void visit (AST::ConstantItem &const_item);
+ virtual void visit (AST::StaticItem &static_item);
+ virtual void visit (AST::TraitItemFunc &item);
+ virtual void visit (AST::TraitItemMethod &item);
+ virtual void visit (AST::TraitItemConst &item);
+ virtual void visit (AST::TraitItemType &item);
+ virtual void visit (AST::Trait &trait);
+ virtual void visit (AST::InherentImpl &impl);
+ virtual void visit (AST::TraitImpl &impl);
+ // virtual void visit(ExternalItem& item);
+ virtual void visit (AST::ExternalStaticItem &item);
+ virtual void visit (AST::ExternalFunctionItem &item);
+ virtual void visit (AST::ExternBlock &block);
+
+ // rust-macro.h
+ virtual void visit (AST::MacroMatchFragment &match);
+ virtual void visit (AST::MacroMatchRepetition &match);
+ virtual void visit (AST::MacroMatcher &matcher);
+ virtual void visit (AST::MacroRulesDefinition &rules_def);
+ virtual void visit (AST::MacroInvocation &macro_invoc);
+ virtual void visit (AST::MetaItemPath &meta_item);
+ virtual void visit (AST::MetaItemSeq &meta_item);
+ virtual void visit (AST::MetaWord &meta_item);
+ virtual void visit (AST::MetaNameValueStr &meta_item);
+ virtual void visit (AST::MetaListPaths &meta_item);
+ virtual void visit (AST::MetaListNameValueStr &meta_item);
+
+ // rust-pattern.h
+ virtual void visit (AST::LiteralPattern &pattern);
+ virtual void visit (AST::IdentifierPattern &pattern);
+ virtual void visit (AST::WildcardPattern &pattern);
+ // virtual void visit(RangePatternBound& bound);
+ virtual void visit (AST::RangePatternBoundLiteral &bound);
+ virtual void visit (AST::RangePatternBoundPath &bound);
+ virtual void visit (AST::RangePatternBoundQualPath &bound);
+ virtual void visit (AST::RangePattern &pattern);
+ virtual void visit (AST::ReferencePattern &pattern);
+ // virtual void visit(StructPatternField& field);
+ virtual void visit (AST::StructPatternFieldTuplePat &field);
+ virtual void visit (AST::StructPatternFieldIdentPat &field);
+ virtual void visit (AST::StructPatternFieldIdent &field);
+ virtual void visit (AST::StructPattern &pattern);
+ // virtual void visit(TupleStructItems& tuple_items);
+ virtual void visit (AST::TupleStructItemsNoRange &tuple_items);
+ virtual void visit (AST::TupleStructItemsRange &tuple_items);
+ virtual void visit (AST::TupleStructPattern &pattern);
+ // virtual void visit(TuplePatternItems& tuple_items);
+ virtual void visit (AST::TuplePatternItemsMultiple &tuple_items);
+ virtual void visit (AST::TuplePatternItemsRanged &tuple_items);
+ virtual void visit (AST::TuplePattern &pattern);
+ virtual void visit (AST::GroupedPattern &pattern);
+ virtual void visit (AST::SlicePattern &pattern);
+
+ // rust-stmt.h
+ virtual void visit (AST::EmptyStmt &stmt);
+ virtual void visit (AST::LetStmt &stmt);
+ virtual void visit (AST::ExprStmtWithoutBlock &stmt);
+ virtual void visit (AST::ExprStmtWithBlock &stmt);
+
+ // rust-type.h
+ virtual void visit (AST::TraitBound &bound);
+ virtual void visit (AST::ImplTraitType &type);
+ virtual void visit (AST::TraitObjectType &type);
+ virtual void visit (AST::ParenthesisedType &type);
+ virtual void visit (AST::ImplTraitTypeOneBound &type);
+ virtual void visit (AST::TraitObjectTypeOneBound &type);
+ virtual void visit (AST::TupleType &type);
+ virtual void visit (AST::NeverType &type);
+ virtual void visit (AST::RawPointerType &type);
+ virtual void visit (AST::ReferenceType &type);
+ virtual void visit (AST::ArrayType &type);
+ virtual void visit (AST::SliceType &type);
+ virtual void visit (AST::InferredType &type);
+ virtual void visit (AST::BareFunctionType &type);
+
+private:
+ TypeResolution (AST::Crate &crate);
+
+ bool go ();
+
+ Scope scope;
+ AST::Crate &crate;
+
+ std::vector<AST::IdentifierPattern> letPatternBuffer;
+};
+
+} // namespace Analysis
+} // namespace Rust
diff --git a/gcc/rust/analysis/scope.h b/gcc/rust/analysis/scope.h
new file mode 100644
index 0000000..0374251
--- /dev/null
+++ b/gcc/rust/analysis/scope.h
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "rust-system.h"
+#include "rust-ast-full.h"
+
+namespace Rust {
+namespace Analysis {
+
+class Scope
+{
+public:
+ Scope () : scopeStack () {}
+
+ ~Scope () {}
+
+ bool Insert (std::string key, AST::Type *val)
+ {
+ if (scopeStack.back ().find (key) != scopeStack.back ().end ())
+ {
+ return false;
+ }
+
+ scopeStack.back ().insert (std::make_pair (key, std::move (val)));
+ return true;
+ }
+
+ bool Lookup (std::string key, AST::Type **result)
+ {
+ for (auto it = scopeStack.rbegin (); it != scopeStack.rend (); ++it)
+ {
+ auto lookup = it->find (key);
+ if (lookup != it->end ())
+ {
+ *result = lookup->second;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void Push () { scopeStack.push_back ({}); }
+
+ std ::map<std::string, AST::Type *> Pop ()
+ {
+ auto toplevel = scopeStack.back ();
+ scopeStack.pop_back ();
+ return toplevel;
+ }
+
+private:
+ std::vector<std::map<std::string, AST::Type *> > scopeStack;
+};
+
+} // namespace Analysis
+} // namespace Rust
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc
index d1fbb95..ac5cad7 100644
--- a/gcc/rust/ast/rust-ast-full-test.cc
+++ b/gcc/rust/ast/rust-ast-full-test.cc
@@ -783,8 +783,7 @@ UseTreeGlob::as_string () const
return "*";
case GLOBAL:
return "::*";
- case PATH_PREFIXED:
- {
+ case PATH_PREFIXED: {
::std::string path_str = path.as_string ();
return path_str + "::*";
}
@@ -807,8 +806,7 @@ UseTreeList::as_string () const
case GLOBAL:
path_str = "::{";
break;
- case PATH_PREFIXED:
- {
+ case PATH_PREFIXED: {
path_str = path.as_string () + "::{";
break;
}
@@ -4688,8 +4686,7 @@ MacroParser::parse_meta_item_inner ()
case SELF:
case CRATE:
case DOLLAR_SIGN:
- case SCOPE_RESOLUTION:
- {
+ case SCOPE_RESOLUTION: {
return parse_path_meta_item ();
}
default:
@@ -4830,16 +4827,14 @@ MacroParser::parse_path_meta_item ()
switch (peek_token ()->get_id ())
{
- case LEFT_PAREN:
- {
+ case LEFT_PAREN: {
::std::vector< ::std::unique_ptr<MetaItemInner> > meta_items
= parse_meta_item_seq ();
return ::std::unique_ptr<MetaItemSeq> (
new MetaItemSeq (::std::move (path), ::std::move (meta_items)));
}
- case EQUAL:
- {
+ case EQUAL: {
skip_token ();
Location locus = peek_token ()->get_locus ();
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 6a7511e..5378378 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -303,7 +303,7 @@ class DelimTokenTree : public TokenTree, public AttrInput
// 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
+ // Literal
// parse_literal(const ::std::unique_ptr<Token>& tok) const;
//::std::unique_ptr<MetaItem> parse_path_meta_item(const ::std::vector<
//::std::unique_ptr<Token> >& token_stream, int& i) const; bool
@@ -819,6 +819,8 @@ public:
add_crate_name (::std::vector< ::std::string> &names ATTRIBUTE_UNUSED) const
{}
+ virtual void accept_vis (ASTVisitor &vis ATTRIBUTE_UNUSED) {}
+
protected:
// Constructor
Item (::std::vector<Attribute> outer_attribs = ::std::vector<Attribute> ())
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 2bc6cf9..ce78bd7 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -556,15 +556,15 @@ public:
enum ExprType
{
ADD, // std::ops::Add
- SUBTRACT, // std::ops::Sub
- MULTIPLY, // std::ops::Mul
- DIVIDE, // std::ops::Div
- MODULUS, // std::ops::Rem
+ SUBTRACT, // std::ops::Sub
+ MULTIPLY, // std::ops::Mul
+ DIVIDE, // std::ops::Div
+ MODULUS, // std::ops::Rem
BITWISE_AND, // std::ops::BitAnd
- BITWISE_OR, // std::ops::BitOr
+ BITWISE_OR, // std::ops::BitOr
BITWISE_XOR, // std::ops::BitXor
- LEFT_SHIFT, // std::ops::Shl
- RIGHT_SHIFT // std::ops::Shr
+ LEFT_SHIFT, // std::ops::Shl
+ RIGHT_SHIFT // std::ops::Shr
};
private:
@@ -647,10 +647,10 @@ class ComparisonExpr : public OperatorExpr
public:
enum ExprType
{
- EQUAL, // std::cmp::PartialEq::eq
- NOT_EQUAL, // std::cmp::PartialEq::ne
+ EQUAL, // std::cmp::PartialEq::eq
+ NOT_EQUAL, // std::cmp::PartialEq::ne
GREATER_THAN, // std::cmp::PartialEq::gt
- LESS_THAN, // std::cmp::PartialEq::lt
+ LESS_THAN, // std::cmp::PartialEq::lt
GREATER_OR_EQUAL, // std::cmp::PartialEq::ge
LESS_OR_EQUAL // std::cmp::PartialEq::le
};
@@ -964,15 +964,15 @@ public:
enum ExprType
{
ADD, // std::ops::AddAssign
- SUBTRACT, // std::ops::SubAssign
- MULTIPLY, // std::ops::MulAssign
- DIVIDE, // std::ops::DivAssign
- MODULUS, // std::ops::RemAssign
+ SUBTRACT, // std::ops::SubAssign
+ MULTIPLY, // std::ops::MulAssign
+ DIVIDE, // std::ops::DivAssign
+ MODULUS, // std::ops::RemAssign
BITWISE_AND, // std::ops::BitAndAssign
- BITWISE_OR, // std::ops::BitOrAssign
+ BITWISE_OR, // std::ops::BitOrAssign
BITWISE_XOR, // std::ops::BitXorAssign
- LEFT_SHIFT, // std::ops::ShlAssign
- RIGHT_SHIFT // std::ops::ShrAssign
+ LEFT_SHIFT, // std::ops::ShlAssign
+ RIGHT_SHIFT // std::ops::ShrAssign
};
private:
@@ -2936,6 +2936,7 @@ protected:
// A block AST node
class BlockExpr : public ExprWithBlock
{
+public:
::std::vector<Attribute> inner_attrs;
/*bool has_statements;
@@ -2948,7 +2949,6 @@ class BlockExpr : public ExprWithBlock
Location locus;
-public:
::std::string as_string () const;
// Returns whether the block contains statements.
@@ -4763,7 +4763,7 @@ public:
// Copy constructor with clone
MatchArm (MatchArm const &other)
: /*match_arm_patterns(other.match_arm_patterns),*/ outer_attrs (
- other.outer_attrs)
+ other.outer_attrs)
{
// guard to protect from null pointer dereference
if (other.guard_expr != NULL)
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 669c262..45f5842 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -1310,6 +1310,7 @@ protected:
// Rust function declaration AST node
class Function : public VisItem, public InherentImplItem, public TraitImplItem
{
+public:
FunctionQualifiers qualifiers;
Identifier function_name;
@@ -1334,7 +1335,6 @@ class Function : public VisItem, public InherentImplItem, public TraitImplItem
Location locus;
-public:
/*~Function() {
delete function_body;
}*/
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 533a65f..e61d473 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -49,6 +49,7 @@ protected:
// Identifier pattern AST node (bind value matched to a variable)
class IdentifierPattern : public Pattern
{
+public:
Identifier variable_ident;
bool is_ref;
bool is_mut;
@@ -59,7 +60,6 @@ class IdentifierPattern : public Pattern
Location locus;
-public:
/*~IdentifierPattern() {
delete to_bind;
}*/
diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
index 08d5ff8..49c94fd 100644
--- a/gcc/rust/ast/rust-stmt.h
+++ b/gcc/rust/ast/rust-stmt.h
@@ -46,6 +46,7 @@ protected:
* introduces new name into scope */
class LetStmt : public Stmt
{
+public:
// bool has_outer_attrs;
::std::vector<Attribute> outer_attrs;
@@ -62,7 +63,6 @@ class LetStmt : public Stmt
Location locus;
-public:
// Returns whether let statement has outer attributes.
inline bool has_outer_attrs () const { return !outer_attrs.empty (); }
diff --git a/gcc/rust/parse/rust-parse.cc b/gcc/rust/parse/rust-parse.cc
index 4d15ac7..5e9443f 100644
--- a/gcc/rust/parse/rust-parse.cc
+++ b/gcc/rust/parse/rust-parse.cc
@@ -192,8 +192,7 @@ Parser::skip_generics_right_angle ()
// this is good - skip token
lexer.skip_token ();
return true;
- case RIGHT_SHIFT:
- {
+ case RIGHT_SHIFT: {
/* 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
@@ -201,8 +200,7 @@ Parser::skip_generics_right_angle ()
lexer.replace_current_token (right_angle);
return true;
}
- case GREATER_OR_EQUAL:
- {
+ case GREATER_OR_EQUAL: {
// another HACK - replace with equal (as assignment intended, probably)
/* FIXME: is this even required? how many people wouldn't leave a space?
* - apparently rustc has this feature */
@@ -211,8 +209,7 @@ Parser::skip_generics_right_angle ()
lexer.replace_current_token (equal);
return true;
}
- case RIGHT_SHIFT_EQ:
- {
+ case RIGHT_SHIFT_EQ: {
// 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
@@ -677,8 +674,7 @@ Parser::parse_attr_input ()
{
case LEFT_PAREN:
case LEFT_SQUARE:
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
// must be a delimited token tree, so parse that
::std::unique_ptr<AST::DelimTokenTree> input_tree (
new AST::DelimTokenTree (parse_delim_token_tree ()));
@@ -687,8 +683,7 @@ Parser::parse_attr_input ()
return input_tree;
}
- case EQUAL:
- {
+ case EQUAL: {
// = LiteralExpr
lexer.skip_token ();
@@ -1713,8 +1708,7 @@ Parser::parse_macro_match ()
{
case LEFT_PAREN:
case LEFT_SQUARE:
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
// must be macro matcher as delimited
AST::MacroMatcher matcher = parse_macro_matcher ();
if (matcher.is_error ())
@@ -1726,8 +1720,7 @@ Parser::parse_macro_match ()
return ::std::unique_ptr<AST::MacroMatcher> (
new AST::MacroMatcher (::std::move (matcher)));
}
- case DOLLAR_SIGN:
- {
+ case DOLLAR_SIGN: {
// have to do more lookahead to determine if fragment or repetition
const_TokenPtr t2 = lexer.peek_token (1);
switch (t2->get_id ())
@@ -1949,8 +1942,7 @@ Parser::parse_visibility ()
skip_token (RIGHT_PAREN);
return AST::Visibility::create_super ();
- case IN:
- {
+ case IN: {
lexer.skip_token ();
// parse the "in" path as well
@@ -2001,8 +1993,7 @@ Parser::parse_module (AST::Visibility vis,
new AST::ModuleNoBody (::std::move (name), ::std::move (vis),
::std::move (outer_attrs),
locus)); // module name?
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
lexer.skip_token ();
// parse inner attributes
@@ -2234,8 +2225,7 @@ Parser::parse_use_tree ()
return ::std::unique_ptr<AST::UseTreeGlob> (
new AST::UseTreeGlob (AST::UseTreeGlob::NO_PATH,
AST::SimplePath::create_empty (), locus));
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
// nested tree UseTree type
lexer.skip_token ();
@@ -2307,8 +2297,7 @@ Parser::parse_use_tree ()
return ::std::unique_ptr<AST::UseTreeGlob> (
new AST::UseTreeGlob (AST::UseTreeGlob::PATH_PREFIXED,
::std::move (path), locus));
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
// nested tree UseTree type
lexer.skip_token ();
@@ -2347,8 +2336,7 @@ Parser::parse_use_tree ()
::std::move (path), std::move (use_trees),
locus));
}
- case AS:
- {
+ case AS: {
// rebind UseTree type
lexer.skip_token ();
@@ -3490,8 +3478,7 @@ Parser::parse_struct (AST::Visibility vis,
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
{
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
// struct with body
// skip curly bracket
@@ -3808,8 +3795,7 @@ Parser::parse_enum_item ()
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
{
- case LEFT_PAREN:
- {
+ case LEFT_PAREN: {
// tuple enum item
lexer.skip_token ();
@@ -3825,8 +3811,7 @@ Parser::parse_enum_item ()
::std::move (item_name), ::std::move (tuple_fields),
::std::move (outer_attrs), item_name_tok->get_locus ()));
}
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
// struct enum item
lexer.skip_token ();
@@ -3842,8 +3827,7 @@ Parser::parse_enum_item ()
::std::move (item_name), ::std::move (struct_fields),
::std::move (outer_attrs), item_name_tok->get_locus ()));
}
- case EQUAL:
- {
+ case EQUAL: {
// discriminant enum item
lexer.skip_token ();
@@ -4127,8 +4111,7 @@ Parser::parse_trait_item ()
gcc_fallthrough ();
case UNSAFE:
case EXTERN_TOK:
- case FN_TOK:
- {
+ case FN_TOK: {
/* function and method can't be disambiguated by lookahead alone
* (without a lot of work and waste), so either make a
* "parse_trait_function_or_method" or parse here mostly and pass in
@@ -4248,8 +4231,7 @@ Parser::parse_trait_item ()
tok->get_locus ()));
}
}
- default:
- {
+ default: {
// TODO: try and parse macro invocation semi - if fails, maybe error.
::std::unique_ptr<AST::MacroInvocationSemi> macro_invoc
= parse_macro_invocation_semi (outer_attrs);
@@ -4560,8 +4542,7 @@ Parser::parse_inherent_impl_item ()
case DOLLAR_SIGN:
// these seem to be SimplePath tokens, so this is a macro invocation semi
return parse_macro_invocation_semi (::std::move (outer_attrs));
- case PUB:
- {
+ case PUB: {
// visibility, so not a macro invocation semi - must be constant,
// function, or method
AST::Visibility vis = parse_visibility ();
@@ -4777,8 +4758,7 @@ Parser::parse_trait_impl_item ()
case TYPE:
return parse_type_alias (AST::Visibility::create_error (),
::std::move (outer_attrs));
- case PUB:
- {
+ case PUB: {
// visibility, so not a macro invocation semi - must be constant,
// function, or method
AST::Visibility vis = parse_visibility ();
@@ -5099,8 +5079,7 @@ Parser::parse_external_item ()
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
{
- case STATIC_TOK:
- {
+ case STATIC_TOK: {
// parse extern static item
lexer.skip_token ();
@@ -5148,8 +5127,7 @@ Parser::parse_external_item ()
has_mut, ::std::move (vis),
::std::move (outer_attrs), locus));
}
- case FN_TOK:
- {
+ case FN_TOK: {
// parse extern function declaration item
// skip function token
lexer.skip_token ();
@@ -5687,8 +5665,7 @@ Parser::parse_type_path_segment ()
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
{
- case LEFT_ANGLE:
- {
+ case LEFT_ANGLE: {
// parse generic args
AST::GenericArgs generic_args = parse_path_generic_args ();
@@ -5697,8 +5674,7 @@ Parser::parse_type_path_segment ()
has_separating_scope_resolution,
::std::move (generic_args), locus));
}
- case LEFT_PAREN:
- {
+ case LEFT_PAREN: {
// parse type path function
AST::TypePathFunction type_path_function = parse_type_path_function ();
@@ -6272,8 +6248,7 @@ Parser::parse_expr_stmt (::std::vector<AST::Attribute> outer_attrs)
case ASYNC:
// expression with block
return parse_expr_stmt_with_block (::std::move (outer_attrs));
- case LIFETIME:
- {
+ case LIFETIME: {
/* FIXME: are there any expressions without blocks that can have
* lifetime as their first token? Or is loop expr the only one? */
// safe side for now:
@@ -6287,8 +6262,7 @@ Parser::parse_expr_stmt (::std::vector<AST::Attribute> outer_attrs)
return parse_expr_stmt_without_block (::std::move (outer_attrs));
}
}
- case UNSAFE:
- {
+ case UNSAFE: {
/* FIXME: are there any expressions without blocks that can have unsafe
* as their first token? Or is unsafe the only one? */
// safe side for now
@@ -6342,8 +6316,7 @@ Parser::parse_expr_stmt_with_block (::std::vector<AST::Attribute> outer_attrs)
// "for" iterator loop
expr_parsed = parse_for_loop_expr (::std::move (outer_attrs));
break;
- case WHILE:
- {
+ case WHILE: {
// while or while let, so more lookahead to find out
if (lexer.peek_token ()->get_id () == LET)
{
@@ -6510,8 +6483,7 @@ Parser::parse_expr_without_block (::std::vector<AST::Attribute> outer_attrs)
/* either grouped expr or tuple expr - depends on whether there is a comma
* inside the parentheses - if so, tuple expr, otherwise, grouped expr. */
return parse_grouped_or_tuple_expr (::std::move (outer_attrs));
- default:
- {
+ default: {
// HACK: piggyback on pratt parsed expr and abuse polymorphism to
// essentially downcast
@@ -7038,8 +7010,7 @@ Parser::parse_if_expr (
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
{
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
// double selection - else
// parse else block expr (required)
::std::unique_ptr<AST::BlockExpr> else_body = parse_block_expr ();
@@ -7057,8 +7028,7 @@ Parser::parse_if_expr (
::std::move (if_body),
::std::move (else_body), locus));
}
- case IF:
- {
+ case IF: {
// multiple selection - else if or else if let
// branch on whether next token is 'let' or not
if (lexer.peek_token (1)->get_id () == LET)
@@ -7200,8 +7170,7 @@ Parser::parse_if_let_expr (
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
{
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
// double selection - else
// parse else block expr (required)
::std::unique_ptr<AST::BlockExpr> else_body = parse_block_expr ();
@@ -7220,8 +7189,7 @@ Parser::parse_if_let_expr (
::std::move (if_let_body),
::std::move (else_body), locus));
}
- case IF:
- {
+ case IF: {
// multiple selection - else if or else if let
// branch on whether next token is 'let' or not
if (lexer.peek_token (1)->get_id () == LET)
@@ -8207,8 +8175,7 @@ Parser::parse_type ()
case LEFT_SQUARE:
// slice type or array type - requires further disambiguation
return parse_slice_or_array_type ();
- case LEFT_ANGLE:
- {
+ case LEFT_ANGLE: {
// qualified path in type
AST::QualifiedPathInType path = parse_qualified_path_in_type ();
if (path.is_error ())
@@ -8231,8 +8198,7 @@ Parser::parse_type ()
case AMP: // does this also include AMP_AMP?
// reference type
return parse_reference_type ();
- case LIFETIME:
- {
+ case LIFETIME: {
// probably a lifetime bound, so probably type param bounds in
// TraitObjectType
::std::vector< ::std::unique_ptr<AST::TypeParamBound> > bounds
@@ -8247,8 +8213,7 @@ Parser::parse_type ()
case SELF_ALIAS:
case CRATE:
case DOLLAR_SIGN:
- case SCOPE_RESOLUTION:
- {
+ case SCOPE_RESOLUTION: {
// macro invocation or type path - requires further disambiguation.
/* for parsing path component of each rule, perhaps parse it as a
* typepath and attempt conversion to simplepath if a trailing '!' is
@@ -8273,8 +8238,7 @@ Parser::parse_type ()
t = lexer.peek_token ();
switch (t->get_id ())
{
- case EXCLAM:
- {
+ case EXCLAM: {
// macro invocation
// convert to simple path
AST::SimplePath macro_path = path.as_simple_path ();
@@ -8296,8 +8260,7 @@ Parser::parse_type ()
::std::vector<AST::Attribute> (),
locus));
}
- case PLUS:
- {
+ case PLUS: {
// type param bounds
::std::vector< ::std::unique_ptr<AST::TypeParamBound> > bounds;
@@ -8413,8 +8376,7 @@ Parser::parse_type ()
new AST::ImplTraitType (::std::move (bounds), locus));
}
case DYN:
- case QUESTION_MARK:
- {
+ case QUESTION_MARK: {
// either TraitObjectType or TraitObjectTypeOneBound
bool has_dyn = false;
if (t->get_id () == DYN)
@@ -8664,8 +8626,7 @@ Parser::parse_for_prefixed_type ()
case SELF:
case SELF_ALIAS:
case CRATE:
- case DOLLAR_SIGN:
- {
+ case DOLLAR_SIGN: {
// path, so trait type
// parse type path to finish parsing trait bound
@@ -8966,8 +8927,7 @@ Parser::parse_slice_or_array_type ()
return ::std::unique_ptr<AST::SliceType> (
new AST::SliceType (::std::move (inner_type), locus));
- case SEMICOLON:
- {
+ case SEMICOLON: {
// array type
lexer.skip_token ();
@@ -9014,8 +8974,7 @@ Parser::parse_type_no_bounds ()
case LEFT_SQUARE:
// slice type or array type - requires further disambiguation
return parse_slice_or_array_type ();
- case LEFT_ANGLE:
- {
+ case LEFT_ANGLE: {
// qualified path in type
AST::QualifiedPathInType path = parse_qualified_path_in_type ();
if (path.is_error ())
@@ -9038,8 +8997,7 @@ Parser::parse_type_no_bounds ()
case AMP: // does this also include AMP_AMP?
// reference type
return parse_reference_type ();
- case LIFETIME:
- {
+ case LIFETIME: {
// probably a lifetime bound, so probably type param bounds in
// TraitObjectType this is not allowed, but detection here for error
// message
@@ -9054,8 +9012,7 @@ Parser::parse_type_no_bounds ()
case SELF_ALIAS:
case CRATE:
case DOLLAR_SIGN:
- case SCOPE_RESOLUTION:
- {
+ case SCOPE_RESOLUTION: {
// macro invocation or type path - requires further disambiguation.
/* for parsing path component of each rule, perhaps parse it as a
* typepath and attempt conversion to simplepath if a trailing '!' is
@@ -9081,8 +9038,7 @@ Parser::parse_type_no_bounds ()
t = lexer.peek_token ();
switch (t->get_id ())
{
- case EXCLAM:
- {
+ case EXCLAM: {
// macro invocation
// convert to simple path
AST::SimplePath macro_path = path.as_simple_path ();
@@ -9104,8 +9060,7 @@ Parser::parse_type_no_bounds ()
::std::vector<AST::Attribute> (),
locus));
}
- case PLUS:
- {
+ case PLUS: {
// type param bounds - not allowed, here for error message
rust_error_at (t->get_locus (),
"type param bounds (in TraitObjectType) are not "
@@ -9178,8 +9133,7 @@ Parser::parse_type_no_bounds ()
new AST::ImplTraitTypeOneBound (::std::move (value_bound), locus));
}
case DYN:
- case QUESTION_MARK:
- {
+ case QUESTION_MARK: {
// either TraitObjectTypeOneBound
bool has_dyn = false;
if (t->get_id () == DYN)
@@ -9506,8 +9460,7 @@ Parser::parse_range_pattern_bound ()
case SELF_ALIAS:
case CRATE:
case SCOPE_RESOLUTION:
- case DOLLAR_SIGN:
- {
+ case DOLLAR_SIGN: {
// path in expression
AST::PathInExpression path = parse_path_in_expression ();
if (path.is_error ())
@@ -9520,8 +9473,7 @@ Parser::parse_range_pattern_bound ()
return ::std::unique_ptr<AST::RangePatternBoundPath> (
new AST::RangePatternBoundPath (::std::move (path)));
}
- case LEFT_ANGLE:
- {
+ case LEFT_ANGLE: {
// qualified path in expression
AST::QualifiedPathInExpression path
= parse_qualified_path_in_expression ();
@@ -9611,8 +9563,7 @@ Parser::parse_pattern ()
case LEFT_SQUARE:
// slice pattern
return parse_slice_pattern ();
- case LEFT_ANGLE:
- {
+ case LEFT_ANGLE: {
// qualified path in expression or qualified range pattern bound
AST::QualifiedPathInExpression path
= parse_qualified_path_in_expression ();
@@ -9647,8 +9598,7 @@ Parser::parse_pattern ()
case SELF_ALIAS:
case CRATE:
case SCOPE_RESOLUTION:
- case DOLLAR_SIGN:
- {
+ case DOLLAR_SIGN: {
// path in expression or range pattern bound
AST::PathInExpression path = parse_path_in_expression ();
@@ -9656,8 +9606,7 @@ Parser::parse_pattern ()
switch (next->get_id ())
{
case DOT_DOT_EQ:
- case ELLIPSIS:
- {
+ case ELLIPSIS: {
// qualified range pattern bound, so parse rest of range pattern
bool has_ellipsis_syntax
= lexer.peek_token ()->get_id () == ELLIPSIS;
@@ -9677,8 +9626,7 @@ Parser::parse_pattern ()
case EXCLAM:
return parse_macro_invocation_partial (
::std::move (path), ::std::vector<AST::Attribute> ());
- case LEFT_PAREN:
- {
+ case LEFT_PAREN: {
// tuple struct
lexer.skip_token ();
@@ -9701,8 +9649,7 @@ Parser::parse_pattern ()
new AST::TupleStructPattern (::std::move (path),
::std::move (items)));
}
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
// struct
lexer.skip_token ();
@@ -9854,8 +9801,7 @@ Parser::parse_grouped_or_tuple_pattern ()
return ::std::unique_ptr<AST::GroupedPattern> (
new AST::GroupedPattern (::std::move (initial_pattern), paren_locus));
- case COMMA:
- {
+ case COMMA: {
// tuple pattern
lexer.skip_token ();
@@ -10097,8 +10043,7 @@ Parser::parse_ident_leading_pattern ()
case EXCLAM:
return parse_macro_invocation_partial (::std::move (path),
::std::vector<AST::Attribute> ());
- case LEFT_PAREN:
- {
+ case LEFT_PAREN: {
// tuple struct
lexer.skip_token ();
@@ -10130,8 +10075,7 @@ Parser::parse_ident_leading_pattern ()
new AST::TupleStructPattern (::std::move (path),
::std::move (items)));
}
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
// struct
lexer.skip_token ();
@@ -10150,8 +10094,7 @@ Parser::parse_ident_leading_pattern ()
new AST::StructPattern (::std::move (path), ::std::move (elems)));
}
case DOT_DOT_EQ:
- case ELLIPSIS:
- {
+ case ELLIPSIS: {
// range
bool has_ellipsis_syntax = lexer.peek_token ()->get_id () == ELLIPSIS;
@@ -10166,8 +10109,7 @@ Parser::parse_ident_leading_pattern ()
::std::move (lower_bound), ::std::move (upper_bound),
Linemap::unknown_location (), has_ellipsis_syntax));
}
- case PATTERN_BIND:
- {
+ case PATTERN_BIND: {
// only allow on single-segment paths
if (path.is_single_segment ())
{
@@ -10300,8 +10242,7 @@ Parser::parse_tuple_struct_items ()
case RIGHT_PAREN:
return ::std::unique_ptr<AST::TupleStructItemsNoRange> (
new AST::TupleStructItemsNoRange (::std::move (lower_patterns)));
- case DOT_DOT:
- {
+ case DOT_DOT: {
// has an upper range that must be parsed separately
lexer.skip_token ();
@@ -10412,8 +10353,7 @@ Parser::parse_struct_pattern_field ()
const_TokenPtr t = lexer.peek_token ();
switch (t->get_id ())
{
- case INT_LITERAL:
- {
+ case INT_LITERAL: {
// tuple index
::std::string index_str = t->get_str ();
int index = atoi (index_str.c_str ());
@@ -10443,8 +10383,7 @@ Parser::parse_struct_pattern_field ()
// branch on next token
switch (lexer.peek_token (1)->get_id ())
{
- case COLON:
- {
+ case COLON: {
// identifier-pattern
Identifier ident = t->get_str ();
lexer.skip_token ();
@@ -10468,8 +10407,7 @@ Parser::parse_struct_pattern_field ()
t->get_locus ()));
}
case COMMA:
- case RIGHT_CURLY:
- {
+ case RIGHT_CURLY: {
// identifier only
Identifier ident = t->get_str ();
lexer.skip_token ();
@@ -10488,8 +10426,7 @@ Parser::parse_struct_pattern_field ()
return NULL;
}
case REF:
- case MUT:
- {
+ case MUT: {
// only identifier
bool has_ref = false;
if (t->get_id () == REF)
@@ -10557,8 +10494,7 @@ Parser::parse_stmt_or_expr_without_block ()
t = lexer.peek_token ();
switch (t->get_id ())
{
- case LET:
- {
+ case LET: {
// let statement
::std::unique_ptr<AST::LetStmt> stmt (
parse_let_stmt (::std::move (outer_attrs)));
@@ -10575,48 +10511,42 @@ Parser::parse_stmt_or_expr_without_block ()
case CONST:
case STATIC_TOK:
case TRAIT:
- case IMPL:
- {
+ case IMPL: {
::std::unique_ptr<AST::VisItem> item (
parse_vis_item (::std::move (outer_attrs)));
return ExprOrStmt (::std::move (item));
}
- /* TODO: implement union keyword but not really because of
- * context-dependence crappy hack way to parse a union written below to
- * separate it from the good code. */
- // case UNION:
- case UNSAFE:
- { // maybe - unsafe traits are a thing
+ /* TODO: implement union keyword but not really because of
+ * context-dependence crappy hack way to parse a union written below to
+ * separate it from the good code. */
+ // case UNION:
+ case UNSAFE: { // maybe - unsafe traits are a thing
// if any of these (should be all possible VisItem prefixes), parse a
// VisItem can't parse item because would require reparsing outer
// attributes
const_TokenPtr t2 = lexer.peek_token (1);
switch (t2->get_id ())
{
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
// unsafe block
::std::unique_ptr<AST::ExprStmtWithBlock> stmt (
parse_expr_stmt_with_block (::std::move (outer_attrs)));
return ExprOrStmt (::std::move (stmt));
}
- case TRAIT:
- {
+ case TRAIT: {
// unsafe trait
::std::unique_ptr<AST::VisItem> item (
parse_vis_item (::std::move (outer_attrs)));
return ExprOrStmt (::std::move (item));
}
case EXTERN_TOK:
- case FN_TOK:
- {
+ case FN_TOK: {
// unsafe function
::std::unique_ptr<AST::VisItem> item (
parse_vis_item (::std::move (outer_attrs)));
return ExprOrStmt (::std::move (item));
}
- case IMPL:
- {
+ case IMPL: {
// unsafe trait impl
::std::unique_ptr<AST::VisItem> item (
parse_vis_item (::std::move (outer_attrs)));
@@ -10635,8 +10565,7 @@ Parser::parse_stmt_or_expr_without_block ()
case SUPER:
case SELF:
case CRATE:
- case DOLLAR_SIGN:
- {
+ case DOLLAR_SIGN: {
/* path-based thing so struct/enum or path or macro invocation of a
* kind. however, the expressions are composable (i think) */
@@ -10668,16 +10597,14 @@ Parser::parse_stmt_or_expr_without_block ()
case IF:
case MATCH_TOK:
case LEFT_CURLY:
- case ASYNC:
- {
+ case ASYNC: {
// all expressions with block, so cannot be final expr without block in
// function
::std::unique_ptr<AST::ExprStmtWithBlock> stmt (
parse_expr_stmt_with_block (::std::move (outer_attrs)));
return ExprOrStmt (::std::move (stmt));
}
- case LIFETIME:
- {
+ case LIFETIME: {
/* FIXME: are there any expressions without blocks that can have
* lifetime as their first token? Or is loop expr the only one? */
// safe side for now:
@@ -10757,8 +10684,7 @@ Parser::parse_stmt_or_expr_without_block ()
}
gcc_fallthrough ();
// TODO: find out how to disable gcc "implicit fallthrough" warning
- default:
- {
+ default: {
// expression statement (without block) or expression itself - parse
// expression then make it statement if semi afterwards
@@ -10796,8 +10722,7 @@ Parser::parse_path_based_stmt_or_expr (
const_TokenPtr t2 = lexer.peek_token ();
switch (t2->get_id ())
{
- case EXCLAM:
- {
+ case EXCLAM: {
// macro invocation or macro invocation semi - depends on whether there
// is a final ';' convert path in expr to simple path (as that is used
// in macros)
@@ -10912,8 +10837,7 @@ Parser::parse_path_based_stmt_or_expr (
return ExprOrStmt::create_error ();
}
}
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
/* definitely not a block:
* path '{' ident ','
* path '{' ident ':' [anything] ','
@@ -10924,7 +10848,7 @@ Parser::parse_path_based_stmt_or_expr (
|| (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 (3)->get_id ()))));
::std::unique_ptr<AST::ExprWithoutBlock> expr = NULL;
if (not_a_block)
@@ -10965,8 +10889,7 @@ Parser::parse_path_based_stmt_or_expr (
// otherwise, expression
return ExprOrStmt (::std::move (expr));
}
- case LEFT_PAREN:
- {
+ case LEFT_PAREN: {
// assume struct expr tuple (as struct-enum disambiguation requires name
// lookup) again, make statement if final ';'
::std::unique_ptr<AST::StructExprTuple> struct_expr
@@ -10993,8 +10916,7 @@ Parser::parse_path_based_stmt_or_expr (
// otherwise, expression
return ExprOrStmt (::std::move (struct_expr));
}
- default:
- {
+ default: {
// assume path - make statement if final ';'
// lexer.skip_token();
@@ -11067,8 +10989,7 @@ Parser::parse_struct_expr_field ()
return ::std::unique_ptr<AST::StructExprFieldIdentifier> (
new AST::StructExprFieldIdentifier (::std::move (ident)));
}
- case INT_LITERAL:
- {
+ case INT_LITERAL: {
// parse tuple index field
int index = atoi (t->get_str ().c_str ());
lexer.skip_token ();
@@ -11478,21 +11399,21 @@ Parser::null_denotation_NEW (const_TokenPtr tok,
switch (tok->get_id ())
{
- /*case IDENTIFIER: {
- // when encountering identifier, lookup in scope
- SymbolPtr s = scope.lookup(tok->get_str());
- if (s == NULL) {
- rust_error_at(tok->get_locus(), "variable '%s' not declared in the
- current scope", tok->get_str().c_str());
+ /*case IDENTIFIER: {
+ // when encountering identifier, lookup in scope
+ SymbolPtr s = scope.lookup(tok->get_str());
+ if (s == NULL) {
+ rust_error_at(tok->get_locus(), "variable '%s' not declared in the
+ current scope", tok->get_str().c_str());
- return Tree::error();
- }
- // expression is just its VAR_DECL that was stored in the Symbol at
- declaration return Tree(s->get_tree_decl(), tok->get_locus());
- }*/
- // symbol table must be created in semantic analysis pass, so can't use this
- case IDENTIFIER:
- {
+ return Tree::error();
+ }
+ // expression is just its VAR_DECL that was stored in the Symbol at
+ declaration return Tree(s->get_tree_decl(), tok->get_locus());
+ }*/
+ // symbol table must be created in semantic analysis pass, so can't use
+ // this
+ case IDENTIFIER: {
// DEBUG
fprintf (stderr, "beginning null denotation identifier handling\n");
@@ -11512,15 +11433,14 @@ Parser::null_denotation_NEW (const_TokenPtr tok,
// macro
return parse_macro_invocation_partial (::std::move (path),
::std::move (outer_attrs));
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
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 (3)->get_id ()))));
/* definitely not a block:
* path '{' ident ','
@@ -11598,12 +11518,11 @@ Parser::null_denotation_NEW (const_TokenPtr tok,
}
gcc_unreachable ();
}
- // FIXME: delegate to parse_literal_expr instead? would have to rejig tokens
- // and whatever.
- // FIXME: could also be path expression (and hence macro expression,
- // struct/enum expr)
- case LEFT_ANGLE:
- {
+ // FIXME: delegate to parse_literal_expr instead? would have to rejig
+ // tokens and whatever.
+ // FIXME: could also be path expression (and hence macro expression,
+ // struct/enum expr)
+ case LEFT_ANGLE: {
// qualified path
// HACK: add outer attrs to path
AST::QualifiedPathInExpression path
@@ -11633,8 +11552,7 @@ Parser::null_denotation_NEW (const_TokenPtr tok,
case FALSE_LITERAL:
return ::std::unique_ptr<AST::LiteralExpr> (
new AST::LiteralExpr ("false", AST::Literal::BOOL, tok->get_locus ()));
- case LEFT_PAREN:
- { // have to parse whole expression if inside brackets
+ case LEFT_PAREN: { // have to parse whole expression if inside brackets
/* recursively invoke parse_expression with lowest priority possible as
* it it were a top-level expression. */
/*AST::Expr* expr = parse_expr();
@@ -11652,24 +11570,23 @@ Parser::null_denotation_NEW (const_TokenPtr tok,
return parse_grouped_or_tuple_expr (::std::move (outer_attrs), true);
}
- /*case PLUS: { // unary plus operator
- // invoke parse_expr recursively with appropriate priority, etc. for
- below AST::Expr* expr = parse_expr(LBP_UNARY_PLUS);
+ /*case PLUS: { // unary plus operator
+ // invoke parse_expr recursively with appropriate priority, etc. for
+ below AST::Expr* expr = parse_expr(LBP_UNARY_PLUS);
- if (expr == NULL)
- return NULL;
- // can only apply to integer and float expressions
- if (expr->get_type() != integer_type_node || expr->get_type() !=
- float_type_node) { rust_error_at(tok->get_locus(), "operand of unary plus
- must be int or float but it is %s", print_type(expr->get_type())); return
- NULL;
- }
+ if (expr == NULL)
+ return NULL;
+ // can only apply to integer and float expressions
+ if (expr->get_type() != integer_type_node || expr->get_type() !=
+ float_type_node) { rust_error_at(tok->get_locus(), "operand of unary plus
+ must be int or float but it is %s", print_type(expr->get_type())); return
+ NULL;
+ }
- return Tree(expr, tok->get_locus());
- }*/
- // Rust has no unary plus operator
- case MINUS:
- { // unary minus
+ return Tree(expr, tok->get_locus());
+ }*/
+ // Rust has no unary plus operator
+ case MINUS: { // unary minus
ParseRestrictions entered_from_unary;
entered_from_unary.entered_from_unary = true;
::std::unique_ptr<AST::Expr> expr
@@ -11694,8 +11611,7 @@ Parser::null_denotation_NEW (const_TokenPtr tok,
new AST::NegationExpr (::std::move (expr), AST::NegationExpr::NEGATE,
::std::move (outer_attrs), tok->get_locus ()));
}
- case EXCLAM:
- { // logical or bitwise not
+ case EXCLAM: { // logical or bitwise not
ParseRestrictions entered_from_unary;
entered_from_unary.entered_from_unary = true;
::std::unique_ptr<AST::Expr> expr
@@ -11719,8 +11635,7 @@ Parser::null_denotation_NEW (const_TokenPtr tok,
new AST::NegationExpr (::std::move (expr), AST::NegationExpr::NOT,
::std::move (outer_attrs), tok->get_locus ()));
}
- case ASTERISK:
- {
+ case ASTERISK: {
// pointer dereference only - HACK: as struct expressions should always
// be value expressions, cannot be dereferenced
ParseRestrictions entered_from_unary;
@@ -11735,8 +11650,7 @@ Parser::null_denotation_NEW (const_TokenPtr tok,
::std::move (outer_attrs),
tok->get_locus ()));
}
- case AMP:
- {
+ case AMP: {
// (single) "borrow" expression - shared (mutable) or immutable
::std::unique_ptr<AST::Expr> expr = NULL;
bool is_mut_borrow = false;
@@ -11766,8 +11680,7 @@ Parser::null_denotation_NEW (const_TokenPtr tok,
new AST::BorrowExpr (::std::move (expr), is_mut_borrow, false,
::std::move (outer_attrs), tok->get_locus ()));
}
- case LOGICAL_AND:
- {
+ case LOGICAL_AND: {
// (double) "borrow" expression - shared (mutable) or immutable
::std::unique_ptr<AST::Expr> expr = NULL;
bool is_mut_borrow = false;
@@ -11794,8 +11707,7 @@ Parser::null_denotation_NEW (const_TokenPtr tok,
new AST::BorrowExpr (::std::move (expr), is_mut_borrow, true,
::std::move (outer_attrs), tok->get_locus ()));
}
- case SCOPE_RESOLUTION:
- {
+ 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 "
@@ -11806,8 +11718,7 @@ Parser::null_denotation_NEW (const_TokenPtr tok,
case SELF_ALIAS:
case DOLLAR_SIGN:
case CRATE:
- case SUPER:
- {
+ case SUPER: {
// DEBUG
fprintf (stderr, "beginning null denotation "
"self/self-alias/dollar/crate/super handling\n");
@@ -11839,8 +11750,7 @@ Parser::null_denotation_NEW (const_TokenPtr tok,
// macro
return parse_macro_invocation_partial (::std::move (path),
::std::move (outer_attrs));
- case LEFT_CURLY:
- {
+ case LEFT_CURLY: {
// struct/enum expr struct
fprintf (stderr, "can_be_struct_expr: %s\n",
restrictions.can_be_struct_expr ? "true" : "false");
@@ -11851,7 +11761,7 @@ Parser::null_denotation_NEW (const_TokenPtr tok,
|| (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 (3)->get_id ()))));
if (!restrictions.can_be_struct_expr && !not_a_block)
{
@@ -11942,9 +11852,8 @@ Parser::left_denotation (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
switch (tok->get_id ())
{
- // FIXME: allow for outer attributes to be applied
- case QUESTION_MARK:
- {
+ // FIXME: allow for outer attributes to be applied
+ case QUESTION_MARK: {
Location left_locus = left->get_locus_slow ();
// error propagation expression - unary postfix
return ::std::unique_ptr<AST::ErrorPropagationExpr> (
@@ -12108,8 +12017,7 @@ Parser::left_denotation (const_TokenPtr tok, ::std::unique_ptr<AST::Expr> left,
"found scope resolution operator in left denotation "
"function - this should probably be handled elsewhere.");
return NULL;
- case DOT:
- {
+ case DOT: {
// field expression or method call - relies on parentheses after next
// identifier or await if token after is "await" (unary postfix) or
// tuple index if token after is a decimal int literal
@@ -13222,8 +13130,7 @@ Parser::parse_struct_expr_struct_partial (
/* technically this would give a struct base-only struct, but this
* algorithm should work too. As such, AST type not happening. */
case IDENTIFIER:
- case INT_LITERAL:
- {
+ case INT_LITERAL: {
// struct with struct expr fields
// parse struct expr fields
@@ -13504,8 +13411,7 @@ Parser::parse_closure_expr_pratt (const_TokenPtr tok,
case OR:
// no parameters, don't skip token
break;
- case PIPE:
- {
+ case PIPE: {
// actually may have parameters
// don't skip token
const_TokenPtr t = lexer.peek_token ();
@@ -13687,10 +13593,8 @@ Parser::debug_dump_lex_output ()
// Parses crate and dumps AST to stderr, recursively.
void
-Parser::debug_dump_ast_output ()
+Parser::debug_dump_ast_output (AST::Crate &crate)
{
- AST::Crate crate = parse_crate ();
-
// print crate "as string", which then calls each item as string, etc.
fprintf (stderr, "%s", crate.as_string ().c_str ());
}
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 5bc62d3..5abfba6 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -556,7 +556,7 @@ public:
// Dumps all lexer output.
void debug_dump_lex_output ();
- void debug_dump_ast_output ();
+ void debug_dump_ast_output (AST::Crate &crate);
private:
// The lexer associated with the parser.
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 8e9e4a3..b0cfca2 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -9,769 +9,922 @@
#include "rust-lex.h"
#include "rust-parse.h"
+#include "rust-resolution.h"
#include "rust-target.h"
#include <algorithm>
-extern Linemap* rust_get_linemap();
+extern Linemap *
+rust_get_linemap ();
namespace Rust {
- // Simple wrapper for FILE* that simplifies destruction.
- struct RAIIFile {
- FILE* file;
-
- RAIIFile(const char* filename) : file(fopen(filename, "r")) {}
-
- ~RAIIFile() {
- fclose(file);
- }
- };
-
- // Implicitly enable a target_feature (and recursively enable dependencies).
- void Session::implicitly_enable_feature(::std::string feature_name) {
- // TODO: is this really required since features added would be complete via target spec?
-
- if (!options.target_data.has_key_value_pair("target_data", feature_name)) {
- // if feature has dependencies, enable them
- if (feature_name == "aes") {
- implicitly_enable_feature("sse2");
- } else if (feature_name == "avx") {
- implicitly_enable_feature("sse4.2");
- } else if (feature_name == "avx2") {
- implicitly_enable_feature("avx");
- } else if (feature_name == "fma") {
- implicitly_enable_feature("avx");
- } else if (feature_name == "pclmulqdq") {
- implicitly_enable_feature("sse2");
- } else if (feature_name == "sha") {
- implicitly_enable_feature("sse2");
- } else if (feature_name == "sse2") {
- implicitly_enable_feature("sse");
- } else if (feature_name == "sse3") {
- implicitly_enable_feature("sse2");
- } else if (feature_name == "sse4.1") {
- implicitly_enable_feature("sse3");
- } else if (feature_name == "sse4.2") {
- implicitly_enable_feature("sse4.1");
- } else if (feature_name == "ssse3") {
- implicitly_enable_feature("sse3");
- }
-
- options.target_data.insert_key_value_pair("target_feature", ::std::move(feature_name));
- }
+// Simple wrapper for FILE* that simplifies destruction.
+struct RAIIFile
+{
+ FILE *file;
+
+ RAIIFile (const char *filename) : file (fopen (filename, "r")) {}
+
+ ~RAIIFile () { fclose (file); }
+};
+
+// Implicitly enable a target_feature (and recursively enable dependencies).
+void
+Session::implicitly_enable_feature (::std::string feature_name)
+{
+ // TODO: is this really required since features added would be complete via
+ // target spec?
+
+ if (!options.target_data.has_key_value_pair ("target_data", feature_name))
+ {
+ // if feature has dependencies, enable them
+ if (feature_name == "aes")
+ {
+ implicitly_enable_feature ("sse2");
+ }
+ else if (feature_name == "avx")
+ {
+ implicitly_enable_feature ("sse4.2");
+ }
+ else if (feature_name == "avx2")
+ {
+ implicitly_enable_feature ("avx");
+ }
+ else if (feature_name == "fma")
+ {
+ implicitly_enable_feature ("avx");
+ }
+ else if (feature_name == "pclmulqdq")
+ {
+ implicitly_enable_feature ("sse2");
+ }
+ else if (feature_name == "sha")
+ {
+ implicitly_enable_feature ("sse2");
+ }
+ else if (feature_name == "sse2")
+ {
+ implicitly_enable_feature ("sse");
+ }
+ else if (feature_name == "sse3")
+ {
+ implicitly_enable_feature ("sse2");
+ }
+ else if (feature_name == "sse4.1")
+ {
+ implicitly_enable_feature ("sse3");
+ }
+ else if (feature_name == "sse4.2")
+ {
+ implicitly_enable_feature ("sse4.1");
+ }
+ else if (feature_name == "ssse3")
+ {
+ implicitly_enable_feature ("sse3");
+ }
+
+ options.target_data.insert_key_value_pair ("target_feature",
+ ::std::move (feature_name));
}
+}
- // Meant to enable all target features. As this will be done by target hook, this method's
- // deprecated.
- void Session::enable_features() {
- bool has_target_crt_static = false;
- const char* target = "PLACEHOLDER";
-
- fprintf(stderr, "ERROR: Somewhere in call chain Session::enable_features is called.\n");
-
- if (has_target_crt_static) {
- // enable "crt-static" attribute
- }
-
- /* TODO: do this via target hook. have one for each target that implicitly enables the
- * features for that platform. Would probably have to make custom target hook. */
-
- /*
- if (target == "x86" || target == "x86_64") {
- if (TARGET_ISA_AES) {
- // enable aes, implicitly enable sse2
- implicitly_enable_feature("aes");
- }
-
- if (TARGET_ISA_AVX) {
- // enable avx, implicitly enable sse4.2
- implicitly_enable_feature("sse4.2");
- }
-
- if (TARGET_ISA_AVX2) {
- // enable avx2, implicitly enable avx
- implicitly_enable_feature("avx");
- }
-
- if (TARGET_ISA_BMI) {
- // enable bmi1
- implicitly_enable_feature("bmi1");
- }
-
- if (TARGET_ISA_BMI2) {
- // enable bmi2
- implicitly_enable_feature("bmi2");
- }
-
- if (TARGET_ISA_FMA) {
- // enable fma, implicitly enable avx
- implicitly_enable_feature("fma");
- }
-
- if (TARGET_ISA_FXSR) {
- // enable fxsr
- implicitly_enable_feature("fxsr");
- }
-
- if (TARGET_ISA_LZCNT) {
- // enable lzcnt
- implicitly_enable_feature("lzcnt");
- }
-
- if (TARGET_ISA_VPCLMULQDQ) {
- // enable pclmulqdq, implicitly enable sse2
- implicitly_enable_feature("pclmulqdq");
- }
-
- if (TARGET_ISA_POPCNT) {
- // enable popcnt
- implicitly_enable_feature("popcnt");
- }
-
- if (TARGET_ISA_RDRND) {
- // enable rdrand
- implicitly_enable_feature("rdrand");
- }
-
- if (TARGET_ISA_RDSEED) {
- // enable rdseed
- implicitly_enable_feature("rdseed");
- }
-
- if (TARGET_ISA_SHA) {
- // enable sha, implicitly enable sse2
- implicitly_enable_feature("sha");
- }
-
- if (TARGET_ISA_SSE) {
- // enable sse
- implicitly_enable_feature("sse");
- }
-
- if (TARGET_ISA_SSE2) {
- // enable sse2, implicitly enable sse
- implicitly_enable_feature("sse2");
- }
-
- if (TARGET_ISA_SSE3) {
- // enable sse3, implicitly enable sse2
- implicitly_enable_feature("sse3");
- }
-
- if (TARGET_ISA_SSE4_1) {
- // enable sse4.1, implicitly enable sse3
- implicitly_enable_feature("sse4.1");
- }
-
- if (TARGET_ISA_SSE4_2) {
- // enable sse4.2, implicitly enable sse4.1
- implicitly_enable_feature("sse4.2");
- }
-
- if (TARGET_ISA_SSSE3) {
- // enable ssse3, implicitly enable sse3
- implicitly_enable_feature("ssse3");
- }
-
- if (TARGET_ISA_XSAVE) {
- // enable xsave
- implicitly_enable_feature("xsave");
- }
-
- if (TARGET_ISA_XSAVEC) {
- // enable xsavec
- implicitly_enable_feature("xsavec");
- }
-
- if (TARGET_ISA_XSAVEOPT) {
- // enable xsaveopt
- implicitly_enable_feature("xsaveopt");
- }
-
- if (TARGET_ISA_XSAVES) {
- // enable xsaves
- implicitly_enable_feature("xsaves");
- }
- }
- options.target_data.features.shrink_to_fit();
- ::std::sort(options.target_data.features.begin(), options.target_data.features.end());*/
+// Meant to enable all target features. As this will be done by target hook,
+// this method's deprecated.
+void
+Session::enable_features ()
+{
+ bool has_target_crt_static = false;
+ const char *target = "PLACEHOLDER";
+
+ fprintf (
+ stderr,
+ "ERROR: Somewhere in call chain Session::enable_features is called.\n");
+
+ if (has_target_crt_static)
+ {
+ // enable "crt-static" attribute
}
- void Session::init() {
+ /* TODO: do this via target hook. have one for each target that implicitly
+ * enables the
+ * features for that platform. Would probably have to make custom target hook.
+ */
+
+ /*
+ if (target == "x86" || target == "x86_64") {
+ if (TARGET_ISA_AES) {
+ // enable aes, implicitly enable sse2
+ implicitly_enable_feature("aes");
+ }
+
+ if (TARGET_ISA_AVX) {
+ // enable avx, implicitly enable sse4.2
+ implicitly_enable_feature("sse4.2");
+ }
+
+ if (TARGET_ISA_AVX2) {
+ // enable avx2, implicitly enable avx
+ implicitly_enable_feature("avx");
+ }
+
+ if (TARGET_ISA_BMI) {
+ // enable bmi1
+ implicitly_enable_feature("bmi1");
+ }
+
+ if (TARGET_ISA_BMI2) {
+ // enable bmi2
+ implicitly_enable_feature("bmi2");
+ }
+
+ if (TARGET_ISA_FMA) {
+ // enable fma, implicitly enable avx
+ implicitly_enable_feature("fma");
+ }
+
+ if (TARGET_ISA_FXSR) {
+ // enable fxsr
+ implicitly_enable_feature("fxsr");
+ }
+
+ if (TARGET_ISA_LZCNT) {
+ // enable lzcnt
+ implicitly_enable_feature("lzcnt");
+ }
+
+ if (TARGET_ISA_VPCLMULQDQ) {
+ // enable pclmulqdq, implicitly enable sse2
+ implicitly_enable_feature("pclmulqdq");
+ }
+
+ if (TARGET_ISA_POPCNT) {
+ // enable popcnt
+ implicitly_enable_feature("popcnt");
+ }
+
+ if (TARGET_ISA_RDRND) {
+ // enable rdrand
+ implicitly_enable_feature("rdrand");
+ }
+
+ if (TARGET_ISA_RDSEED) {
+ // enable rdseed
+ implicitly_enable_feature("rdseed");
+ }
+
+ if (TARGET_ISA_SHA) {
+ // enable sha, implicitly enable sse2
+ implicitly_enable_feature("sha");
+ }
+
+ if (TARGET_ISA_SSE) {
+ // enable sse
+ implicitly_enable_feature("sse");
+ }
+
+ if (TARGET_ISA_SSE2) {
+ // enable sse2, implicitly enable sse
+ implicitly_enable_feature("sse2");
+ }
+
+ if (TARGET_ISA_SSE3) {
+ // enable sse3, implicitly enable sse2
+ implicitly_enable_feature("sse3");
+ }
+
+ if (TARGET_ISA_SSE4_1) {
+ // enable sse4.1, implicitly enable sse3
+ implicitly_enable_feature("sse4.1");
+ }
+
+ if (TARGET_ISA_SSE4_2) {
+ // enable sse4.2, implicitly enable sse4.1
+ implicitly_enable_feature("sse4.2");
+ }
+
+ if (TARGET_ISA_SSSE3) {
+ // enable ssse3, implicitly enable sse3
+ implicitly_enable_feature("ssse3");
+ }
+
+ if (TARGET_ISA_XSAVE) {
+ // enable xsave
+ implicitly_enable_feature("xsave");
+ }
+
+ if (TARGET_ISA_XSAVEC) {
+ // enable xsavec
+ implicitly_enable_feature("xsavec");
+ }
+
+ if (TARGET_ISA_XSAVEOPT) {
+ // enable xsaveopt
+ implicitly_enable_feature("xsaveopt");
+ }
+
+ if (TARGET_ISA_XSAVES) {
+ // enable xsaves
+ implicitly_enable_feature("xsaves");
+ }
+ }
+ options.target_data.features.shrink_to_fit();
+ ::std::sort(options.target_data.features.begin(),
+ options.target_data.features.end());*/
+}
+
+void
+Session::init ()
+{
#ifndef TARGET_RUST_OS_INFO
-# define TARGET_RUST_OS_INFO()
+#define TARGET_RUST_OS_INFO()
#endif
//#define builtin_rust_info(KEY, VALUE) rust_add_target_info (KEY, VALUE)
// might as well use c++ stuff
-#define builtin_rust_info(KEY, VALUE) options.target_data.insert_key_value_pair(KEY, VALUE)
-
- // initialise target hooks
- //targetrustm.rust_cpu_info();
- //targetrustm.rust_os_info();
- // ok, that's not working too well TODO - see if can salvage old implementation
- TARGET_RUST_CPU_INFO();
- TARGET_RUST_OS_INFO();
-
+#define builtin_rust_info(KEY, VALUE) \
+ options.target_data.insert_key_value_pair (KEY, VALUE)
+
+ // initialise target hooks
+ // targetrustm.rust_cpu_info();
+ // targetrustm.rust_os_info();
+ // ok, that's not working too well TODO - see if can salvage old
+ // implementation
+ TARGET_RUST_CPU_INFO ();
+ TARGET_RUST_OS_INFO ();
+
#undef builtin_rust_info
- // target-independent values that should exist in all targets
- options.target_data.insert_key_value_pair("target_pointer_width", std::to_string(POINTER_SIZE));
- options.target_data.insert_key_value_pair("target_endian", BYTES_BIG_ENDIAN ? "big" : "little");
+ // target-independent values that should exist in all targets
+ options.target_data.insert_key_value_pair ("target_pointer_width",
+ std::to_string (POINTER_SIZE));
+ options.target_data.insert_key_value_pair ("target_endian", BYTES_BIG_ENDIAN
+ ? "big"
+ : "little");
+
+ // TODO: find min atomic width and max atomic width
+ // from it, add atomic-related stuff for sizes 8, 16, 32, 64, and 128 (if
+ // inside bounds) in rustc, min atomic width is a known quantity (or 8 if not
+ // known), and max is also a known quantity (or is pointer size if not known)
+ // TODO: add atomic pointer if some criteria is satisfied
+
+ // TODO: find whether target has "atomic cas"
- // TODO: find min atomic width and max atomic width
- // from it, add atomic-related stuff for sizes 8, 16, 32, 64, and 128 (if inside bounds)
- // in rustc, min atomic width is a known quantity (or 8 if not known), and max is also a known quantity (or is pointer size if not known)
- // TODO: add atomic pointer if some criteria is satisfied
+ // add debug_assertions if enabled and proc_macro if crate type has it or
+ // whatever
- // TODO: find whether target has "atomic cas"
+ // derived values from hook
+ options.target_data.init_derived_values ();
+}
- // add debug_assertions if enabled and proc_macro if crate type has it or whatever
+// Initialise default options. Actually called before handle_option, unlike init
+// itself.
+void
+Session::init_options ()
+{
+ options.dump_option = CompileOptions::NO_DUMP;
+}
- // derived values from hook
- options.target_data.init_derived_values();
+// Handle option selection.
+bool
+Session::handle_option (
+ enum opt_code code, const char *arg, HOST_WIDE_INT value ATTRIBUTE_UNUSED,
+ int kind ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED,
+ const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
+{
+ // used to store whether results of various stuff are successful
+ bool ret = true;
+
+ // Handles options as listed in lang.opt.
+ switch (code)
+ {
+ case OPT_I:
+ // TODO: add search path
+ break;
+ case OPT_L:
+ // TODO: add library link path or something
+ break;
+ case OPT_frust_dump_:
+ // enable dump and return whether this was successful
+ if (arg != NULL)
+ {
+ ret = enable_dump (::std::string (arg));
+ }
+ else
+ {
+ ret = false;
+ }
+ break;
+ // no option handling for -o
+ default:
+ // return 1 to indicate option is valid
+ break;
}
- // Initialise default options. Actually called before handle_option, unlike init itself.
- void Session::init_options() {
- options.dump_option = CompileOptions::NO_DUMP;
+ return ret;
+}
+
+/* Enables a certain dump depending on the name passed in. Returns true if name
+ * is valid, false otherwise. */
+bool
+Session::enable_dump (::std::string arg)
+{
+ // FIXME: change dumping algorithm when new non-inhibiting dump system is
+ // created
+ if (arg == "all")
+ {
+ error_at (
+ UNKNOWN_LOCATION,
+ "dumping all is not supported as of now. choose 'lex' or 'parse'");
+ return false;
+ }
+ else if (arg == "lex")
+ {
+ options.dump_option = CompileOptions::LEXER_DUMP;
+ }
+ else if (arg == "parse")
+ {
+ options.dump_option = CompileOptions::PARSER_AST_DUMP;
+ }
+ else if (arg == "register_plugins")
+ {
+ options.dump_option = CompileOptions::REGISTER_PLUGINS_DUMP;
}
+ else if (arg == "injection")
+ {
+ options.dump_option = CompileOptions::INJECTION_DUMP;
+ }
+ else if (arg == "expansion")
+ {
+ options.dump_option = CompileOptions::EXPANSION_DUMP;
+ }
+ else if (arg == "name_resolution")
+ {
+ options.dump_option = CompileOptions::NAME_RESOLUTION_DUMP;
+ }
+ else if (arg == "target_options")
+ {
+ // special case - dump all target options, and then quit compilation
+ // nope, option handling called before init, so have to make this an
+ // actual compile option
+ // options.target_data.dump_target_options();
+ // return false;
+ options.dump_option = CompileOptions::TARGET_OPTION_DUMP;
+ }
+ else if (arg == "")
+ {
+ error_at (UNKNOWN_LOCATION,
+ "dump option was not given a name. choose 'lex' or 'parse'");
+ return false;
+ }
+ else
+ {
+ error_at (UNKNOWN_LOCATION,
+ "dump option '%s' was unrecognised. choose 'lex' or 'parse'",
+ arg.c_str ());
+ return false;
+ }
+ return true;
+}
- // Handle option selection.
- bool Session::handle_option(enum opt_code code, const char* arg,
- HOST_WIDE_INT value ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED,
- location_t loc ATTRIBUTE_UNUSED, const struct cl_option_handlers* handlers ATTRIBUTE_UNUSED) {
- // used to store whether results of various stuff are successful
- bool ret = true;
-
- // Handles options as listed in lang.opt.
- switch (code) {
- case OPT_I:
- // TODO: add search path
- break;
- case OPT_L:
- // TODO: add library link path or something
- break;
- case OPT_frust_dump_:
- // enable dump and return whether this was successful
- if (arg != NULL) {
- ret = enable_dump(::std::string(arg));
- } else {
- ret = false;
- }
- break;
- // no option handling for -o
- default:
- // return 1 to indicate option is valid
- break;
- }
-
- return ret;
+/* Actual main entry point for front-end. Called from langhook to parse files.
+ */
+void
+Session::parse_files (int num_files, const char **files)
+{
+ for (int i = 0; i < num_files; i++)
+ {
+ parse_file (files[i]);
}
+ // TODO: should semantic analysis be dealed with here? or per file? for now,
+ // per-file.
+}
+
+// Parses a single file with filename filename.
+void
+Session::parse_file (const char *filename)
+{
+ RAIIFile file_wrap (filename);
- /* Enables a certain dump depending on the name passed in. Returns true if name is valid, false
- * otherwise. */
- bool Session::enable_dump(::std::string arg) {
- // FIXME: change dumping algorithm when new non-inhibiting dump system is created
- if (arg == "all") {
- error_at(
- UNKNOWN_LOCATION, "dumping all is not supported as of now. choose 'lex' or 'parse'");
- return false;
- } else if (arg == "lex") {
- options.dump_option = CompileOptions::LEXER_DUMP;
- } else if (arg == "parse") {
- options.dump_option = CompileOptions::PARSER_AST_DUMP;
- } else if (arg == "register_plugins") {
- options.dump_option = CompileOptions::REGISTER_PLUGINS_DUMP;
- } else if (arg == "injection") {
- options.dump_option = CompileOptions::INJECTION_DUMP;
- } else if (arg == "expansion") {
- options.dump_option = CompileOptions::EXPANSION_DUMP;
- } else if (arg == "name_resolution") {
- options.dump_option = CompileOptions::NAME_RESOLUTION_DUMP;
- } else if (arg == "target_options") {
- // special case - dump all target options, and then quit compilation
- // nope, option handling called before init, so have to make this an actual compile option
- //options.target_data.dump_target_options();
- //return false;
- options.dump_option = CompileOptions::TARGET_OPTION_DUMP;
- } else if (arg == "") {
- error_at(UNKNOWN_LOCATION, "dump option was not given a name. choose 'lex' or 'parse'");
- return false;
- } else {
- error_at(UNKNOWN_LOCATION, "dump option '%s' was unrecognised. choose 'lex' or 'parse'",
- arg.c_str());
- return false;
- }
- return true;
+ if (file_wrap.file == NULL)
+ {
+ fatal_error (UNKNOWN_LOCATION, "cannot open filename %s: %m", filename);
}
- /* Actual main entry point for front-end. Called from langhook to parse files. */
- void Session::parse_files(int num_files, const char** files) {
- for (int i = 0; i < num_files; i++) {
- parse_file(files[i]);
- }
- // TODO: should semantic analysis be dealed with here? or per file? for now, per-file.
+ // parse file here
+ // create lexer and parser - these are file-specific and so aren't instance
+ // variables
+ Rust::Lexer lex (filename, file_wrap.file, rust_get_linemap ());
+ Rust::Parser parser (lex);
+
+ // generate crate from parser
+ auto parsed_crate = parser.parse_crate ();
+
+ // give a chance to give some debug
+ switch (options.dump_option)
+ {
+ case CompileOptions::LEXER_DUMP:
+ parser.debug_dump_lex_output ();
+ break;
+ case CompileOptions::PARSER_AST_DUMP:
+ parser.debug_dump_ast_output (parsed_crate);
+ break;
+ default:
+ break;
}
- // Parses a single file with filename filename.
- void Session::parse_file(const char* filename) {
- RAIIFile file_wrap(filename);
-
- if (file_wrap.file == NULL) {
- fatal_error(UNKNOWN_LOCATION, "cannot open filename %s: %m", filename);
- }
-
- // parse file here
- // create lexer and parser - these are file-specific and so aren't instance variables
- Rust::Lexer lex(filename, file_wrap.file, rust_get_linemap());
- Rust::Parser parser(lex);
-
- // determine parsing method from options
- /* FIXME: currently, the dump means that full compilation will not occur as of present. In
- * future, dumps should not inhibit full compilation. */
- switch (options.dump_option) {
- case CompileOptions::NO_DUMP:
- fatal_error(UNKNOWN_LOCATION, "no-dump parsing has not been enabled yet");
- return;
- case CompileOptions::LEXER_DUMP:
- parser.debug_dump_lex_output();
- return;
- case CompileOptions::PARSER_AST_DUMP:
- parser.debug_dump_ast_output();
- return;
- case CompileOptions::REGISTER_PLUGINS_DUMP:
- case CompileOptions::INJECTION_DUMP:
- case CompileOptions::EXPANSION_DUMP:
- case CompileOptions::NAME_RESOLUTION_DUMP:
- // will break later after more stages
- break;
- // semantic analysis when completed
- case CompileOptions::TARGET_OPTION_DUMP:
- options.target_data.dump_target_options();
- return;
- default:
- fatal_error(UNKNOWN_LOCATION, "unrecognised dump option: '%u'", options.dump_option);
- return;
- }
-
- /* basic pipeline:
- * - lex
- * - parse
- * - register plugins (dummy stage for now) - attribute injection? what is this?
- * (attribute injection is injecting attributes specified in command line into crate root)
- * - injection (some lint checks or dummy, register builtin macros, crate injection)
- * - expansion (expands all macros, maybe build test harness, AST validation, maybe macro
- * crate)
- * - name resolution (name resolution, maybe feature checking, maybe buffered lints)
- * TODO not done */
-
- // generate crate from parser
- AST::Crate parsed_crate = parser.parse_crate();
-
- fprintf(stderr, "\033[0;31mSUCCESSFULLY PARSED CRATE \n\033[0m");
-
- // register plugins pipeline stage
- register_plugins(parsed_crate);
- fprintf(stderr, "\033[0;31mSUCCESSFULLY REGISTERED PLUGINS \n\033[0m");
-
- if (options.dump_option == CompileOptions::REGISTER_PLUGINS_DUMP) {
- // TODO: what do I dump here?
- return;
- }
-
- // injection pipeline stage
- injection(parsed_crate);
- fprintf(stderr, "\033[0;31mSUCCESSFULLY FINISHED INJECTION \n\033[0m");
-
- if (options.dump_option == CompileOptions::INJECTION_DUMP) {
- // TODO: what do I dump here? injected crate names?
- return;
- }
-
- // expansion pipeline stage
- expansion(parsed_crate);
- fprintf(stderr, "\033[0;31mSUCCESSFULLY FINISHED EXPANSION \n\033[0m");
-
- if (options.dump_option == CompileOptions::EXPANSION_DUMP) {
- // TODO: what do I dump here? expanded macros? AST with expanded macros?
- return;
- }
-
- // name resolution pipeline stage
- name_resolution(parsed_crate);
- fprintf(stderr, "\033[0;31mSUCCESSFULLY FINISHED NAME RESOLUTION \n\033[0m");
-
- if (options.dump_option == CompileOptions::NAME_RESOLUTION_DUMP) {
- // TODO: what do I dump here? resolved names? AST with resolved names?
- return;
- }
+ /* basic pipeline:
+ * - lex
+ * - parse
+ * - register plugins (dummy stage for now) - attribute injection? what is
+ * this? (attribute injection is injecting attributes specified in command
+ * line into crate root)
+ * - injection (some lint checks or dummy, register builtin macros, crate
+ * injection)
+ * - expansion (expands all macros, maybe build test harness, AST validation,
+ * maybe macro crate)
+ * - name resolution (name resolution, maybe feature checking, maybe buffered
+ * lints)
+ * TODO not done */
+
+ fprintf (stderr, "\033[0;31mSUCCESSFULLY PARSED CRATE \n\033[0m");
+
+ // register plugins pipeline stage
+ register_plugins (parsed_crate);
+ fprintf (stderr, "\033[0;31mSUCCESSFULLY REGISTERED PLUGINS \n\033[0m");
+
+ if (options.dump_option == CompileOptions::REGISTER_PLUGINS_DUMP)
+ {
+ // TODO: what do I dump here?
+ return;
}
- // Checks whether 'cfg' attribute prevents compilation.
- bool check_cfg(const AST::Attribute& attr ATTRIBUTE_UNUSED) {
- // if "has sub items", and if 'cfg' attr, recursively call this on sub items?
+ // injection pipeline stage
+ injection (parsed_crate);
+ fprintf (stderr, "\033[0;31mSUCCESSFULLY FINISHED INJECTION \n\033[0m");
+
+ if (options.dump_option == CompileOptions::INJECTION_DUMP)
+ {
+ // TODO: what do I dump here? injected crate names?
+ return;
+ }
- // TODO: actually implement. assume true for now
+ // expansion pipeline stage
+ expansion (parsed_crate);
+ fprintf (stderr, "\033[0;31mSUCCESSFULLY FINISHED EXPANSION \n\033[0m");
- return true;
+ if (options.dump_option == CompileOptions::EXPANSION_DUMP)
+ {
+ // TODO: what do I dump here? expanded macros? AST with expanded macros?
+ return;
}
- // TODO: deprecated - don't use
- // Checks whether any 'cfg' attribute on the item prevents compilation of that item.
- bool check_item_cfg(::std::vector<AST::Attribute> attrs) {
- for (const auto& attr : attrs) {
- if (attr.get_path() == "cfg" && !check_cfg(attr)) {
- return false;
- }
- }
+ // name resolution pipeline stage
+ name_resolution (parsed_crate);
+ fprintf (stderr, "\033[0;31mSUCCESSFULLY FINISHED NAME RESOLUTION \n\033[0m");
- return true;
+ if (options.dump_option == CompileOptions::NAME_RESOLUTION_DUMP)
+ {
+ // TODO: what do I dump here? resolved names? AST with resolved names?
+ return;
}
- // TODO: deprecated - don't use
-
- // TODO: actually implement method
- void load_extern_crate(::std::string crate_name ATTRIBUTE_UNUSED) {}
- // TODO: deprecated - don't use
-
- // Parses up to the "load (external) crates" part of the frontend.
- // TODO: lots of this code is probably actually useful outside of dumping, so maybe split off
- // function
- void Session::debug_dump_load_crates(Parser& parser) {
- // parse crate as AST
- AST::Crate crate = parser.parse_crate();
-
- /* TODO: search through inner attrs and see whether any of those attr paths contain "no_core",
- * "no_std", "compiler_builtins". If so/not, save certain crate names. In these names, insert
- * items at beginning of crate items. This is crate injection. Also, inject prelude use decl
- * at beginning (first name is assumed to be prelude - prelude is a use decl automatically
- * generated to enable using Option and Copy without qualifying it or importing it via 'use'
- * manually) */
-
- ::std::vector< ::std::string> crate_names;
- for (const auto& item : crate.items) {
- // if item is extern crate, add name? to list of stuff ONLY IF config is checked
- // if item is module, iterate this loop inside it as well (recursive?) ONLY IF config is
- // checked
-
- // TODO: actually do the checks somewhere - probably in the items
-
- item->add_crate_name(crate_names);
- }
-
- /* loop through list of crate names/paths/whatever, attempting to load each one. save loaded
- * crates to a Session variable? Or save to current AST::Crate? */
- for (const auto& name : crate_names) {
- load_extern_crate(name /*, basename = ""?*/);
- }
- // for each loaded crate, load dependencies of it as well
+}
+
+// Checks whether 'cfg' attribute prevents compilation.
+bool
+check_cfg (const AST::Attribute &attr ATTRIBUTE_UNUSED)
+{
+ // if "has sub items", and if 'cfg' attr, recursively call this on sub items?
+
+ // TODO: actually implement. assume true for now
+
+ return true;
+}
+// TODO: deprecated - don't use
+
+// Checks whether any 'cfg' attribute on the item prevents compilation of that
+// item.
+bool
+check_item_cfg (::std::vector<AST::Attribute> attrs)
+{
+ for (const auto &attr : attrs)
+ {
+ if (attr.get_path () == "cfg" && !check_cfg (attr))
+ {
+ return false;
+ }
}
- // TODO: deprecated - don't use
- void Session::register_plugins(AST::Crate& crate ATTRIBUTE_UNUSED) {
- fprintf(stderr, "ran register_plugins (with no body)\n");
+ return true;
+}
+// TODO: deprecated - don't use
+
+// TODO: actually implement method
+void
+load_extern_crate (::std::string crate_name ATTRIBUTE_UNUSED)
+{}
+// TODO: deprecated - don't use
+
+// Parses up to the "load (external) crates" part of the frontend.
+// TODO: lots of this code is probably actually useful outside of dumping, so
+// maybe split off function
+void
+Session::debug_dump_load_crates (Parser &parser)
+{
+ // parse crate as AST
+ AST::Crate crate = parser.parse_crate ();
+
+ /* TODO: search through inner attrs and see whether any of those attr paths
+ * contain "no_core", "no_std", "compiler_builtins". If so/not, save certain
+ * crate names. In these names, insert items at beginning of crate items. This
+ * is crate injection. Also, inject prelude use decl at beginning (first name
+ * is assumed to be prelude - prelude is a use decl automatically generated to
+ * enable using Option and Copy without qualifying it or importing it via
+ * 'use' manually) */
+
+ ::std::vector< ::std::string> crate_names;
+ for (const auto &item : crate.items)
+ {
+ // if item is extern crate, add name? to list of stuff ONLY IF config is
+ // checked if item is module, iterate this loop inside it as well
+ // (recursive?) ONLY IF config is checked
+
+ // TODO: actually do the checks somewhere - probably in the items
+
+ item->add_crate_name (crate_names);
}
- // TODO: move somewhere else
- bool contains_name(const std::vector<AST::Attribute>& attrs, std::string name) {
- for (const auto& attr : attrs) {
- if (attr.get_path() == name) {
- return true;
- }
- }
+ /* loop through list of crate names/paths/whatever, attempting to load each
+ * one. save loaded crates to a Session variable? Or save to current
+ * AST::Crate? */
+ for (const auto &name : crate_names)
+ {
+ load_extern_crate (name /*, basename = ""?*/);
+ }
+ // for each loaded crate, load dependencies of it as well
+}
+// TODO: deprecated - don't use
+
+void
+Session::register_plugins (AST::Crate &crate ATTRIBUTE_UNUSED)
+{
+ fprintf (stderr, "ran register_plugins (with no body)\n");
+}
- return false;
+// TODO: move somewhere else
+bool
+contains_name (const std::vector<AST::Attribute> &attrs, std::string name)
+{
+ for (const auto &attr : attrs)
+ {
+ if (attr.get_path () == name)
+ {
+ return true;
+ }
}
- void Session::injection(AST::Crate& crate) {
- fprintf(stderr, "started injection\n");
-
- // lint checks in future maybe?
-
- // register builtin macros
- /* In rustc, builtin macros are divided into 3 categories depending on use - "bang" macros,
- * "attr" macros, and "derive" macros. I think the meanings of these categories should be
- * fairly obvious to anyone who has used rust. Builtin macro list by category: Bang
- * - asm
- * - assert
- * - cfg
- * - column
- * - compile_error
- * - concat_idents
- * - concat
- * - env
- * - file
- * - format_args_nl
- * - format_args
- * - global_asm
- * - include_bytes
- * - include_str
- * - include
- * - line
- * - log_syntax
- * - module_path
- * - option_env
- * - stringify
- * - trace_macros
- * Attr
- * - bench
- * - global_allocator
- * - test
- * - test_case
- * Derive
- * - Clone
- * - Copy
- * - Debug
- * - Default
- * - Eq
- * - Hash
- * - Ord
- * - PartialEq
- * - PartialOrd
- * - RustcDecodable
- * - RustcEncodable
- * rustc also has a "quote" macro that is defined differently and is supposedly not stable so
- * eh. */
- /* TODO: actually implement injection of these macros. In particular, derive macros, cfg, and
- * test should be prioritised since they seem to be used the most. */
-
- // crate injection
- ::std::vector< ::std::string> names;
- if (contains_name(crate.inner_attrs, "no_core")) {
- // no prelude
- injected_crate_name = "";
- } else if (contains_name(crate.inner_attrs, "no_std")) {
- names.push_back("core");
-
- if (!contains_name(crate.inner_attrs, "compiler_builtins")) {
- names.push_back("compiler_builtins");
- }
-
- injected_crate_name = "core";
- } else {
- names.push_back("std");
-
- injected_crate_name = "std";
- }
-
- // reverse iterate through names to insert crate items in "forward" order at beginning of
- // crate
- for (auto it = names.rbegin(); it != names.rend(); ++it) {
- // create "macro use" attribute for use on extern crate item to enable loading macros from
- // it
- AST::Attribute attr(AST::SimplePath::from_str("macro_use"), NULL);
-
- // create "extern crate" item with the name
- ::std::unique_ptr<AST::ExternCrate> extern_crate(
- new AST::ExternCrate(*it, AST::Visibility::create_error(), { ::std::move(attr) },
- Linemap::unknown_location()));
-
- // insert at beginning
- crate.items.insert(crate.items.begin(), ::std::move(extern_crate));
- }
-
- // create use tree path
- // prelude is injected_crate_name
- ::std::vector<AST::SimplePathSegment> segments
- = { AST::SimplePathSegment(injected_crate_name), AST::SimplePathSegment("prelude"),
- AST::SimplePathSegment("v1") };
- // create use tree and decl
- ::std::unique_ptr<AST::UseTreeGlob> use_tree(new AST::UseTreeGlob(
- AST::UseTreeGlob::PATH_PREFIXED, AST::SimplePath(::std::move(segments)), Location()));
- AST::Attribute prelude_attr(AST::SimplePath::from_str("prelude_import"), NULL);
- ::std::unique_ptr<AST::UseDeclaration> use_decl(new AST::UseDeclaration(::std::move(use_tree),
- AST::Visibility::create_error(), { ::std::move(prelude_attr) }, Location()));
-
- crate.items.insert(crate.items.begin(), ::std::move(use_decl));
-
- /* TODO: potentially add checking attribute crate type? I can't figure out what this does
- * currently comment says "Unconditionally collect crate types from attributes to make them
- * used", which presumably refers to checking the linkage info by "crate_type". It also seems
- * to ensure that an invalid crate type is not specified, so maybe just do that. Valid crate
- * types: bin lib dylib staticlib cdylib rlib proc-macro */
-
- fprintf(stderr, "finished injection\n");
+ return false;
+}
+
+void
+Session::injection (AST::Crate &crate)
+{
+ fprintf (stderr, "started injection\n");
+
+ // lint checks in future maybe?
+
+ // register builtin macros
+ /* In rustc, builtin macros are divided into 3 categories depending on use -
+ * "bang" macros, "attr" macros, and "derive" macros. I think the meanings of
+ * these categories should be fairly obvious to anyone who has used rust.
+ * Builtin macro list by category: Bang
+ * - asm
+ * - assert
+ * - cfg
+ * - column
+ * - compile_error
+ * - concat_idents
+ * - concat
+ * - env
+ * - file
+ * - format_args_nl
+ * - format_args
+ * - global_asm
+ * - include_bytes
+ * - include_str
+ * - include
+ * - line
+ * - log_syntax
+ * - module_path
+ * - option_env
+ * - stringify
+ * - trace_macros
+ * Attr
+ * - bench
+ * - global_allocator
+ * - test
+ * - test_case
+ * Derive
+ * - Clone
+ * - Copy
+ * - Debug
+ * - Default
+ * - Eq
+ * - Hash
+ * - Ord
+ * - PartialEq
+ * - PartialOrd
+ * - RustcDecodable
+ * - RustcEncodable
+ * rustc also has a "quote" macro that is defined differently and is
+ * supposedly not stable so eh. */
+ /* TODO: actually implement injection of these macros. In particular, derive
+ * macros, cfg, and
+ * test should be prioritised since they seem to be used the most. */
+
+ // crate injection
+ ::std::vector< ::std::string> names;
+ if (contains_name (crate.inner_attrs, "no_core"))
+ {
+ // no prelude
+ injected_crate_name = "";
}
+ else if (contains_name (crate.inner_attrs, "no_std"))
+ {
+ names.push_back ("core");
- void Session::expansion(AST::Crate& crate ATTRIBUTE_UNUSED) {
- fprintf(stderr, "started expansion\n");
+ if (!contains_name (crate.inner_attrs, "compiler_builtins"))
+ {
+ names.push_back ("compiler_builtins");
+ }
- // rustc has a modification to windows PATH temporarily here, which may end up being required
+ injected_crate_name = "core";
+ }
+ else
+ {
+ names.push_back ("std");
- // create macro expansion config?
- // if not, would at least have to configure recursion_limit
+ injected_crate_name = "std";
+ }
- // create extctxt? from parse session, cfg, and resolver?
- // expand by calling cxtctxt object's monotonic_expander's expand_crate method.
+ // reverse iterate through names to insert crate items in "forward" order at
+ // beginning of crate
+ for (auto it = names.rbegin (); it != names.rend (); ++it)
+ {
+ // create "macro use" attribute for use on extern crate item to enable
+ // loading macros from it
+ AST::Attribute attr (AST::SimplePath::from_str ("macro_use"), NULL);
+
+ // create "extern crate" item with the name
+ ::std::unique_ptr<AST::ExternCrate> extern_crate (
+ new AST::ExternCrate (*it, AST::Visibility::create_error (),
+ {::std::move (attr)},
+ Linemap::unknown_location ()));
+
+ // insert at beginning
+ crate.items.insert (crate.items.begin (), ::std::move (extern_crate));
+ }
- // error reporting - check unused macros, get missing fragment specifiers
+ // create use tree path
+ // prelude is injected_crate_name
+ ::std::vector<AST::SimplePathSegment> segments
+ = {AST::SimplePathSegment (injected_crate_name),
+ AST::SimplePathSegment ("prelude"), AST::SimplePathSegment ("v1")};
+ // create use tree and decl
+ ::std::unique_ptr<AST::UseTreeGlob> use_tree (
+ new AST::UseTreeGlob (AST::UseTreeGlob::PATH_PREFIXED,
+ AST::SimplePath (::std::move (segments)),
+ Location ()));
+ AST::Attribute prelude_attr (AST::SimplePath::from_str ("prelude_import"),
+ NULL);
+ ::std::unique_ptr<AST::UseDeclaration> use_decl (
+ new AST::UseDeclaration (::std::move (use_tree),
+ AST::Visibility::create_error (),
+ {::std::move (prelude_attr)}, Location ()));
+
+ crate.items.insert (crate.items.begin (), ::std::move (use_decl));
+
+ /* TODO: potentially add checking attribute crate type? I can't figure out
+ * what this does currently comment says "Unconditionally collect crate types
+ * from attributes to make them used", which presumably refers to checking the
+ * linkage info by "crate_type". It also seems to ensure that an invalid crate
+ * type is not specified, so maybe just do that. Valid crate types: bin lib
+ * dylib staticlib cdylib rlib proc-macro */
+
+ fprintf (stderr, "finished injection\n");
+}
- // build test harness
+void
+Session::expansion (AST::Crate &crate ATTRIBUTE_UNUSED)
+{
+ fprintf (stderr, "started expansion\n");
- // ast validation (also with proc macro decls)
+ // rustc has a modification to windows PATH temporarily here, which may end up
+ // being required
- // maybe create macro crate if not rustdoc
+ // create macro expansion config?
+ // if not, would at least have to configure recursion_limit
- fprintf(stderr, "finished expansion\n");
- }
+ // create extctxt? from parse session, cfg, and resolver?
+ // expand by calling cxtctxt object's monotonic_expander's expand_crate
+ // method.
- void Session::name_resolution(AST::Crate& crate ATTRIBUTE_UNUSED) {
- fprintf(stderr, "started name resolution\n");
+ // error reporting - check unused macros, get missing fragment specifiers
- fprintf(stderr, "finished name resolution\n");
- }
+ // build test harness
- void TargetOptions::dump_target_options() const {
- fprintf(stderr, "\033[0;31m--PREPARING TO DUMP ALL TARGET OPTIONS--\n\033[0m");
- for (const auto& pairs : features) {
- for (const auto& value : pairs.second) {
- fprintf(stderr, "%s: \"%s\"\n", pairs.first.c_str(), value.c_str());
- }
- if (pairs.second.empty()) {
- fprintf(stderr, "%s\n", pairs.first.c_str());
- }
- }
- if (features.empty()) {
- fprintf(stderr, "No target options available!\n");
- }
-
- fprintf(stderr, "\033[0;31m--END OF TARGET OPTION DUMP--\n\033[0m");
- }
+ // ast validation (also with proc macro decls)
- void TargetOptions::init_derived_values() {
- // enable derived values based on target families
- if (has_key_value_pair("target_family", "unix"))
- insert_key("unix");
- if (has_key_value_pair("target_family", "windows"))
- insert_key("windows");
-
- // implicitly enable features
- if (has_key_value_pair("target_feature", "aes"))
- enable_implicit_feature_reqs("aes");
- if (has_key_value_pair("target_feature", "avx"))
- enable_implicit_feature_reqs("sse4.2");
- if (has_key_value_pair("target_feature", "avx2"))
- enable_implicit_feature_reqs("avx");
- if (has_key_value_pair("target_feature", "pclmulqdq"))
- enable_implicit_feature_reqs("sse2");
- if (has_key_value_pair("target_feature", "sha"))
- enable_implicit_feature_reqs("sse2");
- if (has_key_value_pair("target_feature", "sse2"))
- enable_implicit_feature_reqs("sse");
- if (has_key_value_pair("target_feature", "sse3"))
- enable_implicit_feature_reqs("sse2");
- if (has_key_value_pair("target_feature", "sse4.1"))
- enable_implicit_feature_reqs("sse3");
- if (has_key_value_pair("target_feature", "sse4.2"))
- enable_implicit_feature_reqs("sse4.1");
- if (has_key_value_pair("target_feature", "ssse3"))
- enable_implicit_feature_reqs("sse3");
- }
+ // maybe create macro crate if not rustdoc
+
+ fprintf (stderr, "finished expansion\n");
+}
+
+void
+Session::name_resolution (AST::Crate &crate)
+{
+ fprintf (stderr, "started name resolution\n");
+ Analysis::TypeResolution::ResolveNamesAndTypes (crate);
+ fprintf (stderr, "finished name resolution\n");
+}
- void TargetOptions::enable_implicit_feature_reqs(std::string feature) {
- if (feature == "aes")
- enable_implicit_feature_reqs("sse2");
- else if (feature == "avx")
- enable_implicit_feature_reqs("sse4.2");
- else if (feature == "avx2")
- enable_implicit_feature_reqs("avx");
- else if (feature == "fma")
- enable_implicit_feature_reqs("avx");
- else if (feature == "pclmulqdq")
- enable_implicit_feature_reqs("sse2");
- else if (feature == "sha")
- enable_implicit_feature_reqs("sse2");
- else if (feature == "sse2")
- enable_implicit_feature_reqs("sse");
- else if (feature == "sse3")
- enable_implicit_feature_reqs("sse2");
- else if (feature == "sse4.1")
- enable_implicit_feature_reqs("sse3");
- else if (feature == "sse4.2")
- enable_implicit_feature_reqs("sse4.1");
- else if (feature == "ssse3")
- enable_implicit_feature_reqs("sse3");
-
- if (!has_key_value_pair("target_feature", feature))
- insert_key_value_pair("target_feature", feature);
+void
+TargetOptions::dump_target_options () const
+{
+ fprintf (stderr,
+ "\033[0;31m--PREPARING TO DUMP ALL TARGET OPTIONS--\n\033[0m");
+ for (const auto &pairs : features)
+ {
+ for (const auto &value : pairs.second)
+ {
+ fprintf (stderr, "%s: \"%s\"\n", pairs.first.c_str (),
+ value.c_str ());
+ }
+ if (pairs.second.empty ())
+ {
+ fprintf (stderr, "%s\n", pairs.first.c_str ());
+ }
}
+ if (features.empty ())
+ {
+ fprintf (stderr, "No target options available!\n");
+ }
+
+ fprintf (stderr, "\033[0;31m--END OF TARGET OPTION DUMP--\n\033[0m");
+}
- // NOTEs:
- /* mrustc compile pipeline:
- * - target load (pass target spec to parser?)
- * - parse (convert source to AST)
- * - load crates (load any explicitly mentioned extern crates [not all of them])
- * - expand (AST transformations from attributes and macros, loads remaining extern crates
- * [std/core and any triggered by macro expansion])
- * - implicit crates (test harness, allocator crate, panic crate)
- * - resolve use (annotate every 'use' item with source [supposedly handles nasty recursion])
- * - resolve index (generate index of visible items for every module [avoids recursion in next
- * pass])
- * - resolve absolute (resolve all paths into either variable names [types/values] or absolute
- * paths)
- * - HIR lower (convert modified AST to simpler HIR [both expressions and module tree])
- * - resolve type aliases (replace any usages of type aliases with actual type [except associated
- * types])
- * - resolve bind (iterate HIR tree and set binding annotations on all concrete types [avoids
- * path lookups later])
- * - resolve HIR markings (generate "markings" [e.g. for Copy/Send/Sync/...] for all types
- * - sort impls (small pass - sort impls into groups)
- * - resolve UFCS outer (determine source trait for all top-level <T>::Type [qualified] paths)
- * - resolve UFCS paths (do the same, but include for exprs this time. also normalises results of
- * previous pass [expanding known associated types])
- * - constant evaluate (evaluate all constants)
- * - typecheck outer (checks impls are sane)
- * - typecheck expressions (resolve and check types for all exprs)
- * - expand HIR annotate (annotate how exprs are used - used for closure extractions and
- * reborrows)
- * - expand HIR closures (extract closures into structs implementing Fn* traits)
- * - expand HIR vtables (generate vtables for types with dyn dispatch)
- * - expand HIR calls (converts method and callable calls into explicit function calls)
- * - expand HIR reborrows (apply reborrow rules [taking '&mut *v' instead of 'v'])
- * - expand HIR erasedtype (replace all erased types 'impl Trait' with the true type)
- * - typecheck expressions (validate - double check that previous passes haven't broke type
- * system rules)
- * - lower MIR (convert HIR exprs into a control-flow graph [MIR])
- * - MIR validate (check that the generated MIR is consistent)
- * - MIR cleanup (perform various transformations on MIR - replace reads of const items with the
- * item itself; convert casts to unsized types into 'MakeDst' operations)
- * - MIR optimise (perform various simple optimisations on the MIR - constant propagation, dead
- * code elimination, borrow elimination, some inlining)
- * - MIR validate PO (re-validate the MIR)
- * - MIR validate full (optionally: perform expensive state-tracking validation on MIR)
- * - trans enumerate (enumerate all items needed for code generation, primarily types used for
- * generics)
- * - trans auto impls (create magic trait impls as enumerated in previous pass)
- * - trans monomorph (generate monomorphised copies of all functions [with generics replaced with
- * real types])
- * - MIR optimise inline (run optimisation again, this time with full type info [primarily for
- * inlining])
- * - HIR serialise (write out HIR dump [module tree and generic/inline MIR])
- * - trans codegen (generate final output file: emit C source file and call C compiler) */
-
- /* rustc compile pipeline (basic, in way less detail):
- * - parse input (parse .rs to AST)
- * - name resolution, macro expansion, and configuration (process AST recursively, resolving
- * paths, expanding macros, processing #[cfg] nodes [i.e. maybe stripping stuff from AST])
- * - lower to HIR
- * - type check and other analyses (e.g. privacy checking)
- * - lower to MIR and post-processing (and do stuff like borrow checking)
- * - translation to LLVM IR and LLVM optimisations (produce the .o files)
- * - linking (link together .o files) */
-
- /* Pierced-together rustc compile pipeline (from source):
- * - parse input (parse file to crate)
- * - register plugins (attributes injection, set various options, register lints, load plugins)
- * - expansion/configure and expand (initial 'cfg' processing, 'loading compiler plugins',
- * syntax expansion, secondary 'cfg' expansion, synthesis of a test harness if required,
- * injection of any std lib dependency and prelude, and name resolution) - actually documented
- * inline
- * - seeming pierced-together order: pre-AST expansion lint checks, registering builtin
- * macros, crate injection, then expand all macros, then maybe build test harness, AST validation,
- * maybe create a macro crate (if not rustdoc), name resolution, complete gated feature
- * checking, add all buffered lints
- * - create global context (lower to HIR)
- * - analysis on global context (HIR optimisations? create MIR?)
- * - code generation
- * - link */
+void
+TargetOptions::init_derived_values ()
+{
+ // enable derived values based on target families
+ if (has_key_value_pair ("target_family", "unix"))
+ insert_key ("unix");
+ if (has_key_value_pair ("target_family", "windows"))
+ insert_key ("windows");
+
+ // implicitly enable features
+ if (has_key_value_pair ("target_feature", "aes"))
+ enable_implicit_feature_reqs ("aes");
+ if (has_key_value_pair ("target_feature", "avx"))
+ enable_implicit_feature_reqs ("sse4.2");
+ if (has_key_value_pair ("target_feature", "avx2"))
+ enable_implicit_feature_reqs ("avx");
+ if (has_key_value_pair ("target_feature", "pclmulqdq"))
+ enable_implicit_feature_reqs ("sse2");
+ if (has_key_value_pair ("target_feature", "sha"))
+ enable_implicit_feature_reqs ("sse2");
+ if (has_key_value_pair ("target_feature", "sse2"))
+ enable_implicit_feature_reqs ("sse");
+ if (has_key_value_pair ("target_feature", "sse3"))
+ enable_implicit_feature_reqs ("sse2");
+ if (has_key_value_pair ("target_feature", "sse4.1"))
+ enable_implicit_feature_reqs ("sse3");
+ if (has_key_value_pair ("target_feature", "sse4.2"))
+ enable_implicit_feature_reqs ("sse4.1");
+ if (has_key_value_pair ("target_feature", "ssse3"))
+ enable_implicit_feature_reqs ("sse3");
}
+
+void
+TargetOptions::enable_implicit_feature_reqs (std::string feature)
+{
+ if (feature == "aes")
+ enable_implicit_feature_reqs ("sse2");
+ else if (feature == "avx")
+ enable_implicit_feature_reqs ("sse4.2");
+ else if (feature == "avx2")
+ enable_implicit_feature_reqs ("avx");
+ else if (feature == "fma")
+ enable_implicit_feature_reqs ("avx");
+ else if (feature == "pclmulqdq")
+ enable_implicit_feature_reqs ("sse2");
+ else if (feature == "sha")
+ enable_implicit_feature_reqs ("sse2");
+ else if (feature == "sse2")
+ enable_implicit_feature_reqs ("sse");
+ else if (feature == "sse3")
+ enable_implicit_feature_reqs ("sse2");
+ else if (feature == "sse4.1")
+ enable_implicit_feature_reqs ("sse3");
+ else if (feature == "sse4.2")
+ enable_implicit_feature_reqs ("sse4.1");
+ else if (feature == "ssse3")
+ enable_implicit_feature_reqs ("sse3");
+
+ if (!has_key_value_pair ("target_feature", feature))
+ insert_key_value_pair ("target_feature", feature);
+}
+
+// NOTEs:
+/* mrustc compile pipeline:
+ * - target load (pass target spec to parser?)
+ * - parse (convert source to AST)
+ * - load crates (load any explicitly mentioned extern crates [not all of
+ * them])
+ * - expand (AST transformations from attributes and macros, loads remaining
+ * extern crates [std/core and any triggered by macro expansion])
+ * - implicit crates (test harness, allocator crate, panic crate)
+ * - resolve use (annotate every 'use' item with source [supposedly handles
+ * nasty recursion])
+ * - resolve index (generate index of visible items for every module [avoids
+ * recursion in next pass])
+ * - resolve absolute (resolve all paths into either variable names
+ * [types/values] or absolute paths)
+ * - HIR lower (convert modified AST to simpler HIR [both expressions and
+ * module tree])
+ * - resolve type aliases (replace any usages of type aliases with actual type
+ * [except associated types])
+ * - resolve bind (iterate HIR tree and set binding annotations on all concrete
+ * types [avoids path lookups later])
+ * - resolve HIR markings (generate "markings" [e.g. for Copy/Send/Sync/...]
+ * for all types
+ * - sort impls (small pass - sort impls into groups)
+ * - resolve UFCS outer (determine source trait for all top-level <T>::Type
+ * [qualified] paths)
+ * - resolve UFCS paths (do the same, but include for exprs this time. also
+ * normalises results of previous pass [expanding known associated types])
+ * - constant evaluate (evaluate all constants)
+ * - typecheck outer (checks impls are sane)
+ * - typecheck expressions (resolve and check types for all exprs)
+ * - expand HIR annotate (annotate how exprs are used - used for closure
+ * extractions and reborrows)
+ * - expand HIR closures (extract closures into structs implementing Fn*
+ * traits)
+ * - expand HIR vtables (generate vtables for types with dyn dispatch)
+ * - expand HIR calls (converts method and callable calls into explicit
+ * function calls)
+ * - expand HIR reborrows (apply reborrow rules [taking '&mut *v' instead of
+ * 'v'])
+ * - expand HIR erasedtype (replace all erased types 'impl Trait' with the true
+ * type)
+ * - typecheck expressions (validate - double check that previous passes
+ * haven't broke type system rules)
+ * - lower MIR (convert HIR exprs into a control-flow graph [MIR])
+ * - MIR validate (check that the generated MIR is consistent)
+ * - MIR cleanup (perform various transformations on MIR - replace reads of
+ * const items with the item itself; convert casts to unsized types into
+ * 'MakeDst' operations)
+ * - MIR optimise (perform various simple optimisations on the MIR - constant
+ * propagation, dead code elimination, borrow elimination, some inlining)
+ * - MIR validate PO (re-validate the MIR)
+ * - MIR validate full (optionally: perform expensive state-tracking validation
+ * on MIR)
+ * - trans enumerate (enumerate all items needed for code generation, primarily
+ * types used for generics)
+ * - trans auto impls (create magic trait impls as enumerated in previous pass)
+ * - trans monomorph (generate monomorphised copies of all functions [with
+ * generics replaced with real types])
+ * - MIR optimise inline (run optimisation again, this time with full type info
+ * [primarily for inlining])
+ * - HIR serialise (write out HIR dump [module tree and generic/inline MIR])
+ * - trans codegen (generate final output file: emit C source file and call C
+ * compiler) */
+
+/* rustc compile pipeline (basic, in way less detail):
+ * - parse input (parse .rs to AST)
+ * - name resolution, macro expansion, and configuration (process AST
+ * recursively, resolving paths, expanding macros, processing #[cfg] nodes [i.e.
+ * maybe stripping stuff from AST])
+ * - lower to HIR
+ * - type check and other analyses (e.g. privacy checking)
+ * - lower to MIR and post-processing (and do stuff like borrow checking)
+ * - translation to LLVM IR and LLVM optimisations (produce the .o files)
+ * - linking (link together .o files) */
+
+/* Pierced-together rustc compile pipeline (from source):
+ * - parse input (parse file to crate)
+ * - register plugins (attributes injection, set various options, register
+ * lints, load plugins)
+ * - expansion/configure and expand (initial 'cfg' processing, 'loading
+ * compiler plugins', syntax expansion, secondary 'cfg' expansion, synthesis of
+ * a test harness if required, injection of any std lib dependency and prelude,
+ * and name resolution) - actually documented inline
+ * - seeming pierced-together order: pre-AST expansion lint checks,
+ * registering builtin macros, crate injection, then expand all macros, then
+ * maybe build test harness, AST validation, maybe create a macro crate (if not
+ * rustdoc), name resolution, complete gated feature checking, add all buffered
+ * lints
+ * - create global context (lower to HIR)
+ * - analysis on global context (HIR optimisations? create MIR?)
+ * - code generation
+ * - link */
+} // namespace Rust