| /* |
| 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); |
| } |
| |
| |
| |
| |