| /* |
| 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: ResolveSymbols.cpp |
| * Author: alain |
| * |
| * Created on July 1, 2017, 12:38 PM |
| */ |
| #include "SourceCompile/VObjectTypes.h" |
| #include "Design/VObject.h" |
| #include "Library/Library.h" |
| #include "Design/FileContent.h" |
| #include "SourceCompile/SymbolTable.h" |
| #include "ErrorReporting/Error.h" |
| #include "ErrorReporting/Location.h" |
| #include "ErrorReporting/Error.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 "Testbench/Program.h" |
| #include "Testbench/ClassDefinition.h" |
| #include "DesignCompile/CompileDesign.h" |
| #include "DesignCompile/ResolveSymbols.h" |
| |
| using namespace SURELOG; |
| |
| ResolveSymbols::~ResolveSymbols() {} |
| |
| int FunctorCreateLookup::operator()() const { |
| ResolveSymbols* instance = new ResolveSymbols( |
| m_compileDesign, m_fileData, m_symbolTable, m_errorContainer); |
| instance->createFastLookup(); |
| delete instance; |
| return true; |
| } |
| |
| int FunctorResolve::operator()() const { |
| ResolveSymbols* instance = new ResolveSymbols( |
| m_compileDesign, m_fileData, m_symbolTable, m_errorContainer); |
| instance->resolve(); |
| delete instance; |
| return true; |
| } |
| |
| std::string ResolveSymbols::SymName(NodeId index) { |
| return m_fileData->getSymbolTable()->getSymbol(Name(index)); |
| } |
| |
| void ResolveSymbols::createFastLookup() { |
| Library* lib = m_fileData->getLibrary(); |
| std::string libName = lib->getName(); |
| |
| // std::string fileName = "FILE: " + m_fileData->getFileName() + " " + |
| // m_fileData->getChunkFileName () + "\n"; std::cout << fileName; |
| |
| std::vector<VObjectType> types = { |
| VObjectType::slModule_declaration, VObjectType::slPackage_declaration, |
| VObjectType::slConfig_declaration, VObjectType::slUdp_declaration, |
| VObjectType::slInterface_declaration, VObjectType::slProgram_declaration, |
| VObjectType::slClass_declaration}; |
| |
| std::vector<VObjectType> stopPoints = { |
| VObjectType::slModule_declaration, VObjectType::slPackage_declaration, |
| VObjectType::slProgram_declaration, VObjectType::slClass_declaration}; |
| |
| std::vector<NodeId> objects = |
| m_fileData->sl_collect_all(m_fileData->getRootNode(), types, stopPoints); |
| |
| for (auto object : objects) { |
| VObjectType type = m_fileData->Type(object); |
| NodeId stId = m_fileData->sl_collect(object, VObjectType::slStringConst, |
| VObjectType::slAttr_spec); |
| if (stId != InvalidNodeId) { |
| std::string name = SymName(stId); |
| m_fileData->insertObjectLookup(name, object, m_errorContainer); |
| std::string fullName = libName + "@" + name; |
| |
| switch (type) { |
| case VObjectType::slPackage_declaration: { |
| // Package names are not prefixed by Library names! |
| std::string pkgname = name; |
| Package* pdef = new Package(pkgname, lib, m_fileData, object); |
| m_fileData->addPackageDefinition(pkgname, pdef); |
| |
| std::vector<VObjectType> subtypes = { |
| VObjectType::slClass_declaration}; |
| std::vector<NodeId> subobjects = |
| m_fileData->sl_collect_all(object, subtypes, subtypes); |
| for (auto subobject : subobjects) { |
| NodeId stId = |
| m_fileData->sl_collect(subobject, VObjectType::slStringConst, |
| VObjectType::slAttr_spec); |
| if (stId != InvalidNodeId) { |
| std::string name = SymName(stId); |
| std::string fullSubName = pkgname + "::" + name; |
| m_fileData->insertObjectLookup(fullSubName, subobject, |
| m_errorContainer); |
| |
| ClassDefinition* def = new ClassDefinition( |
| fullSubName, lib, pdef, m_fileData, subobject, NULL); |
| m_fileData->addClassDefinition(fullSubName, def); |
| pdef->addClassDefinition(fullSubName, def); |
| } |
| } |
| break; |
| } |
| case VObjectType::slProgram_declaration: { |
| Program* mdef = new Program(fullName, lib, m_fileData, object); |
| m_fileData->addProgramDefinition(fullName, mdef); |
| |
| std::vector<VObjectType> subtypes = { |
| VObjectType::slClass_declaration}; |
| std::vector<NodeId> subobjects = |
| m_fileData->sl_collect_all(object, subtypes, subtypes); |
| for (auto subobject : subobjects) { |
| NodeId stId = |
| m_fileData->sl_collect(subobject, VObjectType::slStringConst, |
| VObjectType::slAttr_spec); |
| if (stId != InvalidNodeId) { |
| std::string name = SymName(stId); |
| std::string fullSubName = fullName + "::" + name; |
| m_fileData->insertObjectLookup(fullSubName, subobject, |
| m_errorContainer); |
| ClassDefinition* def = new ClassDefinition( |
| fullSubName, lib, mdef, m_fileData, subobject, NULL); |
| m_fileData->addClassDefinition(fullSubName, def); |
| mdef->addClassDefinition(fullSubName, def); |
| } |
| } |
| break; |
| } |
| case VObjectType::slClass_declaration: { |
| ClassDefinition* def = new ClassDefinition(fullName, lib, NULL, |
| m_fileData, object, NULL); |
| m_fileData->addClassDefinition(fullName, def); |
| break; |
| } |
| case VObjectType::slModule_declaration: { |
| ModuleDefinition* mdef = |
| new ModuleDefinition(m_fileData, object, fullName); |
| m_fileData->addModuleDefinition(fullName, mdef); |
| |
| std::vector<VObjectType> subtypes = { |
| VObjectType::slClass_declaration, |
| VObjectType::slModule_declaration}; |
| std::vector<NodeId> subobjects = |
| m_fileData->sl_collect_all(object, subtypes, subtypes); |
| for (auto subobject : subobjects) { |
| NodeId stId = |
| m_fileData->sl_collect(subobject, VObjectType::slStringConst, |
| VObjectType::slAttr_spec); |
| if (stId != InvalidNodeId) { |
| std::string name = SymName(stId); |
| std::string fullSubName = fullName + "::" + name; |
| m_fileData->insertObjectLookup(fullSubName, subobject, |
| m_errorContainer); |
| |
| if (m_fileData->Type(subobject) == |
| VObjectType::slClass_declaration) { |
| ClassDefinition* def = new ClassDefinition( |
| fullSubName, lib, mdef, m_fileData, subobject, NULL); |
| m_fileData->addClassDefinition(fullSubName, def); |
| mdef->addClassDefinition(fullSubName, def); |
| } else { |
| ModuleDefinition* def = |
| new ModuleDefinition(m_fileData, subobject, fullSubName); |
| m_fileData->addModuleDefinition(fullSubName, def); |
| } |
| } |
| } |
| |
| break; |
| } |
| case VObjectType::slConfig_declaration: |
| case VObjectType::slUdp_declaration: |
| case VObjectType::slInterface_declaration: |
| default: |
| ModuleDefinition* def = |
| new ModuleDefinition(m_fileData, object, fullName); |
| m_fileData->addModuleDefinition(fullName, def); |
| break; |
| } |
| } |
| } |
| } |
| |
| VObject& ResolveSymbols::Object(NodeId index) { |
| if (index == InvalidNodeId) return m_fileData->Object(0); |
| return m_fileData->Object(index); |
| } |
| |
| NodeId ResolveSymbols::UniqueId(NodeId index) { return index; } |
| |
| SymbolId ResolveSymbols::Name(NodeId index) { |
| if (index == InvalidNodeId) return 0; |
| return Object(index).m_name; |
| } |
| |
| NodeId ResolveSymbols::Child(NodeId index) { |
| if (index == InvalidNodeId) return 0; |
| return Object(index).m_child; |
| } |
| |
| NodeId ResolveSymbols::Sibling(NodeId index) { |
| if (index == InvalidNodeId) return 0; |
| return Object(index).m_sibling; |
| } |
| |
| static NodeId UndefinedObjectDefinition = 0; |
| NodeId& ResolveSymbols::Definition(NodeId index) { |
| if (index == InvalidNodeId) return UndefinedObjectDefinition; |
| return Object(index).m_definition; |
| } |
| |
| NodeId ResolveSymbols::Parent(NodeId index) { |
| if (index == InvalidNodeId) return 0; |
| return Object(index).m_parent; |
| } |
| |
| static unsigned short UndefinedObjectType = 0; |
| unsigned short& ResolveSymbols::Type(NodeId index) { |
| if (index == InvalidNodeId) return UndefinedObjectType; |
| return Object(index).m_type; |
| } |
| |
| unsigned int ResolveSymbols::Line(NodeId index) { |
| if (index == InvalidNodeId) return 0; |
| return Object(index).m_line; |
| } |
| |
| std::string ResolveSymbols::Symbol(SymbolId id) { |
| return m_fileData->getSymbolTable()->getSymbol(id); |
| } |
| |
| NodeId ResolveSymbols::sl_get(NodeId parent, VObjectType type) { |
| return m_fileData->sl_get(parent, type); |
| } |
| |
| NodeId ResolveSymbols::sl_parent(NodeId parent, VObjectType type) { |
| return m_fileData->sl_parent(parent, type); |
| } |
| |
| NodeId ResolveSymbols::sl_parent(NodeId parent, std::vector<VObjectType> types, |
| VObjectType& actualType) { |
| return m_fileData->sl_parent(parent, types, actualType); |
| } |
| |
| std::vector<NodeId> ResolveSymbols::sl_get_all(NodeId parent, |
| VObjectType type) { |
| return m_fileData->sl_get_all(parent, type); |
| } |
| |
| NodeId ResolveSymbols::sl_collect(NodeId parent, VObjectType type) { |
| return m_fileData->sl_collect(parent, type); |
| } |
| |
| std::vector<NodeId> ResolveSymbols::sl_collect_all(NodeId parent, |
| VObjectType type) { |
| return m_fileData->sl_collect_all(parent, type); |
| } |
| |
| bool ResolveSymbols::bindDefinition_(unsigned int objIndex, |
| std::vector<VObjectType> bindTypes) { |
| std::string modName = |
| SymName(sl_collect(objIndex, VObjectType::slStringConst)); |
| std::string instName = |
| SymName(Child(sl_collect(objIndex, slName_of_instance))); |
| Design::FileIdDesignContentMap& all_files = |
| this->m_compileDesign->getCompiler()->getDesign()->getAllFileContents(); |
| |
| bool found = false; |
| for (auto file : all_files) { |
| SymbolId fileId = file.first; |
| FileContent* fcontent = file.second; |
| |
| auto itr = fcontent->getObjectLookup().find(modName); |
| if (itr != fcontent->getObjectLookup().end()) { |
| VObjectType actualType; |
| NodeId index = (*itr).second; |
| NodeId mod = fcontent->sl_parent(index, bindTypes, actualType); |
| if (mod != InvalidNodeId) { |
| Definition(objIndex) = mod; |
| fcontent->getReferencedObjects().insert(modName); |
| m_fileData->SetDefinitionFile(objIndex, fileId); |
| switch (actualType) { |
| case VObjectType::slUdp_declaration: |
| Type(objIndex) = VObjectType::slUdp_instantiation; |
| break; |
| case VObjectType::slModule_declaration: |
| Type(objIndex) = VObjectType::slModule_instantiation; |
| break; |
| case VObjectType::slInterface_declaration: |
| Type(objIndex) = VObjectType::slInterface_instantiation; |
| break; |
| case VObjectType::slProgram_declaration: |
| Type(objIndex) = VObjectType::slProgram_instantiation; |
| break; |
| default: |
| break; |
| } |
| found = true; |
| // std::cout << "FOUND MODEL FOR " << modName << " " << instName << |
| // std::endl; std::cout << m_fileData->printSubTree (objIndex) << |
| // std::endl; |
| break; |
| } |
| } |
| } |
| return found; |
| } |
| |
| bool ResolveSymbols::resolve() { |
| unsigned int size = m_fileData->getVObjects().size(); |
| for (unsigned int objIndex = 0; objIndex < size; objIndex++) { |
| // ErrorDefinition::ErrorType errorType; |
| bool bind = false; |
| if (Type(objIndex) == VObjectType::slUdp_instantiation) { |
| bind = true; |
| // errorType = ErrorDefinition::ELAB_NO_UDP_DEFINITION; |
| } else if (Type(objIndex) == VObjectType::slModule_instantiation) { |
| bind = true; |
| // errorType = ErrorDefinition::ELAB_NO_MODULE_DEFINITION; |
| } else if (Type(objIndex) == VObjectType::slInterface_instantiation) { |
| bind = true; |
| // errorType = ErrorDefinition::ELAB_NO_INTERFACE_DEFINITION; |
| } else if (Type(objIndex) == VObjectType::slProgram_instantiation) { |
| bind = true; |
| // errorType = ErrorDefinition::ELAB_NO_PROGRAM_DEFINITION; |
| } |
| if (bind) { |
| /*bool found = */ |
| bindDefinition_(objIndex, |
| {slUdp_declaration, slModule_declaration, |
| slInterface_declaration, slProgram_declaration}); |
| /* |
| * This warning is now treated in the elaboration to give the library |
| information if (!found) |
| { |
| std::string modName = SymName (sl_collect (objIndex, slStringConst)); |
| Location loc (m_fileData->getFileId (), Line (objIndex), 0, |
| m_symbolTable->registerSymbol (modName)); Error err (errorType, loc); |
| m_errorContainer->addError (err, false, false); |
| } |
| */ |
| } |
| } |
| |
| return true; |
| } |