blob: 84cd99c8b86baffb3a9ab3878c96bd355cabb59e [file] [log] [blame]
// 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.
#ifndef VERIBLE_VERILOG_CST_DECLARATION_H_
#define VERIBLE_VERILOG_CST_DECLARATION_H_
// See comment at the top
// verilog/CST/verilog_treebuilder_utils.h that explains use
// of std::forward in Make* helper functions.
#include <utility>
#include <vector>
#include "common/analysis/syntax_tree_search.h"
#include "common/text/concrete_syntax_leaf.h"
#include "common/text/concrete_syntax_tree.h"
#include "common/text/symbol.h"
#include "common/text/symbol_ptr.h" // IWYU pragma: export
#include "common/text/token_info.h"
#include "common/text/tree_utils.h"
#include "verilog/CST/verilog_nonterminals.h"
namespace verilog {
// Interface for consistently building a type-id-dimensions tuple.
template <typename T1, typename T2, typename T3>
verible::SymbolPtr MakeTypeIdDimensionsTuple(T1 &&type, T2 &&id,
T3 &&unpacked_dimensions) {
verible::CheckSymbolAsNode(*type.get(), NodeEnum::kDataType);
// id can be qualified or unqualified
verible::CheckOptionalSymbolAsNode(unpacked_dimensions,
NodeEnum::kUnpackedDimensions);
return verible::MakeTaggedNode(NodeEnum::kDataTypeImplicitBasicIdDimensions,
std::forward<T1>(type), std::forward<T2>(id),
std::forward<T3>(unpacked_dimensions));
}
// Interface for consistently building a type-id tuple (no unpacked dimensions).
// TODO(fangism): combine this with MakeTypeIdDimensionsTuple above?
// That would be one fewer auxiliary CST node type.
template <typename T1, typename T2>
verible::SymbolPtr MakeTypeIdTuple(T1 &&type, T2 &&id) {
verible::CheckSymbolAsNode(*type.get(), NodeEnum::kDataType);
verible::CheckSymbolAsNode(*id.get(), NodeEnum::kUnqualifiedId);
return verible::MakeTaggedNode(NodeEnum::kTypeIdentifierId,
std::forward<T1>(type), std::forward<T2>(id));
}
// Repacks output of MakeTypeIdDimensionsTuple into a type-id pair.
verible::SymbolPtr RepackReturnTypeId(verible::SymbolPtr type_id_tuple);
// Maps lexical token enum to corresponding syntax tree node.
// Useful for syntax tree construction.
NodeEnum DeclarationKeywordToNodeEnum(const verible::Symbol &);
template <typename T1, typename T2>
verible::SymbolPtr MakeInstantiationBase(T1 &&type, T2 &&decl_list) {
verible::CheckSymbolAsNode(*type.get(), NodeEnum::kInstantiationType);
// decl_list could contain either instantiations or variable declarations
return verible::MakeTaggedNode(NodeEnum::kInstantiationBase,
std::forward<T1>(type),
std::forward<T2>(decl_list));
}
// Interface for consistently building a data declaration.
template <typename T1, typename T2, typename T3>
verible::SymbolPtr MakeDataDeclaration(T1 &&qualifiers, T2 &&inst_base,
T3 &&semicolon) {
verible::CheckOptionalSymbolAsNode(qualifiers, NodeEnum::kQualifierList);
if (inst_base.get()->Tag().tag == (int)NodeEnum::kFunctionCall) {
return verible::ExtendNode(std::forward<T2>(inst_base),
std::forward<T3>(semicolon));
}
verible::CheckSymbolAsNode(*inst_base.get(), NodeEnum::kInstantiationBase);
verible::CheckSymbolAsLeaf(*semicolon.get(), ';');
return verible::MakeTaggedNode(
NodeEnum::kDataDeclaration, std::forward<T1>(qualifiers),
std::forward<T2>(inst_base), std::forward<T3>(semicolon));
}
// Find all data declarations.
std::vector<verible::TreeSearchMatch> FindAllDataDeclarations(
const verible::Symbol &);
std::vector<verible::TreeSearchMatch> FindAllNetVariables(
const verible::Symbol &);
std::vector<verible::TreeSearchMatch> FindAllRegisterVariables(
const verible::Symbol &);
std::vector<verible::TreeSearchMatch> FindAllGateInstances(
const verible::Symbol &);
std::vector<verible::TreeSearchMatch> FindAllVariableDeclarationAssignment(
const verible::Symbol &);
// For a given data declaration (includes module instantiation), returns the
// subtree containing qualifiers. e.g. from "const foo bar, baz;",
// this returns the subtree spanning "const". Returns nullptr if there
// are no qualifiers.
const verible::SyntaxTreeNode *GetQualifiersOfDataDeclaration(
const verible::Symbol &data_declaration);
// For a given data declaration (includes module instantiation), returns the
// subtree containing the type. e.g. from "foo #(...) bar..., baz...;",
// this returns the subtree spanning "foo #(...)".
// It is possible for type to be implicit, in which case, the node
// will be an empty subtree.
const verible::SyntaxTreeNode *GetInstantiationTypeOfDataDeclaration(
const verible::Symbol &data_declaration);
// For a given data declaration returns the node spanning param declaration
// list. e.g "module_type #(N)" return the node for "#(N)".
const verible::SyntaxTreeNode *GetParamListFromDataDeclaration(
const verible::Symbol &);
// For a given data declaration (includes module instantiation), returns the
// subtree containing instances. e.g. from "foo bar..., baz...;",
// this returns the subtree spanning "bar..., baz..."
const verible::SyntaxTreeNode *GetInstanceListFromDataDeclaration(
const verible::Symbol &data_declaration);
// For a given module gate instance return the node spanning the paren group.
// e.g "module_type instance(a, b, c)" return the node spanning "(a, b, c)".
const verible::SyntaxTreeNode *GetParenGroupFromModuleInstantiation(
const verible::Symbol &gate_instance);
// For a given gate instance subtree returns the TokenInfo of the module name.
// e.g. "bar b1();" returns TokenInfo for "b1".
const verible::TokenInfo *GetModuleInstanceNameTokenInfoFromGateInstance(
const verible::Symbol &);
// For a given register variable subtree returns the TokenInfo of the instance
// name. e.g. "int b1;" returns TokenInfo for "b1".
const verible::TokenInfo *GetInstanceNameTokenInfoFromRegisterVariable(
const verible::Symbol &);
// For a given node tagged with kVariableDeclarationAssign return the
// unqualified id inside that node.
// e.g from "int x" or "logic x" or "bit x" return the leaf spanning "x".
const verible::SyntaxTreeLeaf *
GetUnqualifiedIdFromVariableDeclarationAssignment(
const verible::Symbol &variable_declaration_assign);
// Extracts kExpression node from nodes tagged with kVariableDeclarationAssign
// (if exists).
const verible::SyntaxTreeNode *
GetTrailingExpressionFromVariableDeclarationAssign(
const verible::Symbol &variable_declaration_assign);
// Extracts kExpression node from nodes tagged with kRegisterVariable (if
// exists).
const verible::SyntaxTreeNode *GetTrailingExpressionFromRegisterVariable(
const verible::Symbol &register_variable);
// Extracts kPackedDimensions node from nodes tagged with kDataDeclaration.
const verible::SyntaxTreeNode *GetPackedDimensionFromDataDeclaration(
const verible::Symbol &data_declaration);
// Extracts kUnpackedDimensions node from nodes tagged with kRegisterVariable.
const verible::SyntaxTreeNode *GetUnpackedDimensionFromRegisterVariable(
const verible::Symbol &register_variable);
// Extracts kUnpackedDimensions node from nodes tagged with
// kVariableDeclarationAssign.
const verible::SyntaxTreeNode *
GetUnpackedDimensionFromVariableDeclarationAssign(
const verible::Symbol &variable_declaration_assign);
// Returns the type name from data declaration (if exists).
// The type can be inside a node tagged with kDataType or kLocalRoot.
// e.g module_type m(); return "module_type".
// e.g some_type m; return "some_type".
const verible::Symbol *GetTypeIdentifierFromDataDeclaration(
const verible::Symbol &);
// Returns the node tagged with kStructType, kEnumType or kUnionType from node
// tagged with kDataDeclaration.
const verible::SyntaxTreeNode *GetStructOrUnionOrEnumTypeFromDataDeclaration(
const verible::Symbol &);
} // namespace verilog
#endif // VERIBLE_VERILOG_CST_DECLARATION_H_