blob: 4255713b5e7c0e6855de64c6bf3c89d581737d7c [file] [log] [blame] [edit]
/*
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: SV3_1aTreeShapeHelper.cpp
* Author: alain
*
* Created on June 25, 2017, 2:51 PM
*/
#include "SymbolTable.h"
#include "../CommandLine/CommandLineParser.hpp"
#include "../ErrorReporting/ErrorContainer.h"
#include "CompilationUnit.h"
#include "PreprocessFile.h"
#include "CompileSourceFile.h"
#include "Compiler.h"
#include "ParseFile.h"
#include <cstdlib>
#include <iostream>
#include "antlr4-runtime.h"
using namespace std;
using namespace antlr4;
using namespace SURELOG;
#include "../parser/SV3_1aLexer.h"
#include "../parser/SV3_1aParser.h"
#include "../parser/SV3_1aParserBaseListener.h"
#include "SV3_1aTreeShapeHelper.h"
using namespace antlr4;
#include "../Utils/ParseUtils.h"
#include "SV3_1aTreeShapeHelper.h"
SV3_1aTreeShapeHelper::SV3_1aTreeShapeHelper (ParseFile* pf, antlr4::CommonTokenStream* tokens, unsigned int lineOffset) :
m_pf(pf), m_fileContent(NULL), m_currentElement(NULL), m_tokens(tokens), m_lineOffset(lineOffset), m_version(SystemVerilog) {
if (pf->getCompileSourceFile ())
m_ppOutputFileLocation = pf->getCompileSourceFile ()->getCommandLineParser ()->usePPOutoutFileLocation ();
}
SV3_1aTreeShapeHelper::SV3_1aTreeShapeHelper(ParseLibraryDef* pf, antlr4::CommonTokenStream* tokens) :
m_pf(NULL), m_fileContent(NULL), m_currentElement(NULL), m_tokens(tokens), m_lineOffset(0), m_ppOutputFileLocation(false), m_version(SystemVerilog) {
}
SV3_1aTreeShapeHelper::~SV3_1aTreeShapeHelper () { }
void
SV3_1aTreeShapeHelper::logError (ErrorDefinition::ErrorType error, ParserRuleContext* ctx, std::string object, bool printColumn)
{
std::pair<int, int> lineCol = ParseUtils::getLineColumn (m_tokens, ctx);
Location loc (m_pf->getFileId (lineCol.first /*+ m_lineOffset*/), m_pf->getLineNb (lineCol.first /*+ m_lineOffset*/), printColumn ? lineCol.second : 0,
m_pf->getCompileSourceFile()->getSymbolTable ()->registerSymbol(object));
Error err (error, loc);
m_pf->addError (err);
}
void
SV3_1aTreeShapeHelper::logError (ErrorDefinition::ErrorType error, Location& loc, bool showDuplicates)
{
Error err (error, loc);
m_pf->getCompileSourceFile ()->getErrorContainer ()->addError (err, showDuplicates);
}
void
SV3_1aTreeShapeHelper::logError (ErrorDefinition::ErrorType error, Location& loc, Location& extraLoc, bool showDuplicates)
{
std::vector<Location> extras;
extras.push_back (extraLoc);
Error err (error, loc, &extras);
m_pf->getCompileSourceFile ()->getErrorContainer ()->addError (err, showDuplicates);
}
NodeId
SV3_1aTreeShapeHelper::generateDesignElemId ()
{
return m_pf->getCompilationUnit ()->generateUniqueDesignElemId ();
}
NodeId
SV3_1aTreeShapeHelper::generateNodeId ()
{
return m_pf->getCompilationUnit ()->generateUniqueNodeId ();
}
SymbolId
SV3_1aTreeShapeHelper::registerSymbol (std::string symbol)
{
return m_pf->getSymbolTable ()->registerSymbol (symbol);
}
int
SV3_1aTreeShapeHelper::registerObject (VObject& object)
{
m_fileContent->getVObjects ().push_back (object);
return LastObjIndex ();
}
int
SV3_1aTreeShapeHelper::LastObjIndex ()
{
return m_fileContent->getVObjects ().size () - 1;
}
int
SV3_1aTreeShapeHelper::ObjectIndexFromContext (tree::ParseTree* ctx)
{
ContextToObjectMap::iterator itr = m_contextToObjectMap.find (ctx);
if (itr == m_contextToObjectMap.end ())
{
return -1;
}
else
{
return (*itr).second;
}
}
VObject&
SV3_1aTreeShapeHelper::Object (NodeId index)
{
return m_fileContent->getVObjects ()[index];
}
NodeId
SV3_1aTreeShapeHelper::UniqueId (NodeId index)
{
//return m_fileContent->m_objects[index].m_uniqueId;
return index;
}
SymbolId&
SV3_1aTreeShapeHelper::Name (NodeId index)
{
return m_fileContent->getVObjects ()[index].m_name;
}
NodeId&
SV3_1aTreeShapeHelper::Child (NodeId index)
{
return m_fileContent->getVObjects ()[index].m_child;
}
NodeId&
SV3_1aTreeShapeHelper::Sibling (NodeId index)
{
return m_fileContent->getVObjects ()[index].m_sibling;
}
NodeId&
SV3_1aTreeShapeHelper::Definition (NodeId index)
{
return m_fileContent->getVObjects ()[index].m_definition;
}
NodeId&
SV3_1aTreeShapeHelper::Parent (NodeId index)
{
return m_fileContent->getVObjects ()[index].m_parent;
}
unsigned short&
SV3_1aTreeShapeHelper::Type (NodeId index)
{
return m_fileContent->getVObjects ()[index].m_type;
}
unsigned int&
SV3_1aTreeShapeHelper::Line (NodeId index)
{
return m_fileContent->getVObjects ()[index].m_line;
}
void
SV3_1aTreeShapeHelper::addNestedDesignElement (ParserRuleContext* ctx, std::string name, DesignElement::ElemType elemtype, VObjectType objtype)
{
SymbolId fileId;
unsigned int line = getFileLine(ctx, fileId);
DesignElement elem (registerSymbol (name), fileId, elemtype,
generateDesignElemId (), line, 0);
elem.m_context = ctx;
elem.m_timeInfo = m_pf->getCompilationUnit ()->getTimeInfo (m_pf->getFileId (line), line);
if (m_nestedElements.size ())
{
elem.m_timeInfo = m_nestedElements.top ()->m_timeInfo;
elem.m_parent = m_nestedElements.top ()->m_uniqueId;
}
m_fileContent->getDesignElements ().push_back (elem);
m_currentElement = &m_fileContent->getDesignElements ().back ();
m_nestedElements.push (m_currentElement);
}
void
SV3_1aTreeShapeHelper::addDesignElement (ParserRuleContext* ctx, std::string name, DesignElement::ElemType elemtype, VObjectType objtype)
{
SymbolId fileId;
unsigned int line = getFileLine(ctx, fileId);
DesignElement elem (registerSymbol (name), fileId, elemtype,
generateDesignElemId (), line, 0);
elem.m_context = ctx;
elem.m_timeInfo = m_pf->getCompilationUnit ()->getTimeInfo (m_pf->getFileId (line), line);
m_fileContent->getDesignElements ().push_back (elem);
m_currentElement = &m_fileContent->getDesignElements ().back ();
}
unsigned int SV3_1aTreeShapeHelper::getFileLine(ParserRuleContext* ctx, SymbolId& fileId)
{
std::pair<int, int> lineCol = ParseUtils::getLineColumn (m_tokens, ctx);
unsigned int line = 0;
if (m_ppOutputFileLocation)
{
fileId = m_pf->getFileId(0);
line = lineCol.first;
}
else
{
fileId = m_pf->getFileId (lineCol.first + m_lineOffset);
line = m_pf->getLineNb (lineCol.first + m_lineOffset);
}
return line;
}
int
SV3_1aTreeShapeHelper::addVObject (ParserRuleContext* ctx, std::string name, VObjectType objtype)
{
SymbolId fileId;
unsigned int line = getFileLine(ctx, fileId);
VObject object (registerSymbol (name), fileId, objtype, line, 0);
m_fileContent->getVObjects ().push_back (object);
int objectIndex = m_fileContent->getVObjects ().size () - 1;
m_contextToObjectMap.insert (std::make_pair (ctx, objectIndex));
addParentChildRelations (objectIndex, ctx);
if (m_fileContent->getDesignElements ().size())
{
for (unsigned int i = 0; i <= m_fileContent->getDesignElements ().size () - 1; i++)
{
DesignElement& elem = m_fileContent->getDesignElements ()[m_fileContent->getDesignElements ().size () - 1 - i];
if (elem.m_context == ctx)
{
// Use the file and line number of the design object (package, module), true file/line when splitting
m_fileContent->getVObjects ().back ().m_fileId = elem.m_fileId;
m_fileContent->getVObjects ().back ().m_line = elem.m_line;
elem.m_node = objectIndex;
break;
}
}
}
return objectIndex;
}
int
SV3_1aTreeShapeHelper::addVObject (ParserRuleContext* ctx, VObjectType objtype)
{
SymbolId fileId;
unsigned int line = getFileLine(ctx, fileId);
VObject object (0, fileId, objtype, line, 0);
m_fileContent->getVObjects ().push_back (object);
int objectIndex = m_fileContent->getVObjects ().size () - 1;
m_contextToObjectMap.insert (std::make_pair (ctx, objectIndex));
addParentChildRelations (objectIndex, ctx);
if (m_fileContent->getDesignElements ().size())
{
for (unsigned int i = 0; i <= m_fileContent->getDesignElements ().size () - 1; i++)
{
DesignElement& elem = m_fileContent->getDesignElements ()[m_fileContent->getDesignElements ().size () - 1 - i];
if (elem.m_context == ctx)
{
// Use the file and line number of the design object (package, module), true file/line when splitting
m_fileContent->getVObjects ().back ().m_fileId = elem.m_fileId;
m_fileContent->getVObjects ().back ().m_line = elem.m_line;
elem.m_node = objectIndex;
break;
}
}
}
return objectIndex;
}
void
SV3_1aTreeShapeHelper::addParentChildRelations (int indexParent, ParserRuleContext* ctx)
{
int currentIndex = indexParent;
for (tree::ParseTree* child : ctx->children)
{
int childIndex = ObjectIndexFromContext (child);
if (childIndex != -1)
{
Parent (childIndex) = UniqueId (indexParent);
if (currentIndex == indexParent)
{
Child (indexParent) = UniqueId (childIndex);
}
else
{
Sibling (currentIndex) = UniqueId (childIndex);
}
currentIndex = childIndex;
}
}
}
NodeId
SV3_1aTreeShapeHelper::getObjectId (ParserRuleContext* ctx)
{
ContextToObjectMap::iterator itr = m_contextToObjectMap.find (ctx);
if (itr == m_contextToObjectMap.end ())
{
return 0;
}
else
{
return (*itr).second;
}
}
std::pair<double, TimeInfo::Unit>
SV3_1aTreeShapeHelper::getTimeValue (SV3_1aParser::Time_literalContext* ctx)
{
double actual_value = 0;
TimeInfo::Unit unit = TimeInfo::Second;
if (ctx->Integral_number ())
actual_value = atoi (ctx->Integral_number ()->getText ().c_str ());
if (ctx->Real_number ())
actual_value = atoi (ctx->Real_number ()->getText ().c_str ());
unit = TimeInfo::unitFromString (ctx->time_unit ()->getText ());
return std::make_pair (actual_value, unit);
}