diff --git a/common/text/concrete_syntax_tree.h b/common/text/concrete_syntax_tree.h index c0981177a..0ba4fae42 100644 --- a/common/text/concrete_syntax_tree.h +++ b/common/text/concrete_syntax_tree.h @@ -74,6 +74,8 @@ class SyntaxTreeNode final : public Symbol { // This container needs to provide a random access [] operator and // rbegin(), rend() iterators. using ChildContainer = std::vector; + using ConstRange = iterator_range; + using MutableRange = iterator_range; explicit SyntaxTreeNode(const int tag = kUntagged) : tag_(tag) {} @@ -128,9 +130,17 @@ class SyntaxTreeNode final : public Symbol { size_t size() const { return children_.size(); } bool empty() const { return children_.empty(); } - // TODO(hzeller): return ranges for these. Only used in range-loops. - const ChildContainer &children() const { return children_; } + ConstRange children() const { + return ConstRange(children_.cbegin(), children_.cend()); + } + +#if 0 // TODO: to switch, find solution for pop_back() in PruneTreeFromRight() + MutableRange mutable_children() { + return MutableRange(children_.begin(), children_.end()); + } +#else ChildContainer &mutable_children() { return children_; } +#endif // Compares this node to an arbitrary symbol using the compare_tokens // function. diff --git a/common/text/tree_utils.cc b/common/text/tree_utils.cc index 37bcad5f4..a192704b9 100644 --- a/common/text/tree_utils.cc +++ b/common/text/tree_utils.cc @@ -58,7 +58,7 @@ const SyntaxTreeLeaf *GetRightmostLeaf(const Symbol &symbol) { const auto &node = SymbolCastToNode(symbol); - for (const auto &child : reversed_view(node.children())) { + for (const auto &child : const_reversed_view(node.children())) { if (child != nullptr) { const auto *leaf = GetRightmostLeaf(*child); if (leaf != nullptr) { diff --git a/common/util/iterator_adaptors.h b/common/util/iterator_adaptors.h index 07e6e1e9a..39b469f6b 100644 --- a/common/util/iterator_adaptors.h +++ b/common/util/iterator_adaptors.h @@ -50,6 +50,14 @@ reversed_view(T &t) { // in std:: when compiling with C++14 or newer. } +template +verible::iterator_range< + std::reverse_iterator::type>> +const_reversed_view(const T &t) { + return make_range(verible::make_reverse_iterator(t.end()), + verible::make_reverse_iterator(t.begin())); +} + // Given a const_iterator and a mutable iterator to the original mutable // container, return the corresponding mutable iterator (without resorting to // const_cast). diff --git a/verilog/CST/type.cc b/verilog/CST/type.cc index 087ee757d..6ca644cf5 100644 --- a/verilog/CST/type.cc +++ b/verilog/CST/type.cc @@ -48,12 +48,11 @@ SymbolPtr ReinterpretReferenceAsDataTypePackedDimensions( } verible::SyntaxTreeNode &base(verible::CheckSymbolAsNode( *ABSL_DIE_IF_NULL(reference_call_base), NodeEnum::kReference)); - auto &children(base.mutable_children()); - CHECK(!children.empty()); + CHECK(!base.empty()); - Symbol &local_root(*children.front()); + Symbol &local_root(*base.front()); if (local_root.Kind() != verible::SymbolKind::kNode || - verible::SymbolCastToNode(*children.back()) + verible::SymbolCastToNode(*base.back()) .MatchesTag(NodeEnum::kHierarchyExtension)) { // function call -like syntax can never be interpreted as a type, // so return the whole subtree unmodified. @@ -71,9 +70,14 @@ SymbolPtr ReinterpretReferenceAsDataTypePackedDimensions( verible::SyntaxTreeNode &local_root_with_extension_node( verible::SymbolCastToNode(*local_root_with_extension)); local_root_with_extension_node.AppendChild( - ReinterpretLocalRootAsType(*children.front())); + ReinterpretLocalRootAsType(*base.front())); - for (auto &child : verible::make_range(++children.begin(), children.end())) { + bool is_first = true; + for (auto &child : base.mutable_children()) { + if (is_first) { + is_first = false; + continue; + } // Each child could be a call-extension or an index (bit-select/slice). // Only [] indices are valid, any others are syntax errors. // We discard syntax errors for now, but in the future should retain these @@ -171,7 +175,7 @@ const verible::Symbol *GetBaseTypeFromDataType( if (local_root->Tag().tag != (int)NodeEnum::kLocalRoot) return local_root; CHECK(!local_root->empty()); - auto &children = local_root->children(); + const auto &children = local_root->children(); verible::Symbol *last_child = nullptr; for (auto &child : children) { if (child != nullptr && child->Kind() == verible::SymbolKind::kNode) { diff --git a/verilog/tools/kythe/indexing_facts_tree_extractor.cc b/verilog/tools/kythe/indexing_facts_tree_extractor.cc index 9f25fb8b0..2d4c72484 100644 --- a/verilog/tools/kythe/indexing_facts_tree_extractor.cc +++ b/verilog/tools/kythe/indexing_facts_tree_extractor.cc @@ -908,9 +908,12 @@ void IndexingFactsTreeExtractor::ExtractModuleInstantiation( GetSubtreeAsSymbol(*type, NodeEnum::kInstantiationType, 0); if (reference->Tag().tag == (int)NodeEnum::kReference && SymbolCastToNode(*reference).size() > 1) { - const auto &children = SymbolCastToNode(*reference).children(); - for (auto &child : - verible::make_range(++children.begin(), children.end())) { + bool is_first = true; + for (const auto &child : SymbolCastToNode(*reference).children()) { + if (is_first) { // skip the first one. + is_first = false; + continue; + } if (child->Tag().tag == (int)NodeEnum::kHierarchyExtension) { Visit(verible::SymbolCastToNode(*child)); } @@ -1327,9 +1330,12 @@ void IndexingFactsTreeExtractor::ExtractFunctionOrTaskCall( *reference_call_base, NodeEnum::kReferenceCallBase, 0); if (reference->Tag().tag == (int)NodeEnum::kReference) { if (SymbolCastToNode(*reference).size() > 1) { - const auto &children = SymbolCastToNode(*reference).children(); - for (auto &child : - verible::make_range(++children.begin(), children.end())) { + bool is_first = true; + for (const auto &child : SymbolCastToNode(*reference).children()) { + if (is_first) { // skip the first one + is_first = false; + continue; + } if (child->Tag().tag == (int)NodeEnum::kHierarchyExtension) { Visit(verible::SymbolCastToNode(*child)); }