blob: 7a876901f7c2ac7d06bb94a7aa0a1ef9603ed4da [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: 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;
}