| /* |
| 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: CheckCompile.cpp |
| * Author: alain |
| * |
| * Created on June 10, 2017, 10:15 PM |
| */ |
| #include <iostream> |
| #include <set> |
| #include "SymbolTable.h" |
| #include "../Design/TimeInfo.h" |
| #include "../Design/DesignElement.h" |
| #include "../Design/FileContent.h" |
| #include "../ErrorReporting/Location.h" |
| #include "../ErrorReporting/Error.h" |
| #include "../ErrorReporting/ErrorDefinition.h" |
| #include "../ErrorReporting/ErrorContainer.h" |
| #include "CompilationUnit.h" |
| #include "PreprocessFile.h" |
| #include "CompileSourceFile.h" |
| #include "Compiler.h" |
| #include "ParseFile.h" |
| #include "../CommandLine/CommandLineParser.hpp" |
| #include "CheckCompile.h" |
| |
| using namespace SURELOG; |
| |
| CheckCompile::~CheckCompile() { |
| } |
| |
| bool CheckCompile::check() { |
| if (!mergeSymbolTables_()) return false; |
| if (!checkTimescale_()) return false; |
| return true; |
| } |
| |
| bool |
| CheckCompile::mergeSymbolTables_ () |
| { |
| Design::FileIdDesignContentMap& all_files = m_compiler->getDesign()->getAllFileContents(); |
| for (auto fitr = all_files.begin (); |
| fitr != all_files.end (); fitr++) |
| { |
| auto fileContent = (*fitr).second; |
| m_compiler->getSymbolTable ()->registerSymbol(fileContent->getFileName ()); |
| for (NodeId id : fileContent->getNodeIds ()) |
| { |
| fileContent->getFileId (id) = m_compiler->getSymbolTable ()->registerSymbol (fileContent->getSymbolTable ()->getSymbol (fileContent->getFileId (id))); |
| } |
| for (DesignElement& elem : fileContent->getDesignElements ()) |
| { |
| elem.m_name = m_compiler->getSymbolTable ()->registerSymbol (fileContent->getSymbolTable ()->getSymbol (elem.m_name)); |
| elem.m_fileId = m_compiler->getSymbolTable ()->registerSymbol(fileContent->getSymbolTable ()->getSymbol (fileContent->getFileId(elem.m_node))); |
| } |
| } |
| return true; |
| } |
| |
| bool |
| CheckCompile::checkTimescale_ () |
| { |
| std::string globaltimescale = m_compiler->getCommandLineParser ()->getTimeScale (); |
| if (globaltimescale != "") |
| { |
| Location loc (0, 0, 0, m_compiler->getSymbolTable ()->registerSymbol(globaltimescale)); |
| Error err (ErrorDefinition::CMD_USING_GLOBAL_TIMESCALE, loc); |
| m_compiler->getErrorContainer ()->addError (err); |
| return true; |
| } |
| |
| bool timeUnitUsed = false; |
| bool timeScaleUsed = false; |
| std::vector<Location> noTimeUnitLocs; |
| Design::FileIdDesignContentMap& all_files = m_compiler->getDesign ()->getAllFileContents (); |
| std::unordered_set<SymbolId> reportedMissingTimescale; |
| std::unordered_set<SymbolId> reportedMissingTimeunit; |
| for (auto fitr = all_files.begin (); |
| fitr != all_files.end (); fitr++) |
| { |
| auto fileContent = (*fitr).second; |
| for (auto elem : fileContent->getDesignElements ()) |
| { |
| if (elem.m_type == DesignElement::Module || elem.m_type == DesignElement::Interface |
| || elem.m_type == DesignElement::Package || elem.m_type == DesignElement::Primitive |
| || elem.m_type == DesignElement::Program) |
| { |
| if (elem.m_timeInfo.m_type == TimeInfo::TimeUnitTimePrecision) |
| { |
| timeUnitUsed = true; |
| } |
| else if (elem.m_timeInfo.m_type == TimeInfo::Timescale) |
| { |
| timeScaleUsed = true; |
| Location loc (m_compiler->getSymbolTable ()->registerSymbol (fileContent->getSymbolTable ()->getSymbol (fileContent->getFileId (elem.m_node))), elem.m_line, 0, elem.m_name); |
| noTimeUnitLocs.push_back (loc); |
| } |
| else |
| { |
| Location loc (m_compiler->getSymbolTable ()->registerSymbol (fileContent->getSymbolTable ()->getSymbol (fileContent->getFileId (elem.m_node))), elem.m_line, 0, elem.m_name); |
| noTimeUnitLocs.push_back (loc); |
| if (reportedMissingTimescale.find (elem.m_name) == reportedMissingTimescale.end ()) |
| { |
| reportedMissingTimescale.insert (elem.m_name); |
| Error err (ErrorDefinition::PA_NOTIMESCALE_INFO, loc); |
| m_compiler->getErrorContainer ()->addError (err); |
| } |
| } |
| } |
| } |
| } |
| if (timeUnitUsed && timeScaleUsed) |
| { |
| for (auto loc : noTimeUnitLocs) |
| { |
| if (reportedMissingTimeunit.find (loc.m_object) == reportedMissingTimeunit.end ()) |
| { |
| reportedMissingTimeunit.insert (loc.m_object); |
| Error err (ErrorDefinition::PA_MISSING_TIMEUNIT, loc); |
| m_compiler->getErrorContainer ()->addError (err); |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| |