| /* |
| 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.hpp" |
| #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 "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]; |
| Location loc (m_symbols->registerSymbol (fC->getFileName(nodeId)), 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; |
| } |