blob: fc96c3e0d3757a62ba76aee1dee116794f7437f4 [file] [log] [blame]
/*
Copyright 2019 Alain Dargelas
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.
*/
/*
* File: CompileClass.cpp
* Author: alain
*
* Created on June 7, 2018, 10:26 PM
*/
#include "SourceCompile/VObjectTypes.h"
#include "Design/VObject.h"
#include "Library/Library.h"
#include "Design/Signal.h"
#include "Design/FileContent.h"
#include "Design/ClockingBlock.h"
#include "SourceCompile/SymbolTable.h"
#include "ErrorReporting/Error.h"
#include "ErrorReporting/Location.h"
#include "ErrorReporting/Error.h"
#include "CommandLine/CommandLineParser.h"
#include "ErrorReporting/ErrorDefinition.h"
#include "ErrorReporting/ErrorContainer.h"
#include "SourceCompile/CompilationUnit.h"
#include "SourceCompile/PreprocessFile.h"
#include "SourceCompile/CompileSourceFile.h"
#include "SourceCompile/ParseFile.h"
#include "SourceCompile/Compiler.h"
#include "DesignCompile/CompileDesign.h"
#include "Testbench/ClassDefinition.h"
#include "DesignCompile/CompileClass.h"
using namespace SURELOG;
CompileClass::~CompileClass() {}
int FunctorCompileClass::operator()() const {
CompileClass* instance =
new CompileClass(m_compileDesign, m_class, m_design, m_symbols, m_errors);
instance->compile();
delete instance;
return true;
}
bool CompileClass::compile() {
FileContent* fC = m_class->m_fileContents[0];
NodeId nodeId = m_class->m_nodeIds[0];
std::string fileName = fC->getFileName(nodeId);
if (strstr(fileName.c_str(), "builtin.sv")) {
fileName = "builtin.sv";
}
Location loc(m_symbols->registerSymbol(fileName),
fC->Line(nodeId), 0,
m_symbols->registerSymbol(m_class->getName()));
Error err1(ErrorDefinition::COMP_COMPILE_CLASS, loc);
ErrorContainer* errors = new ErrorContainer(m_symbols);
errors->regiterCmdLine(
m_compileDesign->getCompiler()->getCommandLineParser());
errors->addError(err1);
errors->printMessage(
err1,
m_compileDesign->getCompiler()->getCommandLineParser()->muteStdout());
delete errors;
if (fC->getSize() == 0) return true;
// Package imports
std::vector<FileCNodeId> pack_imports;
// - Local file imports
for (auto import : fC->getObjects(VObjectType::slPackage_import_item)) {
pack_imports.push_back(import);
}
// - Parent container imports
DesignComponent* container = m_class->getContainer();
if (container) {
// FileCNodeId itself(container->getFileContents ()[0],
// container->getNodeIds ()[0]); pack_imports.push_back(itself);
for (auto import :
container->getObjects(VObjectType::slPackage_import_item)) {
pack_imports.push_back(import);
}
}
for (auto pack_import : pack_imports) {
FileContent* pack_fC = pack_import.fC;
NodeId pack_id = pack_import.nodeId;
m_helper.importPackage(m_class, m_design, pack_fC, pack_id);
}
compile_class_parameters_(fC, nodeId);
// This
DataType* thisdt =
new DataType(fC, nodeId, "this", VObjectType::slClass_declaration);
thisdt->setDefinition(m_class);
Property* prop = new Property(thisdt, fC, nodeId, 0, "this", false, false,
false, false, false);
m_class->insertProperty(prop);
VObject current = fC->Object(fC->getSize() - 2);
NodeId id = nodeId;
if (!id) return false;
std::stack<NodeId> stack;
stack.push(id);
bool inFunction_body_declaration = false;
bool inTask_body_declaration = false;
while (stack.size()) {
bool skipGuts = false;
id = stack.top();
stack.pop();
current = fC->Object(id);
VObjectType type = fC->Type(id);
switch (type) {
case VObjectType::slPackage_import_item: {
m_helper.importPackage(m_class, m_design, fC, id);
break;
}
case VObjectType::slClass_constructor_declaration: {
inFunction_body_declaration = true;
break;
}
case VObjectType::slFunction_body_declaration: {
inFunction_body_declaration = true;
break;
}
case VObjectType::slEndfunction: {
inFunction_body_declaration = false;
break;
}
case VObjectType::slTask_body_declaration: {
inTask_body_declaration = true;
break;
}
case VObjectType::slEndtask: {
inTask_body_declaration = false;
break;
}
case VObjectType::slClass_property:
if (inFunction_body_declaration || inTask_body_declaration) break;
compile_class_property_(fC, id);
break;
case VObjectType::slClass_constraint:
compile_class_constraint_(fC, id);
break;
case VObjectType::slClass_declaration:
if (id != nodeId) {
compile_class_declaration_(fC, id);
if (current.m_sibling) stack.push(current.m_sibling);
continue;
}
break;
case VObjectType::slCovergroup_declaration:
compile_covergroup_declaration_(fC, id);
break;
case VObjectType::slLocal_parameter_declaration:
compile_local_parameter_declaration_(fC, id);
break;
case VObjectType::slParameter_declaration:
compile_parameter_declaration_(fC, id);
break;
case VObjectType::slClass_method:
compile_class_method_(fC, id);
skipGuts = true;
break;
case VObjectType::slClass_type:
compile_class_type_(fC, id);
default:
break;
}
if (current.m_sibling) stack.push(current.m_sibling);
if (!skipGuts)
if (current.m_child) stack.push(current.m_child);
}
// Default constructor
DataType* returnType = new DataType();
FunctionMethod* method =
new FunctionMethod(m_class, fC, nodeId, "new", returnType, false, false,
false, false, false, false);
method->compile(m_helper);
Function* prevDef = m_class->getFunction("new");
if (!prevDef) {
m_class->insertFunction(method);
}
return true;
}
bool CompileClass::compile_class_property_(FileContent* fC, NodeId id) {
NodeId data_declaration = fC->Child(id);
NodeId var_decl = fC->Child(data_declaration);
VObjectType type = fC->Type(data_declaration);
bool is_local = false;
bool is_static = false;
bool is_protected = false;
bool is_rand = false;
bool is_randc = false;
while ((type == VObjectType::slPropQualifier_ClassItem) ||
(type == VObjectType::slPropQualifier_Rand) ||
(type == VObjectType::slPropQualifier_Randc)) {
NodeId qualifier = fC->Child(data_declaration);
VObjectType qualType = fC->Type(qualifier);
if (qualType == VObjectType::slClassItemQualifier_Protected)
is_protected = true;
if (qualType == VObjectType::slClassItemQualifier_Static) is_static = true;
if (qualType == VObjectType::slClassItemQualifier_Local) is_local = true;
if (type == VObjectType::slPropQualifier_Rand) is_rand = true;
if (type == VObjectType::slPropQualifier_Randc) is_randc = true;
data_declaration = fC->Sibling(data_declaration);
type = fC->Type(data_declaration);
var_decl = fC->Child(data_declaration);
}
if (type == VObjectType::slData_declaration) {
/*
n<A> u<3> t<StringConst> p<37> s<12> l<5>
n<> u<4> t<IntegerAtomType_Int> p<5> l<6>
n<> u<5> t<Data_type> p<9> c<4> s<8> l<6>
n<size> u<6> t<StringConst> p<7> l<6>
n<> u<7> t<Variable_decl_assignment> p<8> c<6> l<6>
n<> u<8> t<List_of_variable_decl_assignments> p<9> c<7> l<6>
n<> u<9> t<Variable_declaration> p<10> c<5> l<6>
n<> u<10> t<Data_declaration> p<11> c<9> l<6>
n<> u<11> t<Class_property> p<12> c<10> l<6>
n<> u<12> t<Class_item> p<37> c<11> s<35> l<6>
*/
VObjectType var_type = fC->Type(var_decl);
if (var_type == VObjectType::slVariable_declaration) {
NodeId data_type = fC->Child(var_decl);
NodeId node_type = fC->Child(data_type);
VObjectType the_type = fC->Type(node_type);
std::string typeName;
if (the_type == VObjectType::slStringConst) {
typeName = fC->SymName(node_type);
} else if (the_type == VObjectType::slClass_scope) {
NodeId class_type = fC->Child(node_type);
NodeId class_name = fC->Child(class_type);
typeName = fC->SymName(class_name);
typeName += "::";
NodeId symb_id = fC->Sibling(node_type);
typeName += fC->SymName(symb_id);
} else {
typeName = VObject::getTypeName(the_type);
}
DataType* datatype = m_class->getUsedDataType(typeName);
if (!datatype) {
DataType* type =
new DataType(fC, node_type, typeName, fC->Type(node_type));
m_class->insertUsedDataType(typeName, type);
datatype = m_class->getUsedDataType(typeName);
}
NodeId list_of_variable_decl_assignments = fC->Sibling(data_type);
NodeId variable_decl_assignment =
fC->Child(list_of_variable_decl_assignments);
while (variable_decl_assignment) {
NodeId var = fC->Child(variable_decl_assignment);
NodeId range = fC->Sibling(var);
std::string varName = fC->SymName(var);
Property* previous = m_class->getProperty(varName);
if (previous) {
Location loc1(m_symbols->registerSymbol(fC->getFileName(var)),
fC->Line(var), 0, m_symbols->registerSymbol(varName));
FileContent* prevFile = previous->getFileContent();
NodeId prevNode = previous->getNodeId();
Location loc2(
m_symbols->registerSymbol(prevFile->getFileName(prevNode)),
prevFile->Line(prevNode), 0, m_symbols->registerSymbol(varName));
Error err(ErrorDefinition::COMP_MULTIPLY_DEFINED_PROPERTY, loc1,
loc2);
m_errors->addError(err);
}
Property* prop =
new Property(datatype, fC, var, range, varName, is_local, is_static,
is_protected, is_rand, is_randc);
m_class->insertProperty(prop);
variable_decl_assignment = fC->Sibling(variable_decl_assignment);
}
} else if (var_type == VObjectType::slType_declaration) {
compile_type_declaration_(fC, data_declaration);
}
}
return true;
}
bool CompileClass::compile_class_method_(FileContent* fC, NodeId id) {
/*
n<> u<8> t<MethodQualifier_Virtual> p<21> s<20> l<12>
n<> u<9> t<Function_data_type> p<10> l<12>
n<> u<10> t<Function_data_type_or_implicit> p<19> c<9> s<11> l<12>
n<print_tree1> u<11> t<StringConst> p<19> s<17> l<12>
n<> u<12> t<IntegerAtomType_Int> p<13> l<12>
n<> u<13> t<Data_type> p<14> c<12> l<12>
n<> u<14> t<Data_type_or_implicit> p<16> c<13> s<15> l<12>
n<a> u<15> t<StringConst> p<16> l<12>
n<> u<16> t<Tf_port_item> p<17> c<14> l<12>
n<> u<17> t<Tf_port_list> p<19> c<16> s<18> l<12>
n<> u<18> t<Endfunction> p<19> l<14>
n<> u<19> t<Function_body_declaration> p<20> c<10> l<12>
n<> u<20> t<Function_declaration> p<21> c<19> l<12>
n<> u<21> t<Class_method> p<22> c<8> l<12>
*/
NodeId func_decl = fC->Child(id);
VObjectType func_type = fC->Type(func_decl);
std::string funcName;
std::string taskName;
bool is_virtual = false;
bool is_extern = false;
bool is_static = false;
bool is_local = false;
bool is_protected = false;
bool is_pure = false;
DataType* returnType = new DataType();
while ((func_type == VObjectType::slMethodQualifier_Virtual) ||
(func_type == VObjectType::slMethodQualifier_ClassItem) ||
(func_type == VObjectType::slPure_virtual_qualifier) ||
(func_type == VObjectType::slExtern_qualifier) ||
(func_type == VObjectType::slClassItemQualifier_Protected)) {
if (func_type == VObjectType::slMethodQualifier_Virtual) {
is_virtual = true;
func_decl = fC->Sibling(func_decl);
func_type = fC->Type(func_decl);
}
if (func_type == VObjectType::slClassItemQualifier_Protected) {
is_protected = true;
func_decl = fC->Sibling(func_decl);
func_type = fC->Type(func_decl);
}
if (func_type == VObjectType::slPure_virtual_qualifier) {
is_virtual = true;
is_pure = true;
func_decl = fC->Sibling(func_decl);
func_type = fC->Type(func_decl);
}
if (func_type == VObjectType::slExtern_qualifier) {
is_extern = true;
func_decl = fC->Sibling(func_decl);
func_type = fC->Type(func_decl);
}
if (func_type == VObjectType::slMethodQualifier_ClassItem) {
NodeId qualifier = fC->Child(func_decl);
VObjectType type = fC->Type(qualifier);
if (type == VObjectType::slClassItemQualifier_Static) is_static = true;
if (type == VObjectType::slClassItemQualifier_Local) is_local = true;
if (type == VObjectType::slClassItemQualifier_Protected)
is_protected = true;
func_decl = fC->Sibling(func_decl);
func_type = fC->Type(func_decl);
}
}
if (func_type == VObjectType::slFunction_declaration) {
NodeId func_body_decl = fC->Child(func_decl);
NodeId function_data_type_or_implicit = fC->Child(func_body_decl);
NodeId function_data_type = fC->Child(function_data_type_or_implicit);
NodeId data_type = fC->Child(function_data_type);
NodeId type = fC->Child(data_type);
VObjectType the_type = fC->Type(type);
std::string typeName;
if (the_type == VObjectType::slStringConst) {
typeName = fC->SymName(type);
} else {
typeName = VObject::getTypeName(the_type);
}
returnType->init(fC, type, typeName, fC->Type(type));
NodeId function_name = fC->Sibling(function_data_type_or_implicit);
funcName = fC->SymName(function_name);
} else if (func_type == VObjectType::slTask_declaration) {
/*
n<cfg_dut> u<143> t<StringConst> p<146> s<144> l<37>
n<> u<144> t<Endtask> p<146> s<145> l<39>
n<cfg_dut> u<145> t<StringConst> p<146> l<39>
n<> u<146> t<Task_body_declaration> p<147> c<143> l<37>
n<> u<147> t<Task_declaration> p<148> c<146> l<37>
n<> u<148> t<Class_method> p<149> c<147> l<37>
*/
NodeId task_body_decl = fC->Child(func_decl);
NodeId task_name = fC->Child(task_body_decl);
taskName = fC->SymName(task_name);
} else if (func_type == VObjectType::slMethod_prototype) {
/*
n<> u<65> t<IntVec_TypeBit> p<66> l<37>
n<> u<66> t<Data_type> p<67> c<65> l<37>
n<> u<67> t<Function_data_type> p<69> c<66> s<68> l<37>
n<is_active> u<68> t<StringConst> p<69> l<37>
n<> u<69> t<Function_prototype> p<70> c<67> l<37>
n<> u<70> t<Method_prototype> p<71> c<69> l<37>
n<> u<71> t<Class_method> p<72> c<70> l<37>
*/
NodeId func_prototype = fC->Child(func_decl);
if (fC->Type(func_prototype) == VObjectType::slTask_prototype) {
NodeId task_name = fC->Child(func_prototype);
taskName = fC->SymName(task_name);
} else {
NodeId function_data_type = fC->Child(func_prototype);
NodeId data_type = fC->Child(function_data_type);
NodeId type = fC->Child(data_type);
VObjectType the_type = fC->Type(type);
std::string typeName;
if (the_type == VObjectType::slStringConst) {
typeName = fC->SymName(type);
} else {
typeName = VObject::getTypeName(the_type);
}
returnType->init(fC, type, typeName, fC->Type(type));
NodeId function_name = fC->Sibling(function_data_type);
funcName = fC->SymName(function_name);
}
is_extern = true;
} else if (func_type == VObjectType::slClass_constructor_declaration) {
funcName = "new";
returnType->init(fC, 0, "void", VObjectType::slNoType);
} else if (func_type == VObjectType::slClass_constructor_prototype) {
funcName = "new";
} else {
funcName = "UNRECOGNIZED_METHOD_TYPE";
}
if (taskName != "") {
TaskMethod* method = new TaskMethod(m_class, fC, id, taskName, is_extern);
method->compile(m_helper);
TaskMethod* prevDef = m_class->getTask(taskName);
if (prevDef) {
Location loc1(m_symbols->registerSymbol(fC->getFileName(id)),
fC->Line(id), 0, m_symbols->registerSymbol(taskName));
FileContent* prevFile = prevDef->getFileContent();
NodeId prevNode = prevDef->getNodeId();
Location loc2(m_symbols->registerSymbol(prevFile->getFileName(prevNode)),
prevFile->Line(prevNode), 0,
m_symbols->registerSymbol(taskName));
Error err(ErrorDefinition::COMP_MULTIPLY_DEFINED_TASK, loc1, loc2);
m_errors->addError(err);
}
m_class->insertTask(method);
} else {
FunctionMethod* method = new FunctionMethod(
m_class, fC, id, funcName, returnType, is_virtual, is_extern, is_static,
is_local, is_protected, is_pure);
Variable* variable = new Variable(returnType, fC, id, 0, funcName);
method->addVariable(variable);
method->compile(m_helper);
Function* prevDef = m_class->getFunction(funcName);
if (prevDef) {
Location loc1(m_symbols->registerSymbol(fC->getFileName(id)),
fC->Line(id), 0, m_symbols->registerSymbol(funcName));
FileContent* prevFile = prevDef->getFileContent();
NodeId prevNode = prevDef->getNodeId();
Location loc2(m_symbols->registerSymbol(prevFile->getFileName(prevNode)),
prevFile->Line(prevNode), 0,
m_symbols->registerSymbol(funcName));
Error err(ErrorDefinition::COMP_MULTIPLY_DEFINED_FUNCTION, loc1, loc2);
m_errors->addError(err);
}
m_class->insertFunction(method);
}
return true;
}
bool CompileClass::compile_class_constraint_(FileContent* fC,
NodeId class_constraint) {
NodeId constraint_prototype = fC->Child(class_constraint);
NodeId constraint_name = fC->Child(constraint_prototype);
std::string constName = fC->SymName(constraint_name);
Constraint* prevDef = m_class->getConstraint(constName);
if (prevDef) {
Location loc1(m_symbols->registerSymbol(fC->getFileName(class_constraint)),
fC->Line(class_constraint), 0,
m_symbols->registerSymbol(constName));
FileContent* prevFile = prevDef->getFileContent();
NodeId prevNode = prevDef->getNodeId();
Location loc2(m_symbols->registerSymbol(prevFile->getFileName(prevNode)),
prevFile->Line(prevNode), 0,
m_symbols->registerSymbol(constName));
Error err(ErrorDefinition::COMP_MULTIPLY_DEFINED_CONSTRAINT, loc1, loc2);
m_errors->addError(err);
}
Constraint* constraint = new Constraint(fC, class_constraint, constName);
m_class->insertConstraint(constraint);
return true;
}
bool CompileClass::compile_type_declaration_(FileContent* fC, NodeId id) {
/*
n<> u<8> t<IntegerAtomType_Int> p<9> l<3>
n<> u<9> t<Data_type> p<11> c<8> s<10> l<3>
n<my_int> u<10> t<StringConst> p<11> l<3>
n<> u<11> t<Type_declaration> p<12> c<9> l<3>
n<> u<12> t<Data_declaration> p<13> c<11> l<3>
n<> u<13> t<Class_property> p<14> c<12> l<3>
*/
m_helper.compileTypeDef(m_class, fC, id);
return true;
}
bool CompileClass::compile_class_declaration_(FileContent* fC, NodeId id) {
NodeId class_name_id = fC->Child(id);
std::string class_name =
m_class->getName() + "::" + fC->SymName(class_name_id);
ClassDefinition* prevDef = m_class->getClass(class_name);
if (prevDef) {
Location loc1(m_symbols->registerSymbol(fC->getFileName(class_name_id)),
fC->Line(class_name_id), 0,
m_symbols->registerSymbol(class_name));
FileContent* prevFile = prevDef->getFileContent();
NodeId prevNode = prevDef->getNodeId();
Location loc2(m_symbols->registerSymbol(prevFile->getFileName(prevNode)),
prevFile->Line(prevNode), 0,
m_symbols->registerSymbol(class_name));
Error err(ErrorDefinition::COMP_MULTIPLY_DEFINED_INNER_CLASS, loc1, loc2);
m_errors->addError(err);
}
ClassDefinition* the_class =
new ClassDefinition(class_name, m_class->getLibrary(),
m_class->getContainer(), fC, class_name_id, m_class);
m_class->insertClass(the_class);
CompileClass* instance = new CompileClass(m_compileDesign, the_class,
m_design, m_symbols, m_errors);
instance->compile();
delete instance;
return true;
}
bool CompileClass::compile_covergroup_declaration_(FileContent* fC, NodeId id) {
NodeId covergroup_name = fC->Child(id);
std::string covergroupName = fC->SymName(covergroup_name);
CoverGroupDefinition* prevDef = m_class->getCoverGroup(covergroupName);
if (prevDef) {
Location loc1(m_symbols->registerSymbol(fC->getFileName(covergroup_name)),
fC->Line(covergroup_name), 0,
m_symbols->registerSymbol(covergroupName));
FileContent* prevFile = prevDef->getFileContent();
NodeId prevNode = prevDef->getNodeId();
Location loc2(m_symbols->registerSymbol(prevFile->getFileName(prevNode)),
prevFile->Line(prevNode), 0,
m_symbols->registerSymbol(covergroupName));
Error err(ErrorDefinition::COMP_MULTIPLY_DEFINED_COVERGROUP, loc1, loc2);
m_errors->addError(err);
}
CoverGroupDefinition* covergroup =
new CoverGroupDefinition(fC, id, covergroupName);
m_class->insertCoverGroup(covergroup);
return true;
}
bool CompileClass::compile_local_parameter_declaration_(FileContent* fC,
NodeId id) {
/*
n<> u<8> t<IntegerAtomType_Int> p<9> l<3>
n<> u<9> t<Data_type> p<10> c<8> l<3>
n<> u<10> t<Data_type_or_implicit> p<20> c<9> s<19> l<3>
n<FOO> u<11> t<StringConst> p<18> s<17> l<3>
n<3> u<12> t<IntConst> p<13> l<3>
n<> u<13> t<Primary_literal> p<14> c<12> l<3>
n<> u<14> t<Constant_primary> p<15> c<13> l<3>
n<> u<15> t<Constant_expression> p<16> c<14> l<3>
n<> u<16> t<Constant_mintypmax_expression> p<17> c<15> l<3>
n<> u<17> t<Constant_param_expression> p<18> c<16> l<3>
n<> u<18> t<Param_assignment> p<19> c<11> l<3>
n<> u<19> t<List_of_param_assignments> p<20> c<18> l<3>
n<> u<20> t<Local_parameter_declaration> p<21> c<10> l<3>
*/
NodeId data_type_or_implicit = fC->Child(id);
NodeId list_of_param_assignments = fC->Sibling(data_type_or_implicit);
NodeId param_assignment = fC->Child(list_of_param_assignments);
while (param_assignment) {
NodeId var = fC->Child(param_assignment);
std::string name = fC->SymName(var);
std::pair<FileCNodeId, DesignComponent*>* prevDef =
m_class->getNamedObject(name);
if (prevDef) {
Location loc1(m_symbols->registerSymbol(fC->getFileName(var)),
fC->Line(var), 0, m_symbols->registerSymbol(name));
FileContent* prevFile = prevDef->first.fC;
NodeId prevNode = prevDef->first.nodeId;
Location loc2(m_symbols->registerSymbol(prevFile->getFileName(prevNode)),
prevFile->Line(prevNode), 0,
m_symbols->registerSymbol(name));
Error err(ErrorDefinition::COMP_MULTIPLY_DEFINED_PARAMETER, loc1, loc2);
m_errors->addError(err);
}
FileCNodeId fnid(fC, id);
m_class->addObject(VObjectType::slLocal_parameter_declaration, fnid);
m_class->addNamedObject(name, fnid, NULL);
param_assignment = fC->Sibling(param_assignment);
}
return true;
}
bool CompileClass::compile_parameter_declaration_(FileContent* fC, NodeId id) {
NodeId data_type_or_implicit = fC->Child(id);
NodeId list_of_param_assignments = fC->Sibling(data_type_or_implicit);
NodeId param_assignment = fC->Child(list_of_param_assignments);
while (param_assignment) {
NodeId var = fC->Child(param_assignment);
std::string name = fC->SymName(var);
std::pair<FileCNodeId, DesignComponent*>* prevDef =
m_class->getNamedObject(name);
if (prevDef) {
Location loc1(m_symbols->registerSymbol(fC->getFileName(var)),
fC->Line(var), 0, m_symbols->registerSymbol(name));
FileContent* prevFile = prevDef->first.fC;
NodeId prevNode = prevDef->first.nodeId;
Location loc2(m_symbols->registerSymbol(prevFile->getFileName(prevNode)),
prevFile->Line(prevNode), 0,
m_symbols->registerSymbol(name));
Error err(ErrorDefinition::COMP_MULTIPLY_DEFINED_PARAMETER, loc1, loc2);
m_errors->addError(err);
}
FileCNodeId fnid(fC, id);
m_class->addObject(VObjectType::slLocal_parameter_declaration, fnid);
m_class->addNamedObject(name, fnid, NULL);
param_assignment = fC->Sibling(param_assignment);
}
return true;
}
bool CompileClass::compile_class_type_(FileContent* fC, NodeId id) {
NodeId parent = fC->Parent(id);
VObjectType ptype = fC->Type(parent);
if (ptype != VObjectType::slClass_declaration) return true;
NodeId base_class_id = fC->Child(id);
std::string base_class_name = fC->SymName(base_class_id);
while (fC->Sibling(base_class_id) &&
(fC->Type(fC->Sibling(base_class_id)) == VObjectType::slStringConst)) {
base_class_id = fC->Sibling(base_class_id);
base_class_name += "::" + fC->SymName(base_class_id);
}
// Insert base class placeholder
// Will be bound in UVMElaboration step
ClassDefinition* base_class =
new ClassDefinition(base_class_name, m_class->getLibrary(),
m_class->getContainer(), fC, base_class_id, NULL);
m_class->insertBaseClass(base_class);
return true;
}
bool CompileClass::compile_class_parameters_(FileContent* fC, NodeId id) {
/*
n<all_c> u<1> t<StringConst> p<16> s<14> l<3>
n<uvm_port_base> u<2> t<StringConst> p<12> s<8> l<7>
n<IF> u<3> t<StringConst> p<6> s<5> l<7>
n<uvm_void> u<4> t<StringConst> p<5> l<7>
n<> u<5> t<Data_type> p<6> c<4> l<7>
n<> u<6> t<List_of_type_assignments> p<7> c<3> l<7>
n<> u<7> t<Parameter_port_declaration> p<8> c<6> l<7>
n<> u<8> t<Parameter_port_list> p<12> c<7> s<10> l<7>
n<IF> u<9> t<StringConst> p<10> l<7>
n<> u<10> t<Class_type> p<12> c<9> s<11> l<7>
n<> u<11> t<Endclass> p<12> l<8>
n<> u<12> t<Class_declaration> p<13> c<2> l<7>
or
n<T1> u<3> t<StringConst> p<9> s<5> l<18>
n<> u<4> t<IntegerAtomType_Int> p<5> l<18>
n<> u<5> t<Data_type> p<9> c<4> s<6> l<18>
n<T2> u<6> t<StringConst> p<9> s<8> l<18>
n<T1> u<7> t<StringConst> p<8> l<18>
n<> u<8> t<Data_type> p<9> c<7> l<18>
n<> u<9> t<List_of_type_assignments> p<10> c<3> l<18>
n<> u<10> t<Parameter_port_declaration> p<11> c<9> l<18>
n<> u<11> t<Parameter_port_list> p<31> c<10> s<20> l<18>
*/
NodeId className = fC->Child(id);
NodeId paramList = fC->Sibling(className);
if (fC->Type(paramList) == VObjectType::slParameter_port_list) {
NodeId parameter_port_declaration = fC->Child(paramList);
while (parameter_port_declaration) {
NodeId list_of_type_assignments = fC->Child(parameter_port_declaration);
NodeId typeNameId = fC->Child(list_of_type_assignments);
while (typeNameId) {
NodeId ntype = fC->Sibling(typeNameId);
bool skip = false;
if (ntype && fC->Type(ntype) == VObjectType::slData_type) {
ntype = fC->Child(ntype);
skip = true;
} else {
ntype = 0;
}
Parameter* param =
new Parameter(fC, typeNameId, fC->SymName(typeNameId), ntype);
m_class->insertParameter(param);
typeNameId = fC->Sibling(typeNameId);
if (skip) typeNameId = fC->Sibling(typeNameId);
}
parameter_port_declaration = fC->Sibling(parameter_port_declaration);
}
}
return true;
}