| /* |
| 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 "CompileDesign.h" |
| #include "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; |
| } |
| |