mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 20:01:22 -05:00
gccrs: early-name-resolver: Add simple macro name resolution
This name resolver performs the same macro name resolution as what was previously done by the AttrVisitor visitor and macro expander. It also resolves macro expressions in builtin-macros properly, as well as expanded AST nodes when necessary. gcc/rust/ChangeLog: * Make-lang.in: Compile early name resolver. * expand/rust-attribute-visitor.cc (AttrVisitor::visit): Move macro name resolution. * expand/rust-macro-builtins.cc (try_expand_macro_expression): Run ENR when recursively expanding macros. * expand/rust-macro-expand.cc (MacroExpander::expand_invoc): No longer perform name resolution in `expand_invoc`. * expand/rust-macro-expand.h (struct MacroExpander): Keep ENR within MacroExpander. * rust-session-manager.cc (Session::expansion): Run ENR. * resolve/rust-early-name-resolver.cc: New file. * resolve/rust-early-name-resolver.h: New file.
This commit is contained in:
@@ -93,6 +93,7 @@ GRS_OBJS = \
|
||||
rust/rust-ast-lower-base.o \
|
||||
rust/rust-ast-lower-pattern.o \
|
||||
rust/rust-ast-lower-item.o \
|
||||
rust/rust-early-name-resolver.o \
|
||||
rust/rust-name-resolver.o \
|
||||
rust/rust-ast-resolve.o \
|
||||
rust/rust-ast-resolve-base.o \
|
||||
|
||||
@@ -2877,16 +2877,6 @@ AttrVisitor::visit (AST::MacroRulesDefinition &rules_def)
|
||||
rules_def.mark_for_strip ();
|
||||
return;
|
||||
}
|
||||
|
||||
// I don't think any macro rules can be stripped in any way
|
||||
|
||||
auto path = Resolver::CanonicalPath::new_seg (rules_def.get_node_id (),
|
||||
rules_def.get_rule_name ());
|
||||
expander.resolver->get_macro_scope ().insert (path, rules_def.get_node_id (),
|
||||
rules_def.get_locus ());
|
||||
expander.mappings->insert_macro_def (&rules_def);
|
||||
rust_debug_loc (rules_def.get_locus (), "inserting macro def: [%s]",
|
||||
path.get ().c_str ());
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "rust-macro-invoc-lexer.h"
|
||||
#include "rust-lex.h"
|
||||
#include "rust-parse.h"
|
||||
#include "rust-early-name-resolver.h"
|
||||
#include "rust-attribute-visitor.h"
|
||||
|
||||
namespace Rust {
|
||||
@@ -70,9 +71,11 @@ try_expand_macro_expression (AST::Expr *expr, MacroExpander *expander)
|
||||
{
|
||||
rust_assert (expander);
|
||||
|
||||
auto vis = Rust::AttrVisitor (*expander);
|
||||
expr->accept_vis (vis);
|
||||
return expander->take_expanded_fragment (vis);
|
||||
auto attr_visitor = Rust::AttrVisitor (*expander);
|
||||
auto early_name_resolver = Resolver::EarlyNameResolver ();
|
||||
expr->accept_vis (early_name_resolver);
|
||||
expr->accept_vis (attr_visitor);
|
||||
return expander->take_expanded_fragment (attr_visitor);
|
||||
}
|
||||
|
||||
/* Expand and then extract a string literal from the macro */
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "rust-diagnostics.h"
|
||||
#include "rust-parse.h"
|
||||
#include "rust-attribute-visitor.h"
|
||||
#include "rust-early-name-resolver.h"
|
||||
|
||||
namespace Rust {
|
||||
AST::ASTFragment
|
||||
@@ -138,32 +139,17 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc, bool has_semicolon)
|
||||
// - else is unreachable
|
||||
// - derive container macro - unreachable
|
||||
|
||||
// lookup the rules for this macro
|
||||
NodeId resolved_node = UNKNOWN_NODEID;
|
||||
NodeId source_node = UNKNOWN_NODEID;
|
||||
if (has_semicolon)
|
||||
source_node = invoc.get_macro_node_id ();
|
||||
else
|
||||
source_node = invoc.get_pattern_node_id ();
|
||||
auto seg
|
||||
= Resolver::CanonicalPath::new_seg (source_node,
|
||||
invoc_data.get_path ().as_string ());
|
||||
|
||||
bool found = resolver->get_macro_scope ().lookup (seg, &resolved_node);
|
||||
if (!found)
|
||||
{
|
||||
rust_error_at (invoc.get_locus (), "unknown macro: [%s]",
|
||||
seg.get ().c_str ());
|
||||
return;
|
||||
}
|
||||
auto fragment = AST::ASTFragment::create_error ();
|
||||
invoc_data.set_expander (this);
|
||||
|
||||
// lookup the rules
|
||||
AST::MacroRulesDefinition *rules_def = nullptr;
|
||||
bool ok = mappings->lookup_macro_def (resolved_node, &rules_def);
|
||||
rust_assert (ok);
|
||||
bool ok = mappings->lookup_macro_invocation (invoc, &rules_def);
|
||||
|
||||
auto fragment = AST::ASTFragment::create_error ();
|
||||
invoc_data.set_expander (this);
|
||||
// If there's no rule associated with the invocation, we can simply return
|
||||
// early. The early name resolver will have already emitted an error.
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
if (rules_def->is_builtin ())
|
||||
fragment
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "rust-ast.h"
|
||||
#include "rust-macro.h"
|
||||
#include "rust-hir-map.h"
|
||||
#include "rust-early-name-resolver.h"
|
||||
#include "rust-name-resolver.h"
|
||||
#include "rust-macro-invoc-lexer.h"
|
||||
|
||||
@@ -323,10 +324,13 @@ struct MacroExpander
|
||||
AST::ASTFragment old_fragment = std::move (expanded_fragment);
|
||||
auto accumulator = std::vector<AST::SingleASTNode> ();
|
||||
expanded_fragment = AST::ASTFragment::create_error ();
|
||||
auto early_name_resolver = Resolver::EarlyNameResolver ();
|
||||
|
||||
for (auto &node : old_fragment.get_nodes ())
|
||||
{
|
||||
expansion_depth++;
|
||||
|
||||
node.accept_vis (early_name_resolver);
|
||||
node.accept_vis (vis);
|
||||
// we'll decide the next move according to the outcome of the macro
|
||||
// expansion
|
||||
|
||||
1087
gcc/rust/resolve/rust-early-name-resolver.cc
Normal file
1087
gcc/rust/resolve/rust-early-name-resolver.cc
Normal file
File diff suppressed because it is too large
Load Diff
210
gcc/rust/resolve/rust-early-name-resolver.h
Normal file
210
gcc/rust/resolve/rust-early-name-resolver.h
Normal file
@@ -0,0 +1,210 @@
|
||||
// Copyright (C) 2020-2022 Free Software Foundation, Inc.
|
||||
|
||||
// This file is part of GCC.
|
||||
|
||||
// GCC is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation; either version 3, or (at your option) any later
|
||||
// version.
|
||||
|
||||
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with GCC; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef RUST_EARLY_NAME_RESOLVER_H
|
||||
#define RUST_EARLY_NAME_RESOLVER_H
|
||||
|
||||
#include "rust-name-resolver.h"
|
||||
#include "rust-system.h"
|
||||
#include "rust-ast.h"
|
||||
#include "rust-ast-visitor.h"
|
||||
|
||||
namespace Rust {
|
||||
namespace Resolver {
|
||||
|
||||
class EarlyNameResolver : public AST::ASTVisitor
|
||||
{
|
||||
public:
|
||||
EarlyNameResolver ();
|
||||
|
||||
void go (AST::Crate &crate);
|
||||
|
||||
private:
|
||||
Resolver &resolver;
|
||||
Analysis::Mappings &mappings;
|
||||
|
||||
/**
|
||||
* Early name-resolve generic args, which can be macro invocations
|
||||
*/
|
||||
void resolve_generic_args (AST::GenericArgs &generic_args);
|
||||
|
||||
/**
|
||||
* Early name-resolve a qualified path type, which can contain macro
|
||||
* invocations
|
||||
*/
|
||||
void resolve_qualified_path_type (AST::QualifiedPathType &path);
|
||||
|
||||
virtual void visit (AST::Token &tok);
|
||||
virtual void visit (AST::DelimTokenTree &delim_tok_tree);
|
||||
virtual void visit (AST::AttrInputMetaItemContainer &input);
|
||||
virtual void visit (AST::IdentifierExpr &ident_expr);
|
||||
virtual void visit (AST::Lifetime &lifetime);
|
||||
virtual void visit (AST::LifetimeParam &lifetime_param);
|
||||
virtual void visit (AST::ConstGenericParam &const_param);
|
||||
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);
|
||||
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 (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 (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::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 (AST::MatchExpr &expr);
|
||||
virtual void visit (AST::AwaitExpr &expr);
|
||||
virtual void visit (AST::AsyncBlockExpr &expr);
|
||||
virtual void visit (AST::TypeParam ¶m);
|
||||
virtual void visit (AST::LifetimeWhereClauseItem &item);
|
||||
virtual void visit (AST::TypeBoundWhereClauseItem &item);
|
||||
virtual void visit (AST::Method &method);
|
||||
virtual void visit (AST::Module &module);
|
||||
virtual void visit (AST::ExternCrate &crate);
|
||||
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 (AST::ExternalStaticItem &item);
|
||||
virtual void visit (AST::ExternalFunctionItem &item);
|
||||
virtual void visit (AST::ExternBlock &block);
|
||||
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 ¯o_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);
|
||||
virtual void visit (AST::LiteralPattern &pattern);
|
||||
virtual void visit (AST::IdentifierPattern &pattern);
|
||||
virtual void visit (AST::WildcardPattern &pattern);
|
||||
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 (AST::StructPatternFieldTuplePat &field);
|
||||
virtual void visit (AST::StructPatternFieldIdentPat &field);
|
||||
virtual void visit (AST::StructPatternFieldIdent &field);
|
||||
virtual void visit (AST::StructPattern &pattern);
|
||||
virtual void visit (AST::TupleStructItemsNoRange &tuple_items);
|
||||
virtual void visit (AST::TupleStructItemsRange &tuple_items);
|
||||
virtual void visit (AST::TupleStructPattern &pattern);
|
||||
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);
|
||||
virtual void visit (AST::EmptyStmt &stmt);
|
||||
virtual void visit (AST::LetStmt &stmt);
|
||||
virtual void visit (AST::ExprStmtWithoutBlock &stmt);
|
||||
virtual void visit (AST::ExprStmtWithBlock &stmt);
|
||||
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);
|
||||
};
|
||||
|
||||
} // namespace Resolver
|
||||
} // namespace Rust
|
||||
|
||||
#endif // RUST_EARLY_NAME_RESOLVER_H
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "rust-imports.h"
|
||||
#include "rust-extern-crate.h"
|
||||
#include "rust-attributes.h"
|
||||
#include "rust-early-name-resolver.h"
|
||||
|
||||
#include "diagnostic.h"
|
||||
#include "input.h"
|
||||
@@ -805,6 +806,9 @@ Session::injection (AST::Crate &crate)
|
||||
void
|
||||
Session::expansion (AST::Crate &crate)
|
||||
{
|
||||
/* We need to name resolve macros and imports here */
|
||||
Resolver::EarlyNameResolver ().go (crate);
|
||||
|
||||
rust_debug ("started expansion");
|
||||
|
||||
/* rustc has a modification to windows PATH temporarily here, which may end
|
||||
|
||||
Reference in New Issue
Block a user