| // Copyright 2017-2020 The Verible Authors. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #include "verilog/CST/declaration.h" | |
| #include <map> | |
| #include <memory> | |
| #include <utility> | |
| #include "common/text/concrete_syntax_leaf.h" | |
| #include "common/text/concrete_syntax_tree.h" | |
| #include "common/text/constants.h" | |
| #include "common/text/symbol.h" | |
| #include "common/text/token_info.h" | |
| #include "common/text/tree_utils.h" | |
| #include "common/util/container_util.h" | |
| #include "verilog/CST/identifier.h" | |
| #include "verilog/CST/verilog_matchers.h" | |
| #include "verilog/CST/verilog_nonterminals.h" | |
| #include "verilog/parser/verilog_token_enum.h" | |
| namespace verilog { | |
| using verible::Symbol; | |
| using verible::SymbolPtr; | |
| using verible::SyntaxTreeNode; | |
| using verible::container::FindWithDefault; | |
| SymbolPtr RepackReturnTypeId(SymbolPtr type_id_tuple) { | |
| auto& node = CheckSymbolAsNode(*type_id_tuple, | |
| NodeEnum::kDataTypeImplicitBasicIdDimensions); | |
| return verible::MakeNode(std::move(node[0]) /* type */, | |
| std::move(node[1]) /* id */); | |
| // Discard unpacked dimensions node[2], should be nullptr, and not | |
| // syntactically valid. | |
| } | |
| NodeEnum DeclarationKeywordToNodeEnum(const Symbol& symbol) { | |
| static const auto* node_map = new std::map<verilog_tokentype, NodeEnum>{ | |
| {TK_module, NodeEnum::kModuleDeclaration}, | |
| {TK_macromodule, NodeEnum::kMacroModuleDeclaration}, | |
| {TK_program, NodeEnum::kProgramDeclaration}, | |
| {TK_interface, NodeEnum::kInterfaceDeclaration}, | |
| }; | |
| return FindWithDefault( | |
| *node_map, | |
| verilog_tokentype(verible::SymbolCastToLeaf(symbol).get().token_enum()), | |
| NodeEnum(verible::kUntagged)); | |
| } | |
| std::vector<verible::TreeSearchMatch> FindAllDataDeclarations( | |
| const Symbol& root) { | |
| return SearchSyntaxTree(root, NodekDataDeclaration()); | |
| } | |
| std::vector<verible::TreeSearchMatch> FindAllNetVariables(const Symbol& root) { | |
| return SearchSyntaxTree(root, NodekNetVariable()); | |
| } | |
| std::vector<verible::TreeSearchMatch> FindAllRegisterVariables( | |
| const Symbol& root) { | |
| return SearchSyntaxTree(root, NodekRegisterVariable()); | |
| } | |
| std::vector<verible::TreeSearchMatch> FindAllGateInstances(const Symbol& root) { | |
| return SearchSyntaxTree(root, NodekGateInstance()); | |
| } | |
| // Don't want to expose kInstantiationBase because it is an artificial grouping. | |
| static const SyntaxTreeNode& GetInstantiationBaseFromDataDeclaration( | |
| const Symbol& data_declaration) { | |
| return GetSubtreeAsNode(data_declaration, NodeEnum::kDataDeclaration, 1, | |
| NodeEnum::kInstantiationBase); | |
| } | |
| const SyntaxTreeNode* GetQualifiersOfDataDeclaration( | |
| const Symbol& data_declaration) { | |
| const auto* quals = | |
| GetSubtreeAsSymbol(data_declaration, NodeEnum::kDataDeclaration, 0); | |
| return verible::CheckOptionalSymbolAsNode(quals, NodeEnum::kQualifierList); | |
| } | |
| const SyntaxTreeNode& GetTypeOfDataDeclaration(const Symbol& data_declaration) { | |
| return GetSubtreeAsNode( | |
| GetInstantiationBaseFromDataDeclaration(data_declaration), | |
| NodeEnum::kInstantiationBase, 0); | |
| } | |
| const SyntaxTreeNode& GetInstanceListFromDataDeclaration( | |
| const Symbol& data_declaration) { | |
| return GetSubtreeAsNode( | |
| GetInstantiationBaseFromDataDeclaration(data_declaration), | |
| NodeEnum::kInstantiationBase, 1); | |
| } | |
| const SyntaxTreeNode& GetReferenceCallBaseFromInstantiationType( | |
| const Symbol& instantiation_type) { | |
| return GetSubtreeAsNode(instantiation_type, NodeEnum::kInstantiationType, 0); | |
| } | |
| const SyntaxTreeNode& GetReferenceFromReferenceCallBase( | |
| const Symbol& reference_call_base) { | |
| return GetSubtreeAsNode(reference_call_base, NodeEnum::kReferenceCallBase, 0); | |
| } | |
| const SyntaxTreeNode& GetLocalRootFromReference(const Symbol& reference) { | |
| return GetSubtreeAsNode(reference, NodeEnum::kReference, 0); | |
| } | |
| const SyntaxTreeNode& GetUnqualifiedIdFromLocalRoot(const Symbol& local_root) { | |
| return GetSubtreeAsNode(local_root, NodeEnum::kLocalRoot, 0); | |
| } | |
| const verible::TokenInfo& GetTypeTokenInfoFromDataDeclaration( | |
| const verible::Symbol& data_declaration) { | |
| const SyntaxTreeNode& instantiation_type = | |
| GetTypeOfDataDeclaration(data_declaration); | |
| const SyntaxTreeNode& reference_call_base = | |
| GetReferenceCallBaseFromInstantiationType(instantiation_type); | |
| const SyntaxTreeNode& reference = | |
| GetReferenceFromReferenceCallBase(reference_call_base); | |
| const SyntaxTreeNode& local_root = GetLocalRootFromReference(reference); | |
| const SyntaxTreeNode& unqualified_id = | |
| GetUnqualifiedIdFromLocalRoot(local_root); | |
| const verible::SyntaxTreeLeaf* instance_symbol_identifier = | |
| GetIdentifier(unqualified_id); | |
| return instance_symbol_identifier->get(); | |
| } | |
| const verible::TokenInfo& GetModuleInstanceNameTokenInfoFromGateInstance( | |
| const verible::Symbol& gate_instance) { | |
| const verible::SyntaxTreeLeaf& instance_name = | |
| GetSubtreeAsLeaf(gate_instance, NodeEnum::kGateInstance, 0); | |
| return instance_name.get(); | |
| } | |
| const verible::TokenInfo& GetInstanceNameTokenInfoFromRegisterVariable( | |
| const verible::Symbol& regiseter_variable) { | |
| const verible::SyntaxTreeLeaf& instance_name = | |
| GetSubtreeAsLeaf(regiseter_variable, NodeEnum::kRegisterVariable, 0); | |
| return instance_name.get(); | |
| } | |
| } // namespace verilog |