From 67426928762dd68e34a95511a63cf783c673e1c5 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sat, 28 Mar 2026 19:13:35 -0700 Subject: [PATCH 1/9] string squash Signed-off-by: James Cherry --- CMakeLists.txt | 2 +- app/Main.cc | 33 +- app/StaMain.cc | 12 +- dcalc/ArcDelayCalc.cc | 18 +- dcalc/ArnoldiDelayCalc.cc | 2 +- dcalc/CcsCeffDelayCalc.cc | 2 +- dcalc/CcsCeffDelayCalc.hh | 4 +- dcalc/DelayCalc.cc | 12 +- dcalc/DelayCalc.i | 2 + dcalc/DelayCalcBase.cc | 2 +- dcalc/DelayCalcBase.hh | 2 +- dcalc/DmpCeff.cc | 13 +- dcalc/DmpDelayCalc.cc | 4 +- dcalc/GraphDelayCalc.cc | 4 +- dcalc/LumpedCapDelayCalc.hh | 2 +- dcalc/PrimaDelayCalc.cc | 9 +- dcalc/PrimaDelayCalc.hh | 10 +- dcalc/UnitDelayCalc.cc | 2 +- dcalc/UnitDelayCalc.hh | 4 +- doc/ApiChanges.txt | 29 +- graph/Graph.cc | 34 +- graph/Graph.i | 9 +- include/sta/ArcDelayCalc.hh | 17 +- include/sta/Clock.hh | 25 +- include/sta/ClockGroups.hh | 2 +- include/sta/ConcreteLibrary.hh | 63 +- include/sta/ConcreteNetwork.hh | 114 +-- include/sta/ContainerHelpers.hh | 66 +- include/sta/Debug.hh | 10 +- include/sta/DelayCalc.hh | 7 +- include/sta/EnumNameMap.hh | 22 +- include/sta/Error.hh | 16 +- include/sta/ExceptionPath.hh | 19 +- include/sta/Graph.hh | 4 +- include/sta/Hash.hh | 3 +- include/sta/Liberty.hh | 149 ++-- include/sta/LinearModel.hh | 2 +- include/sta/Mode.hh | 2 +- include/sta/Network.hh | 135 ++- include/sta/NetworkClass.hh | 2 +- include/sta/Parasitics.hh | 2 +- include/sta/PathGroup.hh | 23 +- include/sta/PatternMatch.hh | 30 +- include/sta/PocvMode.hh | 6 +- include/sta/PortDirection.hh | 2 +- include/sta/PowerClass.hh | 2 +- include/sta/Property.hh | 49 +- include/sta/Report.hh | 6 +- include/sta/ReportTcl.hh | 6 +- include/sta/Sdc.hh | 31 +- include/sta/SdcCmdComment.hh | 14 +- include/sta/SdcNetwork.hh | 93 ++- include/sta/SearchClass.hh | 1 - include/sta/Sta.hh | 80 +- include/sta/StaMain.hh | 6 +- include/sta/StringUtil.hh | 102 +-- include/sta/TableModel.hh | 43 +- include/sta/TclTypeHelpers.hh | 12 +- include/sta/TimingArc.hh | 14 +- include/sta/TimingModel.hh | 3 +- include/sta/Transition.hh | 33 +- include/sta/Units.hh | 2 +- include/sta/VerilogReader.hh | 70 +- include/sta/Wireload.hh | 20 +- liberty/EquivCells.cc | 8 +- liberty/InternalPower.cc | 2 +- liberty/LibExprLex.ll | 8 +- liberty/LibExprParse.yy | 24 +- liberty/LibExprReader.cc | 29 +- liberty/LibExprReader.hh | 6 +- liberty/LibExprReaderPvt.hh | 17 +- liberty/Liberty.cc | 258 +++--- liberty/Liberty.i | 23 +- liberty/LibertyBuilder.cc | 33 +- liberty/LibertyBuilder.hh | 19 +- liberty/LibertyExt.cc | 22 +- liberty/LibertyParse.yy | 4 +- liberty/LibertyParser.cc | 188 ++--- liberty/LibertyParser.hh | 71 +- liberty/LibertyReader.cc | 1171 +++++++++++++-------------- liberty/LibertyReader.hh | 4 +- liberty/LibertyReaderPvt.hh | 128 +-- liberty/LibertyScanner.hh | 5 +- liberty/LibertyWriter.cc | 8 +- liberty/LinearModel.cc | 2 +- liberty/TableModel.cc | 66 +- liberty/TimingArc.cc | 26 +- liberty/Units.cc | 16 +- liberty/Wireload.cc | 30 +- network/ConcreteLibrary.cc | 111 +-- network/ConcreteNetwork.cc | 144 ++-- network/Network.cc | 245 +++--- network/Network.i | 26 +- network/NetworkCmp.cc | 2 +- network/SdcNetwork.cc | 251 +++--- network/VerilogNamespace.cc | 4 +- parasitics/ConcreteParasitics.cc | 6 +- parasitics/ConcreteParasitics.hh | 5 +- parasitics/ConcreteParasiticsPvt.hh | 3 +- parasitics/SpefLex.ll | 12 +- parasitics/SpefNamespace.cc | 71 +- parasitics/SpefNamespace.hh | 22 +- parasitics/SpefParse.yy | 157 ++-- parasitics/SpefReader.cc | 181 ++--- parasitics/SpefReader.hh | 3 +- parasitics/SpefReaderPvt.hh | 51 +- parasitics/SpefScanner.hh | 8 +- power/Power.cc | 42 +- power/Power.hh | 8 +- power/ReportPower.cc | 44 +- power/ReportPower.hh | 44 +- power/SaifLex.ll | 9 +- power/SaifParse.yy | 51 +- power/SaifReader.cc | 34 +- power/SaifReaderPvt.hh | 10 +- power/VcdParse.cc | 7 +- power/VcdParse.hh | 18 +- power/VcdReader.cc | 60 +- power/VcdReader.hh | 6 +- sdc/Clock.cc | 21 +- sdc/ClockGroups.cc | 4 +- sdc/DisabledPorts.cc | 19 +- sdc/ExceptionPath.cc | 22 +- sdc/Sdc.cc | 46 +- sdc/Sdc.i | 164 ++-- sdc/SdcCmdComment.cc | 32 +- sdc/WriteSdc.cc | 162 ++-- sdc/WriteSdc.hh | 6 +- sdc/WriteSdcPvt.hh | 64 +- sdf/ReportAnnotation.cc | 12 +- sdf/Sdf.i | 18 +- sdf/SdfLex.ll | 18 +- sdf/SdfParse.yy | 66 +- sdf/SdfReader.cc | 324 ++++---- sdf/SdfReader.hh | 9 +- sdf/SdfReaderPvt.hh | 66 +- sdf/SdfScanner.hh | 8 +- sdf/SdfWriter.cc | 48 +- sdf/SdfWriter.hh | 4 +- search/CheckMinPulseWidths.cc | 2 +- search/ClkLatency.cc | 2 +- search/ClkSkew.cc | 16 +- search/MakeTimingModel.cc | 16 +- search/MakeTimingModel.hh | 8 +- search/MakeTimingModelPvt.hh | 14 +- search/Mode.cc | 2 +- search/PathGroup.cc | 33 +- search/PocvMode.cc | 4 +- search/Property.cc | 103 ++- search/ReportPath.cc | 411 +++++----- search/ReportPath.hh | 117 +-- search/Search.cc | 22 +- search/Search.i | 27 +- search/Sim.cc | 6 +- search/Sta.cc | 163 ++-- spice/WritePathSpice.cc | 70 +- spice/WritePathSpice.hh | 14 +- spice/WriteSpice.cc | 203 +++-- spice/WriteSpice.hh | 57 +- spice/Xyce.cc | 3 +- tcl/StaTclTypes.i | 154 ++-- tcl/TclTypeHelpers.cc | 32 +- tcl/Util.tcl | 1 - util/Debug.cc | 28 +- util/Error.cc | 10 +- util/Hash.cc | 9 +- util/MinMax.cc | 22 +- util/PatternMatch.cc | 129 ++- util/Report.cc | 18 +- util/ReportTcl.cc | 6 +- util/StringUtil.cc | 124 +-- util/Transition.cc | 42 +- util/Util.i | 26 +- verilog/VerilogLex.ll | 22 +- verilog/VerilogParse.yy | 166 ++-- verilog/VerilogReader.cc | 415 ++++------ verilog/VerilogReaderPvt.hh | 14 +- verilog/VerilogScanner.hh | 11 +- verilog/VerilogWriter.cc | 44 +- 179 files changed, 4256 insertions(+), 4745 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index db29b2af..d843dcfe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.14) cmake_policy(SET CMP0086 NEW) endif() -project(STA VERSION 3.0.1 +project(STA VERSION 3.1.0 LANGUAGES CXX ) diff --git a/app/Main.cc b/app/Main.cc index aa28aed8..8134b35e 100644 --- a/app/Main.cc +++ b/app/Main.cc @@ -28,6 +28,7 @@ #include #include // exit #include +#include #include #if TCL_READLINE #include @@ -58,14 +59,14 @@ static char **cmd_argv; static const char *init_filename = ".sta"; static void -showUsage(const char *prog, - const char *init_filename); +showUsage(std::string_view prog, + std::string_view init_filename); static int tclAppInit(Tcl_Interp *interp); static int staTclAppInit(int argc, char *argv[], - const char *init_filename, + std::string_view init_filename, Tcl_Interp *interp); static void initStaApp(int &argc, @@ -105,7 +106,7 @@ tclAppInit(Tcl_Interp *interp) static int staTclAppInit(int argc, char *argv[], - const char *init_filename, + std::string_view init_filename, Tcl_Interp *interp) { // source init.tcl @@ -130,7 +131,7 @@ staTclAppInit(int argc, if (home) { std::string init_path = home; init_path += "/"; - init_path += init_filename; + init_path.append(init_filename); if (std::filesystem::is_regular_file(init_path.c_str())) sourceTclFile(init_path.c_str(), true, true, interp); } @@ -183,15 +184,17 @@ initStaApp(int &argc, } static void -showUsage(const char *prog, - const char *init_filename) +showUsage(std::string_view prog, + std::string_view init_filename) { - printf("Usage: %s [-help] [-version] [-no_init] [-exit] cmd_file\n", prog); - printf(" -help show help and exit\n"); - printf(" -version show version and exit\n"); - printf(" -no_init do not read %s init file\n", init_filename); - printf(" -threads count|max use count threads\n"); - printf(" -no_splash do not show the license splash at startup\n"); - printf(" -exit exit after reading cmd_file\n"); - printf(" cmd_file source cmd_file\n"); + sta::print(stdout, "Usage: {} [-help] [-version] [-no_init] [-exit] cmd_file\n", + prog); + sta::print(stdout, " -help show help and exit\n"); + sta::print(stdout, " -version show version and exit\n"); + sta::print(stdout, " -no_init do not read {} init file\n", + init_filename); + sta::print(stdout, " -threads count|max use count threads\n"); + sta::print(stdout, " -no_splash do not show the license splash at startup\n"); + sta::print(stdout, " -exit exit after reading cmd_file\n"); + sta::print(stdout, " cmd_file source cmd_file\n"); } diff --git a/app/StaMain.cc b/app/StaMain.cc index 079112e1..f2eda7ae 100644 --- a/app/StaMain.cc +++ b/app/StaMain.cc @@ -24,6 +24,8 @@ #include "StaMain.hh" +#include +#include #include #include #include @@ -43,7 +45,7 @@ parseThreadsArg(int &argc, if (stringEqual(thread_arg, "max")) return processorCount(); else if (isDigits(thread_arg)) - return atoi(thread_arg); + return std::stoi(thread_arg); else fprintf(stderr,"Warning: -threads must be max or a positive integer.\n"); } @@ -53,11 +55,11 @@ parseThreadsArg(int &argc, bool findCmdLineFlag(int &argc, char *argv[], - const char *flag) + std::string_view flag) { for (int i = 1; i < argc; i++) { char *arg = argv[i]; - if (stringEq(arg, flag)) { + if (std::string_view(arg) == flag) { // Remove flag from argv. for (int j = i + 1; j < argc; j++, i++) argv[i] = argv[j]; @@ -72,11 +74,11 @@ findCmdLineFlag(int &argc, char * findCmdLineKey(int &argc, char *argv[], - const char *key) + std::string_view key) { for (int i = 1; i < argc; i++) { char *arg = argv[i]; - if (stringEq(arg, key) && i + 1 < argc) { + if (std::string_view(arg) == key && i + 1 < argc) { char *value = argv[i + 1]; // Remove key and value from argv. for (int j = i + 2; j < argc; j++, i++) diff --git a/dcalc/ArcDelayCalc.cc b/dcalc/ArcDelayCalc.cc index 86759411..a2a1ad0e 100644 --- a/dcalc/ArcDelayCalc.cc +++ b/dcalc/ArcDelayCalc.cc @@ -25,7 +25,9 @@ #include "ArcDelayCalc.hh" #include +#include +#include "StringUtil.hh" #include "Units.hh" #include "Liberty.hh" #include "TimingArc.hh" @@ -61,13 +63,14 @@ ArcDelayCalc::gateDelay(const TimingArc *arc, //////////////////////////////////////////////////////////////// +// For TCL %typemap(in) ArcDcalcArg. ArcDcalcArg -makeArcDcalcArg(const char *inst_name, - const char *in_port_name, - const char *in_rf_name, - const char *drvr_port_name, - const char *drvr_rf_name, - const char *input_delay_str, +makeArcDcalcArg(std::string_view inst_name, + std::string_view in_port_name, + std::string_view in_rf_name, + std::string_view drvr_port_name, + std::string_view drvr_rf_name, + std::string_view input_delay_str, const StaState *sta) { Report *report = sta->report(); @@ -82,7 +85,8 @@ makeArcDcalcArg(const char *inst_name, if (drvr_pin) { const RiseFall *drvr_rf = RiseFall::find(drvr_rf_name); if (drvr_rf) { - float input_delay = strtof(input_delay_str, nullptr); + const std::string input_delay_buf(input_delay_str); + auto [input_delay, valid] = stringFloat(input_delay_buf); input_delay = sta->units()->timeUnit()->userToSta(input_delay); const Graph *graph = sta->graph(); diff --git a/dcalc/ArnoldiDelayCalc.cc b/dcalc/ArnoldiDelayCalc.cc index c85d1998..97866a79 100644 --- a/dcalc/ArnoldiDelayCalc.cc +++ b/dcalc/ArnoldiDelayCalc.cc @@ -121,7 +121,7 @@ public: ArnoldiDelayCalc(StaState *sta); ~ArnoldiDelayCalc() override; ArcDelayCalc *copy() override; - const char *name() const override { return "arnoldi"; } + std::string_view name() const override { return "arnoldi"; } Parasitic *findParasitic(const Pin *drvr_pin, const RiseFall *rf, const Scene *scene, diff --git a/dcalc/CcsCeffDelayCalc.cc b/dcalc/CcsCeffDelayCalc.cc index 3c4e82b4..6ca9cb96 100644 --- a/dcalc/CcsCeffDelayCalc.cc +++ b/dcalc/CcsCeffDelayCalc.cc @@ -670,7 +670,7 @@ CcsCeffDelayCalc::reportGateDelay(const Pin *drvr_pin, } void -CcsCeffDelayCalc::fail(const char *reason) +CcsCeffDelayCalc::fail(std::string_view reason) { // Report failures with a unique debug flag. if (debug_->check("ccs_dcalc", 1) || debug_->check("dcalc_error", 1)) diff --git a/dcalc/CcsCeffDelayCalc.hh b/dcalc/CcsCeffDelayCalc.hh index 46125a94..665588f8 100644 --- a/dcalc/CcsCeffDelayCalc.hh +++ b/dcalc/CcsCeffDelayCalc.hh @@ -41,7 +41,7 @@ public: CcsCeffDelayCalc(StaState *sta); virtual ~CcsCeffDelayCalc(); ArcDelayCalc *copy() override; - const char *name() const override { return "ccs_ceff"; } + std::string_view name() const override { return "ccs_ceff"; } bool reduceSupported() const override { return true; } ArcDcalcResult gateDelay(const Pin *drvr_pin, const TimingArc *arc, @@ -113,7 +113,7 @@ protected: double &dvl_dt); double vl(double t, double elmore); - void fail(const char *reason); + void fail(std::string_view reason); const Pin *drvr_pin_; const RiseFall *drvr_rf_; diff --git a/dcalc/DelayCalc.cc b/dcalc/DelayCalc.cc index c149d6cb..614ff610 100644 --- a/dcalc/DelayCalc.cc +++ b/dcalc/DelayCalc.cc @@ -38,7 +38,7 @@ namespace sta { -typedef std::map DelayCalcMap; +typedef std::map> DelayCalcMap; static DelayCalcMap delay_calcs; @@ -55,10 +55,10 @@ registerDelayCalcs() } void -registerDelayCalc(const std::string &name, +registerDelayCalc(std::string_view name, MakeArcDelayCalc maker) { - delay_calcs[name] = maker; + delay_calcs[std::string(name)] = maker; } void @@ -68,10 +68,10 @@ deleteDelayCalcs() } ArcDelayCalc * -makeDelayCalc(const std::string &name, +makeDelayCalc(const std::string_view name, StaState *sta) { - MakeArcDelayCalc maker = findKey(&delay_calcs, name); + MakeArcDelayCalc maker = findStringKey(delay_calcs, name); if (maker) return maker(sta); else @@ -79,7 +79,7 @@ makeDelayCalc(const std::string &name, } bool -isDelayCalcName(const std::string &name) +isDelayCalcName(std::string_view name) { return delay_calcs.contains(name); } diff --git a/dcalc/DelayCalc.i b/dcalc/DelayCalc.i index 7577f0e5..992ecade 100644 --- a/dcalc/DelayCalc.i +++ b/dcalc/DelayCalc.i @@ -24,6 +24,8 @@ %module dcalc +%include + %{ #include "DelayCalc.hh" diff --git a/dcalc/DelayCalcBase.cc b/dcalc/DelayCalcBase.cc index f153e44c..71e2f116 100644 --- a/dcalc/DelayCalcBase.cc +++ b/dcalc/DelayCalcBase.cc @@ -174,7 +174,7 @@ std::string DelayCalcBase::reportCheckDelay(const Pin *check_pin, const TimingArc *arc, const Slew &from_slew, - const char *from_slew_annotation, + std::string_view from_slew_annotation, const Slew &to_slew, float related_out_cap, const Scene *scene, diff --git a/dcalc/DelayCalcBase.hh b/dcalc/DelayCalcBase.hh index faaa4358..da69ed1b 100644 --- a/dcalc/DelayCalcBase.hh +++ b/dcalc/DelayCalcBase.hh @@ -58,7 +58,7 @@ public: std::string reportCheckDelay(const Pin *check_pin, const TimingArc *arc, const Slew &from_slew, - const char *from_slew_annotation, + std::string_view from_slew_annotation, const Slew &to_slew, float related_out_cap, const Scene *scene, diff --git a/dcalc/DmpCeff.cc b/dcalc/DmpCeff.cc index 1cccadaf..577bce5c 100644 --- a/dcalc/DmpCeff.cc +++ b/dcalc/DmpCeff.cc @@ -35,6 +35,7 @@ #include #include #include +#include #include "Format.hh" #include "Report.hh" @@ -126,7 +127,7 @@ public: DmpAlg(int nr_order, StaState *sta); ~DmpAlg() override = default; - virtual const char *name() = 0; + virtual std::string_view name() = 0; // Set driver model and pi model parameters for delay calculation. virtual void init(const LibertyLibrary *library, const LibertyCell *drvr_cell, @@ -201,7 +202,7 @@ protected: double lower_bound, double upper_bound); void showVl(); - void fail(const char *reason); + void fail(std::string_view reason); // Output response to vs(t) ramp driving capacitive load. double y(double t, @@ -655,7 +656,7 @@ DmpAlg::showVl() } void -DmpAlg::fail(const char *reason) +DmpAlg::fail(std::string_view reason) { // Report failures with a unique debug flag. if (debug_->check("dmp_ceff", 1) || debug_->check("dcalc_error", 1)) @@ -673,7 +674,7 @@ class DmpCap : public DmpAlg { public: DmpCap(StaState *sta); - const char *name() override { return "cap"; } + std::string_view name() override { return "cap"; } void init(const LibertyLibrary *library, const LibertyCell *drvr_cell, const Pvt *pvt, @@ -789,7 +790,7 @@ class DmpPi : public DmpAlg { public: DmpPi(StaState *sta); - const char *name() override { return "Pi"; } + std::string_view name() override { return "Pi"; } void init(const LibertyLibrary *library, const LibertyCell *drvr_cell, const Pvt *pvt, @@ -1115,7 +1116,7 @@ class DmpZeroC2 : public DmpOnePole { public: DmpZeroC2(StaState *sta); - const char *name() override { return "c2=0"; } + std::string_view name() override { return "c2=0"; } void init(const LibertyLibrary *drvr_library, const LibertyCell *drvr_cell, const Pvt *pvt, diff --git a/dcalc/DmpDelayCalc.cc b/dcalc/DmpDelayCalc.cc index aece357e..3fefc53b 100644 --- a/dcalc/DmpDelayCalc.cc +++ b/dcalc/DmpDelayCalc.cc @@ -43,7 +43,7 @@ class DmpCeffElmoreDelayCalc : public DmpCeffDelayCalc public: DmpCeffElmoreDelayCalc(StaState *sta); ArcDelayCalc *copy() override; - const char *name() const override { return "dmp_ceff_elmore"; } + std::string_view name() const override { return "dmp_ceff_elmore"; } ArcDcalcResult inputPortDelay(const Pin *port_pin, float in_slew, const RiseFall *rf, @@ -139,7 +139,7 @@ class DmpCeffTwoPoleDelayCalc : public DmpCeffDelayCalc public: DmpCeffTwoPoleDelayCalc(StaState *sta); ArcDelayCalc *copy() override; - const char *name() const override { return "dmp_ceff_two_pole"; } + std::string_view name() const override { return "dmp_ceff_two_pole"; } Parasitic *findParasitic(const Pin *drvr_pin, const RiseFall *rf, const Scene *scene, diff --git a/dcalc/GraphDelayCalc.cc b/dcalc/GraphDelayCalc.cc index 9c95ed1b..bcfb9cc0 100644 --- a/dcalc/GraphDelayCalc.cc +++ b/dcalc/GraphDelayCalc.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include "ContainerHelpers.hh" #include "Debug.hh" @@ -1685,7 +1686,8 @@ GraphDelayCalc::reportDelayCalc(const Edge *edge, const Slew to_slew = graph_->slew(to_vertex, to_rf, slew_index); const ClkNetwork *clk_network = scene->mode()->clkNetwork(); bool from_ideal_clk = clk_network->isIdealClock(from_vertex); - const char *from_slew_annotation = from_ideal_clk ? " (ideal clock)" : nullptr; + std::string_view from_slew_annotation = + from_ideal_clk ? std::string_view(" (ideal clock)") : std::string_view{}; result = arc_delay_calc_->reportCheckDelay(to_pin, arc, from_slew, from_slew_annotation, to_slew, related_out_cap, scene, min_max, digits); diff --git a/dcalc/LumpedCapDelayCalc.hh b/dcalc/LumpedCapDelayCalc.hh index 752edea9..eb2bf4f0 100644 --- a/dcalc/LumpedCapDelayCalc.hh +++ b/dcalc/LumpedCapDelayCalc.hh @@ -35,7 +35,7 @@ class LumpedCapDelayCalc : public ParallelDelayCalc public: LumpedCapDelayCalc(StaState *sta); ArcDelayCalc *copy() override; - const char *name() const override { return "lumped_cap"; } + std::string_view name() const override { return "lumped_cap"; } Parasitic *findParasitic(const Pin *drvr_pin, const RiseFall *rf, const Scene *scene, diff --git a/dcalc/PrimaDelayCalc.cc b/dcalc/PrimaDelayCalc.cc index fc1b0208..9cea3ea6 100644 --- a/dcalc/PrimaDelayCalc.cc +++ b/dcalc/PrimaDelayCalc.cc @@ -25,6 +25,7 @@ #include "PrimaDelayCalc.hh" #include // abs +#include #include "Debug.hh" #include "Units.hh" @@ -951,7 +952,7 @@ PrimaDelayCalc::watchWaveform(const Pin *pin) //////////////////////////////////////////////////////////////// void -PrimaDelayCalc::reportMatrix(const char *name, +PrimaDelayCalc::reportMatrix(std::string_view name, MatrixSd &matrix) { report_->report("{}", name); @@ -959,7 +960,7 @@ PrimaDelayCalc::reportMatrix(const char *name, } void -PrimaDelayCalc::reportMatrix(const char *name, +PrimaDelayCalc::reportMatrix(std::string_view name, Eigen::MatrixXd &matrix) { report_->report("{}", name); @@ -967,7 +968,7 @@ PrimaDelayCalc::reportMatrix(const char *name, } void -PrimaDelayCalc::reportMatrix(const char *name, +PrimaDelayCalc::reportMatrix(std::string_view name, Eigen::VectorXd &matrix) { report_->report("{}", name); @@ -975,7 +976,7 @@ PrimaDelayCalc::reportMatrix(const char *name, } void -PrimaDelayCalc::reportVector(const char *name, +PrimaDelayCalc::reportVector(std::string_view name, std::vector &matrix) { report_->report("{}", name); diff --git a/dcalc/PrimaDelayCalc.hh b/dcalc/PrimaDelayCalc.hh index c295478c..8ed47a05 100644 --- a/dcalc/PrimaDelayCalc.hh +++ b/dcalc/PrimaDelayCalc.hh @@ -60,7 +60,7 @@ public: ~PrimaDelayCalc(); ArcDelayCalc *copy() override; void copyState(const StaState *sta) override; - const char *name() const override { return "prima"; } + std::string_view name() const override { return "prima"; } void setPrimaReduceOrder(size_t order); Parasitic *findParasitic(const Pin *drvr_pin, const RiseFall *rf, @@ -157,13 +157,13 @@ protected: void primaReduce(); void primaReduce2(); - void reportMatrix(const char *name, + void reportMatrix(std::string_view name, MatrixSd &matrix); - void reportMatrix(const char *name, + void reportMatrix(std::string_view name, Eigen::MatrixXd &matrix); - void reportMatrix(const char *name, + void reportMatrix(std::string_view name, Eigen::VectorXd &matrix); - void reportVector(const char *name, + void reportVector(std::string_view name, std::vector &matrix); void reportMatrix(MatrixSd &matrix); void reportMatrix(Eigen::MatrixXd &matrix); diff --git a/dcalc/UnitDelayCalc.cc b/dcalc/UnitDelayCalc.cc index 61221c71..afda4922 100644 --- a/dcalc/UnitDelayCalc.cc +++ b/dcalc/UnitDelayCalc.cc @@ -172,7 +172,7 @@ std::string UnitDelayCalc::reportCheckDelay(const Pin *, const TimingArc *, const Slew &, - const char *, + std::string_view, const Slew &, float, const Scene *, diff --git a/dcalc/UnitDelayCalc.hh b/dcalc/UnitDelayCalc.hh index 7ae21aff..5e2a3079 100644 --- a/dcalc/UnitDelayCalc.hh +++ b/dcalc/UnitDelayCalc.hh @@ -34,7 +34,7 @@ class UnitDelayCalc : public ArcDelayCalc public: UnitDelayCalc(StaState *sta); ArcDelayCalc *copy() override; - const char *name() const override { return "unit"; } + std::string_view name() const override { return "unit"; } Parasitic *findParasitic(const Pin *drvr_pin, const RiseFall *rf, const Scene *scene, @@ -94,7 +94,7 @@ public: std::string reportCheckDelay(const Pin *check_pin, const TimingArc *arc, const Slew &from_slew, - const char *from_slew_annotation, + std::string_view from_slew_annotation, const Slew &to_slew, float related_out_cap, const Scene *scene, diff --git a/doc/ApiChanges.txt b/doc/ApiChanges.txt index 83759119..7b62f981 100644 --- a/doc/ApiChanges.txt +++ b/doc/ApiChanges.txt @@ -24,6 +24,33 @@ This file summarizes STA API changes for each release. +Release 3.1.0 2026/03/25 +------------------------ + +OpenSTA now uses std::string and std::string_view instead of const char *. +Lookup funtions such as Network::findPin use std::string_view that accept +a const char *, std::string, or std::string_view caller argument. + +2026/03/19 +---------- + +LibertyCell::footprint() returns const std::string& instead of const char*. +LibertyCell::userFunctionClass returns const std::string& instead of const char*. + +The Sdc, Liberty, ConcreteLibrary, ConcreteNetwork classes have been updated to +use std::string and std::string_view instead of const char *. std::string_view +is used when the lifetime of the string argument is only while the function is +called. std::string is used when the string value outlives the function call +because it is stored in data structures. + +The LibertyPort functions + relatedGroundPin + relatedPowerPin +are renamed to + relatedGroundPort + relatedPowerPort +and return LibertyPort's instead of strings. + 2026/03/12 ---------- @@ -37,7 +64,7 @@ stdstrPrint, strintPrint, stringAppend have been removed. Use sta::format. reportLineString is now reportLine -Release 3.0.0 2025/01/03 +Release 3.0.0 2026/01/03 ------------------------ OpenSTA now requires c++ 20. diff --git a/graph/Graph.cc b/graph/Graph.cc index 022504ca..ca65fe01 100644 --- a/graph/Graph.cc +++ b/graph/Graph.cc @@ -52,7 +52,7 @@ Graph::Graph(StaState *sta, vertices_(nullptr), edges_(nullptr), ap_count_(ap_count), - period_check_annotations_(nullptr), + period_check_annotations_(network_), reg_clk_vertices_(makeVertexSet(this)) { // For the benifit of reg_clk_vertices_ that references graph_. @@ -910,13 +910,11 @@ Graph::periodCheckAnnotation(const Pin *pin, bool &exists) { exists = false; - if (period_check_annotations_) { - float *periods = findKey(period_check_annotations_, pin); - if (periods) { - period = periods[ap_index]; - if (period >= 0.0) - exists = true; - } + float *periods = findKey(period_check_annotations_, pin); + if (periods) { + period = periods[ap_index]; + if (period >= 0.0) + exists = true; } } @@ -925,15 +923,13 @@ Graph::setPeriodCheckAnnotation(const Pin *pin, DcalcAPIndex ap_index, float period) { - if (period_check_annotations_ == nullptr) - period_check_annotations_ = new PeriodCheckAnnotations(network_); float *periods = findKey(period_check_annotations_, pin); if (periods == nullptr) { periods = new float[ap_count_]; // Use negative (illegal) period values to indicate unannotated checks. for (int i = 0; i < ap_count_; i++) periods[i] = -1; - (*period_check_annotations_)[pin] = periods; + period_check_annotations_[pin] = periods; } periods[ap_index] = period; } @@ -941,12 +937,9 @@ Graph::setPeriodCheckAnnotation(const Pin *pin, void Graph::removePeriodCheckAnnotations() { - if (period_check_annotations_) { - for (const auto [pin, periods] : *period_check_annotations_) - delete [] periods; - delete period_check_annotations_; - period_check_annotations_ = nullptr; - } + for (auto& [pin, periods] : period_check_annotations_) + delete [] periods; + period_check_annotations_.clear(); } void @@ -1026,7 +1019,7 @@ Vertex::to_string(const StaState *sta) const { const Network *network = sta->sdcNetwork(); if (network->direction(pin_)->isBidirect()) { - std::string str = network->pathName(pin_); + std::string str(network->pathName(pin_)); str += ' '; str += is_bidirect_drvr_ ? "driver" : "load"; return str; @@ -1035,11 +1028,10 @@ Vertex::to_string(const StaState *sta) const return network->pathName(pin_); } -const char * +std::string Vertex::name(const Network *network) const { - std::string name = to_string(network); - return makeTmpString(name); + return to_string(network); } bool diff --git a/graph/Graph.i b/graph/Graph.i index 85cb5124..371e929c 100644 --- a/graph/Graph.i +++ b/graph/Graph.i @@ -180,7 +180,7 @@ Vertex *to() { return self->to(Sta::sta()->graph()); } Pin *from_pin() { return self->from(Sta::sta()->graph())->pin(); } Pin *to_pin() { return self->to(Sta::sta()->graph())->pin(); } const TimingRole *role() { return self->role(); } -const char *sense() { return to_string(self->sense()); } +const char *sense() { return to_string(self->sense()).c_str(); } TimingArcSeq & timing_arcs() { return self->timingArcSet()->arcs(); } bool is_disabled_loop() { return Sta::sta()->isDisabledLoop(self); } @@ -212,13 +212,16 @@ disabled_constant_pins() bool is_disabled_bidirect_inst_path() { return Sta::sta()->isDisabledBidirectInstPath(self); } + bool is_disabled_preset_clear() { return Sta::sta()->isDisabledPresetClr(self); } + const char * -sim_timing_sense(){ +sim_timing_sense() +{ Sta *sta = Sta::sta(); const Mode *mode = sta->cmdMode(); - return to_string(sta->simTimingSense(self, mode)); + return to_string(sta->simTimingSense(self, mode)).c_str(); } FloatSeq diff --git a/include/sta/ArcDelayCalc.hh b/include/sta/ArcDelayCalc.hh index 45dcbae3..85e656d1 100644 --- a/include/sta/ArcDelayCalc.hh +++ b/include/sta/ArcDelayCalc.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include #include @@ -103,12 +104,12 @@ protected: ArcDcalcArg -makeArcDcalcArg(const char *inst_name, - const char *in_port_name, - const char *in_rf_name, - const char *drvr_port_name, - const char *drvr_rf_name, - const char *input_delay_str, +makeArcDcalcArg(std::string_view inst_name, + std::string_view in_port_name, + std::string_view in_rf_name, + std::string_view drvr_port_name, + std::string_view drvr_rf_name, + std::string_view input_delay_str, const StaState *sta); // Arc delay calc result. @@ -161,7 +162,7 @@ public: ArcDelayCalc(StaState *sta); virtual ~ArcDelayCalc() {} virtual ArcDelayCalc *copy() = 0; - virtual const char *name() const = 0; + virtual std::string_view name() const = 0; // Find the parasitic for drvr_pin that is acceptable to the delay // calculator by probing parasitics_. @@ -252,7 +253,7 @@ public: virtual std::string reportCheckDelay(const Pin *check_pin, const TimingArc *arc, const Slew &from_slew, - const char *from_slew_annotation, + std::string_view from_slew_annotation, const Slew &to_slew, float related_out_cap, const Scene *scene, diff --git a/include/sta/Clock.hh b/include/sta/Clock.hh index 06215222..4422212d 100644 --- a/include/sta/Clock.hh +++ b/include/sta/Clock.hh @@ -41,7 +41,7 @@ class Clock : public SdcCmdComment { public: ~Clock(); - const char *name() const { return name_; } + const std::string &name() const { return name_; } float period() const { return period_; } // Virtual clocks have no pins. bool isVirtual() const; @@ -135,14 +135,14 @@ public: protected: // Private to Sdc::makeClock. - Clock(const char *name, + Clock(std::string_view name, int index, const Network *network); void initClk(PinSet *pins, bool add_to_pins, float period, FloatSeq *waveform, - const char *comment, + std::string_view comment, const Network *network); void initGeneratedClk(PinSet *pins, bool add_to_pins, @@ -156,7 +156,7 @@ protected: IntSeq *edges, FloatSeq *edge_shifts, bool is_propagated, - const char *comment, + std::string_view comment, const Network *network); void setPins(PinSet *pins, const Network *network); @@ -168,7 +168,7 @@ protected: float scale); void generateEdgesClk(const Clock *src_clk); - const char *name_; + std::string name_; PinSet pins_; bool add_to_pins_; // Hierarchical pins in pins_ become driver pins through the pin. @@ -241,7 +241,10 @@ class ClockNameLess { public: bool operator()(const Clock *clk1, - const Clock *clk2); + const Clock *clk2) const + { + return clk1->name() < clk2->name(); + } }; //////////////////////////////////////////////////////////////// @@ -282,16 +285,6 @@ public: const InterClockUncertainty *inter2) const; }; -class ClkNameLess -{ -public: - bool operator()(const Clock *clk1, - const Clock *clk2) const - { - return stringLess(clk1->name(), clk2->name()); - } -}; - ClockSeq sortByName(ClockSet *set); int diff --git a/include/sta/ClockGroups.hh b/include/sta/ClockGroups.hh index 89159a82..63765088 100644 --- a/include/sta/ClockGroups.hh +++ b/include/sta/ClockGroups.hh @@ -39,7 +39,7 @@ public: bool physically_exclusive, bool asynchronous, bool allow_paths, - const char *comment); + std::string comment); ~ClockGroups(); void makeClockGroup(ClockSet *clks); const std::string &name() const { return name_; } diff --git a/include/sta/ConcreteLibrary.hh b/include/sta/ConcreteLibrary.hh index a47585dd..e3983076 100644 --- a/include/sta/ConcreteLibrary.hh +++ b/include/sta/ConcreteLibrary.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include #include @@ -45,9 +46,9 @@ class PatternMatch; class LibertyCell; class LibertyPort; -using ConcreteCellMap = std::map; +using ConcreteCellMap = std::map>; using ConcretePortSeq = std::vector; -using ConcretePortMap = std::map; +using ConcretePortMap = std::map>; using ConcreteLibraryCellIterator = MapIterator; using ConcreteCellPortIterator = VectorIterator; using ConcretePortMemberIterator = VectorIterator; @@ -55,22 +56,21 @@ using ConcretePortMemberIterator = VectorIterator port_msb_first); + std::function port_msb_first); size_t portCount() const; - void setName(const char *name); + void setName(std::string_view name); void addPort(ConcretePort *port); void addPortBit(ConcretePort *port); protected: - ConcreteCell(const char *name, - const char *filename, + ConcreteCell(std::string_view name, + std::string_view filename, bool is_leaf, ConcreteLibrary *library); - ConcretePort *makeBusPort(const char *name, + ConcretePort *makeBusPort(std::string_view name, int from_index, int to_index, ConcretePortSeq *members); void makeBusPortBits(ConcretePort *bus_port, - const char *name, + std::string_view bus_name, int from_index, int to_index); // Bus port bit (internal to makeBusPortBits). - ConcretePort *makePort(const char *bit_name, + ConcretePort *makePort(std::string bit_name, int bit_index); void makeBusPortBit(ConcretePort *bus_port, - const char *name, + std::string_view bus_name, int index); std::string name_; @@ -181,9 +180,9 @@ class ConcretePort { public: virtual ~ConcretePort(); - const char *name() const { return name_.c_str(); } + const std::string &name() const { return name_; } ObjectId id() const { return id_; } - const char *busName() const; + std::string busName() const; Cell *cell() const; ConcreteLibrary *library() const { return cell_->library(); } PortDirection *direction() const { return direction_; } @@ -231,7 +230,7 @@ public: protected: // Constructors for factory in cell class. - ConcretePort(const char *name, + ConcretePort(std::string_view name, bool is_bus, int from_index, int to_index, diff --git a/include/sta/ConcreteNetwork.hh b/include/sta/ConcreteNetwork.hh index 25ab0f91..b3a37793 100644 --- a/include/sta/ConcreteNetwork.hh +++ b/include/sta/ConcreteNetwork.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include #include #include @@ -47,9 +48,9 @@ class ConcreteBindingTbl; class ConcreteLibertyLibraryIterator; using ConcreteLibrarySeq = std::vector; -using ConcreteLibraryMap = std::map; -using ConcreteInstanceChildMap = std::map; -using ConcreteInstanceNetMap = std::map; +using ConcreteLibraryMap = std::map>; +using ConcreteInstanceChildMap = std::map>; +using ConcreteInstanceNetMap = std::map>; using ConcreteNetSeq = std::vector; using ConcretePinSeq = std::vector; using CellNetworkViewMap = std::map; @@ -63,26 +64,26 @@ public: ConcreteNetwork(); ~ConcreteNetwork(); void clear() override; - bool linkNetwork(const char *top_cell_name, + bool linkNetwork(std::string_view top_cell_name, bool make_black_boxes, Report *report) override; Instance *topInstance() const override; - const char *name(const Library *library) const override; + std::string name(const Library *library) const override; ObjectId id(const Library *library) const override; LibraryIterator *libraryIterator() const override; LibertyLibraryIterator *libertyLibraryIterator() const override; - Library *findLibrary(const char *name) override; - LibertyLibrary *findLiberty(const char *name) override; + Library *findLibrary(std::string_view name) override; + LibertyLibrary *findLiberty(std::string_view name) override; Cell *findCell(const Library *library, - const char *name) const override; - Cell *findAnyCell(const char *name) override; + std::string_view name) const override; + Cell *findAnyCell(std::string_view name) override; CellSeq findCellsMatching(const Library *library, const PatternMatch *pattern) const override; - const char *name(const Cell *cell) const override; + std::string name(const Cell *cell) const override; std::string getAttribute(const Cell *cell, - const std::string &key) const override; + std::string_view key) const override; const AttributeMap &attributeMap(const Cell *cell) const override; ObjectId id(const Cell *cell) const override; Library *library(const Cell *cell) const override; @@ -90,15 +91,15 @@ public: const LibertyCell *libertyCell(const Cell *cell) const override; Cell *cell(LibertyCell *cell) const override; const Cell *cell(const LibertyCell *cell) const override; - const char *filename(const Cell *cell) override; + std::string_view filename(const Cell *cell) const override; Port *findPort(const Cell *cell, - const char *name) const override; + std::string_view name) const override; bool isLeaf(const Cell *cell) const override; CellPortIterator *portIterator(const Cell *cell) const override; CellPortBitIterator *portBitIterator(const Cell *cell) const override; int portBitCount(const Cell *cell) const override; - const char *name(const Port *port) const override; + std::string name(const Port *port) const override; ObjectId id(const Port *port) const override; Cell *cell(const Port *port) const override; LibertyPort *libertyPort(const Port *port) const override; @@ -108,7 +109,7 @@ public: bool isBus(const Port *port) const override; int size(const Port *port) const override; - const char *busName(const Port *port) const override; + std::string busName(const Port *port) const override; Port *findBusBit(const Port *port, int index) const override; int fromIndex(const Port *port) const override; @@ -117,18 +118,18 @@ public: int index) const override; PortMemberIterator *memberIterator(const Port *port) const override; - const char *name(const Instance *instance) const override; + std::string name(const Instance *instance) const override; std::string getAttribute(const Instance *inst, - const std::string &key) const override; + std::string_view key) const override; const AttributeMap &attributeMap(const Instance *inst) const override; ObjectId id(const Instance *instance) const override; Cell *cell(const Instance *instance) const override; Instance *parent(const Instance *instance) const override; bool isLeaf(const Instance *instance) const override; Instance *findChild(const Instance *parent, - const char *name) const override; + std::string_view name) const override; Pin *findPin(const Instance *instance, - const char *port_name) const override; + std::string_view port_name) const override; Pin *findPin(const Instance *instance, const Port *port) const override; @@ -153,10 +154,10 @@ public: Net *net(const Term *term) const override; Pin *pin(const Term *term) const override; - const char *name(const Net *net) const override; + std::string name(const Net *net) const override; ObjectId id(const Net *net) const override; Net *findNet(const Instance *instance, - const char *net_name) const override; + std::string_view net_name) const override; void findInstNetsMatching(const Instance *instance, const PatternMatch *pattern, NetSeq &matches) const override; @@ -174,44 +175,44 @@ public: LogicValue value) override; // Edit methods. - Library *makeLibrary(const char *name, - const char *filename) override; - LibertyLibrary *makeLibertyLibrary(const char *name, - const char *filename) override; + Library *makeLibrary(std::string_view name, + std::string_view filename) override; + LibertyLibrary *makeLibertyLibrary(std::string_view name, + std::string_view filename) override; void deleteLibrary(Library *library) override; Cell *makeCell(Library *library, - const char *name, + std::string_view name, bool is_leaf, - const char *filename) override; + std::string_view filename) override; void deleteCell(Cell *cell) override; void setName(Cell *cell, - const char *name) override; + std::string_view name) override; void setIsLeaf(Cell *cell, bool is_leaf) override; void setAttribute(Cell *cell, - const std::string &key, - const std::string &value) override; + std::string_view key, + std::string_view value) override; Port *makePort(Cell *cell, - const char *name) override; + std::string_view name) override; Port *makeBusPort(Cell *cell, - const char *name, + std::string_view name, int from_index, int to_index) override; void groupBusPorts(Cell *cell, - std::function port_msb_first) override; + std::function port_msb_first) override; Port *makeBundlePort(Cell *cell, - const char *name, + std::string_view name, PortSeq *members) override; void setDirection(Port *port, PortDirection *dir) override; // For NetworkEdit. Instance *makeInstance(LibertyCell *cell, - const char *name, + std::string_view name, Instance *parent) override; void makePins(Instance *inst) override; // For linking. Instance *makeInstance(Cell *cell, - const char *name, + std::string_view name, Instance *parent) override; void replaceCell(Instance *inst, Cell *cell) override; @@ -223,11 +224,11 @@ public: LibertyPort *port, Net *net) override; void setAttribute(Instance *inst, - const std::string &key, - const std::string &value) override; + std::string_view key, + std::string_view value) override; void disconnectPin(Pin *pin) override; void deletePin(Pin *pin) override; - Net *makeNet(const char *name, + Net *makeNet(std::string_view name, Instance *parent) override; void deleteNet(Net *net) override; @@ -263,13 +264,13 @@ public: protected: void addLibrary(ConcreteLibrary *library); - void setName(const char *name); + void setName(std::string_view name); void clearConstantNets(); void visitConnectedPins(const Net *net, PinVisitor &visitor, NetSet &visited_nets) const override; Instance *makeConcreteInstance(ConcreteCell *cell, - const char *name, + std::string_view name, Instance *parent); void disconnectNetPin(ConcreteNet *cnet, ConcretePin *cpin); @@ -292,40 +293,40 @@ private: class ConcreteInstance { public: - const char *name() const { return name_; } + std::string_view name() const { return name_; } ObjectId id() const { return id_; } Cell *cell() const; ConcreteInstance *parent() const { return parent_; } - ConcretePin *findPin(const char *port_name) const; + ConcretePin *findPin(std::string_view port_name) const; ConcretePin *findPin(const Port *port) const; - ConcreteNet *findNet(const char *net_name) const; + ConcreteNet *findNet(std::string_view net_name) const; void findNetsMatching(const PatternMatch *pattern, NetSeq &matches) const; InstanceNetIterator *netIterator() const; - Instance *findChild(const char *name) const; + Instance *findChild(std::string_view name) const; InstanceChildIterator *childIterator() const; - void setAttribute(const std::string &key, - const std::string &value); - std::string getAttribute(const std::string &key) const; + void setAttribute(std::string_view key, + std::string_view value); + std::string getAttribute(std::string_view key) const; const AttributeMap &attributeMap() const { return attribute_map_; } void addChild(ConcreteInstance *child); void deleteChild(ConcreteInstance *child); void addPin(ConcretePin *pin); void deletePin(ConcretePin *pin); void addNet(ConcreteNet *net); - void addNet(const char *name, + void addNet(std::string_view name, ConcreteNet *net); void deleteNet(ConcreteNet *net); void setCell(ConcreteCell *cell); void initPins(); protected: - ConcreteInstance(const char *name, + ConcreteInstance(std::string_view name, ConcreteCell *cell, ConcreteInstance *parent); ~ConcreteInstance(); - const char *name_; + std::string name_; ObjectId id_; ConcreteCell *cell_; ConcreteInstance *parent_; @@ -343,7 +344,7 @@ private: class ConcretePin { public: - const char *name() const; + std::string_view name() const; ConcreteInstance *instance() const { return instance_; } ConcreteNet *net() const { return net_; } ConcretePort *port() const { return port_; } @@ -377,7 +378,7 @@ private: class ConcreteTerm { public: - const char *name() const; + std::string_view name() const; ObjectId id() const { return id_; } ConcreteNet *net() const { return net_; } ConcretePin *pin() const { return pin_; } @@ -402,7 +403,7 @@ private: class ConcreteNet { public: - const char *name() const { return name_; } + std::string_view name() const { return name_; } ObjectId id() const { return id_; } ConcreteInstance *instance() const { return instance_; } void addPin(ConcretePin *pin); @@ -413,10 +414,9 @@ public: ConcreteNet *mergedInto() { return merged_into_; } protected: - ConcreteNet(const char *name, + ConcreteNet(std::string_view name, ConcreteInstance *instance); - ~ConcreteNet(); - const char *name_; + std::string name_; ObjectId id_; ConcreteInstance *instance_; // Pointer to head of linked list of pins. diff --git a/include/sta/ContainerHelpers.hh b/include/sta/ContainerHelpers.hh index a626bc18..010d30e7 100644 --- a/include/sta/ContainerHelpers.hh +++ b/include/sta/ContainerHelpers.hh @@ -143,7 +143,7 @@ struct find_return }; -// Find an pointer value in a reference to a contaiiner of pointers. +// Find a pointer value in a reference to a contaiiner of pointers. // Return nullptr if not found. template auto @@ -166,29 +166,24 @@ findKey(const AssocContainer& c, return *it; // set } -// Find an pointer value in a pointer to a contaiiner of pointers. +// Find a pointer value in a reference to a map that uses strings as keys. // Return nullptr if not found. template auto -findKey(const AssocContainer *c, - typename AssocContainer::key_type key) +findStringKey(const AssocContainer& c, + std::string_view key) -> typename find_return::type { using ReturnType = typename find_return::type; static_assert(std::is_pointer_v, - "findKey requires pointer types"); + "findStringKey requires pointer types"); - auto it = c->find(key); - if (it == c->end()) + auto it = c.find(key); + if (it == c.end()) return nullptr; - - if constexpr (has_mapped_type::value) - // map - return it->second; else - // set - return *it; + return it->second; } //////////////////////////////////////////////////////////////// @@ -212,7 +207,7 @@ findKeyValue(const AssocContainer& c, return empty; } -// Find an value reference in a reference to a contaiiner of objects. +// Find a value reference in a reference to a contaiiner of objects. // Return exists. template void @@ -239,7 +234,7 @@ findKeyValue(const AssocContainer& c, } } -// Find an value reference in a pointer to a contaiiner of objects. +// Find a value reference in a pointer to a contaiiner of objects. // Return exists. template void @@ -268,7 +263,8 @@ findKeyValue(const AssocContainer *c, //////////////////////////////////////////////////////////////// -// Find an value pointer in a reference to a contaiiner of objects. +// Find a value pointer in a reference to a contaiiner of objects. +// Return nullptr if not found. template auto findKeyValuePtr(AssocContainer& c, @@ -283,17 +279,17 @@ findKeyValuePtr(AssocContainer& c, // map return &it->second; else - // set + // sett return *it; } -// Find an pointger to a value in a const reference to a contaiiner objects. +// Find a value pointer in a reference to a contaiiner of objects. // Return nullptr if not found. template auto findKeyValuePtr(const AssocContainer& c, typename AssocContainer::key_type key) - -> const typename find_return::type* + -> typename find_return::type const* { auto it = c.find(key); if (it == c.end()) @@ -307,6 +303,38 @@ findKeyValuePtr(const AssocContainer& c, return *it; } +// Find a pointer to a value in a reference to a contaiiner of objects +// using std::string as the key. +// Return nullptr if not found. +template +auto +findStringValuePtr(AssocContainer& c, + std::string_view key) + -> typename find_return::type* +{ + auto it = c.find(key); + if (it == c.end()) + return nullptr; + else + return &it->second; +} + +// Find a const pointer to a value in a const reference to a contaiiner objects +// using std::string as the key. +// Return nullptr if not found. +template +auto +findStringValuePtr(const AssocContainer& c, + std::string_view key) + -> typename find_return::type const* +{ + auto it = c.find(key); + if (it == c.end()) + return nullptr; + else + return &it->second; +} + //////////////////////////////////////////////////////////////// // Determine if two std::set's intersect. diff --git a/include/sta/Debug.hh b/include/sta/Debug.hh index 1ff45934..afbb68e2 100644 --- a/include/sta/Debug.hh +++ b/include/sta/Debug.hh @@ -38,20 +38,20 @@ namespace sta { class Report; class Pin; -using DebugMap = std::map; +using DebugMap = std::map>; class Debug { public: Debug(Report *report); - int level(const char *what); - void setLevel(const char *what, + int level(std::string_view what); + void setLevel(std::string_view what, int level); - bool check(const char *what, + bool check(std::string_view what, int level) const; int statsLevel() const { return stats_level_; } template - void report(const char *what, + void report(std::string_view what, std::string_view fmt, Args &&...args) { diff --git a/include/sta/DelayCalc.hh b/include/sta/DelayCalc.hh index be0da6d3..4969b956 100644 --- a/include/sta/DelayCalc.hh +++ b/include/sta/DelayCalc.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include "StringUtil.hh" @@ -40,10 +41,10 @@ void registerDelayCalcs(); // Register a delay calculator for the set_delay_calc command. void -registerDelayCalc(const std::string &name, +registerDelayCalc(std::string_view name, MakeArcDelayCalc maker); bool -isDelayCalcName(const std::string &name); +isDelayCalcName(std::string_view name); StringSeq delayCalcNames(); void @@ -51,7 +52,7 @@ deleteDelayCalcs(); // Make a registered delay calculator by name. ArcDelayCalc * -makeDelayCalc(const std::string &name, +makeDelayCalc(std::string_view name, StaState *sta); } // namespace diff --git a/include/sta/EnumNameMap.hh b/include/sta/EnumNameMap.hh index 68d1fe9a..9ae20acb 100644 --- a/include/sta/EnumNameMap.hh +++ b/include/sta/EnumNameMap.hh @@ -35,17 +35,17 @@ class EnumNameMap { public: EnumNameMap(std::initializer_list> enum_names); - const char *find(ENUM key) const; - ENUM find(std::string name, + const std::string &find(ENUM key) const; + ENUM find(std::string_view name, ENUM unknown_key) const; - void find(std::string name, + void find(std::string_view name, // Return values. ENUM &key, bool &exists) const; private: std::map enum_map_; - std::map name_map_; + std::map> name_map_; }; template @@ -57,19 +57,21 @@ EnumNameMap::EnumNameMap(std::initializer_list -const char * +const std::string& EnumNameMap::find(ENUM key) const { auto find_iter = enum_map_.find(key); if (find_iter != enum_map_.end()) - return find_iter->second.c_str(); - else - return nullptr; + return find_iter->second; + else { + static std::string null_ref; + return null_ref; + } } template void -EnumNameMap::find(std::string name, +EnumNameMap::find(std::string_view name, // Return values. ENUM &key, bool &exists) const @@ -85,7 +87,7 @@ EnumNameMap::find(std::string name, template ENUM -EnumNameMap::find(std::string name, +EnumNameMap::find(std::string_view name, ENUM unknown_key) const { auto find_iter = name_map_.find(name); diff --git a/include/sta/Error.hh b/include/sta/Error.hh index a653024d..80fb1b0a 100644 --- a/include/sta/Error.hh +++ b/include/sta/Error.hh @@ -37,7 +37,7 @@ class Exception : public std::exception public: Exception(); virtual ~Exception() {} - virtual const char *what() const noexcept = 0; + const char *what() const noexcept override = 0; }; class ExceptionMsg : public Exception @@ -45,8 +45,8 @@ class ExceptionMsg : public Exception public: ExceptionMsg(const std::string &msg, const bool suppressed); - virtual const char *what() const noexcept; - virtual bool suppressed() const { return suppressed_; } + const char *what() const noexcept override; + bool suppressed() const { return suppressed_; } private: std::string msg_; @@ -68,11 +68,10 @@ protected: class FileNotReadable : public Exception { public: - FileNotReadable(std::string filename); - virtual const char *what() const noexcept; + FileNotReadable(std::string_view filename); + const char *what() const noexcept override; protected: - std::string filename_; std::string msg_; }; @@ -80,11 +79,10 @@ protected: class FileNotWritable : public Exception { public: - FileNotWritable(std::string filename); - virtual const char *what() const noexcept; + FileNotWritable(std::string_view filename); + const char *what() const noexcept override; protected: - std::string filename_; std::string msg_; }; diff --git a/include/sta/ExceptionPath.hh b/include/sta/ExceptionPath.hh index 9e4a555c..bfe9c16d 100644 --- a/include/sta/ExceptionPath.hh +++ b/include/sta/ExceptionPath.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include #include "Error.hh" @@ -57,7 +58,7 @@ public: const MinMaxAll *min_max, bool own_pts, int priority, - const char *comment); + std::string_view comment); virtual ~ExceptionPath(); size_t id() const { return id_; } void setId(size_t id); @@ -128,7 +129,7 @@ public: virtual bool useEndClk() const { return false; } virtual int pathMultiplier() const { return 0; } virtual float delay() const { return 0.0; } - virtual std::string name() const { return ""; } + virtual std::string_view name() const { return {}; } virtual bool isDefault() const { return false; } virtual bool ignoreClkLatency() const { return false; } virtual bool breakPath() const { return false; } @@ -157,14 +158,14 @@ public: ExceptionTo *to, const MinMaxAll *min_max, bool own_pts, - const char *comment); + std::string_view comment); FalsePath(ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, const MinMaxAll *min_max, bool own_pts, int priority, - const char *comment); + std::string_view comment); ExceptionPath *clone(ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, @@ -203,7 +204,7 @@ public: bool break_path, float delay, bool own_pts, - const char *comment); + std::string_view comment); ExceptionPath *clone(ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, @@ -237,7 +238,7 @@ public: bool use_end_clk, int path_multiplier, bool own_pts, - const char *comment); + std::string_view comment); ExceptionPath *clone(ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, @@ -293,13 +294,13 @@ public: class GroupPath : public ExceptionPath { public: - GroupPath(const std::string &name, + GroupPath(std::string_view name, bool is_default, ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, bool own_pts, - const char *comment); + std::string_view comment); ~GroupPath() override; ExceptionPath *clone(ExceptionFrom *from, ExceptionThruSeq *thrus, @@ -312,7 +313,7 @@ public: bool overrides(ExceptionPath *exception) const override; int typePriority() const override; bool tighterThan(ExceptionPath *exception) const override; - std::string name() const override { return name_; } + std::string_view name() const override { return name_; } bool isDefault() const override { return is_default_; } protected: diff --git a/include/sta/Graph.hh b/include/sta/Graph.hh index 6846ae89..a7475962 100644 --- a/include/sta/Graph.hh +++ b/include/sta/Graph.hh @@ -220,7 +220,7 @@ protected: PinVertexMap pin_bidirect_drvr_vertex_map_; DcalcAPIndex ap_count_; // Sdf period check annotations. - PeriodCheckAnnotations *period_check_annotations_; + PeriodCheckAnnotations period_check_annotations_; // Register/latch clock vertices to search from. VertexSet reg_clk_vertices_; @@ -241,7 +241,7 @@ public: // Pin path with load/driver suffix for bidirects. std::string to_string(const StaState *sta) const; // compatibility - const char *name(const Network *network) const; + std::string name(const Network *network) const; [[nodiscard]] bool isBidirectDriver() const { return is_bidirect_drvr_; } [[nodiscard]] bool isDriver(const Network *network) const; Level level() const { return level_; } diff --git a/include/sta/Hash.hh b/include/sta/Hash.hh index ebd833a9..6f87d56c 100644 --- a/include/sta/Hash.hh +++ b/include/sta/Hash.hh @@ -26,6 +26,7 @@ #include #include +#include namespace sta { @@ -56,7 +57,7 @@ nextMersenne(size_t n) // Sadly necessary until c++ std::hash works for char *. size_t -hashString(const char *str); +hashString(std::string_view str); // Pointer hashing is strongly discouraged because it causes results to change // from run to run. Use Network::id functions instead. diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index 450f1dff..732545a4 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "ContainerHelpers.hh" @@ -68,7 +69,7 @@ class DriverWaveform; class ModeValueDef { public: - ModeValueDef(std::string value, FuncExpr *cond, std::string sdf_cond); + ModeValueDef(std::string value); ModeValueDef(ModeValueDef &&other) noexcept; ~ModeValueDef(); const std::string &value() const { return value_; } @@ -115,14 +116,14 @@ private: TimingArcSet *setup_check_; }; -using TableTemplateMap = std::map; +using TableTemplateMap = std::map>; using TableTemplateSeq = std::vector; -using BusDclMap = std::map; +using BusDclMap = std::map>; using BusDclSeq = std::vector; -using ScaleFactorsMap = std::map; -using WireloadMap = std::map; -using WireloadSelectionMap = std::map; -using OperatingConditionsMap = std::map; +using ScaleFactorsMap = std::map>; +using WireloadMap = std::map>; +using WireloadSelectionMap = std::map>; +using OperatingConditionsMap = std::map>; using PortToSequentialMap = std::map; using TimingArcSetSeq = std::vector; using TimingArcSetSet = std::set; @@ -135,13 +136,13 @@ using PortInternalPowerMap = std::map; using ScaledCellMap = std::map; using ScaledPortMap = std::map; -using ModeDefMap = std::map; -using ModeValueMap = std::map; +using ModeDefMap = std::map>; +using ModeValueMap = std::map>; using LatchEnableIndexMap = std::map; using LatchEnableSeq = std::vector; -using OcvDerateMap = std::map; -using SupplyVoltageMap = std::map; -using DriverWaveformMap = std::map; +using OcvDerateMap = std::map>; +using SupplyVoltageMap = std::map>; +using DriverWaveformMap = std::map>; using SceneSeq = std::vector; enum class ClockGateType { none, latch_posedge, latch_negedge, other }; @@ -175,13 +176,13 @@ void deleteLiberty(); ScaleFactorPvt -findScaleFactorPvt(const char *name); -const char * +findScaleFactorPvt(std::string_view name); +const std::string& scaleFactorPvtName(ScaleFactorPvt pvt); ScaleFactorType -findScaleFactorType(const char *name); -const char * +findScaleFactorType(std::string_view name); +const std::string& scaleFactorTypeName(ScaleFactorType type); bool scaleFactorTypeRiseFallSuffix(ScaleFactorType type); @@ -191,7 +192,7 @@ bool scaleFactorTypeLowHighSuffix(ScaleFactorType type); // Timing sense as a string. -const char * +const std::string& to_string(TimingSense sense); // Opposite timing sense. @@ -203,10 +204,10 @@ timingSenseOpposite(TimingSense sense); class LibertyLibrary : public ConcreteLibrary { public: - LibertyLibrary(const char *name, - const char *filename); + LibertyLibrary(std::string name, + std::string filename); virtual ~LibertyLibrary(); - LibertyCell *findLibertyCell(const char *name) const; + LibertyCell *findLibertyCell(std::string_view name) const; LibertyCellSeq findLibertyCellsMatching(PatternMatch *pattern); // Liberty cells that are buffers. LibertyCellSeq *buffers(); @@ -214,12 +215,14 @@ public: DelayModelType delayModelType() const { return delay_model_type_; } void setDelayModelType(DelayModelType type); - BusDcl *makeBusDcl(std::string name, int from, int to); - BusDcl *findBusDcl(const char *name) const; + BusDcl *makeBusDcl(std::string name, + int from, + int to); + BusDcl *findBusDcl(std::string_view name); BusDclSeq busDcls() const; TableTemplate *makeTableTemplate(std::string name, TableTemplateType type); - TableTemplate *findTableTemplate(const char *name, + TableTemplate *findTableTemplate(std::string_view name, TableTemplateType type); TableTemplateSeq tableTemplates() const; TableTemplateSeq tableTemplates(TableTemplateType type) const; @@ -232,8 +235,8 @@ public: void setScaleFactors(ScaleFactors *scales); // Make named scale factor group. Returns pointer to the inserted element. - ScaleFactors *makeScaleFactors(const char *name); - ScaleFactors *findScaleFactors(const char *name); + ScaleFactors *makeScaleFactors(std::string name); + ScaleFactors *findScaleFactors(std::string_view name); ScaleFactors *scaleFactors() const { return scale_factors_; } float scaleFactor(ScaleFactorType type, const Pvt *pvt) const; @@ -334,18 +337,18 @@ public: const Units *units() const { return units_; } Wireload *makeWireload(std::string name); - const Wireload *findWireload(const char *name) const; + const Wireload *findWireload(std::string_view name); void setDefaultWireload(const Wireload *wireload); const Wireload *defaultWireload() const; WireloadSelection *makeWireloadSelection(std::string name); - const WireloadSelection *findWireloadSelection(const char *name) const; + const WireloadSelection *findWireloadSelection(std::string_view name) const; const WireloadSelection *defaultWireloadSelection() const; WireloadMode defaultWireloadMode() const; void setDefaultWireloadMode(WireloadMode mode); void setDefaultWireloadSelection(const WireloadSelection *selection); OperatingConditions *makeOperatingConditions(std::string name); - OperatingConditions *findOperatingConditions(const char *name); + OperatingConditions *findOperatingConditions(std::string_view name); OperatingConditions *defaultOperatingConditions() const; void setDefaultOperatingConditions(OperatingConditions *op_cond); @@ -356,18 +359,18 @@ public: OcvDerate *defaultOcvDerate() const; void setDefaultOcvDerate(OcvDerate *derate); OcvDerate *makeOcvDerate(std::string name); - OcvDerate *findOcvDerate(const char *derate_name); - void addSupplyVoltage(const char *suppy_name, + OcvDerate *findOcvDerate(std::string_view derate_name); + void addSupplyVoltage(std::string suppy_name, float voltage); - bool supplyExists(const char *suppy_name) const; - void supplyVoltage(const char *supply_name, + bool supplyExists(std::string_view supply_name) const; + void supplyVoltage(std::string_view supply_name, // Return value. float &voltage, bool &exists) const; // Make scaled cell. Call LibertyCell::addScaledCell after it is complete. - LibertyCell *makeScaledCell(const char *name, - const char *filename); + LibertyCell *makeScaledCell(std::string name, + std::string filename); static void makeSceneMap(LibertyLibrary *lib, @@ -390,9 +393,9 @@ public: const SceneSeq &scenes, Report *report); - DriverWaveform *findDriverWaveform(const char *name); + DriverWaveform *findDriverWaveform(std::string_view name); DriverWaveform *driverWaveformDefault() { return findDriverWaveform(""); } - DriverWaveform *makeDriverWaveform(const std::string &name, + DriverWaveform *makeDriverWaveform(std::string name, TablePtr waveforms); protected: @@ -471,18 +474,18 @@ class LibertyCell : public ConcreteCell { public: LibertyCell(LibertyLibrary *library, - const char *name, - const char *filename); + std::string name, + std::string filename); virtual ~LibertyCell(); LibertyLibrary *libertyLibrary() const { return liberty_library_; } LibertyLibrary *libertyLibrary() { return liberty_library_; } - LibertyPort *findLibertyPort(const char *name) const; + LibertyPort *findLibertyPort(std::string_view name) const; LibertyPortSeq findLibertyPortsMatching(PatternMatch *pattern) const; bool hasInternalPorts() const { return has_internal_ports_; } ScaleFactors *scaleFactors() const { return scale_factors_; } void setScaleFactors(ScaleFactors *scale_factors); ModeDef *makeModeDef(std::string name); - const ModeDef *findModeDef(const char *name) const; + const ModeDef *findModeDef(std::string_view name) const; float area() const { return area_; } void setArea(float area); @@ -541,8 +544,10 @@ public: const Statetable *statetable() const { return statetable_; } // Find bus declaration local to this cell. - BusDcl *makeBusDcl(std::string name, int from, int to); - BusDcl *findBusDcl(const char *name) const; + BusDcl *makeBusDcl(std::string name, + int from, + int to); + BusDcl *findBusDcl(std::string_view name); // True when TimingArcSetBuilder::makeRegLatchArcs infers register // timing arcs. bool hasInferedRegTimingArcs() const { return has_infered_reg_timing_arcs_; } @@ -561,7 +566,7 @@ public: float ocvArcDepth() const; OcvDerate *ocvDerate() const; OcvDerate *makeOcvDerate(std::string name); - OcvDerate *findOcvDerate(const char *derate_name); + OcvDerate *findOcvDerate(std::string_view derate_name); // Build helpers. void makeSequential(int size, @@ -614,10 +619,10 @@ public: // for all the defined scenes. static void checkLibertyScenes(); void ensureVoltageWaveforms(const SceneSeq &scenes); - const char *footprint() const; - void setFootprint(const char *footprint); - const char *userFunctionClass() const; - void setUserFunctionClass(const char *user_function_class); + const std::string &footprint() const { return footprint_; } + void setFootprint(std::string footprint); + const std::string &userFunctionClass() const { return user_function_class_; } + void setUserFunctionClass(std::string user_function_class); protected: void addPort(ConcretePort *port); @@ -752,8 +757,8 @@ public: bool isPwrGnd() const; PwrGndType pwrGndType() const { return pwr_gnd_type_; } void setPwrGndType(PwrGndType type); - const char *voltageName() const { return voltage_name_.c_str(); } - void setVoltageName(const char *voltage_name); + const std::string &voltageName() const { return voltage_name_; } + void setVoltageName(std::string voltage_name); //////////////////////////////////////////////////////////////// ScanSignalType scanSignalType() const { return scan_signal_type_; } @@ -876,10 +881,10 @@ public: const LibertyPort *scenePort(int ap_index) const; void setScenePort(LibertyPort *scene_port, int ap_index); - const char *relatedGroundPin() const; - void setRelatedGroundPin(const char *related_ground_pin); - const char *relatedPowerPin() const; - void setRelatedPowerPin(const char *related_power_pin); + LibertyPort *relatedGroundPort() const { return related_ground_port_; } + void setRelatedGroundPort(LibertyPort *related_ground_port); + LibertyPort *relatedPowerPort() const { return related_power_port_; } + void setRelatedPowerPort(LibertyPort *related_power_port); const ReceiverModel *receiverModel() const { return receiver_model_.get(); } void setReceiverModel(ReceiverModelPtr receiver_model); DriverWaveform *driverWaveform(const RiseFall *rf) const; @@ -901,7 +906,7 @@ public: protected: // Constructor is internal to LibertyBuilder. LibertyPort(LibertyCell *cell, - const char *name, + std::string name, bool is_bus, BusDcl *bus_dcl, int from_index, @@ -942,8 +947,8 @@ protected: float min_pulse_width_[RiseFall::index_count]; const RiseFall *pulse_clk_trigger_; const RiseFall *pulse_clk_sense_; - std::string related_ground_pin_; - std::string related_power_pin_; + LibertyPort *related_ground_port_; + LibertyPort *related_power_port_; std::vector scene_ports_; ReceiverModelPtr receiver_model_; DriverWaveform *driver_waveform_[RiseFall::index_count]; @@ -1011,13 +1016,8 @@ protected: class OperatingConditions : public Pvt { public: - OperatingConditions(const char *name); - OperatingConditions(const char *name, - float process, - float voltage, - float temperature, - WireloadTree wire_load_tree); - const char *name() const { return name_.c_str(); } + OperatingConditions(std::string name); + const std::string &name() const { return name_; } WireloadTree wireloadTree() const { return wire_load_tree_; } void setWireloadTree(WireloadTree tree); @@ -1029,8 +1029,8 @@ protected: class ScaleFactors { public: - ScaleFactors(const char *name); - const char *name() const { return name_.c_str(); } + ScaleFactors(std::string name); + const std::string &name() const { return name_; } float scale(ScaleFactorType type, ScaleFactorPvt pvt, const RiseFall *rf); @@ -1073,14 +1073,11 @@ protected: class ModeDef { public: + ModeDef(std::string name); const std::string &name() const { return name_; } - ModeValueDef *defineValue(const char *value, - FuncExpr *cond, - const char *sdf_cond); - const ModeValueDef *findValueDef(const char *value) const; - const ModeValueMap *values() const { return &values_; } - - explicit ModeDef(std::string name); + ModeValueDef *defineValue(std::string value); + const ModeValueDef *findValueDef(std::string_view value) const; + const ModeValueMap &values() const { return values_; } protected: std::string name_; @@ -1152,12 +1149,12 @@ private: }; std::string -portLibertyToSta(const char *port_name); -const char * +portLibertyToSta(std::string_view port_name); +const std::string & scanSignalTypeName(ScanSignalType scan_type); -const char * +const std::string & pwrGndTypeName(PwrGndType pwr_gnd_type); PwrGndType -findPwrGndType(const char *pg_name); +findPwrGndType(std::string_view pg_name); } // namespace diff --git a/include/sta/LinearModel.hh b/include/sta/LinearModel.hh index 07251739..0ee16401 100644 --- a/include/sta/LinearModel.hh +++ b/include/sta/LinearModel.hh @@ -76,7 +76,7 @@ public: PocvMode pocv_mode) const override; std::string reportCheckDelay(const Pvt *pvt, float from_slew, - const char *from_slew_annotation, + std::string_view from_slew_annotation, float to_slew, float related_out_cap, const MinMax *min_max, diff --git a/include/sta/Mode.hh b/include/sta/Mode.hh index ddb824ad..11222619 100644 --- a/include/sta/Mode.hh +++ b/include/sta/Mode.hh @@ -42,7 +42,7 @@ using PathGroupSeq = std::vector; class Mode : public StaState { public: - Mode(const std::string &name, + Mode(std::string_view name, size_t mode_index, StaState *sta); virtual ~Mode(); diff --git a/include/sta/Network.hh b/include/sta/Network.hh index 64480738..b12db2db 100644 --- a/include/sta/Network.hh +++ b/include/sta/Network.hh @@ -26,6 +26,8 @@ #include #include +#include +#include #include "StringUtil.hh" #include "LibertyClass.hh" @@ -39,11 +41,11 @@ class Report; class PatternMatch; class PinVisitor; -using LibertyLibraryMap = std::map; +using LibertyLibraryMap = std::map>; // Link network function returns top level instance. // Return nullptr if link fails. -using LinkNetworkFunc = std::function; +using LinkNetworkFunc = std::function; using NetDrvrPinsMap = std::map; // The Network class defines the network API used by sta. @@ -100,7 +102,7 @@ public: // has been linked. When the network interfaces to an external database, // linking is not necessary because the network has already been expanded. // Return true if successful. - virtual bool linkNetwork(const char *top_cell_name, + virtual bool linkNetwork(std::string_view top_cell_name, bool make_black_boxes, Report *report) = 0; virtual bool isLinked() const; @@ -108,23 +110,23 @@ public: //////////////////////////////////////////////////////////////// // Library functions. - virtual const char *name(const Library *library) const = 0; + virtual std::string name(const Library *library) const = 0; virtual ObjectId id(const Library *library) const = 0; virtual LibraryIterator *libraryIterator() const = 0; virtual LibertyLibraryIterator *libertyLibraryIterator() const = 0; - virtual Library *findLibrary(const char *name) = 0; - virtual LibertyLibrary *findLiberty(const char *name) = 0; + virtual Library *findLibrary(std::string_view name) = 0; + virtual LibertyLibrary *findLiberty(std::string_view name) = 0; // Find liberty library by filename. - virtual LibertyLibrary *findLibertyFilename(const char *filename); + virtual LibertyLibrary *findLibertyFilename(std::string_view filename); virtual Cell *findCell(const Library *library, - const char *name) const = 0; + std::string_view name) const = 0; // Search the design (non-liberty) libraries for cells matching pattern. virtual CellSeq findCellsMatching(const Library *library, const PatternMatch *pattern) const = 0; // Search liberty libraries for cell name. - virtual LibertyCell *findLibertyCell(const char *name) const; - virtual LibertyLibrary *makeLibertyLibrary(const char *name, - const char *filename) = 0; + virtual LibertyCell *findLibertyCell(std::string_view name) const; + virtual LibertyLibrary *makeLibertyLibrary(std::string_view name, + std::string_view filename) = 0; // Hook for network after reading liberty library. virtual void readLibertyAfter(LibertyLibrary *library); // First liberty library read is used to look up defaults. @@ -139,7 +141,7 @@ public: //////////////////////////////////////////////////////////////// // Cell functions. - virtual const char *name(const Cell *cell) const = 0; + virtual std::string name(const Cell *cell) const = 0; virtual ObjectId id(const Cell *cell) const = 0; virtual Library *library(const Cell *cell) const = 0; virtual LibertyLibrary *libertyLibrary(const Cell *cell) const; @@ -149,14 +151,13 @@ public: virtual const Cell *cell(const LibertyCell *cell) const = 0; virtual Cell *cell(LibertyCell *cell) const = 0; // Filename may return null. - virtual const char *filename(const Cell *cell) = 0; - // Attributes can be null + virtual std::string_view filename(const Cell *cell) const = 0; virtual std::string getAttribute(const Cell *cell, - const std::string &key) const = 0; + std::string_view key) const = 0; virtual const AttributeMap &attributeMap(const Cell *cell) const = 0; // Name can be a simple, bundle, bus, or bus bit name. virtual Port *findPort(const Cell *cell, - const char *name) const = 0; + std::string_view name) const = 0; virtual PortSeq findPortsMatching(const Cell *cell, const PatternMatch *pattern) const; virtual bool isLeaf(const Cell *cell) const = 0; @@ -168,7 +169,7 @@ public: //////////////////////////////////////////////////////////////// // Port functions - virtual const char *name(const Port *port) const = 0; + virtual std::string name(const Port *port) const = 0; virtual ObjectId id(const Port *port) const = 0; virtual Cell *cell(const Port *port) const = 0; virtual LibertyPort *libertyPort(const Port *port) const = 0; @@ -179,7 +180,7 @@ public: // Size is the bus/bundle member count (1 for non-bus/bundle ports). virtual int size(const Port *port) const = 0; // Bus range bus[from:to]. - virtual const char *busName(const Port *port) const = 0; + virtual std::string busName(const Port *port) const = 0; // Bus member, bus[subscript]. virtual Port *findBusBit(const Port *port, int index) const = 0; @@ -202,25 +203,25 @@ public: //////////////////////////////////////////////////////////////// // Instance functions // Name local to containing cell/instance. - virtual const char *name(const Instance *instance) const = 0; + virtual std::string name(const Instance *instance) const = 0; virtual ObjectId id(const Instance *instance) const = 0; // Top level instance of the design (defined after link). virtual Instance *topInstance() const = 0; virtual bool isTopInstance(const Instance *inst) const; - virtual Instance *findInstance(const char *path_name) const; + virtual Instance *findInstance(std::string_view path_name) const; // Find instance relative to hierarchical instance. virtual Instance *findInstanceRelative(const Instance *inst, - const char *path_name) const; + std::string_view path_name) const; // Default implementation uses linear search. virtual InstanceSeq findInstancesMatching(const Instance *context, const PatternMatch *pattern) const; virtual InstanceSeq findInstancesHierMatching(const Instance *instance, const PatternMatch *pattern) const; virtual std::string getAttribute(const Instance *inst, - const std::string &key) const = 0; + std::string_view key) const = 0; virtual const AttributeMap &attributeMap(const Instance *inst) const = 0; // Hierarchical path name. - virtual const char *pathName(const Instance *instance) const; + virtual std::string pathName(const Instance *instance) const; bool pathNameLess(const Instance *inst1, const Instance *inst2) const; int pathNameCmp(const Instance *inst1, @@ -230,14 +231,14 @@ public: // Return value. InstanceSeq &path) const; virtual Cell *cell(const Instance *instance) const = 0; - virtual const char *cellName(const Instance *instance) const; + virtual std::string cellName(const Instance *instance) const; virtual LibertyLibrary *libertyLibrary(const Instance *instance) const; virtual LibertyCell *libertyCell(const Instance *instance) const; virtual Instance *parent(const Instance *instance) const = 0; virtual bool isLeaf(const Instance *instance) const = 0; virtual bool isHierarchical(const Instance *instance) const; virtual Instance *findChild(const Instance *parent, - const char *name) const = 0; + std::string_view name) const = 0; virtual void findChildrenMatching(const Instance *parent, const PatternMatch *pattern, // Return value. @@ -270,18 +271,18 @@ public: //////////////////////////////////////////////////////////////// // Pin functions // Name is instance_name/port_name (the same as path name). - virtual const char *name(const Pin *pin) const; + virtual std::string name(const Pin *pin) const; virtual ObjectId id(const Pin *pin) const = 0; - virtual Pin *findPin(const char *path_name) const; + virtual Pin *findPin(std::string_view path_name) const; virtual Pin *findPin(const Instance *instance, - const char *port_name) const = 0; + std::string_view port_name) const = 0; virtual Pin *findPin(const Instance *instance, const Port *port) const; virtual Pin *findPin(const Instance *instance, const LibertyPort *port) const; // Find pin relative to hierarchical instance. Pin *findPinRelative(const Instance *inst, - const char *path_name) const; + std::string_view path_name) const; // Default implementation uses linear search. virtual PinSeq findPinsMatching(const Instance *instance, const PatternMatch *pattern) const; @@ -289,9 +290,9 @@ public: // pattern of the form instance_name/port_name. virtual PinSeq findPinsHierMatching(const Instance *instance, const PatternMatch *pattern) const; - virtual const char *portName(const Pin *pin) const; + virtual std::string portName(const Pin *pin) const; // Path name is instance_name/port_name. - virtual const char *pathName(const Pin *pin) const; + virtual std::string pathName(const Pin *pin) const; bool pathNameLess(const Pin *pin1, const Pin *pin2) const; int pathNameCmp(const Pin *pin1, @@ -349,27 +350,27 @@ public: //////////////////////////////////////////////////////////////// // Terminal functions // Name is instance_name/port_name (the same as path name). - virtual const char *name(const Term *term) const; + virtual std::string name(const Term *term) const; virtual ObjectId id(const Term *term) const = 0; - virtual const char *portName(const Term *term) const; + virtual std::string portName(const Term *term) const; // Path name is instance_name/port_name (pin name). - virtual const char *pathName(const Term *term) const; + virtual std::string pathName(const Term *term) const; virtual Net *net(const Term *term) const = 0; virtual Pin *pin(const Term *term) const = 0; //////////////////////////////////////////////////////////////// // Net functions - virtual const char *name(const Net *net) const = 0; // no hierarchy prefix + virtual std::string name(const Net *net) const = 0; // no hierarchy prefix virtual ObjectId id(const Net *net) const = 0; - virtual Net *findNet(const char *path_name) const; + virtual Net *findNet(std::string_view path_name) const; // Find net relative to hierarchical instance. virtual Net *findNetRelative(const Instance *inst, - const char *path_name) const; + std::string_view path_name) const; // Default implementation uses linear search. virtual NetSeq findNetsMatching(const Instance *context, const PatternMatch *pattern) const; virtual Net *findNet(const Instance *instance, - const char *net_name) const = 0; + std::string_view net_name) const = 0; // Traverse the hierarchy from instance down and find nets matching // pattern of the form instance_name/net_name. virtual NetSeq findNetsHierMatching(const Instance *instance, @@ -378,7 +379,7 @@ public: virtual void findInstNetsMatching(const Instance *instance, const PatternMatch *pattern, NetSeq &matches) const = 0; - virtual const char *pathName(const Net *net) const; + virtual std::string pathName(const Net *net) const; bool pathNameLess(const Net *net1, const Net *net2) const; int pathNameCmp(const Net *net1, @@ -424,17 +425,13 @@ public: //////////////////////////////////////////////////////////////// // Parse path into first/tail (first hierarchy divider separated token). - // first and tail are both null if there are no dividers in path. - // Caller must delete first and tail. - void pathNameFirst(const char *path_name, - char *&first, - char *&tail) const; + void pathNameFirst(std::string_view path_name, + std::string &first, + std::string &tail) const; // Parse path into head/last (last hierarchy divider separated token). - // head and last are both null if there are no dividers in path. - // Caller must delete head and last. - void pathNameLast(const char *path_name, - char *&head, - char *&last) const; + void pathNameLast(std::string_view path_name, + std::string &head, + std::string &last) const; // Divider between instance names in a hierarchical path name. virtual char pathDivider() const { return divider_; } @@ -445,7 +442,7 @@ public: protected: Pin *findPinLinear(const Instance *instance, - const char *port_name) const; + std::string_view port_name) const; void findInstancesMatching1(const Instance *context, size_t context_name_length, const PatternMatch *pattern, @@ -484,7 +481,7 @@ protected: PinSeq &matches) const; // findNet using linear search. Net *findNetLinear(const Instance *instance, - const char *net_name) const; + std::string_view net_name) const; // findNetsMatching using linear search. NetSeq findNetsMatchingLinear(const Instance *instance, const PatternMatch *pattern) const; @@ -506,7 +503,7 @@ public: NetworkEdit(); virtual bool isEditable() const { return true; } virtual Instance *makeInstance(LibertyCell *cell, - const char *name, + std::string_view name, Instance *parent) = 0; virtual void makePins(Instance *inst) = 0; virtual void replaceCell(Instance *inst, @@ -523,7 +520,7 @@ public: // Disconnect pin from net. virtual void disconnectPin(Pin *pin) = 0; virtual void deletePin(Pin *pin) = 0; - virtual Net *makeNet(const char *name, + virtual Net *makeNet(std::string_view name, Instance *parent) = 0; // Deleting net disconnects (but does not delete) net pins. virtual void deleteNet(Net *net) = 0; @@ -540,39 +537,39 @@ public: // Called before reading a netlist to delete any previously linked network. virtual void readNetlistBefore() = 0; virtual void setLinkFunc(LinkNetworkFunc link) = 0; - virtual Library *makeLibrary(const char *name, - const char *filename) = 0; + virtual Library *makeLibrary(std::string_view name, + std::string_view filename) = 0; virtual void deleteLibrary(Library *library) = 0; // Search the libraries in read order for a cell by name. - virtual Cell *findAnyCell(const char *name) = 0; + virtual Cell *findAnyCell(std::string_view name) = 0; virtual Cell *makeCell(Library *library, - const char *name, + std::string_view name, bool is_leaf, - const char *filename) = 0; + std::string_view filename) = 0; virtual void deleteCell(Cell *cell) = 0; virtual void setName(Cell *cell, - const char *name) = 0; + std::string_view name) = 0; virtual void setIsLeaf(Cell *cell, bool is_leaf) = 0; virtual void setAttribute(Cell *cell, - const std::string &key, - const std::string &value) = 0; + std::string_view key, + std::string_view value) = 0; virtual void setAttribute(Instance *instance, - const std::string &key, - const std::string &value) = 0; + std::string_view key, + std::string_view value) = 0; virtual Port *makePort(Cell *cell, - const char *name) = 0; + std::string_view name) = 0; virtual Port *makeBusPort(Cell *cell, - const char *name, + std::string_view name, int from_index, int to_index) = 0; virtual void groupBusPorts(Cell *cell, - std::function port_msb_first) = 0; + std::function port_msb_first) = 0; virtual Port *makeBundlePort(Cell *cell, - const char *name, + std::string_view name, PortSeq *members) = 0; virtual Instance *makeInstance(Cell *cell, - const char *name, + std::string_view name, Instance *parent) = 0; virtual Pin *makePin(Instance *inst, Port *port, diff --git a/include/sta/NetworkClass.hh b/include/sta/NetworkClass.hh index 3480d587..23f63a6a 100644 --- a/include/sta/NetworkClass.hh +++ b/include/sta/NetworkClass.hh @@ -74,7 +74,7 @@ using ConnectedPinIterator = Iterator; using NetConnectedPinIterator = ConnectedPinIterator; using PinConnectedPinIterator = ConnectedPinIterator; using ObjectId = uint32_t; -using AttributeMap = std::map; +using AttributeMap = std::map>; enum class LogicValue : unsigned { zero, one, unknown, rise, fall }; diff --git a/include/sta/Parasitics.hh b/include/sta/Parasitics.hh index 5d1800a9..8c010f07 100644 --- a/include/sta/Parasitics.hh +++ b/include/sta/Parasitics.hh @@ -185,7 +185,7 @@ public: // Increment the grounded capacitance on node. virtual void incrCap(ParasiticNode *node, float cap) = 0; - virtual const char *name(const ParasiticNode *node) const = 0; + virtual std::string name(const ParasiticNode *node) const = 0; virtual const Pin *pin(const ParasiticNode *node) const = 0; virtual const Net *net(const ParasiticNode *node, const Network *network) const = 0; diff --git a/include/sta/PathGroup.hh b/include/sta/PathGroup.hh index d8ba2af6..c7c6c545 100644 --- a/include/sta/PathGroup.hh +++ b/include/sta/PathGroup.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include #include #include @@ -50,7 +51,7 @@ class PathGroup { public: // Path group that compares compare slacks. - static PathGroup *makePathGroupArrival(const char *name, + static PathGroup *makePathGroupArrival(std::string_view name, int group_path_count, int endpoint_path_count, bool unique_pins, @@ -58,7 +59,7 @@ public: const MinMax *min_max, const StaState *sta); // Path group that compares arrival time, sorted by min_max. - static PathGroup *makePathGroupSlack(const char *name, + static PathGroup *makePathGroupSlack(std::string_view name, int group_path_count, int endpoint_path_count, bool unique_pins, @@ -82,7 +83,7 @@ public: static int group_path_count_max; protected: - PathGroup(const char *name, + PathGroup(std::string_view name, int group_path_count, int endpoint_path_count, bool unique_pins, @@ -147,10 +148,10 @@ public: PathGroupSeq pathGroups(const PathEnd *path_end) const; static StringSeq pathGroupNames(const PathEnd *path_end, const StaState *sta); - static const char *asyncPathGroupName() { return async_group_name_; } - static const char *pathDelayGroupName() { return path_delay_group_name_; } - static const char *gatedClkGroupName() { return gated_clk_group_name_; } - static const char *unconstrainedGroupName() { return unconstrained_group_name_; } + static std::string_view asyncPathGroupName() { return async_group_name_; } + static std::string_view pathDelayGroupName() { return path_delay_group_name_; } + static std::string_view gatedClkGroupName() { return gated_clk_group_name_; } + static std::string_view unconstrainedGroupName() { return unconstrained_group_name_; } protected: void makeGroupPathEnds(ExceptionTo *to, @@ -219,10 +220,10 @@ protected: // Unconstrained paths. PathGroup *unconstrained_[MinMax::index_count]; - static const char *path_delay_group_name_; - static const char *gated_clk_group_name_; - static const char *async_group_name_; - static const char *unconstrained_group_name_; + static constexpr std::string_view path_delay_group_name_ = "path delay"; + static constexpr std::string_view gated_clk_group_name_ = "gated clock"; + static constexpr std::string_view async_group_name_ = "asynchronous"; + static constexpr std::string_view unconstrained_group_name_ = "unconstrained"; }; } // namespace diff --git a/include/sta/PatternMatch.hh b/include/sta/PatternMatch.hh index 429aef04..dc41363f 100644 --- a/include/sta/PatternMatch.hh +++ b/include/sta/PatternMatch.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include "Error.hh" @@ -45,20 +46,17 @@ public: // Regular expressions are always anchored. // If nocase is true, ignore case in the pattern. // Tcl_Interp is optional for reporting regexp compile errors. - PatternMatch(const char *pattern, + PatternMatch(std::string_view pattern, bool is_regexp, bool nocase, Tcl_Interp *interp); // Use unix glob style matching. - PatternMatch(const char *pattern); - PatternMatch(const char *pattern, + PatternMatch(std::string_view pattern); + PatternMatch(std::string_view pattern, const PatternMatch *inherit_from); - PatternMatch(const std::string &pattern, - const PatternMatch *inherit_from); - bool match(const char *str) const; - bool match(const std::string &str) const; - bool matchNoCase(const char *str) const; - const char *pattern() const { return pattern_; } + bool match(std::string_view str) const; + bool matchNoCase(std::string_view str) const; + const std::string &pattern() const { return pattern_; } bool isRegexp() const { return is_regexp_; } bool nocase() const { return nocase_; } Tcl_Interp *tclInterp() const { return interp_; } @@ -67,7 +65,7 @@ public: private: void compileRegexp(); - const char *pattern_; + std::string pattern_; bool is_regexp_; bool nocase_; Tcl_Interp *interp_; @@ -78,7 +76,7 @@ private: class RegexpCompileError : public Exception { public: - RegexpCompileError(const char *pattern); + RegexpCompileError(std::string_view pattern); virtual ~RegexpCompileError() noexcept {} virtual const char *what() const noexcept; @@ -90,14 +88,14 @@ private: // '*' matches zero or more characters // '?' matches any character bool -patternMatch(const char *pattern, - const char *str); +patternMatch(std::string_view pattern, + std::string_view str); bool -patternMatchNoCase(const char *pattern, - const char *str, +patternMatchNoCase(std::string_view pattern, + std::string_view str, bool nocase); // Predicate to find out if there are wildcard characters in the pattern. bool -patternWildcards(const char *pattern); +patternWildcards(std::string_view pattern); } // namespace diff --git a/include/sta/PocvMode.hh b/include/sta/PocvMode.hh index 29d19a63..d75785ec 100644 --- a/include/sta/PocvMode.hh +++ b/include/sta/PocvMode.hh @@ -24,13 +24,15 @@ #pragma once +#include + namespace sta { enum class PocvMode { scalar, normal, skew_normal }; -const char * +const std::string & pocvModeName(PocvMode mode); PocvMode -findPocvMode(const char *mode_name); +findPocvMode(std::string_view mode_name); } // namespace diff --git a/include/sta/PortDirection.hh b/include/sta/PortDirection.hh index 38ca9b5b..0b8186f9 100644 --- a/include/sta/PortDirection.hh +++ b/include/sta/PortDirection.hh @@ -43,7 +43,7 @@ public: static PortDirection *power() { return power_; } static PortDirection *unknown() { return unknown_; } static PortDirection *find(const char *dir_name); - const char *name() const { return name_; } + std::string_view name() const { return name_; } int index() const { return index_; } bool isInput() const { return this == input_; } // Input or bidirect. diff --git a/include/sta/PowerClass.hh b/include/sta/PowerClass.hh index 55fb292f..b3f2a6df 100644 --- a/include/sta/PowerClass.hh +++ b/include/sta/PowerClass.hh @@ -58,7 +58,7 @@ public: void setDuty(float duty); PwrActivityOrigin origin() const { return origin_; } void setOrigin(PwrActivityOrigin origin); - const char *originName() const; + const std::string &originName() const; void set(float density, float duty, PwrActivityOrigin origin); diff --git a/include/sta/Property.hh b/include/sta/Property.hh index ae89b599..fd734437 100644 --- a/include/sta/Property.hh +++ b/include/sta/Property.hh @@ -51,12 +51,12 @@ public: void defineProperty(std::string_view property, PropertyHandler handler); PropertyValue getProperty(TYPE object, - const std::string &property, - const char *type_name, + std::string_view property, + std::string_view type_name, Sta *sta); private: - std::map registry_; + std::map> registry_; }; class Properties @@ -66,33 +66,33 @@ public: virtual ~Properties() {} PropertyValue getProperty(const Library *lib, - const std::string &property); + std::string_view property); PropertyValue getProperty(const LibertyLibrary *lib, - const std::string &property); + std::string_view property); PropertyValue getProperty(const Cell *cell, - const std::string &property); + std::string_view property); PropertyValue getProperty(const LibertyCell *cell, - const std::string &property); + std::string_view property); PropertyValue getProperty(const Port *port, - const std::string &property); + std::string_view property); PropertyValue getProperty(const LibertyPort *port, - const std::string &property); + std::string_view property); PropertyValue getProperty(const Instance *inst, - const std::string &property); + std::string_view property); PropertyValue getProperty(const Pin *pin, - const std::string &property); + std::string_view property); PropertyValue getProperty(const Net *net, - const std::string &property); + std::string_view property); PropertyValue getProperty(Edge *edge, - const std::string &property); + std::string_view property); PropertyValue getProperty(const Clock *clk, - const std::string &property); + std::string_view property); PropertyValue getProperty(PathEnd *end, - const std::string &property); + std::string_view property); PropertyValue getProperty(Path *path, - const std::string &property); + std::string_view property); PropertyValue getProperty(TimingArcSet *arc_set, - const std::string &property); + std::string_view property); // Define handler for external property. // properties->defineProperty("foo", @@ -160,7 +160,7 @@ protected: }; // Adding a new property type -// value union +// value union (string values use std::string* so the union stays trivial) // enum Type // constructor // copy constructor switch clause @@ -178,11 +178,11 @@ public: instance, pin, pins, net, clk, clks, paths, pwr_activity }; PropertyValue(); - PropertyValue(const char *value); - PropertyValue(std::string &value); + PropertyValue(std::string_view value); + PropertyValue(std::string value); PropertyValue(float value, const Unit *unit); - explicit PropertyValue(bool value); + PropertyValue(bool value); PropertyValue(const Library *value); PropertyValue(const Cell *value); PropertyValue(const Port *value); @@ -209,7 +209,7 @@ public: const Unit *unit() const { return unit_; } std::string to_string(const Network *network) const; - const char *stringValue() const; // valid for type string + const std::string &stringValue() const; // valid for type string float floatValue() const; // valid for type float bool boolValue() const; // valid for type bool const LibertyLibrary *libertyLibrary() const { return liberty_library_; } @@ -233,9 +233,12 @@ public: PropertyValue &operator=(PropertyValue &&) noexcept; private: + void destroyActive(); + Type type_; union { - const char *string_; + // Use heap string to simplify initialization/destrucction. + std::string *string_; float float_; bool bool_; const Library *library_; diff --git a/include/sta/Report.hh b/include/sta/Report.hh index 51cde2ed..e8c39de3 100644 --- a/include/sta/Report.hh +++ b/include/sta/Report.hh @@ -177,13 +177,13 @@ public: } // Log output to filename until logEnd is called. - virtual void logBegin(std::string filename); + virtual void logBegin(std::string_view filename); virtual void logEnd(); // Redirect output to filename until redirectFileEnd is called. - virtual void redirectFileBegin(std::string filename); + virtual void redirectFileBegin(std::string_view filename); // Redirect append output to filename until redirectFileEnd is called. - virtual void redirectFileAppendBegin(std::string filename); + virtual void redirectFileAppendBegin(std::string_view filename); virtual void redirectFileEnd(); // Redirect output to a string until redirectStringEnd is called. virtual void redirectStringBegin(); diff --git a/include/sta/ReportTcl.hh b/include/sta/ReportTcl.hh index acdf84dc..5f4a6cd0 100644 --- a/include/sta/ReportTcl.hh +++ b/include/sta/ReportTcl.hh @@ -44,10 +44,10 @@ class ReportTcl : public Report public: ReportTcl(); virtual ~ReportTcl(); - void logBegin(std::string filename) override; + void logBegin(std::string_view filename) override; void logEnd() override; - void redirectFileBegin(std::string filename) override; - void redirectFileAppendBegin(std::string filename) override; + void redirectFileBegin(std::string_view filename) override; + void redirectFileAppendBegin(std::string_view filename) override; void redirectFileEnd() override; void redirectStringBegin() override; const char *redirectStringEnd() override; diff --git a/include/sta/Sdc.hh b/include/sta/Sdc.hh index 64a41375..eaf65e77 100644 --- a/include/sta/Sdc.hh +++ b/include/sta/Sdc.hh @@ -28,6 +28,7 @@ #include #include #include +#include #include "StringUtil.hh" #include "MinMax.hh" @@ -131,7 +132,7 @@ private: bool subtract_pin_cap_[MinMax::index_count]; }; -using ClockNameMap = std::map; +using ClockNameMap = std::map>; using ClockPinMap = std::unordered_map; using InputDelaySet = std::set; using InputDelaysPinMap = std::map; @@ -179,11 +180,11 @@ using InstDeratingFactorsMap = std::map; using CellDeratingFactorsMap = std::map; using ClockGroupsSet = std::set; using ClockGroupsClkMap = std::map; -using ClockGroupsNameMap = std::map; +using ClockGroupsNameMap = std::map>; using ClockSenseMap = std::map; using ClkHpinDisables = std::set; using GroupPathSet = std::set; -using GroupPathMap = std::map; +using GroupPathMap = std::map>; using ClockPairSet = std::set; using NetVoltageMap = std::map; @@ -377,14 +378,14 @@ public: float fanout); void setMaxArea(float area); float maxArea() const; - Clock *makeClock(const char *name, + Clock *makeClock(std::string_view name, PinSet *pins, bool add_to_pins, float period, FloatSeq *waveform, - const char *comment); + std::string_view comment); // edges size must be 3. - Clock *makeGeneratedClock(const char *name, + Clock *makeGeneratedClock(std::string_view name, PinSet *pins, bool add_to_pins, Pin *src_pin, @@ -396,7 +397,7 @@ public: bool combinational, IntSeq *edges, FloatSeq *edge_shifts, - const char *comment); + std::string_view comment); // Invalidate all generated clock waveforms. void invalidateGeneratedClks() const; void removeClock(Clock *clk); @@ -504,7 +505,7 @@ public: bool physically_exclusive, bool asynchronous, bool allow_paths, - const char *comment); + std::string comment); void makeClockGroup(ClockGroups *clk_groups, ClockSet *clks); void removeClockGroups(const std::string &name); @@ -730,7 +731,7 @@ public: ExceptionThruSeq *thrus, ExceptionTo *to, const MinMaxAll *min_max, - const char *comment); + std::string_view comment); // Loop paths are false paths used to disable paths around // combinational loops when dynamic loop breaking is enabled. void makeLoopExceptions(); @@ -742,7 +743,7 @@ public: const MinMaxAll *min_max, bool use_end_clk, int path_multiplier, - const char *comment); + std::string_view comment); void makePathDelay(ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, @@ -750,7 +751,7 @@ public: bool ignore_clk_latency, bool break_path, float delay, - const char *comment); + std::string_view comment); bool pathDelaysWithoutTo() const { return path_delays_without_to_; } // Delete matching false/multicycle/path_delay exceptions. // Caller owns from, thrus, to exception points (and must delete them). @@ -758,13 +759,13 @@ public: ExceptionThruSeq *thrus, ExceptionTo *to, const MinMaxAll *min_max); - void makeGroupPath(const std::string &name, + void makeGroupPath(std::string_view name, bool is_default, ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, - const char *comment); - bool isGroupPathName(const char *group_name) const; + std::string_view comment); + bool isGroupPathName(std::string_view group_name) const; const GroupPathMap &groupPaths() const { return group_path_map_; } void addException(ExceptionPath *exception); // The pin/clk/instance/net set arguments passed into the following @@ -833,7 +834,7 @@ public: const MinMax *min_max, float voltage); InputDrive *findInputDrive(Port *port) const; - Clock *findClock(const char *name) const; + Clock *findClock(std::string_view name) const; ClockSeq findClocksMatching(PatternMatch *pattern) const; // True if pin is defined as a clock source (pin may be hierarchical). bool isClock(const Pin *pin) const; diff --git a/include/sta/SdcCmdComment.hh b/include/sta/SdcCmdComment.hh index 5e995fb5..b1c70d0b 100644 --- a/include/sta/SdcCmdComment.hh +++ b/include/sta/SdcCmdComment.hh @@ -24,22 +24,28 @@ #pragma once +#include +#include + namespace sta { class SdcCmdComment { public: SdcCmdComment(); - SdcCmdComment(const char *comment); - const char *comment() { return comment_; } - void setComment(const char *comment); + SdcCmdComment(std::string comment); + SdcCmdComment(std::string_view comment); + const std::string &comment() { return comment_; } + const std::string &comment() const { return comment_; } + void setComment(std::string comment); + void setComment(std::string_view comment); protected: // Destructor is protected to prevent deletion of a derived // class with a pointer to this base class. ~SdcCmdComment(); - char *comment_; + std::string comment_; }; } // namespace diff --git a/include/sta/SdcNetwork.hh b/include/sta/SdcNetwork.hh index 3c2c84be..84b0b367 100644 --- a/include/sta/SdcNetwork.hh +++ b/include/sta/SdcNetwork.hh @@ -25,6 +25,8 @@ #pragma once #include +#include +#include #include "Network.hh" @@ -36,26 +38,26 @@ class NetworkNameAdapter : public NetworkEdit { public: NetworkNameAdapter(Network *network); - bool linkNetwork(const char *top_cell_name, + bool linkNetwork(std::string_view top_cell_name, bool make_black_boxes, Report *report) override; - const char *name(const Library *library) const override; + std::string name(const Library *library) const override; ObjectId id(const Library *library) const override; LibertyLibrary *defaultLibertyLibrary() const override; LibraryIterator *libraryIterator() const override; LibertyLibraryIterator *libertyLibraryIterator() const override; - Library *findLibrary(const char *name) override; - LibertyLibrary *findLibertyFilename(const char *filename) override; - LibertyLibrary *findLiberty(const char *name) override; + Library *findLibrary(std::string_view name) override; + LibertyLibrary *findLibertyFilename(std::string_view filename) override; + LibertyLibrary *findLiberty(std::string_view name) override; Cell *findCell(const Library *library, - const char *name) const override; + std::string_view name) const override; CellSeq findCellsMatching(const Library *library, const PatternMatch *pattern) const override; - const char *name(const Cell *cell) const override; + std::string name(const Cell *cell) const override; std::string getAttribute(const Cell *cell, - const std::string &key) const override; + std::string_view key) const override; const AttributeMap &attributeMap(const Cell *cell) const override; ObjectId id(const Cell *cell) const override; Library *library(const Cell *cell) const override; @@ -63,9 +65,9 @@ public: const LibertyCell *libertyCell(const Cell *cell) const override; Cell *cell(LibertyCell *cell) const override; const Cell *cell(const LibertyCell *cell) const override; - const char *filename(const Cell *cell) override; + std::string_view filename(const Cell *cell) const override; Port *findPort(const Cell *cell, - const char *name) const override; + std::string_view name) const override; PortSeq findPortsMatching(const Cell *cell, const PatternMatch *pattern) const override; bool isLeaf(const Cell *cell) const override; @@ -73,7 +75,7 @@ public: CellPortBitIterator *portBitIterator(const Cell *cell) const override; int portBitCount(const Cell *cell) const override; - const char *name(const Port *port) const override; + std::string name(const Port *port) const override; ObjectId id(const Port *port) const override; Cell *cell(const Port *port) const override; LibertyPort *libertyPort(const Port *port) const override; @@ -81,7 +83,7 @@ public: bool isBundle(const Port *port) const override; bool isBus(const Port *port) const override; int size(const Port *port) const override; - const char *busName(const Port *port) const override; + std::string busName(const Port *port) const override; Port *findBusBit(const Port *port, int index) const override; int fromIndex(const Port *port) const override; @@ -93,7 +95,7 @@ public: ObjectId id(const Instance *instance) const override; std::string getAttribute(const Instance *inst, - const std::string &key) const override; + std::string_view key) const override; const AttributeMap &attributeMap(const Instance *inst) const override; Instance *topInstance() const override; Cell *cell(const Instance *instance) const override; @@ -145,15 +147,15 @@ public: void setPathEscape(char escape) override; bool isEditable() const override; - LibertyLibrary *makeLibertyLibrary(const char *name, - const char *filename) override; + LibertyLibrary *makeLibertyLibrary(std::string_view name, + std::string_view filename) override; Instance *makeInstance(LibertyCell *cell, - const char *name, + std::string_view name, Instance *parent) override; void makePins(Instance *inst) override; void replaceCell(Instance *inst, Cell *to_cell) override; - Net *makeNet(const char *name, + Net *makeNet(std::string_view name, Instance *parent) override; Pin *connect(Instance *inst, Port *port, @@ -195,47 +197,47 @@ public: SdcNetwork(Network *network); Port *findPort(const Cell *cell, - const char *name) const override; + std::string_view name) const override; PortSeq findPortsMatching(const Cell *cell, const PatternMatch *pattern) const override; - const char *name(const Port *port) const override; - const char *busName(const Port *port) const override; + std::string name(const Port *port) const override; + std::string busName(const Port *port) const override; - const char *name(const Instance *instance) const override; - const char *pathName(const Instance *instance) const override; - const char *pathName(const Pin *pin) const override; - const char *portName(const Pin *pin) const override; + std::string name(const Instance *instance) const override; + std::string pathName(const Instance *instance) const override; + std::string pathName(const Pin *pin) const override; + std::string portName(const Pin *pin) const override; - const char *name(const Net *net) const override; - const char *pathName(const Net *net) const override; + std::string name(const Net *net) const override; + std::string pathName(const Net *net) const override; - Instance *findInstance(const char *path_name) const override; + Instance *findInstance(std::string_view path_name) const override; Instance *findInstanceRelative(const Instance *inst, - const char *path_name) const override; + std::string_view path_name) const override; InstanceSeq findInstancesMatching(const Instance *context, const PatternMatch *pattern) const override; - Net *findNet(const char *path_name) const override; + Net *findNet(std::string_view path_name) const override; Net *findNetRelative(const Instance *instance, - const char *net_name) const override; + std::string_view net_name) const override; Net *findNet(const Instance *instance, - const char *net_name) const override; + std::string_view net_name) const override; NetSeq findNetsMatching(const Instance *parent, const PatternMatch *pattern) const override; void findInstNetsMatching(const Instance *instance, const PatternMatch *pattern, NetSeq &nets) const override; Instance *findChild(const Instance *parent, - const char *name) const override; - Pin *findPin(const char *path_name) const override; + std::string_view name) const override; + Pin *findPin(std::string_view path_name) const override; Pin *findPin(const Instance *instance, - const char *port_name) const override; + std::string_view port_name) const override; PinSeq findPinsMatching(const Instance *instance, const PatternMatch *pattern) const override; Instance *makeInstance(LibertyCell *cell, - const char *name, + std::string_view name, Instance *parent) override; - Net *makeNet(const char *name, + Net *makeNet(std::string_view name, Instance *parent) override; // The following member functions are inherited from the @@ -247,21 +249,21 @@ public: using Network::findPin; protected: - void parsePath(const char *path, + void parsePath(std::string_view path, // Return values. Instance *&inst, - const char *&path_tail) const; - void scanPath(const char *path, + std::string &path_tail) const; + void scanPath(std::string_view path, // Return values. // Unescaped divider count. int ÷r_count, int &path_length) const; - void parsePath(const char *path, + void parsePath(std::string_view path, int divider_count, int path_length, // Return values. Instance *&inst, - const char *&path_tail) const; + std::string &path_tail) const; bool visitMatches(const Instance *parent, const PatternMatch *pattern, std::function; +using ModeNameMap = std::map>; using SceneNameMap = std::map; using SlowDrvrIterator = Iterator; using CheckError = StringSeq; @@ -143,12 +143,12 @@ public: Mode *cmdMode() const { return cmd_scene_->mode(); } const std::string &cmdModeName(); - void setCmdMode(const std::string &mode_name); - Mode *findMode(const std::string &mode_name) const; + void setCmdMode(std::string_view mode_name); + Mode *findMode(std::string_view mode_name) const; ModeSeq findModes(const std::string &mode_name) const; Sdc *cmdSdc() const; - virtual LibertyLibrary *readLiberty(const char *filename, + virtual LibertyLibrary *readLiberty(std::string_view filename, Scene *scene, const MinMaxAll *min_max, bool infer_latches); @@ -156,7 +156,7 @@ public: void readLibertyAfter(LibertyLibrary *liberty, Scene *scene, const MinMax *min_max); - bool readVerilog(const char *filename); + bool readVerilog(std::string_view filename); // Network readers call this to notify the Sta to delete any previously // linked network. void readNetlistBefore(); @@ -164,6 +164,13 @@ public: bool linkDesign(const char *top_cell_name, bool make_black_boxes); + bool readSdf(std::string_view filename, + std::string_view path, + Scene *scene, + bool unescaped_dividers, + bool incremental_only, + MinMaxAll *cond_use); + // SDC Swig API. Instance *currentInstance() const; void setCurrentInstance(Instance *inst); @@ -340,15 +347,15 @@ public: void setMaxArea(float area, Sdc *sdc); - void makeClock(const char *name, + void makeClock(std::string_view name, PinSet *pins, bool add_to_pins, float period, FloatSeq *waveform, - char *comment, + std::string_view comment, const Mode *mode); // edges size must be 3. - void makeGeneratedClock(const char *name, + void makeGeneratedClock(std::string_view name, PinSet *pins, bool add_to_pins, Pin *src_pin, @@ -360,7 +367,7 @@ public: bool combinational, IntSeq *edges, FloatSeq *edge_shifts, - char *comment, + std::string_view comment, const Mode *mode); void removeClock(Clock *clk, Sdc *sdc); @@ -439,7 +446,7 @@ public: bool physically_exclusive, bool asynchronous, bool allow_paths, - const char *comment, + std::string comment, Sdc *sdc); void removeClockGroupsLogicallyExclusive(Sdc *sdc); void removeClockGroupsLogicallyExclusive(const std::string &name, @@ -623,7 +630,7 @@ public: ExceptionThruSeq *thrus, ExceptionTo *to, const MinMaxAll *min_max, - const char *comment, + std::string_view comment, Sdc *sdc); void makeMulticyclePath(ExceptionFrom *from, ExceptionThruSeq *thrus, @@ -631,7 +638,7 @@ public: const MinMaxAll *min_max, bool use_end_clk, int path_multiplier, - const char *comment, + std::string_view comment, Sdc *sdc); void makePathDelay(ExceptionFrom *from, ExceptionThruSeq *thrus, @@ -640,19 +647,19 @@ public: bool ignore_clk_latency, bool break_path, float delay, - const char *comment, + std::string_view comment, Sdc *sdc); - void makeGroupPath(const std::string &name, + void makeGroupPath(std::string_view name, bool is_default, ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, - const char *comment, + std::string_view comment, Sdc *sdc); // Deprecated 10/24/2025 - bool isGroupPathName(const char *group_name, + bool isGroupPathName(std::string_view group_name, const Sdc *sdc) __attribute__ ((deprecated)); - bool isPathGroupName(const char *group_name, + bool isPathGroupName(std::string_view group_name, const Sdc *sdc) const; StringSeq pathGroupNames(const Sdc *sdc) const; void resetPath(ExceptionFrom *from, @@ -667,7 +674,7 @@ public: const RiseFallBoth *from_rf, const Sdc *sdc); void checkExceptionFromPins(ExceptionFrom *from, - const char *file, + std::string_view filename, int line, const Sdc *sdc) const; void deleteExceptionFrom(ExceptionFrom *from); @@ -892,7 +899,7 @@ public: const MinMaxAll *min_max, const RiseFallBoth *rf, float slew); - void writeSdf(const char *filename, + void writeSdf(std::string_view filename, const Scene *scene, char divider, bool include_typ, @@ -986,7 +993,7 @@ public: bool report_fanout, bool report_variation, bool report_src_attr); - ReportField *findReportPathField(const char *name); + ReportField *findReportPathField(std::string_view name); void setReportPathDigits(int digits); void setReportPathNoSplit(bool no_split); void reportPathEnd(PathEnd *end); @@ -1038,7 +1045,7 @@ public: const MinMax *min_max, int digits); void writeSdc(const Sdc *sdc, - const char *filename, + std::string_view filename, // Map hierarchical pins and instances to leaf pins and instances. bool leaf, // Replace non-sdc get functions with OpenSTA equivalents. @@ -1123,7 +1130,7 @@ public: Slack (&slacks)[RiseFall::index_count][MinMax::index_count]); // Worst slack for an endpoint in a path group. Slack endpointSlack(const Pin *pin, - const std::string &path_group_name, + std::string_view path_group_name, const MinMax *min_max); void reportArrivalWrtClks(const Pin *pin, @@ -1188,8 +1195,8 @@ public: // networks (dspf) are reduced and deleted after reading each net // with reduce_to and delete_after_reduce. // Return true if successful. - bool readSpef(const std::string &name, - const std::string &filename, + bool readSpef(std::string_view name, + std::string_view filename, Instance *instance, Scene *scene, const MinMaxAll *min_max, @@ -1328,7 +1335,7 @@ public: void searchPreamble(); // Define the delay calculator implementation. - void setArcDelayCalc(const char *delay_calc_name); + void setArcDelayCalc(std::string_view delay_calc_name); void setDebugLevel(const char *what, int level); @@ -1376,9 +1383,9 @@ public: PwrActivity activity(const Pin *pin, const Scene *scene); - void writeTimingModel(const char *lib_name, - const char *cell_name, - const char *filename, + void writeTimingModel(std::string_view lib_name, + std::string_view cell_name, + std::string_view filename, const Scene *scene); // Find equivalent cells in equiv_libs. @@ -1388,12 +1395,12 @@ public: LibertyCellSeq *equivCells(LibertyCell *cell); void writePathSpice(const Path *path, - const char *spice_filename, - const char *subckt_filename, - const char *lib_subckt_filename, - const char *model_filename, - const char *power_name, - const char *gnd_name, + std::string_view spice_filename, + std::string_view subckt_filename, + std::string_view lib_subckt_filename, + std::string_view model_filename, + std::string_view power_name, + std::string_view gnd_name, CircuitSim ckt_sim); //////////////////////////////////////////////////////////////// @@ -1485,13 +1492,10 @@ protected: virtual void makeObservers(); NetworkEdit *networkCmdEdit(); - LibertyLibrary *readLibertyFile(const char *filename, + LibertyLibrary *readLibertyFile(std::string_view filename, Scene *scene, const MinMaxAll *min_max, bool infer_latches); - // Allow external Liberty reader to parse forms not used by Sta. - virtual LibertyLibrary *readLibertyFile(const char *filename, - bool infer_latches); void delayCalcPreamble(); void delaysInvalidFrom(const Port *port); void delaysInvalidFromFanin(const Port *port); diff --git a/include/sta/StaMain.hh b/include/sta/StaMain.hh index db4291b8..6d818c41 100644 --- a/include/sta/StaMain.hh +++ b/include/sta/StaMain.hh @@ -24,6 +24,8 @@ #pragma once +#include + struct Tcl_Interp; namespace sta { @@ -58,11 +60,11 @@ unencode(const char *inits[]); bool findCmdLineFlag(int &argc, char *argv[], - const char *flag); + std::string_view flag); char * findCmdLineKey(int &argc, char *argv[], - const char *key); + std::string_view key); int parseThreadsArg(int &argc, diff --git a/include/sta/StringUtil.hh b/include/sta/StringUtil.hh index c2cfb13d..f9161a60 100644 --- a/include/sta/StringUtil.hh +++ b/include/sta/StringUtil.hh @@ -24,9 +24,12 @@ #pragma once +#include #include #include #include +#include +#include // for strncasecmp #include #include @@ -53,14 +56,6 @@ stringEq(const char *str1, return strncmp(str1, str2, length) == 0; } -inline bool -stringEqIf(const char *str1, - const char *str2) -{ - return (str1 == nullptr && str2 == nullptr) - || (str1 && str2 && strcmp(str1, str2) == 0); -} - // Case sensitive compare the beginning of str1 to str2. inline bool stringBeginEq(const char *str1, @@ -71,78 +66,24 @@ stringBeginEq(const char *str1, // Case insensitive compare the beginning of str1 to str2. inline bool -stringBeginEqual(const char *str1, - const char *str2) +stringBeginEqual(std::string_view str, + std::string_view prefix) { - return strncasecmp(str1, str2, strlen(str2)) == 0; + if (str.size() < prefix.size()) + return false; + return strncasecmp(str.data(), prefix.data(), prefix.size()) == 0; } // Case insensitive compare. inline bool -stringEqual(const char *str1, - const char *str2) +stringEqual(std::string_view s1, + std::string_view s2) { - return strcasecmp(str1, str2) == 0; + return std::ranges::equal(s1, s2, [](unsigned char c1, unsigned char c2) { + return std::tolower(c1) == std::tolower(c2); + }); } -inline bool -stringEqualIf(const char *str1, - const char *str2) -{ - return (str1 == nullptr && str2 == nullptr) - || (str1 && str2 && strcasecmp(str1, str2) == 0); -} - -inline bool -stringLess(const char *str1, - const char *str2) -{ - return strcmp(str1, str2) < 0; -} - -inline bool -stringLessIf(const char *str1, - const char *str2) -{ - return (str1 == nullptr && str2 != nullptr) - || (str1 != nullptr && str2 != nullptr && strcmp(str1, str2) < 0); -} - -class CharPtrLess -{ -public: - bool operator()(const char *string1, - const char *string2) const - { - return stringLess(string1, string2); - } -}; - -// Case insensitive comparision. -class CharPtrCaseLess -{ -public: - bool operator()(const char *string1, - const char *string2) const - { - return strcasecmp(string1, string2) < 0; - } -}; - -class StringLessIf -{ -public: - bool operator()(const char *string1, - const char *string2) const - { - return stringLessIf(string1, string2); - } -}; - -// strdup using new instead of malloc so delete can be used on the strings. -char * -stringCopy(const char *str); - void stringDeleteCheck(const char *str); @@ -153,17 +94,14 @@ stringDelete(const char *str) delete [] str; } +std::pair +stringFloat(const std::string &str); + bool isDigits(const char *str); -char * -makeTmpString(size_t length); -char * -makeTmpString(std::string &str); bool -isTmpString(const char *str); -void -deleteTmpStrings(); +isDigits(std::string_view str); //////////////////////////////////////////////////////////////// @@ -171,9 +109,9 @@ deleteTmpStrings(); void trimRight(std::string &str); -// Spit text into delimiter separated tokens and skip whitepace. +// Parse text into delimiter separated tokens and skip whitepace. StringSeq -parseTokens(const std::string &s, - const char delimiter); +parseTokens(const std::string &text, + std::string_view delims = " \t"); } // namespace diff --git a/include/sta/TableModel.hh b/include/sta/TableModel.hh index 95b51132..3afce335 100644 --- a/include/sta/TableModel.hh +++ b/include/sta/TableModel.hh @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "MinMax.hh" @@ -54,8 +55,8 @@ using Waveform = Table; using TableModelsEarlyLate = std::array; TableAxisVariable -stringTableAxisVariable(const char *variable); -const char * +stringTableAxisVariable(std::string_view variable); +std::string_view tableVariableString(TableAxisVariable variable); const Unit * tableVariableUnit(TableAxisVariable variable, @@ -121,7 +122,7 @@ protected: float in_slew, float load_cap, float related_out_cap) const; - std::string reportTableLookup(const char *result_name, + std::string reportTableLookup(std::string_view result_name, const Pvt *pvt, const TableModel *model, float in_slew, @@ -158,7 +159,7 @@ public: PocvMode pocv_mode) const override; std::string reportCheckDelay(const Pvt *pvt, float from_slew, - const char *from_slew_annotation, + std::string_view from_slew_annotation, float to_slew, float related_out_cap, const MinMax *min_max, @@ -189,11 +190,11 @@ protected: float load_cap, float in_slew, float related_out_cap) const; - std::string reportTableDelay(const char *result_name, + std::string reportTableDelay(std::string_view result_name, const Pvt *pvt, const TableModel *model, float from_slew, - const char *from_slew_annotation, + std::string_view from_slew_annotation, float to_slew, float related_out_cap, int digits) const; @@ -208,7 +209,7 @@ public: TableAxis(TableAxisVariable variable, FloatSeq &&values); TableAxisVariable variable() const { return variable_; } - const char *variableString() const; + std::string_view variableString() const; const Unit *unit(const Units *units); size_t size() const { return values_.size(); } bool inBounds(float value) const; @@ -287,11 +288,11 @@ public: float axis_value2, float axis_value3) const; - std::string reportValue(const char *result_name, + std::string reportValue(std::string_view result_name, const LibertyCell *cell, const Pvt *pvt, float value1, - const char *comment1, + std::string_view comment1, float value2, float value3, const Unit *table_unit, @@ -309,30 +310,30 @@ private: void clear(); float findValueOrder2(float axis_value1, float axis_value2) const; float findValueOrder3(float axis_value1, float axis_value2, float axis_value3) const; - std::string reportValueOrder0(const char *result_name, - const char *comment1, + std::string reportValueOrder0(std::string_view result_name, + std::string_view comment1, const Unit *table_unit, int digits) const; - std::string reportValueOrder1(const char *result_name, + std::string reportValueOrder1(std::string_view result_name, const LibertyCell *cell, float value1, - const char *comment1, + std::string_view comment1, float value2, float value3, const Unit *table_unit, int digits) const; - std::string reportValueOrder2(const char *result_name, + std::string reportValueOrder2(std::string_view result_name, const LibertyCell *cell, float value1, - const char *comment1, + std::string_view comment1, float value2, float value3, const Unit *table_unit, int digits) const; - std::string reportValueOrder3(const char *result_name, + std::string reportValueOrder3(std::string_view result_name, const LibertyCell *cell, float value1, - const char *comment1, + std::string_view comment1, float value2, float value3, const Unit *table_unit, @@ -379,11 +380,11 @@ public: float value1, float value2, float value3) const; - std::string reportValue(const char *result_name, + std::string reportValue(std::string_view result_name, const LibertyCell *cell, const Pvt *pvt, float value1, - const char *comment1, + std::string_view comment1, float value2, float value3, const Unit *table_unit, @@ -535,9 +536,9 @@ private: class DriverWaveform { public: - DriverWaveform(const std::string &name, + DriverWaveform(std::string name, TablePtr waveforms); - const char *name() const { return name_.c_str(); } + std::string_view name() const { return name_; } Table waveform(float slew); private: diff --git a/include/sta/TclTypeHelpers.hh b/include/sta/TclTypeHelpers.hh index 95584b7b..acb4e164 100644 --- a/include/sta/TclTypeHelpers.hh +++ b/include/sta/TclTypeHelpers.hh @@ -34,14 +34,14 @@ namespace sta { #endif StringSeq -tclListSeqStdString(Tcl_Obj *const source, - Tcl_Interp *interp); +tclListStringSeq(Tcl_Obj *const source, + Tcl_Interp *interp); StringSeq * -tclListSeqStdStringPtr(Tcl_Obj *const source, - Tcl_Interp *interp); -StringSet * -tclListSetStdString(Tcl_Obj *const source, +tclListStringSeqPtr(Tcl_Obj *const source, Tcl_Interp *interp); +StringSet * +tclListStringSet(Tcl_Obj *const source, + Tcl_Interp *interp); void tclArgError(Tcl_Interp *interp, diff --git a/include/sta/TimingArc.hh b/include/sta/TimingArc.hh index fcec3c4c..274f10e5 100644 --- a/include/sta/TimingArc.hh +++ b/include/sta/TimingArc.hh @@ -83,10 +83,10 @@ enum class TimingType { unknown }; -const char * +std::string_view to_string(TimingType type); TimingType -findTimingType(const char *string); +findTimingType(std::string_view string); bool timingTypeIsCheck(TimingType type); ScaleFactorType @@ -107,15 +107,15 @@ public: FuncExpr *cond() const { return cond_; } void setCond(FuncExpr *cond); const std::string &sdfCond() const { return sdf_cond_; } - void setSdfCond(const std::string &cond); + void setSdfCond(std::string cond); const std::string &sdfCondStart() const { return sdf_cond_start_; } - void setSdfCondStart(const std::string &cond); + void setSdfCondStart(std::string cond); const std::string &sdfCondEnd() const { return sdf_cond_end_; } - void setSdfCondEnd(const std::string &cond); + void setSdfCondEnd(std::string cond); const std::string &modeName() const { return mode_name_; } - void setModeName(const std::string &name); + void setModeName(std::string name); const std::string &modeValue() const { return mode_value_; } - void setModeValue(const std::string &value); + void setModeValue(std::string value); TimingModel *model(const RiseFall *rf) const; void setModel(const RiseFall *rf, TimingModel *model); diff --git a/include/sta/TimingModel.hh b/include/sta/TimingModel.hh index 0ff157f2..55e1623e 100644 --- a/include/sta/TimingModel.hh +++ b/include/sta/TimingModel.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include "Delay.hh" #include "LibertyClass.hh" @@ -88,7 +89,7 @@ public: PocvMode pocv_mode) const = 0; virtual std::string reportCheckDelay(const Pvt *pvt, float from_slew, - const char *from_slew_annotation, + std::string_view from_slew_annotation, float to_slew, float related_out_cap, const MinMax *min_max, diff --git a/include/sta/Transition.hh b/include/sta/Transition.hh index 4af601d4..9d01abbc 100644 --- a/include/sta/Transition.hh +++ b/include/sta/Transition.hh @@ -25,8 +25,9 @@ #pragma once #include -#include +#include #include +#include #include "Iterator.hh" #include "StringUtil.hh" @@ -37,7 +38,7 @@ class Transition; class RiseFall; class RiseFallBoth; -using TransitionMap = std::map; +using TransitionMap = std::map>; // Rise/fall transition. class RiseFall @@ -49,14 +50,14 @@ public: static int riseIndex() { return rise_.sdf_triple_index_; } static int fallIndex() { return fall_.sdf_triple_index_; } const std::string &to_string(bool use_short = false) const; - const char *name() const { return name_.c_str(); } - const char *shortName() const { return short_name_.c_str(); } + const std::string &name() const { return name_; } + const std::string &shortName() const { return short_name_; } int index() const { return sdf_triple_index_; } const RiseFallBoth *asRiseFallBoth(); const RiseFallBoth *asRiseFallBoth() const; const Transition *asTransition() const; // Find transition corresponding to rf_str. - static const RiseFall *find(const char *rf_str); + static const RiseFall *find(std::string_view rf_str); // Find transition from index. static const RiseFall *find(int index); const RiseFall *opposite() const; @@ -71,8 +72,8 @@ public: static const int index_bit_count = 1; protected: - RiseFall(const char *name, - const char *short_name, + RiseFall(std::string_view name, + std::string_view short_name, int sdf_triple_index); const std::string name_; @@ -94,14 +95,14 @@ public: static const RiseFallBoth *fall() { return &fall_; } static const RiseFallBoth *riseFall() { return &rise_fall_; } const std::string &to_string(bool use_short = false) const; - const char *name() const { return name_.c_str(); } - const char *shortName() const { return short_name_.c_str(); } + const std::string &name() const { return name_; } + const std::string &shortName() const { return short_name_; } int index() const { return sdf_triple_index_; } bool matches(const RiseFall *rf) const; bool matches(const Transition *tr) const; const RiseFall *asRiseFall() const { return as_rise_fall_; } // Find transition corresponding to string. - static const RiseFallBoth *find(const char *tr_str); + static const RiseFallBoth *find(std::string_view tr_str); // for (const auto rf : rf->range()) {} const std::vector &range() const { return range_; } // for (const auto rf_index : rf->rangeIndex()) {} @@ -112,8 +113,8 @@ public: static const int index_bit_count = 2; protected: - RiseFallBoth(const char *name, - const char *short_name, + RiseFallBoth(std::string_view name, + std::string_view short_name, int sdf_triple_index, const RiseFall *as_rise_fall, std::vector range, @@ -152,19 +153,19 @@ public: static const Transition *riseFall() { return &rise_fall_; } const std::string &to_string() const { return name_; } // As initial/final value pair. - const char *asInitFinalString() const { return init_final_.c_str(); } + const std::string &asInitFinalString() const { return init_final_; } int sdfTripleIndex() const { return sdf_triple_index_; } int index() const { return sdf_triple_index_; } const RiseFall *asRiseFall() const { return as_rise_fall_; } const RiseFallBoth *asRiseFallBoth() const; bool matches(const Transition *tr) const; // Find transition corresponding to string. - static const Transition *find(const char *tr_str); + static const Transition *find(std::string_view tr_str); static int maxIndex() { return max_index_; } private: - Transition(const char *name, - const char *init_final, + Transition(std::string_view name, + std::string_view init_final, const RiseFall *as_rise_fall, int sdf_triple_index); diff --git a/include/sta/Units.hh b/include/sta/Units.hh index 8c3475f5..0067fe75 100644 --- a/include/sta/Units.hh +++ b/include/sta/Units.hh @@ -75,7 +75,7 @@ class Units { public: Units(); - Unit *find(const char *unit_name); + Unit *find(std::string_view unit_name); void operator=(const Units &units); Unit *timeUnit() { return &time_unit_; } const Unit *timeUnit() const { return &time_unit_; } diff --git a/include/sta/VerilogReader.hh b/include/sta/VerilogReader.hh index 64499238..b28e0f23 100644 --- a/include/sta/VerilogReader.hh +++ b/include/sta/VerilogReader.hh @@ -74,7 +74,7 @@ public: std::string_view msg, bool warn); const char *msg() const { return msg_.c_str(); } - const char *filename() const { return filename_.c_str(); } + std::string_view filename() const { return filename_; } int id() const { return id_; } int line() const { return line_; } bool warn() const { return warn_; } @@ -102,14 +102,14 @@ class VerilogReader public: VerilogReader(NetworkReader *network); ~VerilogReader(); - bool read(const char *filename); + bool read(std::string_view filename); - void makeModule(const std::string *module_name, + void makeModule(std::string &&module_name, VerilogNetSeq *ports, VerilogStmtSeq *stmts, VerilogAttrStmtSeq *attr_stmts, int line); - void makeModule(const std::string *module_name, + void makeModule(std::string &&module_name, VerilogStmtSeq *port_dcls, VerilogStmtSeq *stmts, VerilogAttrStmtSeq *attr_stmts, @@ -122,7 +122,7 @@ public: VerilogDclArg *arg, VerilogAttrStmtSeq *attr_stmts, int line); - VerilogDclArg *makeDclArg(const std::string *net_name); + VerilogDclArg *makeDclArg(std::string &&net_name); VerilogDclArg*makeDclArg(VerilogAssign *assign); VerilogDclBus *makeDclBus(PortDirection *dir, int from_index, @@ -136,43 +136,43 @@ public: VerilogDclArgSeq *args, VerilogAttrStmtSeq *attr_stmts, int line); - VerilogInst *makeModuleInst(const std::string *module_name, - const std::string *inst_name, + VerilogInst *makeModuleInst(std::string &&module_name, + std::string &&inst_name, VerilogNetSeq *pins, VerilogAttrStmtSeq *attr_stmts, const int line); VerilogAssign *makeAssign(VerilogNet *lhs, VerilogNet *rhs, int line); - VerilogNetScalar *makeNetScalar(const std::string *name); - VerilogNetPortRef *makeNetNamedPortRefScalarNet(const std::string *port_vname); - VerilogNetPortRef *makeNetNamedPortRefScalarNet(const std::string *port_name, - const std::string *net_name); - VerilogNetPortRef *makeNetNamedPortRefBitSelect(const std::string *port_name, - const std::string *bus_name, + VerilogNetScalar *makeNetScalar(std::string &&name); + VerilogNetPortRef *makeNetNamedPortRefScalarNet(std::string &&port_vname); + VerilogNetPortRef *makeNetNamedPortRefScalarNet(std::string &&port_name, + std::string &&net_name); + VerilogNetPortRef *makeNetNamedPortRefBitSelect(std::string &&port_name, + std::string &&bus_name, int index); - VerilogNetPortRef *makeNetNamedPortRefScalar(const std::string *port_name, + VerilogNetPortRef *makeNetNamedPortRefScalar(std::string &&port_name, VerilogNet *net); - VerilogNetPortRef *makeNetNamedPortRefBit(const std::string *port_name, + VerilogNetPortRef *makeNetNamedPortRefBit(std::string &&port_name, int index, VerilogNet *net); - VerilogNetPortRef *makeNetNamedPortRefPart(const std::string *port_name, + VerilogNetPortRef *makeNetNamedPortRefPart(std::string &&port_name, int from_index, int to_index, VerilogNet *net); VerilogNetConcat *makeNetConcat(VerilogNetSeq *nets); - VerilogNetConstant *makeNetConstant(const std::string *constant, - int line); - VerilogNetBitSelect *makeNetBitSelect(const std::string *name, + VerilogNetConstant *makeNetConstant(std::string &&constant, + int line); + VerilogNetBitSelect *makeNetBitSelect(std::string &&name, int index); - VerilogNetPartSelect *makeNetPartSelect(const std::string *name, + VerilogNetPartSelect *makeNetPartSelect(std::string &&name, int from_index, int to_index); VerilogModule *module(Cell *cell); - Instance *linkNetwork(const char *top_cell_name, + Instance *linkNetwork(std::string_view top_cell_name, bool make_black_boxes, bool delete_modules); - const char *filename() const { return filename_.c_str(); } + std::string_view filename() const { return filename_; } void incrLine(); Report *report() const { return report_; } template @@ -196,11 +196,10 @@ public: const std::string &zeroNetName() const { return zero_net_name_; } const std::string &oneNetName() const { return one_net_name_; } void deleteModules(); - void reportStmtCounts(); const std::string &constant10Max() const { return constant10_max_; } protected: - void init(const char *filename); + void init(std::string_view filename); void makeCellPorts(Cell *cell, VerilogModule *module, VerilogNetSeq *ports); @@ -315,29 +314,6 @@ protected: const std::string one_net_name_; std::string constant10_max_; ViewType *view_type_; - bool report_stmt_stats_; - int module_count_; - int inst_mod_count_; - int inst_lib_count_; - int inst_lib_net_arrays_; - int port_names_; - int inst_module_names_; - int inst_names_; - int dcl_count_; - int dcl_bus_count_; - int dcl_arg_count_; - int net_scalar_count_; - int net_scalar_names_; - int net_bus_names_; - int net_part_select_count_; - int net_bit_select_count_; - int net_port_ref_scalar_count_; - int net_port_ref_scalar_net_count_; - int net_port_ref_bit_count_; - int net_port_ref_part_count_; - int net_constant_count_; - int assign_count_; - int concat_count_; }; } // namespace sta diff --git a/include/sta/Wireload.hh b/include/sta/Wireload.hh index 01c54a88..6ca8b536 100644 --- a/include/sta/Wireload.hh +++ b/include/sta/Wireload.hh @@ -24,6 +24,8 @@ #pragma once +#include +#include #include #include @@ -40,26 +42,26 @@ using WireloadForAreaSeq = std::vector; const char * wireloadTreeString(WireloadTree tree); WireloadTree -stringWireloadTree(const char *tree); +stringWireloadTree(std::string_view tree); const char * wireloadModeString(WireloadMode wire_load_mode); WireloadMode -stringWireloadMode(const char *wire_load_mode); +stringWireloadMode(std::string_view wire_load_mode); class Wireload { public: - Wireload(const char *name, + Wireload(std::string name, LibertyLibrary *library); - Wireload(const char *name, + Wireload(std::string name, LibertyLibrary *library, float area, float resistance, float capacitance, float slope); virtual ~Wireload(); - const char *name() const { return name_; } + const std::string &name() const { return name_; } void setArea(float area); void setResistance(float res); void setCapacitance(float cap); @@ -73,7 +75,7 @@ public: float &res) const; protected: - const char *name_; + std::string name_; LibertyLibrary *library_; float area_; float resistance_; @@ -86,16 +88,16 @@ protected: class WireloadSelection { public: - WireloadSelection(const char *name); + WireloadSelection(std::string name); ~WireloadSelection(); - const char *name() const { return name_; } + const std::string &name() const { return name_; } void addWireloadFromArea(float min_area, float max_area, const Wireload *wireload); const Wireload *findWireload(float area) const; private: - const char *name_; + const std::string name_; WireloadForAreaSeq wireloads_; }; diff --git a/liberty/EquivCells.cc b/liberty/EquivCells.cc index d0b96b30..e4fbba44 100644 --- a/liberty/EquivCells.cc +++ b/liberty/EquivCells.cc @@ -208,7 +208,7 @@ hashCellPorts(const LibertyCell *cell) static unsigned hashPort(const LibertyPort *port) { - return hashString(port->name()) * 3 + return hashString(port->name().c_str()) * 3 + port->direction()->index() * 5; } @@ -338,8 +338,7 @@ equivCellFuncs(const LibertyCell *cell1, LibertyCellPortIterator port_iter1(cell1); while (port_iter1.hasNext()) { LibertyPort *port1 = port_iter1.next(); - const char *name = port1->name(); - LibertyPort *port2 = cell2->findLibertyPort(name); + LibertyPort *port2 = cell2->findLibertyPort(port1->name()); if (!(port2 && FuncExpr::equiv(port1->function(), port2->function()) && FuncExpr::equiv(port1->tristateEnable(), @@ -359,8 +358,7 @@ equivCellPorts(const LibertyCell *cell1, LibertyCellPortIterator port_iter1(cell1); while (port_iter1.hasNext()) { LibertyPort *port1 = port_iter1.next(); - const char* name = port1->name(); - LibertyPort *port2 = cell2->findLibertyPort(name); + LibertyPort *port2 = cell2->findLibertyPort(port1->name()); if (!(port2 && LibertyPort::equiv(port1, port2))) return false; } diff --git a/liberty/InternalPower.cc b/liberty/InternalPower.cc index d9ecd617..ed2cad24 100644 --- a/liberty/InternalPower.cc +++ b/liberty/InternalPower.cc @@ -108,7 +108,7 @@ InternalPowerModel::reportPower(const LibertyCell *cell, findAxisValues(in_slew, load_cap, axis_value1, axis_value2, axis_value3); const LibertyLibrary *library = cell->libertyLibrary(); - return model_->reportValue("Power", cell, pvt, axis_value1, nullptr, + return model_->reportValue("Power", cell, pvt, axis_value1, {}, axis_value2, axis_value3, library->units()->powerUnit(), digits); } diff --git a/liberty/LibExprLex.ll b/liberty/LibExprLex.ll index e9a3f70b..69402d84 100644 --- a/liberty/LibExprLex.ll +++ b/liberty/LibExprLex.ll @@ -25,14 +25,14 @@ // Liberty function expression lexical analyzer +#include + #include "util/FlexDisableRegister.hh" #include "Debug.hh" -#include "StringUtil.hh" #include "liberty/LibExprReaderPvt.hh" #include "liberty/LibExprReader.hh" #include "liberty/LibExprScanner.hh" -using sta::stringCopy; using sta::FuncExpr; #include "LibExprParse.hh" @@ -76,12 +76,12 @@ EOL \r?\n {ESCAPE}{QUOTE} { BEGIN(INITIAL); - yylval->string = stringCopy(token_.c_str()); + yylval->emplace(token_); return token::PORT; } {PORT} { - yylval->string = stringCopy(yytext); + yylval->emplace(yytext, yyleng); return token::PORT; } diff --git a/liberty/LibExprParse.yy b/liberty/LibExprParse.yy index fc1a4a7d..443f0ce7 100644 --- a/liberty/LibExprParse.yy +++ b/liberty/LibExprParse.yy @@ -25,6 +25,8 @@ // Liberty function expression parser. %{ +#include + #include "FuncExpr.hh" #include "liberty/LibExprReader.hh" #include "liberty/LibExprReaderPvt.hh" @@ -39,7 +41,7 @@ void sta::LibExprParse::error(const std::string &msg) { - reader->parseError(msg.c_str()); + reader->parseError(msg); } %} @@ -52,21 +54,15 @@ sta::LibExprParse::error(const std::string &msg) %parse-param{LibExprScanner *scanner} %parse-param{LibExprReader *reader} %define api.parser.class {LibExprParse} +%define api.value.type variant -%union { - int int_val; - const char *string; - sta::FuncExpr *expr; -} - -%token PORT +%token PORT %left '+' '|' %left '*' '&' %left '^' %left '!' '\'' -%type PORT -%type expr terminal terminal_expr implicit_and +%type expr terminal terminal_expr implicit_and %% @@ -76,14 +72,14 @@ result_expr: ; terminal: - PORT { $$ = reader->makeFuncExprPort($1); } + PORT { $$ = reader->makeFuncExprPort(std::move($1)); } | '0' { $$ = sta::FuncExpr::makeZero(); } | '1' { $$ = sta::FuncExpr::makeOne(); } | '(' expr ')' { $$ = $2; } ; terminal_expr: - terminal + terminal { $$ = $1; } | '!' terminal { $$ = reader->makeFuncExprNot($2); } | terminal '\'' { $$ = reader->makeFuncExprNot($1); } ; @@ -96,8 +92,8 @@ implicit_and: ; expr: - terminal_expr -| implicit_and + terminal_expr { $$ = $1; } +| implicit_and { $$ = $1; } | expr '+' expr { $$ = reader->makeFuncExprOr($1, $3); } | expr '|' expr { $$ = reader->makeFuncExprOr($1, $3); } | expr '*' expr { $$ = reader->makeFuncExprAnd($1, $3); } diff --git a/liberty/LibExprReader.cc b/liberty/LibExprReader.cc index 1b2fc037..d7427223 100644 --- a/liberty/LibExprReader.cc +++ b/liberty/LibExprReader.cc @@ -26,9 +26,10 @@ #include #include +#include +#include #include "Report.hh" -#include "StringUtil.hh" #include "Liberty.hh" #include "LibExprReaderPvt.hh" #include "LibExprScanner.hh" @@ -36,14 +37,14 @@ namespace sta { FuncExpr * -parseFuncExpr(const char *func, +parseFuncExpr(std::string_view func, const LibertyCell *cell, - const char *error_msg, + std::string_view error_msg, Report *report) { - if (func != nullptr && func[0] != '\0') { - std::string func1(func); - std::istringstream stream(func); + if (!func.empty()) { + std::string func_str(func); + std::istringstream stream(func_str); LibExprReader reader(func, cell, error_msg, report); LibExprScanner scanner(stream); LibExprParse parser(&scanner, &reader); @@ -55,9 +56,9 @@ parseFuncExpr(const char *func, return nullptr; } -LibExprReader::LibExprReader(const char *func, +LibExprReader::LibExprReader(std::string_view func, const LibertyCell *cell, - const char *error_msg, + std::string_view error_msg, Report *report) : func_(func), cell_(cell), @@ -70,18 +71,18 @@ LibExprReader::LibExprReader(const char *func, // defined in LibertyReader.cc LibertyPort * libertyReaderFindPort(const LibertyCell *cell, - const char *port_name); + std::string_view port_name); FuncExpr * -LibExprReader::makeFuncExprPort(const char *port_name) +LibExprReader::makeFuncExprPort(std::string &&port_name) { FuncExpr *expr = nullptr; - LibertyPort *port = libertyReaderFindPort(cell_, port_name); + const std::string_view port_view(port_name); + LibertyPort *port = libertyReaderFindPort(cell_, port_view); if (port) expr = FuncExpr::makePort(port); else - report_->warn(1130, "{} references unknown port {}.", error_msg_, port_name); - stringDelete(port_name); + report_->warn(1130, "{} references unknown port {}.", error_msg_, port_view); return expr; } @@ -131,7 +132,7 @@ LibExprReader::setResult(FuncExpr *result) } void -LibExprReader::parseError(const char *msg) +LibExprReader::parseError(std::string_view msg) { report_->error(1131, "{} {}.", error_msg_, msg); } diff --git a/liberty/LibExprReader.hh b/liberty/LibExprReader.hh index 3f65600e..6b0c8cbe 100644 --- a/liberty/LibExprReader.hh +++ b/liberty/LibExprReader.hh @@ -24,6 +24,8 @@ #pragma once +#include + namespace sta { class Report; @@ -31,9 +33,9 @@ class FuncExpr; class LibertyCell; FuncExpr * -parseFuncExpr(const char *func, +parseFuncExpr(std::string_view func, const LibertyCell *cell, - const char *error_msg, + std::string_view error_msg, Report *report); } // namespace diff --git a/liberty/LibExprReaderPvt.hh b/liberty/LibExprReaderPvt.hh index aa7d0646..b6b27bc8 100644 --- a/liberty/LibExprReaderPvt.hh +++ b/liberty/LibExprReaderPvt.hh @@ -24,6 +24,9 @@ #pragma once +#include +#include + namespace sta { class Report; @@ -34,11 +37,11 @@ class LibExprScanner; class LibExprReader { public: - LibExprReader(const char *func, + LibExprReader(std::string_view func, const LibertyCell *cell, - const char *error_msg, + std::string_view error_msg, Report *report); - FuncExpr *makeFuncExprPort(const char *port_name); + FuncExpr *makeFuncExprPort(std::string &&port_name); FuncExpr *makeFuncExprOr(FuncExpr *arg1, FuncExpr *arg2); FuncExpr *makeFuncExprAnd(FuncExpr *arg1, @@ -48,15 +51,13 @@ public: FuncExpr *makeFuncExprNot(FuncExpr *arg); void setResult(FuncExpr *result); FuncExpr *result() { return result_; } - void parseError(const char *msg); - size_t copyInput(char *buf, - size_t max_size); + void parseError(std::string_view msg); Report *report() const { return report_; } private: - const char *func_; + std::string_view func_; const LibertyCell *cell_; - const char *error_msg_; + std::string_view error_msg_; Report *report_; FuncExpr *result_; }; diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 17d0b464..ed471745 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -62,9 +62,9 @@ deleteLiberty() TimingArcSet::destroy(); } -LibertyLibrary::LibertyLibrary(const char *name, - const char *filename) : - ConcreteLibrary(name, filename, true), +LibertyLibrary::LibertyLibrary(std::string name, + std::string filename) : + ConcreteLibrary(std::move(name), std::move(filename), true), units_(new Units()), delay_model_type_(DelayModelType::table), // default nominal_process_(0.0), @@ -121,7 +121,7 @@ LibertyLibrary::~LibertyLibrary() } LibertyCell * -LibertyLibrary::findLibertyCell(const char *name) const +LibertyLibrary::findLibertyCell(std::string_view name) const { return static_cast(findCell(name)); } @@ -188,10 +188,9 @@ LibertyLibrary::makeBusDcl(std::string name, } BusDcl * -LibertyLibrary::findBusDcl(const char *name) const +LibertyLibrary::findBusDcl(std::string_view name) { - auto it = bus_dcls_.find(name); - return it != bus_dcls_.end() ? const_cast(&it->second) : nullptr; + return findStringValuePtr(bus_dcls_, name); } BusDclSeq @@ -208,16 +207,17 @@ LibertyLibrary::makeTableTemplate(std::string name, TableTemplateType type) { std::string key = name; - auto [it, inserted] = template_maps_[int(type)].try_emplace( - std::move(key), std::move(name), type); + auto [it, inserted] = template_maps_[int(type)].try_emplace(std::move(key), + std::move(name), + type); return &it->second; } TableTemplate * -LibertyLibrary::findTableTemplate(const char *name, +LibertyLibrary::findTableTemplate(std::string_view name, TableTemplateType type) { - return findKeyValuePtr(template_maps_[int(type)], name); + return findStringValuePtr(template_maps_[int(type)], name); } TableTemplateSeq @@ -265,16 +265,17 @@ LibertyLibrary::setScaleFactors(ScaleFactors *scales) } ScaleFactors * -LibertyLibrary::makeScaleFactors(const char *name) +LibertyLibrary::makeScaleFactors(std::string name) { - auto [it, inserted] = scale_factors_map_.emplace(name, name); + std::string key = name; + auto [it, inserted] = scale_factors_map_.emplace(std::move(key), std::move(name)); return &it->second; } ScaleFactors * -LibertyLibrary::findScaleFactors(const char *name) +LibertyLibrary::findScaleFactors(std::string_view name) { - return findKeyValuePtr(scale_factors_map_, name); + return findStringValuePtr(scale_factors_map_,name); } float @@ -566,16 +567,14 @@ LibertyLibrary::setDefaultOutputPinRes(const RiseFall *rf, Wireload * LibertyLibrary::makeWireload(std::string name) { - std::string key = name; - auto [it, inserted] = wireloads_.try_emplace( - std::move(key), name.c_str(), this); + auto [it, inserted] = wireloads_.try_emplace(name, name, this); return &it->second; } const Wireload * -LibertyLibrary::findWireload(const char *name) const +LibertyLibrary::findWireload(std::string_view name) { - return findKeyValuePtr(wireloads_, name); + return findStringValuePtr(wireloads_, name); } void @@ -594,14 +593,15 @@ WireloadSelection * LibertyLibrary::makeWireloadSelection(std::string name) { std::string key = name; - auto [it, inserted] = wire_load_selections_.try_emplace(std::move(key), name.c_str()); + auto [it, inserted] = wire_load_selections_.try_emplace(std::move(key), + std::move(name)); return &it->second; } const WireloadSelection * -LibertyLibrary::findWireloadSelection(const char *name) const +LibertyLibrary::findWireloadSelection(std::string_view name) const { - return findKeyValuePtr(wire_load_selections_, name); + return findStringValuePtr(wire_load_selections_, name); } const WireloadSelection * @@ -632,15 +632,14 @@ OperatingConditions * LibertyLibrary::makeOperatingConditions(std::string name) { std::string key = name; - auto [it, inserted] = operating_conditions_.try_emplace( - std::move(key), name.c_str()); + auto [it, inserted] = operating_conditions_.try_emplace(std::move(key), std::move(name)); return &it->second; } OperatingConditions * -LibertyLibrary::findOperatingConditions(const char *name) +LibertyLibrary::findOperatingConditions(std::string_view name) { - return findKeyValuePtr(operating_conditions_, name); + return findStringValuePtr(operating_conditions_, name); } OperatingConditions * @@ -720,11 +719,10 @@ LibertyLibrary::setSlewDerateFromLibrary(float derate) } LibertyCell * -LibertyLibrary::makeScaledCell(const char *name, - const char *filename) +LibertyLibrary::makeScaledCell(std::string name, + std::string filename) { - LibertyCell *cell = new LibertyCell(this, name, filename); - return cell; + return new LibertyCell(this, std::move(name), std::move(filename)); } //////////////////////////////////////////////////////////////// @@ -738,8 +736,7 @@ LibertyLibrary::makeSceneMap(LibertyLibrary *lib, LibertyCellIterator cell_iter(lib); while (cell_iter.hasNext()) { LibertyCell *cell = cell_iter.next(); - const char *name = cell->name(); - LibertyCell *link_cell = network->findLibertyCell(name); + LibertyCell *link_cell = network->findLibertyCell(cell->name()); if (link_cell) makeSceneMap(link_cell, cell, ap_index, report); } @@ -769,8 +766,7 @@ LibertyLibrary::makeSceneMap(LibertyCell *cell1, LibertyCellPortBitIterator port_iter1(cell1); while (port_iter1.hasNext()) { LibertyPort *port1 = port_iter1.next(); - const char *port_name = port1->name(); - LibertyPort *port2 = cell2->findLibertyPort(port_name); + LibertyPort *port2 = cell2->findLibertyPort(port1->name()); if (port2) { if (link) port1->setScenePort(port2, ap_index); @@ -779,7 +775,7 @@ LibertyLibrary::makeSceneMap(LibertyCell *cell1, report->warn(1110, "cell {}/{} port {} not found in cell {}/{}.", cell1->library()->name(), cell1->name(), - port_name, + port1->name(), cell2->library()->name(), cell2->name()); } @@ -807,7 +803,7 @@ LibertyLibrary::makeSceneMap(LibertyCell *cell1, cell1->name(), arc_set1->from() ? arc_set1->from()->name() : "", arc_set1->to()->name(), - arc_set1->role()->to_string().c_str(), + arc_set1->role()->to_string(), cell2->library()->name(), cell2->name()); } @@ -824,8 +820,8 @@ LibertyLibrary::checkScenes(LibertyCell *cell, report->error(1112, "Liberty cell {}/{} for corner {}/{} not found.", cell->libertyLibrary()->name(), cell->name(), - scene->name().c_str(), - min_max->to_string().c_str()); + scene->name(), + min_max->to_string()); } } } @@ -865,21 +861,20 @@ LibertyLibrary::makeOcvDerate(std::string name) } OcvDerate * -LibertyLibrary::findOcvDerate(const char *derate_name) +LibertyLibrary::findOcvDerate(std::string_view derate_name) { - auto it = ocv_derate_map_.find(derate_name); - return it != ocv_derate_map_.end() ? &it->second : nullptr; + return findStringValuePtr(ocv_derate_map_, derate_name); } void -LibertyLibrary::addSupplyVoltage(const char *supply_name, +LibertyLibrary::addSupplyVoltage(std::string supply_name, float voltage) { - supply_voltage_map_[supply_name] = voltage; + supply_voltage_map_[std::move(supply_name)] = voltage; } void -LibertyLibrary::supplyVoltage(const char *supply_name, +LibertyLibrary::supplyVoltage(std::string_view supply_name, // Return value. float &voltage, bool &exists) const @@ -896,26 +891,26 @@ LibertyLibrary::supplyVoltage(const char *supply_name, } bool -LibertyLibrary::supplyExists(const char *supply_name) const +LibertyLibrary::supplyExists(std::string_view supply_name) const { return supply_voltage_map_.contains(supply_name); } DriverWaveform * -LibertyLibrary::findDriverWaveform(const char *name) +LibertyLibrary::findDriverWaveform(std::string_view name) { - auto it = driver_waveform_map_.find(name); - if (it != driver_waveform_map_.end()) - return &it->second; - return nullptr; + return findStringValuePtr(driver_waveform_map_, name); } DriverWaveform * -LibertyLibrary::makeDriverWaveform(const std::string &name, +LibertyLibrary::makeDriverWaveform(std::string name, TablePtr waveforms) { - auto it = driver_waveform_map_.emplace(name, DriverWaveform(name, waveforms)); - return &it.first->second; + std::string key = name; + auto [it, inserted] = driver_waveform_map_.try_emplace(std::move(key), + std::move(name), + waveforms); + return &it->second; } //////////////////////////////////////////////////////////////// @@ -940,8 +935,8 @@ LibertyCellIterator::next() //////////////////////////////////////////////////////////////// LibertyCell::LibertyCell(LibertyLibrary *library, - const char *name, - const char *filename) : + std::string name, + std::string filename) : ConcreteCell(name, filename, true, library), liberty_library_(library), area_(0.0), @@ -982,7 +977,7 @@ LibertyCell::~LibertyCell() } LibertyPort * -LibertyCell::findLibertyPort(const char *name) const +LibertyCell::findLibertyPort(std::string_view name) const { return static_cast(findPort(name)); } @@ -1032,9 +1027,9 @@ LibertyCell::makeModeDef(std::string name) } const ModeDef * -LibertyCell::findModeDef(const char *name) const +LibertyCell::findModeDef(std::string_view name) const { - return findKeyValuePtr(mode_defs_, name); + return findStringValuePtr(mode_defs_, name); } void @@ -1054,10 +1049,9 @@ LibertyCell::makeBusDcl(std::string name, } BusDcl * -LibertyCell::findBusDcl(const char *name) const +LibertyCell::findBusDcl(std::string_view name) { - auto it = bus_dcls_.find(name); - return it != bus_dcls_.end() ? const_cast(&it->second) : nullptr; + return findStringValuePtr(bus_dcls_, name); } void @@ -1494,8 +1488,7 @@ LibertyCell::outputPortSequential(LibertyPort *port) bool LibertyCell::hasSequentials() const { - return !sequentials_.empty() - || statetable_ != nullptr; + return !sequentials_.empty(); } void @@ -1639,10 +1632,9 @@ LibertyCell::makeOcvDerate(std::string name) } OcvDerate * -LibertyCell::findOcvDerate(const char *derate_name) +LibertyCell::findOcvDerate(std::string_view derate_name) { - auto it = ocv_derate_map_.find(derate_name); - return it != ocv_derate_map_.end() ? &it->second : nullptr; + return findStringValuePtr(ocv_derate_map_, derate_name); } //////////////////////////////////////////////////////////////// @@ -1936,35 +1928,16 @@ LibertyCell::ensureVoltageWaveforms(const SceneSeq &scenes) } } -const char * -LibertyCell::footprint() const -{ - if (footprint_.empty()) - return nullptr; - else - return footprint_.c_str(); -} - - void -LibertyCell::setFootprint(const char *footprint) +LibertyCell::setFootprint(std::string footprint) { - footprint_ = footprint; -} - -const char * -LibertyCell::userFunctionClass() const -{ - if (user_function_class_.empty()) - return nullptr; - else - return user_function_class_.c_str(); + footprint_ = std::move(footprint); } void -LibertyCell::setUserFunctionClass(const char *user_function_class) +LibertyCell::setUserFunctionClass(std::string user_function_class) { - user_function_class_ = user_function_class; + user_function_class_ = std::move(user_function_class); } //////////////////////////////////////////////////////////////// @@ -2013,14 +1986,15 @@ LibertyCellPortBitIterator::next() //////////////////////////////////////////////////////////////// LibertyPort::LibertyPort(LibertyCell *cell, - const char *name, + std::string name, bool is_bus, BusDcl *bus_dcl, int from_index, int to_index, bool is_bundle, ConcretePortSeq *members) : - ConcretePort(name, is_bus, from_index, to_index, is_bundle, members, cell), + ConcretePort(name, is_bus, from_index, to_index, + is_bundle, members, cell), liberty_cell_(cell), bus_dcl_(bus_dcl), pwr_gnd_type_(PwrGndType::none), @@ -2033,6 +2007,8 @@ LibertyPort::LibertyPort(LibertyCell *cell, min_period_(0.0), pulse_clk_trigger_(nullptr), pulse_clk_sense_(nullptr), + related_ground_port_(nullptr), + related_power_port_(nullptr), receiver_model_(nullptr), driver_waveform_{nullptr, nullptr}, min_pulse_width_exists_(false), @@ -2103,9 +2079,9 @@ LibertyPort::setPwrGndType(PwrGndType type) } void -LibertyPort::setVoltageName(const char *voltage_name) +LibertyPort::setVoltageName(std::string voltage_name) { - voltage_name_ = voltage_name; + voltage_name_ = std::move(voltage_name); } static EnumNameMap pwr_gnd_type_map = @@ -2121,21 +2097,21 @@ static EnumNameMap pwr_gnd_type_map = {PwrGndType::deepnwell, "deepnwell"}, {PwrGndType::deeppwell, "deeppwell"}}; -const char * +const std::string & pwrGndTypeName(PwrGndType pg_type) { return pwr_gnd_type_map.find(pg_type); } PwrGndType -findPwrGndType(const char *pg_name) +findPwrGndType(std::string_view pg_name) { return pwr_gnd_type_map.find(pg_name, PwrGndType::none); } //////////////////////////////////////////////////////////////// -const char * +const std::string & scanSignalTypeName(ScanSignalType scan_type) { return scan_signal_type_map.find(scan_type); @@ -2491,7 +2467,7 @@ LibertyPort::equiv(const LibertyPort *port1, { return (port1 == nullptr && port2 == nullptr) || (port1 != nullptr && port2 != nullptr - && stringEq(port1->name(), port2->name()) + && port1->name() == port2->name() && port1->direction() == port2->direction() && port1->pwr_gnd_type_ == port2->pwr_gnd_type_); } @@ -2504,14 +2480,14 @@ LibertyPort::less(const LibertyPort *port1, return true; if (port1 != nullptr && port2 == nullptr) return false; - const char *name1 = port1->name(); - const char *name2 = port2->name(); - if (stringEq(name1, name2)) { + const std::string &name1 = port1->name(); + const std::string &name2 = port2->name(); + if (name1 == name2) { PortDirection *dir1 = port1->direction(); PortDirection *dir2 = port2->direction(); return dir1->index() < dir2->index(); } - return stringLess(name1, name2); + return name1 < name2; } void @@ -2674,34 +2650,16 @@ LibertyPort::setScenePort(LibertyPort *scene_port, scene_ports_[ap_index] = scene_port; } -const char * -LibertyPort::relatedGroundPin() const +void +LibertyPort::setRelatedGroundPort(LibertyPort *related_ground_port) { - if (related_ground_pin_.empty()) - return nullptr; - else - return related_ground_pin_.c_str(); + related_ground_port_ = related_ground_port; } void -LibertyPort::setRelatedGroundPin(const char *related_ground_pin) +LibertyPort::setRelatedPowerPort(LibertyPort *related_power_port) { - related_ground_pin_ = related_ground_pin; -} - -const char * -LibertyPort::relatedPowerPin() const -{ - if (related_power_pin_.empty()) - return nullptr; - else - return related_power_pin_.c_str(); -} - -void -LibertyPort::setRelatedPowerPin(const char *related_power_pin) -{ - related_power_pin_ = related_power_pin; + related_power_port_ = related_power_port; } void @@ -2711,13 +2669,12 @@ LibertyPort::setReceiverModel(ReceiverModelPtr receiver_model) } std::string -portLibertyToSta(const char *port_name) +portLibertyToSta(std::string_view port_name) { constexpr char bus_brkt_left = '['; constexpr char bus_brkt_right = ']'; - size_t name_length = strlen(port_name); std::string sta_name; - for (size_t i = 0; i < name_length; i++) { + for (size_t i = 0; i < port_name.size(); i++) { char ch = port_name[i]; if (ch == bus_brkt_left || ch == bus_brkt_right) @@ -2841,7 +2798,7 @@ bool LibertyPortNameLess::operator()(const LibertyPort *port1, const LibertyPort *port2) const { - return stringLess(port1->name(), port2->name()); + return port1->name() < port2->name(); } bool @@ -2900,30 +2857,24 @@ ModeDef::ModeDef(std::string name) : } ModeValueDef * -ModeDef::defineValue(const char *value, - FuncExpr *cond, - const char *sdf_cond) +ModeDef::defineValue(std::string value) { std::string key = value; - std::string sdf = sdf_cond ? sdf_cond : std::string(); - auto [it, inserted] = values_.try_emplace(key, key, cond, std::move(sdf)); + auto [it, inserted] = values_.try_emplace(std::move(key), std::move(value)); return &it->second; } const ModeValueDef * -ModeDef::findValueDef(const char *value) const +ModeDef::findValueDef(std::string_view value) const { - return findKeyValuePtr(values_, value); + return findStringValuePtr(values_, value); } //////////////////////////////////////////////////////////////// -ModeValueDef::ModeValueDef(std::string value, - FuncExpr *cond, - std::string sdf_cond) : +ModeValueDef::ModeValueDef(std::string value) : value_(std::move(value)), - cond_(cond), - sdf_cond_(std::move(sdf_cond)) + cond_(nullptr) { } @@ -3038,25 +2989,14 @@ Pvt::setTemperature(float temp) temperature_ = temp; } -OperatingConditions::OperatingConditions(const char *name) : +OperatingConditions::OperatingConditions(std::string name) : Pvt(0.0, 0.0, 0.0), - name_(name), + name_(std::move(name)), // Default wireload tree. wire_load_tree_(WireloadTree::unknown) { } -OperatingConditions::OperatingConditions(const char *name, - float process, - float voltage, - float temperature, - WireloadTree wire_load_tree) : - Pvt(process, voltage, temperature), - name_(name), - wire_load_tree_(wire_load_tree) -{ -} - void OperatingConditions::setWireloadTree(WireloadTree tree) { @@ -3084,7 +3024,7 @@ static EnumNameMap scale_factor_type_map = {ScaleFactorType::unknown, "unknown"} }; -const char * +const std::string & scaleFactorTypeName(ScaleFactorType type) { return scale_factor_type_map.find(type); @@ -3137,7 +3077,7 @@ findScaleFactorPvt(const char *name) return scale_factor_pvt_names.find(name, ScaleFactorPvt::unknown); } -const char * +const std::string & scaleFactorPvtName(ScaleFactorPvt pvt) { return scale_factor_pvt_names.find(pvt); @@ -3145,8 +3085,8 @@ scaleFactorPvtName(ScaleFactorPvt pvt) //////////////////////////////////////////////////////////////// -ScaleFactors::ScaleFactors(const char *name) : - name_(name) +ScaleFactors::ScaleFactors(std::string name) : + name_(std::move(name)) { for (int type = 0; type < scale_factor_type_count; type++) { for (int pvt = 0; pvt < scale_factor_pvt_count; pvt++) { @@ -3230,7 +3170,7 @@ ScaleFactors::report(Report *report) TestCell::TestCell(LibertyLibrary *library, std::string name, std::string filename) : - LibertyCell(library, name.c_str(), filename.c_str()) + LibertyCell(library, name, filename) { } diff --git a/liberty/Liberty.i b/liberty/Liberty.i index 07529526..a87cd799 100644 --- a/liberty/Liberty.i +++ b/liberty/Liberty.i @@ -173,7 +173,7 @@ find_library_buffers(LibertyLibrary *library) return library->buffers(); } -const char * +std::string_view liberty_port_direction(const LibertyPort *port) { return port->direction()->name(); @@ -220,7 +220,7 @@ timing_role_is_check(const TimingRole *role) //////////////////////////////////////////////////////////////// %extend LibertyLibrary { -const char *name() { return self->name(); } +const char *name() { return self->name().c_str(); } LibertyCell * find_liberty_cell(const char *name) @@ -264,7 +264,7 @@ default_operating_conditions() } // LibertyLibrary methods %extend LibertyCell { -const char *name() { return self->name(); } +const char *name() { return self->name().c_str(); } bool is_leaf() { return self->isLeaf(); } bool is_buffer() { return self->isBuffer(); } bool is_inverter() { return self->isInverter(); } @@ -306,7 +306,8 @@ LibertyCell *test_cell() { return self->testCell(); } } // LibertyCell methods %extend LibertyPort { -const char *bus_name() { return self->busName(); } +const char *name() { return self->name().c_str(); } +std::string bus_name() { return self->busName(); } Cell *cell() { return self->cell(); } bool is_bus() { return self->isBus(); } bool is_bus_bit() { return self->isBusBit(); } @@ -355,7 +356,7 @@ set_direction(const char *dir) const char * scan_signal_type() { - return scanSignalTypeName(self->scanSignalType()); + return scanSignalTypeName(self->scanSignalType()).c_str(); } } // LibertyPort methods @@ -370,10 +371,10 @@ const char *sdf_cond() { return self->sdfCond().c_str(); } std::string full_name() { - const char *from = self->from()->name(); - const char *to = self->to()->name(); - const char *cell_name = self->libertyCell()->name(); - return sta::format("{} {} -> {}", cell_name, from, to); + return sta::format("{} {} -> {}", + self->libertyCell()->name(), + self->from()->name(), + self->to()->name()); } const std::string @@ -395,9 +396,9 @@ timing_arcs() { return self->arcs(); } LibertyPort *from() { return self->from(); } LibertyPort *to() { return self->to(); } const Transition *from_edge() { return self->fromEdge(); } -const char *from_edge_name() { return self->fromEdge()->asRiseFall()->name(); } +const char *from_edge_name() { return self->fromEdge()->asRiseFall()->name().c_str(); } const Transition *to_edge() { return self->toEdge(); } -const char *to_edge_name() { return self->toEdge()->asRiseFall()->name(); } +const char *to_edge_name() { return self->toEdge()->asRiseFall()->name().c_str(); } const TimingRole *role() { return self->role(); } float diff --git a/liberty/LibertyBuilder.cc b/liberty/LibertyBuilder.cc index 52cd97d5..e7e92791 100644 --- a/liberty/LibertyBuilder.cc +++ b/liberty/LibertyBuilder.cc @@ -36,7 +36,7 @@ namespace sta { LibertyBuilder::LibertyBuilder(Debug *debug, - Report *report) : + Report *report) : debug_(debug), report_(report) { @@ -44,19 +44,19 @@ LibertyBuilder::LibertyBuilder(Debug *debug, LibertyCell * LibertyBuilder::makeCell(LibertyLibrary *library, - const char *name, - const char *filename) + std::string_view name, + std::string_view filename) { - LibertyCell *cell = new LibertyCell(library, name, filename); + LibertyCell *cell = new LibertyCell(library, std::string(name), std::string(filename)); library->addCell(cell); return cell; } LibertyPort * LibertyBuilder::makePort(LibertyCell *cell, - const char *port_name) + std::string_view port_name) { - LibertyPort *port = new LibertyPort(cell, port_name, false, nullptr, + LibertyPort *port = new LibertyPort(cell, std::string(port_name), false, nullptr, -1, -1, false, nullptr); cell->addPort(port); return port; @@ -64,12 +64,12 @@ LibertyBuilder::makePort(LibertyCell *cell, LibertyPort * LibertyBuilder::makeBusPort(LibertyCell *cell, - const char *bus_name, + std::string_view bus_name, int from_index, int to_index, BusDcl *bus_dcl) { - LibertyPort *port = new LibertyPort(cell, bus_name, true, bus_dcl, + LibertyPort *port = new LibertyPort(cell, std::string(bus_name), true, bus_dcl, from_index, to_index, false, new ConcretePortSeq); cell->addPort(port); @@ -81,7 +81,7 @@ void LibertyBuilder::makeBusPortBits(ConcreteLibrary *library, LibertyCell *cell, ConcretePort *bus_port, - const char *bus_name, + std::string_view bus_name, int from_index, int to_index) { @@ -99,22 +99,25 @@ void LibertyBuilder::makeBusPortBit(ConcreteLibrary *library, LibertyCell *cell, ConcretePort *bus_port, - const char *bus_name, + std::string_view bus_name, int bit_index) { - std::string bit_name = std::string(bus_name) + library->busBrktLeft() - + std::to_string(bit_index) + library->busBrktRight(); - LibertyPort *port = makePort(cell, bit_name.c_str(), bit_index); + std::string bit_name; + bit_name.append(bus_name); + bit_name += library->busBrktLeft(); + bit_name += std::to_string(bit_index); + bit_name += library->busBrktRight(); + LibertyPort *port = makePort(cell, std::move(bit_name), bit_index); bus_port->addPortBit(port); cell->addPortBit(port); } LibertyPort * LibertyBuilder::makePort(LibertyCell *cell, - const char *bit_name, + std::string bit_name, int bit_index) { - LibertyPort *port = new LibertyPort(cell, bit_name, false, nullptr, + LibertyPort *port = new LibertyPort(cell, std::move(bit_name), false, nullptr, bit_index, bit_index, false, nullptr); return port; } diff --git a/liberty/LibertyBuilder.hh b/liberty/LibertyBuilder.hh index 70879092..11e8c2b1 100644 --- a/liberty/LibertyBuilder.hh +++ b/liberty/LibertyBuilder.hh @@ -24,6 +24,9 @@ #pragma once +#include +#include + #include "MinMax.hh" #include "Transition.hh" #include "LibertyClass.hh" @@ -41,12 +44,12 @@ public: LibertyBuilder(Debug *debug, Report *report); LibertyCell *makeCell(LibertyLibrary *library, - const char *name, - const char *filename); + std::string_view name, + std::string_view filename); LibertyPort *makePort(LibertyCell *cell, - const char *name); + std::string_view name); LibertyPort *makeBusPort(LibertyCell *cell, - const char *bus_name, + std::string_view bus_name, int from_index, int to_index, BusDcl *bus_dcl); @@ -87,24 +90,24 @@ public: TimingArcAttrsPtr attrs); protected: - ConcretePort *makeBusPort(const char *name, + ConcretePort *makeBusPort(std::string_view name, int from_index, int to_index, ConcretePortSeq *members); void makeBusPortBits(ConcreteLibrary *library, LibertyCell *cell, ConcretePort *bus_port, - const char *bus_name, + std::string_view bus_name, int from_index, int to_index); // Bus port bit (internal to makeBusPortBits). LibertyPort *makePort(LibertyCell *cell, - const char *bit_name, + std::string bit_name, int bit_index); void makeBusPortBit(ConcreteLibrary *library, LibertyCell *cell, ConcretePort *bus_port, - const char *bus_name, + std::string_view bus_name, int index); TimingArc *makeTimingArc(TimingArcSet *set, const Transition *from_rf, diff --git a/liberty/LibertyExt.cc b/liberty/LibertyExt.cc index 32c10b5e..68f1fe77 100644 --- a/liberty/LibertyExt.cc +++ b/liberty/LibertyExt.cc @@ -28,6 +28,7 @@ // * a string attribute named "thingy" is parsed #include +#include #include "Machine.hh" #include "StringUtil.hh" #include "LibertyReader.hh" @@ -162,15 +163,17 @@ BigcoTimingArcSet::BigcoTimingArcSet(LibertyCell *cell, LibertyPort *from, class BigcoLibertyBuilder : public LibertyBuilder { public: - virtual LibertyCell *makeCell(LibertyLibrary *library, const char *name, - const char *filename); + virtual LibertyCell *makeCell(LibertyLibrary *library, std::string_view name, + std::string_view filename); }; LibertyCell * -BigcoLibertyBuilder::makeCell(LibertyLibrary *library, const char *name, - const char *filename) +BigcoLibertyBuilder::makeCell(LibertyLibrary *library, std::string_view name, + std::string_view filename) { - LibertyCell *cell = new BigcoCell(library, name, filename); + std::string name_str(name); + std::string filename_str(filename); + LibertyCell *cell = new BigcoCell(library, name_str.c_str(), filename_str.c_str()); library->addCell(cell); return cell; } @@ -210,9 +213,8 @@ void BigcoLibertyReader::beginCell(const LibertyGroup *group, const LibertyGroup *library_group) { - const char *name = group->firstName(); - if (name - && libertyCellRequired(name)) + if (group->hasFirstParam() + && libertyCellRequired(group->firstParam().c_str())) LibertyReader::beginCell(group, library_group); } @@ -263,7 +265,7 @@ public: BigcoSta(); protected: - virtual LibertyLibrary *readLibertyFile(const char *filename, + virtual LibertyLibrary *readLibertyFile(std::string_view filename, bool infer_latches, Network *network); }; @@ -275,7 +277,7 @@ BigcoSta::BigcoSta() : // Replace Sta liberty file reader with Bigco's very own. LibertyLibrary * -Sta::readLibertyFile(const char *filename, +Sta::readLibertyFile(std::string_view filename, bool infer_latches, Network *network) { diff --git a/liberty/LibertyParse.yy b/liberty/LibertyParse.yy index b20b5c6c..f19a7c1f 100644 --- a/liberty/LibertyParse.yy +++ b/liberty/LibertyParse.yy @@ -44,7 +44,7 @@ void sta::LibertyParse::error(const location_type &loc, const std::string &msg) { - reader->report()->fileError(164, reader->filename().c_str(), + reader->report()->fileError(164, reader->filename(), loc.begin.line, "{}", msg); } @@ -192,7 +192,7 @@ volt_op: expr: expr_term1 | expr_term1 expr_op expr - { $$ = sta::format("{}{}{}", $1.c_str(), $2, $3.c_str()); } + { $$ = sta::format("{}{}{}", $1, $2, $3); } ; expr_term: diff --git a/liberty/LibertyParser.cc b/liberty/LibertyParser.cc index b3cefe9a..5ee1be81 100644 --- a/liberty/LibertyParser.cc +++ b/liberty/LibertyParser.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include "ContainerHelpers.hh" #include "Zlib.hh" @@ -38,11 +39,12 @@ namespace sta { void -parseLibertyFile(const char *filename, +parseLibertyFile(std::string_view filename, LibertyGroupVisitor *library_visitor, Report *report) { - gzstream::igzstream stream(filename); + std::string fn(filename); + gzstream::igzstream stream(fn.c_str()); if (stream.is_open()) { LibertyParser reader(filename, library_visitor, report); LibertyScanner scanner(&stream, filename, &reader, report); @@ -53,7 +55,7 @@ parseLibertyFile(const char *filename, throw FileNotReadable(filename); } -LibertyParser::LibertyParser(const char *filename, +LibertyParser::LibertyParser(std::string_view filename, LibertyGroupVisitor *library_visitor, Report *report) : filename_(filename), @@ -63,7 +65,7 @@ LibertyParser::LibertyParser(const char *filename, } void -LibertyParser::setFilename(const std::string &filename) +LibertyParser::setFilename(std::string_view filename) { filename_ = filename; } @@ -74,7 +76,7 @@ LibertyParser::makeDefine(const LibertyAttrValueSeq *values, { LibertyDefine *define = nullptr; if (values->size() == 3) { - const std::string &define_name = (*values)[0]->stringValue(); + std::string &define_name = (*values)[0]->stringValue(); const std::string &group_type_name = (*values)[1]->stringValue(); const std::string &value_type_name = (*values)[2]->stringValue(); LibertyAttrType value_type = attrValueType(value_type_name); @@ -87,7 +89,7 @@ LibertyParser::makeDefine(const LibertyAttrValueSeq *values, delete values; } else - report_->fileWarn(24, filename_.c_str(), line, + report_->fileWarn(24, filename_, line, "define does not have three arguments."); return define; } @@ -126,12 +128,15 @@ LibertyParser::groupType(const std::string &group_type_name) } void -LibertyParser::groupBegin(const std::string type, +LibertyParser::groupBegin(std::string &&type, LibertyAttrValueSeq *params, int line) { - LibertyGroup *group = new LibertyGroup( - std::move(type), params ? std::move(*params) : LibertyAttrValueSeq(), line); + LibertyGroup *group = new LibertyGroup(std::move(type), + params + ? std::move(*params) + : LibertyAttrValueSeq(), + line); delete params; LibertyGroup *parent_group = group_stack_.empty() ? nullptr : group_stack_.back(); group_visitor_->begin(group, parent_group); @@ -163,12 +168,13 @@ LibertyParser::deleteGroups() } LibertySimpleAttr * -LibertyParser::makeSimpleAttr(const std::string name, +LibertyParser::makeSimpleAttr(std::string &&name, const LibertyAttrValue *value, int line) { - LibertySimpleAttr *attr = - new LibertySimpleAttr(std::move(name), std::move(*value), line); + LibertySimpleAttr *attr = new LibertySimpleAttr(std::move(name), + std::move(*value), + line); delete value; LibertyGroup *group = this->group(); group->addAttr(attr); @@ -177,7 +183,7 @@ LibertyParser::makeSimpleAttr(const std::string name, } LibertyComplexAttr * -LibertyParser::makeComplexAttr(const std::string name, +LibertyParser::makeComplexAttr(std::string &&name, const LibertyAttrValueSeq *values, int line) { @@ -199,7 +205,7 @@ LibertyParser::makeComplexAttr(const std::string name, } LibertyVariable * -LibertyParser::makeVariable(const std::string var, +LibertyParser::makeVariable(std::string &&var, float value, int line) { @@ -211,7 +217,7 @@ LibertyParser::makeVariable(const std::string var, } LibertyAttrValue * -LibertyParser::makeAttrValueString(std::string value) +LibertyParser::makeAttrValueString(std::string &&value) { return new LibertyAttrValue(std::move(value)); } @@ -225,7 +231,7 @@ LibertyParser::makeAttrValueFloat(float value) //////////////////////////////////////////////////////////////// LibertyScanner::LibertyScanner(std::istream *stream, - const char *filename, + std::string_view filename, LibertyParser *reader, Report *report) : yyFlexLexer(stream), @@ -261,7 +267,7 @@ LibertyScanner::includeBegin() return true; } else { - report_->fileWarn(25, filename_.c_str(), yylineno, + report_->fileWarn(25, filename_, yylineno, "cannot open include file {}.", filename); delete stream; } @@ -287,7 +293,7 @@ LibertyScanner::fileEnd() void LibertyScanner::error(const char *msg) { - report_->fileError(1866, filename_.c_str(), lineno(), "{}", msg); + report_->fileError(1866, filename_, lineno(), "{}", msg); } //////////////////////////////////////////////////////////////// @@ -366,9 +372,9 @@ void LibertyGroup::addAttr(LibertySimpleAttr *attr) { // Only keep the most recent simple attribute value. - const auto &itr = simple_attr_map_.find(attr->name()); - if (itr != simple_attr_map_.end()) - delete itr->second; + const auto &it = simple_attr_map_.find(attr->name()); + if (it != simple_attr_map_.end()) + delete it->second; simple_attr_map_[attr->name()] = attr; } @@ -384,37 +390,46 @@ LibertyGroup::addVariable(LibertyVariable *var) variables_.push_back(var); } -const char * -LibertyGroup::firstName() const +bool +LibertyGroup::hasFirstParam() const { - if (params_.size() >= 1) { - LibertyAttrValue *value = params_[0]; - if (value->isString()) - return value->stringValue().c_str(); - } - return nullptr; + return !params_.empty(); } -const char * -LibertyGroup::secondName() const +const std::string & +LibertyGroup::firstParam() const +{ + LibertyAttrValue *value = params_[0]; + return value->stringValue(); +} + +bool +LibertyGroup::hasSecondParam() const +{ + return params_.size() >= 2; +} + +const std::string & +LibertyGroup::secondParam() const { LibertyAttrValue *value = params_[1]; - if (value->isString()) - return value->stringValue().c_str(); - else - return nullptr; + return value->stringValue(); } const LibertyGroupSeq & -LibertyGroup::findSubgroups(const std::string type) const +LibertyGroup::findSubgroups(std::string_view type) const { - return findKeyValue(subgroup_map_, type); + auto it = subgroup_map_.find(type); + if (it != subgroup_map_.end()) + return it->second; + static const LibertyGroupSeq empty; + return empty; } const LibertyGroup * -LibertyGroup::findSubgroup(const std::string type) const +LibertyGroup::findSubgroup(std::string_view type) const { - const LibertyGroupSeq &groups = findKeyValue(subgroup_map_, type); + const LibertyGroupSeq &groups = findSubgroups(type); if (groups.size() >= 1) return groups[0]; else @@ -422,39 +437,43 @@ LibertyGroup::findSubgroup(const std::string type) const } const LibertySimpleAttr * -LibertyGroup::findSimpleAttr(const std::string attr_name) const +LibertyGroup::findSimpleAttr(std::string_view attr_name) const { - return findKeyValue(simple_attr_map_, attr_name); + return findStringKey(simple_attr_map_, attr_name); } const LibertyComplexAttrSeq & -LibertyGroup::findComplexAttrs(const std::string attr_name) const +LibertyGroup::findComplexAttrs(std::string_view attr_name) const { - return findKeyValue(complex_attr_map_, attr_name); + auto it = complex_attr_map_.find(attr_name); + if (it != complex_attr_map_.end()) + return it->second; + static const LibertyComplexAttrSeq empty; + return empty; } const LibertyComplexAttr * -LibertyGroup::findComplexAttr(const std::string attr_name) const +LibertyGroup::findComplexAttr(std::string_view attr_name) const { - const LibertyComplexAttrSeq &attrs = findKeyValue(complex_attr_map_, attr_name); + const LibertyComplexAttrSeq &attrs = findComplexAttrs(attr_name); if (attrs.size() >= 1) return attrs[0]; else return nullptr; } -const std::string * -LibertyGroup::findAttrString(const std::string attr_name) const +const std::string & +LibertyGroup::findAttrString(std::string_view attr_name) const { const LibertySimpleAttr *attr = findSimpleAttr(attr_name); if (attr) - return &attr->value().stringValue(); - else - return nullptr; + return attr->value().stringValue(); + static const std::string null_string; + return null_string; } void -LibertyGroup::findAttrFloat(const std::string attr_name, +LibertyGroup::findAttrFloat(std::string_view attr_name, // Return values. float &value, bool &exists) const @@ -463,26 +482,25 @@ LibertyGroup::findAttrFloat(const std::string attr_name, if (attr) { const LibertyAttrValue &attr_value = attr->value(); if (attr_value.isFloat()) { - value = attr_value.floatValue(); - exists = true; + auto [value1, exists1] = attr_value.floatValue(); + value = value1; + exists = exists1; return; } else { // Possibly quoted string float. const std::string &float_str = attr_value.stringValue(); - char *end = nullptr; - value = std::strtof(float_str.c_str(), &end); - if (end) { - exists = true; - return; - } + auto [value1, valid1] = stringFloat(float_str); + value = value1; + exists = valid1; + return; } } exists = false; } void -LibertyGroup::findAttrInt(const std::string attr_name, +LibertyGroup::findAttrInt(std::string_view attr_name, // Return values. int &value, bool &exists) const @@ -491,8 +509,9 @@ LibertyGroup::findAttrInt(const std::string attr_name, if (attr) { const LibertyAttrValue &attr_value = attr->value(); if (attr_value.isFloat()) { - value = static_cast(attr_value.floatValue()); - exists = true; + auto [value1, exists1] = attr_value.floatValue(); + value = static_cast(value1); + exists = exists1; return; } } @@ -501,7 +520,7 @@ LibertyGroup::findAttrInt(const std::string attr_name, //////////////////////////////////////////////////////////////// -LibertySimpleAttr::LibertySimpleAttr(const std::string name, +LibertySimpleAttr::LibertySimpleAttr(std::string &&name, const LibertyAttrValue value, int line) : name_(std::move(name)), @@ -510,15 +529,9 @@ LibertySimpleAttr::LibertySimpleAttr(const std::string name, { } -const std::string * -LibertySimpleAttr::stringValue() const -{ - return &value().stringValue(); -} - //////////////////////////////////////////////////////////////// -LibertyComplexAttr::LibertyComplexAttr(std::string name, +LibertyComplexAttr::LibertyComplexAttr(std::string &&name, const LibertyAttrValueSeq values, int line) : name_(std::move(name)), @@ -540,7 +553,7 @@ LibertyComplexAttr::firstValue() const //////////////////////////////////////////////////////////////// -LibertyAttrValue::LibertyAttrValue(std::string value) : +LibertyAttrValue::LibertyAttrValue(std::string &&value) : string_value_(std::move(value)) { } @@ -562,39 +575,18 @@ LibertyAttrValue::isString() const return !string_value_.empty(); } -float +std::pair LibertyAttrValue::floatValue() const { - if (!string_value_.empty()) - criticalError(1127, "LibertyAttrValue::floatValue() called on string"); - return float_value_; -} - -void -LibertyAttrValue::floatValue( // Return values. - float &value, - bool &valid) const -{ - valid = false; - if (string_value_.empty()) { - value = float_value_; - valid = true; - } - else { - // Some floats are enclosed in quotes. - char *end; - value = strtof(string_value_.c_str(), &end); - if ((*end == '\0' || isspace(*end)) - // strtof support INF as a valid float. - && string_value_ != "inf") { - valid = true; - } - } + if (string_value_.empty()) + return {float_value_, true}; + else + return stringFloat(string_value_); } //////////////////////////////////////////////////////////////// -LibertyDefine::LibertyDefine(std::string name, +LibertyDefine::LibertyDefine(std::string &&name, LibertyGroupType group_type, LibertyAttrType value_type, int line) : diff --git a/liberty/LibertyParser.hh b/liberty/LibertyParser.hh index 00f2ac33..de9ec60c 100644 --- a/liberty/LibertyParser.hh +++ b/liberty/LibertyParser.hh @@ -24,8 +24,11 @@ #pragma once +#include +#include #include #include +#include #include "Zlib.hh" #include "StringUtil.hh" @@ -43,15 +46,15 @@ class LibertyVariable; class LibertyScanner; using LibertyGroupSeq = std::vector; -using LibertySubGroupMap = std::map; -using LibertySimpleAttrMap = std::map; +using LibertySubGroupMap = std::map>; +using LibertySimpleAttrMap = std::map>; using LibertyComplexAttrSeq = std::vector; -using LibertyComplexAttrMap = std::map; -using LibertyDefineMap = std::map; +using LibertyComplexAttrMap = std::map>; +using LibertyDefineMap = std::map>; using LibertyAttrValueSeq = std::vector; using LibertyVariableSeq = std::vector; -using LibertyVariableMap = std::map; -using LibertyGroupVisitorMap = std::map; +using LibertyVariableMap = std::map>; +using LibertyGroupVisitorMap = std::map>; enum class LibertyAttrType { attr_string, attr_int, attr_double, attr_boolean, attr_unknown }; @@ -61,31 +64,31 @@ enum class LibertyGroupType { library, cell, pin, timing, unknown }; class LibertyParser { public: - LibertyParser(const char *filename, + LibertyParser(std::string_view filename, LibertyGroupVisitor *library_visitor, Report *report); const std::string &filename() const { return filename_; } - void setFilename(const std::string &filename); + void setFilename(std::string_view filename); Report *report() const { return report_; } LibertyDefine *makeDefine(const LibertyAttrValueSeq *values, int line); LibertyAttrType attrValueType(const std::string &value_type_name); LibertyGroupType groupType(const std::string &group_type_name); - void groupBegin(const std::string type, + void groupBegin(std::string &&type, LibertyAttrValueSeq *params, int line); LibertyGroup *groupEnd(); LibertyGroup *group(); void deleteGroups(); - LibertySimpleAttr *makeSimpleAttr(const std::string name, + LibertySimpleAttr *makeSimpleAttr(std::string &&name, const LibertyAttrValue *value, int line); - LibertyComplexAttr *makeComplexAttr(const std::string name, + LibertyComplexAttr *makeComplexAttr(std::string &&name, const LibertyAttrValueSeq *values, int line); - LibertyAttrValue *makeAttrValueString(const std::string value); + LibertyAttrValue *makeAttrValueString(std::string &&value); LibertyAttrValue *makeAttrValueFloat(float value); - LibertyVariable *makeVariable(const std::string var, + LibertyVariable *makeVariable(std::string &&var, float value, int line); @@ -102,14 +105,12 @@ class LibertyAttrValue public: LibertyAttrValue() {} LibertyAttrValue(float value); - LibertyAttrValue(std::string value); + LibertyAttrValue(std::string &&value); bool isString() const; bool isFloat() const; - float floatValue() const; - void floatValue(// Return values. - float &value, - bool &valid) const; + std::pair floatValue() const; const std::string &stringValue() const { return string_value_; } + std::string &stringValue() { return string_value_; } private: float float_value_; @@ -131,23 +132,23 @@ public: bool oneGroupOnly() const; const std::string &type() const { return type_; } const LibertyAttrValueSeq ¶ms() const { return params_; } - // First param as a string. - const char *firstName() const; - // Second param as a string. - const char *secondName() const; + bool hasFirstParam() const; + const std::string &firstParam() const; + bool hasSecondParam() const; + const std::string &secondParam() const; int line() const { return line_; } - const LibertyGroupSeq &findSubgroups(const std::string type) const; - const LibertyGroup *findSubgroup(const std::string type) const; - const LibertySimpleAttr *findSimpleAttr(const std::string attr_name) const; - const LibertyComplexAttrSeq &findComplexAttrs(const std::string attr_name) const; - const LibertyComplexAttr *findComplexAttr(const std::string attr_name) const; - const std::string *findAttrString(const std::string attr_name) const; - void findAttrFloat(const std::string attr_name, + const LibertyGroupSeq &findSubgroups(std::string_view type) const; + const LibertyGroup *findSubgroup(std::string_view type) const; + const LibertySimpleAttr *findSimpleAttr(std::string_view attr_name) const; + const LibertyComplexAttrSeq &findComplexAttrs(std::string_view attr_name) const; + const LibertyComplexAttr *findComplexAttr(std::string_view attr_name) const; + const std::string &findAttrString(std::string_view attr_name) const; + void findAttrFloat(std::string_view attr_name, // Return values. float &value, bool &exists) const; - void findAttrInt(const std::string attr_name, + void findAttrInt(std::string_view attr_name, // Return values. int &value, bool &exists) const; @@ -189,12 +190,12 @@ public: class LibertySimpleAttr { public: - LibertySimpleAttr(const std::string name, + LibertySimpleAttr(std::string &&name, const LibertyAttrValue value, int line); const std::string &name() const { return name_; } const LibertyAttrValue &value() const { return value_; }; - const std::string *stringValue() const; + const std::string &stringValue() const { return value_.stringValue(); } int line() const { return line_; } private: @@ -208,7 +209,7 @@ private: class LibertyComplexAttr { public: - LibertyComplexAttr(const std::string name, + LibertyComplexAttr(std::string &&name, const LibertyAttrValueSeq values, int line); ~LibertyComplexAttr(); @@ -229,7 +230,7 @@ private: class LibertyDefine { public: - LibertyDefine(std::string name, + LibertyDefine(std::string &&name, LibertyGroupType group_type, LibertyAttrType value_type, int line); @@ -280,7 +281,7 @@ public: }; void -parseLibertyFile(const char *filename, +parseLibertyFile(std::string_view filename, LibertyGroupVisitor *library_visitor, Report *report); } // namespace diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index a873a881..b91c10e6 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -28,11 +28,13 @@ #include #include #include +#include #include "ContainerHelpers.hh" -#include "EnumNameMap.hh" +#include "Format.hh" #include "Report.hh" #include "Debug.hh" +#include "EnumNameMap.hh" #include "Units.hh" #include "Transition.hh" #include "FuncExpr.hh" @@ -60,7 +62,7 @@ scaleFloats(FloatSeq &floats, float scale); LibertyLibrary * -readLibertyFile(const char *filename, +readLibertyFile(std::string_view filename, bool infer_latches, Network *network) { @@ -68,7 +70,7 @@ readLibertyFile(const char *filename, return reader.readLibertyFile(filename); } -LibertyReader::LibertyReader(const char *filename, +LibertyReader::LibertyReader(std::string_view filename, bool infer_latches, Network *network) : LibertyGroupVisitor(), @@ -84,7 +86,7 @@ LibertyReader::LibertyReader(const char *filename, } LibertyLibrary * -LibertyReader::readLibertyFile(const char *filename) +LibertyReader::readLibertyFile(std::string_view filename) { //::LibertyParse_debug = 1; parseLibertyFile(filename, this, report_); @@ -92,14 +94,15 @@ LibertyReader::readLibertyFile(const char *filename) } void -LibertyReader::defineGroupVisitor(const char *type, +LibertyReader::defineGroupVisitor(std::string_view type, LibraryGroupVisitor begin_visitor, LibraryGroupVisitor end_visitor) { + std::string type_str(type); if (begin_visitor) - group_begin_map_[type] = begin_visitor; + group_begin_map_[type_str] = begin_visitor; if (end_visitor) - group_end_map_[type] = end_visitor; + group_end_map_[type_str] = end_visitor; } void @@ -170,10 +173,10 @@ LibertyReader::endCell(const LibertyGroup *cell_group, if (!library_group->oneGroupOnly()) readLibraryAttributes(library_group); - const char *name = cell_group->firstName(); - if (name) { + if (cell_group->hasFirstParam()) { + const std::string &name = cell_group->firstParam(); debugPrint(debug_, "liberty", 1, "cell {}", name); - LibertyCell *cell = builder_.makeCell(library_, name, filename_); + LibertyCell *cell = builder_.makeCell(library_, name, std::string(filename_)); readCell(cell, cell_group); } else @@ -261,16 +264,16 @@ LibertyReader::readLibraryAttributes(const LibertyGroup *library_group) } void -LibertyReader::makeLibrary(const LibertyGroup *libary_group) +LibertyReader::makeLibrary(const LibertyGroup *library_group) { - const char *name = libary_group->firstName(); - if (name) { - LibertyLibrary *library = network_->findLiberty(name); + if (library_group->hasFirstParam()) { + const std::string &lib_name = library_group->firstParam(); + LibertyLibrary *library = network_->findLiberty(lib_name); if (library) - warn(1140, libary_group, "library {} already exists.", name); + warn(1140, library_group, "library {} already exists.", lib_name); // Make a new library even if a library with the same name exists. // Both libraries may be accessed by min/max analysis points. - library_ = network_->makeLibertyLibrary(name, filename_); + library_ = network_->makeLibertyLibrary(lib_name, filename_); // 1ns default time_scale_ = 1E-9F; // 1ohm default @@ -296,7 +299,7 @@ LibertyReader::makeLibrary(const LibertyGroup *libary_group) library_->setDelayModelType(DelayModelType::cmos_linear); } else - error(1141, libary_group, "library missing name."); + error(1141, library_group, "library missing name."); } // Energy scale is derived from other units. @@ -341,29 +344,14 @@ LibertyReader::readLibraryUnits(const LibertyGroup *library_group) const LibertyAttrValueSeq &values = cap_attr->values(); if (values.size() == 2) { LibertyAttrValue *value = values[0]; - bool valid = false; - float scale; - if (value->isFloat()) { - scale = value->floatValue(); - valid = true; - } - else if (value->isString()) { - try { - scale = std::stof(value->stringValue()); - valid = true; - } - catch (...) { - valid = false; - } - } - + auto [scale, valid] = value->floatValue(); if (valid) { value = values[1]; if (value->isString()) { const std::string suffix = value->stringValue(); - if (stringEqual(suffix.c_str(), "ff")) + if (stringEqual(suffix, "ff")) cap_scale_ = scale * 1E-15F; - else if (stringEqual(suffix.c_str(), "pf")) + else if (stringEqual(suffix, "pf")) cap_scale_ = scale * 1E-12F; else warn(1154, cap_attr, "capacitive_load_units are not ff or pf."); @@ -383,25 +371,24 @@ LibertyReader::readLibraryUnits(const LibertyGroup *library_group) } void -LibertyReader::readUnit(const char *unit_attr_name, - const char *unit_suffix, +LibertyReader::readUnit(std::string_view unit_attr_name, + std::string_view unit_suffix, float &scale_var, Unit *unit, const LibertyGroup *library_group) { const LibertySimpleAttr *unit_attr = library_group->findSimpleAttr(unit_attr_name); if (unit_attr) { - const std::string *units = unit_attr->stringValue(); - if (units) { + const std::string &units = unit_attr->stringValue(); + if (!units.empty()) { // Unit format is . // Find the multiplier digits. - std::string units1 = *units; - size_t mult_end = units1.find_first_not_of("0123456789"); + size_t mult_end = units.find_first_not_of("0123456789"); float mult = 1.0F; std::string scale_suffix; - if (mult_end != units1.npos) { - std::string unit_mult = units1.substr(0, mult_end); - scale_suffix = units1.substr(mult_end); + if (mult_end != units.npos) { + std::string unit_mult = units.substr(0, mult_end); + scale_suffix = units.substr(mult_end); if (unit_mult == "1") mult = 1.0F; else if (unit_mult == "10") @@ -412,12 +399,12 @@ LibertyReader::readUnit(const char *unit_attr_name, warn(1150, unit_attr, "unknown unit multiplier {}.", unit_mult); } else - scale_suffix = *units; + scale_suffix = units; float scale_mult = 1.0F; - if (scale_suffix.size() == strlen(unit_suffix) + 1) { + if (scale_suffix.size() == unit_suffix.size() + 1) { std::string suffix = scale_suffix.substr(1); - if (stringEqual(suffix.c_str(), unit_suffix)) { + if (stringEqual(suffix, unit_suffix)) { char scale_char = tolower(scale_suffix[0]); if (scale_char == 'k') scale_mult = 1E+3F; @@ -437,7 +424,7 @@ LibertyReader::readUnit(const char *unit_attr_name, else warn(1152, unit_attr, "unknown unit suffix {}.", suffix); } - else if (!stringEqual(scale_suffix.c_str(), unit_suffix)) + else if (!stringEqual(scale_suffix, unit_suffix)) warn(1153, unit_attr, "unknown unit suffix {}.", scale_suffix); scale_var = scale_mult * mult; unit->setScale(scale_var); @@ -448,46 +435,46 @@ LibertyReader::readUnit(const char *unit_attr_name, void LibertyReader::readDelayModel(const LibertyGroup *library_group) { - const std::string *type_name = library_group->findAttrString("delay_model"); - if (type_name) { - if (*type_name == "table_lookup") + const std::string &type_name = library_group->findAttrString("delay_model"); + if (!type_name.empty()) { + if (type_name == "table_lookup") library_->setDelayModelType(DelayModelType::table); - else if (*type_name == "generic_cmos") + else if (type_name == "generic_cmos") library_->setDelayModelType(DelayModelType::cmos_linear); - else if (*type_name == "piecewise_cmos") { + else if (type_name == "piecewise_cmos") { library_->setDelayModelType(DelayModelType::cmos_pwl); - warn(1160, library_group, "delay_model {} not supported.", *type_name); + warn(1160, library_group, "delay_model {} not supported.", type_name); } - else if (*type_name == "cmos2") { + else if (type_name == "cmos2") { library_->setDelayModelType(DelayModelType::cmos2); - warn(1161, library_group, "delay_model {} not supported.", *type_name); + warn(1161, library_group, "delay_model {} not supported.", type_name); } - else if (*type_name == "polynomial") { + else if (type_name == "polynomial") { library_->setDelayModelType(DelayModelType::polynomial); - warn(1162, library_group, "delay_model {} not supported.", *type_name); + warn(1162, library_group, "delay_model {} not supported.", type_name); } // Evil IBM garbage. - else if (*type_name == "dcm") { + else if (type_name == "dcm") { library_->setDelayModelType(DelayModelType::dcm); - warn(1163, library_group, "delay_model {} not supported..", *type_name); + warn(1163, library_group, "delay_model {} not supported..", type_name); } else - warn(1164, library_group, "unknown delay_model {}.", *type_name); + warn(1164, library_group, "unknown delay_model {}.", type_name); } } void LibertyReader::readBusStyle(const LibertyGroup *library_group) { - const std::string *bus_style = library_group->findAttrString("bus_naming_style"); - if (bus_style) { + const std::string &bus_style = library_group->findAttrString("bus_naming_style"); + if (!bus_style.empty()) { // Assume bus style is of the form "%s[%d]". - if (bus_style->size() == 6 - && (*bus_style)[0] == '%' - && (*bus_style)[1] == 's' - && (*bus_style)[3] == '%' - && (*bus_style)[4] == 'd') - library_->setBusBrkts((*bus_style)[2], (*bus_style)[5]); + if (bus_style.size() == 6 + && bus_style[0] == '%' + && bus_style[1] == 's' + && bus_style[3] == '%' + && bus_style[4] == 'd') + library_->setBusBrkts(bus_style[2], bus_style[5]); else warn(1165, library_group, "unknown bus_naming_style format."); } @@ -498,8 +485,8 @@ LibertyReader::readBusTypes(LibertyCell *cell, const LibertyGroup *group) { for (const LibertyGroup *type_group : group->findSubgroups("type")) { - const char *name = type_group->firstName(); - if (name) { + if (type_group->hasFirstParam()) { + const std::string &name = type_group->firstParam(); int from, to; bool from_exists, to_exists; type_group->findAttrInt("bit_from", from, from_exists); @@ -522,14 +509,14 @@ void LibertyReader::readThresholds(const LibertyGroup *library_group) { for (const RiseFall *rf : RiseFall::range()) { - std::string suffix = rf->to_string(); - readLibAttrFloat(library_group, ("input_threshold_pct_" + suffix).c_str(), + std::string suffix(rf->to_string()); + readLibAttrFloat(library_group, "input_threshold_pct_" + suffix, &LibertyLibrary::setInputThreshold, rf, 0.01F); - readLibAttrFloat(library_group, ("output_threshold_pct_" + suffix).c_str(), + readLibAttrFloat(library_group, "output_threshold_pct_" + suffix, &LibertyLibrary::setOutputThreshold, rf, 0.01F); - readLibAttrFloat(library_group, ("slew_lower_threshold_pct_" + suffix).c_str(), + readLibAttrFloat(library_group, "slew_lower_threshold_pct_" + suffix, &LibertyLibrary::setSlewLowerThreshold, rf, 0.01F); - readLibAttrFloat(library_group, ("slew_upper_threshold_pct_" + suffix).c_str(), + readLibAttrFloat(library_group, "slew_upper_threshold_pct_" + suffix, &LibertyLibrary::setSlewUpperThreshold, rf, 0.01F); } } @@ -561,12 +548,13 @@ LibertyReader::readTableTemplates(const LibertyGroup *library_group) void LibertyReader::readTableTemplates(const LibertyGroup *library_group, - const char *group_name, + std::string_view group_name, TableTemplateType type) { - for (const LibertyGroup *template_group : library_group->findSubgroups(group_name)) { - const char *name = template_group->firstName(); - if (name) { + for (const LibertyGroup *template_group : + library_group->findSubgroups(group_name)) { + if (template_group->hasFirstParam()) { + const std::string &name = template_group->firstParam(); TableTemplate *tbl_template = library_->makeTableTemplate(name, type); TableAxisPtr axis1 = makeTableTemplateAxis(template_group, 1); if (axis1) @@ -587,14 +575,14 @@ TableAxisPtr LibertyReader::makeTableTemplateAxis(const LibertyGroup *template_group, int axis_index) { - std::string var_attr_name = "variable_" + std::to_string(axis_index); - const std::string *var_name = template_group->findAttrString(var_attr_name); - if (var_name) { - TableAxisVariable axis_var = stringTableAxisVariable(var_name->c_str()); + std::string var_attr_name = sta::format("variable_{}", axis_index); + const std::string &var_name = template_group->findAttrString(var_attr_name); + if (!var_name.empty()) { + TableAxisVariable axis_var = stringTableAxisVariable(var_name); if (axis_var == TableAxisVariable::unknown) - warn(1297, template_group, "axis type {} not supported.", *var_name); + warn(1297, template_group, "axis type {} not supported.", var_name); else { - std::string index_attr_name = "index_" + std::to_string(axis_index); + std::string index_attr_name = sta::format("index_{}", axis_index); const LibertyComplexAttr *index_attr = template_group->findComplexAttr(index_attr_name); FloatSeq axis_values; @@ -638,11 +626,9 @@ LibertyReader::readVoltateMaps(const LibertyGroup *library_group) const LibertyAttrValueSeq &values = volt_attr->values(); if (values.size() == 2) { const std::string &volt_name = values[0]->stringValue(); - float volt; - bool valid; - values[1]->floatValue(volt, valid); + auto [volt, valid] = values[1]->floatValue(); if (valid) - library_->addSupplyVoltage(volt_name.c_str(), volt); + library_->addSupplyVoltage(volt_name, volt); else warn(1166, volt_attr, "voltage_map voltage is not a float."); } @@ -654,8 +640,8 @@ LibertyReader::readOperatingConds(const LibertyGroup *library_group) { for (const LibertyGroup *opcond_group : library_group->findSubgroups("operating_conditions")) { - const char *name = opcond_group->firstName(); - if (name) { + if (opcond_group->hasFirstParam()) { + const std::string &name = opcond_group->firstParam(); OperatingConditions *op_cond = library_->makeOperatingConditions(name); float value; bool exists; @@ -668,24 +654,24 @@ LibertyReader::readOperatingConds(const LibertyGroup *library_group) opcond_group->findAttrFloat("voltage", value, exists); if (exists) op_cond->setVoltage(value); - const std::string *tree_type = opcond_group->findAttrString("tree_type"); - if (tree_type) { - WireloadTree wireload_tree = stringWireloadTree(tree_type->c_str()); + const std::string &tree_type = opcond_group->findAttrString("tree_type"); + if (!tree_type.empty()) { + WireloadTree wireload_tree = stringWireloadTree(tree_type); op_cond->setWireloadTree(wireload_tree); } } } - const std::string *default_op_cond = + const std::string &default_op_cond = library_group->findAttrString("default_operating_conditions"); - if (default_op_cond) { + if (!default_op_cond.empty()) { OperatingConditions *op_cond = - library_->findOperatingConditions(default_op_cond->c_str()); + library_->findOperatingConditions(default_op_cond); if (op_cond) library_->setDefaultOperatingConditions(op_cond); else warn(1144, library_group, "default_operating_condition {} not found.", - *default_op_cond); + default_op_cond); } } @@ -699,8 +685,8 @@ LibertyReader::readScaleFactors(const LibertyGroup *library_group) // Named scale factors. for (const LibertyGroup *scale_group : library_group->findSubgroups("scaling_factors")){ - const char *name = scale_group->firstName(); - if (name) { + if (scale_group->hasFirstParam()) { + const std::string &name = scale_group->firstParam(); ScaleFactors *scale_factors = library_->makeScaleFactors(name); readScaleFactors(scale_group, scale_factors); } @@ -714,7 +700,7 @@ LibertyReader::readScaleFactors(const LibertyGroup *scale_group, // Skip unknown type. for (int type_index = 0; type_index < scale_factor_type_count - 1; type_index++) { ScaleFactorType type = static_cast(type_index); - const char *type_name = scaleFactorTypeName(type); + const std::string &type_name = scaleFactorTypeName(type); // Skip unknown pvt. for (int pvt_index = 0; pvt_index < scale_factor_pvt_count - 1; pvt_index++) { ScaleFactorPvt pvt = static_cast(pvt_index); @@ -723,18 +709,18 @@ LibertyReader::readScaleFactors(const LibertyGroup *scale_group, for (const RiseFall *rf : RiseFall::range()) { if (scaleFactorTypeRiseFallSuffix(type)) { const std::string rf_name = (rf == RiseFall::rise()) ? "rise" : "fall"; - attr_name = "k_" + pvt_name + "_" + type_name + "_" + rf_name; + attr_name = sta::format("k_{}_{}_{}", pvt_name, type_name, rf_name); } else if (scaleFactorTypeRiseFallPrefix(type)) { - const char *rf_name = (rf == RiseFall::rise()) ? "rise" : "fall"; - attr_name = "k_" + pvt_name + "_" + rf_name + "_" + type_name; + const std::string rf_name = (rf == RiseFall::rise()) ? "rise" : "fall"; + attr_name = sta::format("k_{}_{}_{}", pvt_name, rf_name, type_name); } else if (scaleFactorTypeLowHighSuffix(type)) { - const char *rf_name = (rf == RiseFall::rise()) ? "high":"low"; - attr_name = "k_" + pvt_name + "_" + type_name + "_" + rf_name; + const std::string rf_name = (rf == RiseFall::rise()) ? "high" : "low"; + attr_name = sta::format("k_{}_{}_{}", pvt_name, type_name, rf_name); } else - attr_name = "k_" + pvt_name + "_" + type_name; + attr_name = sta::format("k_{}_{}", pvt_name, type_name); float value; bool exists; scale_group->findAttrFloat(attr_name, value, exists); @@ -749,8 +735,8 @@ void LibertyReader::readWireloads(const LibertyGroup *library_group) { for (const LibertyGroup *wl_group : library_group->findSubgroups("wire_load")) { - const char *name = wl_group->firstName(); - if (name) { + if (wl_group->hasFirstParam()) { + const std::string &name = wl_group->firstParam(); Wireload *wireload = library_->makeWireload(name); float value; bool exists; @@ -787,25 +773,23 @@ LibertyReader::readWireloadSelection(const LibertyGroup *library_group) { const LibertyGroup *sel_group = library_group->findSubgroup("wire_load_selection"); if (sel_group) { - const char *name = sel_group->firstName(); - if (name == nullptr) - name = ""; + std::string name; + if (sel_group->hasFirstParam()) + name = sel_group->firstParam(); WireloadSelection *wireload_selection = library_->makeWireloadSelection(name); for (const LibertyComplexAttr *area_attr : sel_group->findComplexAttrs("wire_load_from_area")) { const LibertyAttrValueSeq &values = area_attr->values(); if (values.size() == 3) { - LibertyAttrValue *value = values[0]; - if (value->isFloat()) { - float min_area = value->floatValue(); - value = values[1]; - if (value->isFloat()) { - float max_area = value->floatValue(); - value = values[2]; + auto [min_area, min_valid] = values[0]->floatValue(); + if (min_valid) { + auto [max_area, max_valid] = values[1]->floatValue(); + if (max_valid) { + LibertyAttrValue *value = values[2]; if (value->isString()) { const std::string &wireload_name = value->stringValue(); const Wireload *wireload = - library_->findWireload(wireload_name.c_str()); + library_->findWireload(wireload_name); if (wireload) wireload_selection->addWireloadFromArea(min_area, max_area, wireload); @@ -831,45 +815,46 @@ LibertyReader::readWireloadSelection(const LibertyGroup *library_group) void LibertyReader::readDefaultWireLoad(const LibertyGroup *library_group) { - const std::string *wireload_name = library_group->findAttrString("default_wire_load"); - if (wireload_name) { - const Wireload *wireload = library_->findWireload(wireload_name->c_str()); + const std::string &wireload_name = + library_group->findAttrString("default_wire_load"); + if (!wireload_name.empty()) { + const Wireload *wireload = library_->findWireload(wireload_name); if (wireload) library_->setDefaultWireload(wireload); else warn(1142, library_group, "default_wire_load {} not found.", - *wireload_name); + wireload_name); } } void LibertyReader::readDefaultWireLoadMode(const LibertyGroup *library_group) { - const std::string *wire_load_mode = + const std::string &wire_load_mode = library_group->findAttrString("default_wire_load_mode"); - if (wire_load_mode) { - WireloadMode mode = stringWireloadMode(wire_load_mode->c_str()); + if (!wire_load_mode.empty()) { + WireloadMode mode = stringWireloadMode(wire_load_mode); if (mode != WireloadMode::unknown) library_->setDefaultWireloadMode(mode); else warn(1174, library_group, "default_wire_load_mode {} not found.", - *wire_load_mode); + wire_load_mode); } } void LibertyReader::readDefaultWireLoadSelection(const LibertyGroup *library_group) { - const std::string *selection_name = + const std::string &selection_name = library_group->findAttrString("default_wire_load_selection"); - if (selection_name) { + if (!selection_name.empty()) { const WireloadSelection *selection = - library_->findWireloadSelection(selection_name->c_str()); + library_->findWireloadSelection(selection_name.c_str()); if (selection) library_->setDefaultWireloadSelection(selection); else warn(1143, library_group, "default_wire_selection {} not found.", - *selection_name); + selection_name); } } @@ -878,20 +863,20 @@ LibertyReader::readModeDefs(LibertyCell *cell, const LibertyGroup *cell_group) { for (const LibertyGroup *mode_group : cell_group->findSubgroups("mode_definition")) { - const char *name = mode_group->firstName(); - if (name) { + if (mode_group->hasFirstParam()) { + const std::string &name = mode_group->firstParam(); ModeDef *mode_def = cell->makeModeDef(name); for (const LibertyGroup *value_group : mode_group->findSubgroups("mode_value")) { - const char *value_name = value_group->firstName(); - if (value_name) { - ModeValueDef *mode_value = mode_def->defineValue(value_name, nullptr, nullptr); - const std::string *sdf_cond = value_group->findAttrString("sdf_cond"); - if (sdf_cond) - mode_value->setSdfCond(sdf_cond->c_str()); - const std::string *when = value_group->findAttrString("when"); - if (when) { + if (value_group->hasFirstParam()) { + const std::string &value_name = value_group->firstParam(); + ModeValueDef *mode_value = mode_def->defineValue(value_name); + const std::string &sdf_cond = value_group->findAttrString("sdf_cond"); + if (!sdf_cond.empty()) + mode_value->setSdfCond(sdf_cond); + const std::string &when = value_group->findAttrString("when"); + if (!when.empty()) { // line - FuncExpr *when_expr = parseFunc(when->c_str(), "when", cell, + FuncExpr *when_expr = parseFunc(when, "when", cell, value_group->line()); mode_value->setCond(when_expr); } @@ -909,9 +894,10 @@ void LibertyReader::readSlewDegradations(const LibertyGroup *library_group) { for (const RiseFall *rf : RiseFall::range()) { - const std::string group_name = rf->to_string() + "_transition_degradation"; + const std::string group_name = sta::format("{}_transition_degradation", + rf->to_string()); const LibertyGroup *degradation_group = - library_group->findSubgroup(group_name.c_str()); + library_group->findSubgroup(group_name); if (degradation_group) { TableModel *table_model = readTableModel(degradation_group, rf, TableTemplateType::delay, @@ -927,7 +913,7 @@ LibertyReader::readSlewDegradations(const LibertyGroup *library_group) void LibertyReader::readLibAttrFloat(const LibertyGroup *library_group, - const char *attr_name, + std::string_view attr_name, void (LibertyLibrary::*set_func)(float value), float scale) { @@ -940,7 +926,7 @@ LibertyReader::readLibAttrFloat(const LibertyGroup *library_group, void LibertyReader::readLibAttrFloat(const LibertyGroup *library_group, - const char *attr_name, + std::string_view attr_name, void (LibertyLibrary::*set_func)(const RiseFall *rf, float value), const RiseFall *rf, @@ -955,7 +941,7 @@ LibertyReader::readLibAttrFloat(const LibertyGroup *library_group, void LibertyReader::readLibAttrFloatWarnZero(const LibertyGroup *library_group, - const char *attr_name, + std::string_view attr_name, void (LibertyLibrary::*set_func)(float value), float scale) { @@ -1008,17 +994,18 @@ LibertyReader::readCell(LibertyCell *cell, void LibertyReader::readScaledCell(const LibertyGroup *scaled_cell_group) { - const char *name = scaled_cell_group->firstName(); - if (name) { + if (scaled_cell_group->hasFirstParam()) { + const std::string &name = scaled_cell_group->firstParam(); LibertyCell *owner = library_->findLibertyCell(name); if (owner) { - const char *op_cond_name = scaled_cell_group->secondName(); - if (op_cond_name) { + if (scaled_cell_group->hasSecondParam()) { + const std::string &op_cond_name = scaled_cell_group->secondParam(); OperatingConditions *op_cond = library_->findOperatingConditions(op_cond_name); if (op_cond) { debugPrint(debug_, "liberty", 1, "scaled cell {} {}", - name, op_cond_name); - LibertyCell *scaled_cell = library_->makeScaledCell(name, filename_); + name.c_str(), op_cond_name.c_str()); + LibertyCell *scaled_cell = library_->makeScaledCell(name, + std::string(filename_)); readCell(scaled_cell, scaled_cell_group); checkScaledCell(scaled_cell, owner, scaled_cell_group, op_cond_name); // Add scaled cell AFTER ports and timing arcs are defined. @@ -1043,7 +1030,7 @@ void LibertyReader::checkScaledCell(LibertyCell *scaled_cell, LibertyCell *owner, const LibertyGroup *scaled_cell_group, - const char *op_cond_name) + std::string_view op_cond_name) { if (equivCellPorts(scaled_cell, owner)) { if (!equivCellPorts(scaled_cell, owner)) @@ -1091,7 +1078,7 @@ LibertyReader::makePinPort(LibertyCell *cell, { for (const LibertyAttrValue *port_value : pin_group->params()) { const std::string &port_name = port_value->stringValue(); - LibertyPort *port = makePort(cell, port_name.c_str()); + LibertyPort *port = makePort(cell, port_name); port_group_map[pin_group].push_back(port); } } @@ -1105,15 +1092,15 @@ LibertyReader::makeBusPort(LibertyCell *cell, const std::string &port_name = port_value->stringValue(); const LibertySimpleAttr *bus_type_attr = bus_group->findSimpleAttr("bus_type"); if (bus_type_attr) { - const std::string *bus_type = bus_type_attr->stringValue(); - if (bus_type) { + const std::string &bus_type = bus_type_attr->stringValue(); + if (!bus_type.empty()) { // Look for bus dcl local to cell first. - BusDcl *bus_dcl = cell->findBusDcl(bus_type->c_str()); + BusDcl *bus_dcl = cell->findBusDcl(bus_type); if (bus_dcl == nullptr) - bus_dcl = library_->findBusDcl(bus_type->c_str()); + bus_dcl = library_->findBusDcl(bus_type); if (bus_dcl) { debugPrint(debug_, "liberty", 1, " bus {}", port_name); - LibertyPort *bus_port = makeBusPort(cell, port_name.c_str(), + LibertyPort *bus_port = makeBusPort(cell, port_name, bus_dcl->from(), bus_dcl->to(), bus_dcl); port_group_map[bus_group].push_back(bus_port); @@ -1121,7 +1108,7 @@ LibertyReader::makeBusPort(LibertyCell *cell, makeBusPinPorts(cell, bus_group, port_group_map); } else - warn(1235, bus_type_attr, "bus_type {} not found.", *bus_type); + warn(1235, bus_type_attr, "bus_type {} not found.", bus_type); } } else @@ -1140,7 +1127,7 @@ LibertyReader::makeBusPinPorts(LibertyCell *cell, const std::string pin_name = param->stringValue(); debugPrint(debug_, "liberty", 1, " bus pin port {}", pin_name); // Expand foo[3:0] port names. - PortNameBitIterator name_iter(cell, pin_name.c_str(), this, pin_group->line()); + PortNameBitIterator name_iter(cell, pin_name, this, pin_group->line()); while (name_iter.hasNext()) { LibertyPort *pin_port = name_iter.next(); if (pin_port) { @@ -1161,25 +1148,29 @@ LibertyReader::makeBundlePort(LibertyCell *cell, const LibertyGroup *bundle_group, LibertyPortGroupMap &port_group_map) { - const std::string &bundle_name = bundle_group->firstName(); - debugPrint(debug_, "liberty", 1, " bundle {}", bundle_name); + if (bundle_group->hasFirstParam()) { + const std::string &bundle_name = bundle_group->firstParam(); + debugPrint(debug_, "liberty", 1, " bundle {}", bundle_name); - const LibertyComplexAttr *member_attr = bundle_group->findComplexAttr("members"); - ConcretePortSeq *members = new ConcretePortSeq; - for (const LibertyAttrValue *member_value : member_attr->values()) { - if (member_value->isString()) { - const char *member_name = member_value->stringValue().c_str(); - LibertyPort *member = cell->findLibertyPort(member_name); - if (member == nullptr) - member = makePort(cell, member_name); - members->push_back(member); + const LibertyComplexAttr *member_attr = bundle_group->findComplexAttr("members"); + ConcretePortSeq *members = new ConcretePortSeq; + for (const LibertyAttrValue *member_value : member_attr->values()) { + if (member_value->isString()) { + const std::string &member_name = member_value->stringValue(); + LibertyPort *member = cell->findLibertyPort(member_name); + if (member == nullptr) + member = makePort(cell, member_name); + members->push_back(member); + } } + LibertyPort *bundle_port = builder_.makeBundlePort(cell, bundle_name.c_str(), + members); + port_group_map[bundle_group].push_back(bundle_port); + // Make ports for pin groups inside the bundle group. + makeBundlePinPorts(cell, bundle_group, port_group_map); } - LibertyPort *bundle_port = builder_.makeBundlePort(cell, bundle_name.c_str(), - members); - port_group_map[bundle_group].push_back(bundle_port); - // Make ports for pin groups inside the bundle group. - makeBundlePinPorts(cell, bundle_group, port_group_map); + else + warn(1313, bundle_group, "bundle missing name."); } void @@ -1192,9 +1183,9 @@ LibertyReader::makeBundlePinPorts(LibertyCell *cell, if (param->isString()) { const std::string pin_name = param->stringValue(); debugPrint(debug_, "liberty", 1, " bundle pin port {}", pin_name); - LibertyPort *pin_port = cell->findLibertyPort(pin_name.c_str()); + LibertyPort *pin_port = cell->findLibertyPort(pin_name); if (pin_port == nullptr) - pin_port = makePort(cell, pin_name.c_str()); + pin_port = makePort(cell, pin_name); port_group_map[pin_group].push_back(pin_port); } else @@ -1207,37 +1198,41 @@ void LibertyReader::makePgPinPort(LibertyCell *cell, const LibertyGroup *pg_pin_group) { - const std::string &port_name = pg_pin_group->firstName(); - LibertyPort *pg_port = makePort(cell, port_name.c_str()); + if (pg_pin_group->hasFirstParam()) { + const std::string &port_name = pg_pin_group->firstParam(); + LibertyPort *pg_port = makePort(cell, port_name); - const std::string *type_name = pg_pin_group->findAttrString("pg_type"); - if (type_name) { - PwrGndType type = findPwrGndType(type_name->c_str()); - PortDirection *dir = PortDirection::unknown(); - switch (type) { - case PwrGndType::primary_ground: - case PwrGndType::backup_ground: - case PwrGndType::internal_ground: - dir = PortDirection::ground(); - break; - case PwrGndType::primary_power: - case PwrGndType::backup_power: - case PwrGndType::internal_power: - dir = PortDirection::power(); - break; - case PwrGndType::none: - error(1291, pg_pin_group, "unknown pg_type."); - break; - default: - break; + const std::string &type_name = pg_pin_group->findAttrString("pg_type"); + if (!type_name.empty()) { + PwrGndType type = findPwrGndType(type_name.c_str()); + PortDirection *dir = PortDirection::unknown(); + switch (type) { + case PwrGndType::primary_ground: + case PwrGndType::backup_ground: + case PwrGndType::internal_ground: + dir = PortDirection::ground(); + break; + case PwrGndType::primary_power: + case PwrGndType::backup_power: + case PwrGndType::internal_power: + dir = PortDirection::power(); + break; + case PwrGndType::none: + error(1291, pg_pin_group, "unknown pg_type."); + break; + default: + break; + } + pg_port->setPwrGndType(type); + pg_port->setDirection(dir); } - pg_port->setPwrGndType(type); - pg_port->setDirection(dir); - } - const std::string *voltate_name = pg_pin_group->findAttrString("voltage_name"); - if (voltate_name) - pg_port->setVoltageName(voltate_name->c_str()); + const std::string &voltate_name = pg_pin_group->findAttrString("voltage_name"); + if (!voltate_name.empty()) + pg_port->setVoltageName(voltate_name.c_str()); + } + else + warn(1314, pg_pin_group, "pg_pin missing name."); } //////////////////////////////////////////////////////////////// @@ -1275,10 +1270,12 @@ LibertyReader::readPortAttributes(LibertyCell *cell, readPortAttrBool("level_shifter_data_pin", &LibertyPort::setLevelShifterData, ports, port_group); readPortAttrBool("switch_pin", &LibertyPort::setIsSwitch, ports, port_group); - readPortAttrString("related_ground_pin", &LibertyPort::setRelatedGroundPin, - ports, port_group); - readPortAttrString("related_power_pin", &LibertyPort::setRelatedPowerPin, - ports, port_group); + readPortAttrLibertyPort("related_ground_pin", + &LibertyPort::setRelatedGroundPort, + cell, ports, port_group); + readPortAttrLibertyPort("related_power_pin", + &LibertyPort::setRelatedPowerPort, + cell, ports, port_group); readDriverWaveform(ports, port_group); } @@ -1287,11 +1284,12 @@ LibertyReader::readDriverWaveform(const LibertyPortSeq &ports, const LibertyGroup *port_group) { for (const RiseFall *rf : RiseFall::range()) { - const char *attr_name = rf == RiseFall::rise() - ? "driver_waveform_rise" : "driver_waveform_fall"; - const std::string *name = port_group->findAttrString(attr_name); - if (name) { - DriverWaveform *waveform = library_->findDriverWaveform(name->c_str()); + const std::string_view attr_name = (rf == RiseFall::rise()) + ? "driver_waveform_rise" + : "driver_waveform_fall"; + const std::string &name = port_group->findAttrString(attr_name); + if (!name.empty()) { + DriverWaveform *waveform = library_->findDriverWaveform(name.c_str()); if (waveform) { for (LibertyPort *port : ports) port->setDriverWaveform(waveform, rf); @@ -1301,20 +1299,35 @@ LibertyReader::readDriverWaveform(const LibertyPortSeq &ports, } void -LibertyReader::readPortAttrString(const char *attr_name, - void (LibertyPort::*set_func)(const char *value), +LibertyReader::readPortAttrString(std::string_view attr_name, + void (LibertyPort::*set_func)(std::string value), const LibertyPortSeq &ports, const LibertyGroup *group) { - const std::string *value = group->findAttrString(attr_name); - if (value) { + const std::string &value = group->findAttrString(attr_name); + if (!value.empty()) { for (LibertyPort *port : ports) - (port->*set_func)(value->c_str()); + (port->*set_func)(value); } } void -LibertyReader::readPortAttrFloat(const char *attr_name, +LibertyReader::readPortAttrLibertyPort(std::string_view attr_name, + void (LibertyPort::*set_func)(LibertyPort *port), + LibertyCell *cell, + const LibertyPortSeq &ports, + const LibertyGroup *group) +{ + const std::string &value = group->findAttrString(attr_name); + if (!value.empty()) { + LibertyPort *related = cell->findLibertyPort(value); + for (LibertyPort *port : ports) + (port->*set_func)(related); + } +} + +void +LibertyReader::readPortAttrFloat(std::string_view attr_name, void (LibertyPort::*set_func)(float value), const LibertyPortSeq &ports, const LibertyGroup *group, @@ -1330,7 +1343,7 @@ LibertyReader::readPortAttrFloat(const char *attr_name, } void -LibertyReader::readPortAttrBool(const char *attr_name, +LibertyReader::readPortAttrBool(std::string_view attr_name, void (LibertyPort::*set_func)(bool value), const LibertyPortSeq &ports, const LibertyGroup *group) @@ -1340,11 +1353,11 @@ LibertyReader::readPortAttrBool(const char *attr_name, const LibertyAttrValue &attr_value = attr->value(); if (attr_value.isString()) { const std::string &value = attr_value.stringValue(); - if (stringEqual(value.c_str(), "true")) { + if (stringEqual(value, "true")) { for (LibertyPort *port : ports) (port->*set_func)(true); } - else if (stringEqual(value.c_str(), "false")) { + else if (stringEqual(value, "false")) { for (LibertyPort *port : ports) (port->*set_func)(false); } @@ -1357,7 +1370,7 @@ LibertyReader::readPortAttrBool(const char *attr_name, } void -LibertyReader::readPortAttrFloatMinMax(const char *attr_name, +LibertyReader::readPortAttrFloatMinMax(std::string_view attr_name, void (LibertyPort::*set_func)(float value, const MinMax *min_max), const LibertyPortSeq &ports, @@ -1378,23 +1391,23 @@ void LibertyReader::readPulseClock(const LibertyPortSeq &ports, const LibertyGroup *port_group) { - const std::string *pulse_clk = port_group->findAttrString("pulse_clock"); - if (pulse_clk) { + const std::string &pulse_clk = port_group->findAttrString("pulse_clock"); + if (!pulse_clk.empty()) { const RiseFall *trigger = nullptr; const RiseFall *sense = nullptr; - if (*pulse_clk == "rise_triggered_high_pulse") { + if (pulse_clk == "rise_triggered_high_pulse") { trigger = RiseFall::rise(); sense = RiseFall::rise(); } - else if (*pulse_clk == "rise_triggered_low_pulse") { + else if (pulse_clk == "rise_triggered_low_pulse") { trigger = RiseFall::rise(); sense = RiseFall::fall(); } - else if (*pulse_clk == "fall_triggered_high_pulse") { + else if (pulse_clk == "fall_triggered_high_pulse") { trigger = RiseFall::fall(); sense = RiseFall::rise(); } - else if (*pulse_clk == "fall_triggered_low_pulse") { + else if (pulse_clk == "fall_triggered_low_pulse") { trigger = RiseFall::fall(); sense = RiseFall::fall(); } @@ -1414,30 +1427,30 @@ LibertyReader::readSignalType(LibertyCell *cell, { if (!dynamic_cast(cell)) return; - const std::string *type = port_group->findAttrString("signal_type"); - if (!type) + const std::string &type = port_group->findAttrString("signal_type"); + if (type.empty()) return; ScanSignalType signal_type = ScanSignalType::none; - if (*type == "test_scan_enable") + if (type == "test_scan_enable") signal_type = ScanSignalType::enable; - else if (*type == "test_scan_enable_inverted") + else if (type == "test_scan_enable_inverted") signal_type = ScanSignalType::enable_inverted; - else if (*type == "test_scan_clock") + else if (type == "test_scan_clock") signal_type = ScanSignalType::clock; - else if (*type == "test_scan_clock_a") + else if (type == "test_scan_clock_a") signal_type = ScanSignalType::clock_a; - else if (*type == "test_scan_clock_b") + else if (type == "test_scan_clock_b") signal_type = ScanSignalType::clock_b; - else if (*type == "test_scan_in") + else if (type == "test_scan_in") signal_type = ScanSignalType::input; - else if (*type == "test_scan_in_inverted") + else if (type == "test_scan_in_inverted") signal_type = ScanSignalType::input_inverted; - else if (*type == "test_scan_out") + else if (type == "test_scan_out") signal_type = ScanSignalType::output; - else if (*type == "test_scan_out_inverted") + else if (type == "test_scan_out_inverted") signal_type = ScanSignalType::output_inverted; else { - warn(1299, port_group, "unknown signal_type {}.", *type); + warn(1299, port_group, "unknown signal_type {}.", type); return; } for (LibertyPort *port : ports) @@ -1452,16 +1465,16 @@ LibertyReader::readPortDir(const LibertyPortSeq &ports, // Note missing direction attribute is not an error because a bus group // can have pin groups for the bus bits that have direcitons. if (dir_attr) { - const std::string *dir = dir_attr->stringValue(); - if (dir) { + const std::string &dir = dir_attr->stringValue(); + if (!dir.empty()) { PortDirection *port_dir = PortDirection::unknown(); - if (*dir == "input") + if (dir == "input") port_dir = PortDirection::input(); - else if (*dir == "output") + else if (dir == "output") port_dir = PortDirection::output(); - else if (*dir == "inout") + else if (dir == "inout") port_dir = PortDirection::bidirect(); - else if (*dir == "internal") + else if (dir == "internal") port_dir = PortDirection::internal(); else warn(1240, dir_attr, "unknown port direction."); @@ -1482,7 +1495,7 @@ LibertyReader::readCapacitance(const LibertyPortSeq &ports, for (LibertyPort *port : ports) { // rise/fall_capacitance for (const RiseFall *rf : RiseFall::range()) { - std::string attr_name = rf->to_string() + "_capacitance"; + std::string attr_name = sta::format("{}_capacitance", rf->to_string()); float cap; bool exists; port_group->findAttrFloat(attr_name, cap, exists); @@ -1492,16 +1505,18 @@ LibertyReader::readCapacitance(const LibertyPortSeq &ports, } // rise/fall_capacitance_range(min_cap, max_cap); - attr_name = rf->to_string() + "_capacitance_range"; + attr_name = sta::format("{}_capacitance_range", rf->to_string()); const LibertyComplexAttrSeq &range_attrs = port_group->findComplexAttrs(attr_name); if (!range_attrs.empty()) { const LibertyComplexAttr *attr = range_attrs[0]; const LibertyAttrValueSeq &values = attr->values(); if (values.size() == 2) { - float cap_min = values[0]->floatValue(); - float cap_max = values[1]->floatValue(); - port->setCapacitance(rf, MinMax::min(), cap_min * cap_scale_); - port->setCapacitance(rf, MinMax::max(), cap_max * cap_scale_); + auto [cap_min, min_valid] = values[0]->floatValue(); + if (min_valid) + port->setCapacitance(rf, MinMax::min(), cap_min * cap_scale_); + auto [cap_max, max_valid] = values[1]->floatValue(); + if (max_valid) + port->setCapacitance(rf, MinMax::max(), cap_max * cap_scale_); } } } @@ -1510,7 +1525,7 @@ LibertyReader::readCapacitance(const LibertyPortSeq &ports, for (const MinMax *min_max : MinMax::range()) { // min/max_capacitance - std::string attr_name = min_max->to_string() + "_capacitance"; + std::string attr_name = sta::format("{}_capacitance", min_max->to_string()); float limit; bool exists; port_group->findAttrFloat(attr_name, limit, exists); @@ -1518,7 +1533,7 @@ LibertyReader::readCapacitance(const LibertyPortSeq &ports, port->setCapacitanceLimit(limit * cap_scale_, min_max); // min/max_transition - attr_name = min_max->to_string() + "_transition"; + attr_name = sta::format("{}_transition", min_max->to_string()); port_group->findAttrFloat(attr_name, limit, exists); if (exists) { if (min_max == MinMax::max() && limit == 0.0) @@ -1564,7 +1579,7 @@ LibertyReader::readMinPulseWidth(LibertyCell *cell, for (LibertyPort *port : ports) { TimingArcAttrsPtr timing_attrs = nullptr; for (const RiseFall *rf : RiseFall::range()) { - const char *mpw_attr_name = rf == RiseFall::rise() + const std::string mpw_attr_name = rf == RiseFall::rise() ? "min_pulse_width_high" : "min_pulse_width_low"; float mpw; @@ -1598,9 +1613,9 @@ LibertyReader::makePortFuncs(LibertyCell *cell, { const LibertySimpleAttr *func_attr = port_group->findSimpleAttr("function"); if (func_attr) { - const std::string *func = func_attr->stringValue(); - if (func) { - FuncExpr *func_expr = parseFunc(func->c_str(), "function", cell, func_attr->line()); + const std::string &func = func_attr->stringValue(); + if (!func.empty()) { + FuncExpr *func_expr = parseFunc(func, "function", cell, func_attr->line()); for (LibertyPort *port : ports) { port->setFunction(func_expr); if (func_expr->checkSize(port)) { @@ -1614,9 +1629,9 @@ LibertyReader::makePortFuncs(LibertyCell *cell, const LibertySimpleAttr *tri_attr = port_group->findSimpleAttr("three_state"); if (tri_attr) { - const std::string *tri_disable = tri_attr->stringValue(); - if (tri_disable) { - FuncExpr *tri_disable_expr = parseFunc(tri_disable->c_str(), + const std::string tri_disable = tri_attr->stringValue(); + if (!tri_disable.empty()) { + FuncExpr *tri_disable_expr = parseFunc(tri_disable, "three_state", cell, tri_attr->line()); FuncExpr *tri_enable_expr = tri_disable_expr->invert(); @@ -1653,11 +1668,12 @@ void LibertyReader::makeSequentials(LibertyCell *cell, const LibertyGroup *cell_group, bool is_register, - const char *seq_group_name, - const char *clk_attr_name, - const char *data_attr_name) + std::string_view seq_group_name, + std::string_view clk_attr_name, + std::string_view data_attr_name) { - for (const LibertyGroup *seq_group : cell_group->findSubgroups(seq_group_name)) { + for (const LibertyGroup *seq_group : + cell_group->findSubgroups(seq_group_name)) { LibertyPort *out_port = nullptr; LibertyPort *out_port_inv = nullptr; size_t size; @@ -1686,13 +1702,13 @@ LibertyReader::makeSequentials(LibertyCell *cell, FuncExpr * LibertyReader::makeSeqFunc(LibertyCell *cell, const LibertyGroup *seq_group, - const char *attr_name, + std::string_view attr_name, int size) { FuncExpr *expr = nullptr; - const std::string *attr = seq_group->findAttrString(attr_name); - if (attr) { - expr = parseFunc(attr->c_str(), attr_name, cell, seq_group->line()); + const std::string &attr = seq_group->findAttrString(attr_name); + if (!attr.empty()) { + expr = parseFunc(attr, attr_name, cell, seq_group->line()); if (expr && expr->checkSize(size)) { warn(1196, seq_group, "{} {} bus width mismatch.", seq_group->type(), attr_name); @@ -1711,17 +1727,17 @@ LibertyReader::makeSeqPorts(LibertyCell *cell, LibertyPort *&out_port_inv, size_t &size) { - const char *out_name, *out_inv_name; + std::string out_name, out_inv_name; bool has_size; seqPortNames(seq_group, out_name, out_inv_name, has_size, size); - if (out_name) { + if (!out_name.empty()) { if (has_size) out_port = makeBusPort(cell, out_name, size - 1, 0, nullptr); else out_port = makePort(cell, out_name); out_port->setDirection(PortDirection::internal()); } - if (out_inv_name) { + if (!out_inv_name.empty()) { if (has_size) out_port_inv = makeBusPort(cell, out_inv_name, size - 1, 0, nullptr); else @@ -1732,39 +1748,39 @@ LibertyReader::makeSeqPorts(LibertyCell *cell, void LibertyReader::seqPortNames(const LibertyGroup *group, - const char *&out_name, - const char *&out_inv_name, + // Return values. + std::string &out_name, + std::string &out_inv_name, bool &has_size, size_t &size) { - out_name = nullptr; - out_inv_name = nullptr; if (group->params().size() == 1) { // out_port - out_name = group->firstName(); + out_name = group->firstParam(); size = 1; has_size = false; } if (group->params().size() == 2) { // out_port, out_port_inv - out_name = group->firstName(); - out_inv_name = group->secondName(); + out_name = group->firstParam(); + out_inv_name = group->secondParam(); size = 1; has_size = false; } else if (group->params().size() == 3) { LibertyAttrValue *third_value = group->params()[2]; - if (third_value->isFloat()) { + auto [size_flt, size_valid] = third_value->floatValue(); + if (size_valid) { // out_port, out_port_inv, bus_size - out_name = group->firstName(); - out_inv_name = group->secondName(); - size = static_cast(third_value->floatValue()); + out_name = group->firstParam(); + out_inv_name = group->secondParam(); + size = static_cast(size_flt); has_size = true; } else { // in_port (ignored), out_port, out_port_inv - out_name = group->secondName(); - out_inv_name = third_value->stringValue().c_str(); + out_name = group->secondParam(); + out_inv_name = third_value->stringValue(); has_size = true; size = 1; } @@ -1805,12 +1821,12 @@ LibertyReader::readCellAttributes(LibertyCell *cell, readGroupAttrFloat("ocv_arc_depth", cell_group, [cell](float v) { cell->setOcvArcDepth(v); }); - const std::string *clock_gate_type = + const std::string &clock_gate_type = cell_group->findAttrString("clock_gating_integrated_cell"); - if (clock_gate_type) { - if (stringBeginEqual(clock_gate_type->c_str(), "latch_posedge")) + if (!clock_gate_type.empty()) { + if (stringBeginEqual(clock_gate_type.c_str(), "latch_posedge")) cell->setClockGateType(ClockGateType::latch_posedge); - else if (stringBeginEqual(clock_gate_type->c_str(), "latch_negedge")) + else if (stringBeginEqual(clock_gate_type.c_str(), "latch_negedge")) cell->setClockGateType(ClockGateType::latch_negedge); else cell->setClockGateType(ClockGateType::other); @@ -1826,29 +1842,31 @@ void LibertyReader::readScaleFactors(LibertyCell *cell, const LibertyGroup *cell_group) { - const std::string *scale_factors_name = cell_group->findAttrString("scaling_factors"); - if (scale_factors_name) { - ScaleFactors *scale_factors = library_->findScaleFactors(scale_factors_name->c_str()); + const std::string &scale_factors_name = + cell_group->findAttrString("scaling_factors"); + if (!scale_factors_name.empty()) { + ScaleFactors *scale_factors = + library_->findScaleFactors(scale_factors_name.c_str()); if (scale_factors) cell->setScaleFactors(scale_factors); else - warn(1230, cell_group, "scaling_factors {} not found.", *scale_factors_name); + warn(1230, cell_group, "scaling_factors {} not found.", scale_factors_name); } } void -LibertyReader::readCellAttrString(const char *attr_name, - void (LibertyCell::*set_func)(const char *value), +LibertyReader::readCellAttrString(std::string_view attr_name, + void (LibertyCell::*set_func)(std::string value), LibertyCell *cell, const LibertyGroup *group) { - const std::string *value = group->findAttrString(attr_name); - if (value) - (cell->*set_func)(value->c_str()); + const std::string &value = group->findAttrString(attr_name); + if (!value.empty()) + (cell->*set_func)(value); } void -LibertyReader::readCellAttrFloat(const char *attr_name, +LibertyReader::readCellAttrFloat(std::string_view attr_name, void (LibertyCell::*set_func)(float value), LibertyCell *cell, const LibertyGroup *group, @@ -1862,7 +1880,7 @@ LibertyReader::readCellAttrFloat(const char *attr_name, } void -LibertyReader::readCellAttrBool(const char *attr_name, +LibertyReader::readCellAttrBool(std::string_view attr_name, void (LibertyCell::*set_func)(bool value), LibertyCell *cell, const LibertyGroup *group) @@ -1872,9 +1890,9 @@ LibertyReader::readCellAttrBool(const char *attr_name, const LibertyAttrValue &attr_value = attr->value(); if (attr_value.isString()) { const std::string &value = attr_value.stringValue(); - if (stringEqual(value.c_str(), "true")) + if (stringEqual(value, "true")) (cell->*set_func)(true); - else if (stringEqual(value.c_str(), "false")) + else if (stringEqual(value, "false")) (cell->*set_func)(false); else warn(1279, attr, "{} attribute is not boolean.", attr_name); @@ -1947,7 +1965,7 @@ LibertyReader::readTimingArcAttrs(LibertyCell *cell, } void -LibertyReader::readGroupAttrFloat(const char *attr_name, +LibertyReader::readGroupAttrFloat(std::string_view attr_name, const LibertyGroup *group, const std::function &set_func, float scale) @@ -1965,17 +1983,15 @@ LibertyReader::readTimingSense(const LibertyGroup *timing_group, { const LibertySimpleAttr *sense_attr = timing_group->findSimpleAttr("timing_sense"); if (sense_attr) { - const std::string *sense_name = sense_attr->stringValue(); - if (sense_name) { - if (*sense_name == "non_unate") - timing_attrs->setTimingSense(TimingSense::non_unate); - else if (*sense_name == "positive_unate") - timing_attrs->setTimingSense(TimingSense::positive_unate); - else if (*sense_name == "negative_unate") - timing_attrs->setTimingSense(TimingSense::negative_unate); - else - warn(1245, timing_group, "unknown timing_sense {}.", *sense_name); - } + const std::string &sense_name = sense_attr->stringValue(); + if (sense_name == "non_unate") + timing_attrs->setTimingSense(TimingSense::non_unate); + else if (sense_name == "positive_unate") + timing_attrs->setTimingSense(TimingSense::positive_unate); + else if (sense_name == "negative_unate") + timing_attrs->setTimingSense(TimingSense::negative_unate); + else + warn(1245, timing_group, "unknown timing_sense {}.", sense_name); } } @@ -1986,13 +2002,11 @@ LibertyReader::readTimingType(const LibertyGroup *timing_group, TimingType type = TimingType::combinational; const LibertySimpleAttr *type_attr = timing_group->findSimpleAttr("timing_type"); if (type_attr) { - const std::string *type_name = type_attr->stringValue(); - if (type_name) { - type = findTimingType(type_name->c_str()); - if (type == TimingType::unknown) { - warn(1244, type_attr, "unknown timing_type {}.", *type_name); - type = TimingType::combinational; - } + const std::string type_name = type_attr->stringValue(); + type = findTimingType(type_name); + if (type == TimingType::unknown) { + warn(1244, type_attr, "unknown timing_type {}.", type_name); + type = TimingType::combinational; } } timing_attrs->setTimingType(type); @@ -2005,30 +2019,27 @@ LibertyReader::readTimingWhen(const LibertyCell *cell, { const LibertySimpleAttr *when_attr = timing_group->findSimpleAttr("when"); if (when_attr) { - const std::string *when = when_attr->stringValue(); - if (when) { - FuncExpr *when_expr = parseFunc(when->c_str(), "when", cell, when_attr->line()); + const std::string &when = when_attr->stringValue(); + if (!when.empty()) { + FuncExpr *when_expr = parseFunc(when, "when", cell, when_attr->line()); timing_attrs->setCond(when_expr); } } const LibertySimpleAttr *cond_attr = timing_group->findSimpleAttr("sdf_cond"); if (cond_attr) { - const std::string *cond = cond_attr->stringValue(); - if (cond) - timing_attrs->setSdfCond(cond->c_str()); + const std::string &cond = cond_attr->stringValue(); + timing_attrs->setSdfCond(cond); } cond_attr = timing_group->findSimpleAttr("sdf_cond_start"); if (cond_attr) { - const std::string *cond = cond_attr->stringValue(); - if (cond) - timing_attrs->setSdfCondStart(cond->c_str()); + const std::string &cond = cond_attr->stringValue(); + timing_attrs->setSdfCondStart(cond); } cond_attr = timing_group->findSimpleAttr("sdf_cond_end"); if (cond_attr) { - const std::string *cond = cond_attr->stringValue(); - if (cond) - timing_attrs->setSdfCondEnd(cond->c_str()); + const std::string &cond = cond_attr->stringValue(); + timing_attrs->setSdfCondEnd(cond); } } @@ -2085,7 +2096,7 @@ LibertyReader::makeLinearModels(LibertyCell *cell, { LibertyLibrary *library = cell->libertyLibrary(); for (const RiseFall *rf : RiseFall::range()) { - std::string intr_attr_name = "intrinsic_" + rf->to_string(); + std::string intr_attr_name = sta::format("intrinsic_{}", rf->to_string()); float intr = 0.0; bool intr_exists; timing_group->findAttrFloat(intr_attr_name, intr, intr_exists); @@ -2098,7 +2109,7 @@ LibertyReader::makeLinearModels(LibertyCell *cell, if (timingTypeIsCheck(timing_attrs->timingType())) model = new CheckLinearModel(cell, intr); else { - std::string res_attr_name = rf->to_string() + "_resistance"; + std::string res_attr_name = sta::format("{}_resistance", rf->to_string()); float res = 0.0; bool res_exists; timing_group->findAttrFloat(res_attr_name, res, res_exists); @@ -2122,13 +2133,14 @@ LibertyReader::makeTableModels(LibertyCell *cell, bool found_model = false; for (const RiseFall *rf : RiseFall::range()) { TableModel *delay_model = readTableModel(timing_group, - "cell_" + rf->to_string(), + sta::format("cell_{}", rf->to_string()), rf, TableTemplateType::delay, time_scale_, ScaleFactorType::cell, GateTableModel::checkAxes); TableModel *slew_model = readTableModel(timing_group, - rf->to_string() + "_transition", + sta::format("{}_transition", + rf->to_string()), rf, TableTemplateType::delay, time_scale_, ScaleFactorType::transition, @@ -2136,18 +2148,18 @@ LibertyReader::makeTableModels(LibertyCell *cell, if (delay_model || slew_model) { TableModels *delay_models = new TableModels(delay_model); readLvfModels(timing_group, - "ocv_sigma_cell_" + rf->to_string(), - "ocv_std_dev_cell_" + rf->to_string(), - "ocv_mean_shift_cell_" + rf->to_string(), - "ocv_skewness_cell_" + rf->to_string(), + sta::format("ocv_sigma_cell_{}", rf->to_string()), + sta::format("ocv_std_dev_cell_{}", rf->to_string()), + sta::format("ocv_mean_shift_cell_{}", rf->to_string()), + sta::format("ocv_skewness_cell_{}", rf->to_string()), rf, delay_models, GateTableModel::checkAxes); TableModels *slew_models = new TableModels(slew_model); readLvfModels(timing_group, - "ocv_sigma_" + rf->to_string() + "_transition", - "ocv_std_dev_" + rf->to_string() + "_transition", - "ocv_mean_shift_" + rf->to_string() + "_transition", - "ocv_skewness_" + rf->to_string() + "_transition", + sta::format("ocv_sigma_{}_transition", rf->to_string()), + sta::format("ocv_std_dev_{}_transition", rf->to_string()), + sta::format("ocv_mean_shift_{}_transition", rf->to_string()), + sta::format("ocv_skewness_{}_transition", rf->to_string()), rf, slew_models, GateTableModel::checkAxes); ReceiverModelPtr receiver_model = readReceiverCapacitance(timing_group, rf); @@ -2167,21 +2179,21 @@ LibertyReader::makeTableModels(LibertyCell *cell, found_model = true; } - std::string constraint_attr_name = rf->to_string() + "_constraint"; + std::string constraint_attr_name = sta::format("{}_constraint", rf->to_string()); ScaleFactorType scale_factor_type = timingTypeScaleFactorType(timing_attrs->timingType()); TableModel *check_model = readTableModel(timing_group, - constraint_attr_name.c_str(), + constraint_attr_name, rf, TableTemplateType::delay, time_scale_, scale_factor_type, CheckTableModel::checkAxes); if (check_model) { TableModels *check_models = new TableModels(check_model); readLvfModels(timing_group, - "ocv_sigma_" + rf->to_string() + "_constraint", - "ocv_std_dev_" + rf->to_string() + "_constraint", - "ocv_mean_shift_" + rf->to_string() + "_constraint", - "ocv_skewness_" + rf->to_string() + "_constraint", + sta::format("ocv_sigma_{}_constraiint", rf->to_string()), + sta::format("ocv_std_dev_{}_constraiint", rf->to_string()), + sta::format("ocv_mean_shift_{}_constraiint", rf->to_string()), + sta::format("ocv_skewness_{}_constraiint", rf->to_string()), rf, check_models, CheckTableModel::checkAxes); timing_attrs->setModel(rf, new CheckTableModel(cell, check_models)); found_model = true; @@ -2237,7 +2249,7 @@ LibertyReader::readLvfModels(const LibertyGroup *timing_group, { TableModelsEarlyLate sigmas = readEarlyLateTableModels(timing_group, - sigma_group_name.c_str(), + sigma_group_name, rf, TableTemplateType::delay, time_scale_, ScaleFactorType::unknown, @@ -2274,7 +2286,7 @@ LibertyReader::readLvfModels(const LibertyGroup *timing_group, TableModelsEarlyLate LibertyReader::readEarlyLateTableModels(const LibertyGroup *timing_group, - const char *table_group_name, + std::string_view table_group_name, const RiseFall *rf, TableTemplateType template_type, float scale, @@ -2282,18 +2294,18 @@ LibertyReader::readEarlyLateTableModels(const LibertyGroup *timing_group, const std::function check_axes) { TableModelsEarlyLate models{}; - for (const LibertyGroup *table_group : timing_group->findSubgroups(table_group_name)) { + for (const LibertyGroup *table_group : timing_group->findSubgroups(table_group_name)){ TableModel *model = readTableModel(table_group, rf, template_type, scale, scale_factor_type, check_axes); - const std::string *early_late = table_group->findAttrString("sigma_type"); - if (early_late == nullptr - || *early_late == "early_and_late") { + const std::string &early_late = table_group->findAttrString("sigma_type"); + if (early_late.empty() + || early_late == "early_and_late") { models[EarlyLate::early()->index()] = model; models[EarlyLate::late()->index()] = model; } - else if (*early_late == "early") + else if (early_late == "early") models[EarlyLate::early()->index()] = model; - else if (*early_late == "late") + else if (early_late == "late") models[EarlyLate::late()->index()] = model; } return models; @@ -2315,13 +2327,12 @@ LibertyReader::readReceiverCapacitance(const LibertyGroup *timing_group, void LibertyReader::readReceiverCapacitance(const LibertyGroup *timing_group, - const char *cap_group_name, + std::string_view cap_group_name, int index, const RiseFall *rf, ReceiverModelPtr &receiver_model) { - std::string cap_group_name1 = cap_group_name; - cap_group_name1 += "_" + rf->to_string(); + std::string cap_group_name1 = sta::format("{}_{}", cap_group_name, rf->to_string()); const LibertyGroup *cap_group = timing_group->findSubgroup(cap_group_name1); if (cap_group) { const LibertySimpleAttr *segment_attr = cap_group->findSimpleAttr("segment"); @@ -2351,7 +2362,7 @@ OutputWaveforms * LibertyReader::readOutputWaveforms(const LibertyGroup *timing_group, const RiseFall *rf) { - const std::string current_group_name = "output_current_" + rf->to_string(); + const std::string current_group_name=sta::format("output_current_{}",rf->to_string()); const LibertyGroup *current_group = timing_group->findSubgroup(current_group_name); if (current_group) { OutputWaveformSeq output_currents; @@ -2466,8 +2477,8 @@ LibertyReader::readTableModel(const LibertyGroup *table_group, ScaleFactorType scale_factor_type, const std::function &check_axes) { - const char *template_name = table_group->firstName(); - if (library_ && template_name) { + if (library_ && table_group->hasFirstParam()) { + const std::string &template_name = table_group->firstParam(); TableTemplate *tbl_template = library_->findTableTemplate(template_name, template_type); if (tbl_template) { @@ -2527,7 +2538,7 @@ LibertyReader::readTableModel(const LibertyGroup *table_group, TableAxisPtr LibertyReader::makeTableAxis(const LibertyGroup *table_group, - const char *index_attr_name, + std::string_view index_attr_name, TableAxisPtr template_axis) { const LibertyComplexAttr *index_attr = table_group->findComplexAttr(index_attr_name); @@ -2566,7 +2577,7 @@ LibertyReader::makeTimingArcs(LibertyCell *cell, TimingArcAttrsPtr timing_attrs, int timing_line) { - PortNameBitIterator from_port_iter(cell, from_port_name.c_str(), this, timing_line); + PortNameBitIterator from_port_iter(cell, from_port_name, this, timing_line); if (from_port_iter.size() == 1 && !to_port->hasMembers()) { // one -> one if (from_port_iter.hasNext()) { @@ -2611,7 +2622,7 @@ LibertyReader::makeTimingArcs(LibertyCell *cell, if (from_size != to_size) warn(1216, timing_line, "timing port {} and related port {} are different sizes.", - from_port_name.c_str(), + from_port_name, to_port->name()); // align to/from iterators for one-to-one mapping while (from_size > to_size) { @@ -2707,7 +2718,7 @@ LibertyReader::readInternalPowerGroups(LibertyCell *cell, InternalPowerModels models{}; // rise/fall_power group for (const RiseFall *rf : RiseFall::range()) { - std::string pwr_attr_name = rf->to_string() + "_power"; + std::string pwr_attr_name = sta::format("{}_power", rf->to_string()); const LibertyGroup *pwr_group = ipwr_group->findSubgroup(pwr_attr_name); if (pwr_group) { TableModel *model = readTableModel(pwr_group, rf, TableTemplateType::power, @@ -2746,11 +2757,11 @@ LibertyReader::readInternalPowerGroups(LibertyCell *cell, FuncExpr * LibertyReader::readFuncExpr(LibertyCell *cell, const LibertyGroup *group, - const char *attr_name) + std::string_view attr_name) { - const std::string *attr = group->findAttrString(attr_name); - if (attr) - return parseFunc(attr->c_str(), attr_name, cell, group->line()); + const std::string &attr = group->findAttrString(attr_name); + if (!attr.empty()) + return parseFunc(attr, attr_name, cell, group->line()); else return nullptr; } @@ -2758,32 +2769,28 @@ LibertyReader::readFuncExpr(LibertyCell *cell, LibertyPort * LibertyReader::findLibertyPort(LibertyCell *cell, const LibertyGroup *group, - const char *port_name_attr) + std::string_view port_name_attr) { const LibertySimpleAttr *attr = group->findSimpleAttr(port_name_attr); if (attr) { - const std::string *port_name = attr->stringValue(); - if (port_name) { - LibertyPort *port = cell->findLibertyPort(port_name->c_str()); - if (port) - return port; - else - warn(1290, attr, "port {} not found.", *port_name); - } + const std::string &port_name = attr->stringValue(); + LibertyPort *port = cell->findLibertyPort(port_name); + if (port) + return port; + else + warn(1290, attr, "port {} not found.", port_name); } return nullptr; } StringSeq LibertyReader::findAttributStrings(const LibertyGroup *group, - const char *name_attr) + std::string_view name_attr) { const LibertySimpleAttr *attr = group->findSimpleAttr(name_attr); if (attr) { - const std::string *strings = attr->stringValue(); - if (strings) { - return parseTokens(*strings, ' '); - } + const std::string &strings = attr->stringValue(); + return parseTokens(strings); } return StringSeq(); } @@ -2791,12 +2798,12 @@ LibertyReader::findAttributStrings(const LibertyGroup *group, LibertyPortSeq LibertyReader::findLibertyPorts(LibertyCell *cell, const LibertyGroup *group, - const char *port_name_attr) + std::string_view port_name_attr) { LibertyPortSeq ports; StringSeq port_names = findAttributStrings(group, port_name_attr); for (const std::string &port_name : port_names) { - LibertyPort *port = findPort(cell, port_name.c_str()); + LibertyPort *port = findPort(cell, port_name); if (port) ports.push_back(port); else @@ -2855,8 +2862,8 @@ LibertyReader::readNormalizedDriverWaveform(const LibertyGroup *library_group) { for (const LibertyGroup *waveform_group : library_group->findSubgroups("normalized_driver_waveform")) { - const char *template_name = waveform_group->firstName(); - if (template_name) { + if (waveform_group->hasFirstParam()) { + const std::string &template_name = waveform_group->firstParam(); TableTemplate *tbl_template = library_->findTableTemplate(template_name, TableTemplateType::delay); if (!tbl_template) { @@ -2877,9 +2884,10 @@ LibertyReader::readNormalizedDriverWaveform(const LibertyGroup *library_group) continue; } std::string driver_waveform_name; - const std::string *name_attr = waveform_group->findAttrString("driver_waveform_name"); - if (name_attr) - driver_waveform_name = *name_attr; + const std::string &name_attr = + waveform_group->findAttrString("driver_waveform_name"); + if (!name_attr.empty()) + driver_waveform_name = name_attr; library_->makeDriverWaveform(driver_waveform_name, table); } else @@ -2893,13 +2901,14 @@ void LibertyReader::readLevelShifterType(LibertyCell *cell, const LibertyGroup *cell_group) { - const std::string *level_shifter_type = cell_group->findAttrString("level_shifter_type"); - if (level_shifter_type) { - if (*level_shifter_type == "HL") + const std::string &level_shifter_type = + cell_group->findAttrString("level_shifter_type"); + if (!level_shifter_type.empty()) { + if (level_shifter_type == "HL") cell->setLevelShifterType(LevelShifterType::HL); - else if (*level_shifter_type == "LH") + else if (level_shifter_type == "LH") cell->setLevelShifterType(LevelShifterType::LH); - else if (*level_shifter_type == "HL_LH") + else if (level_shifter_type == "HL_LH") cell->setLevelShifterType(LevelShifterType::HL_LH); else warn(1228, cell_group, "level_shifter_type must be HL, LH, or HL_LH"); @@ -2910,11 +2919,12 @@ void LibertyReader::readSwitchCellType(LibertyCell *cell, const LibertyGroup *cell_group) { - const std::string *switch_cell_type = cell_group->findAttrString("switch_cell_type"); - if (switch_cell_type) { - if (*switch_cell_type == "coarse_grain") + const std::string &switch_cell_type = + cell_group->findAttrString("switch_cell_type"); + if (!switch_cell_type.empty()) { + if (switch_cell_type == "coarse_grain") cell->setSwitchCellType(SwitchCellType::coarse_grain); - else if (*switch_cell_type == "fine_grain") + else if (switch_cell_type == "fine_grain") cell->setSwitchCellType(SwitchCellType::fine_grain); else warn(1229, cell_group, "switch_cell_type must be coarse_grain or fine_grain"); @@ -2925,16 +2935,16 @@ void LibertyReader::readCellOcvDerateGroup(LibertyCell *cell, const LibertyGroup *cell_group) { - const std::string *derate_name = cell_group->findAttrString("ocv_derate_group"); - if (derate_name) { - OcvDerate *derate = cell->findOcvDerate(derate_name->c_str()); + const std::string &derate_name = cell_group->findAttrString("ocv_derate_group"); + if (!derate_name.empty()) { + OcvDerate *derate = cell->findOcvDerate(derate_name.c_str()); if (derate == nullptr) - derate = library_->findOcvDerate(derate_name->c_str()); + derate = library_->findOcvDerate(derate_name.c_str()); if (derate) cell->setOcvDerate(derate); else warn(1237, cell_group, "OCV derate group named {} not found.", - *derate_name); + derate_name); } } @@ -2943,43 +2953,45 @@ LibertyReader::readStatetable(LibertyCell *cell, const LibertyGroup *cell_group) { for (const LibertyGroup *statetable_group : cell_group->findSubgroups("statetable")) { - const char *input_ports_arg = statetable_group->firstName(); - const char *internal_ports_arg = statetable_group->params().size() >= 2 - ? statetable_group->secondName() : nullptr; StringSeq input_ports; - if (input_ports_arg) - input_ports = parseTokens(input_ports_arg, ' '); + if (statetable_group->hasFirstParam()) { + const std::string &input_ports_arg = statetable_group->firstParam(); + input_ports = parseTokens(input_ports_arg); + } + StringSeq internal_ports; - if (internal_ports_arg) - internal_ports = parseTokens(internal_ports_arg, ' '); + if (statetable_group->hasSecondParam()) { + const std::string &internal_ports_arg = statetable_group->secondParam(); + internal_ports = parseTokens(internal_ports_arg); + } const LibertySimpleAttr *table_attr = statetable_group->findSimpleAttr("table"); if (table_attr) { - const std::string *table_str = table_attr->stringValue(); - StringSeq table_rows = parseTokens(table_str->c_str(), ','); + const std::string &table_str = table_attr->stringValue(); + StringSeq table_rows = parseTokens(table_str, ","); size_t input_count = input_ports.size(); size_t internal_count = internal_ports.size(); StatetableRows table; for (const std::string &row : table_rows) { - const StringSeq row_groups = parseTokens(row, ':'); + const StringSeq row_groups = parseTokens(row, ":"); if (row_groups.size() != 3) { warn(1300, table_attr, "table row must have 3 groups separated by ':'."); break; } - StringSeq inputs = parseTokens(row_groups[0], ' '); + StringSeq inputs = parseTokens(row_groups[0]); if (inputs.size() != input_count) { warn(1301, table_attr, "table row has {} input values but {} are required.", inputs.size(), input_count); break; } - StringSeq currents = parseTokens(row_groups[1], ' '); + StringSeq currents = parseTokens(row_groups[1]); if (currents.size() != internal_count) { warn(1302,table_attr, "table row has {} current values but {} are required.", currents.size(), internal_count); break; } - StringSeq nexts = parseTokens(row_groups[2], ' '); + StringSeq nexts = parseTokens(row_groups[2]); if (nexts.size() != internal_count) { warn(1303, table_attr, "table row has {} next values but {} are required.", nexts.size(), internal_count); @@ -2994,10 +3006,10 @@ LibertyReader::readStatetable(LibertyCell *cell, LibertyPortSeq input_port_ptrs; for (const std::string &input : input_ports) { - LibertyPort *port = cell->findLibertyPort(input.c_str()); + LibertyPort *port = cell->findLibertyPort(input); if (port == nullptr && cell->testCell()) - port = cell->testCell()->findLibertyPort(input.c_str()); + port = cell->testCell()->findLibertyPort(input); if (port) input_port_ptrs.push_back(port); else @@ -3006,9 +3018,9 @@ LibertyReader::readStatetable(LibertyCell *cell, } LibertyPortSeq internal_port_ptrs; for (const std::string &internal : internal_ports) { - LibertyPort *port = cell->findLibertyPort(internal.c_str()); + LibertyPort *port = cell->findLibertyPort(internal); if (port == nullptr) - port = makePort(cell, internal.c_str()); + port = makePort(cell, internal); internal_port_ptrs.push_back(port); } cell->makeStatetable(input_port_ptrs, internal_port_ptrs, table); @@ -3039,27 +3051,27 @@ LibertyReader::readTestCell(LibertyCell *cell, LibertyPort * LibertyReader::makePort(LibertyCell *cell, - const char *port_name) + std::string_view port_name) { std::string sta_name = portLibertyToSta(port_name); - return builder_.makePort(cell, sta_name.c_str()); + return builder_.makePort(cell, sta_name); } LibertyPort * LibertyReader::makeBusPort(LibertyCell *cell, - const char *bus_name, + std::string_view bus_name, int from_index, int to_index, BusDcl *bus_dcl) { std::string sta_name = portLibertyToSta(bus_name); - return builder_.makeBusPort(cell, bus_name, from_index, to_index, bus_dcl); + return builder_.makeBusPort(cell, sta_name, from_index, to_index, bus_dcl); } -// Also used by LibExprParser::makeFuncExprPort. +// Also used by LibExprReader::makeFuncExprPort. LibertyPort * libertyReaderFindPort(const LibertyCell *cell, - const char *port_name) + std::string_view port_name) { LibertyPort *port = cell->findLibertyPort(port_name); if (port == nullptr) { @@ -3069,14 +3081,14 @@ libertyReaderFindPort(const LibertyCell *cell, const char escape = '\\'; // Pins at top level with bus names have escaped brackets. std::string escaped_port_name = escapeChars(port_name, brkt_left, brkt_right, escape); - port = cell->findLibertyPort(escaped_port_name.c_str()); + port = cell->findLibertyPort(escaped_port_name); } return port; } LibertyPort * LibertyReader::findPort(LibertyCell *cell, - const char *port_name) + std::string_view port_name) { return libertyReaderFindPort(cell, port_name); } @@ -3128,10 +3140,9 @@ LibertyReader::parseStateInputValues(StringSeq &inputs, for (std::string input : inputs) { bool exists; StateInputValue value; - state_input_value_name_map.find(input.c_str(), value, exists); + state_input_value_name_map.find(input, value, exists); if (!exists) { - warn(1304, attr, "table input value '{}' not recognized.", - input); + warn(1304, attr, "table input value '{}' not recognized.", input); value = StateInputValue::dont_care; } input_values.push_back(value); @@ -3147,10 +3158,9 @@ LibertyReader::parseStateInternalValues(StringSeq &states, for (std::string state : states) { bool exists; StateInternalValue value; - state_internal_value_name_map.find(state.c_str(), value, exists); + state_internal_value_name_map.find(state, value, exists); if (!exists) { - warn(1305, attr, "table internal value '{}' not recognized.", - state); + warn(1305, attr, "table internal value '{}' not recognized.", state); value = StateInternalValue::unknown; } state_values.push_back(value); @@ -3173,17 +3183,19 @@ LibertyReader::makeFloatTable(const LibertyComplexAttr *values_attr, FloatSeq row; row.reserve(cols); if (value->isString()) - row = parseStringFloatList(value->stringValue(), scale, values_attr); - else if (value->isFloat()) - row.push_back(value->floatValue() * scale); + row = parseFloatList(value->stringValue(), scale, values_attr->line()); + else if (value->isFloat()) { + auto [entry, valid] = value->floatValue(); + row.push_back(entry * scale); + } else warn(1258, values_attr, "{} is not a list of floats.", - values_attr->name()); + values_attr->name()); if (row.size() != cols) { warn(1259, values_attr, "{} row has {} columns but axis has {}.", - table_group->type(), - row.size(), - cols); + table_group->type(), + row.size(), + cols); for (size_t c = row.size(); c < cols; c++) row.push_back(0.0); } @@ -3192,12 +3204,12 @@ LibertyReader::makeFloatTable(const LibertyComplexAttr *values_attr, if (table.size() != rows) { if (rows == 0) warn(1260, values_attr, "{} missing axis values.", - table_group->type()); + table_group->type()); else warn(1261, values_attr, "{} has {} rows but axis has {}.", - table_group->type(), - table.size(), - rows); + table_group->type(), + table.size(), + rows); for (size_t r = table.size(); r < rows; r++) { FloatSeq row(cols, 0.0); table.push_back(std::move(row)); @@ -3218,7 +3230,7 @@ LibertyReader::getAttrInt(const LibertySimpleAttr *attr, exists = false; const LibertyAttrValue &attr_value = attr->value(); if (attr_value.isFloat()) { - float float_val = attr_value.floatValue(); + auto [float_val, valid] = attr_value.floatValue(); value = static_cast(float_val); exists = true; } @@ -3260,21 +3272,19 @@ LibertyReader::getAttrFloat(const LibertyComplexAttr *attr, bool &valid) { if (attr_value->isFloat()) { - valid = true; - value = attr_value->floatValue(); + auto [value1, valid1] = attr_value->floatValue(); + value = value1; + valid = valid1; } else if (attr_value->isString()) { const std::string &str = attr_value->stringValue(); - variableValue(str.c_str(), value, valid); + variableValue(str, value, valid); if (!valid) { - char *end; - value = strtof(str.c_str(), &end); - if ((*end && !isspace(*end)) - || str == "inf") - warn(1183, attr->line(), "{} value {} is not a float.", - attr->name(), - str); - valid = true; + auto [value1, valid1] = stringFloat(str); + value = value1; + valid = valid1; + if (!valid1) + warn(1183, attr->line(), "{} value {} is not a float.", attr->name(), str); } } } @@ -3283,76 +3293,19 @@ LibertyReader::getAttrFloat(const LibertyComplexAttr *attr, // Note that some brain damaged vendors (that used to "Think") are not // consistent about including the delimiters. FloatSeq -LibertyReader::parseStringFloatList(const std::string &float_list, - float scale, - const LibertySimpleAttr *attr) +LibertyReader::parseFloatList(const std::string &float_list, + float scale, + int line) { + StringSeq tokens = parseTokens(float_list, " ,{}"); FloatSeq values; - values.reserve(std::max(10, float_list.size() / 5)); - const char *token = float_list.c_str(); - while (*token != '\0') { - // Some (brain dead) libraries enclose floats in brackets. - if (*token == '{') - token++; - char *end; - float value = strtof(token, &end) * scale; - if (end == token - || !(*end == '\0' - || isspace(*end) - || *end == ',' - || *end == '}')) { - std::string token_end = token; - if (end != token) { - token_end.clear(); - for (const char *t = token; t <= end; t++) - token_end += *t; - } - warn(1310, attr, "{} is not a float.", token_end); - token += token_end.size(); - } - else { - values.push_back(value); - token = end; - } - while (*token == ',' || *token == ' ' || *token == '}') - token++; - } - return values; -} - -FloatSeq -LibertyReader::parseStringFloatList(const std::string &float_list, - float scale, - const LibertyComplexAttr *attr) -{ - FloatSeq values; - values.reserve(std::max(10, float_list.size() / 5)); - const char *token = float_list.c_str(); - while (*token != '\0') { - if (*token == '{') - token++; - char *end; - float value = strtof(token, &end) * scale; - if (end == token - || !(*end == '\0' - || isspace(*end) - || *end == ',' - || *end == '}')) { - std::string token_end = token; - if (end != token) { - token_end.clear(); - for (const char *t = token; t <= end; t++) - token_end += *t; - } - warn(1275, attr, "{} is not a float.", token_end); - token += token_end.size(); - } - else { - values.push_back(value); - token = end; - } - while (*token == ',' || *token == ' ' || *token == '}') - token++; + values.reserve(tokens.size()); + for (const std::string &token : tokens) { + auto [value, valid] = stringFloat(token); + if (!valid) + warn(1310, line, "{} is not a float.", token); + else + values.push_back(value * scale); } return values; } @@ -3365,23 +3318,25 @@ LibertyReader::readFloatSeq(const LibertyComplexAttr *attr, const LibertyAttrValueSeq &attr_values = attr->values(); if (attr_values.size() == 1) { LibertyAttrValue *value = attr_values[0]; - if (value->isString()) { - values = parseStringFloatList(value->stringValue(), scale, attr); + if (value->isString()) + values = parseFloatList(value->stringValue(), scale, attr->line()); + else { + auto [entry, valid] = value->floatValue(); + if (valid) + values.push_back(entry * scale); } - else if (value->isFloat()) { - values.push_back(value->floatValue() * scale); - } - else - warn(1276, attr, "{} is missing values.", attr->name()); } else if (attr_values.size() > 1) { - for (LibertyAttrValue *val : attr_values) { - if (val->isFloat()) - values.push_back(val->floatValue() * scale); - else if (val->isString()) { - FloatSeq parsed = parseStringFloatList(val->stringValue(), scale, attr); + for (LibertyAttrValue *value : attr_values) { + if (value->isString()) { + FloatSeq parsed = parseFloatList(value->stringValue(), scale, attr->line()); values.insert(values.end(), parsed.begin(), parsed.end()); } + else { + auto [entry, valid] = value->floatValue(); + if (valid) + values.push_back(entry * scale); + } } } else @@ -3401,11 +3356,11 @@ LibertyReader::getAttrBool(const LibertySimpleAttr *attr, const LibertyAttrValue &val = attr->value(); if (val.isString()) { const std::string &str = val.stringValue(); - if (stringEqual(str.c_str(), "true")) { + if (stringEqual(str, "true")) { value = true; exists = true; } - else if (stringEqual(str.c_str(), "false")) { + else if (stringEqual(str, "false")) { value = false; exists = true; } @@ -3420,31 +3375,28 @@ LibertyReader::getAttrBool(const LibertySimpleAttr *attr, LogicValue LibertyReader::getAttrLogicValue(const LibertySimpleAttr *attr) { - const std::string *str = attr->stringValue(); - if (str) { - if (*str == "L") - return LogicValue::zero; - else if (*str == "H") - return LogicValue::one; - else if (*str == "X") - return LogicValue::unknown; - else - warn(1282, attr, "attribute {} value {} not recognized.", - attr->name(), *str); - // fall thru - } + const std::string &str = attr->stringValue(); + if (str == "L") + return LogicValue::zero; + else if (str == "H") + return LogicValue::one; + else if (str == "X") + return LogicValue::unknown; + else + warn(1282, attr, "attribute {} value {} not recognized.", attr->name(), str); + // fall thru return LogicValue::unknown; } const EarlyLateAll * LibertyReader::getAttrEarlyLate(const LibertySimpleAttr *attr) { - const std::string *value = attr->stringValue(); - if (*value == "early") + const std::string &value = attr->stringValue(); + if (value == "early") return EarlyLateAll::early(); - else if (*value == "late") + else if (value == "late") return EarlyLateAll::late(); - else if (*value == "early_and_late") + else if (value == "early_and_late") return EarlyLateAll::all(); else { warn(1283, attr, "unknown early/late value."); @@ -3455,16 +3407,16 @@ LibertyReader::getAttrEarlyLate(const LibertySimpleAttr *attr) //////////////////////////////////////////////////////////////// FuncExpr * -LibertyReader::parseFunc(const char *func, - const char *attr_name, +LibertyReader::parseFunc(std::string_view func, + std::string_view attr_name, const LibertyCell *cell, int line) { - std::string error_msg = format("{}, line {}{}", - filename_, - line, - attr_name); - return parseFuncExpr(func, cell, error_msg.c_str(), report_); + std::string error_msg = sta::format("{} line {}, {}", + filename_, + line, + attr_name); + return parseFuncExpr(func, cell, error_msg, report_); } //////////////////////////////////////////////////////////////// @@ -3480,11 +3432,11 @@ LibertyReader::visitVariable(LibertyVariable *var) } void -LibertyReader::variableValue(const char *var, +LibertyReader::variableValue(std::string_view var, float &value, bool &exists) { - findKeyValue(var_map_, var, value, exists); + findKeyValue(var_map_, std::string(var), value, exists); } //////////////////////////////////////////////////////////////// @@ -3492,15 +3444,14 @@ LibertyReader::variableValue(const char *var, void LibertyReader::readDefaultOcvDerateGroup(const LibertyGroup *library_group) { - const std::string *derate_name = + const std::string &derate_name = library_group->findAttrString("default_ocv_derate_group"); - if (derate_name) { - OcvDerate *derate = library_->findOcvDerate(derate_name->c_str()); + if (!derate_name.empty()) { + OcvDerate *derate = library_->findOcvDerate(derate_name.c_str()); if (derate) library_->setDefaultOcvDerate(derate); else - warn(1284, library_group, "OCV derate group named {} not found.", - *derate_name); + warn(1284, library_group, "OCV derate group named {} not found.", derate_name); } } @@ -3511,34 +3462,35 @@ LibertyReader::readOcvDerateFactors(LibertyCell *cell, { for (const LibertyGroup *ocv_derate_group : parent_group->findSubgroups("ocv_derate")) { - const char *name = ocv_derate_group->firstName(); - if (name) { + if (ocv_derate_group->hasFirstParam()) { + const std::string &name = ocv_derate_group->firstParam(); OcvDerate *ocv_derate = cell - ? cell->makeOcvDerate(name) + ? cell->makeOcvDerate(name) : library_->makeOcvDerate(name); for (const LibertyGroup *factors_group : ocv_derate_group->findSubgroups("ocv_derate_factors")) { const RiseFallBoth *rf_type = RiseFallBoth::riseFall(); - const std::string *rf_attr = factors_group->findAttrString("rf_type"); - if (rf_attr) { - if (*rf_attr == "rise") + const std::string &rf_attr = factors_group->findAttrString("rf_type"); + if (!rf_attr.empty()) { + if (rf_attr == "rise") rf_type = RiseFallBoth::rise(); - else if (*rf_attr == "fall") + else if (rf_attr == "fall") rf_type = RiseFallBoth::fall(); - else if (*rf_attr == "rise_and_fall") + else if (rf_attr == "rise_and_fall") rf_type = RiseFallBoth::riseFall(); else error(1286, factors_group, "unknown rise/fall."); } const EarlyLateAll *derate_type = EarlyLateAll::all(); - const std::string *derate_attr = factors_group->findAttrString("derate_type"); - if (derate_attr) { - if (*derate_attr == "early") + const std::string &derate_attr = + factors_group->findAttrString("derate_type"); + if (!derate_attr.empty()) { + if (derate_attr == "early") derate_type = EarlyLateAll::early(); - else if (*derate_attr == "late") + else if (derate_attr == "late") derate_type = EarlyLateAll::late(); - else if (*derate_attr == "early_and_late") + else if (derate_attr == "early_and_late") derate_type = EarlyLateAll::all(); else { warn(1309, factors_group, "unknown early/late value."); @@ -3546,20 +3498,20 @@ LibertyReader::readOcvDerateFactors(LibertyCell *cell, } PathType path_type = PathType::clk_and_data; - const std::string *path_attr = factors_group->findAttrString("path_type"); - if (path_attr) { - if (*path_attr == "clock") + const std::string &path_attr = factors_group->findAttrString("path_type"); + if (!path_attr.empty()) { + if (path_attr == "clock") path_type = PathType::clk; - else if (*path_attr == "data") + else if (path_attr == "data") path_type = PathType::data; - else if (*path_attr == "clock_and_data") + else if (path_attr == "clock_and_data") path_type = PathType::clk_and_data; else warn(1287, factors_group, "unknown derate type."); } - const char *template_name = factors_group->firstName(); - if (template_name) { + if (factors_group->hasFirstParam()) { + const std::string &template_name = factors_group->firstParam(); TableTemplate *tbl_template = library_->findTableTemplate(template_name, TableTemplateType::ocv); if (tbl_template) { @@ -3580,6 +3532,8 @@ LibertyReader::readOcvDerateFactors(LibertyCell *cell, else warn(1308, factors_group, "table template {} not found.", template_name); } + else + warn(1312, factors_group, "ocv_derate_factors missing template."); } } else @@ -3590,7 +3544,7 @@ LibertyReader::readOcvDerateFactors(LibertyCell *cell, //////////////////////////////////////////////////////////////// PortNameBitIterator::PortNameBitIterator(LibertyCell *cell, - const char *port_name, + std::string_view port_name, LibertyReader *visitor, int line) : cell_(cell), @@ -3606,7 +3560,7 @@ PortNameBitIterator::PortNameBitIterator(LibertyCell *cell, } void -PortNameBitIterator::init(const char *port_name) +PortNameBitIterator::init(std::string_view port_name) { LibertyPort *port = visitor_->findPort(cell_, port_name); if (port) { @@ -3637,13 +3591,12 @@ PortNameBitIterator::init(const char *port_name) range_bit_ = from; } else - visitor_->warn(1292, line_, "port {} subscript out of range.", - port_name); + visitor_->warn(1292, line_, "port {} subscript out of range.", port_name); } else visitor_->warn(1293, line_, "port range {} of non-bus port {}.", - port_name, - bus_name); + port_name, + bus_name); } else { range_bus_name_ = bus_name; @@ -3713,7 +3666,7 @@ PortNameBitIterator::findRangeBusNameNext() LibertyLibrary *library = visitor_->library(); std::string bus_bit_name = range_bus_name_ + library->busBrktLeft() + std::to_string(range_bit_) + library->busBrktRight(); - range_name_next_ = visitor_->findPort(cell_, bus_bit_name.c_str()); + range_name_next_ = visitor_->findPort(cell_, bus_bit_name); if (range_name_next_) { if (range_from_ > range_to_) range_bit_--; diff --git a/liberty/LibertyReader.hh b/liberty/LibertyReader.hh index ebf4503d..27fed80a 100644 --- a/liberty/LibertyReader.hh +++ b/liberty/LibertyReader.hh @@ -24,13 +24,15 @@ #pragma once +#include + namespace sta { class Network; class LibertyLibrary; LibertyLibrary * -readLibertyFile(const char *filename, +readLibertyFile(std::string_view filename, bool infer_latches, Network *network); diff --git a/liberty/LibertyReaderPvt.hh b/liberty/LibertyReaderPvt.hh index e1307b7d..a840ebb2 100644 --- a/liberty/LibertyReaderPvt.hh +++ b/liberty/LibertyReaderPvt.hh @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -65,10 +66,10 @@ using OutputWaveformSeq = std::vector; class LibertyReader : public LibertyGroupVisitor { public: - LibertyReader(const char *filename, + LibertyReader(std::string_view filename, bool infer_latches, Network *network); - virtual LibertyLibrary *readLibertyFile(const char *filename); + virtual LibertyLibrary *readLibertyFile(std::string_view filename); LibertyLibrary *library() { return library_; } const LibertyLibrary *library() const { return library_; } @@ -90,7 +91,7 @@ public: void checkScaledCell(LibertyCell *scaled_cell, LibertyCell *owner, const LibertyGroup *scaled_cell_group, - const char *op_cond_name); + std::string_view op_cond_name); void setPortCapDefault(LibertyPort *port); void checkLatchEnableSense(FuncExpr *enable_func, @@ -102,9 +103,9 @@ public: float scale); LibertyPort *findPort(LibertyCell *cell, - const char *port_name); + std::string_view port_name); StringSeq findAttributStrings(const LibertyGroup *group, - const char *name_attr); + std::string_view name_attr); protected: virtual void begin(const LibertyGroup *group, @@ -113,7 +114,7 @@ protected: LibertyGroup *library_group); // Library gruops. - void makeLibrary(const LibertyGroup *libary_group); + void makeLibrary(const LibertyGroup *library_group); void readLibraryAttributes(const LibertyGroup *library_group); void readLibraryUnits(const LibertyGroup *library_group); void readDelayModel(const LibertyGroup *library_group); @@ -122,8 +123,8 @@ protected: void readDefaultWireLoadMode(const LibertyGroup *library_group); void readTechnology(const LibertyGroup *library_group); void readDefaultWireLoadSelection(const LibertyGroup *library_group); - void readUnit(const char *unit_attr_name, - const char *unit_suffix, + void readUnit(std::string_view unit_attr_name, + std::string_view unit_suffix, float &scale_var, Unit *unit, const LibertyGroup *library_group); @@ -131,7 +132,7 @@ protected: const LibertyGroup *type_group); void readTableTemplates(const LibertyGroup *library_group); void readTableTemplates(const LibertyGroup *library_group, - const char *group_name, + std::string_view group_name, TableTemplateType type); void readThresholds(const LibertyGroup *library_group); void checkThresholds(const LibertyGroup *library_group) const; @@ -150,17 +151,17 @@ protected: void readNormalizedDriverWaveform(const LibertyGroup *library_group); void readSlewDegradations(const LibertyGroup *library_group); void readLibAttrFloat(const LibertyGroup *library_group, - const char *attr_name, + std::string_view attr_name, void (LibertyLibrary::*set_func)(float value), float scale); void readLibAttrFloat(const LibertyGroup *library_group, - const char *attr_name, + std::string_view attr_name, void (LibertyLibrary::*set_func)(const RiseFall *rf, float value), const RiseFall *rf, float scale); void readLibAttrFloatWarnZero(const LibertyGroup *library_group, - const char *attr_name, + std::string_view attr_name, void (LibertyLibrary::*set_func)(float value), float scale); @@ -188,9 +189,9 @@ protected: void makePgPinPort(LibertyCell *cell, const LibertyGroup *pg_pin_group); LibertyPort *makePort(LibertyCell *cell, - const char *port_name); + std::string_view port_name); LibertyPort *makeBusPort(LibertyCell *cell, - const char *bus_name, + std::string_view bus_name, int from_index, int to_index, BusDcl *bus_dcl); @@ -198,22 +199,27 @@ protected: void readPortAttributes(LibertyCell *cell, const LibertyPortSeq &ports, const LibertyGroup *port_group); - void readPortAttrString(const char *attr_name, - void (LibertyPort::*set_func)(const char *value), + void readPortAttrString(std::string_view attr_name, + void (LibertyPort::*set_func)(std::string value), const LibertyPortSeq &ports, const LibertyGroup *group); - void readPortAttrFloat(const char *attr_name, + void readPortAttrLibertyPort(std::string_view attr_name, + void (LibertyPort::*set_func)(LibertyPort *port), + LibertyCell *cell, + const LibertyPortSeq &ports, + const LibertyGroup *group); + void readPortAttrFloat(std::string_view attr_name, void (LibertyPort::*set_func)(float value), const LibertyPortSeq &ports, const LibertyGroup *group, float scale); - void readPortAttrBool(const char *attr_name, + void readPortAttrBool(std::string_view attr_name, void (LibertyPort::*set_func)(bool value), const LibertyPortSeq &ports, const LibertyGroup *group); void readDriverWaveform(const LibertyPortSeq &ports, const LibertyGroup *port_group); - void readPortAttrFloatMinMax(const char *attr_name, + void readPortAttrFloatMinMax(std::string_view attr_name, void (LibertyPort::*set_func)(float value, const MinMax *min_max), const LibertyPortSeq &ports, @@ -243,7 +249,7 @@ protected: const std::function check_axes); TableModelsEarlyLate readEarlyLateTableModels(const LibertyGroup *timing_group, - const char *table_group_name, + std::string_view table_group_name, const RiseFall *rf, TableTemplateType template_type, float scale, @@ -252,7 +258,7 @@ protected: ReceiverModelPtr readReceiverCapacitance(const LibertyGroup *timing_group, const RiseFall *rf); void readReceiverCapacitance(const LibertyGroup *timing_group, - const char *cap_group_name, + std::string_view cap_group_name, int index, const RiseFall *rf, ReceiverModelPtr &receiver_model); @@ -291,9 +297,9 @@ protected: const std::function check_axes); TableAxisPtr makeTableAxis(const LibertyGroup *table_group, - const char *index_attr_name, + std::string_view index_attr_name, TableAxisPtr template_axis); - void readGroupAttrFloat(const char *attr_name, + void readGroupAttrFloat(std::string_view attr_name, const LibertyGroup *group, const std::function &set_func, float scale = 1.0F); @@ -318,12 +324,12 @@ protected: void makeSequentials(LibertyCell *cell, const LibertyGroup *cell_group, bool is_register, - const char *seq_group_name, - const char *clk_attr_name, - const char *data_attr_name); + std::string_view seq_group_name, + std::string_view clk_attr_name, + std::string_view data_attr_name); FuncExpr *makeSeqFunc(LibertyCell *cell, const LibertyGroup *seq_group, - const char *attr_name, + std::string_view attr_name, int size); void makeSeqPorts(LibertyCell *cell, const LibertyGroup *seq_group, @@ -332,8 +338,9 @@ protected: LibertyPort *&out_port_inv, size_t &size); void seqPortNames(const LibertyGroup *group, - const char *&out_name, - const char *&out_inv_name, + // Return values. + std::string &out_name, + std::string &out_inv_name, bool &has_size, size_t &size); TimingModel *makeScalarCheckModel(LibertyCell *cell, @@ -367,17 +374,17 @@ protected: const LibertyGroup *cell_group); void readScaleFactors(LibertyCell *cell, const LibertyGroup *cell_group); - void readCellAttrString(const char *attr_name, - void (LibertyCell::*set_func)(const char *value), + void readCellAttrString(std::string_view attr_name, + void (LibertyCell::*set_func)(std::string value), LibertyCell *cell, const LibertyGroup *group); - void readCellAttrFloat(const char *attr_name, + void readCellAttrFloat(std::string_view attr_name, void (LibertyCell::*set_func)(float value), LibertyCell *cell, const LibertyGroup *group, float scale); - void readCellAttrBool(const char *attr_name, - void (LibertyCell::*set_func)(bool value), + void readCellAttrBool(std::string_view attr_name, + void (LibertyCell::*set_func)(bool value), LibertyCell *cell, const LibertyGroup *group); void readLevelShifterType(LibertyCell *cell, @@ -393,18 +400,18 @@ protected: FuncExpr *readFuncExpr(LibertyCell *cell, const LibertyGroup *group, - const char *attr_name); + std::string_view attr_name); LibertyPort *findLibertyPort(LibertyCell *cell, const LibertyGroup *group, - const char *port_name_attr); + std::string_view port_name_attr); LibertyPortSeq findLibertyPorts(LibertyCell *cell, const LibertyGroup *group, - const char *port_name_attr); + std::string_view port_name_attr); float energyScale(); void defineVisitors(); - void defineGroupVisitor(const char *type, + void defineGroupVisitor(std::string_view type, LibraryGroupVisitor begin_visitor, LibraryGroupVisitor end_visitor); @@ -436,52 +443,49 @@ protected: bool &exists); const EarlyLateAll *getAttrEarlyLate(const LibertySimpleAttr *attr); - FloatSeq parseStringFloatList(const std::string &float_list, - float scale, - const LibertySimpleAttr *attr); - FloatSeq parseStringFloatList(const std::string &float_list, - float scale, - const LibertyComplexAttr *attr); + FloatSeq parseFloatList(const std::string &float_list, + float scale, + int line); TableAxisPtr makeAxis(int index, const LibertyGroup *group); FloatSeq readFloatSeq(const LibertyComplexAttr *attr, float scale); - void variableValue(const char *var, + void variableValue(std::string_view var, float &value, bool &exists); - FuncExpr *parseFunc(const char *func, - const char *attr_name, + FuncExpr *parseFunc(std::string_view func, + std::string_view attr_name, const LibertyCell *cell, int line); template void warn(int id, - const LibertyGroup *group, - std::string_view fmt, - Args &&...args) const + const LibertyGroup *group, + std::string_view fmt, + Args &&...args) const { report_->fileWarn(id, filename_, group->line(), fmt, std::forward(args)...); } template void warn(int id, - const LibertySimpleAttr *attr, - std::string_view fmt, - Args &&...args) const + const LibertySimpleAttr *attr, + std::string_view fmt, + Args &&...args) const { report_->fileWarn(id, filename_, attr->line(), fmt, std::forward(args)...); } template void warn(int id, - const LibertyComplexAttr *attr, - std::string_view fmt, - Args &&...args) const + const LibertyComplexAttr *attr, + std::string_view fmt, + Args &&...args) const { report_->fileWarn(id, filename_, attr->line(), fmt, std::forward(args)...); } template void warn(int id, - int line, - std::string_view fmt, - Args &&...args) const + int line, + std::string_view fmt, + Args &&...args) const { report_->fileWarn(id, filename_, line, fmt, std::forward(args)...); } @@ -513,7 +517,7 @@ protected: std::forward(args)...); } - const char *filename_; + std::string_view filename_; bool infer_latches_; Report *report_; Debug *debug_; @@ -547,7 +551,7 @@ class PortNameBitIterator : public Iterator { public: PortNameBitIterator(LibertyCell *cell, - const char *port_name, + std::string_view port_name, LibertyReader *visitor, int line); ~PortNameBitIterator(); @@ -558,7 +562,7 @@ public: protected: void findRangeBusNameNext(); - void init(const char *port_name); + void init(std::string_view port_name); LibertyCell *cell_; LibertyReader *visitor_; int line_; diff --git a/liberty/LibertyScanner.hh b/liberty/LibertyScanner.hh index 3623940c..bb42f4c3 100644 --- a/liberty/LibertyScanner.hh +++ b/liberty/LibertyScanner.hh @@ -24,8 +24,9 @@ #pragma once -#include #include +#include +#include #include "LibertyParse.hh" @@ -44,7 +45,7 @@ class LibertyScanner : public LibertyFlexLexer { public: LibertyScanner(std::istream *stream, - const char *filename, + std::string_view filename, LibertyParser *reader, Report *report); virtual ~LibertyScanner() {} diff --git a/liberty/LibertyWriter.cc b/liberty/LibertyWriter.cc index 5e22ce6d..a27490fb 100644 --- a/liberty/LibertyWriter.cc +++ b/liberty/LibertyWriter.cc @@ -298,11 +298,11 @@ LibertyWriter::writeCell(const LibertyCell *cell) sta::print(stream_, " is_macro_cell : true;\n"); if (cell->interfaceTiming()) sta::print(stream_, " interface_timing : true;\n"); - const char *footprint = cell->footprint(); - if (footprint) + const std::string &footprint = cell->footprint(); + if (!footprint.empty()) sta::print(stream_, " cell_footprint : \"{}\";\n", footprint); - const char *user_function_class = cell->userFunctionClass(); - if (user_function_class) + const std::string &user_function_class = cell->userFunctionClass(); + if (!user_function_class.empty()) sta::print(stream_, " user_function_class : \"{}\";\n", user_function_class); LibertyCellPortIterator port_iter(cell); diff --git a/liberty/LinearModel.cc b/liberty/LinearModel.cc index b8e6a78c..4d96138e 100644 --- a/liberty/LinearModel.cc +++ b/liberty/LinearModel.cc @@ -119,7 +119,7 @@ CheckLinearModel::checkDelay(const Pvt *, std::string CheckLinearModel::reportCheckDelay(const Pvt *, float, - const char *, + std::string_view, float, float, const MinMax *, diff --git a/liberty/TableModel.cc b/liberty/TableModel.cc index c3e8856f..09f80ee8 100644 --- a/liberty/TableModel.cc +++ b/liberty/TableModel.cc @@ -242,7 +242,7 @@ GateTableModel::reportGateDelay(const Pvt *pvt, } std::string -GateTableModel::reportTableLookup(const char *result_name, +GateTableModel::reportTableLookup(std::string_view result_name, const Pvt *pvt, const TableModel *model, float in_slew, @@ -255,7 +255,7 @@ GateTableModel::reportTableLookup(const char *result_name, findAxisValues(model, in_slew, load_cap, related_out_cap, axis_value1, axis_value2, axis_value3); const LibertyLibrary *library = cell_->libertyLibrary(); - return model->reportValue(result_name, cell_, pvt, axis_value1, nullptr, + return model->reportValue(result_name, cell_, pvt, axis_value1, {}, axis_value2, axis_value3, library->units()->timeUnit(), digits); } @@ -538,7 +538,7 @@ CheckTableModel::findValue(const Pvt *pvt, std::string CheckTableModel::reportCheckDelay(const Pvt *pvt, float from_slew, - const char *from_slew_annotation, + std::string_view from_slew_annotation, float to_slew, float related_out_cap, const MinMax *min_max, @@ -567,11 +567,11 @@ CheckTableModel::reportCheckDelay(const Pvt *pvt, } std::string -CheckTableModel::reportTableDelay(const char *result_name, +CheckTableModel::reportTableDelay(std::string_view result_name, const Pvt *pvt, const TableModel *model, float from_slew, - const char *from_slew_annotation, + std::string_view from_slew_annotation, float to_slew, float related_out_cap, int digits) const @@ -852,11 +852,11 @@ TableModel::scaleFactor(const LibertyCell *cell, } std::string -TableModel::reportValue(const char *result_name, +TableModel::reportValue(std::string_view result_name, const LibertyCell *cell, const Pvt *pvt, float value1, - const char *comment1, + std::string_view comment1, float value2, float value3, const Unit *table_unit, @@ -868,7 +868,7 @@ TableModel::reportValue(const char *result_name, result += reportPvtScaleFactor(cell, pvt, digits); - result += result_name; + result.append(result_name); result += " = "; result += table_unit->asString(findValue(cell, pvt, value1, value2, value3), digits); @@ -1255,11 +1255,11 @@ Table::findValue(const LibertyLibrary *, } std::string -Table::reportValue(const char *result_name, +Table::reportValue(std::string_view result_name, const LibertyCell *cell, const Pvt *, float value1, - const char *comment1, + std::string_view comment1, float value2, float value3, const Unit *table_unit, @@ -1283,25 +1283,24 @@ Table::reportValue(const char *result_name, } std::string -Table::reportValueOrder0(const char *result_name, - const char *comment1, +Table::reportValueOrder0(std::string_view result_name, + std::string_view comment1, const Unit *table_unit, int digits) const { - std::string result = result_name; + std::string result(result_name); result += " constant = "; result += table_unit->asString(value_, digits); - if (comment1) - result += comment1; + result.append(comment1); result += '\n'; return result; } std::string -Table::reportValueOrder1(const char *result_name, +Table::reportValueOrder1(std::string_view result_name, const LibertyCell *cell, float value1, - const char *comment1, + std::string_view comment1, float value2, float value3, const Unit *table_unit, @@ -1313,8 +1312,7 @@ Table::reportValueOrder1(const char *result_name, result += axis1_->variableString(); result += " = "; result += unit1->asString(value1, digits); - if (comment1) - result += comment1; + result.append(comment1); result += '\n'; if (axis1_->size() != 1) { size_t index1 = axis1_->findAxisIndex(value1); @@ -1330,7 +1328,7 @@ Table::reportValueOrder1(const char *result_name, result += table_unit->asString(value(index1 + 1), digits); result += '\n'; } - result += result_name; + result.append(result_name); result += " = "; result += table_unit->asString(findValue(value1, value2, value3), digits); result += '\n'; @@ -1338,10 +1336,10 @@ Table::reportValueOrder1(const char *result_name, } std::string -Table::reportValueOrder2(const char *result_name, +Table::reportValueOrder2(std::string_view result_name, const LibertyCell *cell, float value1, - const char *comment1, + std::string_view comment1, float value2, float value3, const Unit *table_unit, @@ -1354,8 +1352,7 @@ Table::reportValueOrder2(const char *result_name, result += axis1_->variableString(); result += " = "; result += unit1->asString(value1, digits); - if (comment1) - result += comment1; + result.append(comment1); result += '\n'; result += "| "; result += axis2_->variableString(); @@ -1390,7 +1387,7 @@ Table::reportValueOrder2(const char *result_name, } } result += '\n'; - result += result_name; + result.append(result_name); result += " = "; result += table_unit->asString(findValue(value1, value2, value3), digits); result += '\n'; @@ -1398,10 +1395,10 @@ Table::reportValueOrder2(const char *result_name, } std::string -Table::reportValueOrder3(const char *result_name, +Table::reportValueOrder3(std::string_view result_name, const LibertyCell *cell, float value1, - const char *comment1, + std::string_view comment1, float value2, float value3, const Unit *table_unit, @@ -1415,8 +1412,7 @@ Table::reportValueOrder3(const char *result_name, result += axis1_->variableString(); result += " = "; result += unit1->asString(value1, digits); - if (comment1) - result += comment1; + result.append(comment1); result += '\n'; result += " | ---- "; result += axis2_->variableString(); @@ -1492,7 +1488,7 @@ Table::reportValueOrder3(const char *result_name, } } result += '\n'; - result += result_name; + result.append(result_name); result += " = "; result += table_unit->asString(findValue(value1, value2, value3), digits); result += '\n'; @@ -1703,7 +1699,7 @@ TableAxis::findAxisClosestIndex(float value) const } } -const char * +std::string_view TableAxis::variableString() const { return tableVariableString(variable_); @@ -1741,12 +1737,12 @@ static EnumNameMap table_axis_variable_map = { {TableAxisVariable::normalized_voltage, "normalized_voltage"}}; TableAxisVariable -stringTableAxisVariable(const char *variable) +stringTableAxisVariable(std::string_view variable) { return table_axis_variable_map.find(variable, TableAxisVariable::unknown); } -const char * +std::string_view tableVariableString(TableAxisVariable variable) { return table_axis_variable_map.find(variable); @@ -2213,9 +2209,9 @@ OutputWaveforms::finalResistance() //////////////////////////////////////////////////////////////// -DriverWaveform::DriverWaveform(const std::string &name, +DriverWaveform::DriverWaveform(std::string name, TablePtr waveforms) : - name_(name), + name_(std::move(name)), waveforms_(waveforms) { } diff --git a/liberty/TimingArc.cc b/liberty/TimingArc.cc index 375ad68e..a254b7cd 100644 --- a/liberty/TimingArc.cc +++ b/liberty/TimingArc.cc @@ -88,34 +88,34 @@ TimingArcAttrs::setCond(FuncExpr *cond) } void -TimingArcAttrs::setSdfCond(const std::string &cond) +TimingArcAttrs::setSdfCond(std::string cond) { - sdf_cond_ = cond; + sdf_cond_ = std::move(cond); sdf_cond_start_ = sdf_cond_end_ = sdf_cond_; } void -TimingArcAttrs::setSdfCondStart(const std::string &cond) +TimingArcAttrs::setSdfCondStart(std::string cond) { - sdf_cond_start_ = cond; + sdf_cond_start_ = std::move(cond); } void -TimingArcAttrs::setSdfCondEnd(const std::string &cond) +TimingArcAttrs::setSdfCondEnd(std::string cond) { - sdf_cond_end_ = cond; + sdf_cond_end_ = std::move(cond); } void -TimingArcAttrs::setModeName(const std::string &name) +TimingArcAttrs::setModeName(std::string name) { - mode_name_ = name; + mode_name_ = std::move(name); } void -TimingArcAttrs::setModeValue(const std::string &value) +TimingArcAttrs::setModeValue(std::string value) { - mode_value_ = value; + mode_value_ = std::move(value); } TimingModel * @@ -679,7 +679,7 @@ static EnumNameMap timing_sense_name_map = {TimingSense::unknown, "unknown"} }; -const char * +const std::string & to_string(TimingSense sense) { return timing_sense_name_map.find(sense); @@ -747,14 +747,14 @@ EnumNameMap timing_type_name_map = {TimingType::unknown, "unknown"} }; -const char * +std::string_view timingTypeString(TimingType type) { return timing_type_name_map.find(type); } TimingType -findTimingType(const char *type_name) +findTimingType(std::string_view type_name) { return timing_type_name_map.find(type_name, TimingType::unknown); } diff --git a/liberty/Units.cc b/liberty/Units.cc index fb3fcdb6..6e5a4e34 100644 --- a/liberty/Units.cc +++ b/liberty/Units.cc @@ -193,21 +193,21 @@ Units::Units() : } Unit * -Units::find(const char *unit_name) +Units::find(std::string_view unit_name) { - if (stringEq(unit_name, "time")) + if (stringEqual(unit_name, "time")) return &time_unit_; - else if (stringEq(unit_name, "resistance")) + else if (stringEqual(unit_name, "resistance")) return &resistance_unit_; - else if (stringEq(unit_name, "capacitance")) + else if (stringEqual(unit_name, "capacitance")) return &capacitance_unit_; - else if (stringEq(unit_name, "voltage")) + else if (stringEqual(unit_name, "voltage")) return &voltage_unit_; - else if (stringEq(unit_name, "current")) + else if (stringEqual(unit_name, "current")) return ¤t_unit_; - else if (stringEq(unit_name, "power")) + else if (stringEqual(unit_name, "power")) return &power_unit_; - else if (stringEq(unit_name, "distance")) + else if (stringEqual(unit_name, "distance")) return &distance_unit_; else return nullptr; diff --git a/liberty/Wireload.cc b/liberty/Wireload.cc index cc88891b..1c30df10 100644 --- a/liberty/Wireload.cc +++ b/liberty/Wireload.cc @@ -31,9 +31,9 @@ namespace sta { -Wireload::Wireload(const char *name, +Wireload::Wireload(std::string name, LibertyLibrary *library) : - name_(stringCopy(name)), + name_(std::move(name)), library_(library), area_(0.0F), resistance_(0.0F), @@ -42,13 +42,13 @@ Wireload::Wireload(const char *name, { } -Wireload::Wireload(const char *name, +Wireload::Wireload(std::string name, LibertyLibrary *library, float area, float resistance, float capacitance, float slope) : - name_(stringCopy(name)), + name_(std::move(name)), library_(library), area_(area), resistance_(resistance), @@ -60,7 +60,6 @@ Wireload::Wireload(const char *name, Wireload::~Wireload() { deleteContents(fanout_lengths_); - stringDelete(name_); } void @@ -186,15 +185,14 @@ WireloadForArea::WireloadForArea(float min_area, { } -WireloadSelection::WireloadSelection(const char *name) : - name_(stringCopy(name)) +WireloadSelection::WireloadSelection(std::string name) : + name_(std::move(name)) { } WireloadSelection::~WireloadSelection() { deleteContents(wireloads_); - stringDelete(name_); } struct WireloadForAreaMinLess @@ -264,13 +262,13 @@ wireloadTreeString(WireloadTree tree) } WireloadTree -stringWireloadTree(const char *wire_load_type) +stringWireloadTree(std::string_view wire_load_type) { - if (stringEq(wire_load_type, "worst_case_tree")) + if (wire_load_type == "worst_case_tree") return WireloadTree::worst_case; - else if (stringEq(wire_load_type, "best_case_tree")) + else if (wire_load_type == "best_case_tree") return WireloadTree::best_case; - else if (stringEq(wire_load_type, "balanced_tree")) + else if (wire_load_type == "balanced_tree") return WireloadTree::balanced; else return WireloadTree::unknown; @@ -294,13 +292,13 @@ wireloadModeString(WireloadMode wire_load_mode) } WireloadMode -stringWireloadMode(const char *wire_load_mode) +stringWireloadMode(std::string_view wire_load_mode) { - if (stringEq(wire_load_mode, "top")) + if (wire_load_mode == "top") return WireloadMode::top; - else if (stringEq(wire_load_mode, "enclosed")) + else if (wire_load_mode == "enclosed") return WireloadMode::enclosed; - else if (stringEq(wire_load_mode, "segmented")) + else if (wire_load_mode == "segmented") return WireloadMode::segmented; else return WireloadMode::unknown; diff --git a/network/ConcreteLibrary.cc b/network/ConcreteLibrary.cc index 1d18d24d..74c37b15 100644 --- a/network/ConcreteLibrary.cc +++ b/network/ConcreteLibrary.cc @@ -38,12 +38,12 @@ namespace sta { static constexpr char escape_ = '\\'; -ConcreteLibrary::ConcreteLibrary(const char *name, - const char *filename, +ConcreteLibrary::ConcreteLibrary(std::string name, + std::string filename, bool is_liberty) : - name_(name), + name_(std::move(name)), id_(ConcreteNetwork::nextObjectId()), - filename_(filename ? filename : ""), + filename_(std::move(filename)), is_liberty_(is_liberty), bus_brkt_left_('['), bus_brkt_right_(']') @@ -56,9 +56,9 @@ ConcreteLibrary::~ConcreteLibrary() } ConcreteCell * -ConcreteLibrary::makeCell(const char *name, +ConcreteLibrary::makeCell(std::string_view name, bool is_leaf, - const char *filename) + std::string_view filename) { ConcreteCell *cell = new ConcreteCell(name, filename, is_leaf, this); addCell(cell); @@ -72,11 +72,9 @@ ConcreteLibrary::addCell(ConcreteCell *cell) } void -ConcreteLibrary::renameCell(ConcreteCell *cell, - const char *cell_name) +ConcreteLibrary::removeCell(ConcreteCell *cell) { cell_map_.erase(cell->name()); - cell_map_[cell_name] = cell; } void @@ -93,9 +91,9 @@ ConcreteLibrary::cellIterator() const } ConcreteCell * -ConcreteLibrary::findCell(const char *name) const +ConcreteLibrary::findCell(std::string_view name) const { - return findKey(cell_map_, name); + return findStringKey(cell_map_, name); } CellSeq @@ -119,13 +117,13 @@ ConcreteLibrary::setBusBrkts(char left, //////////////////////////////////////////////////////////////// -ConcreteCell::ConcreteCell(const char *name, - const char *filename, +ConcreteCell::ConcreteCell(std::string_view name, + std::string_view filename, bool is_leaf, ConcreteLibrary *library) : name_(name), id_(ConcreteNetwork::nextObjectId()), - filename_(filename ? filename : ""), + filename_(filename), library_(library), liberty_cell_(nullptr), ext_cell_(nullptr), @@ -140,10 +138,11 @@ ConcreteCell::~ConcreteCell() } void -ConcreteCell::setName(const char *name) +ConcreteCell::setName(std::string_view name) { - library_->renameCell(this, name); + library_->removeCell(this); name_ = name; + library_->addCell(this); } void @@ -159,18 +158,20 @@ ConcreteCell::setExtCell(void *ext_cell) } ConcretePort * -ConcreteCell::makePort(const char *name) +ConcreteCell::makePort(std::string_view name) { - ConcretePort *port = new ConcretePort(name, false, -1, -1, false, nullptr, this); + ConcretePort *port = new ConcretePort(name, false, -1, -1, + false, nullptr, this); addPort(port); return port; } ConcretePort * -ConcreteCell::makeBundlePort(const char *name, +ConcreteCell::makeBundlePort(std::string_view name, ConcretePortSeq *members) { - ConcretePort *port = new ConcretePort(name, false, -1, -1, true, members, this); + ConcretePort *port = new ConcretePort(name, false, -1, -1, true, + members, this); addPort(port); for (ConcretePort *member : *members) member->setBundlePort(port); @@ -178,19 +179,19 @@ ConcreteCell::makeBundlePort(const char *name, } ConcretePort * -ConcreteCell::makeBusPort(const char *name, +ConcreteCell::makeBusPort(std::string_view name, int from_index, int to_index) { ConcretePort *port = new ConcretePort(name, true, from_index, to_index, false, new ConcretePortSeq, this); addPort(port); - makeBusPortBits(port, name, from_index, to_index); + makeBusPortBits(port, port->name(), from_index, to_index); return port; } ConcretePort * -ConcreteCell::makeBusPort(const char *name, +ConcreteCell::makeBusPort(std::string_view name, int from_index, int to_index, ConcretePortSeq *members) @@ -203,40 +204,42 @@ ConcreteCell::makeBusPort(const char *name, void ConcreteCell::makeBusPortBits(ConcretePort *bus_port, - const char *name, + std::string_view bus_name, int from_index, int to_index) { if (from_index < to_index) { for (int index = from_index; index <= to_index; index++) - makeBusPortBit(bus_port, name, index); + makeBusPortBit(bus_port, bus_name, index); } else { for (int index = from_index; index >= to_index; index--) - makeBusPortBit(bus_port, name, index); + makeBusPortBit(bus_port, bus_name, index); } } void ConcreteCell::makeBusPortBit(ConcretePort *bus_port, - const char *bus_name, + std::string_view bus_name, int bit_index) { - std::string bit_name = std::string(bus_name) - + library_->busBrktLeft() - + std::to_string(bit_index) - + library_->busBrktRight(); - ConcretePort *port = makePort(bit_name.c_str(), bit_index); + std::string bit_name; + bit_name.append(bus_name); + bit_name += library_->busBrktLeft(); + bit_name += std::to_string(bit_index); + bit_name += library_->busBrktRight(); + ConcretePort *port = makePort(bit_name, bit_index); bus_port->addPortBit(port); addPortBit(port); } ConcretePort * -ConcreteCell::makePort(const char *bit_name, +ConcreteCell::makePort(std::string bit_name, int bit_index) { - ConcretePort *port = new ConcretePort(bit_name, false, bit_index, - bit_index, false, nullptr, this); + ConcretePort *port = new ConcretePort(bit_name, false, + bit_index, bit_index, false, + nullptr, this); addPortBit(port); return port; } @@ -264,14 +267,14 @@ ConcreteCell::setIsLeaf(bool is_leaf) } void -ConcreteCell::setAttribute(const std::string &key, - const std::string &value) +ConcreteCell::setAttribute(std::string_view key, + std::string_view value) { - attribute_map_[key] = value; + attribute_map_[std::string(key)] = value; } std::string -ConcreteCell::getAttribute(const std::string &key) const +ConcreteCell::getAttribute(std::string_view key) const { const auto &itr = attribute_map_.find(key); if (itr != attribute_map_.end()) @@ -280,9 +283,9 @@ ConcreteCell::getAttribute(const std::string &key) const } ConcretePort * -ConcreteCell::findPort(const char *name) const +ConcreteCell::findPort(std::string_view name) const { - return findKey(port_map_, name); + return findStringKey(port_map_, name); } size_t @@ -350,7 +353,7 @@ BusPort::addBusBit(ConcretePort *port, void ConcreteCell::groupBusPorts(const char bus_brkt_left, const char bus_brkt_right, - std::function port_msb_first) + std::function port_msb_first) { const char bus_brkts_left[2]{bus_brkt_left, '\0'}; const char bus_brkts_right[2]{bus_brkt_right, '\0'}; @@ -362,11 +365,10 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left, ConcretePortSeq ports = ports_; ports_.clear(); for (ConcretePort *port : ports) { - const char *port_name = port->name(); bool is_bus; std::string bus_name; int index; - parseBusName(port_name, bus_brkts_left, bus_brkts_right, escape_, + parseBusName(port->name(), bus_brkts_left, bus_brkts_right, escape_, is_bus, bus_name, index); if (is_bus) { if (!port->isBusBit()) { @@ -385,7 +387,7 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left, int from = bus_port.from(); int to = bus_port.to(); size_t size = to - from + 1; - bool msb_first = port_msb_first(bus_name.c_str()); + bool msb_first = port_msb_first(bus_name); ConcretePortSeq *members = new ConcretePortSeq(size); // Index the bus bit ports. for (ConcretePort *bus_bit : bus_port.members()) { @@ -395,14 +397,14 @@ ConcreteCell::groupBusPorts(const char bus_brkt_left, } if (msb_first) std::swap(from, to); - ConcretePort *port = makeBusPort(bus_name.c_str(), from, to, members); + ConcretePort *port = makeBusPort(bus_name, from, to, members); port->setDirection(bus_port.direction()); } } //////////////////////////////////////////////////////////////// -ConcretePort::ConcretePort(const char *name, +ConcretePort::ConcretePort(std::string_view name, bool is_bus, int from_index, int to_index, @@ -458,18 +460,17 @@ ConcretePort::setExtPort(void *port) ext_port_ = port; } -const char * +std::string ConcretePort::busName() const { if (is_bus_) { ConcreteLibrary *lib = cell_->library(); - std::string bus_name = sta::format("{}{}{}:{}{}", - name(), - lib->busBrktLeft(), - from_index_, - to_index_, - lib->busBrktRight()); - return makeTmpString(bus_name); + return sta::format("{}{}{}:{}{}", + name(), + lib->busBrktLeft(), + from_index_, + to_index_, + lib->busBrktRight()); } else return name(); diff --git a/network/ConcreteNetwork.cc b/network/ConcreteNetwork.cc index 6291d5bc..44cc8a0a 100644 --- a/network/ConcreteNetwork.cc +++ b/network/ConcreteNetwork.cc @@ -25,6 +25,7 @@ #include "ConcreteNetwork.hh" #include +#include #include "PatternMatch.hh" #include "Report.hh" @@ -424,19 +425,21 @@ ConcreteNetwork::libertyLibraryIterator() const //////////////////////////////////////////////////////////////// Library * -ConcreteNetwork::makeLibrary(const char *name, - const char *filename) +ConcreteNetwork::makeLibrary(std::string_view name, + std::string_view filename) { - ConcreteLibrary *library = new ConcreteLibrary(name, filename, false); + ConcreteLibrary *library = new ConcreteLibrary(std::string(name), + std::string(filename), false); addLibrary(library); return reinterpret_cast(library); } LibertyLibrary * -ConcreteNetwork::makeLibertyLibrary(const char *name, - const char *filename) +ConcreteNetwork::makeLibertyLibrary(std::string_view name, + std::string_view filename) { - LibertyLibrary *library = new LibertyLibrary(name, filename); + LibertyLibrary *library = new LibertyLibrary(std::string(name), + std::string(filename)); addLibrary(library); return library; } @@ -449,9 +452,9 @@ ConcreteNetwork::addLibrary(ConcreteLibrary *library) } Library * -ConcreteNetwork::findLibrary(const char *name) +ConcreteNetwork::findLibrary(std::string_view name) { - return reinterpret_cast(findKey(library_map_, name)); + return reinterpret_cast(findStringKey(library_map_, name)); } void @@ -463,7 +466,7 @@ ConcreteNetwork::deleteLibrary(Library *library) delete clib; } -const char * +std::string ConcreteNetwork::name(const Library *library) const { const ConcreteLibrary *clib = @@ -480,16 +483,16 @@ ConcreteNetwork::id(const Library *library) const } LibertyLibrary * -ConcreteNetwork::findLiberty(const char *name) +ConcreteNetwork::findLiberty(std::string_view name) { - ConcreteLibrary *lib = findKey(library_map_, name); + ConcreteLibrary *lib = findStringKey(library_map_, name); if (lib) { if (lib->isLiberty()) return static_cast(lib); // Potential name conflict else { for (ConcreteLibrary *lib : library_seq_) { - if (stringEq(lib->name(), name) + if (lib->name() == name && lib->isLiberty()) return static_cast(lib); } @@ -500,9 +503,9 @@ ConcreteNetwork::findLiberty(const char *name) Cell * ConcreteNetwork::makeCell(Library *library, - const char *name, + std::string_view name, bool is_leaf, - const char *filename) + std::string_view filename) { ConcreteLibrary *clib = reinterpret_cast(library); return reinterpret_cast(clib->makeCell(name, is_leaf, filename)); @@ -510,7 +513,7 @@ ConcreteNetwork::makeCell(Library *library, Cell * ConcreteNetwork::findCell(const Library *library, - const char *name) const + std::string_view name) const { const ConcreteLibrary *clib = reinterpret_cast(library); @@ -518,7 +521,7 @@ ConcreteNetwork::findCell(const Library *library, } Cell * -ConcreteNetwork::findAnyCell(const char *name) +ConcreteNetwork::findAnyCell(std::string_view name) { for (ConcreteLibrary *lib : library_seq_) { ConcreteCell *cell = lib->findCell(name); @@ -547,7 +550,7 @@ ConcreteNetwork::deleteCell(Cell *cell) //////////////////////////////////////////////////////////////// -const char * +std::string ConcreteNetwork::name(const Cell *cell) const { const ConcreteCell *ccell = reinterpret_cast(cell); @@ -563,7 +566,7 @@ ConcreteNetwork::id(const Cell *cell) const void ConcreteNetwork::setName(Cell *cell, - const char *name) + std::string_view name) { ConcreteCell *ccell = reinterpret_cast(cell); ccell->setName(name); @@ -579,8 +582,8 @@ ConcreteNetwork::setIsLeaf(Cell *cell, void ConcreteNetwork::setAttribute(Cell *cell, - const std::string &key, - const std::string &value) + std::string_view key, + std::string_view value) { ConcreteCell *ccell = reinterpret_cast(cell); ccell->setAttribute(key, value); @@ -619,8 +622,8 @@ ConcreteNetwork::cell(const LibertyCell *cell) const return reinterpret_cast(cell); } -const char * -ConcreteNetwork::filename(const Cell *cell) +std::string_view +ConcreteNetwork::filename(const Cell *cell) const { const ConcreteCell *ccell = reinterpret_cast(cell); return ccell->filename(); @@ -628,7 +631,7 @@ ConcreteNetwork::filename(const Cell *cell) std::string ConcreteNetwork::getAttribute(const Cell *cell, - const std::string &key) const + std::string_view key) const { const ConcreteCell *ccell = reinterpret_cast(cell); return ccell->getAttribute(key); @@ -643,7 +646,7 @@ ConcreteNetwork::attributeMap(const Cell *cell) const Port * ConcreteNetwork::findPort(const Cell *cell, - const char *name) const + std::string_view name) const { const ConcreteCell *ccell = reinterpret_cast(cell); return reinterpret_cast(ccell->findPort(name)); @@ -658,7 +661,7 @@ ConcreteNetwork::isLeaf(const Cell *cell) const Port * ConcreteNetwork::makePort(Cell *cell, - const char *name) + std::string_view name) { ConcreteCell *ccell = reinterpret_cast(cell); ConcretePort *port = ccell->makePort(name); @@ -667,7 +670,7 @@ ConcreteNetwork::makePort(Cell *cell, Port * ConcreteNetwork::makeBusPort(Cell *cell, - const char *name, + std::string_view name, int from_index, int to_index) { @@ -678,7 +681,7 @@ ConcreteNetwork::makeBusPort(Cell *cell, void ConcreteNetwork::groupBusPorts(Cell *cell, - std::function port_msb_first) + std::function port_msb_first) { Library *lib = library(cell); ConcreteLibrary *clib = reinterpret_cast(lib); @@ -689,7 +692,7 @@ ConcreteNetwork::groupBusPorts(Cell *cell, Port * ConcreteNetwork::makeBundlePort(Cell *cell, - const char *name, + std::string_view name, PortSeq *members) { ConcreteCell *ccell = reinterpret_cast(cell); @@ -795,7 +798,7 @@ ConcreteNetwork::portBitCount(const Cell *cell) const //////////////////////////////////////////////////////////////// -const char * +std::string ConcreteNetwork::name(const Port *port) const { const ConcretePort *cport = reinterpret_cast(port); @@ -844,7 +847,7 @@ ConcreteNetwork::isBus(const Port *port) const return cport->isBus(); } -const char * +std::string ConcreteNetwork::busName(const Port *port) const { const ConcretePort *cport = reinterpret_cast(port); @@ -949,12 +952,12 @@ ConcreteNetwork::memberIterator(const Port *port) const //////////////////////////////////////////////////////////////// -const char * +std::string ConcreteNetwork::name(const Instance *instance) const { const ConcreteInstance *inst = reinterpret_cast(instance); - return inst->name(); + return std::string(inst->name()); } ObjectId @@ -967,7 +970,7 @@ ConcreteNetwork::id(const Instance *instance) const std::string ConcreteNetwork::getAttribute(const Instance *inst, - const std::string &key) const + std::string_view key) const { const ConcreteInstance *cinst = reinterpret_cast(inst); return cinst->getAttribute(key); @@ -1007,7 +1010,7 @@ ConcreteNetwork::isLeaf(const Instance *instance) const Instance * ConcreteNetwork::findChild(const Instance *parent, - const char *name) const + std::string_view name) const { const ConcreteInstance *inst = reinterpret_cast(parent); @@ -1016,7 +1019,7 @@ ConcreteNetwork::findChild(const Instance *parent, Pin * ConcreteNetwork::findPin(const Instance *instance, - const char *port_name) const + std::string_view port_name) const { const ConcreteInstance *inst = reinterpret_cast(instance); @@ -1034,7 +1037,7 @@ ConcreteNetwork::findPin(const Instance *instance, Net * ConcreteNetwork::findNet(const Instance *instance, - const char *net_name) const + std::string_view net_name) const { const ConcreteInstance *inst = reinterpret_cast(instance); @@ -1164,11 +1167,11 @@ ConcreteNetwork::pin(const Term *term) const //////////////////////////////////////////////////////////////// -const char * +std::string ConcreteNetwork::name(const Net *net) const { const ConcreteNet *cnet = reinterpret_cast(net); - return cnet->name(); + return std::string(cnet->name()); } ObjectId @@ -1238,7 +1241,7 @@ ConcreteInstance::cell() const Instance * ConcreteNetwork::makeInstance(Cell *cell, - const char *name, + std::string_view name, Instance *parent) { ConcreteCell *ccell = reinterpret_cast(cell); @@ -1247,7 +1250,7 @@ ConcreteNetwork::makeInstance(Cell *cell, Instance * ConcreteNetwork::makeInstance(LibertyCell *cell, - const char *name, + std::string_view name, Instance *parent) { return makeConcreteInstance(cell, name, parent); @@ -1255,7 +1258,7 @@ ConcreteNetwork::makeInstance(LibertyCell *cell, Instance * ConcreteNetwork::makeConcreteInstance(ConcreteCell *cell, - const char *name, + std::string_view name, Instance *parent) { ConcreteInstance *cparent = @@ -1387,8 +1390,8 @@ ConcreteNetwork::connect(Instance *inst, void ConcreteNetwork::setAttribute(Instance *inst, - const std::string &key, - const std::string &value) + std::string_view key, + std::string_view value) { ConcreteInstance *cinst = reinterpret_cast(inst); cinst->setAttribute(key, value); @@ -1509,7 +1512,7 @@ ConcreteNetwork::deletePin(Pin *pin) } Net * -ConcreteNetwork::makeNet(const char *name, +ConcreteNetwork::makeNet(std::string_view name, Instance *parent) { ConcreteInstance *cparent = reinterpret_cast(parent); @@ -1608,10 +1611,10 @@ ConcreteNetwork::visitConnectedPins(const Net *net, //////////////////////////////////////////////////////////////// -ConcreteInstance::ConcreteInstance(const char *name, +ConcreteInstance::ConcreteInstance(std::string_view name, ConcreteCell *cell, ConcreteInstance *parent) : - name_(stringCopy(name)), + name_(name), id_(ConcreteNetwork::nextObjectId()), cell_(cell), parent_(parent), @@ -1630,22 +1633,21 @@ ConcreteInstance::initPins() ConcreteInstance::~ConcreteInstance() { - stringDelete(name_); delete children_; delete nets_; } Instance * -ConcreteInstance::findChild(const char *name) const +ConcreteInstance::findChild(std::string_view name) const { if (children_) - return reinterpret_cast(findKey(children_, name)); + return reinterpret_cast(findStringKey(*children_, name)); else return nullptr; } ConcretePin * -ConcreteInstance::findPin(const char *port_name) const +ConcreteInstance::findPin(std::string_view port_name) const { ConcreteCell *ccell = reinterpret_cast(cell_); const ConcretePort *cport = @@ -1669,11 +1671,11 @@ ConcreteInstance::findPin(const Port *port) const } ConcreteNet * -ConcreteInstance::findNet(const char *net_name) const +ConcreteInstance::findNet(std::string_view net_name) const { ConcreteNet *net = nullptr; if (nets_) { - net = findKey(nets_, net_name); + net = findStringKey(*nets_, net_name); // Follow merge pointer to surviving net. if (net) { while (net->mergedInto()) @@ -1716,14 +1718,14 @@ ConcreteInstance::childIterator() const } void -ConcreteInstance::setAttribute(const std::string &key, - const std::string &value) +ConcreteInstance::setAttribute(std::string_view key, + std::string_view value) { - attribute_map_[key] = value; + attribute_map_[std::string(key)] = value; } std::string -ConcreteInstance::getAttribute(const std::string &key) const +ConcreteInstance::getAttribute(std::string_view key) const { const auto &itr = attribute_map_.find(key); if (itr != attribute_map_.end()) @@ -1736,13 +1738,13 @@ ConcreteInstance::addChild(ConcreteInstance *child) { if (children_ == nullptr) children_ = new ConcreteInstanceChildMap; - (*children_)[child->name()] = child; + (*children_)[child->name().data()] = child; } void ConcreteInstance::deleteChild(ConcreteInstance *child) { - children_->erase(child->name()); + children_->erase(child->name().data()); } void @@ -1767,22 +1769,22 @@ ConcreteInstance::addNet(ConcreteNet *net) { if (nets_ == nullptr) nets_ = new ConcreteInstanceNetMap; - (*nets_)[net->name()] = net; + (*nets_)[net->name().data()] = net; } void -ConcreteInstance::addNet(const char *name, +ConcreteInstance::addNet(std::string_view, ConcreteNet *net) { if (nets_ == nullptr) nets_ = new ConcreteInstanceNetMap; - (*nets_)[name] = net; + (*nets_)[net->name().data()] = net; } void ConcreteInstance::deleteNet(ConcreteNet *net) { - nets_->erase(net->name()); + nets_->erase(net->name().data()); } void @@ -1807,7 +1809,7 @@ ConcretePin::ConcretePin(ConcreteInstance *instance, { } -const char * +std::string_view ConcretePin::name() const { return port_->name(); @@ -1821,7 +1823,7 @@ ConcretePin::setVertexId(VertexId id) //////////////////////////////////////////////////////////////// -const char * +std::string_view ConcreteTerm::name() const { ConcretePin *cpin = reinterpret_cast(pin_); @@ -1841,9 +1843,9 @@ ConcreteTerm::ConcreteTerm(ConcretePin *pin, //////////////////////////////////////////////////////////////// -ConcreteNet::ConcreteNet(const char *name, +ConcreteNet::ConcreteNet(std::string_view name, ConcreteInstance *instance) : - name_(stringCopy(name)), + name_(name), id_(ConcreteNetwork::nextObjectId()), instance_(instance), pins_(nullptr), @@ -1852,11 +1854,6 @@ ConcreteNet::ConcreteNet(const char *name, { } -ConcreteNet::~ConcreteNet() -{ - stringDelete(name_); -} - // Merged nets are kept around to serve as name aliases. // Only Instance::findNet and InstanceNetIterator need to know // the net has been merged. @@ -1990,14 +1987,15 @@ ConcreteNetwork::setLinkFunc(LinkNetworkFunc link) } bool -ConcreteNetwork::linkNetwork(const char *top_cell_name, +ConcreteNetwork::linkNetwork(std::string_view top_cell_name, bool make_black_boxes, Report *report) { if (link_func_) { clearConstantNets(); deleteTopInstance(); - top_instance_ = link_func_(top_cell_name, make_black_boxes); + top_instance_ = link_func_(top_cell_name, + make_black_boxes); if (top_instance_) checkNetworkLibertyScenes(); return top_instance_ != nullptr; diff --git a/network/Network.cc b/network/Network.cc index b0a7d635..ca1f085d 100644 --- a/network/Network.cc +++ b/network/Network.cc @@ -25,6 +25,7 @@ #include "Network.hh" +#include #include #include "ContainerHelpers.hh" @@ -79,7 +80,7 @@ Network::findPortsMatching(const Cell *cell, parseBusName(pattern->pattern(), '[', ']', '\\', is_bus, is_range, bus_name, from, to, subscript_wild); if (is_bus) { - PatternMatch bus_pattern(bus_name.c_str(), pattern); + PatternMatch bus_pattern(bus_name, pattern); CellPortIterator *port_iter = portIterator(cell); while (port_iter->hasNext()) { Port *port = port_iter->next(); @@ -138,7 +139,7 @@ Network::readLibertyAfter(LibertyLibrary *) } LibertyCell * -Network::findLibertyCell(const char *name) const +Network::findLibertyCell(std::string_view name) const { LibertyLibraryIterator *iter = libertyLibraryIterator(); while (iter->hasNext()) { @@ -207,12 +208,12 @@ Network::checkNetworkLibertyScenes() } LibertyLibrary * -Network::findLibertyFilename(const char *filename) +Network::findLibertyFilename(std::string_view filename) { LibertyLibraryIterator *lib_iter = libertyLibraryIterator(); while (lib_iter->hasNext()) { LibertyLibrary *lib = lib_iter->next(); - if (stringEq(lib->filename(), filename)) { + if (lib->filename() == filename) { delete lib_iter; return lib; } @@ -257,7 +258,7 @@ Network::hasMembers(const Port *port) const return isBus(port) || isBundle(port); } -const char * +std::string Network::pathName(const Instance *instance) const { InstanceSeq inst_path; @@ -270,7 +271,7 @@ Network::pathName(const Instance *instance) const if (!inst_path.empty()) path_name += pathDivider(); } - return makeTmpString(path_name); + return path_name; } bool @@ -298,9 +299,9 @@ Network::pathNameCmp(const Instance *inst1, while (!path1.empty() && !path2.empty()) { const Instance *inst1 = path1.back(); const Instance *inst2 = path2.back(); - int cmp = strcmp(name(inst1), name(inst2)); + auto cmp = name(inst1) <=> name(inst2); if (cmp != 0) - return cmp; + return cmp < 0 ? -1 : 1; path1.pop_back(); path2.pop_back(); } @@ -350,27 +351,27 @@ Network::isHierarchical(const Instance *instance) const //////////////////////////////////////////////////////////////// -const char * +std::string Network::name(const Pin *pin) const { return pathName(pin); } -const char * +std::string Network::portName(const Pin *pin) const { return name(port(pin)); } -const char * +std::string Network::pathName(const Pin *pin) const { const Instance *inst = instance(pin); if (inst && inst != topInstance()) { - std::string path_name = pathName(inst); + std::string path_name(pathName(inst)); path_name += pathDivider(); path_name += portName(pin); - return makeTmpString(path_name); + return path_name; } else return portName(pin); @@ -388,8 +389,14 @@ Network::pathNameCmp(const Pin *pin1, const Pin *pin2) const { int inst_cmp = pathNameCmp(instance(pin1), instance(pin2)); - if (inst_cmp == 0) - return strcmp(portName(pin1), portName(pin2)); + if (inst_cmp == 0) { + auto cmp = portName(pin1) <=> portName(pin2); + if (cmp < 0) + return -1; + if (cmp > 0) + return 1; + return 0; + } else return inst_cmp; } @@ -442,18 +449,18 @@ Network::pinLess(const Pin *pin1, //////////////////////////////////////////////////////////////// -const char * +std::string Network::pathName(const Net *net) const { const Instance *inst = instance(net); if (inst && inst != topInstance()) { - std::string path_name = pathName(inst); + std::string path_name(pathName(inst)); path_name += pathDivider(); path_name += name(net); - return makeTmpString(path_name); + return path_name; } else - return name(net); + return std::string(name(net)); } bool @@ -468,8 +475,14 @@ Network::pathNameCmp(const Net *net1, const Net *net2) const { int inst_cmp = pathNameCmp(instance(net1), instance(net2)); - if (inst_cmp == 0) - return strcmp(name(net1), name(net2)); + if (inst_cmp == 0) { + auto cmp = name(net1) <=> name(net2); + if (cmp < 0) + return -1; + if (cmp > 0) + return 1; + return 0; + } else return inst_cmp; } @@ -506,7 +519,7 @@ Network::highestConnectedNet(Net *net) const int level = hierarchyLevel(net1); if (level < highest_level || (level == highest_level - && stringLess(pathName(net1), pathName(highest_net)))) { + && pathName(net1) < pathName(highest_net))) { highest_net = net1; highest_level = level; } @@ -632,19 +645,19 @@ Network::isLatchData(const Pin *pin) const //////////////////////////////////////////////////////////////// -const char * +std::string Network::name(const Term *term) const { return name(pin(term)); } -const char * +std::string Network::pathName(const Term *term) const { return pathName(pin(term)); } -const char * +std::string Network::portName(const Term *term) const { return portName(pin(term)); @@ -652,40 +665,35 @@ Network::portName(const Term *term) const //////////////////////////////////////////////////////////////// -const char * +std::string Network::cellName(const Instance *inst) const { return name(cell(inst)); } Instance * -Network::findInstance(const char *path_name) const +Network::findInstance(std::string_view path_name) const { return findInstanceRelative(topInstance(), path_name); } Instance * Network::findInstanceRelative(const Instance *inst, - const char *path_name) const + std::string_view path_name) const { - char *first, *tail; + std::string first, tail; pathNameFirst(path_name, first, tail); - if (first) { + if (!first.empty()) { Instance *inst1 = findChild(inst, first); - stringDelete(first); - while (inst1 && tail) { - char *next_tail; + while (inst1 && !tail.empty()) { + std::string next_tail; pathNameFirst(tail, first, next_tail); - if (first) { + if (!first.empty()) inst1 = findChild(inst1, first); - stringDelete(first); - } else inst1 = findChild(inst1, tail); - stringDelete(tail); tail = next_tail; } - stringDelete(tail); return inst1; } else @@ -701,7 +709,7 @@ Network::findInstancesMatching(const Instance *context, size_t context_name_length = 0; if (context != topInstance()) // Add one for the trailing divider. - context_name_length = strlen(pathName(context)) + 1; + context_name_length = pathName(context).size() + 1; findInstancesMatching1(context, context_name_length, pattern, matches); } else { @@ -721,9 +729,10 @@ Network::findInstancesMatching1(const Instance *context, InstanceChildIterator *child_iter = childIterator(context); while (child_iter->hasNext()) { Instance *child = child_iter->next(); - const char *child_name = pathName(child); + std::string child_name = pathName(child); // Remove context prefix from the name. - const char *child_context_name = &child_name[context_name_length]; + std::string_view child_context_name = + std::string_view(child_name).substr(context_name_length); if (pattern->match(child_context_name)) matches.push_back(child); if (!isLeaf(child)) @@ -779,27 +788,22 @@ Network::findChildrenMatching(const Instance *parent, } Pin * -Network::findPin(const char *path_name) const +Network::findPin(std::string_view path_name) const { return findPinRelative(topInstance(), path_name); } Pin * Network::findPinRelative(const Instance *inst, - const char *path_name) const + std::string_view path_name) const { - char *inst_path, *port_name; - pathNameLast(path_name, inst_path, port_name); - if (inst_path) { + std::string inst_path, port_name; + std::string path_storage(path_name); + pathNameLast(path_storage, inst_path, port_name); + if (!inst_path.empty()) { Instance *pin_inst = findInstanceRelative(inst, inst_path); - if (pin_inst) { - Pin *pin = findPin(pin_inst, port_name); - stringDelete(inst_path); - stringDelete(port_name); - return pin; - } - stringDelete(inst_path); - stringDelete(port_name); + if (pin_inst) + return findPin(pin_inst, port_name); return nullptr; } else @@ -809,12 +813,12 @@ Network::findPinRelative(const Instance *inst, Pin * Network::findPinLinear(const Instance *instance, - const char *port_name) const + std::string_view port_name) const { InstancePinIterator *pin_iter = pinIterator(instance); while (pin_iter->hasNext()) { Pin *pin = pin_iter->next(); - if (stringEq(port_name, portName(pin))) { + if (port_name == portName(pin)) { delete pin_iter; return pin; } @@ -838,27 +842,22 @@ Network::findPin(const Instance *instance, } Net * -Network::findNet(const char *path_name) const +Network::findNet(std::string_view path_name) const { return findNetRelative(topInstance(), path_name); } Net * Network::findNetRelative(const Instance *inst, - const char *path_name) const + std::string_view path_name) const { - char *inst_path, *net_name; - pathNameLast(path_name, inst_path, net_name); - if (inst_path) { + std::string inst_path, net_name; + std::string path_storage(path_name); + pathNameLast(path_storage, inst_path, net_name); + if (!inst_path.empty()) { Instance *net_inst = findInstanceRelative(inst, inst_path); - if (net_inst) { - Net *net = findNet(net_inst, net_name); - stringDelete(inst_path); - stringDelete(net_name); - return net; - } - stringDelete(inst_path); - stringDelete(net_name); + if (net_inst) + return findNet(net_inst, net_name); return nullptr; } else @@ -868,12 +867,12 @@ Network::findNetRelative(const Instance *inst, Net * Network::findNetLinear(const Instance *instance, - const char *net_name) const + std::string_view net_name) const { InstanceNetIterator *net_iter = netIterator(instance); while (net_iter->hasNext()) { Net *net = net_iter->next(); - if (stringEq(name(net), net_name)) { + if (name(net) == net_name) { delete net_iter; return net; } @@ -897,16 +896,14 @@ Network::findNetsMatching(const Instance *context, NetSeq &matches) const { if (pattern->hasWildcards()) { - char *inst_path, *net_name; + std::string inst_path, net_name; pathNameLast(pattern->pattern(), inst_path, net_name); - if (inst_path) { + if (!inst_path.empty()) { PatternMatch inst_pattern(inst_path, pattern); PatternMatch net_pattern(net_name, pattern); InstanceSeq insts = findInstancesMatching(context, &inst_pattern); for (const Instance *inst : insts) findNetsMatching(inst, &net_pattern, matches); - stringDelete(inst_path); - stringDelete(net_name); } else // Top level net. @@ -963,16 +960,14 @@ Network::findPinsMatching(const Instance *instance, { PinSeq matches; if (pattern->hasWildcards()) { - char *inst_path, *port_name; + std::string inst_path, port_name; pathNameLast(pattern->pattern(), inst_path, port_name); - if (inst_path) { + if (!inst_path.empty()) { PatternMatch inst_pattern(inst_path, pattern); PatternMatch port_pattern(port_name, pattern); InstanceSeq insts = findInstancesMatching(instance, &inst_pattern); for (const Instance *inst : insts) findInstPinsMatching(inst, &port_pattern, matches); - stringDelete(inst_path); - stringDelete(port_name); } else // Top level pin. @@ -1016,13 +1011,13 @@ Network::findInstPinsHierMatching(const Instance *instance, // Return value. PinSeq &matches) const { - std::string inst_name = name(instance); + std::string inst_name(name(instance)); InstancePinIterator *pin_iter = pinIterator(instance); while (pin_iter->hasNext()) { const Pin *pin = pin_iter->next(); - const char *port_name = name(port(pin)); - std::string pin_name = inst_name + divider_ + port_name; - if (pattern->match(pin_name.c_str())) + std::string port_name = name(port(pin)); + std::string pin_name = inst_name + divider_ + std::string(port_name); + if (pattern->match(pin_name)) matches.push_back(pin); } delete pin_iter; @@ -1601,64 +1596,54 @@ Network::drivers(const Net *net) //////////////////////////////////////////////////////////////// void -Network::pathNameFirst(const char *path_name, - char *&first, - char *&tail) const +Network::pathNameFirst(std::string_view path_name, + std::string &first, + std::string &tail) const { + first.clear(); + tail.clear(); + char escape = pathEscape(); char divider = pathDivider(); - const char *d = strchr(path_name, divider); - // Skip escaped dividers. - while (d != nullptr - && d > path_name - && d[-1] == escape) - d = strchr(d + 1, divider); - if (d) { - first = new char[d - path_name + 1]; - strncpy(first, path_name, d - path_name); - first[d - path_name] = '\0'; - - tail = new char[strlen(d)]; - // Chop off the leading divider. - strcpy(tail, d + 1); - } - else { - // No divider in path_name. - first = nullptr; - tail = nullptr; + size_t i = 0; + while (i < path_name.size()) { + size_t d = path_name.find(divider, i); + while (d != std::string_view::npos && d > 0 + && path_name[d - 1] == escape) + d = path_name.find(divider, d + 1); + if (d != std::string_view::npos) { + first = path_name.substr(0, d); + tail = path_name.substr(d + 1); + return; + } + break; } } void -Network::pathNameLast(const char *path_name, - char *&head, - char *&last) const +Network::pathNameLast(std::string_view path_name, + std::string &head, + std::string &last) const { + head.clear(); + last.clear(); + char escape = pathEscape(); char divider = pathDivider(); - const char *d = strrchr(path_name, divider); - // Search for a non-escaped divider. - if (d) { - while (d > path_name - && (d[0] != divider - || (d[0] == divider - && d > &path_name[1] - && d[-1] == escape))) - d--; - } - if (d && d != path_name) { - head = new char[d - path_name + 1]; - strncpy(head, path_name, d - path_name); - head[d - path_name] = '\0'; - last = new char[strlen(d)]; - // Chop off the last divider. - strcpy(last, d + 1); - } - else { - // No divider in path_name. - head = nullptr; - last = nullptr; + size_t div_pos = path_name.rfind(divider); + size_t path_end = path_name.size(); + while (div_pos > 0) { + if (div_pos == std::string_view::npos) + return; + if (path_name[div_pos - 1] != escape) { + // Found the last non-escaped divider. + head = path_name.substr(0, div_pos); + last = path_name.substr(div_pos + 1); + return; + } + path_end = div_pos - 1; + div_pos = path_name.rfind(divider, path_end); } } diff --git a/network/Network.i b/network/Network.i index c07f6de8..6af7c8a3 100644 --- a/network/Network.i +++ b/network/Network.i @@ -24,8 +24,12 @@ %module network +%include + %{ #include "Network.hh" +#include "StringUtil.hh" +#include %} //////////////////////////////////////////////////////////////// @@ -252,12 +256,12 @@ find_cells_matching(const char *pattern, } void -set_cmd_namespace_cmd(const char *namespc) +set_cmd_namespace_cmd(std::string namespc) { Sta *sta = Sta::sta(); - if (stringEq(namespc, "sdc")) + if (namespc == "sdc") sta->setCmdNamespace(CmdNamespace::sdc); - else if (stringEq(namespc, "sta")) + else if (namespc == "sta") sta->setCmdNamespace(CmdNamespace::sta); else sta->report()->warn(2120, "unknown namespace"); @@ -284,16 +288,16 @@ leaf_instance_iterator() return network->leafInstanceIterator(); } -const char * +std::string_view port_direction(const Port *port) { return Sta::sta()->ensureLinked()->direction(port)->name(); } -const char * +std::string pin_direction(const Pin *pin) { - return Sta::sta()->ensureLinked()->direction(pin)->name(); + return std::string(Sta::sta()->ensureLinked()->direction(pin)->name()); } PortSeq @@ -542,7 +546,7 @@ port_location(const Port *port) //////////////////////////////////////////////////////////////// %extend Library { -const char *name() +std::string name() { return Sta::sta()->ensureLinked()->name(self); } @@ -574,13 +578,13 @@ void finish() { delete self; } } // LibraryIterator methods %extend Cell { -const char *name() { return Sta::sta()->cmdNetwork()->name(self); } +std::string name() { return Sta::sta()->cmdNetwork()->name(self); } Library *library() { return Sta::sta()->cmdNetwork()->library(self); } LibertyCell *liberty_cell() { return Sta::sta()->cmdNetwork()->libertyCell(self); } bool is_leaf() { return Sta::sta()->cmdNetwork()->isLeaf(self); } CellPortIterator * port_iterator() { return Sta::sta()->cmdNetwork()->portIterator(self); } -std::string +std::string get_attribute(const char *key) { return Sta::sta()->cmdNetwork()->getAttribute(self, key); @@ -612,7 +616,7 @@ void finish() { delete self; } } // CellPortIterator methods %extend Port { -const char *bus_name() { return Sta::sta()->ensureLinked()->busName(self); } +std::string bus_name() { return Sta::sta()->ensureLinked()->busName(self); } Cell *cell() { return Sta::sta()->ensureLinked()->cell(self); } LibertyPort *liberty_port() { return Sta::sta()->ensureLibLinked()->libertyPort(self); } bool is_bus() { return Sta::sta()->ensureLinked()->isBus(self); } @@ -678,7 +682,7 @@ void finish() { delete self; } } // InstanceNetIterator methods %extend Pin { -const char *port_name() { return Sta::sta()->ensureLinked()->portName(self); } +std::string port_name() { return Sta::sta()->ensureLinked()->portName(self); } Instance *instance() { return Sta::sta()->ensureLinked()->instance(self); } Net *net() { return Sta::sta()->ensureLinked()->net(self); } Port *port() { return Sta::sta()->ensureLinked()->port(self); } diff --git a/network/NetworkCmp.cc b/network/NetworkCmp.cc index 7dbc9511..cda43af7 100644 --- a/network/NetworkCmp.cc +++ b/network/NetworkCmp.cc @@ -41,7 +41,7 @@ bool PortNameLess::operator()(const Port *port1, const Port *port2) const { - return stringLess(network_->name(port1), network_->name(port2)); + return network_->name(port1) < network_->name(port2); } PinPathNameLess::PinPathNameLess(const Network *network) : diff --git a/network/SdcNetwork.cc b/network/SdcNetwork.cc index 4cdef63e..e36b0acd 100644 --- a/network/SdcNetwork.cc +++ b/network/SdcNetwork.cc @@ -30,13 +30,6 @@ namespace sta { -static std::string -escapeDividers(const char *token, - const Network *network); -static std::string -escapeBrackets(const char *token, - const Network *network); - NetworkNameAdapter::NetworkNameAdapter(Network *network) : NetworkEdit(), network_(network), @@ -45,7 +38,7 @@ NetworkNameAdapter::NetworkNameAdapter(Network *network) : } bool -NetworkNameAdapter::linkNetwork(const char *top_cell_name, +NetworkNameAdapter::linkNetwork(std::string_view top_cell_name, bool make_black_boxes, Report *report) { @@ -77,24 +70,24 @@ NetworkNameAdapter::libertyLibraryIterator() const } Library * -NetworkNameAdapter::findLibrary(const char *name) +NetworkNameAdapter::findLibrary(std::string_view name) { return network_->findLibrary(name); } LibertyLibrary * -NetworkNameAdapter::findLiberty(const char *name) +NetworkNameAdapter::findLiberty(std::string_view name) { return network_->findLiberty(name); } LibertyLibrary * -NetworkNameAdapter::findLibertyFilename(const char *filename) +NetworkNameAdapter::findLibertyFilename(std::string_view filename) { return network_->findLibertyFilename(filename); } -const char * +std::string NetworkNameAdapter::name(const Library *library) const { return network_->name(library); @@ -108,7 +101,7 @@ NetworkNameAdapter::id(const Library *library) const Cell * NetworkNameAdapter::findCell(const Library *library, - const char *name) const + std::string_view name) const { return network_->findCell(library, name); } @@ -122,7 +115,7 @@ NetworkNameAdapter::findCellsMatching(const Library *library, //////////////////////////////////////////////////////////////// -const char * +std::string NetworkNameAdapter::name(const Cell *cell) const { return network_->name(cell); @@ -136,7 +129,7 @@ NetworkNameAdapter::id(const Cell *cell) const std::string NetworkNameAdapter::getAttribute(const Cell *cell, - const std::string &key) const + std::string_view key) const { return network_->getAttribute(cell, key); } @@ -153,8 +146,8 @@ NetworkNameAdapter::library(const Cell *cell) const return network_->library(cell); } -const char * -NetworkNameAdapter::filename(const Cell *cell) +std::string_view +NetworkNameAdapter::filename(const Cell *cell) const { return network_->filename(cell); } @@ -185,7 +178,7 @@ NetworkNameAdapter::cell(const LibertyCell *cell) const Port * NetworkNameAdapter::findPort(const Cell *cell, - const char *name) const + std::string_view name) const { return network_->findPort(cell, name); } @@ -223,7 +216,7 @@ NetworkNameAdapter::portBitCount(const Cell *cell) const //////////////////////////////////////////////////////////////// -const char * +std::string NetworkNameAdapter::name(const Port *port) const { return network_->name(port); @@ -288,7 +281,7 @@ NetworkNameAdapter::isBus(const Port *port) const return network_->isBus(port); } -const char * +std::string NetworkNameAdapter::busName(const Port *port) const { return network_->busName(port); @@ -354,7 +347,7 @@ NetworkNameAdapter::cell(const Instance *instance) const std::string NetworkNameAdapter::getAttribute(const Instance *inst, - const std::string &key) const + std::string_view key) const { return network_->getAttribute(inst, key); } @@ -537,15 +530,15 @@ NetworkNameAdapter::isEditable() const LibertyLibrary * -NetworkNameAdapter::makeLibertyLibrary(const char *name, - const char *filename) +NetworkNameAdapter::makeLibertyLibrary(std::string_view name, + std::string_view filename) { return network_edit_->makeLibertyLibrary(name, filename); } Instance * NetworkNameAdapter::makeInstance(LibertyCell *cell, - const char *name, + std::string_view name, Instance *parent) { return network_edit_->makeInstance(cell, name, parent); @@ -571,7 +564,7 @@ NetworkNameAdapter::mergedInto(Net *net) } Net * -NetworkNameAdapter::makeNet(const char *name, +NetworkNameAdapter::makeNet(std::string_view name, Instance *parent) { return network_edit_->makeNet(name, parent); @@ -639,7 +632,7 @@ SdcNetwork::SdcNetwork(Network *network) : // Translate sta namespace to sdc namespace. // Remove all escapes. -const char * +std::string SdcNetwork::staToSdc(std::string_view sta_name) const { char escape = pathEscape(); @@ -660,12 +653,12 @@ SdcNetwork::staToSdc(std::string_view sta_name) const // Non escape. sdc_name += ch; } - return makeTmpString(sdc_name); + return sdc_name; } Port * SdcNetwork::findPort(const Cell *cell, - const char *name) const + std::string_view name) const { Port *port = network_->findPort(cell, name); if (port == nullptr) { @@ -675,22 +668,22 @@ SdcNetwork::findPort(const Cell *cell, int index; parseBusName(name, '[', ']', pathEscape(), is_bus, bus_name, index); if (is_bus) { - std::string escaped1 = escapeBrackets(name, this); - port = network_->findPort(cell, escaped1.c_str()); + std::string escaped1 = escapeBrackets(std::string(name), this); + port = network_->findPort(cell, escaped1); if (port == nullptr) { // Try escaping base foo\[0\][1] - std::string escaped_bus_name = escapeBrackets(bus_name.c_str(), this); + std::string escaped_bus_name = escapeBrackets(bus_name, this); std::string escaped2 = escaped_bus_name + '[' + std::to_string(index) + ']'; - port = network_->findPort(cell, escaped2.c_str()); + port = network_->findPort(cell, escaped2); } } else { // Try escaping brackets foo\[0\].bar - std::string escaped = escapeBrackets(name, this); - port = network_->findPort(cell, escaped.c_str()); + std::string escaped = escapeBrackets(std::string(name), this); + port = network_->findPort(cell, escaped); } } return port; @@ -710,71 +703,71 @@ SdcNetwork::findPortsMatching(const Cell *cell, is_bus, bus_name, index); if (is_bus) { std::string escaped1 = escapeBrackets(pattern->pattern(), this); - PatternMatch escaped_pattern1(escaped1.c_str(), pattern); + PatternMatch escaped_pattern1(escaped1, pattern); matches = network_->findPortsMatching(cell, &escaped_pattern1); if (matches.empty()) { // Try escaping base foo\[0\][1] - std::string escaped_name = escapeBrackets(bus_name.c_str(), this); + std::string escaped_name = escapeBrackets(bus_name, this); escaped_name += '['; escaped_name += std::to_string(index); escaped_name += ']'; - PatternMatch escaped_pattern2(escaped_name.c_str(), pattern); + PatternMatch escaped_pattern2(escaped_name, pattern); matches = network_->findPortsMatching(cell, &escaped_pattern2); } } else { // Try escaping brackets foo\[0\].bar std::string escaped = escapeBrackets(pattern->pattern(), this); - PatternMatch escaped_pattern(escaped.c_str(), pattern); + PatternMatch escaped_pattern(escaped, pattern); matches = network_->findPortsMatching(cell, &escaped_pattern); } } return matches; } -const char * +std::string SdcNetwork::name(const Port *port) const { return staToSdc(network_->name(port)); } -const char * +std::string SdcNetwork::busName(const Port *port) const { return staToSdc(network_->busName(port)); } -const char * +std::string SdcNetwork::name(const Instance *instance) const { return staToSdc(network_->name(instance)); } -const char * +std::string SdcNetwork::pathName(const Instance *instance) const { return staToSdc(network_->pathName(instance)); } -const char * +std::string SdcNetwork::pathName(const Pin *pin) const { return staToSdc(network_->pathName(pin)); } -const char * +std::string SdcNetwork::portName(const Pin *pin) const { return staToSdc(network_->portName(pin)); } -const char * +std::string SdcNetwork::name(const Net *net) const { return staToSdc(network_->name(net)); } -const char * +std::string SdcNetwork::pathName(const Net *net) const { return staToSdc(network_->pathName(net)); @@ -783,9 +776,9 @@ SdcNetwork::pathName(const Net *net) const //////////////////////////////////////////////////////////////// Instance * -SdcNetwork::findInstance(const char *path_name) const +SdcNetwork::findInstance(std::string_view path_name) const { - const char *child_name; + std::string child_name; Instance *parent; parsePath(path_name, parent, child_name); if (parent == nullptr) @@ -793,22 +786,22 @@ SdcNetwork::findInstance(const char *path_name) const Instance *child = findChild(parent, child_name); if (child == nullptr) { std::string escaped_name = escapeDividers(child_name, this); - child = findChild(parent, escaped_name.c_str()); + child = findChild(parent, escaped_name); } return child; } Instance * SdcNetwork::findInstanceRelative(const Instance *inst, - const char *path_name) const + std::string_view path_name) const { Instance *inst1 = network_->findInstanceRelative(inst, path_name); if (inst1 == nullptr) { - std::string path_name1 = escapeBrackets(path_name, this); - inst1 = network_->findInstanceRelative(inst, path_name1.c_str()); + std::string path_name1 = escapeBrackets(std::string(path_name), this); + inst1 = network_->findInstanceRelative(inst, path_name1); if (inst1 == nullptr) { - std::string path_name2 = escapeDividers(path_name1.c_str(), network_); - inst1 = network_->findInstanceRelative(inst, path_name2.c_str()); + std::string path_name2 = escapeDividers(path_name1, network_); + inst1 = network_->findInstanceRelative(inst, path_name2); } } return inst1; @@ -840,12 +833,12 @@ SdcNetwork::findInstancesMatching1(const Instance *context, Instance * SdcNetwork::findChild(const Instance *parent, - const char *name) const + std::string_view name) const { Instance *child = network_->findChild(parent, name); if (child == nullptr) { - std::string escaped = escapeBrackets(name, this); - child = network_->findChild(parent, escaped.c_str()); + std::string escaped = escapeBrackets(std::string(name), this); + child = network_->findChild(parent, escaped); } return child; } @@ -853,9 +846,9 @@ SdcNetwork::findChild(const Instance *parent, //////////////////////////////////////////////////////////////// Net * -SdcNetwork::findNet(const char *path_name) const +SdcNetwork::findNet(std::string_view path_name) const { - const char *net_name; + std::string net_name; Instance *inst; parsePath(path_name, inst, net_name); if (inst == nullptr) @@ -865,33 +858,33 @@ SdcNetwork::findNet(const char *path_name) const Net * SdcNetwork::findNet(const Instance *instance, - const char *net_name) const + std::string_view net_name) const { Net *net = network_->findNet(instance, net_name); if (net == nullptr) { - std::string net_name1 = escapeBrackets(net_name, this); - std::string net_name2 = escapeDividers(net_name1.c_str(), network_); - net = network_->findNet(instance, net_name2.c_str()); + std::string net_name1 = escapeBrackets(std::string(net_name), this); + std::string net_name2 = escapeDividers(net_name1, network_); + net = network_->findNet(instance, net_name2); } return net; } Net * SdcNetwork::findNetRelative(const Instance *inst, - const char *path_name) const + std::string_view path_name) const { Net *net = network_->findNetRelative(inst, path_name); if (net == nullptr) { - std::string path_name1 = escapeDividers(path_name, network_); - net = network_->findNetRelative(inst, path_name1.c_str()); + std::string path_name1 = escapeDividers(std::string(path_name), network_); + net = network_->findNetRelative(inst, path_name1); if (net == nullptr) { - std::string path_name2 = escapeBrackets(path_name, network_); - net = network_->findNetRelative(inst, path_name2.c_str()); + std::string path_name2 = escapeBrackets(std::string(path_name), network_); + net = network_->findNetRelative(inst, path_name2); if (net == nullptr) { - std::string path_name3 = escapeDividers(path_name2.c_str(), network_); - net = network_->findNetRelative(inst, path_name3.c_str()); + std::string path_name3 = escapeDividers(path_name2, network_); + net = network_->findNetRelative(inst, path_name3); } } } @@ -923,12 +916,12 @@ SdcNetwork::findInstNetsMatching(const Instance *instance, if (matches.empty()) { // Look for matches after escaping path dividers. std::string escaped_pattern = escapeDividers(pattern->pattern(), this); - const PatternMatch escaped_dividers(escaped_pattern.c_str(), pattern); + const PatternMatch escaped_dividers(escaped_pattern, pattern); network_->findInstNetsMatching(instance, &escaped_dividers, matches); if (matches.empty()) { // Look for matches after escaping brackets. std::string escaped_pattern2 = escapeBrackets(pattern->pattern(),this); - const PatternMatch escaped_brkts(escaped_pattern2.c_str(), pattern); + const PatternMatch escaped_brkts(escaped_pattern2, pattern); network_->findInstNetsMatching(instance, &escaped_brkts, matches); } } @@ -937,9 +930,9 @@ SdcNetwork::findInstNetsMatching(const Instance *instance, //////////////////////////////////////////////////////////////// Pin * -SdcNetwork::findPin(const char *path_name) const +SdcNetwork::findPin(std::string_view path_name) const { - const char *port_name; + std::string port_name; Instance *inst; parsePath(path_name, inst, port_name); if (inst == nullptr) @@ -949,7 +942,7 @@ SdcNetwork::findPin(const char *path_name) const Pin * SdcNetwork::findPin(const Instance *instance, - const char *port_name) const + std::string_view port_name) const { Pin *pin = network_->findPin(instance, port_name); if (pin == nullptr) { @@ -960,22 +953,22 @@ SdcNetwork::findPin(const Instance *instance, parseBusName(port_name, '[', ']', pathEscape(), is_bus, bus_name, index); if (is_bus) { - std::string escaped1 = escapeBrackets(port_name, this); - pin = network_->findPin(instance, escaped1.c_str()); + std::string escaped1 = escapeBrackets(std::string(port_name), this); + pin = network_->findPin(instance, escaped1); if (pin == nullptr) { // Try escaping base foo\[0\][1] - std::string escaped_bus_name = escapeBrackets(bus_name.c_str(), this); + std::string escaped_bus_name = escapeBrackets(bus_name, this); std::string escaped2 = escaped_bus_name + '[' + std::to_string(index) + ']'; - pin = network_->findPin(instance, escaped2.c_str()); + pin = network_->findPin(instance, escaped2); } } else { // Try escaping port brackets foo\[0\].bar - std::string escaped = escapeBrackets(port_name, this); - pin = network_->findPin(instance, escaped.c_str()); + std::string escaped = escapeBrackets(std::string(port_name), this); + pin = network_->findPin(instance, escaped); } } return pin; @@ -987,7 +980,7 @@ SdcNetwork::findPinsMatching(const Instance *instance, const PatternMatch *pattern) const { PinSeq matches; - if (stringEq(pattern->pattern(), "*")) { + if (pattern->pattern() == "*") { // Pattern of '*' matches all child instance pins. InstanceChildIterator *child_iter = childIterator(instance); while (child_iter->hasNext()) { @@ -1022,11 +1015,12 @@ SdcNetwork::visitPinTail(const Instance *instance, CellPortIterator *port_iter = network_->portIterator(cell); while (port_iter->hasNext()) { Port *port = port_iter->next(); - const char *port_name = network_->name(port); + std::string port_name = network_->name(port); if (network_->hasMembers(port)) { bool bus_matches = tail->match(port_name); if (!bus_matches) { - std::string escaped_name = escapeDividers(port_name, network_); + std::string escaped_name = escapeDividers(std::string(port_name), + network_); bus_matches = tail->match(escaped_name); } PortMemberIterator *member_iter = network_->memberIterator(port); @@ -1039,10 +1033,11 @@ SdcNetwork::visitPinTail(const Instance *instance, found_match = true; } else { - const char *member_name = network_->name(member_port); + std::string member_name = network_->name(member_port); bool member_matches = tail->match(member_name); if (!member_matches) { - std::string escaped_name = escapeDividers(member_name, network_); + std::string escaped_name = escapeDividers(std::string(member_name), + network_); member_matches = tail->match(escaped_name); } if (member_matches) { @@ -1057,7 +1052,8 @@ SdcNetwork::visitPinTail(const Instance *instance, else { bool port_matches = tail->match(port_name); if (!port_matches) { - std::string escaped_name = escapeDividers(port_name, network_); + std::string escaped_name = escapeDividers(std::string(port_name), + network_); port_matches = tail->match(escaped_name); } if (port_matches) { @@ -1076,19 +1072,19 @@ SdcNetwork::visitPinTail(const Instance *instance, Instance * SdcNetwork::makeInstance(LibertyCell *cell, - const char *name, + std::string_view name, Instance *parent) { - std::string escaped_name = escapeDividers(name, this); - return network_edit_->makeInstance(cell, escaped_name.c_str(), parent); + std::string escaped_name = escapeDividers(std::string(name), this); + return network_edit_->makeInstance(cell, escaped_name, parent); } Net * -SdcNetwork::makeNet(const char *name, +SdcNetwork::makeNet(std::string_view name, Instance *parent) { - std::string escaped_name = escapeDividers(name, this); - return network_edit_->makeNet(escaped_name.c_str(), parent); + std::string escaped_name = escapeDividers(std::string(name), this); + return network_edit_->makeNet(escaped_name, parent); } //////////////////////////////////////////////////////////////// @@ -1101,10 +1097,10 @@ SdcNetwork::makeNet(const char *name, // a\/b // a\/b\/c void -SdcNetwork::parsePath(const char *path, +SdcNetwork::parsePath(std::string_view path, // Return values. Instance *&inst, - const char *&path_tail) const + std::string &path_tail) const { int divider_count, path_length; scanPath(path, divider_count, path_length); @@ -1118,7 +1114,7 @@ SdcNetwork::parsePath(const char *path, // Scan the path for unescaped dividers. void -SdcNetwork::scanPath(const char *path, +SdcNetwork::scanPath(std::string_view path, // Return values. // Unescaped divider count. int ÷r_count, @@ -1126,12 +1122,12 @@ SdcNetwork::scanPath(const char *path, { divider_count = 0; path_length = 0; - for (const char *s = path; *s; s++) { - char ch = *s; + for (size_t i = 0; i < path.size(); i++) { + char ch = path[i]; if (ch == escape_) { // Make sure we don't skip the null if escape is the last char. - if (s[1] != '\0') { - s++; + if (i != path.size() - 1) { + i++; path_length++; } } @@ -1142,37 +1138,37 @@ SdcNetwork::scanPath(const char *path, } void -SdcNetwork::parsePath(const char *path, +SdcNetwork::parsePath(std::string_view path, int divider_count, int path_length, // Return values. Instance *&inst, - const char *&path_tail) const + std::string &path_tail) const { Instance *parent = topInstance(); std::string inst_path; - // Leave room to escape all the dividers and '\0'. - inst_path.reserve(path_length + divider_count + 1); + // Leave room to escape all the dividers. + inst_path.reserve(path_length + divider_count); inst = nullptr; path_tail = path; - for (const char *s = path; *s; s++) { - char ch = *s; + for (size_t i = 0; i < path.size(); i++) { + char ch = path[i]; if (ch == escape_) { // Make sure we don't skip the null if escape is the last char. - if (s[1] != '\0') { + if (i < path.size() - 1) { inst_path += ch; - inst_path += s[1]; - s++; + inst_path += path[i + 1]; + i++; } } else if (ch == divider_) { - Instance *child = findChild(parent, inst_path.c_str()); + Instance *child = findChild(parent, inst_path); if (child) { // Found an instance for the sub-path up to this divider. parent = inst = child; // Reset the instance path. inst_path.clear(); - path_tail = s + 1; + path_tail = path.substr(i + 1); } else { // No match for sub-path. Escape the divider and keep looking. @@ -1206,29 +1202,30 @@ SdcNetwork::visitMatches(const Instance *parent, inst_path.reserve(path_length + divider_count + 1); bool has_brkts = false; bool found_match = false; - for (const char *s = pattern->pattern(); *s; s++) { - char ch = *s; + const std::string &pattern_str = pattern->pattern(); + for (size_t i = 0; i < pattern_str.size(); i++) { + char ch = pattern_str[i]; if (ch == escape_) { // Make sure we don't skip the null if escape is the last char. - if (s[1] != '\0') { + if (i < pattern_str.size() - 1) { inst_path += ch; - inst_path += s[1]; - s++; + inst_path += pattern_str[i + 1]; + i++; } } else if (ch == divider_) { - PatternMatch matcher(inst_path.c_str(), pattern); + PatternMatch matcher(inst_path, pattern); InstanceSeq matches; network_->findChildrenMatching(parent, &matcher, matches); if (has_brkts && matches.empty()) { // Look for matches after escaping brackets. - std::string escaped_brkts = escapeBrackets(inst_path.c_str(), this); + std::string escaped_brkts = escapeBrackets(inst_path, this); const PatternMatch escaped_pattern(escaped_brkts, pattern); network_->findChildrenMatching(parent, &escaped_pattern, matches); } if (!matches.empty()) { // Found instance matches for the sub-path up to this divider. - const PatternMatch tail_pattern(s + 1, pattern); + const PatternMatch tail_pattern(pattern_str.substr(i + 1), pattern); for (const Instance *match : matches) // Recurse to save the iterator state so we can iterate over // multiple nested partial matches. @@ -1245,11 +1242,11 @@ SdcNetwork::visitMatches(const Instance *parent, } } if (!found_match) { - PatternMatch tail_pattern(inst_path.c_str(), pattern); + PatternMatch tail_pattern(inst_path, pattern); found_match |= visit_tail(parent, &tail_pattern); if (!found_match && has_brkts) { // Look for matches after escaping brackets. - std::string escaped_path = escapeBrackets(inst_path.c_str(), this); + std::string escaped_path = escapeBrackets(inst_path, this); const PatternMatch escaped_tail(escaped_path, pattern); found_match |= visit_tail(parent, &escaped_tail); } @@ -1259,19 +1256,19 @@ SdcNetwork::visitMatches(const Instance *parent, //////////////////////////////////////////////////////////////// -static std::string -escapeDividers(const char *token, +std::string +escapeDividers(std::string_view name, const Network *network) { - return escapeChars(token, network->pathDivider(), '\0', + return escapeChars(name, network->pathDivider(), '\0', network->pathEscape()); } -static std::string -escapeBrackets(const char *token, +std::string +escapeBrackets(std::string_view name, const Network *network) { - return escapeChars(token, '[', ']', network->pathEscape()); + return escapeChars(name, '[', ']', network->pathEscape()); } } // namespace diff --git a/network/VerilogNamespace.cc b/network/VerilogNamespace.cc index 702ca6d2..b12d9c3a 100644 --- a/network/VerilogNamespace.cc +++ b/network/VerilogNamespace.cc @@ -58,9 +58,9 @@ netVerilogName(std::string sta_name) bool is_bus; std::string bus_name; int index; - parseBusName(sta_name.c_str(), '[', ']', verilog_escape, is_bus, bus_name, index); + parseBusName(sta_name, '[', ']', verilog_escape, is_bus, bus_name, index); if (is_bus) { - std::string bus_vname = staToVerilog(bus_name.c_str()); + std::string bus_vname = staToVerilog(bus_name); std::string vname = bus_vname + '[' + std::to_string(index) + ']'; return vname; } diff --git a/parasitics/ConcreteParasitics.cc b/parasitics/ConcreteParasitics.cc index e85036ee..d85b4fa6 100644 --- a/parasitics/ConcreteParasitics.cc +++ b/parasitics/ConcreteParasitics.cc @@ -406,14 +406,14 @@ ConcreteParasiticNode::incrCapacitance(float cap) cap_ += cap; } -const char * +std::string ConcreteParasiticNode::name(const Network *network) const { if (is_net_) { std::string name = std::string(network->pathName(net_pin_.net_)) + ':' + std::to_string(id_); - return makeTmpString(name); + return name; } else return network->pathName(net_pin_.pin_); @@ -1312,7 +1312,7 @@ ConcreteParasitics::capacitors(const Parasitic *parasitic) const } -const char * +std::string ConcreteParasitics::name(const ParasiticNode *node) const { const ConcreteParasiticNode *cnode = diff --git a/parasitics/ConcreteParasitics.hh b/parasitics/ConcreteParasitics.hh index f033ae35..a6486736 100644 --- a/parasitics/ConcreteParasitics.hh +++ b/parasitics/ConcreteParasitics.hh @@ -24,9 +24,10 @@ #pragma once -#include #include #include +#include +#include #include "MinMax.hh" #include "Parasitics.hh" @@ -143,7 +144,7 @@ public: ParasiticNodeSeq nodes(const Parasitic *parasitic) const override; void incrCap(ParasiticNode *node, float cap) override; - const char *name(const ParasiticNode *node) const override; + std::string name(const ParasiticNode *node) const override; const Pin *pin(const ParasiticNode *node) const override; const Net *net(const ParasiticNode *node, const Network *network) const override; diff --git a/parasitics/ConcreteParasiticsPvt.hh b/parasitics/ConcreteParasiticsPvt.hh index ef363cab..168926de 100644 --- a/parasitics/ConcreteParasiticsPvt.hh +++ b/parasitics/ConcreteParasiticsPvt.hh @@ -26,6 +26,7 @@ #include #include +#include #include "Parasitics.hh" @@ -272,7 +273,7 @@ public: ConcreteParasiticNode(const Pin *pin, bool is_external); float capacitance() const { return cap_; } - const char *name(const Network *network) const; + std::string name(const Network *network) const; const Net *net(const Network *network) const; unsigned id() const { return id_; } bool isExternal() const { return is_external_; } diff --git a/parasitics/SpefLex.ll b/parasitics/SpefLex.ll index bf7bbdde..58975b84 100644 --- a/parasitics/SpefLex.ll +++ b/parasitics/SpefLex.ll @@ -163,7 +163,7 @@ INDEX "*"{POS_INTEGER} "\"" { BEGIN INITIAL; - yylval->string = sta::stringCopy(token_.c_str()); + yylval->emplace(std::move(token_)); return token::QSTRING; } @@ -179,27 +179,27 @@ INDEX "*"{POS_INTEGER} {BLANK}*\n { loc->lines(); loc->step(); } {INTEGER} { - yylval->integer = atoi(yytext); + yylval->emplace(atoi(yytext)); return token::INTEGER; } {FLOAT} { - yylval->number = static_cast(atof(yytext)); + yylval->emplace(static_cast(atof(yytext))); return token::FLOAT; } {IDENT} { - yylval->string = reader_->translated(yytext); + yylval->emplace(reader_->translated(yytext)); return token::IDENT; } {PATH}|{NAME_PAIR} { - yylval->string = reader_->translated(yytext); + yylval->emplace(reader_->translated(yytext)); return token::NAME; } {INDEX} { - yylval->string = sta::stringCopy(yytext); + yylval->emplace(yytext); return token::INDEX; } diff --git a/parasitics/SpefNamespace.cc b/parasitics/SpefNamespace.cc index 2822875c..4a1d7063 100644 --- a/parasitics/SpefNamespace.cc +++ b/parasitics/SpefNamespace.cc @@ -26,97 +26,92 @@ #include #include +#include namespace sta { -char * -spefToSta(const char *token, +std::string +spefToSta(std::string_view spef_name, char spef_divider, char path_divider, char path_escape) { const char spef_escape = '\\'; - char *trans_token = new char[strlen(token) + 1]; - char *t = trans_token; - - for (const char *s = token; *s ; s++) { - char ch = *s; + std::string sta_name; + for (size_t i = 0; i < spef_name.size(); i++) { + char ch = spef_name[i]; if (ch == spef_escape) { - char next_ch = s[1]; + char next_ch = spef_name[i + 1]; if (next_ch == spef_divider) { // Translate spef escape to network escape. - *t++ = path_escape; + sta_name += path_escape; // Translate spef divider to network divider. - *t++ = path_divider; + sta_name += path_divider; } else if (next_ch == '[' || next_ch == ']' || next_ch == spef_escape) { // Translate spef escape to network escape. - *t++ = path_escape; - *t++ = next_ch; + sta_name += path_escape; + sta_name += next_ch; } else // No need to escape other characters. - *t++ = next_ch; - s++; + sta_name += next_ch; + i++; } else if (ch == spef_divider) // Translate spef divider to network divider. - *t++ = path_divider; + sta_name += path_divider; else // Just the normal noises. - *t++ = ch; + sta_name += ch; } - *t++ = '\0'; - return trans_token; + return sta_name; } -char * -staToSpef(const char *token, +std::string +staToSpef(std::string_view sta_name, char spef_divider, char path_divider, char path_escape) { const char spef_escape = '\\'; - char *trans_token = new char[strlen(token) + 1]; - char *t = trans_token; - - for (const char *s = token; *s ; s++) { - char ch = *s; + std::string spef_name; + for (size_t i = 0; i < sta_name.size(); i++) { + char ch = sta_name[i]; if (ch == path_escape) { - char next_ch = s[1]; + char next_ch = sta_name[i + 1]; if (next_ch == path_divider) { // Translate network escape to spef escape. - *t++ = spef_escape; + spef_name += spef_escape; // Translate network divider to spef divider. - *t++ = spef_divider; + spef_name += spef_divider; } else if (next_ch == '[' || next_ch == ']') { // Translate network escape to spef escape. - *t++ = spef_escape; - *t++ = next_ch; + spef_name += spef_escape; + spef_name += next_ch; } else // No need to escape other characters. - *t++ = next_ch; - s++; + spef_name += next_ch; + i++; } else if (ch == path_divider) // Translate network divider to spef divider. - *t++ = spef_divider; + spef_name += spef_divider; else if (!(isdigit(ch) || isalpha(ch) || ch == '_')) { // Escape non-alphanum characters. - *t++ = spef_escape; - *t++ = ch; + spef_name += spef_escape; + spef_name += ch; } else // Just the normal noises. - *t++ = ch; + spef_name += ch; } - *t++ = '\0'; - return trans_token; + return spef_name; } } // namespace diff --git a/parasitics/SpefNamespace.hh b/parasitics/SpefNamespace.hh index 042019f4..4ec55f29 100644 --- a/parasitics/SpefNamespace.hh +++ b/parasitics/SpefNamespace.hh @@ -24,18 +24,22 @@ #pragma once +#include + namespace sta { // Translate from spf/spef namespace to sta namespace. -// Caller owns the result string. -char * -spefToSta(const char *token, char spef_divider, - char path_escape, char path_divider); -// Translate from sta namespace to spf/spef namespace. -// Caller owns the result string. -char * -staToSpef(const char *token, char spef_divider, - char path_divider, char path_escape); +std::string +spefToSta(std::string_view spef_name, + char spef_divider, + char path_divider, + char path_escape); +// Translate from sta namespace to spf/spef namespace. +std::string +staToSpef(std::string_view sta_name, + char spef_divider, + char path_divider, + char path_escape); } // namespace diff --git a/parasitics/SpefParse.yy b/parasitics/SpefParse.yy index a88e2d26..e527d781 100755 --- a/parasitics/SpefParse.yy +++ b/parasitics/SpefParse.yy @@ -23,11 +23,11 @@ // This notice may not be removed or altered from any source distribution. %{ -#include +#include +#include #include "Report.hh" #include "StringUtil.hh" -#include "StringUtil.hh" #include "parasitics/SpefReaderPvt.hh" #include "parasitics/SpefScanner.hh" @@ -41,10 +41,19 @@ void sta::SpefParse::error(const location_type &loc, const std::string &msg) { - reader->report()->fileError(1670,reader->filename(), loc.begin. line, "{}", msg); + reader->report()->fileError(1670, reader->filename(), loc.begin.line, "{}", msg); } %} +%code requires { +#include + +namespace sta { +// Bison's C++ variant skeleton cannot use void as a semantic type. +struct SpefParseVoid {}; +} +} + %require "3.2" %skeleton "lalr1.cc" %debug @@ -55,19 +64,11 @@ sta::SpefParse::error(const location_type &loc, %parse-param { SpefScanner *scanner } %parse-param { SpefReader *reader } %define api.parser.class {SpefParse} +%define api.value.type variant -%union { - char ch; - char *string; - int integer; - float number; - sta::StringSeq *std_string_seq; - sta::PortDirection *port_dir; - sta::SpefRspfPi *pi; - sta::SpefTriple *triple; - sta::Pin *pin; - sta::Net *net; -} +%token INTEGER +%token FLOAT +%token QSTRING INDEX IDENT NAME %token SPEF DESIGN DATE VENDOR PROGRAM DESIGN_FLOW %token PVERSION DIVIDER DELIMITER @@ -78,48 +79,42 @@ sta::SpefParse::error(const location_type &loc, %token CONN CAP RES INDUC KW_P KW_I KW_N DRIVER CELL C2_R1_C1 LOADS %token RC KW_Q KW_K -%token INTEGER FLOAT QSTRING INDEX IDENT NAME +%type conf cap_id res_id induc_id cap_elem cap_elems +%type res_elem res_elems induc_elem induc_elems +%type pos_integer -%type INTEGER -%type FLOAT -%type QSTRING INDEX IDENT NAME +%type number pos_number threshold +%type real_component imaginary_component pole poles +%type residue residues complex_par_value cnumber -%type conf cap_id res_id induc_id cap_elem cap_elems -%type res_elem res_elems induc_elem induc_elems -%type pos_integer +%nterm name_map_entries name_map_entry net_names +%nterm net_name port_entries port_entry pport_entries pport_entry +%nterm pport_name pexternal_connection -%type number pos_number threshold -%type real_component imaginary_component pole poles -%type residue residues complex_par_value cnumber +%type name_or_index inst_name +%type mapped_item +%type physical_inst port_name pport +%type entity external_connection +%type cell_type +%type driver_cell pnet_ref +%type internal_pdspf_node +%type parasitic_node internal_parasitic_node -%type name_or_index net_name net_names inst_name -%type name_map_entries name_map_entry mapped_item -%type physical_inst port_name pport_name port_entry pport_entry -%type port_entries pport_entries pport -%type entity external_connection -%type cell_type -%type driver_cell pnet_ref -%type pexternal_connection internal_pdspf_node -%type parasitic_node internal_parasitic_node +%type hchar suffix_bus_delim prefix_bus_delim -%type hchar suffix_bus_delim prefix_bus_delim +%type qstrings +%type direction -%type qstrings -%type direction +%type par_value total_cap -%type par_value total_cap +%type pi_model -%type pi_model +%type pin_name driver_pair internal_connection -%type pin_name driver_pair internal_connection - -%type net +%type net %start file -%{ -%} - %% file: @@ -184,32 +179,26 @@ header_def: spef_version: SPEF QSTRING - { sta::stringDelete($2); } ; design_name: DESIGN QSTRING - { sta::stringDelete($2); } ; date: DATE QSTRING - { sta::stringDelete($2); } ; program_name: PROGRAM QSTRING - { sta::stringDelete($2); } ; program_version: PVERSION QSTRING - { sta::stringDelete($2); } ; vendor: VENDOR QSTRING - { sta::stringDelete($2); } ; design_flow: @@ -220,12 +209,11 @@ design_flow: qstrings: QSTRING { $$ = new sta::StringSeq; - $$->push_back($1); - sta::stringDelete($1); + $$->push_back(std::move($1)); } | qstrings QSTRING - { $$->push_back($2); - sta::stringDelete($2); + { $$ = $1; + $$->push_back(std::move($2)); } ; @@ -322,7 +310,7 @@ net_names: net_name: name_or_index - { sta::stringDelete($1); } + { $$ = sta::SpefParseVoid{}; } ; /****************************************************************/ @@ -345,14 +333,12 @@ port_entries: port_entry: port_name direction conn_attrs - { sta::stringDelete($1); } + { $$ = sta::SpefParseVoid{}; } ; direction: IDENT - { $$ = reader->portDirection($1); - sta::stringDelete($1); - } + { $$ = reader->portDirection($1); } ; port_name: @@ -374,15 +360,14 @@ pport_entries: pport_entry: pport_name IDENT conn_attrs + { $$ = sta::SpefParseVoid{}; } ; pport_name: name_or_index - { sta::stringDelete($1); } + { $$ = sta::SpefParseVoid{}; } | physical_inst ':' pport - { sta::stringDelete($1); - sta::stringDelete($3); - } + { $$ = sta::SpefParseVoid{}; } ; pport: @@ -441,7 +426,6 @@ threshold: driving_cell: KW_D cell_type - { sta::stringDelete($2); } ; cell_type: @@ -458,18 +442,8 @@ define_def: define_entry: DEFINE inst_name entity - { sta::stringDelete($2); - sta::stringDelete($3); - } | DEFINE inst_name inst_name entity - { sta::stringDelete($2); - sta::stringDelete($3); - sta::stringDelete($4); - } | PDEFINE physical_inst entity - { sta::stringDelete($2); - sta::stringDelete($3); - } ; entity: @@ -501,9 +475,7 @@ d_net: net: name_or_index - { $$ = reader->findNet($1); - sta::stringDelete($1); - } + { $$ = reader->findNet($1); } ; total_cap: @@ -538,11 +510,9 @@ conn_def: external_connection: name_or_index - { sta::stringDelete($1); } + { $$ = std::string(); } | physical_inst ':' pport - { sta::stringDelete($1); - sta::stringDelete($3); - } + { $$ = std::string(); } ; internal_connection: @@ -551,9 +521,7 @@ internal_connection: pin_name: name_or_index - { $$ = reader->findPin($1); - sta::stringDelete($1); - } + { $$ = reader->findPin($1); } ; internal_node_coords: @@ -567,7 +535,7 @@ internal_node_coord: internal_parasitic_node: name_or_index - { sta::stringDelete($1); } + { $$ = std::string(); } ; /****************************************************************/ @@ -581,6 +549,7 @@ cap_elems: /* empty */ { $$ = 0; } | cap_elems cap_elem + { $$ = $1; } ; cap_elem: @@ -609,6 +578,7 @@ res_elems: /* empty */ { $$ = 0; } | res_elems res_elem + { $$ = $1; } ; res_elem: @@ -631,6 +601,7 @@ induc_elems: /* empty */ { $$ = 0; } | induc_elems induc_elem + { $$ = $1; } ; induc_elem: @@ -658,9 +629,7 @@ driver_reducs: driver_reduc: driver_pair driver_cell pi_model - { reader->rspfDrvrBegin($1, $3); - sta::stringDelete($2); - } + { reader->rspfDrvrBegin($1, $3); } load_desc { reader->rspfDrvrFinish(); } ; @@ -709,6 +678,7 @@ pole_desc: poles: pole | poles pole + { $$ = $2; } ; pole: @@ -753,7 +723,6 @@ residue: d_pnet: D_PNET pnet_ref total_cap routing_conf pconn_sec cap_sec res_sec induc_sec END - { sta::stringDelete($2); } ; pnet_ref: @@ -789,10 +758,7 @@ internal_pnode_coord: internal_pdspf_node: name_or_index - { - sta::stringDelete($1); - $$ = 0; - } + { $$ = std::string(); } ; name_or_index: @@ -805,9 +771,7 @@ name_or_index: r_pnet: R_PNET pnet_ref total_cap routing_conf END - { sta::stringDelete($2); } | R_PNET pnet_ref total_cap routing_conf pdriver_reduc END - { sta::stringDelete($2); } ; pdriver_reduc: @@ -824,6 +788,7 @@ number: INTEGER { $$ = static_cast($1); } | FLOAT + { $$ = $1; } ; pos_integer: diff --git a/parasitics/SpefReader.cc b/parasitics/SpefReader.cc index 2bc516ae..84eacea7 100644 --- a/parasitics/SpefReader.cc +++ b/parasitics/SpefReader.cc @@ -24,6 +24,10 @@ #include "SpefReader.hh" +#include +#include +#include + #include "Zlib.hh" #include "Stats.hh" #include "Report.hh" @@ -44,7 +48,7 @@ namespace sta { bool -readSpefFile(const std::string &filename, +readSpefFile(std::string_view filename, Instance *instance, bool pin_cap_included, bool keep_coupling_caps, @@ -61,7 +65,7 @@ readSpefFile(const std::string &filename, return success; } -SpefReader::SpefReader(const std::string &filename, +SpefReader::SpefReader(std::string_view filename, Instance *instance, bool pin_cap_included, bool keep_coupling_caps, @@ -103,7 +107,7 @@ bool SpefReader::read() { bool success; - gzstream::igzstream stream(filename_.c_str()); + gzstream::igzstream stream(std::string(filename_).c_str()); if (stream.is_open()) { Stats stats(debug_, report_); SpefScanner scanner(&stream, filename_, this, report_); @@ -144,13 +148,13 @@ SpefReader::setBusBrackets(char left, } Instance * -SpefReader::findInstanceRelative(const char *name) +SpefReader::findInstanceRelative(std::string_view name) { return sdc_network_->findInstanceRelative(instance_, name); } Net * -SpefReader::findNetRelative(const char *name) +SpefReader::findNetRelative(std::string_view name) { Net *net = network_->findNetRelative(instance_, name); // Relax spef escaping requirement because some commercial tools @@ -161,21 +165,22 @@ SpefReader::findNetRelative(const char *name) } Pin * -SpefReader::findPinRelative(const char *name) +SpefReader::findPinRelative(std::string_view name) { return network_->findPinRelative(instance_, name); } Pin * -SpefReader::findPortPinRelative(const char *name) +SpefReader::findPortPinRelative(std::string_view name) { return network_->findPin(instance_, name); } -char * -SpefReader::translated(const char *token) +std::string +SpefReader::translated(std::string_view spef_name) { - return spefToSta(token, divider_, network_->pathDivider(), network_->pathEscape()); + return spefToSta(spef_name, divider_, network_->pathDivider(), + network_->pathEscape()); } int @@ -187,79 +192,74 @@ SpefReader::warnLine() const void SpefReader::setTimeScale(float scale, - const char *units) + std::string_view units) { - if (stringEq(units, "NS")) + if (stringEqual(units, "NS")) time_scale_ = scale * 1E-9F; - else if (stringEq(units, "PS")) + else if (stringEqual(units, "PS")) time_scale_ = scale * 1E-12F; else warn(1641, "unknown units {}.", units); - stringDelete(units); } void SpefReader::setCapScale(float scale, - const char *units) + std::string_view units) { - if (stringEq(units, "PF")) + if (stringEqual(units, "PF")) cap_scale_ = scale * 1E-12F; - else if (stringEq(units, "FF")) + else if (stringEqual(units, "FF")) cap_scale_ = scale * 1E-15F; else warn(1642, "unknown units {}.", units); - stringDelete(units); } void SpefReader::setResScale(float scale, - const char *units) + std::string_view units) { - if (stringEq(units, "OHM")) + if (stringEqual(units, "OHM")) res_scale_ = scale; - else if (stringEq(units, "KOHM")) + else if (stringEqual(units, "KOHM")) res_scale_ = scale * 1E+3F; else warn(1643, "unknown units {}.", units); - stringDelete(units); } void SpefReader::setInductScale(float scale, - const char *units) + std::string_view units) { - if (stringEq(units, "HENRY")) + if (stringEqual(units, "HENRY")) induct_scale_ = scale; - else if (stringEq(units, "MH")) + else if (stringEqual(units, "MH")) induct_scale_ = scale * 1E-3F; - else if (stringEq(units, "UH")) + else if (stringEqual(units, "UH")) induct_scale_ = scale * 1E-6F; else warn(1644, "unknown units {}.", units); - stringDelete(units); } void -SpefReader::makeNameMapEntry(const char *index, - const char *name) +SpefReader::makeNameMapEntry(std::string_view index, + std::string_view name) { - int i = atoi(index + 1); + int i = std::stoi(std::string(index.substr(1))); name_map_[i] = name; - stringDelete(index); - stringDelete(name); } -const char * -SpefReader::nameMapLookup(const char *name) +std::string_view +SpefReader::nameMapLookup(std::string_view name) { - if (name && name[0] == '*') { - int index = atoi(name + 1); + if (!name.empty() && name[0] == '*') { + std::string index_str(name.substr(1)); + int index = std::stoi(index_str); const auto &itr = name_map_.find(index); if (itr != name_map_.end()) - return itr->second.c_str(); + return itr->second; else { warn(1645, "no name map entry for {}.", index); - return nullptr; + return ""; } } else @@ -267,14 +267,14 @@ SpefReader::nameMapLookup(const char *name) } PortDirection * -SpefReader::portDirection(char *spef_dir) +SpefReader::portDirection(std::string_view spef_dir) { PortDirection *direction = PortDirection::unknown(); - if (stringEq(spef_dir, "I")) + if (spef_dir == "I") direction = PortDirection::input(); - else if (stringEq(spef_dir, "O")) + else if (spef_dir == "O") direction = PortDirection::output(); - else if (stringEq(spef_dir, "B")) + else if (spef_dir == "B") direction = PortDirection::bidirect(); else warn(1646, "unknown port direction {}.", spef_dir); @@ -284,31 +284,31 @@ SpefReader::portDirection(char *spef_dir) void SpefReader::setDesignFlow(StringSeq *flow) { - design_flow_ = std::move(*flow); + design_flow_ = *flow; delete flow; } Pin * -SpefReader::findPin(char *name) +SpefReader::findPin(std::string_view name) { Pin *pin = nullptr; - if (name) { - char *delim = strrchr(name, delimiter_); - if (delim) { - *delim = '\0'; - const char *name1 = nameMapLookup(name); - if (name1) { - Instance *inst = findInstanceRelative(name1); - // Replace delimiter for error messages. - *delim = delimiter_; - const char *port_name = delim + 1; + if (!name.empty()) { + size_t delim = name.rfind(delimiter_); + if (delim != std::string::npos) { + std::string inst_name_mapped(name.substr(0, delim)); + std::string_view inst_name = nameMapLookup(inst_name_mapped); + if (!inst_name.empty()) { + Instance *inst = findInstanceRelative(inst_name); + std::string port_name(name.substr(delim + 1, std::string::npos)); if (inst) { pin = network_->findPin(inst, port_name); if (pin == nullptr) - warn(1647, "pin {} not found.", name1); + warn(1647, "pin {}{}{} not found.", + inst_name, delimiter_, port_name); } else - warn(1648, "instance {} not found.", name1); + warn(1648, "instance {}{}{} not found.", + inst_name, delimiter_, port_name); } } else { @@ -321,11 +321,11 @@ SpefReader::findPin(char *name) } Net * -SpefReader::findNet(const char *name) +SpefReader::findNet(std::string_view name) { Net *net = nullptr; - const char *name1 = nameMapLookup(name); - if (name1) { + std::string_view name1 = nameMapLookup(name); + if (!name1.empty()) { net = findNetRelative(name1); if (net == nullptr) warn(1650, "net {} not found.", name1); @@ -425,16 +425,16 @@ SpefReader::dspfFinish() } ParasiticNode * -SpefReader::findParasiticNode(char *name, +SpefReader::findParasiticNode(std::string_view name, bool local_only) { - if (name && parasitic_) { - char *delim = strrchr(name, delimiter_); - if (delim) { - *delim = '\0'; - char *name2 = delim + 1; - const char *name1 = nameMapLookup(name); - if (name1) { + if (!name.empty() && parasitic_) { + size_t delim = name.rfind(delimiter_); + if (delim != std::string::npos) { + std::string name1_mapped(name.substr(0, delim)); + std::string name2(name.substr(delim + 1, std::string::npos)); + std::string_view name1 = nameMapLookup(name1_mapped); + if (!name1.empty()) { Instance *inst = findInstanceRelative(name1); if (inst) { // : @@ -445,36 +445,32 @@ SpefReader::findParasiticNode(char *name, sdc_network_->pathName(net_)); return parasitics_->ensureParasiticNode(parasitic_, pin, network_); } - else { - // Replace delimiter for error message. - *delim = delimiter_; - warn(1652, "pin {} not found.", name1); - } + else + warn(1652, "pin {}{}{} not found.", + name1, delimiter_, name2); } else { Net *net = findNet(name1); - // Replace delimiter for error messages. - *delim = delimiter_; if (net) { // : - const char *id_str = delim + 1; - if (isDigits(id_str)) { - int id = atoi(id_str); + if (isDigits(name2)) { + int id = std::stoi(name2); if (local_only && !network_->isConnected(net, net_)) - warn(1653, "{} not connected to net {}.", name1, - network_->pathName(net_)); + warn(1653, "{}{}{} not connected to net {}.", + name1, delimiter_, name2, network_->pathName(net_)); return parasitics_->ensureParasiticNode(parasitic_, net, id, network_); } else - warn(1654, "node {} not a pin or net:number", name1); + warn(1654, "node {}{}{} not a pin or net:number", + name1, delimiter_, name2); } } } } else { // - const char *name1 = nameMapLookup(name); - if (name1) { + std::string_view name1 = nameMapLookup(name); + if (!name1.empty()) { Pin *pin = findPortPinRelative(name1); if (pin) { if (local_only && !network_->isConnected(net_, pin)) @@ -494,7 +490,7 @@ SpefReader::findParasiticNode(char *name, void SpefReader::makeCapacitor(int, - char *node_name, + std::string_view node_name, SpefTriple *cap) { ParasiticNode *node = findParasiticNode(node_name, true); @@ -503,13 +499,12 @@ SpefReader::makeCapacitor(int, parasitics_->incrCap(node, cap1); } delete cap; - stringDelete(node_name); } void SpefReader::makeCapacitor(int id, - char *node_name1, - char *node_name2, + std::string_view node_name1, + std::string_view node_name2, SpefTriple *cap) { ParasiticNode *node1 = findParasiticNode(node_name1, false); @@ -527,14 +522,12 @@ SpefReader::makeCapacitor(int id, } } delete cap; - stringDelete(node_name1); - stringDelete(node_name2); } void SpefReader::makeResistor(int id, - char *node_name1, - char *node_name2, + std::string_view node_name1, + std::string_view node_name2, SpefTriple *res) { ParasiticNode *node1 = findParasiticNode(node_name1, true); @@ -544,8 +537,6 @@ SpefReader::makeResistor(int id, parasitics_->makeResistor(parasitic_, id, res1, node1, node2); } delete res; - stringDelete(node_name1); - stringDelete(node_name2); } //////////////////////////////////////////////////////////////// @@ -596,7 +587,7 @@ SpefTriple::value(int index) const //////////////////////////////////////////////////////////////// SpefScanner::SpefScanner(std::istream *stream, - const std::string &filename, + std::string_view filename, SpefReader *reader, Report *report) : yyFlexLexer(stream), @@ -607,9 +598,9 @@ SpefScanner::SpefScanner(std::istream *stream, } void -SpefScanner::error(const char *msg) +SpefScanner::error(std::string_view msg) { - report_->fileError(1658, filename_.c_str(), lineno(), "{}", msg); + report_->fileError(1658, filename_, lineno(), "{}", msg); } } // namespace sta diff --git a/parasitics/SpefReader.hh b/parasitics/SpefReader.hh index f5a9efcb..d07e8a63 100644 --- a/parasitics/SpefReader.hh +++ b/parasitics/SpefReader.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include "Zlib.hh" #include "MinMax.hh" @@ -43,7 +44,7 @@ class StaState; // Min/max and operating condition op_cond are used for parasitic network reduction. // Return true if successful. bool -readSpefFile(const std::string &filename, +readSpefFile(std::string_view filename, Instance *instance, bool pin_cap_included, bool keep_coupling_caps, diff --git a/parasitics/SpefReaderPvt.hh b/parasitics/SpefReaderPvt.hh index 7b01fda6..272d7ef1 100644 --- a/parasitics/SpefReaderPvt.hh +++ b/parasitics/SpefReaderPvt.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include #include "Zlib.hh" @@ -47,7 +48,7 @@ using SpefNameMap = std::map; class SpefReader : public StaState { public: - SpefReader(const std::string &filename, + SpefReader(std::string_view filename, Instance *instance, bool pin_cap_included, bool keep_coupling_caps, @@ -63,25 +64,25 @@ public: void setDivider(char divider); char delimiter() const { return delimiter_; } void setDelimiter(char delimiter); - const std::string &filename() const { return filename_; } + std::string_view filename() const { return filename_; } // Translate from spf/spef namespace to sta namespace. - char *translated(const char *token); + std::string translated(std::string_view spef_name); void setBusBrackets(char left, char right); void setTimeScale(float scale, - const char *units); + std::string_view units); void setCapScale(float scale, - const char *units); + std::string_view units); void setResScale(float scale, - const char *units); + std::string_view units); void setInductScale(float scale, - const char *units); - void makeNameMapEntry(const char *index, - const char *name); - const char *nameMapLookup(const char *index); + std::string_view units); + void makeNameMapEntry(std::string_view index, + std::string_view name); + std::string_view nameMapLookup(std::string_view name); void setDesignFlow(StringSeq *flow_keys); - Pin *findPin(char *name); - Net *findNet(const char *name); + Pin *findPin(std::string_view name); + Net *findNet(std::string_view name); void rspfBegin(Net *net, SpefTriple *total_cap); void rspfFinish(); @@ -94,17 +95,17 @@ public: SpefTriple *total_cap); void dspfFinish(); void makeCapacitor(int id, - char *node_name, + std::string_view node_name, SpefTriple *cap); void makeCapacitor(int id, - char *node_name1, - char *node_name2, + std::string_view node_name1, + std::string_view node_name2, SpefTriple *cap); void makeResistor(int id, - char *node_name1, - char *node_name2, + std::string_view node_name1, + std::string_view node_name2, SpefTriple *res); - PortDirection *portDirection(char *spef_dir); + PortDirection *portDirection(std::string_view spef_dir); int warnLine() const; template void warn(int id, @@ -116,14 +117,14 @@ public: } private: - Pin *findPinRelative(const char *name); - Pin *findPortPinRelative(const char *name); - Net *findNetRelative(const char *name); - Instance *findInstanceRelative(const char *name); - ParasiticNode *findParasiticNode(char *name, + Pin *findPinRelative(std::string_view name); + Pin *findPortPinRelative(std::string_view name); + Net *findNetRelative(std::string_view name); + Instance *findInstanceRelative(std::string_view name); + ParasiticNode *findParasiticNode(std::string_view name, bool local_only); - const std::string filename_; + std::string_view filename_; SpefScanner *scanner_; Instance *instance_; bool pin_cap_included_; @@ -180,6 +181,4 @@ private: SpefTriple *c1_; }; -extern SpefReader *spef_reader; - } // namespace diff --git a/parasitics/SpefScanner.hh b/parasitics/SpefScanner.hh index 0ae97b07..c87a43c0 100644 --- a/parasitics/SpefScanner.hh +++ b/parasitics/SpefScanner.hh @@ -24,6 +24,8 @@ #pragma once +#include + #include "SpefLocation.hh" #include "SpefParse.hh" @@ -41,7 +43,7 @@ class SpefScanner : public SpefFlexLexer { public: SpefScanner(std::istream *stream, - const std::string &filename, + std::string_view filename, SpefReader *reader, Report *report); virtual ~SpefScanner() {} @@ -51,14 +53,14 @@ public: // YY_DECL defined in SpefLex.ll // Method body created by flex in SpefLex.cc - void error(const char *msg); + void error(std::string_view msg); int line() const { return yylineno; } // Get rid of override virtual function warning. using FlexLexer::yylex; private: - std::string filename_; + std::string_view filename_; SpefReader *reader_; Report *report_; std::string token_; diff --git a/power/Power.cc b/power/Power.cc index cd5312b0..78d9adce 100644 --- a/power/Power.cc +++ b/power/Power.cc @@ -344,24 +344,24 @@ Power::reportInstsJson(const InstanceSeq &insts, } void -Power::reportPowerRowJson(const char *name, +Power::reportPowerRowJson(std::string_view type, const PowerResult &power, int digits, - const char *separator) + std::string_view eol) { float internal = power.internal(); float switching = power.switching(); float leakage = power.leakage(); float total = power.total(); - report_->report(" \"{}\": {{", name); + report_->report(" \"{}\": {{", type); report_->report(" \"internal\": {:.{}e},", internal, digits); report_->report(" \"switching\": {:.{}e},", switching, digits); report_->report(" \"leakage\": {:.{}e},", leakage, digits); report_->report(" \"total\": {:.{}e}", total, digits); std::string line = " }"; - if (separator && separator[0] != '\0') - line += separator; + if (!eol.empty()) + line += eol; report_->reportLine(line); } @@ -375,9 +375,8 @@ Power::reportPowerInstJson(const Instance *inst, float leakage = power.leakage(); float total = power.total(); - const char *inst_name = network_->pathName(inst); report_->report("{{"); - report_->report(" \"name\": \"{}\",", inst_name); + report_->report(" \"name\": \"{}\",", network_->pathName(inst)); report_->report(" \"internal\": {:.{}e},", internal, digits); report_->report(" \"switching\": {:.{}e},", switching, digits); report_->report(" \"leakage\": {:.{}e},", leakage, digits); @@ -1622,26 +1621,23 @@ Power::portVoltage(LibertyCell *cell, const Scene *scene, const MinMax *min_max) { - return pgNameVoltage(cell, port->relatedPowerPin(), scene, min_max); + return pgPortVoltage(cell, port->relatedPowerPort(), scene, min_max); } float -Power::pgNameVoltage(LibertyCell *cell, - const char *pg_port_name, +Power::pgPortVoltage(LibertyCell *cell, + const LibertyPort *pg_port, const Scene *scene, const MinMax *min_max) { - if (pg_port_name) { - LibertyPort *pg_port = cell->findLibertyPort(pg_port_name); - if (pg_port) { - const char *volt_name = pg_port->voltageName(); - LibertyLibrary *library = cell->libertyLibrary(); - float voltage; - bool exists; - library->supplyVoltage(volt_name, voltage, exists); - if (exists) - return voltage; - } + if (pg_port) { + const std::string &volt_name = pg_port->voltageName(); + LibertyLibrary *library = cell->libertyLibrary(); + float voltage; + bool exists; + library->supplyVoltage(volt_name, voltage, exists); + if (exists) + return voltage; } Pvt *pvt = scene->sdc()->operatingConditions(min_max); @@ -1714,7 +1710,7 @@ Power::reportActivityAnnotation(bool report_unannotated, for (const Pin *pin : annotated_pins) { const PwrActivity &activity = user_activity_map_[pin]; PwrActivityOrigin origin = activity.origin(); - const char *origin_name = pwr_activity_origin_map.find(origin); + const std::string &origin_name = pwr_activity_origin_map.find(origin); report_->report("{:>5} {}", origin_name, sdc_network_->pathName(pin)); } } @@ -1927,7 +1923,7 @@ PwrActivity::isSet() const return origin_ != PwrActivityOrigin::unknown; } -const char * +const std::string & PwrActivity::originName() const { return pwr_activity_origin_map.find(origin_); diff --git a/power/Power.hh b/power/Power.hh index 49a6dc0a..72471047 100644 --- a/power/Power.hh +++ b/power/Power.hh @@ -151,10 +151,10 @@ protected: void setActivity(const Pin *pin, PwrActivity &activity); PwrActivity findActivity(const Pin *pin); - void reportPowerRowJson(const char *name, + void reportPowerRowJson(std::string_view type, const PowerResult &power, int digits, - const char *separator); + std::string_view eol); void reportPowerInstJson(const Instance *inst, const PowerResult &power, int digits); @@ -209,8 +209,8 @@ protected: const LibertyPort *port, const Scene *scene, const MinMax *min_max); - float pgNameVoltage(LibertyCell *cell, - const char *pg_port_name, + float pgPortVoltage(LibertyCell *cell, + const LibertyPort *pg_port, const Scene *scene, const MinMax *min_max); void seedActivities(BfsFwdIterator &bfs); diff --git a/power/ReportPower.cc b/power/ReportPower.cc index cf4803b7..00407ff6 100644 --- a/power/ReportPower.cc +++ b/power/ReportPower.cc @@ -137,11 +137,11 @@ ReportPower::powerColPercent(float col_total, } void -ReportPower::reportTitle5(const char *title1, - const char *title2, - const char *title3, - const char *title4, - const char *title5, +ReportPower::reportTitle5(std::string_view title1, + std::string_view title2, + std::string_view title3, + std::string_view title4, + std::string_view title5, int field_width) { report_->report("{:<20} {:>{}} {:>{}} {:>{}} {:>{}}", title1, title2, field_width, @@ -149,12 +149,12 @@ ReportPower::reportTitle5(const char *title1, } void -ReportPower::reportTitle5Units(const char *title1, - const char *title2, - const char *title3, - const char *title4, - const char *title5, - const char *units, +ReportPower::reportTitle5Units(std::string_view title1, + std::string_view title2, + std::string_view title3, + std::string_view title4, + std::string_view title5, + std::string_view units, int field_width) { report_->report("{:<20} {:>{}} {:>{}} {:>{}} {:>{}} {}", title1, title2, @@ -171,7 +171,7 @@ ReportPower::reportTitleDashes5(int field_width) } void -ReportPower::reportRow(const char *type, +ReportPower::reportRow(std::string_view type, const PowerResult &power, float design_total, int field_width, @@ -186,7 +186,7 @@ ReportPower::reportRow(const char *type, if (design_total != 0.0 && !std::isnan(design_total)) percent = total / design_total * 100.0; - std::string line = sta::format("{:<20}", type); + std::string line = sta::format("{:<20}", std::string(type)); line += powerCol(internal, field_width, digits); line += powerCol(switching, field_width, digits); line += powerCol(leakage, field_width, digits); @@ -196,10 +196,10 @@ ReportPower::reportRow(const char *type, } void -ReportPower::reportTitle4(const char *title1, - const char *title2, - const char *title3, - const char *title4, +ReportPower::reportTitle4(std::string_view title1, + std::string_view title2, + std::string_view title3, + std::string_view title4, int field_width) { report_->report(" {:>{}} {:>{}} {:>{}} {:>{}}", title1, field_width, title2, @@ -207,11 +207,11 @@ ReportPower::reportTitle4(const char *title1, } void -ReportPower::reportTitle4Units(const char *title1, - const char *title2, - const char *title3, - const char *title4, - const char *units, +ReportPower::reportTitle4Units(std::string_view title1, + std::string_view title2, + std::string_view title3, + std::string_view title4, + std::string_view units, int field_width) { report_->report(" {:>{}} {:>{}} {:>{}} {:>{}} {}", title1, field_width, title2, diff --git a/power/ReportPower.hh b/power/ReportPower.hh index 966e8acb..0486f8d7 100644 --- a/power/ReportPower.hh +++ b/power/ReportPower.hh @@ -24,6 +24,8 @@ #pragma once +#include + #include "StaState.hh" #include "NetworkClass.hh" #include "PowerClass.hh" @@ -51,35 +53,35 @@ private: std::string powerColPercent(float col_total, float total, int field_width); - void reportTitle5(const char *title1, - const char *title2, - const char *title3, - const char *title4, - const char *title5, + void reportTitle5(std::string_view title1, + std::string_view title2, + std::string_view title3, + std::string_view title4, + std::string_view title5, int field_width); - void reportTitle5Units(const char *title1, - const char *title2, - const char *title3, - const char *title4, - const char *title5, - const char *units, + void reportTitle5Units(std::string_view title1, + std::string_view title2, + std::string_view title3, + std::string_view title4, + std::string_view title5, + std::string_view units, int field_width); void reportTitleDashes5(int field_width); - void reportRow(const char *type, + void reportRow(std::string_view type, const PowerResult &power, float design_total, int field_width, int digits); - void reportTitle4(const char *title1, - const char *title2, - const char *title3, - const char *title4, + void reportTitle4(std::string_view title1, + std::string_view title2, + std::string_view title3, + std::string_view title4, int field_width); - void reportTitle4Units(const char *title1, - const char *title2, - const char *title3, - const char *title4, - const char *units, + void reportTitle4Units(std::string_view title1, + std::string_view title2, + std::string_view title3, + std::string_view title4, + std::string_view units, int field_width); void reportTitleDashes4(int field_width); void reportInst(const Instance *inst, diff --git a/power/SaifLex.ll b/power/SaifLex.ll index e602983b..7d53c2a0 100644 --- a/power/SaifLex.ll +++ b/power/SaifLex.ll @@ -24,9 +24,10 @@ // This notice may not be removed or altered from any source distribution. #include +#include +#include #include "util/FlexDisableRegister.hh" -#include "StringUtil.hh" #include "power/SaifReaderPvt.hh" #include "SaifParse.hh" #include "power/SaifScanner.hh" @@ -85,7 +86,7 @@ EOL \r?\n "\"" { BEGIN INITIAL; - yylval->string = sta::stringCopy(token_.c_str()); + yylval->emplace(std::move(token_)); return token::QSTRING; } @@ -101,7 +102,7 @@ EOL \r?\n "//"[^\n]*{EOL} { loc->lines(); loc->step(); } [0-9]+ { - yylval->uint = atoll(yytext); + yylval->emplace(atoll(yytext)); return token::UINT; } @@ -132,7 +133,7 @@ TC { return token::TC; } IG { return token::IG; } {ID} { - yylval->string = sta::stringCopy(yytext); + yylval->emplace(yytext); return token::ID; } diff --git a/power/SaifParse.yy b/power/SaifParse.yy index 6012d59a..9413cbce 100644 --- a/power/SaifParse.yy +++ b/power/SaifParse.yy @@ -24,9 +24,11 @@ %{ #include +#include +#include +#include #include "Report.hh" -#include "StringUtil.hh" #include "power/SaifReaderPvt.hh" #include "power/SaifScanner.hh" @@ -56,29 +58,22 @@ sta::SaifParse::error(const location_type &loc, %parse-param { SaifScanner *scanner } %parse-param { SaifReader *reader } %define api.parser.class {SaifParse} +%define api.value.type variant // expected shift/reduce conflicts %expect 2 -%union { - char character; - const char *string; - uint64_t uint; - sta::SaifState state; - sta::SaifStateDurations state_durations; -} - %token SAIFILE SAIFVERSION DIRECTION DESIGN DATE VENDOR PROGRAM_NAME VERSION %token DIVIDER TIMESCALE DURATION %token INSTANCE NET PORT %token T0 T1 TX TZ TB TC IG -%token QSTRING ID FNUMBER DNUMBER UINT +%token FNUMBER DNUMBER +%token QSTRING ID +%token UINT -%type UINT -%type QSTRING ID -%type hchar -%type state -%type state_durations +%type hchar +%type state +%type state_durations %start file @@ -97,16 +92,16 @@ header: ; header_stmt: - '(' SAIFVERSION QSTRING ')' { sta::stringDelete($3); } -| '(' DIRECTION QSTRING ')' { sta::stringDelete($3); } -| '(' DESIGN QSTRING ')' { sta::stringDelete($3); } -| '(' DESIGN ')' { } -| '(' DATE QSTRING ')' { sta::stringDelete($3); } -| '(' VENDOR QSTRING ')' { sta::stringDelete($3); } -| '(' PROGRAM_NAME QSTRING ')' { sta::stringDelete($3); } -| '(' VERSION QSTRING ')' { sta::stringDelete($3); } + '(' SAIFVERSION QSTRING ')' +| '(' DIRECTION QSTRING ')' +| '(' DESIGN QSTRING ')' +| '(' DESIGN ')' +| '(' DATE QSTRING ')' +| '(' VENDOR QSTRING ')' +| '(' PROGRAM_NAME QSTRING ')' +| '(' VERSION QSTRING ')' | '(' DIVIDER hchar ')' { reader->setDivider($3); } -| '(' TIMESCALE UINT ID ')' { reader->setTimescale($3, $4); } +| '(' TIMESCALE UINT ID ')' { reader->setTimescale($3, std::move($4)); } | '(' DURATION UINT ')' { reader->setDuration($3); } ; @@ -119,11 +114,11 @@ hchar: instance: '(' INSTANCE ID - { reader->instancePush($3); } + { reader->instancePush(std::move($3)); } instance_contents ')' { reader->instancePop(); } | '(' INSTANCE QSTRING ID - { reader->instancePush($3); } + { reader->instancePush(std::move($3)); } instance_contents ')' { reader->instancePop(); } ; @@ -147,7 +142,7 @@ nets: net: '(' ID state_durations ')' - { reader->setNetDurations($2, $3); } + { reader->setNetDurations(std::move($2), $3); } ; ports: @@ -163,7 +158,7 @@ state_durations: '(' state UINT ')' { $$[static_cast($2)] = $3; } | state_durations '(' state UINT ')' - { $$[static_cast($3)] = $4; } + { $$ = $1; $$[static_cast($3)] = $4; } ; state: diff --git a/power/SaifReader.cc b/power/SaifReader.cc index 72a35926..98e21e76 100644 --- a/power/SaifReader.cc +++ b/power/SaifReader.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include "Error.hh" #include "Debug.hh" @@ -93,23 +94,22 @@ SaifReader::setDivider(char divider) void SaifReader::setTimescale(uint64_t multiplier, - const char *units) + std::string &&units) { if (multiplier == 1 || multiplier == 10 || multiplier == 100) { - if (stringEq(units, "us")) + if (stringEqual(units, "us")) timescale_ = multiplier * 1E-6; - else if (stringEq(units, "ns")) + else if (stringEqual(units, "ns")) timescale_ = multiplier * 1E-9; - else if (stringEq(units, "ps")) + else if (stringEqual(units, "ps")) timescale_ = multiplier * 1E-12; - else if (stringEq(units, "fs")) + else if (stringEqual(units, "fs")) timescale_ = multiplier * 1E-15; else report_->error(1861, "SAIF TIMESCALE units not us, ns, or ps."); } else report_->error(1862, "SAIF TIMESCALE multiplier not 1, 10, or 100."); - stringDelete(units); } void @@ -119,11 +119,11 @@ SaifReader::setDuration(uint64_t duration) } void -SaifReader::instancePush(const char *instance_name) +SaifReader::instancePush(std::string &&instance_name) { if (in_scope_level_ == 0) { // Check for a match to the annotation scope. - saif_scope_.push_back(instance_name); + saif_scope_.push_back(std::move(instance_name)); std::string saif_scope; bool first = true; @@ -133,7 +133,7 @@ SaifReader::instancePush(const char *instance_name) saif_scope += inst; first = false; } - if (stringEq(saif_scope.c_str(), scope_)) + if (saif_scope == scope_) in_scope_level_ = saif_scope_.size(); } else { @@ -144,7 +144,6 @@ SaifReader::instancePush(const char *instance_name) : nullptr; path_.push_back(child); } - stringDelete(instance_name); } void @@ -159,14 +158,14 @@ SaifReader::instancePop() } void -SaifReader::setNetDurations(const char *net_name, - SaifStateDurations &durations) +SaifReader::setNetDurations(std::string &&net_name, + const SaifStateDurations &durations) { if (in_scope_level_ > 0) { Instance *parent = path_.empty() ? sdc_network_->topInstance() : path_.back(); if (parent) { std::string unescaped_name = unescaped(net_name); - const Pin *pin = sdc_network_->findPin(parent, unescaped_name.c_str()); + const Pin *pin = sdc_network_->findPin(parent, unescaped_name); LibertyPort *liberty_port = pin ? sdc_network_->libertyPort(pin) : nullptr; if (pin && !sdc_network_->isHierarchical(pin) && !sdc_network_->direction(pin)->isInternal() @@ -183,17 +182,14 @@ SaifReader::setNetDurations(const char *net_name, } } } - stringDelete(net_name); } std::string -SaifReader::unescaped(const char *token) +SaifReader::unescaped(const std::string &token) { std::string unescaped; - for (const char *t = token; *t; t++) { - char ch = *t; + for (char ch : token) { if (ch != escape_) - // Just the normal noises. unescaped += ch; } debugPrint(debug_, "saif_name", 1, "token {} -> {}", token, unescaped); @@ -216,7 +212,7 @@ SaifScanner::SaifScanner(std::istream *stream, void SaifScanner::error(const char *msg) { - report_->fileError(1860, filename_.c_str(), lineno(), "{}", msg); + report_->fileError(1860, filename_, lineno(), "{}", msg); } } // namespace sta diff --git a/power/SaifReaderPvt.hh b/power/SaifReaderPvt.hh index 4de66c5d..af8722a6 100644 --- a/power/SaifReaderPvt.hh +++ b/power/SaifReaderPvt.hh @@ -58,16 +58,16 @@ public: void setDivider(char divider); void setTimescale(uint64_t multiplier, - const char *units); + std::string &&units); void setDuration(uint64_t duration); - void instancePush(const char *instance_name); + void instancePush(std::string &&instance_name); void instancePop(); - void setNetDurations(const char *net_name, - SaifStateDurations &durations); + void setNetDurations(std::string &&net_name, + const SaifStateDurations &durations); const char *filename() { return filename_; } private: - std::string unescaped(const char *token); + std::string unescaped(const std::string &token); const char *filename_; const char *scope_; // Divider delimited scope to begin annotation. diff --git a/power/VcdParse.cc b/power/VcdParse.cc index c82423cf..ea0d71a7 100644 --- a/power/VcdParse.cc +++ b/power/VcdParse.cc @@ -134,7 +134,7 @@ VcdParse::parseTimescale() } void -VcdParse::setTimeUnit(const std::string &time_unit, +VcdParse::setTimeUnit(std::string_view time_unit, double time_scale) { double time_unit_scale = 1.0; @@ -172,7 +172,7 @@ VcdParse::parseVar() { std::vector tokens = readStmtTokens(); if (tokens.size() == 4 || tokens.size() == 5) { - std::string type_name = tokens[0]; + std::string &type_name = tokens[0]; VcdVarType type = vcd_var_type_map.find(type_name, VcdVarType::unknown); if (type == VcdVarType::unknown) report_->fileWarn(809, filename_, file_line_, "Unknown variable type {}.", @@ -180,7 +180,7 @@ VcdParse::parseVar() else { size_t width = std::stoi(tokens[1]); std::string &id = tokens[2]; - std::string name = tokens[3]; + std::string &name = tokens[3]; // iverilog separates bus base name from bit range. if (tokens.size() == 5) { // Preserve space after esacaped name. @@ -188,7 +188,6 @@ VcdParse::parseVar() name += ' '; name += tokens[4]; } - reader_->makeVar(scope_, name, type, width, id); } } diff --git a/power/VcdParse.hh b/power/VcdParse.hh index 6979b0ad..69a3f7d0 100644 --- a/power/VcdParse.hh +++ b/power/VcdParse.hh @@ -68,7 +68,7 @@ public: private: void parseTimescale(); - void setTimeUnit(const std::string &time_unit, + void setTimeUnit(std::string_view time_unit, double time_scale); void parseVar(); void parseScope(); @@ -98,27 +98,27 @@ class VcdReader { public: virtual ~VcdReader() {} - virtual void setDate(const std::string &date) = 0; - virtual void setComment(const std::string &comment) = 0; - virtual void setVersion(const std::string &version) = 0; - virtual void setTimeUnit(const std::string &time_unit, + virtual void setDate(std::string_view date) = 0; + virtual void setComment(std::string_view comment) = 0; + virtual void setVersion(std::string_view version) = 0; + virtual void setTimeUnit(std::string_view time_unit, double time_unit_scale, double time_scale) = 0; virtual void setTimeMin(VcdTime time) = 0; virtual void setTimeMax(VcdTime time) = 0; virtual void varMinDeltaTime(VcdTime min_delta_time) = 0; - virtual bool varIdValid(const std::string &id) = 0; + virtual bool varIdValid(std::string_view id) = 0; virtual void makeVar(const VcdScope &scope, - const std::string &name, + std::string_view name, VcdVarType type, size_t width, - const std::string &id) = 0; + std::string_view id) = 0; virtual void varAppendValue(const std::string &id, VcdTime time, char value) = 0; virtual void varAppendBusValue(const std::string &id, VcdTime time, - const std::string &bus_value) = 0; + std::string_view bus_value) = 0; }; class VcdValue diff --git a/power/VcdReader.cc b/power/VcdReader.cc index fd5ed1cd..ee6e6037 100644 --- a/power/VcdReader.cc +++ b/power/VcdReader.cc @@ -117,7 +117,7 @@ using VcdIdCountsMap = std::unordered_map; class VcdCountReader : public VcdReader { public: - VcdCountReader(const std::string &scope, + VcdCountReader(std::string_view scope, const Network *sdc_network, Report *report, Debug *debug); @@ -127,31 +127,31 @@ public: double timeScale() const { return time_scale_; } // VcdParse callbacks. - void setDate(const std::string &) override {} - void setComment(const std::string &) override {} - void setVersion(const std::string &) override {} - void setTimeUnit(const std::string &time_unit, + void setDate(std::string_view ) override {} + void setComment(std::string_view ) override {} + void setVersion(std::string_view ) override {} + void setTimeUnit(std::string_view time_unit, double time_unit_scale, double time_scale) override; void setTimeMin(VcdTime time) override; void setTimeMax(VcdTime time) override; void varMinDeltaTime(VcdTime) override {} - bool varIdValid(const std::string &id) override; + bool varIdValid(std::string_view id) override; void makeVar(const VcdScope &scope, - const std::string &name, + std::string_view name, VcdVarType type, size_t width, - const std::string &id) override; + std::string_view id) override; void varAppendValue(const std::string &id, VcdTime time, char value) override; void varAppendBusValue(const std::string &id, VcdTime time, - const std::string &bus_value) override; + std::string_view bus_value) override; private: - void addVarPin(const std::string &pin_name, - const std::string &id, + void addVarPin(std::string_view pin_name, + std::string_view id, size_t width, size_t bit_idx); @@ -167,7 +167,7 @@ private: Debug *debug_; }; -VcdCountReader::VcdCountReader(const std::string &scope, +VcdCountReader::VcdCountReader(std::string_view scope, const Network *sdc_network, Report *report, Debug *debug) : @@ -182,7 +182,7 @@ VcdCountReader::VcdCountReader(const std::string &scope, } void -VcdCountReader::setTimeUnit(const std::string &, +VcdCountReader::setTimeUnit(std::string_view , double time_unit_scale, double time_scale) { @@ -202,22 +202,22 @@ VcdCountReader::setTimeMax(VcdTime time) } bool -VcdCountReader::varIdValid(const std::string &) +VcdCountReader::varIdValid(std::string_view ) { return true; } void VcdCountReader::makeVar(const VcdScope &scope, - const std::string &name, + std::string_view name, VcdVarType type, size_t width, - const std::string &id) + std::string_view id) { if (type == VcdVarType::wire || type == VcdVarType::reg) { std::string path_name; bool first = true; - for (const std::string &context : scope) { + for (std::string_view context : scope) { if (!first) path_name += '/'; path_name += context; @@ -238,7 +238,7 @@ VcdCountReader::makeVar(const VcdScope &scope, bool is_bus, is_range, subscript_wild; std::string bus_name; int from, to; - parseBusName(var_scoped.c_str(), '[', ']', '\\', is_bus, is_range, bus_name, + parseBusName(var_scoped, '[', ']', '\\', is_bus, is_range, bus_name, from, to, subscript_wild); if (is_bus) { std::string sta_bus_name = netVerilogToSta(bus_name); @@ -272,18 +272,18 @@ VcdCountReader::makeVar(const VcdScope &scope, } void -VcdCountReader::addVarPin(const std::string &pin_name, - const std::string &id, +VcdCountReader::addVarPin(std::string_view pin_name, + std::string_view id, size_t width, size_t bit_idx) { - const Pin *pin = sdc_network_->findPin(pin_name.c_str()); + const Pin *pin = sdc_network_->findPin(pin_name); LibertyPort *liberty_port = pin ? sdc_network_->libertyPort(pin) : nullptr; if (pin && !sdc_network_->isHierarchical(pin) && !sdc_network_->direction(pin)->isInternal() && !sdc_network_->direction(pin)->isPowerGround() && !(liberty_port && liberty_port->isPwrGnd())) { - VcdCounts &vcd_counts = vcd_count_map_[id]; + VcdCounts &vcd_counts = vcd_count_map_[std::string(id)]; vcd_counts.resize(width); vcd_counts[bit_idx].addPin(pin); debugPrint(debug_, "read_vcd", 2, "id {} pin {}", id, pin_name); @@ -317,7 +317,7 @@ VcdCountReader::varAppendValue(const std::string &id, void VcdCountReader::varAppendBusValue(const std::string &id, VcdTime time, - const std::string &bus_value) + std::string_view bus_value) { const auto &itr = vcd_count_map_.find(id); if (itr != vcd_count_map_.end()) { @@ -347,8 +347,8 @@ VcdCountReader::varAppendBusValue(const std::string &id, class ReadVcdActivities : public StaState { public: - ReadVcdActivities(const std::string &filename, - const std::string &scope, + ReadVcdActivities(std::string_view filename, + std::string_view scope, const Sdc *sdc, Sta *sta); void readActivities(); @@ -370,9 +370,9 @@ private: }; void -readVcdActivities(const std::string &filename, - const std::string &scope, - const std::string &mode_name, +readVcdActivities(std::string_view filename, + std::string_view scope, + std::string_view mode_name, Sta *sta) { const Mode *mode = sta->findMode(mode_name); @@ -381,8 +381,8 @@ readVcdActivities(const std::string &filename, reader.readActivities(); } -ReadVcdActivities::ReadVcdActivities(const std::string &filename, - const std::string &scope, +ReadVcdActivities::ReadVcdActivities(std::string_view filename, + std::string_view scope, const Sdc *sdc, Sta *sta) : StaState(sta), diff --git a/power/VcdReader.hh b/power/VcdReader.hh index 3a2e63f5..205779a6 100644 --- a/power/VcdReader.hh +++ b/power/VcdReader.hh @@ -31,9 +31,9 @@ namespace sta { class Sta; void -readVcdActivities(const std::string &filename, - const std::string &scope, - const std::string &mode_name, +readVcdActivities(std::string_view filename, + std::string_view scope, + std::string_view mode_name, Sta *sta); } // namespace diff --git a/sdc/Clock.cc b/sdc/Clock.cc index df161fc2..f2c91633 100644 --- a/sdc/Clock.cc +++ b/sdc/Clock.cc @@ -42,10 +42,10 @@ namespace sta { static bool isPowerOfTwo(int i); -Clock::Clock(const char *name, +Clock::Clock(std::string_view name, int index, const Network *network) : - name_(stringCopy(name)), + name_(name), pins_(network), add_to_pins_(false), leaf_pins_(network), @@ -76,7 +76,7 @@ Clock::initClk(PinSet *pins, bool add_to_pins, float period, FloatSeq *waveform, - const char *comment, + std::string_view comment, const Network *network) { is_generated_ = false; @@ -87,7 +87,7 @@ Clock::initClk(PinSet *pins, waveform_valid_ = true; period_ = period; setClkEdgeTimes(); - setComment(comment); + setComment(std::move(comment)); } bool @@ -132,7 +132,6 @@ Clock::makeClkEdges() Clock::~Clock() { - stringDelete(name_); if (clk_edges_) { delete clk_edges_[RiseFall::riseIndex()]; delete clk_edges_[RiseFall::fallIndex()]; @@ -328,7 +327,7 @@ Clock::initGeneratedClk(PinSet *pins, IntSeq *edges, FloatSeq *edge_shifts, bool is_propagated, - const char *comment, + std::string_view comment, const Network *network) { is_generated_ = true; @@ -344,7 +343,7 @@ Clock::initGeneratedClk(PinSet *pins, invert_ = invert; combinational_ = combinational; is_propagated_ = is_propagated; - setComment(comment); + setComment(std::move(comment)); delete edges_; if (edges @@ -680,14 +679,6 @@ InterClockUncertaintyLess::operator()(const InterClockUncertainty *inter1, //////////////////////////////////////////////////////////////// -bool -ClockNameLess::operator()(const Clock *clk1, - const Clock *clk2) -{ - return stringLess(clk1->name(), clk2->name()); -} - - bool ClockIndexLess::operator()(const Clock *clk1, const Clock *clk2) const diff --git a/sdc/ClockGroups.cc b/sdc/ClockGroups.cc index 0bf76c38..776b54a2 100644 --- a/sdc/ClockGroups.cc +++ b/sdc/ClockGroups.cc @@ -34,8 +34,8 @@ ClockGroups::ClockGroups(const std::string &name, bool physically_exclusive, bool asynchronous, bool allow_paths, - const char *comment) : - SdcCmdComment(comment), + std::string comment) : + SdcCmdComment(std::move(comment)), name_(name), logically_exclusive_(logically_exclusive), physically_exclusive_(physically_exclusive), diff --git a/sdc/DisabledPorts.cc b/sdc/DisabledPorts.cc index 599f970b..9c3fa921 100644 --- a/sdc/DisabledPorts.cc +++ b/sdc/DisabledPorts.cc @@ -172,8 +172,7 @@ bool DisabledCellPortsLess::operator()(const DisabledCellPorts *disable1, const DisabledCellPorts *disable2) { - return stringLess(disable1->cell()->name(), - disable2->cell()->name()); + return disable1->cell()->name() < disable2->cell()->name(); } DisabledCellPortsSeq @@ -216,8 +215,8 @@ bool DisabledInstPortsLess::operator()(const DisabledInstancePorts *disable1, const DisabledInstancePorts *disable2) { - return stringLess(network_->pathName(disable1->instance()), - network_->pathName(disable2->instance())); + return network_->pathName(disable1->instance()) < + network_->pathName(disable2->instance()); } DisabledInstancePortsSeq @@ -246,12 +245,12 @@ bool LibertyPortPairNameLess::operator()(const LibertyPortPair &pair1, const LibertyPortPair &pair2) { - const char *from1 = pair1.first->name(); - const char *from2 = pair2.first->name(); - const char *to1 = pair1.second->name(); - const char *to2 = pair2.second->name(); - return stringLess(from1, from2) - || (stringEq(from1, from2) && stringLess(to1, to2)); + const std::string &from1 = pair1.first->name(); + const std::string &from2 = pair2.first->name(); + const std::string &to1 = pair1.second->name(); + const std::string &to2 = pair2.second->name(); + return from1 < from2 + || (from1 == from2 && to1 < to2); } LibertyPortPairSeq diff --git a/sdc/ExceptionPath.cc b/sdc/ExceptionPath.cc index 83bb6055..e3cb2dd5 100644 --- a/sdc/ExceptionPath.cc +++ b/sdc/ExceptionPath.cc @@ -92,7 +92,7 @@ ExceptionPath::ExceptionPath(ExceptionFrom *from, const MinMaxAll *min_max, bool own_pts, int priority, - const char *comment) : + std::string_view comment) : SdcCmdComment(comment), from_(from), thrus_(thrus), @@ -225,7 +225,7 @@ ExceptionPath::hash(ExceptionPt *missing_pt) const bool ExceptionPath::mergeable(ExceptionPath *exception) const { - return stringEqualIf(comment_, exception->comment()); + return comment_ == exception->comment(); } bool @@ -480,7 +480,7 @@ PathDelay::PathDelay(ExceptionFrom *from, bool break_path, float delay, bool own_pts, - const char *comment) : + std::string_view comment) : ExceptionPath(from, thrus, to, min_max->asMinMaxAll(), own_pts, pathDelayPriority() + fromThruToPriority(from, thrus, to), comment), @@ -565,7 +565,7 @@ FalsePath::FalsePath(ExceptionFrom *from, ExceptionTo *to, const MinMaxAll *min_max, bool own_pts, - const char *comment) : + std::string_view comment) : ExceptionPath(from, thrus, to, min_max, own_pts, falsePathPriority() + fromThruToPriority(from, thrus, to), comment) @@ -578,7 +578,7 @@ FalsePath::FalsePath(ExceptionFrom *from, const MinMaxAll *min_max, bool own_pts, int priority, - const char *comment) : + std::string_view comment) : ExceptionPath(from, thrus, to, min_max, own_pts, priority, comment) { } @@ -629,8 +629,7 @@ FalsePath::overrides(ExceptionPath *exception) const LoopPath::LoopPath(ExceptionThruSeq *thrus, bool own_pts) : FalsePath(nullptr, thrus, nullptr, MinMaxAll::all(), own_pts, - falsePathPriority() + fromThruToPriority(nullptr, thrus, nullptr), - nullptr) + falsePathPriority() + fromThruToPriority(nullptr, thrus, nullptr), "") { } @@ -655,7 +654,7 @@ MultiCyclePath::MultiCyclePath(ExceptionFrom *from, bool use_end_clk, int path_multiplier, bool own_pts, - const char *comment) : + std::string_view comment) : ExceptionPath(from, thrus, to, min_max, own_pts, multiCyclePathPriority() + fromThruToPriority(from, thrus, to), comment), @@ -756,8 +755,7 @@ FilterPath::FilterPath(ExceptionFrom *from, ExceptionTo *to, bool own_pts) : ExceptionPath(from, thrus, to, MinMaxAll::all(), own_pts, - filterPathPriority() + fromThruToPriority(from, thrus, to), - nullptr) + filterPathPriority() + fromThruToPriority(from, thrus, to), "") { } @@ -814,13 +812,13 @@ FilterPath::resetMatch(ExceptionFrom *, //////////////////////////////////////////////////////////////// -GroupPath::GroupPath(const std::string &name, +GroupPath::GroupPath(std::string_view name, bool is_default, ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, bool own_pts, - const char *comment) : + std::string_view comment) : ExceptionPath(from, thrus, to, MinMaxAll::all(), own_pts, groupPathPriority() + fromThruToPriority(from, thrus, to), comment), diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index 8889f177..27d64569 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -150,7 +150,7 @@ Sdc::makeDefaultArrivalClock() waveform->push_back(0.0); waveform->push_back(0.0); default_arrival_clk_ = new Clock("input port clock", clk_index_++, network_); - default_arrival_clk_->initClk(0, false, 0.0, waveform, nullptr, network_); + default_arrival_clk_->initClk(0, false, 0.0, waveform, "", network_); } Sdc::~Sdc() @@ -956,14 +956,14 @@ Sdc::maxArea() const //////////////////////////////////////////////////////////////// Clock * -Sdc::makeClock(const char *name, +Sdc::makeClock(std::string_view name, PinSet *pins, bool add_to_pins, float period, FloatSeq *waveform, - const char *comment) + std::string_view comment) { - Clock *clk = findKey(clock_name_map_, name); + Clock *clk = findStringKey(clock_name_map_, name); if (!add_to_pins) deletePinClocks(clk, pins); if (clk) @@ -971,7 +971,7 @@ Sdc::makeClock(const char *name, deleteClkPinMappings(clk); else { // Fresh clock definition. - clk = new Clock(name, clk_index_++, network_); + clk = new Clock(std::move(name), clk_index_++, network_); clk->setIsPropagated(variables_->propagateAllClocks()); clocks_.push_back(clk); // Use the copied name in the map. @@ -986,7 +986,7 @@ Sdc::makeClock(const char *name, } Clock * -Sdc::makeGeneratedClock(const char *name, +Sdc::makeGeneratedClock(std::string_view name, PinSet *pins, bool add_to_pins, Pin *src_pin, @@ -998,9 +998,9 @@ Sdc::makeGeneratedClock(const char *name, bool combinational, IntSeq *edges, FloatSeq *edge_shifts, - const char *comment) + std::string_view comment) { - Clock *clk = findKey(clock_name_map_, name); + Clock *clk = findStringKey(clock_name_map_, name); if (!add_to_pins) deletePinClocks(clk, pins); if (clk) @@ -1150,9 +1150,9 @@ Sdc::deleteMasterClkRefs(Clock *clk) } Clock * -Sdc::findClock(const char *name) const +Sdc::findClock(std::string_view name) const { - return findKey(clock_name_map_, name); + return findStringKey(clock_name_map_, name); } bool @@ -1220,7 +1220,7 @@ Sdc::sortedClocks() const ClockSeq clks; for (Clock *clk : clocks_) clks.push_back(clk); - sort(clks, ClkNameLess()); + sort(clks, ClockNameLess()); return clks; } @@ -1946,20 +1946,21 @@ Sdc::makeClockGroups(const std::string &name, bool physically_exclusive, bool asynchronous, bool allow_paths, - const char *comment) + std::string comment) { std::string group_name; if (name.empty()) group_name = makeClockGroupsName(); else { group_name = name; - ClockGroups *groups = findKey(clk_groups_name_map_, group_name); + ClockGroups *groups = findStringKey(clk_groups_name_map_, group_name); if (groups) removeClockGroups(groups); } ClockGroups *groups = new ClockGroups(group_name, logically_exclusive, physically_exclusive, - asynchronous, allow_paths, comment); + asynchronous, allow_paths, + std::move(comment)); clk_groups_name_map_[groups->name()] = groups; return groups; } @@ -3891,7 +3892,7 @@ Sdc::makeFalsePath(ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, const MinMaxAll *min_max, - const char *comment) + std::string_view comment) { checkFromThrusTo(from, thrus, to); FalsePath *exception = new FalsePath(from, thrus, to, min_max, true, @@ -3906,7 +3907,7 @@ Sdc::makeMulticyclePath(ExceptionFrom *from, const MinMaxAll *min_max, bool use_end_clk, int path_multiplier, - const char *comment) + std::string_view comment) { checkFromThrusTo(from, thrus, to); MultiCyclePath *exception = new MultiCyclePath(from, thrus, to, @@ -3924,7 +3925,7 @@ Sdc::makePathDelay(ExceptionFrom *from, bool ignore_clk_latency, bool break_path, float delay, - const char *comment) + std::string_view comment) { checkFromThrusTo(from, thrus, to); PathDelay *exception = new PathDelay(from, thrus, to, min_max, @@ -4090,17 +4091,18 @@ Sdc::clearGroupPathMap() } void -Sdc::makeGroupPath(const std::string &name, +Sdc::makeGroupPath(std::string_view name, bool is_default, ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, - const char *comment) + std::string_view comment) { checkFromThrusTo(from, thrus, to); if (!name.empty() && is_default) report_->critical(1490, "group path name and is_default are mutually exclusive."); else if (!name.empty()) { + const std::string name_key(name); GroupPath *group_path = new GroupPath(name, is_default, from, thrus, to, true, comment); // Clone the group_path because it may get merged and hence deleted @@ -4112,10 +4114,10 @@ Sdc::makeGroupPath(const std::string &name, ExceptionPath *clone = group_path->clone(from1, thrus1, to1, true); addException(clone); // A named group path can have multiple exceptions. - GroupPathSet *groups = findKey(group_path_map_, name); + GroupPathSet *groups = findKey(group_path_map_, name_key); if (groups == nullptr) { groups = new GroupPathSet(network_); - group_path_map_[name] = groups; + group_path_map_[name_key] = groups; } if (groups->contains(group_path)) // Exact copy of existing group path. @@ -4132,7 +4134,7 @@ Sdc::makeGroupPath(const std::string &name, } bool -Sdc::isGroupPathName(const char *group_name) const +Sdc::isGroupPathName(std::string_view group_name) const { return group_path_map_.contains(group_name); } diff --git a/sdc/Sdc.i b/sdc/Sdc.i index 0b0251f1..411d8f49 100644 --- a/sdc/Sdc.i +++ b/sdc/Sdc.i @@ -23,7 +23,8 @@ // This notice may not be removed or altered from any source distribution. %module sdc -%import + +%include "std_string.i" %{ #include @@ -91,12 +92,12 @@ private: %inline %{ void -write_sdc_cmd(const char *filename, - bool leaf, - bool compatible, - int digits, - bool gzip, - bool no_timestamp) +write_sdc_cmd(std::string filename, + bool leaf, + bool compatible, + int digits, + bool gzip, + bool no_timestamp) { Sta *sta = Sta::sta(); const Sdc *sdc = sta->cmdSdc(); @@ -104,16 +105,16 @@ write_sdc_cmd(const char *filename, } void -set_analysis_type_cmd(const char *analysis_type) +set_analysis_type_cmd(std::string analysis_type) { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); AnalysisType type; - if (stringEq(analysis_type, "single")) + if (analysis_type == "single") type = AnalysisType::single; - else if (stringEq(analysis_type, "bc_wc")) + else if (analysis_type == "bc_wc") type = AnalysisType::bc_wc; - else if (stringEq(analysis_type, "on_chip_variation")) + else if (analysis_type == "on_chip_variation") type = AnalysisType::ocv; else { sta->report()->warn(2121, "unknown analysis type"); @@ -249,7 +250,7 @@ set_net_wire_cap(const Net *net, } void -set_wire_load_mode_cmd(const char *mode_name) +set_wire_load_mode_cmd(std::string mode_name) { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); @@ -289,20 +290,21 @@ set_net_resistance(Net *net, } void -make_clock(const char *name, +make_clock(std::string name, PinSet *pins, bool add_to_pins, float period, FloatSeq *waveform, - char *comment) + std::string comment) { Sta *sta = Sta::sta(); const Mode *mode = sta->cmdMode(); - sta->makeClock(name, pins, add_to_pins, period, waveform, comment, mode); + sta->makeClock(name.c_str(), pins, add_to_pins, period, waveform, + std::move(comment), mode); } void -make_generated_clock(const char *name, +make_generated_clock(std::string name, PinSet *pins, bool add_to_pins, Pin *src_pin, @@ -314,15 +316,15 @@ make_generated_clock(const char *name, bool combinational, IntSeq *edges, FloatSeq *edge_shifts, - char *comment) + std::string comment) { Sta *sta = Sta::sta(); const Mode *mode = sta->cmdMode(); - sta->makeGeneratedClock(name, pins, add_to_pins, + sta->makeGeneratedClock(name.c_str(), pins, add_to_pins, src_pin, master_clk, divide_by, multiply_by, duty_cycle, invert, combinational, edges, edge_shifts, - comment, mode); + std::move(comment), mode); } void @@ -796,11 +798,11 @@ make_false_path(ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, const MinMaxAll *min_max, - const char *comment) + std::string comment) { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); - sta->makeFalsePath(from, thrus, to, min_max, comment, sdc); + sta->makeFalsePath(from, thrus, to, min_max, std::move(comment), sdc); } void @@ -810,12 +812,12 @@ make_multicycle_path(ExceptionFrom *from, const MinMaxAll *min_max, bool use_end_clk, int path_multiplier, - const char *comment) + std::string comment) { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); sta->makeMulticyclePath(from, thrus, to, min_max, use_end_clk, - path_multiplier, comment, sdc); + path_multiplier, std::move(comment), sdc); } void @@ -826,13 +828,13 @@ make_path_delay(ExceptionFrom *from, bool ignore_clk_latency, bool break_path, float delay, - const char *comment) + std::string comment) { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); sta->makePathDelay(from, thrus, to, min_max, ignore_clk_latency, break_path, - delay, comment, sdc); + delay, std::move(comment), sdc); } void @@ -851,20 +853,20 @@ reset_path_cmd(ExceptionFrom * } void -make_group_path(const char *name, +make_group_path(std::string name, bool is_default, ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, - const char *comment) + std::string comment) { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); - sta->makeGroupPath(name, is_default, from, thrus, to, comment, sdc); + sta->makeGroupPath(name, is_default, from, thrus, to, std::move(comment), sdc); } bool -is_path_group_name(const char *name) +is_path_group_name(std::string name) { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); @@ -879,8 +881,7 @@ make_exception_from(PinSet *from_pins, { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); - return sta->makeExceptionFrom(from_pins, from_clks, from_insts, - from_rf, sdc); + return sta->makeExceptionFrom(from_pins, from_clks, from_insts, from_rf, sdc); } void @@ -892,12 +893,12 @@ delete_exception_from(ExceptionFrom *from) void check_exception_from_pins(ExceptionFrom *from, - const char *file, + const char *filename, int line) { Sta *sta = Sta::sta(); const Sdc *sdc = sta->cmdSdc(); - sta->checkExceptionFromPins(from, file, line, sdc); + sta->checkExceptionFromPins(from, filename, line, sdc); } ExceptionThru * @@ -950,18 +951,18 @@ check_exception_to_pins(ExceptionTo *to, //////////////////////////////////////////////////////////////// ClockGroups * -make_clock_groups(const char *name, +make_clock_groups(std::string name, bool logically_exclusive, bool physically_exclusive, bool asynchronous, bool allow_paths, - const char *comment) + std::string comment) { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); return sta->makeClockGroups(name, logically_exclusive, physically_exclusive, asynchronous, - allow_paths, comment, sdc); + allow_paths, std::move(comment), sdc); } void @@ -982,7 +983,7 @@ unset_clock_groups_logically_exclusive() } void -unset_clock_groups_logically_exclusive(const char *name) +unset_clock_groups_logically_exclusive(std::string name) { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); @@ -998,7 +999,7 @@ unset_clock_groups_physically_exclusive() } void -unset_clock_groups_physically_exclusive(const char *name) +unset_clock_groups_physically_exclusive(std::string name) { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); @@ -1014,7 +1015,7 @@ unset_clock_groups_asynchronous() } void -unset_clock_groups_asynchronous(const char *name) +unset_clock_groups_asynchronous(std::string name) { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); @@ -1332,7 +1333,7 @@ unset_timing_derate_cmd() } Clock * -find_clock(const char *name) +find_clock(std::string name) { Sta *sta = Sta::sta(); Sdc *sdc = sta->cmdSdc(); @@ -1356,7 +1357,7 @@ default_arrival_clock() } ClockSeq -find_clocks_matching(const char *pattern, +find_clocks_matching(std::string pattern, bool regexp, bool nocase) { @@ -1490,28 +1491,27 @@ find_register_output_pins(ClockSet *clks, //////////////////////////////////////////////////////////////// template std::vector -filter_objects(const char *property, - const char *op, - const char *pattern, +filter_objects(std::string_view property, + std::string_view op, + std::string_view pattern, std::vector *objects) { std::vector filtered_objects; if (objects) { Sta *sta = Sta::sta(); Properties &properties = sta->properties(); - bool exact_match = stringEq(op, "=="); - bool pattern_match = stringEq(op, "=~"); - bool not_match = stringEq(op, "!="); - bool not_pattern_match = stringEq(op, "!~"); + bool exact_match = op == "=="; + bool pattern_match = op == "=~"; + bool not_match = op == "!="; + bool not_pattern_match = op == "!~"; for (T *object : *objects) { PropertyValue value(properties.getProperty(object, property)); - std::string prop_str = value.to_string(sta->network()); - const char *prop = prop_str.c_str(); - if (!prop_str.empty() - && ((exact_match && stringEq(prop, pattern)) - || (not_match && !stringEq(prop, pattern)) - || (pattern_match && patternMatch(pattern, prop)) - || (not_pattern_match && !patternMatch(pattern, prop)))) + std::string prop_value = value.to_string(sta->network()); + if (!prop_value.empty() + && ((exact_match && prop_value == pattern) + || (not_match && prop_value != pattern) + || (pattern_match && patternMatch(pattern, prop_value)) + || (not_pattern_match && !patternMatch(pattern, prop_value)))) filtered_objects.push_back(object); } delete objects; @@ -1520,81 +1520,81 @@ filter_objects(const char *property, } PortSeq -filter_ports(const char *property, - const char *op, - const char *pattern, +filter_ports(std::string_view property, + std::string_view op, + std::string_view pattern, PortSeq *ports) { return filter_objects(property, op, pattern, ports); } InstanceSeq -filter_insts(const char *property, - const char *op, - const char *pattern, +filter_insts(std::string_view property, + std::string_view op, + std::string_view pattern, InstanceSeq *insts) { return filter_objects(property, op, pattern, insts); } PinSeq -filter_pins(const char *property, - const char *op, - const char *pattern, +filter_pins(std::string_view property, + std::string_view op, + std::string_view pattern, PinSeq *pins) { return filter_objects(property, op, pattern, pins); } ClockSeq -filter_clocks(const char *property, - const char *op, - const char *pattern, +filter_clocks(std::string_view property, + std::string_view op, + std::string_view pattern, ClockSeq *clocks) { return filter_objects(property, op, pattern, clocks); } LibertyCellSeq -filter_lib_cells(const char *property, - const char *op, - const char *pattern, +filter_lib_cells(std::string_view property, + std::string_view op, + std::string_view pattern, LibertyCellSeq *cells) { return filter_objects(property, op, pattern, cells); } LibertyPortSeq -filter_lib_pins(const char *property, - const char *op, - const char *pattern, +filter_lib_pins(std::string_view property, + std::string_view op, + std::string_view pattern, LibertyPortSeq *pins) { return filter_objects(property, op, pattern, pins); } LibertyLibrarySeq -filter_liberty_libraries(const char *property, - const char *op, - const char *pattern, +filter_liberty_libraries(std::string_view property, + std::string_view op, + std::string_view pattern, LibertyLibrarySeq *libs) { return filter_objects(property, op, pattern, libs); } NetSeq -filter_nets(const char *property, - const char *op, - const char *pattern, +filter_nets(std::string_view property, + std::string_view op, + std::string_view pattern, NetSeq *nets) { return filter_objects(property, op, pattern, nets); } EdgeSeq -filter_timing_arcs(const char *property, - const char *op, - const char *pattern, +filter_timing_arcs(std::string_view property, + std::string_view op, + std::string_view pattern, EdgeSeq *edges) { return filter_objects(property, op, pattern, edges); diff --git a/sdc/SdcCmdComment.cc b/sdc/SdcCmdComment.cc index 3033ad63..083812ad 100644 --- a/sdc/SdcCmdComment.cc +++ b/sdc/SdcCmdComment.cc @@ -27,30 +27,34 @@ namespace sta { -SdcCmdComment::SdcCmdComment() : - comment_(nullptr) +SdcCmdComment::SdcCmdComment() { } -SdcCmdComment::SdcCmdComment(const char *comment) +SdcCmdComment::SdcCmdComment(std::string comment) : + comment_(std::move(comment)) { - comment_ = nullptr; - if (comment && comment[0] != '\0') - comment_ = stringCopy(comment); } - + +SdcCmdComment::SdcCmdComment(std::string_view comment) : + comment_(comment) +{ +} + SdcCmdComment::~SdcCmdComment() { - stringDelete(comment_); } + void -SdcCmdComment::setComment(const char *comment) +SdcCmdComment::setComment(std::string comment) { - if (comment_) - stringDelete(comment_); - comment_ = nullptr; - if (comment && comment[0] != '\0') - comment_ = stringCopy(comment); + comment_ = std::move(comment); +} + +void +SdcCmdComment::setComment(std::string_view comment) +{ + comment_ = comment; } } // namespace diff --git a/sdc/WriteSdc.cc b/sdc/WriteSdc.cc index 7688fc68..3af1de6a 100644 --- a/sdc/WriteSdc.cc +++ b/sdc/WriteSdc.cc @@ -24,12 +24,12 @@ #include "WriteSdc.hh" -#include #include #include #include #include #include +#include #include "ContainerHelpers.hh" #include "Format.hh" @@ -68,19 +68,19 @@ namespace sta { typedef std::set ClockSenseSet; typedef std::vector ClockSenseSeq; -static const char * +static std::string_view transRiseFallFlag(const RiseFall *rf); -static const char * +static std::string_view transRiseFallFlag(const RiseFallBoth *rf); -static const char * +static std::string_view minMaxFlag(const MinMaxAll *min_max); -static const char * +static std::string_view minMaxFlag(const MinMax *min_max); -static const char * +static std::string_view earlyLateFlag(const MinMax *early_late); -static const char * +static std::string_view setupHoldFlag(const MinMax *min_max); -static const char * +static std::string_view timingDerateTypeKeyword(TimingDerateType type); //////////////////////////////////////////////////////////////// @@ -287,8 +287,8 @@ WriteGetClock::write() const void writeSdc(const Sdc *sdc, Instance *instance, - const char *filename, - const char *creator, + std::string_view filename, + std::string_view creator, bool map_hpins, bool native, int digits, @@ -302,7 +302,7 @@ writeSdc(const Sdc *sdc, WriteSdc::WriteSdc(const Sdc *sdc, Instance *instance, - const char *creator, + std::string_view creator, bool map_hpins, bool native, int digits, @@ -316,7 +316,7 @@ WriteSdc::WriteSdc(const Sdc *sdc, digits_(digits), no_timestamp_(no_timestamp), top_instance_(instance == sdc_network_->topInstance()), - instance_name_length_(strlen(sdc_network_->pathName(instance))), + instance_name_length_(sdc_network_->pathName(instance).size()), cell_(sdc_network_->cell(instance)) { } @@ -326,7 +326,7 @@ WriteSdc::~WriteSdc() } void -WriteSdc::write(const char *filename, +WriteSdc::write(std::string_view filename, bool gzip) { openFile(filename, gzip); @@ -339,10 +339,11 @@ WriteSdc::write(const char *filename, } void -WriteSdc::openFile(const char *filename, +WriteSdc::openFile(std::string_view filename, bool gzip) { - stream_ = gzopen(filename, gzip ? "wb" : "wT"); + std::string filename_str(filename); + stream_ = gzopen(filename_str.c_str(), gzip ? "wb" : "wT"); if (stream_ == nullptr) throw FileNotWritable(filename); } @@ -361,9 +362,9 @@ WriteSdc::writeHeader() const if (!no_timestamp_) { time_t now; time(&now); - char *time_str = ctime(&now); - // Remove trailing \n. - time_str[strlen(time_str) - 1] = '\0'; + std::string time_str(ctime(&now)); + if (!time_str.empty() && time_str.back() == '\n') + time_str.pop_back(); sta::print(stream_, "# {}\n", time_str); } writeCommentSeparator(); @@ -521,7 +522,7 @@ WriteSdc::writeClockUncertainty(const Clock *clk) const void WriteSdc::writeClockUncertainty(const Clock *clk, - const char *setup_hold, + std::string_view setup_hold, float value) const { sta::print(stream_, "set_clock_uncertainty {}", setup_hold); @@ -558,7 +559,7 @@ WriteSdc::writeClockUncertaintyPin(const Pin *pin, } void WriteSdc::writeClockUncertaintyPin(const Pin *pin, - const char *setup_hold, + std::string_view setup_hold, float value) const { sta::print(stream_, "set_clock_uncertainty {}", setup_hold); @@ -726,7 +727,7 @@ WriteSdc::writeOutputDelays() const void WriteSdc::writePortDelay(PortDelay *port_delay, bool is_input_delay, - const char *sdc_cmd) const + std::string_view sdc_cmd) const { RiseFallMinMax *delays = port_delay->delays(); float rise_min, rise_max, fall_min, fall_max; @@ -793,7 +794,7 @@ WriteSdc::writePortDelay(PortDelay *port_delay, float delay, const RiseFallBoth *rf, const MinMaxAll *min_max, - const char *sdc_cmd) const + std::string_view sdc_cmd) const { sta::print(stream_, "{} ", sdc_cmd); writeTime(delay); @@ -870,7 +871,7 @@ void WriteSdc::writeClockSense(PinClockPair &pin_clk, ClockSense sense) const { - const char *flag = nullptr; + std::string_view flag; if (sense == ClockSense::positive) flag = "-positive"; else if (sense == ClockSense::negative) @@ -923,7 +924,7 @@ ClockGroupLess::operator()(const ClockGroup *clk_group1, && clk_iter4 != clks2.end()) { Clock *clk1 = *clk_iter3++; Clock *clk2 = *clk_iter4++; - int cmp = strcmp(clk1->name(), clk2->name()); + int cmp = clk1->name().compare(clk2->name()); if (cmp < 0) return true; else if (cmp > 0) @@ -1166,9 +1167,8 @@ void WriteSdc::writeDisabledEdgeSense(Edge *edge) const { sta::print(stream_, "set_disable_timing "); - const char *sense = to_string(edge->sense()); - std::string filter = sta::format("sense == {}", sense); - writeGetTimingArcs(edge, filter.c_str()); + std::string filter = sta::format("sense == {}", to_string(edge->sense())); + writeGetTimingArcs(edge, filter); sta::print(stream_, "\n"); } @@ -1275,11 +1275,11 @@ WriteSdc::writeExceptionTo(ExceptionTo *to) const void WriteSdc::writeExceptionFromTo(ExceptionFromTo *from_to, - const char *from_to_key, + std::string_view from_to_key, bool map_hpin_to_drvr) const { const RiseFallBoth *rf = from_to->transition(); - const char *rf_prefix = "-"; + std::string_view rf_prefix = "-"; if (rf == RiseFallBoth::rise()) rf_prefix = "-rise_"; else if (rf == RiseFallBoth::fall()) @@ -1320,7 +1320,7 @@ void WriteSdc::writeExceptionThru(ExceptionThru *thru) const { const RiseFallBoth *rf = thru->transition(); - const char *rf_prefix = "-"; + std::string_view rf_prefix = "-"; if (rf == RiseFallBoth::rise()) rf_prefix = "-rise_"; else if (rf == RiseFallBoth::fall()) @@ -1441,14 +1441,14 @@ WriteSdc::writeDataCheck(DataCheck *check, const SetupHold *setup_hold, float margin) const { - const char *from_key = "-from"; + std::string_view from_key = "-from"; if (from_rf == RiseFallBoth::rise()) from_key = "-rise_from"; else if (from_rf == RiseFallBoth::fall()) from_key = "-fall_from"; sta::print(stream_, "set_data_check {} ", from_key); writeGetPin(check->from(), true); - const char *to_key = "-to"; + std::string_view to_key = "-to"; if (to_rf == RiseFallBoth::rise()) to_key = "-rise_to"; else if (to_rf == RiseFallBoth::fall()) @@ -1755,13 +1755,13 @@ WriteSdc::writeConstants() const void WriteSdc::writeConstant(const Pin *pin) const { - const char *cmd = setConstantCmd(pin); + std::string_view cmd = setConstantCmd(pin); sta::print(stream_, "{} ", cmd); writeGetPin(pin, false); sta::print(stream_, "\n"); } -const char * +std::string_view WriteSdc::setConstantCmd(const Pin *pin) const { LogicValue value; @@ -1778,7 +1778,7 @@ WriteSdc::setConstantCmd(const Pin *pin) const case LogicValue::fall: default: report_->critical(1621, "illegal set_logic value"); - return nullptr; + return {}; } } @@ -1795,13 +1795,13 @@ WriteSdc::writeCaseAnalysis() const void WriteSdc::writeCaseAnalysis(const Pin *pin) const { - const char *value_str = caseAnalysisValueStr(pin); + std::string_view value_str = caseAnalysisValueStr(pin); sta::print(stream_, "set_case_analysis {} ", value_str); writeGetPin(pin, false); sta::print(stream_, "\n"); } -const char * +std::string_view WriteSdc::caseAnalysisValueStr(const Pin *pin) const { LogicValue value; @@ -1819,7 +1819,7 @@ WriteSdc::caseAnalysisValueStr(const Pin *pin) const case LogicValue::unknown: default: report_->critical(1622, "invalid set_case_analysis value"); - return nullptr; + return {}; } } @@ -1917,7 +1917,7 @@ WriteSdc::writeDerating(DeratingFactors *factors, const MinMax *early_late, WriteSdcObject *write_obj) const { - const char *type_key = timingDerateTypeKeyword(type); + std::string_view type_key = timingDerateTypeKeyword(type); bool is_one_value; float value; factors->isOneValue(early_late, is_one_value, value); @@ -1939,8 +1939,8 @@ WriteSdc::writeDerating(DeratingFactors *factors, clk_data_index < path_clk_or_data_count; clk_data_index++) { PathClkOrData clk_data = static_cast(clk_data_index); - static const char *clk_data_keys[] = {"-clock", "-data"}; - const char *clk_data_key = clk_data_keys[clk_data_index]; + static constexpr std::string_view clk_data_keys[] = {"-clock", "-data"}; + std::string_view clk_data_key = clk_data_keys[clk_data_index]; factors->isOneValue(clk_data, early_late, is_one_value, value); if (is_one_value) { if (value != 1.0) { @@ -1980,10 +1980,11 @@ WriteSdc::writeDerating(DeratingFactors *factors, } } -static const char * +static std::string_view timingDerateTypeKeyword(TimingDerateType type) { - static const char *type_keys[] = {"-cell_delay","-cell_check","-net_delay"}; + static constexpr std::string_view type_keys[] = { + "-cell_delay", "-cell_check", "-net_delay"}; return type_keys[static_cast(type)]; } @@ -2075,7 +2076,7 @@ WriteSdc::writeMinPulseWidths(RiseFallValues *min_widths, } void -WriteSdc::writeMinPulseWidth(const char *hi_low, +WriteSdc::writeMinPulseWidth(std::string_view hi_low, float value, WriteSdcObject &write_obj) const { @@ -2195,8 +2196,8 @@ WriteSdc::writeClkSlewLimits() const } void -WriteSdc::writeClkSlewLimit(const char *clk_data, - const char *rise_fall, +WriteSdc::writeClkSlewLimit(std::string_view clk_data, + std::string_view rise_fall, const Clock *clk, float limit) const { @@ -2216,7 +2217,7 @@ WriteSdc::writeCapLimits() const void WriteSdc::writeCapLimits(const MinMax *min_max, - const char *cmd) const + std::string_view cmd) const { float cap; bool exists; @@ -2274,7 +2275,7 @@ WriteSdc::writeFanoutLimits() const void WriteSdc::writeFanoutLimits(const MinMax *min_max, - const char *cmd) const + std::string_view cmd) const { float fanout; bool exists; @@ -2330,15 +2331,9 @@ WriteSdc::writeGetTimingArcsOfOjbects(const LibertyCell *cell) const sta::print(stream_, "]"); } -void -WriteSdc::writeGetTimingArcs(Edge *edge) const -{ - writeGetTimingArcs(edge, nullptr); -} - void WriteSdc::writeGetTimingArcs(Edge *edge, - const char *filter) const + std::string_view filter) const { sta::print(stream_, "[{} -from ", getTimingArcsCmd()); Vertex *from_vertex = edge->from(graph_); @@ -2346,12 +2341,12 @@ WriteSdc::writeGetTimingArcs(Edge *edge, sta::print(stream_, " -to "); Vertex *to_vertex = edge->to(graph_); writeGetPin(to_vertex->pin(), false); - if (filter) + if (!filter.empty()) sta::print(stream_, " -filter {{{}}}", filter); sta::print(stream_, "]"); } -const char * +std::string_view WriteSdc::getTimingArcsCmd() const { return native_ ? "get_timing_edges" : "get_timing_arcs"; @@ -2493,38 +2488,38 @@ WriteSdc::writeGetInstance(const Instance *inst) const sta::print(stream_, "[get_cells {{{}}}]", pathName(inst)); } -const char * +std::string WriteSdc::pathName(const Pin *pin) const { - const char *pin_path = sdc_network_->pathName(pin); + std::string pin_path = sdc_network_->pathName(pin); if (top_instance_) return pin_path; else - return pin_path + instance_name_length_ + 1; + return pin_path.substr(instance_name_length_ + 1); } -const char * +std::string WriteSdc::pathName(const Net *net) const { - const char *net_path = sdc_network_->pathName(net); + std::string net_path = sdc_network_->pathName(net); if (top_instance_) return net_path; else - return net_path + instance_name_length_ + 1; + return net_path.substr(instance_name_length_ + 1); } -const char * +std::string WriteSdc::pathName(const Instance *inst) const { - const char *inst_path = sdc_network_->pathName(inst); + std::string inst_path = sdc_network_->pathName(inst); if (top_instance_) return inst_path; else - return inst_path + instance_name_length_ + 1; + return inst_path.substr(instance_name_length_ + 1); } void -WriteSdc::writeCommentSection(const char *line) const +WriteSdc::writeCommentSection(std::string_view line) const { writeCommentSeparator(); sta::print(stream_, "# {}\n", line); @@ -2540,7 +2535,7 @@ WriteSdc::writeCommentSeparator() const //////////////////////////////////////////////////////////////// void -WriteSdc::writeRiseFallMinMaxTimeCmd(const char *sdc_cmd, +WriteSdc::writeRiseFallMinMaxTimeCmd(std::string_view sdc_cmd, const RiseFallMinMax *values, WriteSdcObject &write_object) const { @@ -2549,7 +2544,7 @@ WriteSdc::writeRiseFallMinMaxTimeCmd(const char *sdc_cmd, } void -WriteSdc::writeRiseFallMinMaxCapCmd(const char *sdc_cmd, +WriteSdc::writeRiseFallMinMaxCapCmd(std::string_view sdc_cmd, const RiseFallMinMax *values, WriteSdcObject &write_object) const { @@ -2558,7 +2553,7 @@ WriteSdc::writeRiseFallMinMaxCapCmd(const char *sdc_cmd, } void -WriteSdc::writeRiseFallMinMaxCmd(const char *sdc_cmd, +WriteSdc::writeRiseFallMinMaxCmd(std::string_view sdc_cmd, const RiseFallMinMax *values, float scale, WriteSdcObject &write_object) const @@ -2625,7 +2620,7 @@ WriteSdc::writeRiseFallMinMaxCmd(const char *sdc_cmd, } void -WriteSdc::writeRiseFallMinMaxCmd(const char *sdc_cmd, +WriteSdc::writeRiseFallMinMaxCmd(std::string_view sdc_cmd, float value, float scale, const RiseFallBoth *rf, @@ -2652,7 +2647,7 @@ WriteSdc::writeClockKey(const Clock *clk) const //////////////////////////////////////////////////////////////// void -WriteSdc::writeMinMaxFloatValuesCmd(const char *sdc_cmd, +WriteSdc::writeMinMaxFloatValuesCmd(std::string_view sdc_cmd, const MinMaxFloatValues *values, float scale, WriteSdcObject &write_object) const @@ -2675,7 +2670,7 @@ WriteSdc::writeMinMaxFloatValuesCmd(const char *sdc_cmd, } void -WriteSdc::writeMinMaxFloatCmd(const char *sdc_cmd, +WriteSdc::writeMinMaxFloatCmd(std::string_view sdc_cmd, float value, float scale, const MinMaxAll *min_max, @@ -2691,7 +2686,7 @@ WriteSdc::writeMinMaxFloatCmd(const char *sdc_cmd, } void -WriteSdc::writeMinMaxIntValuesCmd(const char *sdc_cmd, +WriteSdc::writeMinMaxIntValuesCmd(std::string_view sdc_cmd, const MinMaxIntValues *values, WriteSdcObject &write_object) const { @@ -2713,7 +2708,7 @@ WriteSdc::writeMinMaxIntValuesCmd(const char *sdc_cmd, } void -WriteSdc::writeMinMaxIntCmd(const char *sdc_cmd, +WriteSdc::writeMinMaxIntCmd(std::string_view sdc_cmd, int value, const MinMaxAll *min_max, WriteSdcObject &write_object) const @@ -2802,13 +2797,13 @@ WriteSdc::writeIntSeq(IntSeq *ints) const //////////////////////////////////////////////////////////////// -static const char * +static std::string_view transRiseFallFlag(const RiseFall *rf) { return (rf == RiseFall::rise()) ? "-rise" : "-fall"; } -static const char * +static std::string_view transRiseFallFlag(const RiseFallBoth *rf) { if (rf == RiseFallBoth::rise()) @@ -2819,7 +2814,7 @@ transRiseFallFlag(const RiseFallBoth *rf) return ""; } -static const char * +static std::string_view minMaxFlag(const MinMaxAll *min_max) { if (min_max == MinMaxAll::min()) @@ -2830,13 +2825,13 @@ minMaxFlag(const MinMaxAll *min_max) return ""; } -static const char * +static std::string_view minMaxFlag(const MinMax *min_max) { return (min_max == MinMax::min()) ? " -min" : " -max"; } -static const char * +static std::string_view earlyLateFlag(const MinMax *early_late) { return (early_late == MinMax::min()) ? "-early" : "-late"; @@ -2851,7 +2846,7 @@ WriteSdc::writeSetupHoldFlag(const MinMaxAll *min_max) const sta::print(stream_, " -setup"); } -static const char * +static std::string_view setupHoldFlag(const MinMax *min_max) { return (min_max == MinMax::min()) ? " -hold" : " -setup"; @@ -2860,10 +2855,9 @@ setupHoldFlag(const MinMax *min_max) void WriteSdc::writeCmdComment(SdcCmdComment *cmd) const { - const char *comment = cmd->comment(); - if (comment) { + const std::string comment = cmd->comment(); + if (!comment.empty()) sta::print(stream_, " -comment {{{}}}", comment); - } } } // namespace diff --git a/sdc/WriteSdc.hh b/sdc/WriteSdc.hh index 3ac822e1..0e2b33c3 100644 --- a/sdc/WriteSdc.hh +++ b/sdc/WriteSdc.hh @@ -24,6 +24,8 @@ #pragma once +#include + #include "NetworkClass.hh" #include "SdcClass.hh" @@ -34,8 +36,8 @@ namespace sta { void writeSdc(const Sdc *sdc, Instance *instance, - const char *filename, - const char *creator, + std::string_view filename, + std::string_view creator, // Map hierarchical pins and instances to leaf pins and instances. bool map_hpins, // Replace non-sdc get functions with OpenSTA equivalents. diff --git a/sdc/WriteSdcPvt.hh b/sdc/WriteSdcPvt.hh index b4adae56..88600c77 100644 --- a/sdc/WriteSdcPvt.hh +++ b/sdc/WriteSdcPvt.hh @@ -24,6 +24,9 @@ #pragma once +#include +#include + #include "Zlib.hh" #include "NetworkClass.hh" #include "GraphClass.hh" @@ -38,16 +41,16 @@ class WriteSdc : public StaState public: WriteSdc(const Sdc *sdc, Instance *instance, - const char *creator, + std::string_view creator, bool map_hpins, bool native, int digits, bool no_timestamp); virtual ~WriteSdc(); - void write(const char *filename, + void write(std::string_view filename, bool gzip); - void openFile(const char *filename, + void openFile(std::string_view filename, bool gzip); void closeFile(); virtual void writeHeader() const; @@ -75,13 +78,13 @@ public: void writeClockSlews(const Clock *clk) const; void writeClockUncertainty(const Clock *clk) const; void writeClockUncertainty(const Clock *clk, - const char *setup_hold, + std::string_view setup_hold, float value) const; void writeClockUncertaintyPins() const; void writeClockUncertaintyPin(const Pin *pin, ClockUncertainties *uncertainties) const; void writeClockUncertaintyPin(const Pin *pin, - const char *setup_hold, + std::string_view setup_hold, float value) const; void writeClockLatencies() const; void writeClockInsertions() const; @@ -94,13 +97,13 @@ public: void writeOutputDelays() const; void writePortDelay(PortDelay *port_delay, bool is_input_delay, - const char *sdc_cmd) const; + std::string_view sdc_cmd) const; void writePortDelay(PortDelay *port_delay, bool is_input_delay, float delay, const RiseFallBoth *rf, const MinMaxAll *min_max, - const char *sdc_cmd) const; + std::string_view sdc_cmd) const; void writeClockSenses() const; void writeClockSense(PinClockPair &pin_clk, ClockSense sense) const; @@ -113,7 +116,7 @@ public: void writeExceptionFrom(ExceptionFrom *from) const; void writeExceptionTo(ExceptionTo *to) const; void writeExceptionFromTo(ExceptionFromTo *from_to, - const char *from_to_key, + std::string_view from_to_key, bool map_hpin_to_drvr) const; void writeExceptionThru(ExceptionThru *thru) const; void mapThruHpins(ExceptionThru *thru, @@ -144,10 +147,10 @@ public: const MinMax *min_max) const; void writeConstants() const; virtual void writeConstant(const Pin *pin) const; - const char *setConstantCmd(const Pin *pin) const; + std::string_view setConstantCmd(const Pin *pin) const; void writeCaseAnalysis() const; virtual void writeCaseAnalysis(const Pin *pin) const; - const char *caseAnalysisValueStr(const Pin *pin) const; + std::string_view caseAnalysisValueStr(const Pin *pin) const; void sortedLogicValuePins(const LogicValueMap &value_map, PinSeq &pins) const; void writeNetResistances() const; @@ -158,17 +161,17 @@ public: void writeMinPulseWidths() const; void writeMinPulseWidths(RiseFallValues *min_widths, WriteSdcObject &write_obj) const; - void writeMinPulseWidth(const char *hi_low, + void writeMinPulseWidth(std::string_view hi_low, float value, WriteSdcObject &write_obj) const; void writeSlewLimits() const; void writeCapLimits() const; void writeCapLimits(const MinMax *min_max, - const char *cmd) const; + std::string_view cmd) const; void writeMaxArea() const; void writeFanoutLimits() const; void writeFanoutLimits(const MinMax *min_max, - const char *cmd) const; + std::string_view cmd) const; void writeLatchBorowLimits() const; void writeDeratings() const; void writeDerating(DeratingFactorsGlobal *factors) const; @@ -180,17 +183,16 @@ public: WriteSdcObject *write_obj) const; void writeVoltages() const; - const char *pathName(const Pin *pin) const; - const char *pathName(const Net *net) const; - const char *pathName(const Instance *inst) const; - void writeCommentSection(const char *line) const; + std::string pathName(const Pin *pin) const; + std::string pathName(const Net *net) const; + std::string pathName(const Instance *inst) const; + void writeCommentSection(std::string_view line) const; void writeCommentSeparator() const; void writeGetTimingArcsOfOjbects(const LibertyCell *cell) const; - void writeGetTimingArcs(Edge *edge) const; void writeGetTimingArcs(Edge *edge, - const char *filter) const; - const char *getTimingArcsCmd() const; + std::string_view filter = {}) const; + std::string_view getTimingArcsCmd() const; void writeGetLibCell(const LibertyCell *cell) const; void writeGetLibPin(const LibertyPort *port) const; void writeGetClock(const Clock *clk) const; @@ -217,39 +219,39 @@ public: void writeResistance(float res) const; void writeClkSlewLimits() const; - void writeClkSlewLimit(const char *clk_data, - const char *rise_fall, + void writeClkSlewLimit(std::string_view clk_data, + std::string_view rise_fall, const Clock *clk, float limit) const; - void writeRiseFallMinMaxTimeCmd(const char *sdc_cmd, + void writeRiseFallMinMaxTimeCmd(std::string_view sdc_cmd, const RiseFallMinMax *values, WriteSdcObject &write_object) const; - void writeRiseFallMinMaxCapCmd(const char *sdc_cmd, + void writeRiseFallMinMaxCapCmd(std::string_view sdc_cmd, const RiseFallMinMax *values, WriteSdcObject &write_object) const; - void writeRiseFallMinMaxCmd(const char *sdc_cmd, + void writeRiseFallMinMaxCmd(std::string_view sdc_cmd, const RiseFallMinMax *values, float scale, WriteSdcObject &write_object) const; - void writeRiseFallMinMaxCmd(const char *sdc_cmd, + void writeRiseFallMinMaxCmd(std::string_view sdc_cmd, float value, float scale, const RiseFallBoth *rf, const MinMaxAll *min_max, WriteSdcObject &write_object) const; - void writeMinMaxFloatValuesCmd(const char *sdc_cmd, + void writeMinMaxFloatValuesCmd(std::string_view sdc_cmd, const MinMaxFloatValues *values, float scale, WriteSdcObject &write_object) const; - void writeMinMaxFloatCmd(const char *sdc_cmd, + void writeMinMaxFloatCmd(std::string_view sdc_cmd, float value, float scale, const MinMaxAll *min_max, WriteSdcObject &write_object) const; - void writeMinMaxIntValuesCmd(const char *sdc_cmd, + void writeMinMaxIntValuesCmd(std::string_view sdc_cmd, const MinMaxIntValues *values, WriteSdcObject &write_object) const; - void writeMinMaxIntCmd(const char *sdc_cmd, + void writeMinMaxIntCmd(std::string_view sdc_cmd, int value, const MinMaxAll *min_max, WriteSdcObject &write_object) const; @@ -262,7 +264,7 @@ public: protected: const Sdc *sdc_; Instance *instance_; - const char *creator_; + std::string creator_; bool map_hpins_; bool native_; int digits_; diff --git a/sdf/ReportAnnotation.cc b/sdf/ReportAnnotation.cc index 8f667b71..dce57ee1 100644 --- a/sdf/ReportAnnotation.cc +++ b/sdf/ReportAnnotation.cc @@ -24,6 +24,8 @@ #include "sdf/ReportAnnotation.hh" +#include + #include "StringUtil.hh" #include "Report.hh" #include "TimingRole.hh" @@ -91,7 +93,7 @@ protected: void reportPeriodArcs(const Pin *pin, bool report_annotated, int &i); - void reportCount(const char *title, + void reportCount(std::string_view title, int index, int &total, int &annotated_total); @@ -301,7 +303,7 @@ ReportAnnotated::reportCheckCount(const TimingRole *role, int index = role->index(); if (edge_count_[index] > 0) { std::string title = sta::format("cell {} arcs", role->to_string()); - reportCount(title.c_str(), index, total, annotated_total); + reportCount(title, index, total, annotated_total); } } @@ -432,7 +434,7 @@ ReportAnnotated::findPeriodCount(Pin *pin) } void -ReportAnnotated::reportCount(const char *title, +ReportAnnotated::reportCount(std::string_view title, int index, int &total, int &annotated_total) @@ -496,9 +498,9 @@ ReportAnnotated::reportArcs(Vertex *vertex, const Pin *to_pin = edge->to(graph_)->pin(); if (delayAnnotated(edge) == report_annotated && report_role_[roleIndex(role, from_pin, to_pin)]) { - const char *role_name; + std::string_view role_name; if (role->isTimingCheck()) - role_name = role->to_string().c_str(); + role_name = role->to_string(); else if (role->isWire()) { if (network_->isTopLevelPort(from_pin)) role_name = "primary input net"; diff --git a/sdf/Sdf.i b/sdf/Sdf.i index 66c47924..89b1fdd2 100644 --- a/sdf/Sdf.i +++ b/sdf/Sdf.i @@ -25,7 +25,7 @@ %module sdf %{ -#include "sdf/SdfReader.hh" +#include #include "sdf/ReportAnnotation.hh" #include "sdf/SdfWriter.hh" #include "Search.hh" @@ -35,8 +35,6 @@ using sta::Sta; using sta::AnalysisType; using sta::MinMax; using sta::MinMaxAllNull; -using sta::stringEq; -using sta::readSdf; using sta::reportAnnotatedDelay; using sta::reportAnnotatedCheck; @@ -51,22 +49,16 @@ using sta::reportAnnotatedCheck; // Return true if successful. bool -read_sdf_file(const char *filename, - const char *path, +read_sdf_file(std::string filename, + std::string path, Scene *scene, bool unescaped_dividers, bool incremental_only, MinMaxAllNull *cond_use) { Sta *sta = Sta::sta(); - sta->ensureLibLinked(); - sta->ensureGraph(); - if (stringEq(path, "")) - path = NULL; - bool success = readSdf(filename, path, scene, unescaped_dividers, - incremental_only, cond_use, sta); - sta->search()->arrivalsInvalid(); - return success; + return sta->readSdf(filename, path, scene, unescaped_dividers, + incremental_only, cond_use); } void diff --git a/sdf/SdfLex.ll b/sdf/SdfLex.ll index 19849ff3..518915c7 100644 --- a/sdf/SdfLex.ll +++ b/sdf/SdfLex.ll @@ -23,6 +23,10 @@ // // This notice may not be removed or altered from any source distribution. +#include +#include +#include + #include "util/FlexDisableRegister.hh" #include "sdf/SdfReaderPvt.hh" #include "SdfParse.hh" @@ -82,7 +86,7 @@ EOL \r?\n "\"" { BEGIN INITIAL; - yylval->string = new std::string(token_); + yylval->emplace(std::move(token_)); return token::QSTRING; } @@ -98,12 +102,12 @@ EOL \r?\n "//"[^\n]*{EOL} { loc->lines(); loc->step(); } ("-"|"+")?([0-9]*)("."[0-9]+)([eE]("-"|"+")?[0-9]+)? { - yylval->number = atof(yytext); + yylval->emplace(static_cast(atof(yytext))); return token::FNUMBER; } "+"?[0-9]+ { - yylval->integer = atoi(yytext); + yylval->emplace(atoi(yytext)); return token::DNUMBER; } @@ -157,7 +161,7 @@ COND { "("{BLANK}*IOPATH { BEGIN INITIAL; - yylval->string = new std::string(token_); + yylval->emplace(std::move(token_)); return token::EXPR_OPEN_IOPATH; } @@ -167,7 +171,7 @@ COND { */ if (reader_->inTimingCheck()) { BEGIN INITIAL; - yylval->string = new std::string(token_); + yylval->emplace(std::move(token_)); return token::EXPR_OPEN; } else @@ -181,7 +185,7 @@ COND { /* remove trailing ")" */ std::string cond_id(token_); cond_id += yytext; - yylval->string = new std::string(cond_id.substr(0, cond_id.size() - 1)); + yylval->emplace(cond_id.substr(0, cond_id.size() - 1)); /* No way to pass expr and id separately, so pass them together. */ return token::EXPR_ID_CLOSE; } @@ -194,7 +198,7 @@ COND { . { token_ += yytext[0]; } {ID} { - yylval->string = new std::string(yytext); + yylval->emplace(yytext); return token::ID; } diff --git a/sdf/SdfParse.yy b/sdf/SdfParse.yy index 6c9c3efb..7570f5df 100644 --- a/sdf/SdfParse.yy +++ b/sdf/SdfParse.yy @@ -24,6 +24,8 @@ %{ #include +#include +#include #include "sdf/SdfReaderPvt.hh" #include "sdf/SdfScanner.hh" @@ -52,21 +54,14 @@ sta::SdfParse::error(const location_type &loc, %parse-param { SdfScanner *scanner } %parse-param { SdfReader *reader } %define api.parser.class {SdfParse} +%define api.value.type variant // expected shift/reduce conflicts %expect 4 -%union { - char character; - std::string *string; - float number; - float *number_ptr; - int integer; - sta::SdfTriple *triple; - sta::SdfTripleSeq *delval_list; - sta::SdfPortSpec *port_spec; - const sta::Transition *transition; -} +%token QSTRING ID EXPR_OPEN_IOPATH EXPR_OPEN EXPR_ID_CLOSE +%token FNUMBER +%token DNUMBER %token DELAYFILE SDFVERSION DESIGN DATE VENDOR PROGRAM PVERSION %token DIVIDER VOLTAGE PROCESS TEMPERATURE TIMESCALE @@ -75,21 +70,15 @@ sta::SdfParse::error(const location_type &loc, %token IOPATH TIMINGCHECK %token SETUP HOLD SETUPHOLD RECOVERY REMOVAL RECREM WIDTH PERIOD SKEW NOCHANGE %token POSEDGE NEGEDGE COND CONDELSE -%token QSTRING ID FNUMBER DNUMBER EXPR_OPEN_IOPATH EXPR_OPEN EXPR_ID_CLOSE -%type FNUMBER NUMBER -%type DNUMBER -%type number_opt -%type value triple -%type delval_list -%type QSTRING ID path port port_instance -%type EXPR_OPEN_IOPATH EXPR_OPEN EXPR_ID_CLOSE -%type port_spec port_tchk -%type port_transition -%type hchar - -// Used by error recovery. -%destructor { delete $$; } QSTRING +%type NUMBER +%type number_opt +%type value triple +%type delval_list +%type path port port_instance +%type port_spec port_tchk +%type port_transition +%type hchar %start file @@ -106,17 +95,17 @@ header: // technically the ordering of these statements is fixed by the spec header_stmt: - '(' SDFVERSION QSTRING ')' { delete $3; } -| '(' DESIGN QSTRING ')' { delete $3; } -| '(' DATE QSTRING ')' { delete $3; } -| '(' VENDOR QSTRING ')' { delete $3; } -| '(' PROGRAM QSTRING ')' { delete $3; } -| '(' PVERSION QSTRING ')' { delete $3; } + '(' SDFVERSION QSTRING ')' +| '(' DESIGN QSTRING ')' +| '(' DATE QSTRING ')' +| '(' VENDOR QSTRING ')' +| '(' PROGRAM QSTRING ')' +| '(' PVERSION QSTRING ')' | '(' DIVIDER hchar ')' { reader->setDivider($3); } | '(' VOLTAGE triple ')' { reader->deleteTriple($3); } | '(' VOLTAGE NUMBER ')' | '(' VOLTAGE ')' // Illegal SDF (from OC). -| '(' PROCESS QSTRING ')' { delete $3; } +| '(' PROCESS QSTRING ')' | '(' PROCESS ')' // Illegal SDF (from OC). | '(' TEMPERATURE NUMBER ')' | '(' TEMPERATURE triple ')' { reader->deleteTriple($3); } @@ -152,7 +141,7 @@ celltype: cell_instance: '(' INSTANCE ')' - { reader->setInstance(nullptr); } + { reader->setInstance(); } | '(' INSTANCE '*' ')' { reader->setInstanceWildcard(); } | '(' INSTANCE path ')' @@ -195,10 +184,10 @@ path: del_def: '(' IOPATH port_spec port_instance retains delval_list ')' - { reader->iopath($3, $4, $6, nullptr, false); } + { reader->iopath($3, $4, $6, "", false); } | '(' CONDELSE '(' IOPATH port_spec port_instance retains delval_list ')' ')' - { reader->iopath($5, $6, $8, nullptr, true); } + { reader->iopath($5, $6, $8, "", true); } | '(' COND EXPR_OPEN_IOPATH port_spec port_instance retains delval_list ')' ')' { reader->iopath($4, $5, $7, $3, false); } @@ -296,15 +285,16 @@ port: port_instance: port + { $$ = $1; } | path hchar port { $$ = reader->makePath($1, $3); } ; port_spec: port_instance - { $$=reader->makePortSpec(sta::Transition::riseFall(),$1,nullptr); } + { $$ = reader->makePortSpec(sta::Transition::riseFall(), $1); } | '(' port_transition port_instance ')' - { $$ = reader->makePortSpec($2, $3, nullptr); } + { $$ = reader->makePortSpec($2, $3); } ; port_transition: @@ -314,6 +304,7 @@ port_transition: port_tchk: port_spec + { $$ = $1; } | '(' COND EXPR_ID_CLOSE { $$ = reader->makeCondPortSpec($3); } | '(' COND EXPR_OPEN port_transition port_instance ')' ')' @@ -352,6 +343,7 @@ triple: NUMBER: FNUMBER + { $$ = $1; } | DNUMBER { $$ = static_cast($1); } | '-' DNUMBER diff --git a/sdf/SdfReader.cc b/sdf/SdfReader.cc index 65a2bb8e..6a5bfd0b 100644 --- a/sdf/SdfReader.cc +++ b/sdf/SdfReader.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include "ContainerHelpers.hh" #include "Zlib.hh" @@ -64,22 +65,21 @@ class SdfPortSpec { public: SdfPortSpec(const Transition *tr, - const std::string *port, - const std::string *cond); - ~SdfPortSpec(); - const std::string *port() const { return port_; } + std::string_view port, + std::string_view cond); + std::string_view port() const { return port_; } const Transition *transition() const { return tr_; } - const std::string *cond() const { return cond_; } + std::string_view cond() const { return cond_; } private: const Transition *tr_; - const std::string *port_; - const std::string *cond_; // timing checks only + const std::string port_; + const std::string cond_; // timing checks only }; bool -readSdf(const char *filename, - const char *path, +readSdf(std::string_view filename, + std::string_view path, Scene *scene, bool unescaped_dividers, bool incremental_only, @@ -95,8 +95,8 @@ readSdf(const char *filename, return success; } -SdfReader::SdfReader(const char *filename, - const char *path, +SdfReader::SdfReader(std::string_view filename, + std::string_view path, int arc_min_index, int arc_max_index, AnalysisType analysis_type, @@ -118,7 +118,6 @@ SdfReader::SdfReader(const char *filename, divider_('/'), escape_('\\'), instance_(nullptr), - cell_name_(nullptr), in_timing_check_(false), in_incremental_(false), timescale_(1.0E-9F) // default units of ns @@ -136,7 +135,7 @@ SdfReader::~SdfReader() bool SdfReader::read() { - gzstream::igzstream stream(filename_.c_str()); + gzstream::igzstream stream(std::string(filename_).c_str()); if (stream.is_open()) { Stats stats(debug_, report_); SdfScanner scanner(&stream, filename_, this, report_); @@ -158,26 +157,25 @@ SdfReader::setDivider(char divider) void SdfReader::setTimescale(float multiplier, - const std::string *units) + std::string_view units) { if (multiplier == 1.0 || multiplier == 10.0 || multiplier == 100.0) { - if (*units == "us") + if (units == "us") timescale_ = multiplier * 1E-6F; - else if (*units == "ns") + else if (units == "ns") timescale_ = multiplier * 1E-9F; - else if (*units == "ps") + else if (units == "ps") timescale_ = multiplier * 1E-12F; else error(180, "TIMESCALE units not us, ns, or ps."); } else error(181, "TIMESCALE multiplier not 1, 10, or 100."); - delete units; } void -SdfReader::interconnect(const std::string *from_pin_name, - const std::string *to_pin_name, +SdfReader::interconnect(std::string_view from_pin_name, + std::string_view to_pin_name, SdfTripleSeq *triples) { // Ignore non-incremental annotations in incremental only mode. @@ -194,38 +192,36 @@ SdfReader::interconnect(const std::string *from_pin_name, bool to_is_hier = network_->isHierarchical(to_pin); if (from_is_hier || to_is_hier) { if (from_is_hier) - error(182, "pin {} is a hierarchical pin.", *from_pin_name); + error(182, "pin {} is a hierarchical pin.", from_pin_name); if (to_is_hier) - error(183, "pin {} is a hierarchical pin.", *to_pin_name); + error(183, "pin {} is a hierarchical pin.", to_pin_name); } else warn(184, "INTERCONNECT from {} to {} not found.", - *from_pin_name, *to_pin_name); + from_pin_name, to_pin_name); } } else { if (from_pin == nullptr) - warn(185, "pin {} not found.", *from_pin_name); + warn(185, "pin {} not found.", from_pin_name); if (to_pin == nullptr) - warn(186, "pin {} not found.", *to_pin_name); + warn(186, "pin {} not found.", to_pin_name); } } - delete from_pin_name; - delete to_pin_name; deleteTripleSeq(triples); } void -SdfReader::port(const std::string *to_pin_name, +SdfReader::port(std::string_view to_pin_name, SdfTripleSeq *triples) { // Ignore non-incremental annotations in incremental only mode. if (!(is_incremental_only_ && !in_incremental_)) { Pin *to_pin = (instance_) - ? network_->findPinRelative(instance_, to_pin_name->c_str()) - : network_->findPin(to_pin_name->c_str()); + ? network_->findPinRelative(instance_, to_pin_name) + : network_->findPin(to_pin_name); if (to_pin == nullptr) - warn(187, "pin {} not found.", *to_pin_name); + warn(187, "pin {} not found.", to_pin_name); else { Vertex *vertex = graph_->pinLoadVertex(to_pin); VertexInEdgeIterator edge_iter(vertex, graph_); @@ -236,7 +232,6 @@ SdfReader::port(const std::string *to_pin_name, } } } - delete to_pin_name; deleteTripleSeq(triples); } @@ -262,7 +257,7 @@ SdfReader::findWireEdge(Pin *from_pin, void SdfReader::setEdgeDelays(Edge *edge, SdfTripleSeq *triples, - const char *sdf_cmd) + std::string_view sdf_cmd) { // Rise/fall triples. size_t triple_count = triples->size(); @@ -285,59 +280,61 @@ SdfReader::setEdgeDelays(Edge *edge, } void -SdfReader::setCell(const std::string *cell_name) +SdfReader::setCell(std::string_view cell_name) { cell_name_ = cell_name; } void -SdfReader::setInstance(const std::string *instance_name) +SdfReader::setInstance() { - if (instance_name) { - if (*instance_name == "*") { - notSupported("INSTANCE wildcards"); - instance_ = nullptr; - } - else { - instance_ = findInstance(instance_name); - if (instance_) { - Cell *inst_cell = network_->cell(instance_); - const char *inst_cell_name = network_->name(inst_cell); - if (cell_name_ && !stringEq(inst_cell_name, cell_name_->c_str())) - warn(190, "instance {} cell {} does not match enclosing cell {}.", - *instance_name, inst_cell_name, *cell_name_); - } + instance_ = nullptr; +} + +void +SdfReader::setInstance(std::string_view instance_name) +{ + if (instance_name == "*") { + warn(193, "INSTANCE wildcards not supported."); + instance_ = nullptr; + } + else { + instance_ = findInstance(instance_name); + if (instance_) { + Cell *inst_cell = network_->cell(instance_); + std::string inst_cell_name(network_->name(inst_cell)); + if (inst_cell_name != cell_name_) + warn(190, "instance {} cell {} does not match enclosing cell {}.", + instance_name, + inst_cell_name, + cell_name_); } } - else - instance_ = nullptr; - delete instance_name; } void SdfReader::setInstanceWildcard() { - notSupported("INSTANCE wildcards"); + warn(172, "INSTANCE wildcards not supported."); instance_ = nullptr; } void SdfReader::cellFinish() { - delete cell_name_; - cell_name_ = nullptr; + cell_name_.clear(); instance_ = nullptr; } void SdfReader::iopath(SdfPortSpec *from_edge, - const std::string *to_port_name, + std::string_view to_port_name, SdfTripleSeq *triples, - const std::string *cond, + std::string_view cond, bool condelse) { if (instance_) { - const std::string *from_port_name = from_edge->port(); + std::string_view from_port_name = from_edge->port(); Cell *cell = network_->cell(instance_); Port *from_port = findPort(cell, from_port_name); Port *to_port = findPort(cell, to_port_name); @@ -360,8 +357,8 @@ SdfReader::iopath(SdfPortSpec *from_edge, TimingArcSet *arc_set = edge->timingArcSet(); const std::string &lib_cond = arc_set->sdfCond(); const TimingRole *edge_role = arc_set->role(); - bool cond_use_flag = cond_use_ && cond && lib_cond.empty() - && !(!is_incremental_only_ && in_incremental_); + bool cond_use_flag = cond_use_ && !cond.empty() && lib_cond.empty() + && !(!is_incremental_only_ && in_incremental_); if (edge->from(graph_)->pin() == from_pin && edge_role->sdfRole() == TimingRole::sdfIopath() && (cond_use_flag @@ -392,26 +389,25 @@ SdfReader::iopath(SdfPortSpec *from_edge, } if (!matched) warn(191, "cell {} IOPATH {} -> {} not found.", - network_->cellName(instance_), *from_port_name, - *to_port_name); + network_->cellName(instance_), + from_port_name, + to_port_name); } } } } - delete to_port_name; delete from_edge; deleteTripleSeq(triples); - delete cond; } Port * SdfReader::findPort(const Cell *cell, - const std::string *port_name) + std::string_view port_name) { - Port *port = network_->findPort(cell, port_name->c_str()); + Port *port = network_->findPort(cell, port_name); if (port == nullptr) warn(194, "instance {} port {} not found.", network_->pathName(instance_), - *port_name); + port_name); return port; } @@ -422,8 +418,8 @@ SdfReader::timingCheck(const TimingRole *role, SdfTriple *triple) { if (instance_) { - const std::string *data_port_name = data_edge->port(); - const std::string *clk_port_name = clk_edge->port(); + std::string_view data_port_name = data_edge->port(); + std::string_view clk_port_name = clk_edge->port(); Cell *cell = network_->cell(instance_); Port *data_port = findPort(cell, data_port_name); Port *clk_port = findPort(cell, clk_port_name); @@ -495,8 +491,8 @@ SdfReader::annotateCheckEdges(Pin *data_pin, bool match_generic) { bool matched = false; - const std::string *cond_start = data_edge->cond(); - const std::string *cond_end = clk_edge->cond(); + std::string_view cond_start = data_edge->cond(); + std::string_view cond_end = clk_edge->cond(); // Timing check graph edges from clk to data. Vertex *to_vertex = graph_->pinLoadVertex(data_pin); // Fanin < fanout, so search for driver from load. @@ -506,10 +502,10 @@ SdfReader::annotateCheckEdges(Pin *data_pin, if (edge->from(graph_)->pin() == clk_pin) { TimingArcSet *arc_set = edge->timingArcSet(); const TimingRole *edge_role = arc_set->role(); - const std::string &lib_cond_start = arc_set->sdfCondStart(); - const std::string &lib_cond_end = arc_set->sdfCondEnd(); + std::string_view lib_cond_start = arc_set->sdfCondStart(); + std::string_view lib_cond_end = arc_set->sdfCondEnd(); bool cond_matches = - condMatch(cond_start, lib_cond_start) && condMatch(cond_end, lib_cond_end); + condMatch(cond_start, lib_cond_start) && condMatch(cond_end, lib_cond_end); if (((!match_generic && edge_role->sdfRole() == sdf_role) || (match_generic && edge_role->genericRole() == sdf_role->genericRole())) && cond_matches) { @@ -535,11 +531,11 @@ SdfReader::timingCheckWidth(SdfPortSpec *edge, { // Ignore non-incremental annotations in incremental only mode. if (!(is_incremental_only_ && !in_incremental_) && instance_) { - const std::string *port_name = edge->port(); + std::string_view port_name = edge->port(); Cell *cell = network_->cell(instance_); Port *port = findPort(cell, port_name); if (port) { - Pin *pin = network_->findPin(instance_, port_name->c_str()); + Pin *pin = network_->findPin(instance_, port_name); if (pin) { const RiseFall *rf = edge->transition()->asRiseFall(); Edge *edge; @@ -582,8 +578,8 @@ SdfReader::timingCheckSetupHold1(SdfPortSpec *data_edge, const TimingRole *setup_role, const TimingRole *hold_role) { - const std::string *data_port_name = data_edge->port(); - const std::string *clk_port_name = clk_edge->port(); + std::string_view data_port_name = data_edge->port(); + std::string_view clk_port_name = clk_edge->port(); Cell *cell = network_->cell(instance_); Port *data_port = findPort(cell, data_port_name); Port *clk_port = findPort(cell, clk_port_name); @@ -603,12 +599,12 @@ SdfReader::timingCheckPeriod(SdfPortSpec *edge, { // Ignore non-incremental annotations in incremental only mode. if (!(is_incremental_only_ && !in_incremental_) && instance_) { - const std::string *port_name = edge->port(); + std::string_view port_name = edge->port(); Cell *cell = network_->cell(instance_); Port *port = findPort(cell, port_name); if (port) { // Edge specifier is ignored for period checks. - Pin *pin = network_->findPin(instance_, port_name->c_str()); + Pin *pin = network_->findPin(instance_, port_name); if (pin) { float **values = triple->values(); float *value_ptr = values[triple_min_index_]; @@ -636,7 +632,7 @@ SdfReader::timingCheckNochange(SdfPortSpec *data_edge, SdfTriple *before_triple, SdfTriple *after_triple) { - notSupported("NOCHANGE"); + warn(173, "NOCHANGE not supported."); delete data_edge; delete clk_edge; deleteTriple(before_triple); @@ -659,7 +655,7 @@ SdfReader::device(SdfTripleSeq *triples) } void -SdfReader::device(const std::string *to_port_name, +SdfReader::device(std::string_view to_port_name, SdfTripleSeq *triples) { // Ignore non-incremental annotations in incremental only mode. @@ -667,11 +663,10 @@ SdfReader::device(const std::string *to_port_name, Cell *cell = network_->cell(instance_); Port *to_port = findPort(cell, to_port_name); if (to_port) { - Pin *to_pin = network_->findPin(instance_, to_port_name->c_str()); + Pin *to_pin = network_->findPin(instance_, to_port_name); setDevicePinDelays(to_pin, triples); } } - delete to_port_name; deleteTripleSeq(triples); } @@ -773,28 +768,31 @@ SdfReader::setEdgeArcDelaysCondUse(Edge *edge, } bool -SdfReader::condMatch(const std::string *sdf_cond, - const std::string &lib_cond) +SdfReader::condMatch(std::string_view sdf_cond, + std::string_view lib_cond) { // If the sdf is not conditional it matches any library condition. - if (sdf_cond == nullptr) + if (sdf_cond.empty()) return true; - else if (sdf_cond && !lib_cond.empty()) { + else if (!sdf_cond.empty() && !lib_cond.empty()) { // Match sdf_cond and lib_cond ignoring blanks. - const char *c1 = sdf_cond->c_str(); - const char *c2 = lib_cond.c_str(); - char ch1, ch2; - do { - ch1 = *c1++; - ch2 = *c2++; - while (ch1 && isspace(ch1)) - ch1 = *c1++; - while (ch2 && isspace(ch2)) - ch2 = *c2++; + size_t c1 = 0; + size_t c2 = 0; + while (c1 < sdf_cond.size() + && c2 < lib_cond.size()) { + char ch1 = sdf_cond[c1++]; + char ch2 = lib_cond[c2++]; + while (c1 < sdf_cond.size() + && isspace(ch1)) + ch1 = sdf_cond[c1++]; + while (c2 < lib_cond.size() + && isspace(ch2)) + ch2 = lib_cond[c2++]; if (ch1 != ch2) return false; - } while (ch1 && ch2); - return (ch1 == '\0' && ch2 == '\0'); + } + return c1 == sdf_cond.size() + && c2 == lib_cond.size(); } else return false; @@ -802,30 +800,34 @@ SdfReader::condMatch(const std::string *sdf_cond, SdfPortSpec * SdfReader::makePortSpec(const Transition *tr, - const std::string *port, - const std::string *cond) + std::string_view port) +{ + return new SdfPortSpec(tr, port, ""); +} + +SdfPortSpec * +SdfReader::makePortSpec(const Transition *tr, + std::string_view port, + std::string_view cond) { return new SdfPortSpec(tr, port, cond); } SdfPortSpec * -SdfReader::makeCondPortSpec(const std::string *cond_port) +SdfReader::makeCondPortSpec(std::string_view cond_port) { // Search from end to find port name because condition may contain spaces. - std::string cond_port1(*cond_port); + std::string cond_port1(cond_port); trimRight(cond_port1); auto port_idx = cond_port1.find_last_of(" "); if (port_idx != cond_port1.npos) { - std::string *port1 = new std::string(cond_port1.substr(port_idx + 1)); - auto cond_end = cond_port1.find_last_not_of(" ", port_idx); + std::string port1 = cond_port1.substr(port_idx + 1); + size_t cond_end = cond_port1.find_last_not_of(" ", port_idx); if (cond_end != cond_port1.npos) { - std::string *cond1 = new std::string(cond_port1.substr(0, cond_end + 1)); - SdfPortSpec *port_spec = new SdfPortSpec(Transition::riseFall(), port1, cond1); - delete cond_port; - return port_spec; + std::string cond1 = cond_port1.substr(0, cond_end + 1); + return new SdfPortSpec(Transition::riseFall(), port1, cond1); } } - delete cond_port; return nullptr; } @@ -888,75 +890,65 @@ SdfReader::setInIncremental(bool incr) in_incremental_ = incr; } -std::string * -SdfReader::unescaped(const std::string *token) +std::string +SdfReader::unescaped(std::string_view token) { char path_escape = network_->pathEscape(); char path_divider = network_->pathDivider(); - size_t token_length = token->size(); - std::string *unescaped = new std::string; + size_t token_length = token.size(); + std::string result; for (size_t i = 0; i < token_length; i++) { - char ch = (*token)[i]; + char ch = token[i]; if (ch == escape_) { - char next_ch = (*token)[i + 1]; + char next_ch = token[i + 1]; if (next_ch == divider_) { // Escaped divider. // Translate sdf escape to network escape. - *unescaped += path_escape; + result += path_escape; // Translate sdf divider to network divider. - *unescaped += path_divider; + result += path_divider; } else if (next_ch == '[' || next_ch == ']' || next_ch == escape_) { // Escaped bus bracket or escape. // Translate sdf escape to network escape. - *unescaped += path_escape; - *unescaped += next_ch; + result += path_escape; + result += next_ch; } else // Escaped non-divider character. - *unescaped += next_ch; + result += next_ch; i++; } else // Just the normal noises. - *unescaped += ch; + result += ch; } - debugPrint(debug_, "sdf_name", 1, "unescape {} -> {}", *token, - *unescaped); - delete token; - return unescaped; + debugPrint(debug_, "sdf_name", 1, "unescape {} -> {}", token, + result); + return result; } -std::string * -SdfReader::makePath(const std::string *head, - const std::string *tail) +std::string +SdfReader::makePath(std::string_view head, + std::string_view tail) { - std::string *path = new std::string(*head); - *path += network_->pathDivider(); - *path += *tail; - delete head; - delete tail; + std::string path(head); + path += network_->pathDivider(); + path += tail; return path; } -std::string * -SdfReader::makeBusName(std::string *base_name, +std::string +SdfReader::makeBusName(std::string_view base_name, int index) { - std::string *bus_name = unescaped(base_name); - *bus_name += '['; - *bus_name += std::to_string(index); - *bus_name += ']'; - delete base_name; + std::string bus_name = unescaped(base_name); + bus_name += '['; + bus_name += std::to_string(index); + bus_name += ']'; return bus_name; } -void -SdfReader::notSupported(const char *feature) -{ - error(193, "{} not supported.", feature); -} - int SdfReader::sdfLine() const { @@ -964,31 +956,31 @@ SdfReader::sdfLine() const } Pin * -SdfReader::findPin(const std::string *name) +SdfReader::findPin(std::string_view name) { - if (path_) { + if (!path_.empty()) { std::string path_name(path_); path_name += divider_; - path_name += *name; - Pin *pin = network_->findPin(path_name.c_str()); + path_name += name; + Pin *pin = network_->findPin(path_name); return pin; } else - return network_->findPin(name->c_str()); + return network_->findPin(name); } Instance * -SdfReader::findInstance(const std::string *name) +SdfReader::findInstance(std::string_view name) { std::string inst_name; - if (path_) { + if (!path_.empty()) { inst_name = path_; inst_name += divider_; - inst_name += *name; + inst_name += name; } else - inst_name = *name; - Instance *inst = network_->findInstance(inst_name.c_str()); + inst_name = name; + Instance *inst = network_->findInstance(inst_name); if (inst == nullptr) warn(195, "instance {} not found.", inst_name); return inst; @@ -997,20 +989,14 @@ SdfReader::findInstance(const std::string *name) //////////////////////////////////////////////////////////////// SdfPortSpec::SdfPortSpec(const Transition *tr, - const std::string *port, - const std::string *cond) : + std::string_view port, + std::string_view cond) : tr_(tr), port_(port), cond_(cond) { } -SdfPortSpec::~SdfPortSpec() -{ - delete port_; - delete cond_; -} - //////////////////////////////////////////////////////////////// SdfTriple::SdfTriple(float *min, @@ -1045,7 +1031,7 @@ SdfTriple::hasValue() const //////////////////////////////////////////////////////////////// SdfScanner::SdfScanner(std::istream *stream, - const std::string &filename, + std::string_view filename, SdfReader *reader, Report *report) : yyFlexLexer(stream), @@ -1056,9 +1042,9 @@ SdfScanner::SdfScanner(std::istream *stream, } void -SdfScanner::error(const char *msg) +SdfScanner::error(std::string_view msg) { - report_->fileError(196, filename_.c_str(), lineno(), "{}", msg); + report_->fileError(196, filename_, lineno(), "{}", msg); } } // namespace sta diff --git a/sdf/SdfReader.hh b/sdf/SdfReader.hh index f894ebd6..47598d5d 100644 --- a/sdf/SdfReader.hh +++ b/sdf/SdfReader.hh @@ -24,6 +24,9 @@ #pragma once +#include +#include + namespace sta { class MinMaxAll; @@ -40,7 +43,7 @@ class StaState; // If incremental_only is true non-incremental annoatations are ignored. // // path is a hierararchial path prefix for instances and pins in the -// sdf file. Pass 0 (nullptr) to specify no path. +// sdf file. Pass a null string to specify no path. // // The cond_use option is used when the SDF file contains conditional // delays and the library does not have conditional delay arcs. If @@ -52,8 +55,8 @@ class StaState; // maximum operating conditions. bool -readSdf(const char *filename, - const char *path, +readSdf(std::string_view filename, + std::string_view path, Scene *scene, bool unescaped_dividers, bool incremental_only, diff --git a/sdf/SdfReaderPvt.hh b/sdf/SdfReaderPvt.hh index 4ae883ba..3b12d02e 100644 --- a/sdf/SdfReaderPvt.hh +++ b/sdf/SdfReaderPvt.hh @@ -24,6 +24,7 @@ #pragma once +#include #include #include @@ -48,8 +49,8 @@ using SdfTripleSeq = std::vector; class SdfReader : public StaState { public: - SdfReader(const char *filename, - const char *path, + SdfReader(std::string_view filename, + std::string_view path, int arc_min_index, int arc_max_index, AnalysisType analysis_type, @@ -62,7 +63,7 @@ public: void setDivider(char divider); void setTimescale(float multiplier, - const std::string *units); + std::string_view units); void setPortDeviceDelay(Edge *edge, SdfTripleSeq *triples, bool from_trans); @@ -83,17 +84,18 @@ public: int triple_index, int arc_delay_index, const MinMax *min_max); - void setInstance(const std::string *instance_name); + void setInstance(); + void setInstance(std::string_view instance_name); void setInstanceWildcard(); void cellFinish(); - void setCell(const std::string *cell_name); - void interconnect(const std::string *from_pin_name, - const std::string *to_pin_name, + void setCell(std::string_view cell_name); + void interconnect(std::string_view from_pin_name, + std::string_view to_pin_name, SdfTripleSeq *triples); void iopath(SdfPortSpec *from_edge, - const std::string *to_port_name, + std::string_view to_port_name, SdfTripleSeq *triples, - const std::string *cond, + std::string_view cond, bool condelse); void timingCheck(const TimingRole *role, SdfPortSpec *data_edge, @@ -121,10 +123,10 @@ public: SdfPortSpec *clk_edge, SdfTriple *before_triple, SdfTriple *after_triple); - void port(const std::string *to_pin_name, + void port(std::string_view o_pin_name, SdfTripleSeq *triples); void device(SdfTripleSeq *triples); - void device(const std::string *to_pin_name, + void device(std::string_view to_pin_name, SdfTripleSeq *triples); SdfTriple *makeTriple(); @@ -136,20 +138,22 @@ public: SdfTripleSeq *makeTripleSeq(); void deleteTripleSeq(SdfTripleSeq *triples); SdfPortSpec *makePortSpec(const Transition *tr, - const std::string *port, - const std::string *cond); - SdfPortSpec *makeCondPortSpec(const std::string *cond_port); - std::string *unescaped(const std::string *token); - std::string *makePath(const std::string *head, - const std::string *tail); + std::string_view port); + SdfPortSpec *makePortSpec(const Transition *tr, + std::string_view port, + std::string_view cond); + SdfPortSpec *makeCondPortSpec(std::string_view cond_port); + std::string unescaped(std::string_view token); + std::string makePath(std::string_view head, + std::string_view tail); // Parser state used to control lexer for COND handling. bool inTimingCheck() { return in_timing_check_; } void setInTimingCheck(bool in); bool inIncremental() const { return in_incremental_; } void setInIncremental(bool incr); - std::string *makeBusName(std::string *bus_name, - int index); - const std::string &filename() const { return filename_; } + std::string makeBusName(std::string_view bus_name, + int index); + std::string_view filename() const { return filename_; } int sdfLine() const; template void warn(int id, @@ -167,12 +171,8 @@ public: report_->fileError(id, filename_, sdfLine(), fmt, std::forward(args)...); } - void notSupported(const char *feature); private: - int readSdfFile1(Network *network, - Graph *graph, - const char *filename); Edge *findCheckEdge(Pin *from_pin, Pin *to_pin, const TimingRole *sdf_role, @@ -180,8 +180,8 @@ private: const std::string *cond_end); Edge *findWireEdge(Pin *from_pin, Pin *to_pin); - bool condMatch(const std::string *sdf_cond, - const std::string &lib_cond); + bool condMatch(std::string_view sdf_cond, + std::string_view lib_cond); void timingCheck1(const TimingRole *role, Port *data_port, SdfPortSpec *data_edge, @@ -195,19 +195,19 @@ private: const TimingRole *sdf_role, SdfTriple *triple, bool match_generic); - Pin *findPin(const std::string *name); - Instance *findInstance(const std::string *name); + Pin *findPin(std::string_view name); + Instance *findInstance(std::string_view name); void setEdgeDelays(Edge *edge, SdfTripleSeq *triples, - const char *sdf_cmd); + std::string_view sdf_cmd); void setDevicePinDelays(Pin *to_pin, SdfTripleSeq *triples); Port *findPort(const Cell *cell, - const std::string *port_name); + std::string_view port_name); - std::string filename_; + std::string_view filename_; SdfScanner *scanner_; - const char *path_; + std::string_view path_; // Which values to pull out of the sdf triples. int triple_min_index_; int triple_max_index_; @@ -222,7 +222,7 @@ private: char divider_; char escape_; Instance *instance_; - const std::string *cell_name_; + std::string cell_name_; bool in_timing_check_; bool in_incremental_; float timescale_; diff --git a/sdf/SdfScanner.hh b/sdf/SdfScanner.hh index 14407236..bcb0c6cd 100644 --- a/sdf/SdfScanner.hh +++ b/sdf/SdfScanner.hh @@ -24,6 +24,8 @@ #pragma once +#include + #include "SdfLocation.hh" #include "SdfParse.hh" @@ -41,7 +43,7 @@ class SdfScanner : public SdfFlexLexer { public: SdfScanner(std::istream *stream, - const std::string &filename, + std::string_view filename, SdfReader *reader, Report *report); virtual ~SdfScanner() {} @@ -51,13 +53,13 @@ public: // YY_DECL defined in SdfLex.ll // Method body created by flex in SdfLex.cc - void error(const char *msg); + void error(std::string_view msg); // Get rid of override virtual function warning. using FlexLexer::yylex; private: - std::string filename_; + std::string_view filename_; SdfReader *reader_; Report *report_; std::string token_; diff --git a/sdf/SdfWriter.cc b/sdf/SdfWriter.cc index fa79139f..0d750092 100644 --- a/sdf/SdfWriter.cc +++ b/sdf/SdfWriter.cc @@ -26,6 +26,8 @@ #include #include +#include +#include #include "Format.hh" #include "Zlib.hh" @@ -50,7 +52,7 @@ class SdfWriter : public StaState { public: SdfWriter(StaState *sta); - void write(const char *filename, + void write(std::string_view filename, const Scene *scene, char sdf_divider, bool include_typ, @@ -81,14 +83,14 @@ protected: const Instance *inst, bool &inst_header); void writeCheck(Edge *edge, - const char *sdf_check); + std::string_view sdf_check); void writeCheck(Edge *edge, TimingArc *arc, - const char *sdf_check, + std::string_view sdf_check, bool use_data_edge, bool use_clk_edge); void writeEdgeCheck(Edge *edge, - const char *sdf_check, + std::string_view sdf_check, int clk_rf_index, TimingArc *arcs[RiseFall::index_count][RiseFall::index_count]); void writeTimingCheckHeader(); @@ -99,7 +101,7 @@ protected: float max_width); void writePeriodCheck(const Pin *pin, float min_period); - const char *sdfEdge(const Transition *tr); + std::string_view sdfEdge(const Transition *tr); void writeArcDelays(Edge *edge); void writeSdfTriple(RiseFallMinMax &delays, const RiseFall *rf); @@ -127,7 +129,7 @@ private: }; void -writeSdf(const char *filename, +writeSdf(std::string_view filename, const Scene *scene, char sdf_divider, bool include_typ, @@ -150,7 +152,7 @@ SdfWriter::SdfWriter(StaState *sta) : } void -SdfWriter::write(const char *filename, +SdfWriter::write(std::string_view filename, const Scene *scene, char sdf_divider, bool include_typ, @@ -170,7 +172,7 @@ SdfWriter::write(const char *filename, arc_delay_min_index_ = scene->dcalcAnalysisPtIndex(MinMax::min()); arc_delay_max_index_ = scene->dcalcAnalysisPtIndex(MinMax::max()); - stream_ = gzopen(filename, gzip ? "wb" : "wT"); + stream_ = gzopen(std::string(filename).c_str(), gzip ? "wb" : "wT"); if (stream_ == nullptr) throw FileNotWritable(filename); @@ -573,7 +575,7 @@ SdfWriter::writeTimingCheckTrailer() void SdfWriter::writeCheck(Edge *edge, - const char *sdf_check) + std::string_view sdf_check) { TimingArcSet *arc_set = edge->timingArcSet(); // Examine the arcs to see if the check requires clk or data edge specifiers. @@ -600,7 +602,7 @@ SdfWriter::writeCheck(Edge *edge, void SdfWriter::writeEdgeCheck(Edge *edge, - const char *sdf_check, + std::string_view sdf_check, int clk_rf_index, TimingArc *arcs[RiseFall::index_count][RiseFall::index_count]) { @@ -647,7 +649,7 @@ SdfWriter::writeEdgeCheck(Edge *edge, void SdfWriter::writeCheck(Edge *edge, TimingArc *arc, - const char *sdf_check, + std::string_view sdf_check, bool use_data_edge, bool use_clk_edge) { @@ -725,14 +727,14 @@ SdfWriter::writePeriodCheck(const Pin *pin, sta::print(stream_, ")\n"); } -const char * +std::string_view SdfWriter::sdfEdge(const Transition *tr) { if (tr == Transition::rise()) return "posedge"; else if (tr == Transition::fall()) return "negedge"; - return nullptr; + return {}; } //////////////////////////////////////////////////////////////// @@ -762,8 +764,7 @@ SdfWriter::sdfPathName(const Instance *instance) std::string path_name; while (!inst_path.empty()) { const Instance *inst = inst_path.back(); - std::string inst_name = sdfName(inst); - path_name += inst_name; + path_name += sdfName(inst); inst_path.pop_back(); if (!inst_path.empty()) path_name += sdf_divider_; @@ -775,11 +776,9 @@ SdfWriter::sdfPathName(const Instance *instance) std::string SdfWriter::sdfName(const Instance *inst) { - const char *name = network_->name(inst); + const std::string &name = network_->name(inst); std::string sdf_name; - const char *p = name; - while (*p) { - char ch = *p; + for (char ch : name) { // Ignore sta escapes. if (ch != network_escape_) { if (!(isalnum(ch) || ch == '_')) @@ -787,7 +786,6 @@ SdfWriter::sdfName(const Instance *inst) sdf_name += sdf_escape_; sdf_name += ch; } - p++; } return sdf_name; } @@ -795,8 +793,8 @@ SdfWriter::sdfName(const Instance *inst) std::string SdfWriter::sdfPortName(const Pin *pin) { - const char *name = network_->portName(pin); - size_t name_length = strlen(name); + const std::string &name = network_->portName(pin); + size_t name_length = name.size(); std::string sdf_name; constexpr char bus_brkt_left = '['; @@ -804,9 +802,9 @@ SdfWriter::sdfPortName(const Pin *pin) size_t bus_index = name_length; if (name_length >= 4 && name[name_length - 1] == bus_brkt_right) { - const char *left = strrchr(name, bus_brkt_left); - if (left) - bus_index = left - name; + size_t left = name.rfind(bus_brkt_left); + if (left != std::string_view::npos) + bus_index = left; } for (size_t i = 0; i < name_length; i++) { char ch = name[i]; diff --git a/sdf/SdfWriter.hh b/sdf/SdfWriter.hh index c14df631..98ca6f7d 100644 --- a/sdf/SdfWriter.hh +++ b/sdf/SdfWriter.hh @@ -24,13 +24,15 @@ #pragma once +#include + namespace sta { class StaState; class Scene; void -writeSdf(const char *filename, +writeSdf(std::string_view filename, const Scene *scene, char divider, bool include_typ, diff --git a/search/CheckMinPulseWidths.cc b/search/CheckMinPulseWidths.cc index cad8319e..fc5b0c07 100644 --- a/search/CheckMinPulseWidths.cc +++ b/search/CheckMinPulseWidths.cc @@ -171,7 +171,7 @@ MinPulseWidthCheck::MinPulseWidthCheck(Path *open_path) : std::string MinPulseWidthCheck::to_string(const StaState *sta) { - std::string result = sta->network()->pathName(pin(sta)); + std::string result(sta->network()->pathName(pin(sta))); result += " "; result += (openTransition(sta) == RiseFall::rise()) ? "(high)" : "(low)"; return result; diff --git a/search/ClkLatency.cc b/search/ClkLatency.cc index 887c009e..bc2d75f9 100644 --- a/search/ClkLatency.cc +++ b/search/ClkLatency.cc @@ -72,7 +72,7 @@ ClkLatency::reportClkLatency(ConstClockSeq &clks, ConstClockSeq sorted_clks; for (const Clock *clk : clks) sorted_clks.push_back(clk); - sort(sorted_clks, ClkNameLess()); + sort(sorted_clks, ClockNameLess()); for (const Clock *clk : sorted_clks) { ClkDelays clk_delays = clk_delay_map[clk]; diff --git a/search/ClkSkew.cc b/search/ClkSkew.cc index 8167d486..97626ca5 100644 --- a/search/ClkSkew.cc +++ b/search/ClkSkew.cc @@ -26,6 +26,7 @@ #include // abs #include +#include #include #include @@ -75,7 +76,7 @@ ClkSkews::reportClkSkew(ConstClockSeq &clks, ConstClockSeq sorted_clks; for (const Clock *clk : clks) sorted_clks.push_back(clk); - sort(sorted_clks, ClkNameLess()); + sort(sorted_clks, ClockNameLess()); for (const Clock *clk : sorted_clks) { report_->report("Clock {}", clk->name()); @@ -487,12 +488,13 @@ ClkSkew::srcTgtPathNameLess(ClkSkew &clk_skew1, const StaState *sta) { Network *network = sta->sdcNetwork(); - const char *src_path1 = network->pathName(clk_skew1.srcPath()->pin(sta)); - const char *src_path2 = network->pathName(clk_skew2.srcPath()->pin(sta)); - const char *tgt_path1 = network->pathName(clk_skew1.tgtPath()->pin(sta)); - const char *tgt_path2 = network->pathName(clk_skew2.tgtPath()->pin(sta)); - return stringLess(src_path1, src_path2) - || (stringEqual(src_path1, src_path2) && stringEqual(tgt_path1, tgt_path2)); + std::string src_path1 = network->pathName(clk_skew1.srcPath()->pin(sta)); + std::string src_path2 = network->pathName(clk_skew2.srcPath()->pin(sta)); + std::string tgt_path1 = network->pathName(clk_skew1.tgtPath()->pin(sta)); + std::string tgt_path2 = network->pathName(clk_skew2.tgtPath()->pin(sta)); + return src_path1 < src_path2 + || (src_path1 == src_path2 + && tgt_path1 == tgt_path2); } //////////////////////////////////////////////////////////////// diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index 20ec6110..d4fd82f0 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.cc @@ -53,9 +53,9 @@ namespace sta { LibertyLibrary * -makeTimingModel(const char *lib_name, - const char *cell_name, - const char *filename, +makeTimingModel(std::string_view lib_name, + std::string_view cell_name, + std::string_view filename, const Scene *scene, Sta *sta) { @@ -63,9 +63,9 @@ makeTimingModel(const char *lib_name, return maker.makeTimingModel(); } -MakeTimingModel::MakeTimingModel(const char *lib_name, - const char *cell_name, - const char *filename, +MakeTimingModel::MakeTimingModel(std::string_view lib_name, + std::string_view cell_name, + std::string_view filename, const Scene *scene, Sta *sta) : StaState(sta), @@ -186,7 +186,7 @@ MakeTimingModel::makePorts() CellPortIterator *port_iter = network_->portIterator(top_cell); while (port_iter->hasNext()) { Port *port = port_iter->next(); - const char *port_name = network_->name(port); + std::string port_name(network_->name(port)); if (network_->isBus(port)) { int from_index = network_->fromIndex(port); int to_index = network_->toIndex(port); @@ -518,7 +518,7 @@ MakeTimingModel::findClkTreeDelays() while (port_iter->hasNext()) { Port *port = port_iter->next(); if (network_->direction(port)->isInput()) { - const char *port_name = network_->name(port); + std::string port_name = network_->name(port); LibertyPort *lib_port = cell_->findLibertyPort(port_name); Pin *pin = network_->findPin(top_inst, port); if (pin && sdc_->isClock(pin)) { diff --git a/search/MakeTimingModel.hh b/search/MakeTimingModel.hh index c09634bb..9056bce7 100644 --- a/search/MakeTimingModel.hh +++ b/search/MakeTimingModel.hh @@ -24,6 +24,8 @@ #pragma once +#include + namespace sta { class LibertyLibrary; @@ -31,9 +33,9 @@ class Scene; class Sta; LibertyLibrary * -makeTimingModel(const char *lib_name, - const char *cell_name, - const char *filename, +makeTimingModel(std::string_view lib_name, + std::string_view cell_name, + std::string_view filename, const Scene *scene, Sta *sta); diff --git a/search/MakeTimingModelPvt.hh b/search/MakeTimingModelPvt.hh index aeca4267..07470e4e 100644 --- a/search/MakeTimingModelPvt.hh +++ b/search/MakeTimingModelPvt.hh @@ -25,6 +25,8 @@ #pragma once #include +#include +#include #include "LibertyClass.hh" #include "SdcClass.hh" @@ -54,9 +56,9 @@ using OutputPinDelays = std::map; class MakeTimingModel : public StaState { public: - MakeTimingModel(const char *lib_name, - const char *cell_name, - const char *filename, + MakeTimingModel(std::string_view lib_name, + std::string_view cell_name, + std::string_view filename, const Scene *scene, Sta *sta); ~MakeTimingModel(); @@ -102,9 +104,9 @@ private: void restoreSdc(); void swapSdcWithBackup(); - const char *lib_name_; - const char *cell_name_; - const char *filename_; + std::string lib_name_; + std::string cell_name_; + std::string filename_; const Scene *scene_; SceneSet scenes_; LibertyLibrary *library_; diff --git a/search/Mode.cc b/search/Mode.cc index 6bced47a..a73ea28e 100644 --- a/search/Mode.cc +++ b/search/Mode.cc @@ -32,7 +32,7 @@ namespace sta { -Mode::Mode(const std::string &name, +Mode::Mode(std::string_view name, size_t mode_index, StaState *sta) : StaState(sta), diff --git a/search/PathGroup.cc b/search/PathGroup.cc index e2ca7711..1d3e6cd0 100644 --- a/search/PathGroup.cc +++ b/search/PathGroup.cc @@ -53,7 +53,7 @@ namespace sta { int PathGroup::group_path_count_max = std::numeric_limits::max(); PathGroup * -PathGroup::makePathGroupSlack(const char *name, +PathGroup::makePathGroupSlack(std::string_view name, int group_path_count, int endpoint_path_count, bool unique_pins, @@ -68,7 +68,7 @@ PathGroup::makePathGroupSlack(const char *name, } PathGroup * -PathGroup::makePathGroupArrival(const char *name, +PathGroup::makePathGroupArrival(std::string_view name, int group_path_count, int endpoint_path_count, bool unique_pins, @@ -81,7 +81,7 @@ PathGroup::makePathGroupArrival(const char *name, false, min_max, sta); } -PathGroup::PathGroup(const char *name, +PathGroup::PathGroup(std::string_view name, int group_path_count, int endpoint_path_count, bool unique_pins, @@ -247,11 +247,6 @@ PathGroup::clear() //////////////////////////////////////////////////////////////// -const char *PathGroups::path_delay_group_name_ = "path delay"; -const char *PathGroups::gated_clk_group_name_ = "gated clock"; -const char *PathGroups::async_group_name_ = "asynchronous"; -const char *PathGroups::unconstrained_group_name_ = "unconstrained"; - PathGroups::PathGroups(int group_path_count, int endpoint_path_count, bool unique_pins, @@ -309,7 +304,7 @@ PathGroups::makeGroups(int group_path_count, const Sdc *sdc = mode_->sdc(); for (const auto& [name, group] : sdc->groupPaths()) { if (reportGroup(name, group_names)) { - PathGroup *group = PathGroup::makePathGroupSlack(name.c_str(), + PathGroup *group = PathGroup::makePathGroupSlack(name, group_path_count, endpoint_path_count, unique_pins, @@ -321,7 +316,7 @@ PathGroups::makeGroups(int group_path_count, } for (Clock *clk : sdc->clocks()) { - const char *clk_name = clk->name(); + const std::string &clk_name = clk->name(); if (reportGroup(clk_name, group_names)) { PathGroup *group = PathGroup::makePathGroupSlack(clk_name, group_path_count, @@ -336,7 +331,7 @@ PathGroups::makeGroups(int group_path_count, } if (setup_hold - && reportGroup(path_delay_group_name_, group_names)) + && reportGroup(std::string(path_delay_group_name_), group_names)) path_delay_[mm_index] = PathGroup::makePathGroupSlack(path_delay_group_name_, group_path_count, endpoint_path_count, @@ -348,7 +343,7 @@ PathGroups::makeGroups(int group_path_count, path_delay_[mm_index] = nullptr; if (gated_clk - && reportGroup(gated_clk_group_name_, group_names)) + && reportGroup(std::string(gated_clk_group_name_), group_names)) gated_clk_[mm_index] = PathGroup::makePathGroupSlack(gated_clk_group_name_, group_path_count, endpoint_path_count, @@ -360,7 +355,7 @@ PathGroups::makeGroups(int group_path_count, gated_clk_[mm_index] = nullptr; if (async - && reportGroup(async_group_name_, group_names)) + && reportGroup(std::string(async_group_name_), group_names)) async_[mm_index] = PathGroup::makePathGroupSlack(async_group_name_, group_path_count, endpoint_path_count, @@ -372,7 +367,7 @@ PathGroups::makeGroups(int group_path_count, async_[mm_index] = nullptr; if (unconstrained - && reportGroup(unconstrained_group_name_, group_names)) + && reportGroup(std::string(unconstrained_group_name_), group_names)) unconstrained_[mm_index] = PathGroup::makePathGroupArrival(unconstrained_group_name_, group_path_count, endpoint_path_count, @@ -441,7 +436,7 @@ PathGroups::pathGroups(const PathEnd *path_end) const path_groups.push_back(path_delay_[mm_index]); } else { - std::string group_name = group_path->name(); + std::string group_name(group_path->name()); PathGroup *group = findPathGroup(group_name, min_max); if (group) path_groups.push_back(group); @@ -484,7 +479,7 @@ PathGroups::pathGroupNames(const PathEnd *path_end, const StaState *sta) { StringSeq group_names; - const char *group_name = nullptr; + std::string group_name; const Search *search = sta->search(); ExceptionPathSeq group_paths = search->groupPathsTo(path_end); if (path_end->isUnconstrained()) @@ -493,9 +488,9 @@ PathGroups::pathGroupNames(const PathEnd *path_end, // GroupPaths have precedence. for (ExceptionPath *group_path : group_paths) { if (group_path->isDefault()) - group_names.push_back(path_delay_group_name_); + group_names.push_back(std::string(path_delay_group_name_)); else - group_names.push_back(group_path->name()); + group_names.push_back(std::string(group_path->name())); } } else if (path_end->isCheck() || path_end->isLatchCheck()) { @@ -526,7 +521,7 @@ PathGroups::pathGroupNames(const PathEnd *path_end, else group_name = path_delay_group_name_; } - if (group_name) + if (!group_name.empty()) group_names.push_back(group_name); return group_names; } diff --git a/search/PocvMode.cc b/search/PocvMode.cc index 57186138..7e7b28a5 100644 --- a/search/PocvMode.cc +++ b/search/PocvMode.cc @@ -33,14 +33,14 @@ static EnumNameMap pocv_mode_map = {PocvMode::normal, "normal"}, {PocvMode::skew_normal, "skew_normal"}}; -const char * +const std::string & pocvModeName(PocvMode mode) { return pocv_mode_map.find(mode); } PocvMode -findPocvMode(const char *mode_name) +findPocvMode(std::string_view mode_name) { return pocv_mode_map.find(mode_name, PocvMode::scalar); } diff --git a/search/Property.cc b/search/Property.cc index 35e6a096..cdb0c088 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -50,8 +50,8 @@ namespace sta { class PropertyUnknown : public Exception { public: - PropertyUnknown(const std::string &type, - const std::string &property); + PropertyUnknown(std::string_view type, + std::string_view property); virtual ~PropertyUnknown() {} virtual const char *what() const noexcept; @@ -59,8 +59,8 @@ private: std::string msg_; }; -PropertyUnknown::PropertyUnknown(const std::string &type, - const std::string &property) : +PropertyUnknown::PropertyUnknown(std::string_view type, + std::string_view property) : Exception(), msg_(sta::format("{} objects do not have a {} property.", type, property)) { @@ -107,18 +107,18 @@ PropertyValue::PropertyValue() : { } -PropertyValue::PropertyValue(const char *value) : +PropertyValue::PropertyValue(std::string_view value) : type_(Type::string), - string_(stringCopy(value)), unit_(nullptr) { + string_ = new std::string(value); } -PropertyValue::PropertyValue(std::string &value) : +PropertyValue::PropertyValue(std::string value) : type_(Type::string), - string_(stringCopy(value.c_str())), unit_(nullptr) { + string_ = new std::string(std::move(value)); } PropertyValue::PropertyValue(float value, @@ -269,7 +269,7 @@ PropertyValue::PropertyValue(const PropertyValue &value) : case Type::none: break; case Type::string: - string_ = stringCopy(value.string_); + string_ = new std::string(*value.string_); break; case Type::float_: float_ = value.float_; @@ -325,7 +325,6 @@ PropertyValue::PropertyValue(const PropertyValue &value) : PropertyValue::PropertyValue(PropertyValue &&value) noexcept : type_(value.type_), unit_(value.unit_) - { switch (type_) { case Type::none: @@ -333,6 +332,7 @@ PropertyValue::PropertyValue(PropertyValue &&value) noexcept : case Type::string: string_ = value.string_; value.string_ = nullptr; + value.type_ = Type::none; break; case Type::float_: float_ = value.float_; @@ -382,7 +382,7 @@ PropertyValue::PropertyValue(PropertyValue &&value) noexcept : case Type::paths: paths_ = value.paths_; // Steal the value. - value.clks_ = nullptr; + value.paths_ = nullptr; break; case Type::pwr_activity: pwr_activity_ = value.pwr_activity_; @@ -390,11 +390,12 @@ PropertyValue::PropertyValue(PropertyValue &&value) noexcept : } } -PropertyValue::~PropertyValue() -{ +void +PropertyValue::destroyActive() +{ switch (type_) { case Type::string: - stringDelete(string_); + delete string_; break; case Type::clks: delete clks_; @@ -410,9 +411,17 @@ PropertyValue::~PropertyValue() } } +PropertyValue::~PropertyValue() +{ + destroyActive(); +} + PropertyValue & PropertyValue::operator=(const PropertyValue &value) { + if (this == &value) + return *this; + destroyActive(); type_ = value.type_; unit_ = value.unit_; @@ -420,7 +429,7 @@ PropertyValue::operator=(const PropertyValue &value) case Type::none: break; case Type::string: - string_ = stringCopy(value.string_); + string_ = new std::string(*value.string_); break; case Type::float_: float_ = value.float_; @@ -477,6 +486,9 @@ PropertyValue::operator=(const PropertyValue &value) PropertyValue & PropertyValue::operator=(PropertyValue &&value) noexcept { + if (this == &value) + return *this; + destroyActive(); type_ = value.type_; unit_ = value.unit_; @@ -486,6 +498,7 @@ PropertyValue::operator=(PropertyValue &&value) noexcept case Type::string: string_ = value.string_; value.string_ = nullptr; + value.type_ = Type::none; break; case Type::float_: float_ = value.float_; @@ -533,7 +546,7 @@ PropertyValue::operator=(PropertyValue &&value) noexcept break; case Type::paths: paths_ = value.paths_; - value.clks_ = nullptr; + value.paths_ = nullptr; break; case Type::pwr_activity: pwr_activity_ = value.pwr_activity_; @@ -547,7 +560,7 @@ PropertyValue::to_string(const Network *network) const { switch (type_) { case Type::string: - return string_; + return *string_; case Type::float_: return unit_->asString(float_, 6); case Type::bool_: @@ -563,11 +576,11 @@ PropertyValue::to_string(const Network *network) const case Type::liberty_port: return liberty_port_->name(); case Type::library: - return network->name(library_); + return std::string(network->name(library_)); case Type::cell: - return network->name(cell_); + return std::string(network->name(cell_)); case Type::port: - return network->name(port_); + return std::string(network->name(port_)); case Type::instance: return network->pathName(inst_); case Type::pin: @@ -586,12 +599,12 @@ PropertyValue::to_string(const Network *network) const return ""; } -const char * +const std::string & PropertyValue::stringValue() const { if (type_ != Type::string) throw PropertyTypeWrong("stringValue", "string"); - return string_; + return *string_; } float @@ -619,7 +632,7 @@ Properties::Properties(Sta *sta) : PropertyValue Properties::getProperty(const Library *lib, - const std::string &property) + std::string_view property) { Network *network = sta_->cmdNetwork(); if (property == "name" @@ -639,7 +652,7 @@ Properties::getProperty(const Library *lib, PropertyValue Properties::getProperty(const LibertyLibrary *lib, - const std::string &property) + std::string_view property) { if (property == "name" || property == "full_name") @@ -661,7 +674,7 @@ Properties::getProperty(const LibertyLibrary *lib, PropertyValue Properties::getProperty(const Cell *cell, - const std::string &property) + std::string_view property) { Network *network = sta_->cmdNetwork(); if (property == "name" @@ -669,8 +682,8 @@ Properties::getProperty(const Cell *cell, return PropertyValue(network->name(cell)); else if (property == "full_name") { Library *lib = network->library(cell); - std::string lib_name = network->name(lib); - std::string cell_name = network->name(cell); + std::string lib_name(network->name(lib)); + std::string cell_name(network->name(cell)); std::string full_name = lib_name + network->pathDivider() + cell_name; return PropertyValue(full_name); } @@ -692,7 +705,7 @@ Properties::getProperty(const Cell *cell, PropertyValue Properties::getProperty(const LibertyCell *cell, - const std::string &property) + std::string_view property) { if (property == "name" || property == "base_name") @@ -733,11 +746,11 @@ Properties::getProperty(const LibertyCell *cell, PropertyValue Properties::getProperty(const Port *port, - const std::string &property) + std::string_view property) { Network *network = sta_->cmdNetwork(); if (property == "name" - || property == "full_name") + || property == "full_name") return PropertyValue(network->name(port)); else if (property == "direction" || property == "port_direction") @@ -815,7 +828,7 @@ Properties::portSlack(const Port *port, PropertyValue Properties::getProperty(const LibertyPort *port, - const std::string &property) + std::string_view property) { if (property == "name") return PropertyValue(port->name()); @@ -894,7 +907,7 @@ Properties::getProperty(const LibertyPort *port, PropertyValue Properties::getProperty(const Instance *inst, - const std::string &property) + std::string_view property) { Network *network = sta_->ensureLinked(); LibertyCell *liberty_cell = network->libertyCell(inst); @@ -934,7 +947,7 @@ Properties::getProperty(const Instance *inst, PropertyValue Properties::getProperty(const Pin *pin, - const std::string &property) + std::string_view property) { Network *network = sta_->ensureLinked(); if (property == "name" @@ -1062,7 +1075,7 @@ Properties::pinSlew(const Pin *pin, PropertyValue Properties::getProperty(const Net *net, - const std::string &property) + std::string_view property) { Network *network = sta_->ensureLinked(); if (property == "name") @@ -1082,7 +1095,7 @@ Properties::getProperty(const Net *net, PropertyValue Properties::getProperty(Edge *edge, - const std::string &property) + std::string_view property) { if (property == "full_name") { std::string full_name = edge->to_string(sta_); @@ -1135,17 +1148,17 @@ Properties::edgeDelay(Edge *edge, PropertyValue Properties::getProperty(TimingArcSet *arc_set, - const std::string &property) + std::string_view property) { if (property == "name" || property == "full_name") { if (arc_set->isWire()) return PropertyValue("wire"); else { - const char *from = arc_set->from()->name(); - const char *to = arc_set->to()->name(); - const char *cell_name = arc_set->libertyCell()->name(); - std::string name = sta::format("{} {} -> {}", cell_name, from, to); + std::string name = sta::format("{} {} -> {}", + arc_set->libertyCell()->name(), + arc_set->from()->name(), + arc_set->to()->name()); return PropertyValue(name); } } @@ -1157,7 +1170,7 @@ Properties::getProperty(TimingArcSet *arc_set, PropertyValue Properties::getProperty(const Clock *clk, - const std::string &property) + std::string_view property) { if (property == "name" || property == "full_name") @@ -1186,7 +1199,7 @@ Properties::getProperty(const Clock *clk, PropertyValue Properties::getProperty(PathEnd *end, - const std::string &property) + std::string_view property) { if (property == "startpoint") { PathExpanded expanded(end->path(), sta_); @@ -1217,7 +1230,7 @@ Properties::getProperty(PathEnd *end, PropertyValue Properties::getProperty(Path *path, - const std::string &property) + std::string_view property) { if (property == "pin") return PropertyValue(path->pin(sta_)); @@ -1326,8 +1339,8 @@ Properties::defineProperty(std::string_view property, template PropertyValue PropertyRegistry::getProperty(TYPE object, - const std::string &property, - const char *type_name, + std::string_view property, + std::string_view type_name, Sta *sta) { diff --git a/search/ReportPath.cc b/search/ReportPath.cc index 158b7919..037d21cf 100644 --- a/search/ReportPath.cc +++ b/search/ReportPath.cc @@ -24,6 +24,7 @@ #include // reverse #include +#include #include "ReportPath.hh" @@ -79,52 +80,40 @@ hierPinsThruEdge(const Edge *edge, const Network *network, const Graph *graph); -ReportField::ReportField(const char *name, - const char *title, - int width, +ReportField::ReportField(std::string_view name, + std::string_view title, + size_t width, bool left_justify, Unit *unit, bool enabled) : name_(name), - title_(stringCopy(title)), + title_(title), left_justify_(left_justify), unit_(unit), - enabled_(enabled), - blank_(nullptr) + enabled_(enabled) { setWidth(width); } ReportField::~ReportField() { - stringDelete(title_); - stringDelete(blank_); } void -ReportField::setProperties(const char *title, - int width, +ReportField::setProperties(std::string_view title, + size_t width, bool left_justify) { - if (title_) - stringDelete(title_); - title_ = stringCopy(title); + title_ = std::string(title); left_justify_ = left_justify; setWidth(width); } void -ReportField::setWidth(int width) +ReportField::setWidth(size_t width) { width_ = width; - - if (blank_) - stringDelete(blank_); - blank_ = new char[width_ + 1]; - int i; - for (i = 0; i < width_; i++) - blank_[i] = ' '; - blank_[i] = '\0'; + blank_.assign(width_, ' '); } void @@ -185,8 +174,8 @@ ReportPath::makeFields() } ReportField * -ReportPath::makeField(const char *name, - const char *title, +ReportPath::makeField(std::string_view name, + std::string_view title, int width, bool left_justify, Unit *unit, @@ -199,10 +188,10 @@ ReportPath::makeField(const char *name, } ReportField * -ReportPath::findField(const char *name) const +ReportPath::findField(std::string_view name) const { for (ReportField *field : fields_) { - if (stringEq(name, field->name())) + if (field->name() == name) return field; } return nullptr; @@ -217,7 +206,7 @@ ReportPath::setReportFieldOrder(const StringSeq &field_names) ReportFieldSeq next_fields; for (const std::string &field_name : field_names) { - ReportField *field = findField(field_name.c_str()); + ReportField *field = findField(field_name); if (field) { next_fields.push_back(field); field->setEnabled(true); @@ -481,9 +470,9 @@ void ReportPath::reportEndpoint(const PathEndCheck *end) const { Instance *inst = network_->instance(end->vertex(this)->pin()); - const char *inst_name = cmd_network_->pathName(inst); + std::string inst_name = cmd_network_->pathName(inst); std::string clk_name = tgtClkName(end); - const char *rise_fall = asRisingFalling(end->targetClkEndTrans(this)); + std::string_view rise_fall = asRisingFalling(end->targetClkEndTrans(this)); const TimingRole *check_role = end->checkRole(this); const TimingRole *check_generic_role = check_role->genericRole(); if (check_role == TimingRole::recovery() @@ -503,7 +492,7 @@ ReportPath::reportEndpoint(const PathEndCheck *end) const reportEndpoint(inst_name, reason); } else { - const char *reg_desc = clkRegLatchDesc(end); + std::string_view reg_desc = clkRegLatchDesc(end); std::string reason = sta::format("{} clocked by {}", reg_desc, clk_name); reportEndpoint(inst_name, reason); } @@ -588,14 +577,14 @@ void ReportPath::reportEndpoint(const PathEndLatchCheck *end) const { Instance *inst = network_->instance(end->vertex(this)->pin()); - const char *inst_name = cmd_network_->pathName(inst); std::string clk_name = tgtClkName(end); - const char *reg_desc = latchDesc(end); + std::string_view reg_desc = latchDesc(end); std::string reason = sta::format("{} clocked by {}", reg_desc, clk_name); + std::string inst_name = cmd_network_->pathName(inst); reportEndpoint(inst_name, reason); } -const char * +std::string_view ReportPath::latchDesc(const PathEndLatchCheck *end) const { TimingArc *check_arc = end->checkArc(); @@ -626,13 +615,13 @@ ReportPath::reportBorrowing(const PathEndLatchCheck *end, const Path *tgt_clk_path = end->targetClkPath(); if (tgt_clk_path->clkInfo(search_)->isPropagated()) { std::string width_msg = sta::format("{} nominal pulse width", tgt_clk_name); - reportLineTotal(width_msg.c_str(), nom_pulse_width, early_late); + reportLineTotal(width_msg, nom_pulse_width, early_late); if (!delayZero(latency_diff, this)) reportLineTotalMinus("clock latency difference", latency_diff, early_late); } else { - std::string width_msg = sta::format("{} pulse width", tgt_clk_name.c_str()); - reportLineTotal(width_msg.c_str(), tgt_clk_width, early_late); + std::string width_msg = sta::format("{} pulse width", tgt_clk_name); + reportLineTotal(width_msg, tgt_clk_width, early_late); } ArcDelay margin = end->margin(this); reportLineTotalMinus("library setup time", margin, early_late); @@ -686,11 +675,10 @@ ReportPath::reportEndpoint(const PathEndPathDelay *end) const reportEndpointOutputDelay(end); else { Instance *inst = network_->instance(end->vertex(this)->pin()); - const char *inst_name = cmd_network_->pathName(inst); std::string reason = sta::format("{} clocked by {}", clkRegLatchDesc(end), tgtClkName(end)); - reportEndpoint(inst_name, reason); + reportEndpoint(cmd_network_->pathName(inst), reason); } } @@ -721,7 +709,7 @@ ReportPath::reportFull(const PathEndPathDelay *end) const std::string delay_msg = min_max->to_string() + "_delay"; float delay = path_delay->delay(); - reportLine(delay_msg.c_str(), delay, delay, early_late); + reportLine(delay_msg, delay, delay, early_late); if (!path_delay->ignoreClkLatency()) { const Clock *tgt_clk = end->targetClk(this); if (tgt_clk) { @@ -763,7 +751,7 @@ ReportPath::isPropagated(const Path *clk_path, return clk->isPropagated(); } -const char * +std::string_view ReportPath::clkNetworkDelayIdealProp(bool is_prop) const { if (is_prop) @@ -812,7 +800,7 @@ ReportPath::reportEndpointOutputDelay(const PathEndClkConstrained *end) const { Vertex *vertex = end->vertex(this); Pin *pin = vertex->pin(); - const char *pin_name = cmd_network_->pathName(pin); + std::string pin_name = cmd_network_->pathName(pin); const Clock *tgt_clk = end->targetClk(this); if (network_->isTopLevelPort(pin)) { // Pin direction is "output" even for bidirects. @@ -869,7 +857,7 @@ void ReportPath::reportEndpoint(const PathEndGatedClock *end) const { Instance *inst = network_->instance(end->vertex(this)->pin()); - const char *inst_name = cmd_network_->pathName(inst); + const std::string inst_name = cmd_network_->pathName(inst); const RiseFall *clk_end_rf = end->targetClkEndTrans(this); const RiseFall *clk_rf = (end->minMax(this) == MinMax::max()) ? clk_end_rf @@ -936,7 +924,7 @@ void ReportPath::reportEndpoint(const PathEndDataCheck *end) const { Instance *inst = network_->instance(end->vertex(this)->pin()); - const char *inst_name = cmd_network_->pathName(inst); + const std::string inst_name = cmd_network_->pathName(inst); std::string reason = sta::format("{} edge-triggered data to data check clocked by {}", asRisingFalling(end->dataClkPath()->transition(this)), end->targetClk(this)->name()); @@ -976,7 +964,7 @@ ReportPath::reportEndLine(const PathEnd *end) const { std::string line; std::string endpoint = pathEndpoint(end); - reportDescription(endpoint.c_str(), line); + reportDescription(endpoint, line); const EarlyLate *early_late = end->pathEarlyLate(this); reportSpaceFieldDelay(end->requiredTimeOffset(this), early_late, line); reportSpaceFieldDelay(end->dataArrivalTimeOffset(this), early_late, line); @@ -1007,10 +995,10 @@ ReportPath::reportSummaryLine(const PathEnd *end) const PathExpanded expanded(end->path(), this); const EarlyLate *early_late = end->pathEarlyLate(this); std::string startpoint = pathStartpoint(end, expanded); - reportDescription(startpoint.c_str(), line); + reportDescription(startpoint, line); line += ' '; std::string endpoint = pathEndpoint(end); - reportDescription(endpoint.c_str(), line); + reportDescription(endpoint, line); if (end->isUnconstrained()) reportSpaceFieldDelay(end->dataArrivalTimeOffset(this), early_late, line); else @@ -1024,14 +1012,14 @@ ReportPath::pathStartpoint(const PathEnd *end, { const Path *start = expanded.startPath(); Pin *pin = start->pin(graph_); - const char *pin_name = cmd_network_->pathName(pin); + std::string pin_name = cmd_network_->pathName(pin); if (network_->isTopLevelPort(pin)) { PortDirection *dir = network_->direction(pin); return sta::format("{} ({})", pin_name, dir->name()); } else { Instance *inst = network_->instance(end->vertex(this)->pin()); - const char *cell_name = cmd_network_->name(network_->cell(inst)); + std::string cell_name = cmd_network_->name(network_->cell(inst)); return sta::format("{} ({})", pin_name, cell_name); } } @@ -1040,14 +1028,14 @@ std::string ReportPath::pathEndpoint(const PathEnd *end) const { Pin *pin = end->vertex(this)->pin(); - const char *pin_name = cmd_network_->pathName(pin); + std::string pin_name = cmd_network_->pathName(pin); if (network_->isTopLevelPort(pin)) { PortDirection *dir = network_->direction(pin); return sta::format("{} ({})", pin_name, dir->name()); } else { Instance *inst = network_->instance(end->vertex(this)->pin()); - const char *cell_name = cmd_network_->name(network_->cell(inst)); + std::string cell_name = cmd_network_->name(network_->cell(inst)); return sta::format("{} ({})", pin_name, cell_name); } } @@ -1157,7 +1145,7 @@ ReportPath::reportJson(const Path *path) const void ReportPath::reportJson(const Path *path, - const char *path_name, + std::string_view path_name, int indent, bool trailing_comma, std::string &result) const @@ -1168,7 +1156,7 @@ ReportPath::reportJson(const Path *path, void ReportPath::reportJson(const PathExpanded &expanded, - const char *path_name, + std::string_view path_name, int indent, bool trailing_comma, std::string &result) const @@ -1188,26 +1176,26 @@ ReportPath::reportJson(const PathExpanded &expanded, if (inst) { result += sta::format("{:>{}} \"instance\": \"{}\",\n", - "", indent, - sdc_network_->pathName(inst)); + "", indent, + sdc_network_->pathName(inst)); Cell *cell = network_->cell(inst); if (cell) result += sta::format("{:>{}} \"cell\": \"{}\",\n", - "", indent, - sdc_network_->name(cell)); + "", indent, + sdc_network_->name(cell)); result += sta::format("{:>{}} \"verilog_src\": \"{}\",\n", - "", indent, - sdc_network_->getAttribute(inst, "src").c_str()); + "", indent, + sdc_network_->getAttribute(inst, "src")); } result += sta::format("{:>{}} \"pin\": \"{}\",\n", - "", indent, - sdc_network_->pathName(pin)); + "", indent, + sdc_network_->pathName(pin)); if (net) { result += sta::format("{:>{}} \"net\": \"{}\",\n", - "", indent, - sdc_network_->pathName(net)); + "", indent, + sdc_network_->pathName(net)); } PinSeq pins_above; @@ -1216,9 +1204,9 @@ ReportPath::reportJson(const PathExpanded &expanded, result += sta::format("{:>{}} \"hier_pins\": [\n", "", indent); for (const Pin *hpin : pins_above) { result += sta::format("{:>{}} \"{}\"{}\n", - "", indent, - sdc_network_->pathName(hpin), - (hpin != pins_above.back()) ? "," : ""); + "", indent, + sdc_network_->pathName(hpin), + (hpin != pins_above.back()) ? "," : ""); } result += sta::format("{:>{}} ],\n", "", indent); } @@ -1232,22 +1220,22 @@ ReportPath::reportJson(const PathExpanded &expanded, } result += sta::format("{:>{}} \"arrival\": {:.3e},\n", - "", indent, - delayAsFloat(path->arrival())); + "", indent, + delayAsFloat(path->arrival())); if (is_driver) result += sta::format("{:>{}} \"capacitance\": {:.3e},\n", - "", indent, - graph_delay_calc_->loadCap(pin, rf, scene, min_max)); + "", indent, + graph_delay_calc_->loadCap(pin, rf, scene, min_max)); result += sta::format("{:>{}} \"slew\": {:.3e}\n", - "", indent, - delayAsFloat(path->slew(this))); + "", indent, + delayAsFloat(path->slew(this))); result += sta::format("{:>{}} }}{}\n", - "", indent, - (i < expanded.size() - 1) ? "," : ""); + "", indent, + (i < expanded.size() - 1) ? "," : ""); } result += sta::format("{:>{}}]{}\n", - "", indent, - trailing_comma ? "," : ""); + "", indent, + trailing_comma ? "," : ""); } //////////////////////////////////////////////////////////////// @@ -1269,7 +1257,7 @@ ReportPath::reportSlackOnly(const PathEnd *end) const { std::string line; const EarlyLate *early_late = end->pathEarlyLate(this); - reportDescription(end->pathGroup()->name().c_str(), line); + reportDescription(end->pathGroup()->name(), line); if (end->isUnconstrained()) reportSpaceFieldDelay(end->dataArrivalTimeOffset(this), early_late, line); else @@ -1345,7 +1333,7 @@ ReportPath::reportShort(const MinPulseWidthCheck &check) const std::string what = sta::format("{} ({})", cmd_network_->pathName(check.pin(this)), mpwCheckHiLow(check)); - reportDescription(what.c_str(), line); + reportDescription(what, line); reportSpaceFieldTime(check.minWidth(this), line); reportSpaceFieldDelay(check.width(this), EarlyLate::late(), line); reportSpaceSlack(check.slack(this), line); @@ -1355,10 +1343,8 @@ ReportPath::reportShort(const MinPulseWidthCheck &check) const void ReportPath::reportVerbose(const MinPulseWidthCheck &check) const { - std::string line; - const char *pin_name = cmd_network_->pathName(check.pin(this)); - line += "Pin: "; - line += pin_name; + std::string pin_name = cmd_network_->pathName(check.pin(this)); + std::string line = "Pin: " + pin_name; report_->reportLine(line); report_->report("Check: sequential_clock_pulse_width"); @@ -1372,11 +1358,11 @@ ReportPath::reportVerbose(const MinPulseWidthCheck &check) const std::string open_clk_msg = sta::format("clock {} ({} edge)", open_clk->name(), asRiseFall(open_clk_edge->transition())); - reportLine(open_clk_msg.c_str(), open_clk_time, open_clk_time, open_el); + reportLine(open_clk_msg, open_clk_time, open_clk_time, open_el); Arrival open_arrival = check.openArrival(this); bool is_prop = isPropagated(check.openPath()); - const char *clk_ideal_prop = clkNetworkDelayIdealProp(is_prop); + std::string_view clk_ideal_prop = clkNetworkDelayIdealProp(is_prop); reportLine(clk_ideal_prop, check.openDelay(this), open_arrival, open_el); reportLine(pin_name, delay_zero, open_arrival, open_el); reportLine("open edge arrival time", open_arrival, open_el); @@ -1390,7 +1376,7 @@ ReportPath::reportVerbose(const MinPulseWidthCheck &check) const std::string close_clk_msg = sta::format("clock {} ({} edge)", close_clk->name(), asRiseFall(close_clk_edge->transition())); - reportLine(close_clk_msg.c_str(), close_clk_time, close_clk_time, close_el); + reportLine(close_clk_msg, close_clk_time, close_clk_time, close_el); Arrival close_arrival = delaySum(check.closeArrival(this), close_offset, this); reportLine(clk_ideal_prop, check.closeDelay(this), close_arrival, close_el); @@ -1408,13 +1394,13 @@ ReportPath::reportVerbose(const MinPulseWidthCheck &check) const float min_width = check.minWidth(this); std::string rpw_msg = sta::format("required pulse width ({})", mpwCheckHiLow(check)); - reportLine(rpw_msg.c_str(), min_width, EarlyLate::early()); + reportLine(rpw_msg, min_width, EarlyLate::early()); reportLine("actual pulse width", check.width(this), EarlyLate::early()); reportDashLine(); reportSlack(check.slack(this)); } -const char * +std::string_view ReportPath::mpwCheckHiLow(const MinPulseWidthCheck &check) const { if (check.openTransition(this) == RiseFall::rise()) @@ -1490,7 +1476,7 @@ void ReportPath::reportShort(const MinPeriodCheck &check) const { std::string line; - const char *pin_name = cmd_network_->pathName(check.pin()); + const std::string pin_name = cmd_network_->pathName(check.pin()); reportDescription(pin_name, line); reportSpaceFieldDelay(check.period(), EarlyLate::early(), line); reportSpaceFieldDelay(check.minPeriod(this), EarlyLate::early(), line); @@ -1501,10 +1487,7 @@ ReportPath::reportShort(const MinPeriodCheck &check) const void ReportPath::reportVerbose(const MinPeriodCheck &check) const { - std::string line; - const char *pin_name = cmd_network_->pathName(check.pin()); - line += "Pin: "; - line += pin_name; + std::string line = "Pin: " + cmd_network_->pathName(check.pin()); report_->reportLine(line); reportLine("period", check.period(), EarlyLate::early()); @@ -1570,7 +1553,7 @@ ReportPath::reportShort(const MaxSkewCheck &check) const network_->pathName(clk_pin), check_arc->fromEdge()->to_string(), check_arc->toEdge()->to_string()); - reportDescription(what.c_str(), line); + reportDescription(what, line); const EarlyLate *early_late = EarlyLate::early(); reportSpaceFieldDelay(check.maxSkew(this), early_late, line); reportSpaceFieldDelay(check.skew(this), early_late, line); @@ -1607,7 +1590,7 @@ ReportPath::reportVerbose(const MaxSkewCheck &check) const // Based on reportTgtClk. void -ReportPath::reportSkewClkPath(const char *arrival_msg, +ReportPath::reportSkewClkPath(std::string_view arrival_msg, const Path *clk_path) const { const ClockEdge *clk_edge = clk_path->clkEdge(this); @@ -1623,7 +1606,7 @@ ReportPath::reportSkewClkPath(const char *arrival_msg, this); const MinMax *min_max = clk_path->minMax(this); Vertex *clk_vertex = clk_path->vertex(this); - reportClkLine(clk, clk_name.c_str(), clk_end_rf, clk_time, min_max); + reportClkLine(clk, clk_name, clk_end_rf, clk_time, min_max); bool is_prop = isPropagated(clk_path); if (is_prop && reportClkPath()) { @@ -1644,7 +1627,7 @@ ReportPath::reportSkewClkPath(const char *arrival_msg, } else { reportLine(clkNetworkDelayIdealProp(is_prop), clk_delay, clk_arrival, early_late); - reportLine(descriptionField(clk_vertex).c_str(), clk_arrival, + reportLine(descriptionField(clk_vertex), clk_arrival, early_late, clk_end_rf); } reportLine(arrival_msg, search_->clkPathArrival(clk_path), early_late); @@ -1677,7 +1660,7 @@ ReportPath::reportLimitShort(const ReportField *field, float slack) const { std::string line; - const char *pin_name = cmd_network_->pathName(pin); + const std::string pin_name = cmd_network_->pathName(pin); reportDescription(pin_name, line); line += ' '; reportField(limit, field, line); @@ -1729,11 +1712,11 @@ ReportPath::reportLimitVerbose(const ReportField *field, reportField(value, field, line); report_->reportLine(line); - int name_width = strlen(field->name()) + 5; + size_t name_width = field->name().size() + 5; reportDashLine(name_width + field->width()); line = "Slack"; - for (int i = strlen("Slack"); i < name_width; i++) + for (size_t i = strlen("Slack"); i < name_width; i++) line += ' '; reportField(slack, field, line); line += (slack >= 0.0) @@ -1756,16 +1739,16 @@ ReportPath::reportStartpoint(const PathEnd *end, const Pin *pin = start->pin(graph_); const ClockEdge *clk_edge = path->clkEdge(this); const Clock *clk = path->clock(search_); - const char *pin_name = cmd_network_->pathName(pin); + std::string pin_name = cmd_network_->pathName(pin); if (pathFromClkPin(path, pin)) { - const char *clk_name = clk->name(); + const std::string &clk_name = clk->name(); std::string reason = sta::format("clock source '{}'", clk_name); reportStartpoint(pin_name, reason); } else if (network_->isTopLevelPort(pin)) { if (clk && clk != sdc->defaultArrivalClock()) { - const char *clk_name = clk->name(); + const std::string &clk_name = clk->name(); // Pin direction is "input" even for bidirects. std::string reason = sta::format("input port clocked by {}", clk_name); reportStartpoint(pin_name, reason); @@ -1775,20 +1758,20 @@ ReportPath::reportStartpoint(const PathEnd *end, } else if (network_->isLeaf(pin) && prev_arc) { Instance *inst = network_->instance(pin); - const char *inst_name = cmd_network_->pathName(inst); + std::string inst_name = cmd_network_->pathName(inst); if (clk_edge) { const RiseFall *clk_rf = clk_edge->transition(); const Path *clk_path = expanded.clkPath(); bool clk_inverted = clk_path && clk_rf != clk_path->transition(this); std::string clk_name = clkName(clk, clk_inverted); - const char *reg_desc = edgeRegLatchDesc(prev_edge, prev_arc); + std::string_view reg_desc = edgeRegLatchDesc(prev_edge, prev_arc); std::string reason = sta::format("{} clocked by {}", reg_desc, clk_name); reportStartpoint(inst_name, reason); } else { - const char *reg_desc = edgeRegLatchDesc(prev_edge, prev_arc); - reportStartpoint(inst_name, reg_desc); + std::string_view reg_desc = edgeRegLatchDesc(prev_edge, prev_arc); + reportStartpoint(inst_name, std::string(reg_desc)); } } else if (network_->isLeaf(pin)) { @@ -1828,15 +1811,15 @@ ReportPath::pathFromClkPin(const Path *path, } void -ReportPath::reportStartpoint(const char *start, - const std::string reason) const +ReportPath::reportStartpoint(std::string_view start, + const std::string &reason) const { reportStartEndPoint(start, reason, "Startpoint"); } void ReportPath::reportUnclockedEndpoint(const PathEnd *end, - const char *default_reason) const + std::string_view default_reason) const { Vertex *vertex = end->vertex(this); Pin *pin = vertex->pin(); @@ -1853,53 +1836,53 @@ ReportPath::reportUnclockedEndpoint(const PathEnd *end, VertexOutEdgeIterator clk_edge_iter(clk_vertex, graph_); while (clk_edge_iter.hasNext()) { Edge *clk_edge = clk_edge_iter.next(); + Instance *inst = network_->instance(pin); + std::string inst_name = cmd_network_->pathName(inst); if (clk_edge->role() == TimingRole::regClkToQ()) { - Instance *inst = network_->instance(pin); - const char *inst_name = cmd_network_->pathName(inst); - const char *reason = regDesc(clk_edge->timingArcSet()->isRisingFallingEdge()); - reportEndpoint(inst_name, reason); + std::string_view reason = + regDesc(clk_edge->timingArcSet()->isRisingFallingEdge()); + reportEndpoint(inst_name, std::string(reason)); return; } if (clk_edge->role() == TimingRole::latchEnToQ()) { - Instance *inst = network_->instance(pin); - const char *inst_name = cmd_network_->pathName(inst); - const char *reason = latchDesc(clk_edge->timingArcSet()->isRisingFallingEdge()); - reportEndpoint(inst_name, reason); + std::string_view reason = + latchDesc(clk_edge->timingArcSet()->isRisingFallingEdge()); + reportEndpoint(inst_name, std::string(reason)); return; } } } } - reportEndpoint(cmd_network_->pathName(pin), default_reason); + reportEndpoint(cmd_network_->pathName(pin), std::string(default_reason)); } else reportEndpoint(cmd_network_->pathName(pin), ""); } void -ReportPath::reportEndpoint(const char *end, - const std::string reason) const +ReportPath::reportEndpoint(std::string_view end, + const std::string &reason) const { reportStartEndPoint(end, reason, "Endpoint"); } void -ReportPath::reportStartEndPoint(const char *pt, - std::string reason, - const char *key) const +ReportPath::reportStartEndPoint(std::string_view pt, + const std::string &reason, + std::string_view key) const { std::string line; // Account for punctuation in the line. - int line_len = strlen(key) + 2 + strlen(pt) + 2 + reason.size() + 1; + size_t line_len = key.size() + 2 + pt.size() + 2 + reason.size() + 1; if (!no_split_ && line_len > start_end_pt_width_) { - line = key; + line = std::string(key); line += ": "; line += pt; report_->reportLine(line); line.clear(); - for (unsigned i = 0; i < strlen(key); i++) + for (size_t i = 0; i < key.size(); i++) line += ' '; line += " ("; @@ -1908,7 +1891,7 @@ ReportPath::reportStartEndPoint(const char *pt, report_->reportLine(line); } else { - line = key; + line = std::string(key); line += ": "; line += pt; line += " ("; @@ -1972,7 +1955,7 @@ ReportPath::clkName(const Clock *clk, return name; } -const char * +std::string_view ReportPath::clkRegLatchDesc(const PathEnd *end) const { // Goofy libraries can have registers with both rising and falling @@ -2103,13 +2086,13 @@ ReportPath::reportSrcClkAndPath(const Path *path, const EarlyLate *early_late = min_max; if (reportGenClkSrcPath(clk_path, clk, clk_rf, min_max, early_late, sdc) && !(path_from_input && !input_has_ref_path)) { - reportClkLine(clk, clk_name.c_str(), clk_end_rf, clk_time, min_max); + reportClkLine(clk, clk_name, clk_end_rf, clk_time, min_max); reportGenClkSrcAndPath(path, clk, clk_rf, early_late, time_offset, time_offset, clk_used_as_data, mode); } else if (clk_used_as_data && pathFromGenPropClk(path, path->minMax(this))) { - reportClkLine(clk, clk_name.c_str(), clk_end_rf, clk_time, min_max); + reportClkLine(clk, clk_name, clk_end_rf, clk_time, min_max); const ClkInfo *clk_info = path->tag(search_)->clkInfo(); if (clk_info->isPropagated()) reportClkSrcLatency(clk_insertion, clk_time, early_late); @@ -2118,12 +2101,12 @@ ReportPath::reportSrcClkAndPath(const Path *path, else if (is_prop && reportClkPath() && !(path_from_input && !input_has_ref_path)) { - reportClkLine(clk, clk_name.c_str(), clk_end_rf, clk_time, early_late); + reportClkLine(clk, clk_name, clk_end_rf, clk_time, early_late); reportClkSrcLatency(clk_insertion, clk_time, early_late); reportPath1(path, expanded, false, time_offset); } else if (clk_used_as_data) { - reportClkLine(clk, clk_name.c_str(), clk_end_rf, clk_time, early_late); + reportClkLine(clk, clk_name, clk_end_rf, clk_time, early_late); if (delayGreater(clk_insertion, 0.0, this)) reportClkSrcLatency(clk_insertion, clk_time, early_late); if (reportClkPath()) @@ -2137,7 +2120,7 @@ ReportPath::reportSrcClkAndPath(const Path *path, reportLine("clock network delay", clk_delay, end_arrival, early_late); Vertex *end_vertex = path->vertex(this); - reportLine(descriptionField(end_vertex).c_str(), + reportLine(descriptionField(end_vertex), end_arrival, early_late, clk_end_rf); } } @@ -2148,7 +2131,7 @@ ReportPath::reportSrcClkAndPath(const Path *path, clk_end_time, early_late); } else { - reportClkLine(clk, clk_name.c_str(), clk_end_rf, clk_time, min_max); + reportClkLine(clk, clk_name, clk_end_rf, clk_time, min_max); Arrival clk_arrival = clk_end_time; reportLine(clkNetworkDelayIdealProp(is_prop), clk_delay, clk_arrival, early_late); @@ -2204,7 +2187,7 @@ ReportPath::reportTgtClk(const PathEnd *end, Arrival clk_arrival = delaySum(clk_delay, clk_time, this); const MinMax *min_max = end->path()->tgtClkMinMax(this); const Path *clk_path = end->targetClkPath(); - reportClkLine(clk, clk_name.c_str(), clk_end_rf, prev_time, clk_time, min_max); + reportClkLine(clk, clk_name, clk_end_rf, prev_time, clk_time, min_max); const TimingRole *check_role = end->checkRole(this); if (is_prop && reportClkPath()) { float time_offset = prev_time @@ -2245,12 +2228,12 @@ ReportPath::reportTgtClk(const PathEnd *end, reportCommonClkPessimism(end, clk_arrival); if (clk_path) { Vertex *clk_vertex = clk_path->vertex(this); - reportLine(descriptionField(clk_vertex).c_str(), - delaySum(delaySum(prev_time, - end->targetClkArrival(this), - this), - end->sourceClkOffset(this), - this), + reportLine(descriptionField(clk_vertex), + delaySum(delaySum(prev_time, + end->targetClkArrival(this), + this), + end->sourceClkOffset(this), + this), min_max, clk_end_rf); } } @@ -2315,7 +2298,7 @@ ReportPath::isGenPropClk(const Clock *clk, void ReportPath::reportClkLine(const Clock *clk, - const char *clk_name, + std::string_view clk_name, const RiseFall *clk_rf, Arrival clk_time, const MinMax *min_max) const @@ -2325,23 +2308,23 @@ ReportPath::reportClkLine(const Clock *clk, void ReportPath::reportClkLine(const Clock *clk, - const char *clk_name, + std::string_view clk_name, const RiseFall *clk_rf, Arrival prev_time, Arrival clk_time, const MinMax *min_max) const { - const char *rise_fall = asRiseFall(clk_rf); + std::string_view rise_fall = asRiseFall(clk_rf); std::string clk_msg = sta::format("clock {} ({} edge)", clk_name, rise_fall); if (clk->isPropagated()) - reportLine(clk_msg.c_str(), + reportLine(clk_msg, delayDiff(clk_time, prev_time, this), clk_time, min_max); else { // Report ideal clock slew. float clk_slew = clk->slew(clk_rf, min_max); - reportLine(clk_msg.c_str(), + reportLine(clk_msg, clk_slew, delayDiff(clk_time, prev_time, this), clk_time, @@ -2457,7 +2440,7 @@ void ReportPath::reportPathLine(const Path *path, const Delay &incr, const Arrival &time, - const char *line_case) const + std::string_view line_case) const { Vertex *vertex = path->vertex(this); Pin *pin = vertex->pin(); @@ -2477,9 +2460,8 @@ ReportPath::reportPathLine(const Path *path, // Don't show capacitance field for input pins. if (is_driver && field_capacitance_->enabled()) cap = graph_delay_calc_->loadCap(pin, rf, scene, min_max); - reportLine(what.c_str(), cap, slew, field_blank_, - incr, field_blank_, time, false, early_late, rf, src_attr, - line_case); + reportLine(what, cap, slew, field_blank_, incr, field_blank_, + time, false, early_late, rf, src_attr, line_case); } void @@ -2497,7 +2479,7 @@ ReportPath::reportRequired(const PathEnd *end, if (macro_clk_tree_delay != 0.0) reportLine("macro clock tree delay", -macro_clk_tree_delay, delaySum(req_time, margin, this), early_late); - reportLine(margin_msg.c_str(), + reportLine(margin_msg, delayDiff(delay_zero, margin, this), req_time, early_late); @@ -2520,7 +2502,7 @@ void ReportPath::reportSlack(Slack slack) const { const EarlyLate *early_late = EarlyLate::early(); - const char *msg = (delayAsFloat(slack, early_late, this) >= 0.0) + std::string_view msg = (delayAsFloat(slack, early_late, this) >= 0.0) ? "slack (MET)" : "slack (VIOLATED)"; reportLine(msg, slack, early_late); @@ -2750,7 +2732,7 @@ ReportPath::reportPath6(const Path *path, Pin *pin = vertex->pin(); Arrival time = delaySum(path1->arrival(), time_offset, this); Delay incr = 0.0; - const char *line_case = nullptr; + std::string_view line_case = ""; bool is_clk_start = path1->vertex(this) == clk_start; bool is_clk = path1->isClock(search_); Instance *inst = network_->instance(pin); @@ -2847,13 +2829,13 @@ ReportPath::reportPath6(const Path *path, if (field_fanout_->enabled()) fanout = drvrFanout(vertex, scene, min_max); const std::string what = descriptionField(vertex); - reportLine(what.c_str(), cap, slew, fanout, + reportLine(what, cap, slew, fanout, incr, field_blank_, time, false, min_max, rf, src_attr, line_case); if (report_net_) { const std::string what2 = descriptionNet(pin); - reportLine(what2.c_str(), field_blank_, field_blank_, field_blank_, + reportLine(what2, field_blank_, field_blank_, field_blank_, field_blank_, field_blank_, field_blank_, false, min_max, nullptr, src_attr, ""); } @@ -2866,7 +2848,7 @@ ReportPath::reportPath6(const Path *path, || (i == path_last_index) || is_clk_start) { const std::string what = descriptionField(vertex); - reportLine(what.c_str(), field_blank_, slew, field_blank_, + reportLine(what, field_blank_, slew, field_blank_, incr, field_blank_, time, false, min_max, rf, src_attr, line_case); prev_time = time; @@ -2892,28 +2874,28 @@ ReportPath::reportVariation(const Path *path) const case PocvMode::normal: { float std_dev = arc_delay.stdDev(); reportLine("sigma", field_blank_, field_blank_, field_blank_, - field_blank_, std_dev, field_blank_, true, min_max, nullptr, - "", nullptr); + field_blank_, std_dev, field_blank_, true, min_max, + nullptr, "", ""); break; } case PocvMode::skew_normal: { float mean = arc_delay.mean(); reportLine("mean", field_blank_, field_blank_, field_blank_, - field_blank_, mean, field_blank_, true, min_max, nullptr, - "", nullptr); + field_blank_, mean, field_blank_, true, min_max, + nullptr, "", ""); float mean_shift = arc_delay.meanShift(); reportLine("mean_shift", field_blank_, field_blank_, field_blank_, - field_blank_, mean_shift, field_blank_, true, min_max, nullptr, - "", nullptr); + field_blank_, mean_shift, field_blank_, true, min_max, + nullptr, "", ""); float std_dev = arc_delay.stdDev(); reportLine("std_dev", field_blank_, field_blank_, field_blank_, - field_blank_, std_dev, field_blank_, true, min_max, nullptr, - "", nullptr); + field_blank_, std_dev, field_blank_, true, min_max, + nullptr, "", ""); // skewness is dimensionless, so scale it to the field's time units. float skewness = arc_delay.skewness() * units_->timeUnit()->scale(); reportLine("skewness", field_blank_, field_blank_, field_blank_, - field_blank_, skewness, field_blank_, true, min_max, nullptr, - "", nullptr); + field_blank_, skewness, field_blank_, true, min_max, + nullptr, "", ""); break; } default: @@ -2939,7 +2921,7 @@ ReportPath::reportHierPinsThru(const Path *path) const if (prev_edge && prev_edge->isWire()) { for (const Pin *hpin : hierPinsThruEdge(prev_edge, network_, graph_)) { const std::string what = descriptionField(hpin); - reportLine(what.c_str(), field_blank_, field_blank_, field_blank_, + reportLine(what, field_blank_, field_blank_, field_blank_, field_blank_, field_blank_, field_blank_, false, path->minMax(this), nullptr, "", ""); } @@ -2967,8 +2949,7 @@ ReportPath::descriptionField(const Vertex *vertex) const std::string ReportPath::descriptionField(const Pin *pin) const { - const char *pin_name = cmd_network_->pathName(pin); - const char *name2; + std::string name2; if (network_->isTopLevelPort(pin)) { PortDirection *dir = network_->direction(pin); // Translate port direction. Note that this is intentionally @@ -2987,21 +2968,20 @@ ReportPath::descriptionField(const Pin *pin) const Instance *inst = network_->instance(pin); name2 = network_->cellName(inst); } + std::string pin_name = cmd_network_->pathName(pin); return sta::format("{} ({})", pin_name, name2); } std::string ReportPath::descriptionNet(const Pin *pin) const { - if (network_->isTopLevelPort(pin)) { - const char *pin_name = cmd_network_->pathName(pin); - return sta::format("{} (net)", pin_name); - } + if (network_->isTopLevelPort(pin)) + return sta::format("{} (net)", cmd_network_->pathName(pin)); else { Net *net = network_->net(pin); if (net) { Net *highest_net = network_->highestNetAbove(net); - const char *net_name = cmd_network_->pathName(highest_net); + std::string net_name = cmd_network_->pathName(highest_net); return sta::format("{} (net)", net_name); } else @@ -3131,78 +3111,73 @@ ReportPath::reportPathHeader() const // Report total. void -ReportPath::reportLine(const char *what, +ReportPath::reportLine(std::string_view what, Delay total, const EarlyLate *early_late) const { reportLine(what, field_blank_, field_blank_, field_blank_, field_blank_, - field_blank_, total, false, early_late, nullptr, - "", nullptr); + field_blank_, total, false, early_late, nullptr, "", ""); } // Report negative total. void -ReportPath::reportLineNegative(const char *what, +ReportPath::reportLineNegative(std::string_view what, Delay total, const EarlyLate *early_late) const { reportLine(what, field_blank_, field_blank_, field_blank_, field_blank_, field_blank_, total, true /* tota_with_minus */, - early_late, nullptr, "", nullptr); + early_late, nullptr, "", ""); } // Report total, and transition suffix. void -ReportPath::reportLine(const char *what, +ReportPath::reportLine(std::string_view what, Delay total, const EarlyLate *early_late, const RiseFall *rf) const { reportLine(what, field_blank_, field_blank_, field_blank_, - field_blank_, field_blank_, total, false, early_late, rf, "", - nullptr); + field_blank_, field_blank_, total, false, early_late, rf, "", ""); } // Report increment, and total. void -ReportPath::reportLine(const char *what, +ReportPath::reportLine(std::string_view what, const Delay &incr, const Delay &total, const EarlyLate *early_late) const { reportLine(what, field_blank_, field_blank_, field_blank_, - incr, field_blank_, total, false, early_late, nullptr, "", - nullptr); + incr, field_blank_, total, false, early_late, nullptr, "", ""); } // Report increment, total, and transition suffix. void -ReportPath::reportLine(const char *what, +ReportPath::reportLine(std::string_view what, const Delay &incr, const Delay &total, const EarlyLate *early_late, const RiseFall *rf) const { reportLine(what, field_blank_, field_blank_, field_blank_, - incr, field_blank_, total, false, early_late, rf, "", - nullptr); + incr, field_blank_, total, false, early_late, rf, "", ""); } // Report slew, increment, and total. void -ReportPath::reportLine(const char *what, +ReportPath::reportLine(std::string_view what, const Slew &slew, const Delay &incr, const Delay &total, const EarlyLate *early_late) const { reportLine(what, field_blank_, slew, field_blank_, - incr, field_blank_, total, false, early_late, nullptr, - "", nullptr); + incr, field_blank_, total, false, early_late, nullptr, "", ""); } void -ReportPath::reportLine(const char *what, +ReportPath::reportLine(std::string_view what, float cap, const Slew &slew, float fanout, @@ -3213,7 +3188,7 @@ ReportPath::reportLine(const char *what, const EarlyLate *early_late, const RiseFall *rf, std::string src_attr, - const char *line_case) const + std::string_view line_case) const { std::string line; size_t field_index = 0; @@ -3232,7 +3207,7 @@ ReportPath::reportLine(const char *what, reportFieldBlank(field, line); else line += sta::format("{:{}}", - static_cast(fanout), + fanout, field_fanout_->width()); } else if (field == field_capacitance_) @@ -3259,11 +3234,11 @@ ReportPath::reportLine(const char *what, reportFieldBlank(field, line); else if (field == field_src_attr_) { if (src_attr != "") - reportField(src_attr.c_str(), field, line); + reportField(src_attr, field, line); else reportFieldBlank(field, line); } - else if (field == field_case_ && line_case) + else if (field == field_case_) line += line_case; first_field = false; @@ -3280,7 +3255,7 @@ ReportPath::reportLine(const char *what, // Only the total field. void -ReportPath::reportLineTotal(const char *what, +ReportPath::reportLineTotal(std::string_view what, const Delay &incr, const EarlyLate *early_late) const { @@ -3289,7 +3264,7 @@ ReportPath::reportLineTotal(const char *what, // Only the total field and always with leading minus sign. void -ReportPath::reportLineTotalMinus(const char *what, +ReportPath::reportLineTotalMinus(std::string_view what, const Delay &decr, const EarlyLate *early_late) const { @@ -3297,7 +3272,7 @@ ReportPath::reportLineTotalMinus(const char *what, } void -ReportPath::reportLineTotal1(const char *what, +ReportPath::reportLineTotal1(std::string_view what, const Delay &incr, bool incr_with_minus, const EarlyLate *early_late) const @@ -3321,29 +3296,29 @@ ReportPath::reportDashLineTotal() const //////////////////////////////////////////////////////////////// void -ReportPath::reportDescription(const char *what, +ReportPath::reportDescription(std::string_view what, std::string &line) const { reportDescription(what, false, false, line); } void -ReportPath::reportDescription(const char *what, +ReportPath::reportDescription(std::string_view what, bool first_field, bool last_field, std::string &line) const { line += what; - int length = strlen(what); + size_t length = what.size(); if (!no_split_ && first_field && length > field_description_->width()) { reportBlankLine(); - for (int i = 0; i < field_description_->width(); i++) + for (size_t i = 0; i < field_description_->width(); i++) line += ' '; } else if (!last_field) { - for (int i = length; i < field_description_->width(); i++) + for (size_t i = length; i < field_description_->width(); i++) line += ' '; } } @@ -3360,7 +3335,7 @@ ReportPath::reportFieldTime(float value, if (str == minus_zero_) // Filter "-0.00" fields. str = plus_zero_; - reportField(str.c_str(), field, line); + reportField(str, field, line); } } @@ -3390,7 +3365,7 @@ ReportPath::reportTotalDelay(const Delay &value, if (str == minus_zero_) // Filter "-0.00" fields. str = plus_zero_; - reportField(str.c_str(), field_total_, line); + reportField(str, field_total_, line); } // Total time always with leading minus sign. @@ -3409,7 +3384,7 @@ ReportPath::reportFieldDelayMinus(const Delay &value, if (str == plus_zero_) // Force leading minus sign. str = minus_zero_; - reportField(str.c_str(), field, line); + reportField(str, field, line); } } @@ -3426,7 +3401,7 @@ ReportPath::reportFieldDelay(const Delay &value, if (str == minus_zero_) // Filter "-0.00" fields. str = plus_zero_; - reportField(str.c_str(), field, line); + reportField(str, field, line); } } @@ -3441,24 +3416,24 @@ ReportPath::reportField(float value, Unit *unit = field->unit(); if (unit) { std::string value_str = unit->asString(value, digits_); - reportField(value_str.c_str(), field, line); + reportField(value_str, field, line); } else { // fanout std::string value_str = sta::format("{:.0f}", value); - reportField(value_str.c_str(), field, line); + reportField(value_str, field, line); } } } void -ReportPath::reportField(const char *value, +ReportPath::reportField(std::string_view value, const ReportField *field, std::string &line) const { if (field->leftJustify()) line += value; - for (int i = strlen(value); i < field->width(); i++) + for (size_t i = static_cast(value.size()); i < field->width(); i++) line += ' '; if (!field->leftJustify()) line += value; @@ -3477,7 +3452,7 @@ ReportPath::reportDashLine() const std::string line; for (const ReportField *field : fields_) { if (field->enabled()) { - for (int i = 0; i < field->width(); i++) + for (size_t i = 0; i < field->width(); i++) line += '-'; } } @@ -3509,7 +3484,7 @@ ReportPath::reportClkPath() const //////////////////////////////////////////////////////////////// -const char * +std::string_view ReportPath::asRisingFalling(const RiseFall *rf) const { if (rf == RiseFall::rise()) @@ -3518,7 +3493,7 @@ ReportPath::asRisingFalling(const RiseFall *rf) const return "falling"; } -const char * +std::string_view ReportPath::asRiseFall(const RiseFall *rf) const { if (rf == RiseFall::rise()) @@ -3528,7 +3503,7 @@ ReportPath::asRiseFall(const RiseFall *rf) const } // Find the startpoint type from the first path edge. -const char * +std::string_view ReportPath::edgeRegLatchDesc(const Edge *first_edge, const TimingArc *first_arc) const { @@ -3553,7 +3528,7 @@ ReportPath::edgeRegLatchDesc(const Edge *first_edge, return regDesc(first_arc->fromEdge()->asRiseFall()); } -const char * +std::string_view ReportPath::checkRegLatchDesc(const TimingRole *role, const RiseFall *clk_rf) const { @@ -3567,7 +3542,7 @@ ReportPath::checkRegLatchDesc(const TimingRole *role, return "edge-triggered flip-flop"; } -const char * +std::string_view ReportPath::regDesc(const RiseFall *clk_rf) const { if (clk_rf == RiseFall::rise()) @@ -3578,7 +3553,7 @@ ReportPath::regDesc(const RiseFall *clk_rf) const return "edge-triggered flip-flop"; } -const char * +std::string_view ReportPath::latchDesc(const RiseFall *clk_rf) const { return (clk_rf == RiseFall::rise()) diff --git a/search/ReportPath.hh b/search/ReportPath.hh index cec91ba7..b27e5fc1 100644 --- a/search/ReportPath.hh +++ b/search/ReportPath.hh @@ -25,6 +25,7 @@ #pragma once #include +#include #include #include "StringUtil.hh" @@ -61,7 +62,7 @@ public: int digits() const { return digits_; } void setDigits(int digits); void setNoSplit(bool no_split); - ReportField *findField(const char *name) const; + ReportField *findField(std::string_view name) const; // Header above reportPathEnd results. void reportPathEndHeader() const; @@ -99,12 +100,12 @@ public: bool last) const; void reportJson(const Path *path) const; void reportJson(const Path *path, - const char *path_name, + std::string_view path_name, int indent, bool trailing_comma, std::string &result) const; void reportJson(const PathExpanded &expanded, - const char *path_name, + std::string_view path_name, int indent, bool trailing_comma, std::string &result) const; @@ -161,8 +162,8 @@ public: protected: void makeFields(); - ReportField *makeField(const char *name, - const char *title, + ReportField *makeField(std::string_view name, + std::string_view title, int width, bool left_justify, Unit *unit, @@ -194,7 +195,7 @@ protected: Arrival &borrow, Arrival &time_given_to_startpoint) const; void reportEndpoint(const PathEndDataCheck *end) const; - const char *clkNetworkDelayIdealProp(bool is_ideal) const; + std::string_view clkNetworkDelayIdealProp(bool is_ideal) const; std::string checkRoleReason(const PathEnd *end) const; std::string checkRoleString(const PathEnd *end) const; @@ -202,19 +203,19 @@ protected: void reportStartpoint(const PathEnd *end, const PathExpanded &expanded) const; void reportUnclockedEndpoint(const PathEnd *end, - const char *default_reason) const; + std::string_view default_reason) const; void reportEndpoint(const PathEndCheck *end) const; void reportEndpoint(const PathEndLatchCheck *end) const; - const char *latchDesc(const PathEndLatchCheck *end) const; - void reportStartpoint(const char *start, - const std::string reason) const; - void reportEndpoint(const char *end, - const std::string reason) const; - void reportStartEndPoint(const char *pt, - const std::string reason, - const char *key) const; + std::string_view latchDesc(const PathEndLatchCheck *end) const; + void reportStartpoint(std::string_view start, + const std::string &reason) const; + void reportEndpoint(std::string_view end, + const std::string &reason) const; + void reportStartEndPoint(std::string_view pt, + const std::string &reason, + std::string_view key) const; std::string tgtClkName(const PathEnd *end) const; - const char *clkRegLatchDesc(const PathEnd *end) const; + std::string_view clkRegLatchDesc(const PathEnd *end) const; void reportSrcPath(const PathEnd *end, const PathExpanded &expanded) const; void reportTgtClk(const PathEnd *end) const; @@ -268,18 +269,18 @@ protected: void reportPathLine(const Path *path, const Delay &incr, const Arrival &time, - const char *line_case) const; + std::string_view line_case) const; void reportCommonClkPessimism(const PathEnd *end, Arrival &clk_arrival) const ; void reportClkUncertainty(const PathEnd *end, Arrival &clk_arrival) const ; void reportClkLine(const Clock *clk, - const char *clk_name, + std::string_view clk_name, const RiseFall *clk_rf, Arrival clk_time, const MinMax *min_max) const ; void reportClkLine(const Clock *clk, - const char *clk_name, + std::string_view clk_name, const RiseFall *clk_rf, Arrival prev_time, Arrival clk_time, @@ -334,31 +335,31 @@ protected: void reportHierPinsThru(const Path *path) const; void reportInputExternalDelay(const Path *path, float time_offset) const; - void reportLine(const char *what, + void reportLine(std::string_view what, Delay total, const EarlyLate *early_late) const; - void reportLineNegative(const char *what, + void reportLineNegative(std::string_view what, Delay total, const EarlyLate *early_late) const; - void reportLine(const char *what, + void reportLine(std::string_view what, Delay total, const EarlyLate *early_late, const RiseFall *rf) const; - void reportLine(const char *what, + void reportLine(std::string_view what, const Delay &incr, const Delay &total, const EarlyLate *early_late) const; - void reportLine(const char *what, + void reportLine(std::string_view what, const Delay &incr, const Delay &total, const EarlyLate *early_late, const RiseFall *rf) const; - void reportLine(const char *what, + void reportLine(std::string_view what, const Slew &slew, const Delay &incr, const Delay &total, const EarlyLate *early_late) const; - void reportLine(const char *what, + void reportLine(std::string_view what, float cap, const Slew &slew, float fanout, @@ -369,21 +370,21 @@ protected: const EarlyLate *early_late, const RiseFall *rf, std::string src_attr, - const char *line_case) const; - void reportLineTotal(const char *what, + std::string_view line_case) const; + void reportLineTotal(std::string_view what, const Delay &incr, const EarlyLate *early_late) const; - void reportLineTotalMinus(const char *what, + void reportLineTotalMinus(std::string_view what, const Delay &decr, const EarlyLate *early_late) const; - void reportLineTotal1(const char *what, + void reportLineTotal1(std::string_view what, const Delay &incr, bool incr_with_minus, const EarlyLate *early_late) const; void reportDashLineTotal() const; - void reportDescription(const char *what, + void reportDescription(std::string_view what, std::string &result) const; - void reportDescription(const char *what, + void reportDescription(std::string_view what, bool first_field, bool last_field, std::string &result) const; @@ -409,7 +410,7 @@ protected: void reportField(float value, const ReportField *field, std::string &result) const; - void reportField(const char *value, + void reportField(std::string_view value, const ReportField *field, std::string &result) const; void reportFieldBlank(const ReportField *field, @@ -430,15 +431,15 @@ protected: float drvrFanout(Vertex *drvr, const Scene *scene, const MinMax *min_max) const; - const char *mpwCheckHiLow(const MinPulseWidthCheck &check) const; - void reportSkewClkPath(const char *arrival_msg, + std::string_view mpwCheckHiLow(const MinPulseWidthCheck &check) const; + void reportSkewClkPath(std::string_view arrival_msg, const Path *clk_path) const; - const char *edgeRegLatchDesc(const Edge *edge, - const TimingArc *arc) const; - const char *checkRegLatchDesc(const TimingRole *role, - const RiseFall *clk_rf) const; - const char *regDesc(const RiseFall *clk_rf) const; - const char *latchDesc(const RiseFall *clk_rf) const; + std::string_view edgeRegLatchDesc(const Edge *edge, + const TimingArc *arc) const; + std::string_view checkRegLatchDesc(const TimingRole *role, + const RiseFall *clk_rf) const; + std::string_view regDesc(const RiseFall *clk_rf) const; + std::string_view latchDesc(const RiseFall *clk_rf) const; void pathClkPath(const Path *path, const Path &clk_path) const; bool isPropagated(const Path *clk_path) const; @@ -464,8 +465,8 @@ protected: const InputDelay *input_delay, // Return value. Path &ref_path) const; - const char *asRisingFalling(const RiseFall *rf) const; - const char *asRiseFall(const RiseFall *rf) const; + std::string_view asRisingFalling(const RiseFall *rf) const; + std::string_view asRiseFall(const RiseFall *rf) const; Delay delayIncr(const Delay &time, const Delay &prev, const MinMax *min_max) const; @@ -479,7 +480,7 @@ protected: bool no_split_; int digits_; - int start_end_pt_width_; + size_t start_end_pt_width_; ReportField *field_description_; ReportField *field_total_; @@ -503,34 +504,34 @@ protected: class ReportField { public: - ReportField(const char *name, - const char *title, - int width, + ReportField(std::string_view name, + std::string_view title, + size_t width, bool left_justify, Unit *unit, bool enabled); ~ReportField(); - void setProperties(const char *title, - int width, + void setProperties(std::string_view title, + size_t width, bool left_justify); - const char *name() const { return name_; } - const char *title() const { return title_; } - int width() const { return width_; } - void setWidth(int width); + const std::string &name() const { return name_; } + const std::string &title() const { return title_; } + size_t width() const { return width_; } + void setWidth(size_t width); bool leftJustify() const { return left_justify_; } Unit *unit() const { return unit_; } - const char *blank() const { return blank_; } + const std::string &blank() const { return blank_; } void setEnabled(bool enabled); bool enabled() const { return enabled_; } protected: - const char *name_; - const char *title_; - int width_; + std::string name_; + std::string title_; + size_t width_; bool left_justify_; Unit *unit_; bool enabled_; - char *blank_; + std::string blank_; }; } // namespace diff --git a/search/Search.cc b/search/Search.cc index ae6bbfbf..f1a9658c 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -1390,7 +1390,7 @@ ArrivalVisitor::pruneCrprArrivals() ? delayDiff(max_arrival, max_crpr, this) : delaySum(max_arrival, max_crpr, this); debugPrint(debug_, "search", 4, " cmp {} {} - {} = {}", - tag->to_string(this).c_str(), + tag->to_string(this), delayAsString(max_arrival, this), delayAsString(max_crpr, this), delayAsString(max_arrival_max_crpr, this)); @@ -1767,7 +1767,7 @@ Search::seedInputDelayArrival(const Pin *pin, { debugPrint(debug_, "search", 2, input_delay ? "arrival seed input arrival {}" : "arrival seed input {}", - vertex->to_string(this).c_str()); + vertex->to_string(this)); const ClockEdge *clk_edge = nullptr; const Pin *ref_pin = nullptr; const Sdc *sdc = mode->sdc(); @@ -2673,7 +2673,7 @@ Search::findTagGroup(TagGroupBldr *tag_bldr) { TagGroup probe(tag_bldr, this); LockGuard lock(tag_group_lock_); - TagGroup *tag_group = findKey(tag_group_set_, &probe); + TagGroup *tag_group = findKey(*tag_group_set_, &probe); if (tag_group == nullptr) { TagGroupIndex tag_group_index; if (tag_group_free_indices_.empty()) @@ -2918,13 +2918,13 @@ Search::findTag(Scene *scene, Tag probe(scene, 0, rf, min_max, clk_info, is_clk, input_delay, is_segment_start, states, false); if (tag_cache) { - Tag *tag = findKey(tag_cache, &probe); + Tag *tag = findKey(*tag_cache, &probe); if (tag) return tag; } LockGuard lock(tag_lock_); - Tag *tag = findKey(tag_set_, &probe); + Tag *tag = findKey(*tag_set_, &probe); if (tag == nullptr) { // Make rise/fall versions of the tag to avoid tag_set lookups when the // only change is the rise/fall edge. @@ -3014,7 +3014,7 @@ Search::findClkInfo(Scene *scene, gen_clk_src_path, pulse_clk_sense, insertion, latency, uncertainties, min_max, crpr_clk_path, this); LockGuard lock(clk_info_lock_); - const ClkInfo *clk_info = findKey(clk_info_set_, &probe); + const ClkInfo *clk_info = findKey(*clk_info_set_, &probe); if (clk_info == nullptr) { clk_info = new ClkInfo(scene, clk_edge, clk_src, is_propagated, gen_clk_src, gen_clk_src_path, pulse_clk_sense, insertion, latency, @@ -3449,7 +3449,7 @@ RequiredCmp::requiredsSave(Vertex *vertex, const Required &prev_req = path->required(); bool changed = !delayEqual(prev_req, req, sta); debugPrint(debug, "search", 3, "required {} save {} -> {}{}", - path->to_string(sta).c_str(), + path->to_string(sta), delayAsString(prev_req, sta), delayAsString(req, sta), changed ? " changed" : ""); @@ -3549,7 +3549,7 @@ RequiredVisitor::visitFromToPath(const Pin *, Required from_required = delayDiff(to_required, arc_delay, this); debugPrint(debug_, "search", 3, " to tag {:2}: {}", to_tag->index(), - to_tag->to_string(this).c_str()); + to_tag->to_string(this)); debugPrint(debug_, "search", 3, " {} - {} = {} {} {}", delayAsString(to_required, this), delayAsString(arc_delay, this), @@ -3573,7 +3573,7 @@ RequiredVisitor::visitFromToPath(const Pin *, Required from_required = delayDiff(to_required, arc_delay, this); debugPrint(debug_, "search", 3, " to tag {:2}: {}", to_path_tag->index(), - to_path_tag->to_string(this).c_str()); + to_path_tag->to_string(this)); debugPrint(debug_, "search", 3, " {} - {} = {} {} {}", delayAsString(to_required, this), delayAsString(arc_delay, this), @@ -3838,7 +3838,7 @@ Search::tnsIncr(Vertex *vertex, if (delayLess(slack, 0.0, this)) { debugPrint(debug_, "tns", 3, "tns+ {} {}", delayAsString(slack, this), - vertex->to_string(this).c_str()); + vertex->to_string(this)); delayIncr(tns_[path_ap_index], slack, this); if (tns_slacks_[path_ap_index].contains(vertex)) report_->critical(1513, "tns incr existing vertex"); @@ -3857,7 +3857,7 @@ Search::tnsDecr(Vertex *vertex, && delayLess(slack, 0.0, this)) { debugPrint(debug_, "tns", 3, "tns- {} {}", delayAsString(slack, this), - vertex->to_string(this).c_str()); + vertex->to_string(this)); delayDecr(tns_[path_ap_index], slack, this); tns_slacks_[path_ap_index].erase(vertex); } diff --git a/search/Search.i b/search/Search.i index e6716ae1..fe836156 100644 --- a/search/Search.i +++ b/search/Search.i @@ -231,20 +231,21 @@ vertex_worst_slack_path(Vertex *vertex, float endpoint_slack(const Pin *pin, - const char *path_group_name, + const std::string &path_group_name, const MinMax *min_max) { Sta *sta = Sta::sta(); sta->ensureLibLinked(); - if (sta->isGroupPathName(path_group_name, sta->cmdSdc())) { - Slack slack = sta->endpointSlack(pin, std::string(path_group_name), min_max); - return sta->units()->timeUnit()->staToUser(delayAsFloat(slack, min_max, sta)); - } - else { + if (!path_group_name.empty() + && !sta->isGroupPathName(path_group_name, sta->cmdSdc())) { sta->report()->error(1577, "{} is not a known path group name.", path_group_name); return INF; } + else { + Slack slack = sta->endpointSlack(pin, path_group_name, min_max); + return sta->units()->timeUnit()->staToUser(delayAsFloat(slack, min_max, sta)); + } } StringSeq @@ -734,8 +735,8 @@ write_timing_model_cmd(const char *lib_name, void define_scene_cmd(const char *name, const char *mode_name, - const StringSeq liberty_min_files, - const StringSeq liberty_max_files, + StringSeq liberty_min_files, + StringSeq liberty_max_files, const char *spef_min_file, const char *spef_max_file) { @@ -746,7 +747,7 @@ define_scene_cmd(const char *name, } void -define_scenes_cmd(const StringSeq &scene_names) +define_scenes_cmd(StringSeq scene_names) { Sta *sta = Sta::sta(); sta->makeScenes(scene_names); @@ -953,18 +954,18 @@ crpr_mode() } void -set_crpr_mode(const char *mode) +set_crpr_mode(std::string mode) { Sta *sta = Sta::sta(); - if (stringEq(mode, "same_pin")) + if (stringEqual(mode, "same_pin")) sta->setCrprMode(CrprMode::same_pin); - else if (stringEq(mode, "same_transition")) + else if (stringEqual(mode, "same_transition")) sta->setCrprMode(CrprMode::same_transition); else sta->report()->error(1573, "unknown common clk pessimism mode."); } -const char * +const std::string & pocv_mode() { return pocvModeName(Sta::sta()->pocvMode()); diff --git a/search/Sim.cc b/search/Sim.cc index bf459097..f2fd6531 100644 --- a/search/Sim.cc +++ b/search/Sim.cc @@ -873,9 +873,9 @@ Sim::isDisabledMode(Edge *edge, const std::string &mode_value = arc_set->modeValue(); if (!mode_name.empty() && !mode_value.empty()) { LibertyCell *cell = network_->libertyCell(inst); - const ModeDef *mode_def = cell->findModeDef(mode_name.c_str()); + const ModeDef *mode_def = cell->findModeDef(mode_name); if (mode_def) { - const ModeValueDef *value_def = mode_def->findValueDef(mode_value.c_str()); + const ModeValueDef *value_def = mode_def->findValueDef(mode_value); if (value_def) { FuncExpr *cond = value_def->cond(); if (cond) { @@ -883,7 +883,7 @@ Sim::isDisabledMode(Edge *edge, if (cond_value == LogicValue::zero) { // For a mode value to be disabled by having a value of // logic zero one mode value must logic one. - for (const auto &[name, value_def] : *mode_def->values()) { + for (const auto &[name, value_def] : mode_def->values()) { FuncExpr *cond1 = value_def.cond(); if (cond1) { LogicValue cond_value1 = evalExpr(cond1, inst); diff --git a/search/Sta.cc b/search/Sta.cc index 355ef3f0..7a47319d 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -61,6 +61,7 @@ #include "DelayCalc.hh" #include "ArcDelayCalc.hh" #include "GraphDelayCalc.hh" +#include "sdf/SdfReader.hh" #include "sdf/SdfWriter.hh" #include "Levelize.hh" #include "Sim.hh" @@ -257,7 +258,6 @@ deleteAllMemory() deleteDelayCalcs(); PortDirection::destroy(); deleteLiberty(); - deleteTmpStrings(); } //////////////////////////////////////////////////////////////// @@ -581,7 +581,7 @@ Sta::cmdSdc() const } void -Sta::setCmdMode(const std::string &mode_name) +Sta::setCmdMode(std::string_view mode_name) { if (!mode_name.empty()) { if (!mode_name_map_.contains(mode_name)) { @@ -592,7 +592,7 @@ Sta::setCmdMode(const std::string &mode_name) modes_.clear(); } Mode *mode = new Mode(mode_name, mode_name_map_.size(), this); - mode_name_map_[mode_name] = mode; + mode_name_map_[std::string(mode_name)] = mode; modes_.push_back(mode); mode->sim()->setMode(mode); mode->sim()->setObserver(new StaSimObserver(this)); @@ -605,16 +605,16 @@ Sta::setCmdMode(const std::string &mode_name) } Mode * -Sta::findMode(const std::string &mode_name) const +Sta::findMode(std::string_view mode_name) const { - return findKey(mode_name_map_, mode_name); + return findStringKey(mode_name_map_, mode_name); } ModeSeq Sta::findModes(const std::string &name) const { ModeSeq matches; - PatternMatch pattern(name.c_str()); + PatternMatch pattern(name); for (Mode *mode : modes_) { if (pattern.match(mode->name())) matches.push_back(mode); @@ -692,7 +692,7 @@ Sta::setCurrentInstance(Instance *inst) //////////////////////////////////////////////////////////////// LibertyLibrary * -Sta::readLiberty(const char *filename, +Sta::readLiberty(std::string_view filename, Scene *scene, const MinMaxAll *min_max, bool infer_latches) @@ -712,7 +712,7 @@ Sta::readLiberty(const char *filename, } LibertyLibrary * -Sta::readLibertyFile(const char *filename, +Sta::readLibertyFile(std::string_view filename, Scene *scene, const MinMaxAll *min_max, bool infer_latches) @@ -732,13 +732,6 @@ Sta::readLibertyFile(const char *filename, return liberty; } -LibertyLibrary * -Sta::readLibertyFile(const char *filename, - bool infer_latches) -{ - return sta::readLibertyFile(filename, infer_latches, network_); -} - void Sta::readLibertyAfter(LibertyLibrary *liberty, Scene *scene, @@ -750,7 +743,7 @@ Sta::readLibertyAfter(LibertyLibrary *liberty, } bool -Sta::readVerilog(const char *filename) +Sta::readVerilog(std::string_view filename) { NetworkReader *network = networkReader(); if (network) { @@ -785,6 +778,24 @@ Sta::linkDesign(const char *top_cell_name, //////////////////////////////////////////////////////////////// +bool +Sta::readSdf(std::string_view filename, + std::string_view path, + Scene *scene, + bool unescaped_dividers, + bool incremental_only, + MinMaxAll *cond_use) +{ + ensureLibLinked(); + ensureGraph(); + bool success = sta::readSdf(filename, path, scene, unescaped_dividers, + incremental_only, cond_use, this); + search_->arrivalsInvalid(); + return success; +} + +//////////////////////////////////////////////////////////////// + void Sta::setDebugLevel(const char *what, int level) @@ -1145,12 +1156,12 @@ Sta::setMaxArea(float area, } void -Sta::makeClock(const char *name, +Sta::makeClock(std::string_view name, PinSet *pins, bool add_to_pins, float period, FloatSeq *waveform, - char *comment, + std::string_view comment, const Mode *mode) { mode->sdc()->makeClock(name, pins, add_to_pins, period, waveform, comment); @@ -1161,7 +1172,7 @@ Sta::makeClock(const char *name, } void -Sta::makeGeneratedClock(const char *name, +Sta::makeGeneratedClock(std::string_view name, PinSet *pins, bool add_to_pins, Pin *src_pin, @@ -1173,7 +1184,7 @@ Sta::makeGeneratedClock(const char *name, bool combinational, IntSeq *edges, FloatSeq *edge_shifts, - char *comment, + std::string_view comment, const Mode *mode) { mode->sdc()->makeGeneratedClock(name, pins, add_to_pins, src_pin, master_clk, @@ -1375,13 +1386,13 @@ Sta::makeClockGroups(const std::string &name, bool physically_exclusive, bool asynchronous, bool allow_paths, - const char *comment, + std::string comment, Sdc *sdc) { ClockGroups *groups = sdc->makeClockGroups(name, logically_exclusive, physically_exclusive, asynchronous, allow_paths, - comment); + std::move(comment)); search_->requiredsInvalid(); return groups; } @@ -1998,7 +2009,7 @@ Sta::makeFalsePath(ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, const MinMaxAll *min_max, - const char *comment, + std::string_view comment, Sdc *sdc) { sdc->makeFalsePath(from, thrus, to, min_max, comment); @@ -2012,7 +2023,7 @@ Sta::makeMulticyclePath(ExceptionFrom *from, const MinMaxAll *min_max, bool use_end_clk, int path_multiplier, - const char *comment, + std::string_view comment, Sdc *sdc) { sdc->makeMulticyclePath(from, thrus, to, min_max, use_end_clk, path_multiplier, @@ -2028,7 +2039,7 @@ Sta::makePathDelay(ExceptionFrom *from, bool ignore_clk_latency, bool break_path, float delay, - const char *comment, + std::string_view comment, Sdc *sdc) { sdc->makePathDelay(from, thrus, to, min_max, ignore_clk_latency, break_path, delay, @@ -2049,12 +2060,12 @@ Sta::resetPath(ExceptionFrom *from, } void -Sta::makeGroupPath(const std::string &name, +Sta::makeGroupPath(std::string_view name, bool is_default, ExceptionFrom *from, ExceptionThruSeq *thrus, ExceptionTo *to, - const char *comment, + std::string_view comment, Sdc *sdc) { sdc->makeGroupPath(name, is_default, from, thrus, to, comment); @@ -2062,21 +2073,21 @@ Sta::makeGroupPath(const std::string &name, } bool -Sta::isGroupPathName(const char *group_name, +Sta::isGroupPathName(std::string_view group_name, const Sdc *sdc) { return isPathGroupName(group_name, sdc); } bool -Sta::isPathGroupName(const char *group_name, +Sta::isPathGroupName(std::string_view group_name, const Sdc *sdc) const { return sdc->findClock(group_name) || sdc->isGroupPathName(group_name) - || stringEq(group_name, PathGroups::asyncPathGroupName()) - || stringEq(group_name, PathGroups::pathDelayGroupName()) - || stringEq(group_name, PathGroups::gatedClkGroupName()) - || stringEq(group_name, PathGroups::unconstrainedGroupName()); + || group_name == PathGroups::asyncPathGroupName() + || group_name == PathGroups::pathDelayGroupName() + || group_name == PathGroups::gatedClkGroupName() + || group_name == PathGroups::unconstrainedGroupName(); } StringSeq @@ -2089,10 +2100,10 @@ Sta::pathGroupNames(const Sdc *sdc) const for (auto const &[name, group] : sdc->groupPaths()) names.push_back(name); - names.push_back(PathGroups::asyncPathGroupName()); - names.push_back(PathGroups::pathDelayGroupName()); - names.push_back(PathGroups::gatedClkGroupName()); - names.push_back(PathGroups::unconstrainedGroupName()); + names.emplace_back(PathGroups::asyncPathGroupName()); + names.emplace_back(PathGroups::pathDelayGroupName()); + names.emplace_back(PathGroups::gatedClkGroupName()); + names.emplace_back(PathGroups::unconstrainedGroupName()); return names; } @@ -2108,7 +2119,7 @@ Sta::makeExceptionFrom(PinSet *from_pins, void Sta::checkExceptionFromPins(ExceptionFrom *from, - const char *file, + std::string_view filename, int line, const Sdc *sdc) const { @@ -2118,7 +2129,7 @@ Sta::checkExceptionFromPins(ExceptionFrom *from, for (const Pin *pin : *pins) { if (!sdc->isExceptionStartpoint(pin)) { if (line) - report_->fileWarn(1554, file, line, "'{}' is not a valid start point.", + report_->fileWarn(1554, filename, line, "'{}' is not a valid start point.", cmd_network_->pathName(pin)); else report_->warn(1550, "'{}' is not a valid start point.", @@ -2193,7 +2204,7 @@ Sta::checkExceptionToPins(ExceptionTo *to, void Sta::writeSdc(const Sdc *sdc, - const char *filename, + std::string_view filename, bool leaf, bool native, int digits, @@ -2593,7 +2604,7 @@ SceneSeq Sta::findScenes(const std::string &name) const { SceneSeq matches; - PatternMatch pattern(name.c_str()); + PatternMatch pattern(name); for (Scene *scene : scenes_) { if (pattern.match(scene->name())) matches.push_back(scene); @@ -2606,7 +2617,7 @@ Sta::findScenes(const std::string &name, ModeSeq &modes) const { SceneSeq matches; - PatternMatch pattern(name.c_str()); + PatternMatch pattern(name); for (Mode *mode : modes) { for (Scene *scene : mode->scenes()) { if (pattern.match(scene->name())) @@ -2626,9 +2637,9 @@ Sta::updateSceneLiberty(Scene *scene, const StringSeq &liberty_files = min_max == MinMax::min() ? liberty_min_files : liberty_max_files; for (const std::string &lib_file : liberty_files) { - LibertyLibrary *lib = network_->findLiberty(lib_file.c_str()); + LibertyLibrary *lib = network_->findLiberty(lib_file); if (lib == nullptr) - lib = network_->findLibertyFilename(lib_file.c_str()); + lib = network_->findLibertyFilename(lib_file); if (lib) LibertyLibrary::makeSceneMap(lib, scene->libertyIndex(min_max), network_, report_); @@ -2766,7 +2777,7 @@ Sta::setReportPathFields(bool report_input_pin, } ReportField * -Sta::findReportPathField(const char *name) +Sta::findReportPathField(std::string_view name) { return report_path_->findField(name); } @@ -3185,7 +3196,7 @@ Sta::slacks(Vertex *vertex, class EndpointPathEndVisitor : public PathEndVisitor { public: - EndpointPathEndVisitor(const std::string &path_group_name, + EndpointPathEndVisitor(std::string_view path_group_name, const MinMax *min_max, const StaState *sta); PathEndVisitor *copy() const; @@ -3193,13 +3204,13 @@ public: Slack slack() const { return slack_; } private: - const std::string &path_group_name_; + std::string_view path_group_name_; const MinMax *min_max_; Slack slack_; const StaState *sta_; }; -EndpointPathEndVisitor::EndpointPathEndVisitor(const std::string &path_group_name, +EndpointPathEndVisitor::EndpointPathEndVisitor(std::string_view path_group_name, const MinMax *min_max, const StaState *sta) : path_group_name_(path_group_name), @@ -3232,7 +3243,7 @@ EndpointPathEndVisitor::visit(PathEnd *path_end) Slack Sta::endpointSlack(const Pin *pin, - const std::string &path_group_name, + std::string_view path_group_name, const MinMax *min_max) { ensureGraph(); @@ -3348,13 +3359,13 @@ Sta::reportDelaysWrtClks(Vertex *vertex, clk_name = sta::format("({})", clk_edge->name()); report_->report("{} r {}:{} f {}:{}", clk_name, formatDelay(RiseFall::rise(), MinMax::min(), - delays, report_variance, digits).c_str(), + delays, report_variance, digits), formatDelay(RiseFall::rise(), MinMax::max(), - delays, report_variance, digits).c_str(), + delays, report_variance, digits), formatDelay(RiseFall::fall(), MinMax::min(), - delays, report_variance, digits).c_str(), + delays, report_variance, digits), formatDelay(RiseFall::fall(), MinMax::max(), - delays, report_variance, digits).c_str()); + delays, report_variance, digits)); } } @@ -3557,10 +3568,10 @@ Sta::reportDelayCalc(Edge *edge, } void -Sta::setArcDelayCalc(const char *delay_calc_name) +Sta::setArcDelayCalc(std::string_view delay_calc_name) { delete arc_delay_calc_; - arc_delay_calc_ = makeDelayCalc(delay_calc_name, sta_); + arc_delay_calc_ = makeDelayCalc(std::string(delay_calc_name), sta_); // Update pointers to arc_delay_calc. updateComponentsState(); delaysInvalid(); @@ -3847,7 +3858,7 @@ Sta::setAnnotatedSlew(Vertex *vertex, } void -Sta::writeSdf(const char *filename, +Sta::writeSdf(std::string_view filename, const Scene *scene, char divider, bool include_typ, @@ -4087,8 +4098,8 @@ Sta::setResistance(const Net *net, //////////////////////////////////////////////////////////////// bool -Sta::readSpef(const std::string &name, - const std::string &filename, +Sta::readSpef(std::string_view name, + std::string_view filename, Instance *instance, Scene *scene, // -scene deprecated 11/20/2025 const MinMaxAll *min_max, @@ -4109,7 +4120,7 @@ Sta::readSpef(const std::string &name, spef_name += "_"; spef_name += min_max->to_string(); } - parasitics = makeConcreteParasitics(spef_name, filename); + parasitics = makeConcreteParasitics(spef_name, std::string(filename)); } else parasitics = findParasitics(spef_name); @@ -4122,14 +4133,14 @@ Sta::readSpef(const std::string &name, } } else { - parasitics = findParasitics(name); + parasitics = findParasitics(std::string(name)); if (parasitics == nullptr) - parasitics = makeConcreteParasitics(name, filename); + parasitics = makeConcreteParasitics(std::string(name), std::string(filename)); } - bool success = - readSpefFile(filename.c_str(), instance, pin_cap_included, keep_coupling_caps, - coupling_cap_factor, reduce, scene, min_max, parasitics, this); + bool success = readSpefFile(filename, instance, pin_cap_included, + keep_coupling_caps, coupling_cap_factor, reduce, + scene, min_max, parasitics, this); delaysInvalid(); return success; } @@ -5875,16 +5886,16 @@ Sta::equivCells(LibertyCell *cell) //////////////////////////////////////////////////////////////// void -Sta::writeTimingModel(const char *lib_name, - const char *cell_name, - const char *filename, +Sta::writeTimingModel(std::string_view lib_name, + std::string_view cell_name, + std::string_view filename, const Scene *scene) { ensureLibLinked(); ensureGraph(); - LibertyLibrary *library = - makeTimingModel(lib_name, cell_name, filename, scene, this); - writeLiberty(library, filename, this); + LibertyLibrary *library = makeTimingModel(lib_name, cell_name, + filename, scene, this); + writeLiberty(library, std::string(filename).c_str(), this); } //////////////////////////////////////////////////////////////// @@ -5981,12 +5992,12 @@ Sta::activity(const Pin *pin, void Sta::writePathSpice(const Path *path, - const char *spice_filename, - const char *subckt_filename, - const char *lib_subckt_filename, - const char *model_filename, - const char *power_name, - const char *gnd_name, + std::string_view spice_filename, + std::string_view subckt_filename, + std::string_view lib_subckt_filename, + std::string_view model_filename, + std::string_view power_name, + std::string_view gnd_name, CircuitSim ckt_sim) { ensureLibLinked(); diff --git a/spice/WritePathSpice.cc b/spice/WritePathSpice.cc index e5c019bd..9b3ecb00 100644 --- a/spice/WritePathSpice.cc +++ b/spice/WritePathSpice.cc @@ -26,6 +26,7 @@ #include #include +#include #include "Debug.hh" #include "Error.hh" @@ -59,12 +60,12 @@ class WritePathSpice : public WriteSpice { public: WritePathSpice(const Path *path, - const char *spice_filename, - const char *subckt_filename, - const char *lib_subckt_filename, - const char *model_filename, - const char *power_name, - const char *gnd_name, + std::string_view spice_filename, + std::string_view subckt_filename, + std::string_view lib_subckt_filename, + std::string_view model_filename, + std::string_view power_name, + std::string_view gnd_name, CircuitSim ckt_sim, const StaState *sta); void writeSpice(); @@ -124,9 +125,9 @@ private: const LibertyPort *stageGateInputPort(Stage stage); const LibertyPort *stageDrvrPort(Stage stage); const Pin *stageLoadPin(Stage stage); - const char *stageGateInputPinName(Stage stage); - const char *stageDrvrPinName(Stage stage); - const char *stageLoadPinName(Stage stage); + std::string stageGateInputPinName(Stage stage); + std::string stageDrvrPinName(Stage stage); + std::string stageLoadPinName(Stage stage); const LibertyCell *stageLibertyCell(Stage stage); const Instance *stageInstance(Stage stage); @@ -154,12 +155,12 @@ private: void writePathSpice(const Path *path, - const char *spice_filename, - const char *subckt_filename, - const char *lib_subckt_filename, - const char *model_filename, - const char *power_name, - const char *gnd_name, + std::string_view spice_filename, + std::string_view subckt_filename, + std::string_view lib_subckt_filename, + std::string_view model_filename, + std::string_view power_name, + std::string_view gnd_name, CircuitSim ckt_sim, StaState *sta) { @@ -170,12 +171,12 @@ writePathSpice(const Path *path, } WritePathSpice::WritePathSpice(const Path *path, - const char *spice_filename, - const char *subckt_filename, - const char *lib_subckt_filename, - const char *model_filename, - const char *power_name, - const char *gnd_name, + std::string_view spice_filename, + std::string_view subckt_filename, + std::string_view lib_subckt_filename, + std::string_view model_filename, + std::string_view power_name, + std::string_view gnd_name, CircuitSim ckt_sim, const StaState *sta) : WriteSpice(spice_filename, subckt_filename, lib_subckt_filename, @@ -192,7 +193,7 @@ WritePathSpice::WritePathSpice(const Path *path, void WritePathSpice::writeSpice() { - spice_stream_.open(spice_filename_); + spice_stream_.open(std::string(spice_filename_)); if (spice_stream_.is_open()) { path_expanded_.expand(path_, true); // Find subckt port names as a side-effect of writeSubckts. @@ -288,20 +289,19 @@ WritePathSpice::writeStageInstances() for (Stage stage = stageFirst(); stage <= stageLast(); stage++) { std::string stage_name = stageName(stage); - const char *stage_cname = stage_name.c_str(); if (stage == stageFirst()) sta::print(spice_stream_, "x{} {} {} {}\n", - stage_cname, + stage_name, stageDrvrPinName(stage), stageLoadPinName(stage), - stage_cname); + stage_name); else { sta::print(spice_stream_, "x{} {} {} {} {}\n", - stage_cname, + stage_name, stageGateInputPinName(stage), stageDrvrPinName(stage), stageLoadPinName(stage), - stage_cname); + stage_name); } } sta::print(spice_stream_, "\n"); @@ -474,8 +474,8 @@ WritePathSpice::writeInputStage(Stage stage) { // Input arc. // External driver not handled. - const char *drvr_pin_name = stageDrvrPinName(stage); - const char *load_pin_name = stageLoadPinName(stage); + std::string drvr_pin_name = stageDrvrPinName(stage); + std::string load_pin_name = stageLoadPinName(stage); std::string prefix = stageName(stage); sta::print(spice_stream_, ".subckt {} {} {}\n", prefix, @@ -490,11 +490,11 @@ void WritePathSpice::writeGateStage(Stage stage) { const Pin *input_pin = stageGateInputPin(stage); - const char *input_pin_name = stageGateInputPinName(stage); + std::string input_pin_name = stageGateInputPinName(stage); const Pin *drvr_pin = stageDrvrPin(stage); - const char *drvr_pin_name = stageDrvrPinName(stage); + std::string drvr_pin_name = stageDrvrPinName(stage); const Pin *load_pin = stageLoadPin(stage); - const char *load_pin_name = stageLoadPinName(stage); + std::string load_pin_name = stageLoadPinName(stage); std::string subckt_name = "stage" + std::to_string(stage); const Instance *inst = stageInstance(stage); @@ -721,21 +721,21 @@ WritePathSpice::stageLoadPin(Stage stage) return path->pin(this); } -const char * +std::string WritePathSpice::stageGateInputPinName(Stage stage) { const Pin *pin = stageGateInputPin(stage); return network_->pathName(pin); } -const char * +std::string WritePathSpice::stageDrvrPinName(Stage stage) { const Pin *pin = stageDrvrPin(stage); return network_->pathName(pin); } -const char * +std::string WritePathSpice::stageLoadPinName(Stage stage) { const Pin *pin = stageLoadPin(stage); diff --git a/spice/WritePathSpice.hh b/spice/WritePathSpice.hh index 027cc04d..aa22e4fc 100644 --- a/spice/WritePathSpice.hh +++ b/spice/WritePathSpice.hh @@ -24,6 +24,8 @@ #pragma once +#include + #include "CircuitSim.hh" namespace sta { @@ -36,15 +38,15 @@ class StaState; void writePathSpice(const Path *path, // Spice file written for path. - const char *spice_filename, + std::string_view spice_filename, // Subckts used by path included in spice file. - const char *subckt_filename, + std::string_view subckt_filename, // File of all cell spice subckt definitions. - const char *lib_subckt_filename, + std::string_view lib_subckt_filename, // Device model file included in spice file. - const char *model_filename, - const char *power_name, - const char *gnd_name, + std::string_view model_filename, + std::string_view power_name, + std::string_view gnd_name, CircuitSim ckt_sim, StaState *sta); diff --git a/spice/WriteSpice.cc b/spice/WriteSpice.cc index 6a62785c..1823080c 100644 --- a/spice/WriteSpice.cc +++ b/spice/WriteSpice.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include "cudd.h" @@ -56,41 +57,12 @@ Net * pinNet(const Pin *pin, const Network *network); -class SubcktEndsMissing : public Exception -{ -public: - SubcktEndsMissing(const char *cell_name, - const char *subckt_filename); - const char *what() const noexcept; - -protected: - std::string what_; -}; - -SubcktEndsMissing::SubcktEndsMissing(const char *cell_name, - const char *subckt_filename) : - Exception() -{ - what_ = "spice subckt for cell "; - what_ += cell_name; - what_ += " missing .ends in "; - what_ += subckt_filename; -} - -const char * -SubcktEndsMissing::what() const noexcept -{ - return what_.c_str(); -} - -//////////////////////////////////////////////////////////////// - -WriteSpice::WriteSpice(const char *spice_filename, - const char *subckt_filename, - const char *lib_subckt_filename, - const char *model_filename, - const char *power_name, - const char *gnd_name, +WriteSpice::WriteSpice(std::string_view spice_filename, + std::string_view subckt_filename, + std::string_view lib_subckt_filename, + std::string_view model_filename, + std::string_view power_name, + std::string_view gnd_name, CircuitSim ckt_sim, const Scene *scene, const MinMax *min_max, @@ -165,11 +137,11 @@ WriteSpice::writePrintStmt(StringSeq &node_names) } std::string -WriteSpice::replaceFileExt(std::string filename, - const char *ext) +WriteSpice::replaceFileExt(std::string_view filename, + std::string_view ext) { size_t dot = filename.rfind('.'); - std::string ext_filename = filename.substr(0, dot + 1); + std::string ext_filename(filename.substr(0, dot + 1)); ext_filename += ext; return ext_filename; } @@ -201,29 +173,33 @@ void WriteSpice::writeSubckts(StringSet &cell_names) { findCellSubckts(cell_names); - std::ifstream lib_subckts_stream(lib_subckt_filename_); + std::ifstream lib_subckts_stream{std::string(lib_subckt_filename_)}; if (lib_subckts_stream.is_open()) { - std::ofstream subckts_stream(subckt_filename_); + std::ofstream subckts_stream{std::string(subckt_filename_)}; if (subckts_stream.is_open()) { std::string line; + int line_num = 0; while (std::getline(lib_subckts_stream, line)) { + line_num++; // .subckt [args..] - StringSeq tokens = parseTokens(line, ' '); - if (tokens.size() >= 2 && stringEqual(tokens[0].c_str(), ".subckt")) { - const char *cell_name = tokens[1].c_str(); + StringSeq tokens = parseTokens(line); + if (tokens.size() >= 2 && stringEqual(tokens[0], ".subckt")) { + const std::string &cell_name = tokens[1]; if (cell_names.contains(cell_name)) { subckts_stream << line << "\n"; bool found_ends = false; while (std::getline(lib_subckts_stream, line)) { subckts_stream << line << "\n"; - if (stringBeginEqual(line.c_str(), ".ends")) { + if (stringBeginEqual(line, ".ends")) { subckts_stream << "\n"; found_ends = true; break; } } if (!found_ends) - throw SubcktEndsMissing(cell_name, lib_subckt_filename_); + report_->fileError(1606, lib_subckt_filename_, line_num, + "spice subckt for cell {} missing .ends.", + cell_name); cell_names.erase(cell_name); } recordSpicePortNames(cell_name, tokens); @@ -252,19 +228,18 @@ WriteSpice::writeSubckts(StringSet &cell_names) } void -WriteSpice::recordSpicePortNames(const char *cell_name, +WriteSpice::recordSpicePortNames(std::string_view cell_name, StringSeq &tokens) { LibertyCell *cell = network_->findLibertyCell(cell_name); if (cell) { - StringSeq &spice_port_names = cell_spice_port_names_[cell_name]; + StringSeq &spice_port_names = cell_spice_port_names_[std::string(cell_name)]; for (size_t i = 2; i < tokens.size(); i++) { - const char *port_name = tokens[i].c_str(); + const std::string &port_name = tokens[i]; LibertyPort *port = cell->findLibertyPort(port_name); - LibertyPort *pg_port = cell->findLibertyPort(port_name); - if (port == nullptr && pg_port == nullptr - && !stringEqual(port_name, power_name_) - && !stringEqual(port_name, gnd_name_)) + if (port == nullptr + && port_name != power_name_ + && port_name != gnd_name_) report_->error(1606, "subckt {} port {} has no corresponding liberty port, " "pg_port and is not power or ground.", @@ -278,14 +253,14 @@ WriteSpice::recordSpicePortNames(const char *cell_name, void WriteSpice::findCellSubckts(StringSet &cell_names) { - std::ifstream lib_subckts_stream(lib_subckt_filename_); + std::ifstream lib_subckts_stream{std::string(lib_subckt_filename_)}; if (lib_subckts_stream.is_open()) { std::string line; while (std::getline(lib_subckts_stream, line)) { // .subckt [args..] - StringSeq tokens = parseTokens(line, ' '); - if (tokens.size() >= 2 && stringEqual(tokens[0].c_str(), ".subckt")) { - const char *cell_name = tokens[1].c_str(); + StringSeq tokens = parseTokens(line); + if (tokens.size() >= 2 && stringEqual(tokens[0], ".subckt")) { + const std::string &cell_name = tokens[1]; if (cell_names.contains(cell_name)) { // Scan the subckt definition for subckt calls. std::string stmt; @@ -295,13 +270,13 @@ WriteSpice::findCellSubckts(StringSet &cell_names) else { // Process previous statement. if (tolower(stmt[0]) == 'x') { - StringSeq tokens = parseTokens(line, ' '); + StringSeq tokens = parseTokens(line); std::string &subckt_cell = tokens[tokens.size() - 1]; cell_names.insert(subckt_cell); } stmt = line; } - if (stringBeginEqual(line.c_str(), ".ends")) + if (stringBeginEqual(line, ".ends")) break; } } @@ -317,25 +292,21 @@ WriteSpice::findCellSubckts(StringSet &cell_names) void WriteSpice::writeSubcktInst(const Instance *inst) { - const char *inst_name = network_->pathName(inst); + std::string inst_name = network_->pathName(inst); LibertyCell *cell = network_->libertyCell(inst); - const char *cell_name = cell->name(); + const std::string &cell_name = cell->name(); StringSeq &spice_port_names = cell_spice_port_names_[cell_name]; sta::print(spice_stream_, "x{}", inst_name); - for (std::string subckt_port_name : spice_port_names) { - const char *subckt_port_cname = subckt_port_name.c_str(); - Pin *pin = network_->findPin(inst, subckt_port_cname); - LibertyPort *pg_port = cell->findLibertyPort(subckt_port_cname); - const char *pin_name; - if (pin) { - pin_name = network_->pathName(pin); - sta::print(spice_stream_, " {}", pin_name); - } + for (std::string &subckt_port_name : spice_port_names) { + Pin *pin = network_->findPin(inst, subckt_port_name); + LibertyPort *pg_port = cell->findLibertyPort(subckt_port_name); + if (pin) + sta::print(spice_stream_, " {}", network_->pathName(pin)); else if (pg_port) - sta::print(spice_stream_, " {}/{}", inst_name, subckt_port_cname); - else if (stringEq(subckt_port_cname, power_name_) - || stringEq(subckt_port_cname, gnd_name_)) - sta::print(spice_stream_, " {}/{}", inst_name, subckt_port_cname); + sta::print(spice_stream_, " {}/{}", inst_name, subckt_port_name); + else if (subckt_port_name == power_name_ + || subckt_port_name == gnd_name_) + sta::print(spice_stream_, " {}/{}", inst_name, subckt_port_name); } sta::print(spice_stream_, " {}\n", cell_name); } @@ -347,23 +318,23 @@ WriteSpice::writeSubcktInstVoltSrcs(const Instance *inst, const PinSet &excluded_input_pins) { LibertyCell *cell = network_->libertyCell(inst); - const char *cell_name = cell->name(); + const std::string &cell_name = cell->name(); StringSeq &spice_port_names = cell_spice_port_names_[cell_name]; - const char *inst_name = network_->pathName(inst); + std::string inst_name = network_->pathName(inst); debugPrint(debug_, "write_spice", 2, "subckt {}", cell->name()); - for (std::string subckt_port_sname : spice_port_names) { - const char *subckt_port_name = subckt_port_sname.c_str(); + for (std::string &subckt_port_name : spice_port_names) { LibertyPort *port = cell->findLibertyPort(subckt_port_name); const Pin *pin = port ? network_->findPin(inst, port) : nullptr; bool is_pg_port = port && port->isPwrGnd(); - debugPrint(debug_, "write_spice", 2, " port {}{}", subckt_port_name, + debugPrint(debug_, "write_spice", 2, " port {}{}", + subckt_port_name, is_pg_port ? " pwr/gnd" : ""); if (is_pg_port) writeVoltageSource(inst_name, subckt_port_name, pgPortVoltage(port)); - else if (stringEq(subckt_port_name, power_name_)) + else if (subckt_port_name == power_name_) writeVoltageSource(inst_name, subckt_port_name, power_voltage_); - else if (stringEq(subckt_port_name, gnd_name_)) + else if (subckt_port_name == gnd_name_) writeVoltageSource(inst_name, subckt_port_name, gnd_voltage_); else if (port && !excluded_input_pins.contains(pin) && port->direction()->isAnyInput()) { @@ -380,12 +351,12 @@ WriteSpice::writeSubcktInstVoltSrcs(const Instance *inst, switch (port_value) { case LogicValue::zero: case LogicValue::unknown: - writeVoltageSource(cell, inst_name, subckt_port_name, - port->relatedGroundPin(), gnd_voltage_); + writeVoltageSource(inst_name, subckt_port_name, + port->relatedGroundPort(), gnd_voltage_); break; case LogicValue::one: - writeVoltageSource(cell, inst_name, subckt_port_name, - port->relatedPowerPin(), power_voltage_); + writeVoltageSource(inst_name, subckt_port_name, + port->relatedPowerPort(), power_voltage_); break; case LogicValue::rise: case LogicValue::fall: @@ -396,24 +367,35 @@ WriteSpice::writeSubcktInstVoltSrcs(const Instance *inst, } void -WriteSpice::writeVoltageSource(const char *inst_name, - const char *port_name, +WriteSpice::writeVoltageSource(std::string_view inst_name, + std::string_view port_name, float voltage) { - std::string node_name = inst_name; + std::string node_name(inst_name); node_name += '/'; node_name += port_name; - writeVoltageSource(node_name.c_str(), voltage); + writeVoltageSource(node_name, voltage); +} + +void +WriteSpice::writeVoltageSource(std::string_view inst_name, + std::string_view subckt_port_name, + const LibertyPort *pg_port, + float voltage) +{ + if (pg_port) + voltage = pgPortVoltage(pg_port); + writeVoltageSource(inst_name, subckt_port_name, voltage); } void WriteSpice::writeVoltageSource(LibertyCell *cell, - const char *inst_name, - const char *subckt_port_name, - const char *pg_port_name, + std::string_view inst_name, + std::string_view subckt_port_name, + const std::string &pg_port_name, float voltage) { - if (pg_port_name) { + if (!pg_port_name.empty()) { LibertyPort *pg_port = cell->findLibertyPort(pg_port_name); if (pg_port) voltage = pgPortVoltage(pg_port); @@ -424,18 +406,18 @@ WriteSpice::writeVoltageSource(LibertyCell *cell, } float -WriteSpice::pgPortVoltage(LibertyPort *pg_port) +WriteSpice::pgPortVoltage(const LibertyPort *pg_port) { LibertyLibrary *liberty = pg_port->libertyCell()->libertyLibrary(); float voltage = 0.0; bool exists; - const char *voltage_name = pg_port->voltageName(); - if (voltage_name) { + const std::string &voltage_name = pg_port->voltageName(); + if (!voltage_name.empty()) { liberty->supplyVoltage(voltage_name, voltage, exists); if (!exists) { - if (stringEqual(voltage_name, power_name_)) + if (voltage_name == power_name_) voltage = power_voltage_; - else if (stringEqual(voltage_name, gnd_name_)) + else if (voltage_name == gnd_name_) voltage = gnd_voltage_; else report_->error(1601, "pg_pin {}/{} voltage {} not found,", @@ -501,8 +483,9 @@ WriteSpice::writeDrvrParasitics(const Pin *drvr_pin, const NetSet &coupling_nets) { Net *net = network_->net(drvr_pin); - const char *net_name = - net ? network_->pathName(net) : network_->pathName(drvr_pin); + std::string net_name = net + ? std::string(network_->pathName(net)) + : std::string(network_->pathName(drvr_pin)); sta::print(spice_stream_, "* Net {}\n", net_name); if (parasitics_->isParasiticNetwork(parasitic)) @@ -559,9 +542,9 @@ WriteSpice::writeParasiticNetwork(const Pin *drvr_pin, // Sort nodes for consistent regression results. ParasiticNodeSeq nodes = parasitics_->nodes(parasitic); sort(nodes, [this](const ParasiticNode *node1, const ParasiticNode *node2) { - const char *name1 = parasitics_->name(node1); - const char *name2 = parasitics_->name(node2); - return stringLess(name1, name2); + std::string name1 = parasitics_->name(node1); + std::string name2 = parasitics_->name(node2); + return name1 < name2; }); for (ParasiticNode *node : nodes) { @@ -677,7 +660,7 @@ WriteSpice::writeNullParasitic(const Pin *drvr_pin) //////////////////////////////////////////////////////////////// void -WriteSpice::writeVoltageSource(const char *node_name, +WriteSpice::writeVoltageSource(std::string_view node_name, float voltage) { sta::print(spice_stream_, "v{} {} 0 {:.3f}\n", volt_index_++, node_name, voltage); @@ -976,11 +959,11 @@ WriteSpice::writeMeasureDelayStmt(const Pin *from_pin, const RiseFall *from_rf, const Pin *to_pin, const RiseFall *to_rf, - std::string prefix) + std::string_view prefix) { - const char *from_pin_name = network_->pathName(from_pin); + std::string from_pin_name = network_->pathName(from_pin); float from_threshold = power_voltage_ * default_library_->inputThreshold(from_rf); - const char *to_pin_name = network_->pathName(to_pin); + std::string to_pin_name = network_->pathName(to_pin); float to_threshold = power_voltage_ * default_library_->inputThreshold(to_rf); sta::print(spice_stream_, ".measure tran {}_{}_delay_{}\n", prefix, from_pin_name, to_pin_name); @@ -993,10 +976,10 @@ WriteSpice::writeMeasureDelayStmt(const Pin *from_pin, void WriteSpice::writeMeasureSlewStmt(const Pin *pin, const RiseFall *rf, - std::string prefix) + std::string_view prefix) { - const char *pin_name = network_->pathName(pin); - const char *spice_rf = spiceTrans(rf); + std::string pin_name = network_->pathName(pin); + std::string_view spice_rf = spiceTrans(rf); float lower = power_voltage_ * default_library_->slewLowerThreshold(rf); float upper = power_voltage_ * default_library_->slewUpperThreshold(rf); float threshold1, threshold2; @@ -1017,7 +1000,7 @@ WriteSpice::writeMeasureSlewStmt(const Pin *pin, //////////////////////////////////////////////////////////////// -const char * +std::string_view WriteSpice::spiceTrans(const RiseFall *rf) { if (rf == RiseFall::rise()) diff --git a/spice/WriteSpice.hh b/spice/WriteSpice.hh index 74fecf00..2ac35b33 100644 --- a/spice/WriteSpice.hh +++ b/spice/WriteSpice.hh @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -41,19 +42,19 @@ namespace sta { using ParasiticNodeMap = std::map; -using CellSpicePortNames = std::map; +using CellSpicePortNames = std::map>; using LibertyPortLogicValues = std::map; // Utilities for writing a spice deck. class WriteSpice : public StaState { public: - WriteSpice(const char *spice_filename, - const char *subckt_filename, - const char *lib_subckt_filename, - const char *model_filename, - const char *power_name, - const char *gnd_name, + WriteSpice(std::string_view spice_filename, + std::string_view subckt_filename, + std::string_view lib_subckt_filename, + std::string_view model_filename, + std::string_view power_name, + std::string_view gnd_name, CircuitSim ckt_sim, const Scene *scene, const MinMax *min_max, @@ -68,20 +69,24 @@ protected: void writeGnuplotFile(StringSeq &node_nanes); void writeSubckts(StringSet &cell_names); void findCellSubckts(StringSet &cell_names); - void recordSpicePortNames(const char *cell_name, + void recordSpicePortNames(std::string_view cell_name, StringSeq &tokens); void writeSubcktInst(const Instance *inst); void writeSubcktInstVoltSrcs(const Instance *inst, LibertyPortLogicValues &port_values, const PinSet &excluded_input_pins); - float pgPortVoltage(LibertyPort *pg_port); - void writeVoltageSource(const char *inst_name, - const char *port_name, + float pgPortVoltage(const LibertyPort *pg_port); + void writeVoltageSource(std::string_view inst_name, + std::string_view port_name, + float voltage); + void writeVoltageSource(std::string_view inst_name, + std::string_view subckt_port_name, + const LibertyPort *pg_port, float voltage); void writeVoltageSource(LibertyCell *cell, - const char *inst_name, - const char *subckt_port_name, - const char *pg_port_name, + std::string_view inst_name, + std::string_view subckt_port_name, + const std::string &pg_port_name, float voltage); void writeClkedStepSource(const Pin *pin, const RiseFall *rf, @@ -96,7 +101,7 @@ protected: const Parasitic *parasitic); void writeNullParasitic(const Pin *drvr_pin); - void writeVoltageSource(const char *node_name, + void writeVoltageSource(std::string_view node_name, float voltage); void writeRampVoltSource(const Pin *pin, const RiseFall *rf, @@ -121,11 +126,11 @@ protected: const RiseFall *from_rf, const Pin *to_pin, const RiseFall *to_rf, - std::string prefix); + std::string_view prefix); void writeMeasureSlewStmt(const Pin *pin, const RiseFall *rf, - std::string prefix); - const char *spiceTrans(const RiseFall *rf); + std::string_view prefix); + std::string_view spiceTrans(const RiseFall *rf); float findSlew(Vertex *vertex, const RiseFall *rf, const TimingArc *next_arc); @@ -157,15 +162,15 @@ protected: InstanceSet &written_insts); PinSeq drvrLoads(const Pin *drvr_pin); void writeSubcktInstVoltSrcs(); - std::string replaceFileExt(std::string filename, - const char *ext); + std::string replaceFileExt(std::string_view filename, + std::string_view ext); - const char *spice_filename_; - const char *subckt_filename_; - const char *lib_subckt_filename_; - const char *model_filename_; - const char *power_name_; - const char *gnd_name_; + const std::string_view spice_filename_; + const std::string_view subckt_filename_; + const std::string_view lib_subckt_filename_; + const std::string_view model_filename_; + const std::string_view power_name_; + const std::string_view gnd_name_; CircuitSim ckt_sim_; const Scene *scene_; const MinMax *min_max_; diff --git a/spice/Xyce.cc b/spice/Xyce.cc index ff3e4b59..35bf668a 100644 --- a/spice/Xyce.cc +++ b/spice/Xyce.cc @@ -31,6 +31,7 @@ #include #include "Error.hh" +#include "StringUtil.hh" namespace sta { @@ -61,7 +62,7 @@ readXyceCsv(const char *csv_filename, std::stringstream ss(line); size_t col = 0; while (std::getline(ss, field, ',')) { - float value = std::stof(field); + auto [value, valid] = stringFloat(field); values[col].push_back(value); col++; } diff --git a/tcl/StaTclTypes.i b/tcl/StaTclTypes.i index b01986a2..5f2430e1 100644 --- a/tcl/StaTclTypes.i +++ b/tcl/StaTclTypes.i @@ -271,48 +271,24 @@ using namespace sta; // //////////////////////////////////////////////////////////////// -// String that is deleted after crossing over to tcland. -%typemap(out) std::string { - std::string &str = $1; +// SWIG before 4.2.0 has no std::string_view typemaps; newer SWIG defines +// them and duplicates here conflict. +#if SWIG_VERSION < 0x040200 +%typemap(out) std::string_view { + std::string str($1); // String is volatile because it is deleted. Tcl_SetResult(interp, const_cast(str.c_str()), TCL_VOLATILE); } -// String that is deleted after crossing over to tcland. -%typemap(out) TmpString* { - string *str = $1; - if (str) { - // String is volatile because it is deleted. - Tcl_SetResult(interp, const_cast(str->c_str()), TCL_VOLATILE); - delete str; - } - else - Tcl_SetResult(interp, nullptr, TCL_STATIC); -} - -%typemap(in) StringSet* { - $1 = tclListSetStdString($input, interp); +%typemap(in) std::string_view { + int length; + const char *str = Tcl_GetStringFromObj($input, &length); + $1 = std::string_view(str, length); } +#endif %typemap(in) StringSeq { - $1 = tclListSeqStdString($input, interp); -} - -%typemap(in) const StringSeq & (StringSeq seq) { - seq = tclListSeqStdString($input, interp); - $1 = &seq; -} - -%typemap(in) StringSeq* { - $1 = tclListSeqStdStringPtr($input, interp); -} - -%typemap(in) StringSet* { - $1 = tclListSetStdString($input, interp); -} - -%typemap(in) StringSeq { - $1 = tclListSeqStdString($input, interp); + $1 = tclListStringSeq($input, interp); } %typemap(out) StringSeq { @@ -442,7 +418,7 @@ using namespace sta; %typemap(in) Transition* { int length; const char *arg = Tcl_GetStringFromObj($input, &length); - Transition *tr = Transition::find(arg); + Transition *tr = Transition::find(std::string_view(arg, length)); if (tr == nullptr) { tclArgError(interp, 2150, "Unknown transition '{}'.", arg); return TCL_ERROR; @@ -453,16 +429,14 @@ using namespace sta; %typemap(out) Transition* { Transition *tr = $1; - const char *str = ""; - if (tr) - str = tr->to_string().c_str(); - Tcl_SetResult(interp, const_cast(str), TCL_STATIC); + const std::string &name = tr->to_string(); + Tcl_SetResult(interp, const_cast(name.c_str()), TCL_STATIC); } %typemap(in) RiseFall* { int length; const char *arg = Tcl_GetStringFromObj($input, &length); - const RiseFall *rf = RiseFall::find(arg); + const RiseFall *rf = RiseFall::find(std::string_view(arg, length)); if (rf == nullptr) { tclArgError(interp, 2151, "Unknown rise/fall edge '{}'.", arg); return TCL_ERROR; @@ -473,16 +447,14 @@ using namespace sta; %typemap(out) RiseFall* { const RiseFall *rf = $1; - const char *str = ""; - if (rf) - str = rf->shortName(); - Tcl_SetResult(interp, const_cast(str), TCL_STATIC); + const std::string &name = rf->shortName(); + Tcl_SetResult(interp, const_cast(name.c_str()), TCL_STATIC); } %typemap(in) RiseFallBoth* { int length; const char *arg = Tcl_GetStringFromObj($input, &length); - const RiseFallBoth *rf = RiseFallBoth::find(arg); + const RiseFallBoth *rf = RiseFallBoth::find(std::string_view(arg, length)); if (rf == nullptr) { tclArgError(interp, 2152, "Unknown transition name '{}'.", arg); return TCL_ERROR; @@ -492,11 +464,9 @@ using namespace sta; } %typemap(out) RiseFallBoth* { - RiseFallBoth *tr = $1; - const char *str = ""; - if (tr) - str = tr->shortName(); - Tcl_SetResult(interp, const_cast(str), TCL_STATIC); + RiseFallBoth *rf = $1; + const std::string &name = tr->shortName(); + Tcl_SetResult(interp, const_cast(name.c_str()), TCL_STATIC); } %typemap(in) PortDirection* { @@ -530,19 +500,19 @@ using namespace sta; %typemap(in) LogicValue { int length; - const char *arg = Tcl_GetStringFromObj($input, &length); - if (stringEq(arg, "0") || stringEq(arg, "zero")) + std::string arg = Tcl_GetStringFromObj($input, &length); + if (arg == "0" || stringEqual(arg, "zero")) $1 = LogicValue::zero; - else if (stringEq(arg, "1") || stringEq(arg, "one")) + else if (arg == "1" || stringEqual(arg, "one")) $1 = LogicValue::one; - else if (stringEq(arg, "X")) + else if (stringEqual(arg, "X")) $1 = LogicValue::unknown; - else if (stringEq(arg, "rise") || stringEq(arg, "rising")) + else if (stringEqual(arg, "rise") || stringEqual(arg, "rising")) $1 = LogicValue::rise; - else if (stringEq(arg, "fall") || stringEq(arg, "falling")) + else if (stringEqual(arg, "fall") || stringEqual(arg, "falling")) $1 = LogicValue::fall; else { - tclArgError(interp, 2155, "Unknown logic value '{}'.", arg); + tclArgError(interp, 2155, "Unknown logic value '{}'.", arg.c_str()); return TCL_ERROR; } } @@ -554,10 +524,10 @@ using namespace sta; $1 = AnalysisType::single; else if (stringEqual(arg, "bc_wc")) $1 = AnalysisType::bc_wc; - else if (stringEq(arg, "on_chip_variation")) + else if (stringEqual(arg, "on_chip_variation")) $1 = AnalysisType::ocv; else { - tclArgError(interp, 2156, "Unknown analysis type '{}'.", arg); + tclArgError(interp, 2156, "Unknown analysis type '{}'.", arg.c_str()); return TCL_ERROR; } } @@ -985,11 +955,11 @@ using namespace sta; %typemap(in) TimingDerateType { int length; char *arg = Tcl_GetStringFromObj($input, &length); - if (stringEq(arg, "net_delay")) + if (stringEqual(arg, "net_delay")) $1 = TimingDerateType::net_delay; - else if (stringEq(arg, "cell_delay")) + else if (stringEqual(arg, "cell_delay")) $1 = TimingDerateType::cell_delay; - else if (stringEq(arg, "cell_check")) + else if (stringEqual(arg, "cell_check")) $1 = TimingDerateType::cell_check; else { tclArgError(interp, 2166, "{} not net_delay, cell_delay or cell_check.", arg); @@ -1000,9 +970,9 @@ using namespace sta; %typemap(in) TimingDerateCellType { int length; char *arg = Tcl_GetStringFromObj($input, &length); - if (stringEq(arg, "cell_delay")) + if (stringEqual(arg, "cell_delay")) $1 = TimingDerateCellType::cell_delay; - else if (stringEq(arg, "cell_check")) + else if (stringEqual(arg, "cell_check")) $1 = TimingDerateCellType::cell_check; else { tclArgError(interp, 2167, "{} not cell_delay or cell_check.", arg); @@ -1012,51 +982,51 @@ using namespace sta; %typemap(in) PathClkOrData { int length; - char *arg = Tcl_GetStringFromObj($input, &length); - if (stringEq(arg, "clk")) + std::string arg = Tcl_GetStringFromObj($input, &length); + if (stringEqual(arg, "clk")) $1 = PathClkOrData::clk; - else if (stringEq(arg, "data")) + else if (stringEqual(arg, "data")) $1 = PathClkOrData::data; else { - tclArgError(interp, 2168, "{} not clk or data.", arg); + tclArgError(interp, 2168, "{} not clk or data.", arg.c_str()); return TCL_ERROR; } } %typemap(in) ReportSortBy { int length; - char *arg = Tcl_GetStringFromObj($input, &length); - if (stringEq(arg, "group")) + std::string arg = Tcl_GetStringFromObj($input, &length); + if (stringEqual(arg, "group")) $1 = sort_by_group; - else if (stringEq(arg, "slack")) + else if (stringEqual(arg, "slack")) $1 = sort_by_slack; else { - tclArgError(interp, 2169, "{} not group or slack.", arg); + tclArgError(interp, 2169, "{} not group or slack.", arg.c_str()); return TCL_ERROR; } } %typemap(in) ReportPathFormat { int length; - char *arg = Tcl_GetStringFromObj($input, &length); - if (stringEq(arg, "full")) + std::string arg = Tcl_GetStringFromObj($input, &length); + if (stringEqual(arg, "full")) $1 = ReportPathFormat::full; - else if (stringEq(arg, "full_clock")) + else if (stringEqual(arg, "full_clock")) $1 = ReportPathFormat::full_clock; - else if (stringEq(arg, "full_clock_expanded")) + else if (stringEqual(arg, "full_clock_expanded")) $1 = ReportPathFormat::full_clock_expanded; - else if (stringEq(arg, "short")) + else if (stringEqual(arg, "short")) $1 = ReportPathFormat::shorter; - else if (stringEq(arg, "end")) + else if (stringEqual(arg, "end")) $1 = ReportPathFormat::endpoint; - else if (stringEq(arg, "summary")) + else if (stringEqual(arg, "summary")) $1 = ReportPathFormat::summary; - else if (stringEq(arg, "slack_only")) + else if (stringEqual(arg, "slack_only")) $1 = ReportPathFormat::slack_only; - else if (stringEq(arg, "json")) + else if (stringEqual(arg, "json")) $1 = ReportPathFormat::json; else { - tclArgError(interp, 2170, "unknown path type {}.", arg); + tclArgError(interp, 2170, "unknown path type {}.", arg.c_str()); return TCL_ERROR; } } @@ -1247,16 +1217,16 @@ using namespace sta; %typemap(in) Scene* { sta::Sta *sta = Sta::sta(); int length; - char *scene_name = Tcl_GetStringFromObj($input, &length); + std::string scene_name = Tcl_GetStringFromObj($input, &length); // parse_scene_or_all support depreated 11/21/2025 - if (stringEq(scene_name, "NULL")) + if (scene_name == "NULL") $1 = nullptr; else { Scene *scene = sta->findScene(scene_name); if (scene) $1 = scene; else { - tclArgError(interp, 2173, "scene {} not found.", scene_name); + tclArgError(interp, 2173, "scene {} not found.", scene_name.c_str()); return TCL_ERROR; } } @@ -1317,7 +1287,7 @@ using namespace sta; Tcl_SetResult(interp, const_cast(""), TCL_STATIC); break; case PropertyValue::Type::string: - Tcl_SetResult(interp, const_cast(value.stringValue()), TCL_VOLATILE); + Tcl_SetResult(interp, const_cast(value.stringValue().c_str()), TCL_VOLATILE); break; case PropertyValue::Type::float_: { const Unit *unit = value.unit(); @@ -1443,15 +1413,15 @@ using namespace sta; %typemap(in) CircuitSim { int length; - char *arg = Tcl_GetStringFromObj($input, &length); - if (stringEq(arg, "hspice")) + std::string arg = Tcl_GetStringFromObj($input, &length); + if (stringEqual(arg, "hspice")) $1 = CircuitSim::hspice; - else if (stringEq(arg, "ngspice")) + else if (stringEqual(arg, "ngspice")) $1 = CircuitSim::ngspice; - else if (stringEq(arg, "xyce")) + else if (stringEqual(arg, "xyce")) $1 = CircuitSim::xyce; else { - tclArgError(interp, 2171, "unknown circuit simulator {}.", arg); + tclArgError(interp, 2171, "unknown circuit simulator {}.", arg.c_str()); return TCL_ERROR; } } diff --git a/tcl/TclTypeHelpers.cc b/tcl/TclTypeHelpers.cc index 66dc529c..48ccbf57 100644 --- a/tcl/TclTypeHelpers.cc +++ b/tcl/TclTypeHelpers.cc @@ -31,8 +31,8 @@ namespace sta { StringSeq -tclListSeqStdString(Tcl_Obj *const source, - Tcl_Interp *interp) +tclListStringSeq(Tcl_Obj *const source, + Tcl_Interp *interp) { Tcl_Size argc; Tcl_Obj **argv; @@ -49,8 +49,8 @@ tclListSeqStdString(Tcl_Obj *const source, } StringSeq * -tclListSeqStdStringPtr(Tcl_Obj *const source, - Tcl_Interp *interp) +tclListStringSeqPtr(Tcl_Obj *const source, + Tcl_Interp *interp) { Tcl_Size argc; Tcl_Obj **argv; @@ -69,8 +69,8 @@ tclListSeqStdStringPtr(Tcl_Obj *const source, } StringSet * -tclListSetStdString(Tcl_Obj *const source, - Tcl_Interp *interp) +tclListStringSet(Tcl_Obj *const source, + Tcl_Interp *interp) { Tcl_Size argc; Tcl_Obj **argv; @@ -150,24 +150,24 @@ tclArcDcalcArg(ArcDcalcArg &gate, Tcl_Obj *list = Tcl_NewListObj(0, nullptr); Tcl_Obj *obj; - const char *inst_name = network->pathName(drvr); - obj = Tcl_NewStringObj(inst_name, strlen(inst_name)); + std::string inst_name = network->pathName(drvr); + obj = Tcl_NewStringObj(inst_name.data(), inst_name.size()); Tcl_ListObjAppendElement(interp, list, obj); - const char *from_name = arc->from()->name(); - obj = Tcl_NewStringObj(from_name, strlen(from_name)); + const std::string &from_name = arc->from()->name(); + obj = Tcl_NewStringObj(from_name.c_str(), from_name.size()); Tcl_ListObjAppendElement(interp, list, obj); - const char *from_edge = arc->fromEdge()->to_string().c_str(); - obj = Tcl_NewStringObj(from_edge, strlen(from_edge)); + const std::string from_edge(arc->fromEdge()->to_string()); + obj = Tcl_NewStringObj(from_edge.c_str(), from_edge.size()); Tcl_ListObjAppendElement(interp, list, obj); - const char *to_name = arc->to()->name(); - obj = Tcl_NewStringObj(to_name, strlen(to_name)); + const std::string to_name = arc->to()->name(); + obj = Tcl_NewStringObj(to_name.c_str(), to_name.size()); Tcl_ListObjAppendElement(interp, list, obj); - const char *to_edge = arc->toEdge()->to_string().c_str(); - obj = Tcl_NewStringObj(to_edge, strlen(to_edge)); + const std::string to_edge(arc->toEdge()->to_string()); + obj = Tcl_NewStringObj(to_edge.c_str(), to_edge.size()); Tcl_ListObjAppendElement(interp, list, obj); std::string input_delay = delayAsString(gate.inputDelay(), sta); diff --git a/tcl/Util.tcl b/tcl/Util.tcl index 3236cb93..15443529 100644 --- a/tcl/Util.tcl +++ b/tcl/Util.tcl @@ -267,7 +267,6 @@ define_cmd_args "user_run_time" {} # Write run time statistics to filename. proc write_stats { filename } { -puts "stats $filename" if { ![catch {open $filename w} stream] } { puts $stream "[elapsed_run_time] [user_run_time] [memory_usage]" close $stream diff --git a/util/Debug.cc b/util/Debug.cc index 917e40fa..016dc1b5 100644 --- a/util/Debug.cc +++ b/util/Debug.cc @@ -39,44 +39,44 @@ Debug::Debug(Report *report) : } bool -Debug::check(const char *what, +Debug::check(std::string_view what, int level) const { if (debug_on_) { - int dbg_level; - bool exists; - findKeyValue(debug_map_, what, dbg_level, exists); - if (exists) + auto itr = debug_map_.find(what); + if (itr != debug_map_.end()) { + int dbg_level = itr->second; return dbg_level >= level; + } } return false; } int -Debug::level(const char *what) +Debug::level(std::string_view what) { if (debug_on_) { - int dbg_level; - bool exists; - findKeyValue(debug_map_, what, dbg_level, exists); - if (exists) + auto itr = debug_map_.find(what); + if (itr != debug_map_.end()) { + int dbg_level = itr->second; return dbg_level; + } } return 0; } void -Debug::setLevel(const char *what, +Debug::setLevel(std::string_view what, int level) { - if (stringEq(what, "stats")) + if (what == "stats") stats_level_ = level; else if (level == 0) { - debug_map_.erase(what); + debug_map_.erase(std::string(what)); debug_on_ = !debug_map_.empty(); } else { - debug_map_[what] = level; + debug_map_[std::string(what)] = level; debug_on_ = true; } } diff --git a/util/Error.cc b/util/Error.cc index 88914f26..3278d0fe 100644 --- a/util/Error.cc +++ b/util/Error.cc @@ -59,9 +59,8 @@ ExceptionLine::ExceptionLine(const std::string &filename, { } -FileNotReadable::FileNotReadable(std::string filename) : - filename_(std::move(filename)), - msg_(sta::format("cannot read file {}.", filename_)) +FileNotReadable::FileNotReadable(std::string_view filename) : + msg_(sta::format("cannot read file {}.", filename)) { } @@ -71,9 +70,8 @@ FileNotReadable::what() const noexcept return msg_.c_str(); } -FileNotWritable::FileNotWritable(std::string filename) : - filename_(std::move(filename)), - msg_(sta::format("cannot write file {}.", filename_)) +FileNotWritable::FileNotWritable(std::string_view filename) : + msg_(sta::format("cannot write file {}.", filename)) { } diff --git a/util/Hash.cc b/util/Hash.cc index 4f51bd57..49b49798 100644 --- a/util/Hash.cc +++ b/util/Hash.cc @@ -24,17 +24,14 @@ #include "Hash.hh" -#include - namespace sta { size_t -hashString(const char *str) +hashString(std::string_view str) { size_t hash = hash_init_value; - size_t length = strlen(str); - for (size_t i = 0; i < length; i++) - hash = ((hash << 5) + hash) ^ str[i]; + for (char ch : str) + hash = ((hash << 5) + hash) ^ ch; return hash; } diff --git a/util/MinMax.cc b/util/MinMax.cc index d3720ac3..299d3157 100644 --- a/util/MinMax.cc +++ b/util/MinMax.cc @@ -88,11 +88,11 @@ MinMax::opposite() const const MinMax * MinMax::find(const char *min_max) { - if (stringEq(min_max, "min") - || stringEq(min_max, "early")) + if (stringEqual(min_max, "min") + || stringEqual(min_max, "early")) return &min_; - else if (stringEq(min_max, "max") - || stringEq(min_max, "late")) + else if (stringEqual(min_max, "max") + || stringEqual(min_max, "late")) return &max_; else return nullptr; @@ -168,15 +168,15 @@ MinMaxAll::matches(const MinMaxAll *min_max) const const MinMaxAll * MinMaxAll::find(const char *min_max) { - if (stringEq(min_max, "min") - || stringEq(min_max, "early")) + if (stringEqual(min_max, "min") + || stringEqual(min_max, "early")) return &min_; - else if (stringEq(min_max, "max") - || stringEq(min_max, "late")) + else if (stringEqual(min_max, "max") + || stringEqual(min_max, "late")) return &max_; - else if (stringEq(min_max, "all") - || stringEq(min_max, "min_max") - || stringEq(min_max, "minmax")) + else if (stringEqual(min_max, "all") + || stringEqual(min_max, "min_max") + || stringEqual(min_max, "minmax")) return &all_; else return nullptr; diff --git a/util/PatternMatch.cc b/util/PatternMatch.cc index a8397e37..c4f15237 100644 --- a/util/PatternMatch.cc +++ b/util/PatternMatch.cc @@ -23,12 +23,12 @@ // This notice may not be removed or altered from any source distribution. #include "PatternMatch.hh" -#include +#include #include namespace sta { -PatternMatch::PatternMatch(const char *pattern, +PatternMatch::PatternMatch(std::string_view pattern, bool is_regexp, bool nocase, Tcl_Interp *interp) : @@ -42,7 +42,7 @@ PatternMatch::PatternMatch(const char *pattern, compileRegexp(); } -PatternMatch::PatternMatch(const char *pattern) : +PatternMatch::PatternMatch(std::string_view pattern) : pattern_(pattern), is_regexp_(false), nocase_(false), @@ -51,7 +51,7 @@ PatternMatch::PatternMatch(const char *pattern) : { } -PatternMatch::PatternMatch(const char *pattern, +PatternMatch::PatternMatch(std::string_view pattern, const PatternMatch *inherit_from) : pattern_(pattern), is_regexp_(inherit_from->is_regexp_), @@ -63,18 +63,6 @@ PatternMatch::PatternMatch(const char *pattern, compileRegexp(); } -PatternMatch::PatternMatch(const std::string &pattern, - const PatternMatch *inherit_from) : - pattern_(pattern.c_str()), - is_regexp_(inherit_from->is_regexp_), - nocase_(inherit_from->nocase_), - interp_(inherit_from->interp_), - regexp_(nullptr) -{ - if (is_regexp_) - compileRegexp(); -} - void PatternMatch::compileRegexp() { @@ -95,9 +83,9 @@ PatternMatch::compileRegexp() } static bool -regexpWildcards(const char *pattern) +regexpWildcards(std::string_view pattern) { - return strpbrk(pattern, ".+*?[]") != nullptr; + return pattern.find_first_of(".+*?[]") != std::string_view::npos; } bool @@ -110,36 +98,34 @@ PatternMatch::hasWildcards() const } bool -PatternMatch::match(const std::string &str) const +PatternMatch::match(std::string_view str) const { - return match(str.c_str()); + if (regexp_) { + std::string buf(str); + const char *cstr = buf.c_str(); + return Tcl_RegExpExec(nullptr, regexp_, cstr, cstr) == 1; + } + return patternMatch(pattern_, str); } bool -PatternMatch::match(const char *str) const +PatternMatch::matchNoCase(std::string_view str) const { - if (regexp_) - return Tcl_RegExpExec(nullptr, regexp_, str, str) == 1; - else - return patternMatch(pattern_, str); -} - -bool -PatternMatch::matchNoCase(const char *str) const -{ - if (regexp_) - return Tcl_RegExpExec(0, regexp_, str, str) == 1; - else - return patternMatchNoCase(pattern_, str, nocase_); + if (regexp_) { + std::string buf(str); + const char *cstr = buf.c_str(); + return Tcl_RegExpExec(0, regexp_, cstr, cstr) == 1; + } + return patternMatchNoCase(pattern_, str, nocase_); } //////////////////////////////////////////////////////////////// -RegexpCompileError::RegexpCompileError(const char *pattern) : +RegexpCompileError::RegexpCompileError(std::string_view pattern) : Exception() { error_ = "TCL failed to compile regular expression '"; - error_ += pattern; + error_.append(pattern.data(), pattern.size()); error_ += "'."; } @@ -152,70 +138,71 @@ RegexpCompileError::what() const noexcept //////////////////////////////////////////////////////////////// bool -patternMatch(const char *pattern, - const char *str) +patternMatch(std::string_view pattern, + std::string_view str) { - const char *p = pattern; - const char *s = str; - - while (*p && *s && (*s == *p || *p == '?')) { - p++; - s++; + size_t pi = 0; + size_t si = 0; + while (pi < pattern.size() && si < str.size() + && (str[si] == pattern[pi] || pattern[pi] == '?')) { + pi++; + si++; } - if (*p == '\0' && *s == '\0') + if (pi == pattern.size() && si == str.size()) return true; - else if (*p == '*') { - if (p[1] == '\0') + if (pi < pattern.size() && pattern[pi] == '*') { + if (pi + 1 == pattern.size()) return true; - while (*s) { - if (patternMatch(p + 1, s)) + while (si < str.size()) { + if (patternMatch(pattern.substr(pi + 1), str.substr(si))) return true; - s++; + si++; } } return false; } -inline -bool equalCase(char s, - char p, - bool nocase) +static bool +equalCase(char s, + char p, + bool nocase) { return nocase - ? tolower(s) == tolower(p) + ? std::tolower(static_cast(s)) + == std::tolower(static_cast(p)) : s == p; } bool -patternMatchNoCase(const char *pattern, - const char *str, +patternMatchNoCase(std::string_view pattern, + std::string_view str, bool nocase) { - const char *p = pattern; - const char *s = str; - - while (*p && *s && (equalCase(*s, *p, nocase) || *p == '?')) { - p++; - s++; + size_t pi = 0; + size_t si = 0; + while (pi < pattern.size() && si < str.size() + && (equalCase(str[si], pattern[pi], nocase) || pattern[pi] == '?')) { + pi++; + si++; } - if (*p == '\0' && *s == '\0') + if (pi == pattern.size() && si == str.size()) return true; - else if (*p == '*') { - if (p[1] == '\0') + if (pi < pattern.size() && pattern[pi] == '*') { + if (pi + 1 == pattern.size()) return true; - while (*s) { - if (patternMatchNoCase(p + 1, s, nocase)) + while (si < str.size()) { + if (patternMatchNoCase(pattern.substr(pi + 1), str.substr(si), nocase)) return true; - s++; + si++; } } return false; } bool -patternWildcards(const char *pattern) +patternWildcards(std::string_view pattern) { - return strpbrk(pattern, "*?") != 0; + return pattern.find_first_of("*?") != std::string_view::npos; } } // namespace diff --git a/util/Report.cc b/util/Report.cc index d8a6a04d..ca6bc077 100644 --- a/util/Report.cc +++ b/util/Report.cc @@ -185,11 +185,11 @@ Report::isSuppressed(int id) //////////////////////////////////////////////////////////////// void -Report::logBegin(std::string filename) +Report::logBegin(std::string_view filename) { - log_stream_ = fopen(filename.c_str(), "w"); + log_stream_ = fopen(std::string(filename).c_str(), "w"); if (log_stream_ == nullptr) - throw FileNotWritable(std::move(filename)); + throw FileNotWritable(filename); } void @@ -201,19 +201,19 @@ Report::logEnd() } void -Report::redirectFileBegin(std::string filename) +Report::redirectFileBegin(std::string_view filename) { - redirect_stream_ = fopen(filename.c_str(), "w"); + redirect_stream_ = fopen(std::string(filename).c_str(), "w"); if (redirect_stream_ == nullptr) - throw FileNotWritable(std::move(filename)); + throw FileNotWritable(filename); } void -Report::redirectFileAppendBegin(std::string filename) +Report::redirectFileAppendBegin(std::string_view filename) { - redirect_stream_ = fopen(filename.c_str(), "a"); + redirect_stream_ = fopen(std::string(filename).c_str(), "a"); if (redirect_stream_ == nullptr) - throw FileNotWritable(std::move(filename)); + throw FileNotWritable(filename); } void diff --git a/util/ReportTcl.cc b/util/ReportTcl.cc index 97eef4af..a418a53a 100644 --- a/util/ReportTcl.cc +++ b/util/ReportTcl.cc @@ -183,7 +183,7 @@ ReportTcl::flush() // Tcl_Main can eval multiple commands before the flushing the command // output, so the log/redirect commands must force a flush. void -ReportTcl::logBegin(std::string filename) +ReportTcl::logBegin(std::string_view filename) { flush(); Report::logBegin(filename); @@ -197,14 +197,14 @@ ReportTcl::logEnd() } void -ReportTcl::redirectFileBegin(std::string filename) +ReportTcl::redirectFileBegin(std::string_view filename) { flush(); Report::redirectFileBegin(filename); } void -ReportTcl::redirectFileAppendBegin(std::string filename) +ReportTcl::redirectFileAppendBegin(std::string_view filename) { flush(); Report::redirectFileAppendBegin(filename); diff --git a/util/StringUtil.cc b/util/StringUtil.cc index cc77196c..00a36ec4 100644 --- a/util/StringUtil.cc +++ b/util/StringUtil.cc @@ -25,29 +25,12 @@ #include "StringUtil.hh" #include -#include #include -#include -#include // exit - -#include "Machine.hh" -#include "Mutex.hh" -#include "Error.hh" +#include +#include namespace sta { -char * -stringCopy(const char *str) -{ - if (str) { - char *copy = new char[strlen(str) + 1]; - strcpy(copy, str); - return copy; - } - else - return nullptr; -} - bool isDigits(const char *str) { @@ -58,72 +41,28 @@ isDigits(const char *str) return true; } -//////////////////////////////////////////////////////////////// - -static constexpr size_t tmp_string_count = 256; -static constexpr size_t tmp_string_initial_length = 256; -thread_local static std::array tmp_strings; -thread_local static std::array tmp_string_lengths; -thread_local static int tmp_string_next = 0; - -void -deleteTmpStrings() -{ - for (size_t i = 0; i < tmp_string_count; i++) { - stringDelete(tmp_strings[i]); - tmp_string_lengths[i] = 0; - tmp_strings[i] = nullptr; - } - tmp_string_next = 0; -} - -char * -makeTmpString(size_t length) -{ - if (tmp_string_next == tmp_string_count) - tmp_string_next = 0; - char *tmp_str = tmp_strings[tmp_string_next]; - size_t tmp_length = tmp_string_lengths[tmp_string_next]; - if (tmp_length < length) { - // String isn't long enough. Make a new one. - delete [] tmp_str; - tmp_length = std::max(tmp_string_initial_length, length); - tmp_str = new char[tmp_length]; - tmp_strings[tmp_string_next] = tmp_str; - tmp_string_lengths[tmp_string_next] = tmp_length; - } - tmp_string_next++; - return tmp_str; -} - -char * -makeTmpString(std::string &str) -{ - char *tmp = makeTmpString(str.length() + 1); - strcpy(tmp, str.c_str()); - return tmp; -} - -void -stringDeleteCheck(const char *str) -{ - if (isTmpString(str)) - criticalError(2600, "stringDelete for tmp string."); -} - bool -isTmpString(const char *str) +isDigits(std::string_view str) { - if (!tmp_strings.empty()) { - for (size_t i = 0; i < tmp_string_count; i++) { - if (str == tmp_strings[i]) - return true; - } + for (char ch : str) { + if (!isdigit(ch)) + return false; } - return false; + return true; } -//////////////////////////////////////////////////////////////// +// Wrapper for the absurdly named std::from_chars. +std::pair +stringFloat(const std::string &str) +{ + float value; + auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value); + if (ec == std::errc() + && *ptr == '\0') + return {value, true}; + else + return {0.0, false}; +} void trimRight(std::string &str) @@ -132,8 +71,8 @@ trimRight(std::string &str) } StringSeq -split(const std::string &text, - const std::string &delims) +parseTokens(const std::string &text, + std::string_view delims) { StringSeq tokens; auto start = text.find_first_not_of(delims); @@ -148,25 +87,4 @@ split(const std::string &text, return tokens; } -// Parse space separated tokens. -StringSeq -parseTokens(const std::string &s, - const char delimiter) -{ - StringSeq tokens; - size_t i = 0; - while (i < s.size()) { - while (i < s.size() && std::isspace(s[i])) - ++i; - size_t start = i; - while (i < s.size() && s[i] != delimiter) - ++i; - if (start < i) { - tokens.emplace_back(s, start, i - start); - ++i; - } - } - return tokens; -} - } // namespace diff --git a/util/Transition.cc b/util/Transition.cc index 9dd7fdc7..4318366d 100644 --- a/util/Transition.cc +++ b/util/Transition.cc @@ -35,8 +35,8 @@ const RiseFall RiseFall::fall_("fall", "v", 1); const std::array RiseFall::range_{&rise_, &fall_}; const std::array RiseFall::range_index_{rise_.index(), fall_.index()}; -RiseFall::RiseFall(const char *name, - const char *short_name, +RiseFall::RiseFall(std::string_view name, + std::string_view short_name, int sdf_triple_index) : name_(name), short_name_(short_name), @@ -44,7 +44,7 @@ RiseFall::RiseFall(const char *name, { } -const std::string & +const std::string& RiseFall::to_string(bool use_short) const { if (use_short) @@ -63,16 +63,13 @@ RiseFall::opposite() const } const RiseFall * -RiseFall::find(const char *rf_str) +RiseFall::find(std::string_view rf_str) { - if (stringEq(rf_str, rise_.name()) - || stringEq(rf_str, rise_.shortName())) + if (rf_str == rise_.name() || rf_str == rise_.shortName()) return &rise_; - else if (stringEq(rf_str, fall_.name()) - || stringEq(rf_str, fall_.shortName())) + if (rf_str == fall_.name() || rf_str == fall_.shortName()) return &fall_; - else - return nullptr; + return nullptr; } const RiseFall * @@ -128,8 +125,8 @@ const RiseFallBoth RiseFallBoth::rise_fall_("rise_fall", "rf", 2, {RiseFall::riseIndex(), RiseFall::fallIndex()}); -RiseFallBoth::RiseFallBoth(const char *name, - const char *short_name, +RiseFallBoth::RiseFallBoth(std::string_view name, + std::string_view short_name, int sdf_triple_index, const RiseFall *as_rise_fall, std::vector range, @@ -143,7 +140,7 @@ RiseFallBoth::RiseFallBoth(const char *name, { } -const std::string & +const std::string& RiseFallBoth::to_string(bool use_short) const { if (use_short) @@ -153,16 +150,15 @@ RiseFallBoth::to_string(bool use_short) const } const RiseFallBoth * -RiseFallBoth::find(const char *tr_str) +RiseFallBoth::find(std::string_view name) { - if (stringEq(tr_str, rise_.name())) + if (name == rise_.name()) return &rise_; - else if (stringEq(tr_str, fall_.name())) + if (name == fall_.name()) return &fall_; - else if (stringEq(tr_str, rise_fall_.name())) + if (name == rise_fall_.name()) return &rise_fall_; - else - return nullptr; + return nullptr; } bool @@ -202,8 +198,8 @@ const Transition Transition::tr_XZ_{"XZ", "XZ", nullptr, 10}; const Transition Transition::tr_ZX_{"ZX", "ZX", nullptr, 11}; const Transition Transition::rise_fall_{"*", "**", nullptr, -1}; -Transition::Transition(const char *name, - const char *init_final, +Transition::Transition(std::string_view name, + std::string_view init_final, const RiseFall *as_rise_fall, int sdf_triple_index) : name_(name), @@ -223,9 +219,9 @@ Transition::matches(const Transition *tr) const } const Transition * -Transition::find(const char *tr_str) +Transition::find(std::string_view tr_str) { - return findKey(transition_map_, tr_str); + return findStringKey(transition_map_, tr_str); } const RiseFallBoth * diff --git a/util/Util.i b/util/Util.i index e68de5ef..c34ba4a8 100644 --- a/util/Util.i +++ b/util/Util.i @@ -34,6 +34,7 @@ #include "Error.hh" #include "Fuzzy.hh" #include "Units.hh" +#include "StringUtil.hh" using namespace sta; @@ -472,10 +473,10 @@ unit_scale(const char *unit_name) // format_unit functions print with fixed digits and suffix. // Pass value arg as string to support NaNs. std::string -format_time(const char *value, +format_time(std::string value, int digits) { - float value1 = strtof(value, nullptr); + auto [value1, valid] = stringFloat(value); return Sta::sta()->units()->timeUnit()->asString(value1, digits); } @@ -483,7 +484,7 @@ std::string format_capacitance(const char *value, int digits) { - float value1 = strtof(value, nullptr); + auto [value1, valid] = stringFloat(value); return Sta::sta()->units()->capacitanceUnit()->asString(value1, digits); } @@ -491,7 +492,7 @@ std::string format_resistance(const char *value, int digits) { - float value1 = strtof(value, nullptr); + auto [value1, valid] = stringFloat(value); return Sta::sta()->units()->resistanceUnit()->asString(value1, digits); } @@ -499,7 +500,7 @@ std::string format_voltage(const char *value, int digits) { - float value1 = strtof(value, nullptr); + auto [value1, valid] = stringFloat(value); return Sta::sta()->units()->voltageUnit()->asString(value1, digits); } @@ -507,7 +508,7 @@ std::string format_current(const char *value, int digits) { - float value1 = strtof(value, nullptr); + auto [value1, valid] = stringFloat(value); return Sta::sta()->units()->currentUnit()->asString(value1, digits); } @@ -515,7 +516,7 @@ std::string format_power(const char *value, int digits) { - float value1 = strtof(value, nullptr); + auto [value1, valid] = stringFloat(value); return Sta::sta()->units()->powerUnit()->asString(value1, digits); } @@ -523,29 +524,28 @@ std::string format_distance(const char *value, int digits) { - float value1 = strtof(value, nullptr); - Unit *dist_unit = Sta::sta()->units()->distanceUnit(); - return dist_unit->asString(value1, digits); + auto [value1, valid] = stringFloat(value); + return Sta::sta()->units()->distanceUnit()->asString(value1, digits); } std::string format_area(const char *value, int digits) { - float value1 = strtof(value, nullptr); + auto [value1, valid] = stringFloat(value); Unit *dist_unit = Sta::sta()->units()->distanceUnit(); return dist_unit->asString(value1 / dist_unit->scale(), digits); } //////////////////////////////////////////////////////////////// -const char * +std::string_view rise_short_name() { return RiseFall::rise()->shortName(); } -const char * +std::string_view fall_short_name() { return RiseFall::fall()->shortName(); diff --git a/verilog/VerilogLex.ll b/verilog/VerilogLex.ll index e55801b6..626ac905 100644 --- a/verilog/VerilogLex.ll +++ b/verilog/VerilogLex.ll @@ -23,6 +23,8 @@ // // This notice may not be removed or altered from any source distribution. +#include + #include "util/FlexDisableRegister.hh" #include "VerilogNamespace.hh" #include "VerilogReader.hh" @@ -93,27 +95,27 @@ ID_TOKEN {ID_ESCAPED_TOKEN}|{ID_ALPHA_TOKEN} } {SIGN}?{UNSIGNED_NUMBER}?"'"[sS]?[bB][01_xz]+ { - yylval->constant = new std::string(yytext); + yylval->emplace(yytext); return token::CONSTANT; } {SIGN}?{UNSIGNED_NUMBER}?"'"[sS]?[oO][0-7_xz]+ { - yylval->constant = new std::string(yytext); + yylval->emplace(yytext); return token::CONSTANT; } {SIGN}?{UNSIGNED_NUMBER}?"'"[sS]?[dD][0-9_]+ { - yylval->constant = new std::string(yytext); + yylval->emplace(yytext); return token::CONSTANT; } {SIGN}?{UNSIGNED_NUMBER}?"'"[sS]?[hH][0-9a-fA-F_xz]+ { - yylval->constant = new std::string(yytext); + yylval->emplace(yytext); return token::CONSTANT; } {SIGN}?[0-9]+ { - yylval->ival = atol(yytext); + yylval->emplace(static_cast(atol(yytext))); return token::INT; } @@ -143,7 +145,7 @@ wire { return token::WIRE; } wor { return token::WOR; } {ID_TOKEN}("."{ID_TOKEN})* { - yylval->string = new std::string(yytext, yyleng); + yylval->emplace(yytext, yyleng); return token::ID; } @@ -155,18 +157,20 @@ wor { return token::WOR; } {BLANK} { /* ignore blanks */ } \" { - yylval->string = new std::string; + token_.clear(); BEGIN(QSTRING); } \" { BEGIN(INITIAL); + yylval->emplace(std::move(token_)); return token::STRING; } {EOL} { error("unterminated quoted string"); BEGIN(INITIAL); + yylval->emplace(std::move(token_)); return token::STRING; } @@ -177,8 +181,8 @@ wor { return token::WOR; } } [^\r\n\"]+ { - /* Anything return token::or double quote */ - *yylval->string += yytext; + /* Anything but return or double quote */ + token_ += yytext; } <> { diff --git a/verilog/VerilogParse.yy b/verilog/VerilogParse.yy index 5888f993..9bd7f162 100644 --- a/verilog/VerilogParse.yy +++ b/verilog/VerilogParse.yy @@ -25,6 +25,7 @@ %{ #include #include +#include #include "Report.hh" #include "PortDirection.hh" @@ -46,6 +47,7 @@ sta::VerilogParse::error(const location_type &loc, { reader->report()->fileError(171,reader->filename(),loc.begin.line, "{}",msg); } + %} %require "3.2" @@ -58,30 +60,11 @@ sta::VerilogParse::error(const location_type &loc, %parse-param { VerilogScanner *scanner } %parse-param { VerilogReader *reader } %define api.parser.class {VerilogParse} +%define api.value.type variant -%union { - int ival; - std::string *string; - std::string *constant; - std::string *attr_spec_value; - sta::VerilogModule *module; - sta::VerilogStmt *stmt; - sta::VerilogStmtSeq *stmt_seq; - sta::PortDirection *port_type; - sta::VerilogDclArgSeq *dcl_arg_seq; - sta::VerilogDclArg *dcl_arg; - sta::VerilogAssign *assign; - sta::VerilogInst *inst; - sta::VerilogNet *net; - sta::VerilogNetBitSelect *net_bit; - sta::VerilogNetSeq *nets; - sta::VerilogAttrEntry *attr_entry; - sta::VerilogAttrEntrySeq *attr_seq; - sta::VerilogAttrStmt *attr_stmt; - sta::VerilogAttrStmtSeq *attr_stmt_seq; -} - -%token INT CONSTANT ID STRING MODULE ENDMODULE ASSIGN PARAMETER DEFPARAM +%token INT +%token ID STRING CONSTANT +%token MODULE ENDMODULE ASSIGN PARAMETER DEFPARAM %token SPECIFY ENDSPECIFY SPECPARAM %token WIRE WAND WOR TRI INPUT OUTPUT INOUT SUPPLY1 SUPPLY0 REG %token ATTR_OPEN ATTR_CLOSED @@ -90,34 +73,26 @@ sta::VerilogParse::error(const location_type &loc, %left '*' '/' %left NEG /* negation--unary minus */ -%type ID STRING CONSTANT -%type WIRE WAND WOR TRI INPUT OUTPUT INOUT SUPPLY1 SUPPLY0 -%type ATTR_OPEN ATTR_CLOSED -%type INT parameter_exprs parameter_expr -%type attr_spec_value -%type dcl_type port_dcl_type -%type stmt declaration instance parameter parameter_dcls parameter_dcl -%type defparam param_values param_value port_dcl -%type stmts stmt_seq net_assignments continuous_assign port_dcls -%type specify_block -%type specify_stmts -%type net_assignment -%type dcl_arg -%type dcl_args -%type port net_scalar net_bit_select net_part_select net_assign_lhs -%type net_constant net_expr port_ref port_expr named_pin_net_expr -%type inst_named_pin net_named net_expr_concat -%type port_list port_refs inst_ordered_pins -%type inst_named_pins net_exprs inst_pins -%type attr_spec -%type attr_specs -%type attr_instance -%type attr_instance_seq - -// Used by error recovery. -%destructor { delete $$; } STRING -%destructor { delete $$; } CONSTANT -%destructor { delete $$; } attr_spec_value +%type attr_spec_value +%type parameter_exprs parameter_expr +%type dcl_type port_dcl_type +%type stmt declaration instance parameter parameter_dcls parameter_dcl +%type defparam param_values param_value port_dcl +%type stmts stmt_seq net_assignments continuous_assign port_dcls +%type specify_block +%type specify_stmts +%type net_assignment +%type dcl_arg +%type dcl_args +%type port net_scalar net_bit_select net_part_select net_assign_lhs +%type net_constant net_expr port_ref port_expr named_pin_net_expr +%type inst_named_pin net_named net_expr_concat +%type port_list port_refs inst_ordered_pins +%type inst_named_pins net_exprs inst_pins +%type attr_spec +%type attr_specs +%type attr_instance +%type attr_instance_seq %start file @@ -134,30 +109,30 @@ modules: module: attr_instance_seq MODULE ID ';' stmts ENDMODULE - { reader->makeModule($3, new sta::VerilogNetSeq,$5, $1, loc_line(@2));} + { reader->makeModule(std::move($3), new sta::VerilogNetSeq,$5, $1, loc_line(@2));} | attr_instance_seq MODULE ID '(' ')' ';' stmts ENDMODULE - { reader->makeModule($3, new sta::VerilogNetSeq,$7, $1, loc_line(@2));} + { reader->makeModule(std::move($3), new sta::VerilogNetSeq,$7, $1, loc_line(@2));} | attr_instance_seq MODULE ID '(' port_list ')' ';' stmts ENDMODULE - { reader->makeModule($3, $5, $8, $1, loc_line(@2)); } + { reader->makeModule(std::move($3), $5, $8, $1, loc_line(@2)); } | attr_instance_seq MODULE ID '(' port_dcls ')' ';' stmts ENDMODULE - { reader->makeModule($3, $5, $8, $1, loc_line(@2)); } + { reader->makeModule(std::move($3), $5, $8, $1, loc_line(@2)); } ; port_list: port { $$ = new sta::VerilogNetSeq; - $$->push_back($1); + $$->push_back($1); } | port_list ',' port - { $1->push_back($3); } + { $1->push_back($3); $$ = $1; } ; port: port_expr | '.' ID '(' ')' - { $$ = reader->makeNetNamedPortRefScalar($2, nullptr);} + { $$ = reader->makeNetNamedPortRefScalar(std::move($2), nullptr);} | '.' ID '(' port_expr ')' - { $$ = reader->makeNetNamedPortRefScalar($2, $4);} + { $$ = reader->makeNetNamedPortRefScalar(std::move($2), $4);} ; port_expr: @@ -171,7 +146,7 @@ port_refs: $$->push_back($1); } | port_refs ',' port_ref - { $1->push_back($3); } + { $1->push_back($3); $$ = $1; } ; port_ref: @@ -219,12 +194,13 @@ stmts: // empty { $$ = new sta::VerilogStmtSeq; } | stmts stmt - { if ($2) $1->push_back($2); } + { if ($2) $1->push_back($2); $$ = $1; } | stmts stmt_seq // Append stmt_seq to stmts. { for (sta::VerilogStmt *stmt : *$2) $1->push_back(stmt); delete $2; + $$ = $1; } ; @@ -278,18 +254,18 @@ parameter_dcls: parameter_dcl: ID '=' parameter_expr - { delete $1; $$ = nullptr; } + { $$ = nullptr; } | ID '=' STRING - { delete $1; delete $3; $$ = nullptr; } + { $$ = nullptr; } ; parameter_expr: ID - { delete $1; $$ = 0; } + { $$ = 0; } | '`' ID - { delete $2; $$ = 0; } + { $$ = 0; } | CONSTANT - { delete $1; $$ = 0; } + { $$ = 0; } | INT | '-' parameter_expr %prec NEG { $$ = - $2; } @@ -319,9 +295,9 @@ param_values: param_value: ID '=' parameter_expr - { delete $1; $$ = nullptr; } + { $$ = nullptr; } | ID '=' STRING - { delete $1; delete $3; $$ = nullptr; } + { $$ = nullptr; } ; declaration: @@ -356,9 +332,9 @@ dcl_args: dcl_arg: ID - { $$ = reader->makeDclArg($1); } + { $$ = reader->makeDclArg(std::move($1)); } | net_assignment - { $$ = reader->makeDclArg($1); } + { $$ = reader->makeDclArg(std::move($1)); } ; continuous_assign: @@ -372,7 +348,7 @@ net_assignments: $$->push_back($1); } | net_assignments ',' net_assignment - { $1->push_back($3); } + { $1->push_back($3); $$ = $1; } ; net_assignment: @@ -387,9 +363,9 @@ net_assign_lhs: instance: attr_instance_seq ID ID '(' inst_pins ')' ';' - { $$ = reader->makeModuleInst($2, $3, $5, $1, loc_line(@2)); } + { $$ = reader->makeModuleInst(std::move($2), std::move($3), $5, $1, loc_line(@2)); } | attr_instance_seq ID parameter_values ID '(' inst_pins ')' ';' - { $$ = reader->makeModuleInst($2, $4, $6, $1, loc_line(@2)); } + { $$ = reader->makeModuleInst(std::move($2), std::move($4), $6, $1, loc_line(@2)); } ; parameter_values: @@ -417,7 +393,7 @@ inst_ordered_pins: $$->push_back($1); } | inst_ordered_pins ',' net_expr - { $1->push_back($3); } + { $1->push_back($3); $$ = $1; } ; // Named pin connections. @@ -427,7 +403,7 @@ inst_named_pins: $$->push_back($1); } | inst_named_pins ',' inst_named_pin - { $1->push_back($3); } + { $1->push_back($3); $$ = $1; } ; // The port reference is split out into cases to special case @@ -435,23 +411,23 @@ inst_named_pins: inst_named_pin: // Scalar port. '.' ID '(' ')' - { $$ = reader->makeNetNamedPortRefScalarNet($2); } + { $$ = reader->makeNetNamedPortRefScalarNet(std::move($2)); } | '.' ID '(' ID ')' - { $$ = reader->makeNetNamedPortRefScalarNet($2, $4); } + { $$ = reader->makeNetNamedPortRefScalarNet(std::move($2), std::move($4)); } | '.' ID '(' ID '[' INT ']' ')' - { $$ = reader->makeNetNamedPortRefBitSelect($2, $4, $6); } + { $$ = reader->makeNetNamedPortRefBitSelect(std::move($2), std::move($4), $6); } | '.' ID '(' named_pin_net_expr ')' - { $$ = reader->makeNetNamedPortRefScalar($2, $4); } + { $$ = reader->makeNetNamedPortRefScalar(std::move($2), $4); } // Bus port bit select. | '.' ID '[' INT ']' '(' ')' - { $$ = reader->makeNetNamedPortRefBit($2, $4, nullptr); } + { $$ = reader->makeNetNamedPortRefBit(std::move($2), $4, nullptr); } | '.' ID '[' INT ']' '(' net_expr ')' - { $$ = reader->makeNetNamedPortRefBit($2, $4, $7); } + { $$ = reader->makeNetNamedPortRefBit(std::move($2), $4, $7); } // Bus port part select. | '.' ID '[' INT ':' INT ']' '(' ')' - { $$ = reader->makeNetNamedPortRefPart($2, $4, $6, nullptr); } + { $$ = reader->makeNetNamedPortRefPart(std::move($2), $4, $6, nullptr); } | '.' ID '[' INT ':' INT ']' '(' net_expr ')' - { $$ = reader->makeNetNamedPortRefPart($2, $4, $6, $9); } + { $$ = reader->makeNetNamedPortRefPart(std::move($2), $4, $6, $9); } ; named_pin_net_expr: @@ -468,22 +444,22 @@ net_named: net_scalar: ID - { $$ = reader->makeNetScalar($1); } + { $$ = reader->makeNetScalar(std::move($1)); } ; net_bit_select: ID '[' INT ']' - { $$ = reader->makeNetBitSelect($1, $3); } + { $$ = reader->makeNetBitSelect(std::move($1), $3); } ; net_part_select: ID '[' INT ':' INT ']' - { $$ = reader->makeNetPartSelect($1, $3, $5); } + { $$ = reader->makeNetPartSelect(std::move($1), $3, $5); } ; net_constant: CONSTANT - { $$ = reader->makeNetConstant($1, loc_line(@1)); } + { $$ = reader->makeNetConstant(std::move($1), loc_line(@1)); } ; net_expr_concat: @@ -497,7 +473,7 @@ net_exprs: $$->push_back($1); } | net_exprs ',' net_expr - { $$->push_back($3); } + { $1->push_back($3); $$ = $1; } ; net_expr: @@ -512,7 +488,7 @@ attr_instance_seq: // empty { $$ = new sta::VerilogAttrStmtSeq; } | attr_instance_seq attr_instance - { if ($2) $1->push_back($2); } + { if ($2) $1->push_back($2); $$ = $1; } ; attr_instance: @@ -526,23 +502,23 @@ attr_specs: $$->push_back($1); } | attr_specs ',' attr_spec - { $$->push_back($3); } + { $1->push_back($3); $$ = $1; } ; attr_spec: ID - { $$ = new sta::VerilogAttrEntry(*$1, "1"); delete $1; } + { $$ = new sta::VerilogAttrEntry(std::move($1), "1"); } | ID '=' attr_spec_value - { $$ = new sta::VerilogAttrEntry(*$1, *$3); delete $1; delete $3; } + { $$ = new sta::VerilogAttrEntry(std::move($1), std::move($3)); } ; attr_spec_value: CONSTANT - { $$ = $1; } + { $$ = std::move($1); } | STRING - { $$ = $1; } + { $$ = std::move($1); } | INT - { $$ = new std::string(std::to_string($1)); } + { $$ = std::to_string($1); } ; %% diff --git a/verilog/VerilogReader.cc b/verilog/VerilogReader.cc index a539a311..68f99b62 100644 --- a/verilog/VerilogReader.cc +++ b/verilog/VerilogReader.cc @@ -26,6 +26,7 @@ #include #include +#include #include "ContainerHelpers.hh" #include "Zlib.hh" @@ -59,7 +60,7 @@ makeVerilogReader(NetworkReader *network) } bool -readVerilogFile(const char *filename, +readVerilogFile(std::string_view filename, VerilogReader *verilog_reader) { return verilog_reader->read(filename); @@ -115,34 +116,34 @@ VerilogReader::VerilogReader(NetworkReader *network) : zero_net_name_("zero_"), one_net_name_("one_") { - network->setLinkFunc( - [this](const char *top_cell_name, bool make_black_boxes) -> Instance * { - return linkNetwork(top_cell_name, make_black_boxes, true); - }); + network->setLinkFunc([this](std::string_view top_cell_name, + bool make_black_boxes) -> Instance * { + return linkNetwork(top_cell_name, make_black_boxes, true); + }); constant10_max_ = std::to_string(std::numeric_limits::max()); } -VerilogReader::~VerilogReader() { deleteModules(); } +VerilogReader::~VerilogReader() +{ + deleteModules(); +} void VerilogReader::deleteModules() { - for (const auto [name, module] : module_map_) - delete module; - module_map_.clear(); + deleteContents(module_map_); } bool -VerilogReader::read(const char *filename) +VerilogReader::read(std::string_view filename) { - gzstream::igzstream stream(filename); + gzstream::igzstream stream(std::string(filename).c_str()); if (stream.is_open()) { Stats stats(debug_, report_); VerilogScanner scanner(&stream, filename, report_); VerilogParse parser(&scanner, this); init(filename); bool success = (parser.parse() == 0); - reportStmtCounts(); stats.report("Read verilog"); return success; } @@ -151,38 +152,13 @@ VerilogReader::read(const char *filename) } void -VerilogReader::init(const char *filename) +VerilogReader::init(std::string_view filename) { filename_ = filename; library_ = network_->findLibrary("verilog"); if (library_ == nullptr) - library_ = network_->makeLibrary("verilog", nullptr); - - // Stats - report_stmt_stats_ = debug_->check("verilog", 1); - module_count_ = 0; - inst_mod_count_ = 0; - inst_lib_count_ = 0; - inst_lib_net_arrays_ = 0; - dcl_count_ = 0; - dcl_bus_count_ = 0; - dcl_arg_count_ = 0; - net_scalar_count_ = 0; - net_part_select_count_ = 0; - net_bit_select_count_ = 0; - net_port_ref_scalar_count_ = 0; - net_port_ref_scalar_net_count_ = 0; - net_port_ref_bit_count_ = 0; - net_port_ref_part_count_ = 0; - net_constant_count_ = 0; - assign_count_ = 0; - concat_count_ = 0; - inst_names_ = 0; - port_names_ = 0; - inst_module_names_ = 0; - net_scalar_names_ = 0; - net_bus_names_ = 0; + library_ = network_->makeLibrary("verilog", ""); } VerilogModule * @@ -192,14 +168,14 @@ VerilogReader::module(Cell *cell) } void -VerilogReader::makeModule(const std::string *module_vname, +VerilogReader::makeModule(std::string &&module_vname, VerilogNetSeq *ports, VerilogStmtSeq *stmts, VerilogAttrStmtSeq *attr_stmts, int line) { - const std::string module_name = moduleVerilogToSta(*module_vname); - Cell *cell = network_->findCell(library_, module_name.c_str()); + const std::string module_name = moduleVerilogToSta(std::move(module_vname)); + Cell *cell = network_->findCell(library_, module_name); if (cell) { VerilogModule *module = module_map_[cell]; delete module; @@ -207,23 +183,23 @@ VerilogReader::makeModule(const std::string *module_vname, network_->deleteCell(cell); } - VerilogModule *module = new VerilogModule(module_name.c_str(), ports, stmts, + VerilogModule *module = new VerilogModule(module_name, ports, stmts, attr_stmts, filename_, line, this); - cell = network_->makeCell(library_, module_name.c_str(), false, filename_.c_str()); + cell = network_->makeCell(library_, module_name, false, filename_); - for (VerilogAttrStmt *stmt : *attr_stmts) { - for (VerilogAttrEntry *entry : *stmt->attrs()) - network_->setAttribute(cell, entry->key(), entry->value()); + if (attr_stmts) { + for (VerilogAttrStmt *stmt : *attr_stmts) { + for (VerilogAttrEntry *entry : *stmt->attrs()) + network_->setAttribute(cell, entry->key(), entry->value()); + } } module_map_[cell] = module; makeCellPorts(cell, module, ports); - module_count_++; - delete module_vname; } void -VerilogReader::makeModule(const std::string *module_name, +VerilogReader::makeModule(std::string &&module_vname, VerilogStmtSeq *port_dcls, VerilogStmtSeq *stmts, VerilogAttrStmtSeq *attr_stmts, @@ -243,7 +219,7 @@ VerilogReader::makeModule(const std::string *module_name, } } delete port_dcls; - makeModule(module_name, ports, stmts, attr_stmts, line); + makeModule(std::move(module_vname), ports, stmts, attr_stmts, line); } void @@ -265,8 +241,7 @@ VerilogReader::makeCellPorts(Cell *cell, } else warn(165, module->filename(), module->line(), - "module {} repeated port name {}.", module->name().c_str(), - port_name.c_str()); + "module {} repeated port name {}.", module->name(), port_name); } checkModuleDcls(module, port_names); } @@ -276,22 +251,22 @@ VerilogReader::makeCellPort(Cell *cell, VerilogModule *module, const std::string &port_name) { - VerilogDcl *dcl = module->declaration(port_name.c_str()); + VerilogDcl *dcl = module->declaration(port_name); if (dcl) { PortDirection *dir = dcl->direction(); VerilogDclBus *dcl_bus = dynamic_cast(dcl); Port *port = dcl->isBus() - ? network_->makeBusPort(cell, port_name.c_str(), dcl_bus->fromIndex(), + ? network_->makeBusPort(cell, port_name, dcl_bus->fromIndex(), dcl_bus->toIndex()) - : network_->makePort(cell, port_name.c_str()); + : network_->makePort(cell, port_name); network_->setDirection(port, dir); return port; } else { warn(166, module->filename(), module->line(), - "module {} missing declaration for port {}.", module->name().c_str(), - port_name.c_str()); - return network_->makePort(cell, port_name.c_str()); + "module {} missing declaration for port {}.", + module->name(), port_name); + return network_->makePort(cell, port_name); } } @@ -311,7 +286,7 @@ VerilogReader::makeNamedPortRefCellPorts(Cell *cell, } delete net_name_iter; // Note that the bundle does NOT have a port declaration. - network_->makeBundlePort(cell, mod_port->name().c_str(), member_ports); + network_->makeBundlePort(cell, mod_port->name(), member_ports); } // Make sure each declaration appears in the module port list. @@ -347,12 +322,10 @@ VerilogReader::makeDcl(PortDirection *dir, } else { delete arg; - dcl_arg_count_--; } } delete args; if (assign_args) { - dcl_count_++; return new VerilogDcl(dir, assign_args, attr_stmts, line); } else { @@ -362,7 +335,6 @@ VerilogReader::makeDcl(PortDirection *dir, } } else { - dcl_count_++; return new VerilogDcl(dir, args, attr_stmts, line); } } @@ -373,7 +345,6 @@ VerilogReader::makeDcl(PortDirection *dir, VerilogAttrStmtSeq *attr_stmts, int line) { - dcl_count_++; return new VerilogDcl(dir, arg, attr_stmts, line); } @@ -385,7 +356,6 @@ VerilogReader::makeDclBus(PortDirection *dir, VerilogAttrStmtSeq *attr_stmts, int line) { - dcl_bus_count_++; return new VerilogDclBus(dir, from_index, to_index, arg, attr_stmts, line); } @@ -397,72 +367,55 @@ VerilogReader::makeDclBus(PortDirection *dir, VerilogAttrStmtSeq *attr_stmts, int line) { - dcl_bus_count_++; return new VerilogDclBus(dir, from_index, to_index, args, attr_stmts, line); } VerilogDclArg * -VerilogReader::makeDclArg(const std::string *net_vname) +VerilogReader::makeDclArg(std::string &&net_vname) { - dcl_arg_count_++; - const std::string net_name = netVerilogToSta(*net_vname); + const std::string net_name = netVerilogToSta(std::move(net_vname)); VerilogDclArg *dcl = new VerilogDclArg(net_name); - delete net_vname; return dcl; } VerilogDclArg * VerilogReader::makeDclArg(VerilogAssign *assign) { - dcl_arg_count_++; return new VerilogDclArg(assign); } VerilogNetPartSelect * -VerilogReader::makeNetPartSelect(const std::string *net_vname, +VerilogReader::makeNetPartSelect(std::string &&net_vname, int from_index, int to_index) { - net_part_select_count_++; - if (report_stmt_stats_) - net_bus_names_ += net_vname->size() + 1; - const std::string net_name = netVerilogToSta(*net_vname); + const std::string net_name = netVerilogToSta(std::move(net_vname)); VerilogNetPartSelect *select = new VerilogNetPartSelect(net_name, from_index, to_index); - delete net_vname; return select; } VerilogNetConstant * -VerilogReader::makeNetConstant(const std::string *constant, +VerilogReader::makeNetConstant(std::string &&constant, int line) { - net_constant_count_++; - return new VerilogNetConstant(constant, this, line); + return new VerilogNetConstant(std::move(constant), this, line); } VerilogNetScalar * -VerilogReader::makeNetScalar(const std::string *net_vname) +VerilogReader::makeNetScalar(std::string &&net_vname) { - net_scalar_count_++; - if (report_stmt_stats_) - net_scalar_names_ += net_vname->size() + 1; - const std::string net_name = netVerilogToSta(*net_vname); + const std::string net_name = netVerilogToSta(std::move(net_vname)); VerilogNetScalar *scalar = new VerilogNetScalar(net_name); - delete net_vname; return scalar; } VerilogNetBitSelect * -VerilogReader::makeNetBitSelect(const std::string *net_vname, +VerilogReader::makeNetBitSelect(std::string &&net_vname, int index) { - net_bit_select_count_++; - if (report_stmt_stats_) - net_bus_names_ += net_vname->size() + 1; - const std::string net_name = netVerilogToSta(*net_vname); + const std::string net_name = netVerilogToSta(std::move(net_vname)); VerilogNetBitSelect *select = new VerilogNetBitSelect(net_name, index); - delete net_vname; return select; } @@ -471,20 +424,19 @@ VerilogReader::makeAssign(VerilogNet *lhs, VerilogNet *rhs, int line) { - assign_count_++; return new VerilogAssign(lhs, rhs, line); } VerilogInst * -VerilogReader::makeModuleInst(const std::string *module_vname, - const std::string *inst_vname, +VerilogReader::makeModuleInst(std::string &&module_vname, + std::string &&inst_vname, VerilogNetSeq *pins, VerilogAttrStmtSeq *attr_stmts, const int line) { - const std::string module_name = moduleVerilogToSta(*module_vname); - const std::string inst_name = instanceVerilogToSta(*inst_vname); - Cell *cell = network_->findAnyCell(module_name.c_str()); + const std::string module_name = moduleVerilogToSta(std::move(module_vname)); + const std::string inst_name = instanceVerilogToSta(std::move(inst_vname)); + Cell *cell = network_->findAnyCell(module_name); LibertyCell *liberty_cell = nullptr; if (cell) liberty_cell = network_->libertyCell(cell); @@ -496,8 +448,8 @@ VerilogReader::makeModuleInst(const std::string *module_vname, for (VerilogNet *vnet : *pins) { VerilogNetPortRefScalarNet *vpin = dynamic_cast(vnet); - const char *port_name = vpin->name().c_str(); - const std::string &net_name = vpin->netName(); + std::string_view port_name = vpin->name(); + std::string_view net_name = vpin->netName(); Port *port = network_->findPort(cell, port_name); LibertyPort *lport = network_->libertyPort(port); if (lport->isBus()) { @@ -507,30 +459,15 @@ VerilogReader::makeModuleInst(const std::string *module_vname, int pin_index = lport->pinIndex(); net_names[pin_index] = net_name; delete vpin; - net_port_ref_scalar_net_count_--; } VerilogInst *inst = new VerilogLibertyInst(liberty_cell, inst_name, net_names, attr_stmts, line); delete pins; - if (report_stmt_stats_) { - inst_names_ += inst_name.size() + 1; - inst_lib_count_++; - inst_lib_net_arrays_ += port_count; - } - delete module_vname; - delete inst_vname; return inst; } else { - VerilogInst *inst = new VerilogModuleInst(module_name.c_str(), inst_name.c_str(), + VerilogInst *inst = new VerilogModuleInst(module_name, inst_name, pins, attr_stmts, line); - if (report_stmt_stats_) { - inst_module_names_ += module_name.size() + 1; - inst_names_ += inst_name.size() + 1; - inst_mod_count_++; - } - delete module_vname; - delete inst_vname; return inst; } } @@ -541,7 +478,7 @@ VerilogReader::hasScalarNamedPortRefs(LibertyCell *liberty_cell, { if (pins && pins->size() > 0 && (*pins)[0]->isNamedPortRef()) { for (VerilogNet *vpin : *pins) { - const char *port_name = vpin->name().c_str(); + std::string_view port_name = vpin->name(); LibertyPort *port = liberty_cell->findLibertyPort(port_name); if (port) { if (!(port->size() == 1 && (vpin->isNamedPortRefScalarNet()))) @@ -557,142 +494,73 @@ VerilogReader::hasScalarNamedPortRefs(LibertyCell *liberty_cell, } VerilogNetPortRef * -VerilogReader::makeNetNamedPortRefScalarNet(const std::string *port_vname) +VerilogReader::makeNetNamedPortRefScalarNet(std::string &&port_vname) { - net_port_ref_scalar_net_count_++; - if (report_stmt_stats_) - port_names_ += port_vname->size() + 1; - const std::string port_name = portVerilogToSta(*port_vname); - VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name.c_str()); - delete port_vname; + const std::string port_name = portVerilogToSta(std::move(port_vname)); + VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name); return ref; } VerilogNetPortRef * -VerilogReader::makeNetNamedPortRefScalarNet(const std::string *port_vname, - const std::string *net_vname) +VerilogReader::makeNetNamedPortRefScalarNet(std::string &&port_vname, + std::string &&net_vname) { - net_port_ref_scalar_net_count_++; - if (report_stmt_stats_) { - if (net_vname) - net_scalar_names_ += net_vname->size() + 1; - port_names_ += port_vname->size() + 1; - } - const std::string port_name = portVerilogToSta(*port_vname); - const std::string net_name = netVerilogToSta(*net_vname); - VerilogNetPortRef *ref = - new VerilogNetPortRefScalarNet(port_name.c_str(), net_name.c_str()); - delete port_vname; - delete net_vname; + const std::string port_name = portVerilogToSta(std::move(port_vname)); + const std::string net_name = netVerilogToSta(std::move(net_vname)); + VerilogNetPortRef *ref = new VerilogNetPortRefScalarNet(port_name, net_name); return ref; } VerilogNetPortRef * -VerilogReader::makeNetNamedPortRefBitSelect(const std::string *port_vname, - const std::string *bus_vname, +VerilogReader::makeNetNamedPortRefBitSelect(std::string &&port_vname, + std::string &&bus_vname, int index) { - net_port_ref_scalar_net_count_++; - const std::string bus_name = portVerilogToSta(*bus_vname); + const std::string bus_name = portVerilogToSta(std::move(bus_vname)); const std::string net_name = verilogBusBitName(bus_name, index); - if (report_stmt_stats_) { - net_scalar_names_ += net_name.length() + 1; - port_names_ += port_vname->size() + 1; - } - const std::string port_name = portVerilogToSta(*port_vname); + const std::string port_name = portVerilogToSta(std::move(port_vname)); VerilogNetPortRef *ref = - new VerilogNetPortRefScalarNet(port_name.c_str(), net_name.c_str()); - delete port_vname; - delete bus_vname; + new VerilogNetPortRefScalarNet(port_name, net_name); return ref; } VerilogNetPortRef * -VerilogReader::makeNetNamedPortRefScalar(const std::string *port_vname, +VerilogReader::makeNetNamedPortRefScalar(std::string &&port_vname, VerilogNet *net) { - net_port_ref_scalar_count_++; - if (report_stmt_stats_) - port_names_ += port_vname->size() + 1; - const std::string port_name = portVerilogToSta(*port_vname); - VerilogNetPortRef *ref = new VerilogNetPortRefScalar(port_name.c_str(), net); - delete port_vname; + const std::string port_name = portVerilogToSta(std::move(port_vname)); + VerilogNetPortRef *ref = new VerilogNetPortRefScalar(port_name, net); return ref; } VerilogNetPortRef * -VerilogReader::makeNetNamedPortRefBit(const std::string *port_vname, +VerilogReader::makeNetNamedPortRefBit(std::string &&port_vname, int index, VerilogNet *net) { - net_port_ref_bit_count_++; - const std::string port_name = portVerilogToSta(*port_vname); - VerilogNetPortRef *ref = new VerilogNetPortRefBit(port_name.c_str(), index, net); - delete port_vname; + const std::string port_name = portVerilogToSta(std::move(port_vname)); + VerilogNetPortRef *ref = new VerilogNetPortRefBit(port_name, index, net); return ref; } VerilogNetPortRef * -VerilogReader::makeNetNamedPortRefPart(const std::string *port_vname, +VerilogReader::makeNetNamedPortRefPart(std::string &&port_vname, int from_index, int to_index, VerilogNet *net) { - net_port_ref_part_count_++; - const std::string port_name = portVerilogToSta(*port_vname); + const std::string port_name = portVerilogToSta(std::move(port_vname)); VerilogNetPortRef *ref = new VerilogNetPortRefPart(port_name, from_index, to_index, net); - delete port_vname; return ref; } VerilogNetConcat * VerilogReader::makeNetConcat(VerilogNetSeq *nets) { - concat_count_++; return new VerilogNetConcat(nets); } -#define printClassMemory(name, class_name, count) \ - report_->report(" {:<20} {:9} * {:3} = {:6.1f}Mb\n", name, count, \ - sizeof(class_name), (count * sizeof(class_name) * 1e-6)) - -#define printStringMemory(name, count) \ - report_->report(" {:<20} {:6.1f}Mb", name, count * 1e-6) - -void -VerilogReader::reportStmtCounts() -{ - if (debug_->check("verilog", 1)) { - report_->report("Verilog stats"); - printClassMemory("modules", VerilogModule, module_count_); - printClassMemory("module insts", VerilogModuleInst, inst_mod_count_); - printClassMemory("liberty insts", VerilogLibertyInst, inst_lib_count_); - printClassMemory("liberty net arrays", char *, inst_lib_net_arrays_); - printClassMemory("declarations", VerilogDcl, dcl_count_); - printClassMemory("bus declarations", VerilogDclBus, dcl_bus_count_); - printClassMemory("declaration args", VerilogDclArg, dcl_arg_count_); - printClassMemory("port ref scalar", VerilogNetPortRefScalar, - net_port_ref_scalar_count_); - printClassMemory("port ref scalar net", VerilogNetPortRefScalarNet, - net_port_ref_scalar_net_count_); - printClassMemory("port ref bit", VerilogNetPortRefBit, net_port_ref_bit_count_); - printClassMemory("port ref part", VerilogNetPortRefPart, - net_port_ref_part_count_); - printClassMemory("scalar nets", VerilogNetScalar, net_scalar_count_); - printClassMemory("bus bit nets", VerilogNetBitSelect, net_bit_select_count_); - printClassMemory("bus range nets", VerilogNetPartSelect, net_part_select_count_); - printClassMemory("constant nets", VerilogNetConstant, net_constant_count_); - printClassMemory("concats", VerilogNetConcat, concat_count_); - printClassMemory("assigns", VerilogAssign, assign_count_); - printStringMemory("instance names", inst_names_); - printStringMemory("instance mod names", inst_module_names_); - printStringMemory("port names", port_names_); - printStringMemory("net scalar names", net_scalar_names_); - printStringMemory("net bus names", net_bus_names_); - } -} - //////////////////////////////////////////////////////////////// VerilogModule::VerilogModule(const std::string &name, @@ -741,35 +609,35 @@ VerilogModule::parseDcl(VerilogDcl *dcl, for (VerilogDclArg *arg : *dcl->args()) { if (arg->isNamed()) { const std::string &net_name = arg->netName(); - VerilogDcl *existing_dcl = dcl_map_[net_name.c_str()]; + VerilogDcl *existing_dcl = dcl_map_[net_name]; if (existing_dcl) { PortDirection *existing_dir = existing_dcl->direction(); if (existing_dir->isInternal()) // wire dcl can be used as modifier for input/inout dcls. // Ignore the wire dcl. - dcl_map_[net_name.c_str()] = dcl; + dcl_map_[net_name] = dcl; else if (dcl->direction()->isTristate()) { if (existing_dir->isOutput()) // tri dcl can be used as modifier for input/output/inout dcls. // Keep the tristate dcl for outputs because it is more specific // but ignore it for inputs and bidirs. - dcl_map_[net_name.c_str()] = dcl; + dcl_map_[net_name] = dcl; } else if (dcl->direction()->isPowerGround() && (existing_dir->isOutput() || existing_dir->isInput() || existing_dir->isBidirect())) // supply0/supply1 dcl can be used as modifier for // input/output/inout dcls. - dcl_map_[net_name.c_str()] = dcl; + dcl_map_[net_name] = dcl; else if (!dcl->direction()->isInternal()) { - std::string net_vname = netVerilogName(net_name.c_str()); + std::string net_vname = netVerilogName(net_name); reader->warn(1395, filename_, dcl->line(), "signal {} previously declared on line {}.", net_vname, existing_dcl->line()); } } else - dcl_map_[net_name.c_str()] = dcl; + dcl_map_[net_name] = dcl; } } } @@ -788,7 +656,7 @@ VerilogModule::checkInstanceName(VerilogInst *inst, do { replacement_name = sta::format("{}_{}", inst_name, i++); } while (inst_names.contains(replacement_name)); - std::string inst_vname = instanceVerilogName(inst_name.c_str()); + std::string inst_vname = instanceVerilogName(inst_name); reader->warn(1396, filename_, inst->line(), "instance name {} duplicated - renamed to {}.", inst_vname, replacement_name); @@ -799,9 +667,9 @@ VerilogModule::checkInstanceName(VerilogInst *inst, } VerilogDcl * -VerilogModule::declaration(const std::string &net_name) +VerilogModule::declaration(std::string_view net_name) { - return findKey(dcl_map_, net_name.c_str()); + return findStringKey(dcl_map_, net_name); } //////////////////////////////////////////////////////////////// @@ -1090,7 +958,7 @@ static std::string verilogBusBitName(const std::string &bus_name, int index) { - return sta::format("{}[{}]", bus_name.c_str(), index); + return sta::format("{}[{}]", bus_name, index); } class VerilogConstantNetNameIterator : public VerilogNetNameIterator @@ -1212,7 +1080,7 @@ VerilogNetScalar::VerilogNetScalar(const std::string &name) : } static int -verilogNetScalarSize(const char *name, +verilogNetScalarSize(std::string_view name, VerilogModule *module) { VerilogDcl *dcl = module->declaration(name); @@ -1226,7 +1094,7 @@ verilogNetScalarSize(const char *name, int VerilogNetScalar::size(VerilogModule *module) { - return verilogNetScalarSize(name_.c_str(), module); + return verilogNetScalarSize(name_, module); } static VerilogNetNameIterator * @@ -1248,7 +1116,7 @@ VerilogNetNameIterator * VerilogNetScalar::nameIterator(VerilogModule *module, VerilogReader *) { - return verilogNetScalarNameIterator(name_.c_str(), module); + return verilogNetScalarNameIterator(name_, module); } VerilogNetBitSelect::VerilogNetBitSelect(const std::string &name, @@ -1294,10 +1162,10 @@ VerilogNetNameIterator * VerilogNetPartSelect::nameIterator(VerilogModule *, VerilogReader *) { - return new VerilogBusNetNameIterator(name_.c_str(), from_index_, to_index_); + return new VerilogBusNetNameIterator(name_, from_index_, to_index_); } -VerilogNetConstant::VerilogNetConstant(const std::string *constant, +VerilogNetConstant::VerilogNetConstant(std::string constant, VerilogReader *reader, int line) { @@ -1305,13 +1173,13 @@ VerilogNetConstant::VerilogNetConstant(const std::string *constant, } void -VerilogNetConstant::parseConstant(const std::string *constant, +VerilogNetConstant::parseConstant(const std::string &constant, VerilogReader *reader, int line) { // Find constant size. - size_t csize_end = constant->find('\''); - std::string csize = constant->substr(0, csize_end); + size_t csize_end = constant.find('\''); + std::string csize = constant.substr(0, csize_end); // Read the constant size. size_t size = std::stol(csize); @@ -1319,7 +1187,7 @@ VerilogNetConstant::parseConstant(const std::string *constant, // Read the constant base. size_t base_idx = csize_end + 1; - char base = constant->at(base_idx); + char base = constant.at(base_idx); switch (base) { case 'b': case 'B': @@ -1343,11 +1211,10 @@ VerilogNetConstant::parseConstant(const std::string *constant, "unknown constant base."); break; } - delete constant; } void -VerilogNetConstant::parseConstant(const std::string *constant, +VerilogNetConstant::parseConstant(const std::string &constant, size_t base_idx, int base, int digit_bit_count) @@ -1358,9 +1225,9 @@ VerilogNetConstant::parseConstant(const std::string *constant, char *end; value_digit_str[1] = '\0'; size_t bit = 0; - size_t idx = constant->size() - 1; + size_t idx = constant.size() - 1; while (bit < size) { - char ch = (idx > base_idx) ? constant->at(idx--) : '0'; + char ch = (idx > base_idx) ? constant.at(idx--) : '0'; // Skip underscores. if (ch != '_') { value_digit_str[0] = ch; @@ -1376,15 +1243,15 @@ VerilogNetConstant::parseConstant(const std::string *constant, } void -VerilogNetConstant::parseConstant10(const std::string *constant, +VerilogNetConstant::parseConstant10(const std::string &constant, size_t base_idx, VerilogReader *reader, int line) { // Copy the constant skipping underscores. std::string tmp; - for (size_t i = base_idx + 1; i < constant->size(); i++) { - char ch = constant->at(i); + for (size_t i = base_idx + 1; i < constant.size(); i++) { + char ch = constant.at(i); if (ch != '_') tmp += ch; } @@ -1587,47 +1454,48 @@ VerilogAttrStmt::attrs() //////////////////////////////////////////////////////////////// // Verilog net name to network net map. -using BindingMap = std::map; +using BindingMap = std::map>; class VerilogBindingTbl { public: VerilogBindingTbl(const std::string &zero_net_name_, const std::string &one_net_name_); - Net *ensureNetBinding(const char *net_name, + Net *ensureNetBinding(std::string_view net_name, Instance *inst, NetworkReader *network); - Net *find(const char *name, + Net *find(std::string_view name, NetworkReader *network); - void bind(const char *name, + void bind(std::string_view name, Net *net); private: const std::string &zero_net_name_; const std::string &one_net_name_; - BindingMap map_; + BindingMap net_map_; }; Instance * -VerilogReader::linkNetwork(const char *top_cell_name, +VerilogReader::linkNetwork(std::string_view top_cell_name, bool make_black_boxes, bool delete_modules) { if (library_) { - Cell *top_cell = network_->findCell(library_, top_cell_name); + const std::string top_cell_str(top_cell_name); + Cell *top_cell = network_->findCell(library_, top_cell_str); VerilogModule *module = this->module(top_cell); if (module) { // Seed the recursion for expansion with the top level instance. Instance *top_instance = - network_->makeInstance(top_cell, top_cell_name, nullptr); + network_->makeInstance(top_cell, top_cell_str, nullptr); VerilogBindingTbl bindings(zero_net_name_, one_net_name_); for (VerilogNet *mod_port : *module->ports()) { VerilogNetNameIterator *net_name_iter = mod_port->nameIterator(module, this); while (net_name_iter->hasNext()) { const std::string &net_name = net_name_iter->next(); - Port *port = network_->findPort(top_cell, net_name.c_str()); + Port *port = network_->findPort(top_cell, net_name); Net *net = - bindings.ensureNetBinding(net_name.c_str(), top_instance, network_); + bindings.ensureNetBinding(net_name, top_instance, network_); // Guard against repeated port name. if (network_->findPin(top_instance, port) == nullptr) { Pin *pin = network_->makePin(top_instance, port, nullptr); @@ -1680,12 +1548,12 @@ VerilogReader::makeModuleInstBody(VerilogModule *module, mergeAssignNet(assign, module, inst, bindings); if (dir->isGround()) { Net *net = - bindings->ensureNetBinding(arg->netName().c_str(), inst, network_); + bindings->ensureNetBinding(arg->netName(), inst, network_); network_->addConstantNet(net, LogicValue::zero); } if (dir->isPower()) { Net *net = - bindings->ensureNetBinding(arg->netName().c_str(), inst, network_); + bindings->ensureNetBinding(arg->netName(), inst, network_); network_->addConstantNet(net, LogicValue::one); } } @@ -1703,9 +1571,9 @@ VerilogReader::makeModuleInstNetwork(VerilogModuleInst *mod_inst, bool make_black_boxes) { const std::string &module_name = mod_inst->moduleName(); - Cell *cell = network_->findAnyCell(module_name.c_str()); + Cell *cell = network_->findAnyCell(module_name); if (cell == nullptr) { - std::string inst_vname = instanceVerilogName(mod_inst->instanceName().c_str()); + std::string inst_vname = instanceVerilogName(mod_inst->instanceName()); if (make_black_boxes) { cell = makeBlackBox(mod_inst, parent_module); linkWarn(198, parent_module->filename(), mod_inst->line(), @@ -1722,7 +1590,7 @@ VerilogReader::makeModuleInstNetwork(VerilogModuleInst *mod_inst, if (lib_cell) cell = network_->cell(lib_cell); Instance *inst = - network_->makeInstance(cell, mod_inst->instanceName().c_str(), parent); + network_->makeInstance(cell, mod_inst->instanceName(), parent); VerilogAttrStmtSeq *attr_stmts = mod_inst->attrStmts(); for (VerilogAttrStmt *stmt : *attr_stmts) { for (VerilogAttrEntry *entry : *stmt->attrs()) { @@ -1765,10 +1633,10 @@ VerilogReader::makeNamedInstPins(Cell *cell, VerilogBindingTbl *parent_bindings, bool is_leaf) { - std::string inst_vname = instanceVerilogName(mod_inst->instanceName().c_str()); + std::string inst_vname = instanceVerilogName(mod_inst->instanceName()); for (auto mpin : *mod_inst->pins()) { VerilogNetPortRef *vpin = dynamic_cast(mpin); - const char *port_name = vpin->name().c_str(); + const std::string &port_name = vpin->name(); Port *port = network_->findPort(cell, port_name); if (port) { if (vpin->hasNet() && network_->size(port) != vpin->size(parent_module)) { @@ -1819,7 +1687,7 @@ VerilogReader::makeOrderedInstPins(Cell *cell, VerilogNet *net = *pin_iter++; Port *port = port_iter->next(); if (network_->size(port) != net->size(parent_module)) { - std::string inst_vname = instanceVerilogName(mod_inst->instanceName().c_str()); + std::string inst_vname = instanceVerilogName(mod_inst->instanceName()); linkWarn(202, parent_module->filename(), mod_inst->line(), "instance {} port {} size {} does not match net size {}.", inst_vname, network_->name(port), network_->size(port), @@ -1871,7 +1739,7 @@ VerilogReader::makeInstPin(Instance *inst, { Net *net = nullptr; if (!net_name.empty()) - net = parent_bindings->ensureNetBinding(net_name.c_str(), parent, network_); + net = parent_bindings->ensureNetBinding(net_name, parent, network_); if (is_leaf) { // Connect leaf pin to net. if (net) @@ -1883,7 +1751,7 @@ VerilogReader::makeInstPin(Instance *inst, Pin *pin = network_->findPin(inst, port); if (net) { network_->connect(inst, port, net); - const char *port_name = network_->name(port); + std::string port_name = network_->name(port); Net *child_net = bindings->ensureNetBinding(port_name, inst, network_); network_->makeTerm(pin, child_net); } @@ -1899,7 +1767,7 @@ VerilogReader::makeLibertyInst(VerilogLibertyInst *lib_inst, LibertyCell *lib_cell = lib_inst->cell(); Cell *cell = reinterpret_cast(lib_cell); Instance *inst = - network_->makeInstance(cell, lib_inst->instanceName().c_str(), parent); + network_->makeInstance(cell, lib_inst->instanceName(), parent); VerilogAttrStmtSeq *attr_stmts = lib_inst->attrStmts(); for (VerilogAttrStmt *stmt : *attr_stmts) { for (VerilogAttrEntry *entry : *stmt->attrs()) { @@ -1921,10 +1789,10 @@ VerilogReader::makeLibertyInst(VerilogLibertyInst *lib_inst, VerilogDclBus *dcl_bus = dynamic_cast(dcl); // Bus is only 1 bit wide. std::string bus_name = verilogBusBitName(net_name, dcl_bus->fromIndex()); - net = parent_bindings->ensureNetBinding(bus_name.c_str(), parent, network_); + net = parent_bindings->ensureNetBinding(bus_name, parent, network_); } else - net = parent_bindings->ensureNetBinding(net_name.c_str(), parent, network_); + net = parent_bindings->ensureNetBinding(net_name, parent, network_); network_->makePin(inst, reinterpret_cast(port), net); } else @@ -1940,7 +1808,7 @@ VerilogReader::makeBlackBox(VerilogModuleInst *mod_inst, VerilogModule *parent_module) { const std::string &module_name = mod_inst->moduleName(); - Cell *cell = network_->makeCell(library_, module_name.c_str(), true, + Cell *cell = network_->makeCell(library_, module_name, true, parent_module->filename()); if (mod_inst->namedPins()) makeBlackBoxNamedPorts(cell, mod_inst, parent_module); @@ -1956,7 +1824,7 @@ VerilogReader::makeBlackBoxNamedPorts(Cell *cell, { for (VerilogNet *mpin : *mod_inst->pins()) { VerilogNetNamed *vpin = dynamic_cast(mpin); - const char *port_name = vpin->name().c_str(); + const std::string &port_name = vpin->name(); size_t size = vpin->size(parent_module); Port *port = (size == 1) ? network_->makePort(cell, port_name) : network_->makeBusPort(cell, port_name, 0, size - 1); @@ -1976,8 +1844,8 @@ VerilogReader::makeBlackBoxOrderedPorts(Cell *cell, size_t size = net->size(parent_module); std::string port_name = format("p_{}", port_index); Port *port = (size == 1) - ? network_->makePort(cell, port_name.c_str()) - : network_->makeBusPort(cell, port_name.c_str(), size - 1, 0); + ? network_->makePort(cell, port_name) + : network_->makeBusPort(cell, port_name, size - 1, 0); network_->setDirection(port, PortDirection::unknown()); port_index++; } @@ -2006,8 +1874,8 @@ VerilogReader::mergeAssignNet(VerilogAssign *assign, while (lhs_iter->hasNext() && rhs_iter->hasNext()) { const std::string &lhs_name = lhs_iter->next(); const std::string &rhs_name = rhs_iter->next(); - Net *lhs_net = bindings->ensureNetBinding(lhs_name.c_str(), inst, network_); - Net *rhs_net = bindings->ensureNetBinding(rhs_name.c_str(), inst, network_); + Net *lhs_net = bindings->ensureNetBinding(lhs_name, inst, network_); + Net *rhs_net = bindings->ensureNetBinding(rhs_name, inst, network_); // Merge lower level net into higher level net so that deleting // instances from the bottom up does not reference deleted nets // by referencing the mergedInto field. @@ -2053,34 +1921,35 @@ VerilogBindingTbl::VerilogBindingTbl(const std::string &zero_net_name, // binding tables up the call tree when nodes are merged // because the name changes up the hierarchy. Net * -VerilogBindingTbl::find(const char *name, +VerilogBindingTbl::find(std::string_view name, NetworkReader *network) { - Net *net = findKey(map_, name); + Net *net = findStringKey(net_map_, name); while (net && network->mergedInto(net)) net = network->mergedInto(net); return net; } void -VerilogBindingTbl::bind(const char *name, +VerilogBindingTbl::bind(std::string_view name, Net *net) { - map_[name] = net; + net_map_[std::string(name)] = net; } Net * -VerilogBindingTbl::ensureNetBinding(const char *net_name, +VerilogBindingTbl::ensureNetBinding(std::string_view net_name, Instance *inst, NetworkReader *network) { Net *net = find(net_name, network); if (net == nullptr) { - net = network->makeNet(net_name, inst); - map_[network->name(net)] = net; - if (net_name == zero_net_name_) + const std::string net_str(net_name); + net = network->makeNet(net_str, inst); + net_map_[std::string(network->name(net))] = net; + if (net_str == zero_net_name_) network->addConstantNet(net, LogicValue::zero); - if (net_name == one_net_name_) + if (net_str == one_net_name_) network->addConstantNet(net, LogicValue::one); } return net; @@ -2109,7 +1978,7 @@ VerilogReader::reportLinkErrors() //////////////////////////////////////////////////////////////// VerilogScanner::VerilogScanner(std::istream *stream, - const char *filename, + std::string_view filename, Report *report) : yyFlexLexer(stream), filename_(filename), @@ -2118,7 +1987,7 @@ VerilogScanner::VerilogScanner(std::istream *stream, } void -VerilogScanner::error(const char *msg) +VerilogScanner::error(std::string_view msg) { report_->fileError(1870, filename_, lineno(), "{}", msg); } diff --git a/verilog/VerilogReaderPvt.hh b/verilog/VerilogReaderPvt.hh index 7a445ba4..fc5381f8 100644 --- a/verilog/VerilogReaderPvt.hh +++ b/verilog/VerilogReaderPvt.hh @@ -32,7 +32,7 @@ namespace sta { -using VerilogDclMap = std::map; +using VerilogDclMap = std::map>; using VerilogConstantValue = std::vector; class VerilogStmt @@ -63,10 +63,10 @@ public: VerilogReader *reader); ~VerilogModule() override; const std::string &name() { return name_; } - const char *filename() { return filename_.c_str(); } + const std::string &filename() { return filename_; } VerilogAttrStmtSeq *attrStmts() { return attr_stmts_; } VerilogNetSeq *ports() { return ports_; } - VerilogDcl *declaration(const std::string &net_name); + VerilogDcl *declaration(std::string_view net_name); VerilogStmtSeq *stmts() { return stmts_; } VerilogDclMap *declarationMap() { return &dcl_map_; } void parseDcl(VerilogDcl *dcl, @@ -313,7 +313,7 @@ private: class VerilogNetConstant : public VerilogNetUnnamed { public: - VerilogNetConstant(const std::string *constant, + VerilogNetConstant(std::string constant, VerilogReader *reader, int line); ~VerilogNetConstant() override; @@ -322,14 +322,14 @@ public: VerilogReader *reader) override; private: - void parseConstant(const std::string *constant, + void parseConstant(const std::string &constant, VerilogReader *reader, int line); - void parseConstant(const std::string *constant, + void parseConstant(const std::string &constant, size_t base_idx, int base, int digit_bit_count); - void parseConstant10(const std::string *constant, + void parseConstant10(const std::string &constant, size_t base_idx, VerilogReader *reader, int line); diff --git a/verilog/VerilogScanner.hh b/verilog/VerilogScanner.hh index 1776062c..3c0c5d61 100644 --- a/verilog/VerilogScanner.hh +++ b/verilog/VerilogScanner.hh @@ -24,6 +24,9 @@ #pragma once +#include +#include + #include "VerilogLocation.hh" #include "VerilogParse.hh" @@ -41,7 +44,7 @@ class VerilogScanner : public VerilogFlexLexer { public: VerilogScanner(std::istream *stream, - const char *filename, + std::string_view filename, Report *report); virtual ~VerilogScanner() {} @@ -50,14 +53,16 @@ public: // YY_DECL defined in VerilogLex.ll // Method body created by flex in VerilogLex.cc - void error(const char *msg); + void error(std::string_view msg); // Get rid of override virtual function warning. using yyFlexLexer::yylex; private: - const char *filename_; + std::string filename_; Report *report_; + // Quoted string accumulation (see VerilogLex.ll). + std::string token_; }; } // namespace diff --git a/verilog/VerilogWriter.cc b/verilog/VerilogWriter.cc index 3531b865..8edaf699 100644 --- a/verilog/VerilogWriter.cc +++ b/verilog/VerilogWriter.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include "Error.hh" #include "Format.hh" @@ -142,9 +143,9 @@ VerilogWriter::findHierChildren() sort(children, [this](const Instance *inst1, const Instance *inst2) { - const char *cell_name1 = network_->cellName(inst1); - const char *cell_name2 = network_->cellName(inst2); - return stringLess(cell_name1, cell_name2); + std::string cell_name1 = network_->cellName(inst1); + std::string cell_name2 = network_->cellName(inst2); + return cell_name1 < cell_name2; }); return children; @@ -173,7 +174,7 @@ void VerilogWriter::writeModule(const Instance *inst) { Cell *cell = network_->cell(inst); - std::string cell_vname = cellVerilogName(network_->name(cell)); + std::string cell_vname = cellVerilogName(std::string(network_->name(cell))); sta::print(stream_, "module {} (", cell_vname); writePorts(cell); writePortDcls(cell); @@ -196,7 +197,7 @@ VerilogWriter::writePorts(const Cell *cell) || !network_->direction(port)->isPowerGround()) { if (!first) sta::print(stream_, ",\n "); - std::string verilog_name = portVerilogName(network_->name(port)); + std::string verilog_name = portVerilogName(std::string(network_->name(port))); sta::print(stream_, "{}", verilog_name); first = false; } @@ -214,7 +215,7 @@ VerilogWriter::writePortDcls(const Cell *cell) PortDirection *dir = network_->direction(port); if (include_pwr_gnd_ || !network_->direction(port)->isPowerGround()) { - std::string port_vname = portVerilogName(network_->name(port)); + std::string port_vname = portVerilogName(std::string(network_->name(port))); const char *vtype = verilogPortDir(dir); if (vtype) { sta::print(stream_, " {}", vtype); @@ -274,7 +275,7 @@ VerilogWriter::writeWireDcls(const Instance *inst) Net *net = net_iter->next(); if (include_pwr_gnd_ || !(network_->isPower(net) || network_->isGround(net))) { - const char *net_name = network_->name(net); + std::string net_name = network_->name(net); if (network_->findPort(cell, net_name) == nullptr) { if (isBusName(net_name, '[', ']', escape)) { bool is_bus; @@ -286,7 +287,7 @@ VerilogWriter::writeWireDcls(const Instance *inst) range.second = std::min(range.second, index); } else { - std::string net_vname = netVerilogName(net_name); + std::string net_vname = netVerilogName(std::string(net_name)); sta::print(stream_, " wire {};\n", net_vname); } } @@ -294,8 +295,7 @@ VerilogWriter::writeWireDcls(const Instance *inst) } delete net_iter; - for (const auto& [bus_name1, range] : bus_ranges) { - const char *bus_name = bus_name1.c_str(); + for (const auto& [bus_name, range] : bus_ranges) { std::string net_vname = netVerilogName(bus_name); sta::print(stream_, " wire [{}:{}] {};\n", range.first, @@ -322,7 +322,7 @@ VerilogWriter::writeChildren(const Instance *inst) sort(children, [this](const Instance *inst1, const Instance *inst2) { - return stringLess(network_->name(inst1), network_->name(inst2)); + return network_->name(inst1) < network_->name(inst2); }); for (auto child : children) @@ -334,9 +334,9 @@ VerilogWriter::writeChild(const Instance *child) { Cell *child_cell = network_->cell(child); if (!remove_cells_.contains(child_cell)) { - const char *child_name = network_->name(child); - std::string child_vname = instanceVerilogName(child_name); - std::string child_cell_vname = cellVerilogName(network_->name(child_cell)); + std::string child_name = network_->name(child); + std::string child_vname = instanceVerilogName(std::string(child_name)); + std::string child_cell_vname = cellVerilogName(std::string(network_->name(child_cell))); sta::print(stream_, " {} {} (", child_cell_vname, child_vname); @@ -366,11 +366,11 @@ VerilogWriter::writeInstPin(const Instance *inst, if (pin) { Net *net = network_->net(pin); if (net) { - const char *net_name = network_->name(net); - std::string net_vname = netVerilogName(net_name); + std::string net_name = network_->name(net); + std::string net_vname = netVerilogName(std::string(net_name)); if (!first_port) sta::print(stream_, ",\n "); - std::string port_vname = portVerilogName(network_->name(port)); + std::string port_vname = portVerilogName(std::string(network_->name(port))); sta::print(stream_, ".{}({})", port_vname, net_vname); @@ -387,7 +387,7 @@ VerilogWriter::writeInstBusPin(const Instance *inst, if (!first_port) sta::print(stream_, ",\n "); - std::string port_vname = portVerilogName(network_->name(port)); + std::string port_vname = portVerilogName(std::string(network_->name(port))); sta::print(stream_, ".{}({{", port_vname); first_port = false; bool first_member = true; @@ -422,11 +422,11 @@ VerilogWriter::writeInstBusPinBit(const Instance *inst, Pin *pin = network_->findPin(inst, port); Net *net = pin ? network_->net(pin) : nullptr; std::string net_name = net - ? network_->name(net) + ? std::string(network_->name(net)) // There is no verilog syntax to "skip" a bit in the concatentation. : sta::format("_NC{}", unconnected_net_index_++); - std::string net_vname = netVerilogName(net_name.c_str()); + std::string net_vname = netVerilogName(net_name); if (!first_member) sta::print(stream_, ",\n "); sta::print(stream_, "{}", net_vname); @@ -453,8 +453,8 @@ VerilogWriter::writeAssigns(const Instance *inst) || (include_pwr_gnd_ && network_->direction(port)->isPowerGround())) && !stringEqual(network_->name(port), network_->name(net))) { // Port name is different from net name. - std::string port_vname = netVerilogName(network_->name(port)); - std::string net_vname = netVerilogName(network_->name(net)); + std::string port_vname = netVerilogName(std::string(network_->name(port))); + std::string net_vname = netVerilogName(std::string(network_->name(net))); sta::print(stream_, " assign {} = {};\n", port_vname, net_vname); From ad80dd55b34f0094016c17069e7a180be6d4ac51 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sat, 28 Mar 2026 19:46:57 -0700 Subject: [PATCH 2/9] cmake show swig version Signed-off-by: James Cherry --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d843dcfe..d21e91e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -455,6 +455,7 @@ configure_file(${STA_HOME}/util/StaConfig.hh.cmake ########################################################### find_package(SWIG 3.0 REQUIRED) +message(STATUS "SWIG version: ${SWIG_VERSION}") include(UseSWIG) set(STA_SWIG_FILE app/StaApp.i) From 614385fe51570d1b40f6e9df59a6801f3c3de312 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sat, 28 Mar 2026 19:48:21 -0700 Subject: [PATCH 3/9] Liberty unnecessary move Signed-off-by: James Cherry --- liberty/LibertyParser.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/liberty/LibertyParser.cc b/liberty/LibertyParser.cc index 5ee1be81..446ce30d 100644 --- a/liberty/LibertyParser.cc +++ b/liberty/LibertyParser.cc @@ -172,9 +172,7 @@ LibertyParser::makeSimpleAttr(std::string &&name, const LibertyAttrValue *value, int line) { - LibertySimpleAttr *attr = new LibertySimpleAttr(std::move(name), - std::move(*value), - line); + LibertySimpleAttr *attr = new LibertySimpleAttr(std::move(name), *value, line); delete value; LibertyGroup *group = this->group(); group->addAttr(attr); @@ -194,8 +192,7 @@ LibertyParser::makeComplexAttr(std::string &&name, return nullptr; // Define is not a complex attr; already added to group } else { - LibertyComplexAttr *attr = - new LibertyComplexAttr(std::move(name), std::move(*values), line); + LibertyComplexAttr *attr = new LibertyComplexAttr(std::move(name), *values, line); delete values; LibertyGroup *group = this->group(); group->addAttr(attr); From 1806e4aede3b40a72f077d73028e23a2219ea944 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sat, 28 Mar 2026 19:55:13 -0700 Subject: [PATCH 4/9] StaTclTypes %include "std_string_view.i" Signed-off-by: James Cherry --- liberty/Liberty.i | 1 + search/Search.i | 1 + tcl/StaTclTypes.i | 11 +++++------ 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/liberty/Liberty.i b/liberty/Liberty.i index a87cd799..f0a9bc09 100644 --- a/liberty/Liberty.i +++ b/liberty/Liberty.i @@ -25,6 +25,7 @@ %module liberty %{ +#include "PatternMatch.hh" #include "PortDirection.hh" #include "Liberty.hh" #include "EquivCells.hh" diff --git a/search/Search.i b/search/Search.i index fe836156..f1617670 100644 --- a/search/Search.i +++ b/search/Search.i @@ -35,6 +35,7 @@ #include "Search.hh" #include "search/Levelize.hh" #include "search/ReportPath.hh" +#include "search/Tag.hh" #include "PathExpanded.hh" #include "Bfs.hh" #include "Scene.hh" diff --git a/tcl/StaTclTypes.i b/tcl/StaTclTypes.i index 5f2430e1..9157a3fc 100644 --- a/tcl/StaTclTypes.i +++ b/tcl/StaTclTypes.i @@ -23,24 +23,23 @@ // This notice may not be removed or altered from any source distribution. // Swig TCL input/output type parsers. + +#if SWIG_VERSION >= 0x040200 +%include "std_string_view.i" +#endif + %{ -#include "Machine.hh" -#include "StringUtil.hh" -#include "PatternMatch.hh" #include "Network.hh" #include "Liberty.hh" #include "FuncExpr.hh" #include "TimingArc.hh" -#include "TableModel.hh" #include "TimingRole.hh" #include "Graph.hh" -#include "NetworkClass.hh" #include "Clock.hh" #include "Scene.hh" #include "Search.hh" #include "Path.hh" -#include "search/Tag.hh" #include "PathEnd.hh" #include "SearchClass.hh" #include "CircuitSim.hh" From 3d0b34e88c4d4319d52fe85767ce9b2fe07715bc Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sun, 29 Mar 2026 09:58:06 -0700 Subject: [PATCH 5/9] ReportPath::reportLine Signed-off-by: James Cherry --- search/ReportPath.cc | 6 +++--- search/ReportPath.hh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/search/ReportPath.cc b/search/ReportPath.cc index 037d21cf..1ace1d08 100644 --- a/search/ReportPath.cc +++ b/search/ReportPath.cc @@ -2454,7 +2454,7 @@ ReportPath::reportPathLine(const Path *path, Slew slew = graph_->slew(vertex, rf, slew_index); float cap = field_blank_; Instance *inst = network_->instance(pin); - std::string src_attr = ""; + std::string src_attr; if (inst) src_attr = network_->getAttribute(inst, "src"); // Don't show capacitance field for input pins. @@ -2736,7 +2736,7 @@ ReportPath::reportPath6(const Path *path, bool is_clk_start = path1->vertex(this) == clk_start; bool is_clk = path1->isClock(search_); Instance *inst = network_->instance(pin); - std::string src_attr = ""; + std::string src_attr; if (inst) src_attr = network_->getAttribute(inst, "src"); // Always show the search start point (register clk pin). @@ -3187,7 +3187,7 @@ ReportPath::reportLine(std::string_view what, bool total_with_minus, const EarlyLate *early_late, const RiseFall *rf, - std::string src_attr, + std::string_view src_attr, std::string_view line_case) const { std::string line; diff --git a/search/ReportPath.hh b/search/ReportPath.hh index b27e5fc1..98b7dd23 100644 --- a/search/ReportPath.hh +++ b/search/ReportPath.hh @@ -369,7 +369,7 @@ protected: bool total_with_minus, const EarlyLate *early_late, const RiseFall *rf, - std::string src_attr, + std::string_view src_attr, std::string_view line_case) const; void reportLineTotal(std::string_view what, const Delay &incr, From 725a6e5e1c48950dbd892d0d57d41645cc95a63d Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sun, 29 Mar 2026 10:56:45 -0700 Subject: [PATCH 6/9] require cmake 3.16 Signed-off-by: James Cherry --- CMakeLists.txt | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d21e91e7..25b87766 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,15 +22,7 @@ # # This notice may not be removed or altered from any source distribution. -cmake_minimum_required (VERSION 3.10) -if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.13) -# Use standard target names -cmake_policy(SET CMP0078 NEW) -endif() -if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.14) -# Allows SWIG_MODULE_NAME to be set -cmake_policy(SET CMP0086 NEW) -endif() +cmake_minimum_required (VERSION 3.16) project(STA VERSION 3.1.0 LANGUAGES CXX From 5aa56bcfeea05d963d3c5655935516bc4e284389 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sun, 29 Mar 2026 11:23:26 -0700 Subject: [PATCH 7/9] cmake swig Signed-off-by: James Cherry --- CMakeLists.txt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 25b87766..3f5ef070 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -455,14 +455,12 @@ set(STA_SWIG_FILE app/StaApp.i) set_property(SOURCE ${STA_SWIG_FILE} PROPERTY CPLUSPLUS ON ) -# Ubuntu 18.04 cmake version 3.10.2 does not support the -# COMPILE_OPTIONS and INCLUDE_DIRECTORIES properties, so cram -# them into SWIG_FLAGS for the time being. +# SWIG flags (CMake UseSWIG). set_property(SOURCE ${STA_SWIG_FILE} - PROPERTY SWIG_FLAGS + PROPERTY COMPILE_OPTIONS -module sta - -namespace -prefix sta - -I${STA_HOME} + -namespace + -prefix sta ) set(SWIG_FILES @@ -519,6 +517,9 @@ target_include_directories(sta_swig ${CMAKE_CURRENT_BINARY_DIR}/include/sta ) +# Pass sta_swig include directories to SWIG as -I (same paths as the C++ build). +set_property(TARGET sta_swig PROPERTY SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE) + ########################################################### # Library ########################################################### From b5f647cb7f4439ef459b3bd2a8414c1925470deb Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Mon, 30 Mar 2026 19:44:26 +0000 Subject: [PATCH 8/9] update test infra to accomodate std::string instead of const char* Signed-off-by: dsengupta0628 --- graph/test/cpp/TestGraph.cc | 19 +- liberty/Liberty.cc | 4 +- liberty/LibertyParser.cc | 2 +- liberty/test/cpp/TestLibertyClasses.cc | 182 +++++------ network/test/cpp/TestNetwork.cc | 175 +++++----- parasitics/test/cpp/TestParasitics.cc | 94 +++--- power/test/cpp/TestPower.cc | 54 ++-- sdc/test/cpp/TestSdcClasses.cc | 427 +++++++++++++------------ sdf/test/cpp/TestSdf.cc | 102 +++--- search/test/cpp/TestSearchClasses.cc | 116 +++---- spice/test/cpp/TestSpice.cc | 40 +-- util/test/cpp/TestUtil.cc | 174 +--------- verilog/test/cpp/TestVerilog.cc | 4 +- 13 files changed, 617 insertions(+), 776 deletions(-) diff --git a/graph/test/cpp/TestGraph.cc b/graph/test/cpp/TestGraph.cc index 58b1e2c1..5650a1f9 100644 --- a/graph/test/cpp/TestGraph.cc +++ b/graph/test/cpp/TestGraph.cc @@ -953,8 +953,8 @@ TEST_F(GraphDesignTest, GraphVerticesAndEdges) { Vertex *vertex = graph->pinDrvrVertex(pin); if (vertex) { // Vertex::name needs network - const char *vname = vertex->name(network); - EXPECT_NE(vname, nullptr); + std::string vname = vertex->name(network); + EXPECT_FALSE(vname.empty()); found++; } } @@ -979,9 +979,8 @@ TEST_F(GraphDesignTest, VertexName) { if (y_pin) { Vertex *v = graph->pinDrvrVertex(y_pin); if (v) { - const char *name = v->name(network); - EXPECT_NE(name, nullptr); - EXPECT_NE(strlen(name), 0u); + std::string name = v->name(network); + EXPECT_FALSE(name.empty()); } } } @@ -1076,7 +1075,7 @@ protected: FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0f); waveform->push_back(5.0f); - sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, "", sta_->cmdMode()); Clock *clk = sta_->cmdSdc()->findClock("clk"); ASSERT_NE(clk, nullptr); @@ -1456,7 +1455,7 @@ protected: FloatSeq *wave1 = new FloatSeq; wave1->push_back(0.0f); wave1->push_back(5.0f); - sta_->makeClock("clk1", clk1_pins, false, 10.0f, wave1, nullptr, sta_->cmdMode()); + sta_->makeClock("clk1", clk1_pins, false, 10.0f, wave1, "", sta_->cmdMode()); // Create clock2 Pin *clk2_pin = network->findPin(top, "clk2"); @@ -1466,7 +1465,7 @@ protected: FloatSeq *wave2 = new FloatSeq; wave2->push_back(0.0f); wave2->push_back(2.5f); - sta_->makeClock("clk2", clk2_pins, false, 5.0f, wave2, nullptr, sta_->cmdMode()); + sta_->makeClock("clk2", clk2_pins, false, 5.0f, wave2, "", sta_->cmdMode()); // Input delays Clock *clk1 = sta_->cmdSdc()->findClock("clk1"); @@ -1665,7 +1664,7 @@ protected: FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0f); waveform->push_back(5.0f); - sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, "", sta_->cmdMode()); Clock *clk = sta_->cmdSdc()->findClock("clk"); ASSERT_NE(clk, nullptr); @@ -1930,7 +1929,7 @@ protected: FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0f); waveform->push_back(5.0f); - sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, "", sta_->cmdMode()); Clock *clk = sta_->cmdSdc()->findClock("clk"); ASSERT_NE(clk, nullptr); diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 7838436d..a26aee13 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -3031,7 +3031,7 @@ scaleFactorTypeName(ScaleFactorType type) } ScaleFactorType -findScaleFactorType(const char *name) +findScaleFactorType(std::string_view name) { return scale_factor_type_map.find(name, ScaleFactorType::unknown); } @@ -3072,7 +3072,7 @@ EnumNameMap scale_factor_pvt_names = }; ScaleFactorPvt -findScaleFactorPvt(const char *name) +findScaleFactorPvt(std::string_view name) { return scale_factor_pvt_names.find(name, ScaleFactorPvt::unknown); } diff --git a/liberty/LibertyParser.cc b/liberty/LibertyParser.cc index 954a7f32..446ce30d 100644 --- a/liberty/LibertyParser.cc +++ b/liberty/LibertyParser.cc @@ -81,7 +81,7 @@ LibertyParser::makeDefine(const LibertyAttrValueSeq *values, const std::string &value_type_name = (*values)[2]->stringValue(); LibertyAttrType value_type = attrValueType(value_type_name); LibertyGroupType group_type = groupType(group_type_name); - define = new LibertyDefine(define_name, group_type, value_type, line); + define = new LibertyDefine(std::move(define_name), group_type, value_type, line); LibertyGroup *group = this->group(); group->addDefine(define); for (auto value : *values) diff --git a/liberty/test/cpp/TestLibertyClasses.cc b/liberty/test/cpp/TestLibertyClasses.cc index 3b605034..d87fa049 100644 --- a/liberty/test/cpp/TestLibertyClasses.cc +++ b/liberty/test/cpp/TestLibertyClasses.cc @@ -683,9 +683,8 @@ TEST_F(TableAxisTest, FindAxisIndexExact) { TEST_F(TableAxisTest, VariableString) { auto axis = makeAxis(TableAxisVariable::total_output_net_capacitance, {1.0f}); - const char *str = axis->variableString(); - EXPECT_NE(str, nullptr); - EXPECT_STREQ(str, "total_output_net_capacitance"); + auto str = axis->variableString(); + EXPECT_EQ(str, "total_output_net_capacitance"); } TEST_F(TableAxisTest, UnitLookup) { @@ -740,12 +739,12 @@ TEST(TableVariableTest, StringTableAxisVariable) { } TEST(TableVariableTest, TableVariableString) { - EXPECT_STREQ(tableVariableString(TableAxisVariable::total_output_net_capacitance), - "total_output_net_capacitance"); - EXPECT_STREQ(tableVariableString(TableAxisVariable::input_net_transition), - "input_net_transition"); - EXPECT_STREQ(tableVariableString(TableAxisVariable::time), - "time"); + EXPECT_EQ(tableVariableString(TableAxisVariable::total_output_net_capacitance), + "total_output_net_capacitance"); + EXPECT_EQ(tableVariableString(TableAxisVariable::input_net_transition), + "input_net_transition"); + EXPECT_EQ(tableVariableString(TableAxisVariable::time), + "time"); } TEST(TableVariableTest, TableVariableUnit) { @@ -1155,11 +1154,11 @@ TEST(TimingTypeTest, TimingTypeScaleFactorType) { } TEST(TimingSenseTest, ToString) { - EXPECT_STREQ(to_string(TimingSense::positive_unate), "positive_unate"); - EXPECT_STREQ(to_string(TimingSense::negative_unate), "negative_unate"); - EXPECT_STREQ(to_string(TimingSense::non_unate), "non_unate"); - EXPECT_STREQ(to_string(TimingSense::none), "none"); - EXPECT_STREQ(to_string(TimingSense::unknown), "unknown"); + EXPECT_EQ(to_string(TimingSense::positive_unate), "positive_unate"); + EXPECT_EQ(to_string(TimingSense::negative_unate), "negative_unate"); + EXPECT_EQ(to_string(TimingSense::non_unate), "non_unate"); + EXPECT_EQ(to_string(TimingSense::none), "none"); + EXPECT_EQ(to_string(TimingSense::unknown), "unknown"); } TEST(TimingSenseTest, Opposite) { @@ -1353,8 +1352,8 @@ TEST(TimingArcAttrsTest, SetSdfCondStartEnd) { TEST(RiseFallTest, BasicProperties) { EXPECT_EQ(RiseFall::rise()->index(), 0); EXPECT_EQ(RiseFall::fall()->index(), 1); - EXPECT_STREQ(RiseFall::rise()->name(), "rise"); - EXPECT_STREQ(RiseFall::fall()->name(), "fall"); + EXPECT_EQ(RiseFall::rise()->name(), "rise"); + EXPECT_EQ(RiseFall::fall()->name(), "fall"); EXPECT_EQ(RiseFall::rise()->opposite(), RiseFall::fall()); EXPECT_EQ(RiseFall::fall()->opposite(), RiseFall::rise()); } @@ -1496,7 +1495,7 @@ TEST_F(LinearModelTest, CheckLinearModelCheckDelay) { TEST_F(LinearModelTest, CheckLinearModelReportCheckDelay) { CheckLinearModel model(cell_, 2.0f); - std::string report = model.reportCheckDelay(nullptr, 0.0f, nullptr, + std::string report = model.reportCheckDelay(nullptr, 0.0f, "", 0.0f, 0.0f, nullptr, PocvMode::scalar, 3); EXPECT_FALSE(report.empty()); @@ -1686,13 +1685,13 @@ TEST(TableModelTest, Order2) { TEST(WireloadTest, BasicConstruction) { LibertyLibrary lib("test_lib", "test.lib"); Wireload wl("test_wl", &lib, 0.0f, 1.0f, 2.0f, 3.0f); - EXPECT_STREQ(wl.name(), "test_wl"); + EXPECT_EQ(wl.name(), "test_wl"); } TEST(WireloadTest, SimpleConstructor) { LibertyLibrary lib("test_lib", "test.lib"); Wireload wl("test_wl", &lib); - EXPECT_STREQ(wl.name(), "test_wl"); + EXPECT_EQ(wl.name(), "test_wl"); // Set individual properties wl.setArea(10.0f); wl.setResistance(1.5f); @@ -1917,7 +1916,7 @@ TEST_F(LinearModelTest, Table0ReportValue) { Table tbl(42.0f); const Units *units = lib_->units(); std::string report = tbl.reportValue("Delay", cell_, nullptr, - 0.0f, nullptr, 0.0f, 0.0f, + 0.0f, "", 0.0f, 0.0f, units->timeUnit(), 3); EXPECT_FALSE(report.empty()); EXPECT_NE(report.find("Delay"), std::string::npos); @@ -1936,7 +1935,7 @@ TEST_F(LinearModelTest, Table1ReportValue) { const Units *units = lib_->units(); std::string report = tbl.reportValue("Delay", cell_, nullptr, - 0.5f, nullptr, 0.0f, 0.0f, + 0.5f, "", 0.0f, 0.0f, units->timeUnit(), 3); EXPECT_FALSE(report.empty()); EXPECT_NE(report.find("Delay"), std::string::npos); @@ -1959,7 +1958,7 @@ TEST_F(LinearModelTest, Table2ReportValue) { const Units *units = lib_->units(); std::string report = tbl.reportValue("Delay", cell_, nullptr, - 0.5f, nullptr, 0.5f, 0.0f, + 0.5f, "", 0.5f, 0.0f, units->timeUnit(), 3); EXPECT_FALSE(report.empty()); EXPECT_NE(report.find("Delay"), std::string::npos); @@ -1989,7 +1988,7 @@ TEST_F(LinearModelTest, Table3ReportValue) { const Units *units = lib_->units(); std::string report = tbl.reportValue("Delay", cell_, nullptr, - 0.5f, nullptr, 0.5f, 0.5f, + 0.5f, "", 0.5f, 0.5f, units->timeUnit(), 3); EXPECT_FALSE(report.empty()); EXPECT_NE(report.find("Delay"), std::string::npos); @@ -2036,7 +2035,7 @@ TEST_F(LinearModelTest, TableModelReportValue) { const Units *units = lib_->units(); std::string report = model.reportValue("Delay", cell_, nullptr, - 0.5f, nullptr, 0.0f, 0.0f, + 0.5f, "", 0.0f, 0.0f, units->timeUnit(), 3); EXPECT_FALSE(report.empty()); EXPECT_NE(report.find("Delay"), std::string::npos); @@ -2116,11 +2115,11 @@ TEST(FuncExprTest, ZeroOneExpressions) { TEST(SequentialTest, BasicConstruction) { // Sequential class is constructed and used during liberty parsing // We can test the StringTableAxisVariable utility - const char *var_str = tableVariableString(TableAxisVariable::input_transition_time); - EXPECT_STREQ(var_str, "input_transition_time"); + auto var_str = tableVariableString(TableAxisVariable::input_transition_time); + EXPECT_EQ(var_str, "input_transition_time"); var_str = tableVariableString(TableAxisVariable::total_output_net_capacitance); - EXPECT_STREQ(var_str, "total_output_net_capacitance"); + EXPECT_EQ(var_str, "total_output_net_capacitance"); } TEST(TableAxisVariableTest, StringToVariable) { @@ -2140,7 +2139,7 @@ TEST(TableAxisVariableTest, StringToVariable) { TEST(WireloadSelectionTest, BasicConstruction) { WireloadSelection sel("test_sel"); - EXPECT_STREQ(sel.name(), "test_sel"); + EXPECT_EQ(sel.name(), "test_sel"); } TEST(WireloadSelectionTest, FindWireload) { @@ -2507,7 +2506,7 @@ TEST(TableModelTest, FindValueOrder2) { TEST(ScaleFactorsTest, BasicConstruction) { ScaleFactors sf("test_scales"); - EXPECT_STREQ(sf.name(), "test_scales"); + EXPECT_EQ(sf.name(), "test_scales"); } TEST(ScaleFactorsTest, SetAndGetWithRiseFall) { @@ -2541,12 +2540,12 @@ TEST(ScaleFactorsTest, SetAndGetWithoutRiseFall) { //////////////////////////////////////////////////////////////// TEST(OcvDerateTest, BasicConstruction) { - OcvDerate derate(stringCopy("test_ocv")); + OcvDerate derate("test_ocv"); EXPECT_EQ(derate.name(), "test_ocv"); } TEST(OcvDerateTest, SetAndGetDerateTable) { - OcvDerate derate(stringCopy("ocv1")); + OcvDerate derate("ocv1"); TablePtr tbl = std::make_shared(0.95f); derate.setDerateTable(RiseFall::rise(), EarlyLate::early(), PathType::data, tbl); @@ -2556,7 +2555,7 @@ TEST(OcvDerateTest, SetAndGetDerateTable) { } TEST(OcvDerateTest, NullByDefault) { - OcvDerate derate(stringCopy("ocv2")); + OcvDerate derate("ocv2"); const Table *found = derate.derateTable(RiseFall::fall(), EarlyLate::late(), PathType::clk); EXPECT_EQ(found, nullptr); @@ -2575,7 +2574,7 @@ TEST(LibertyLibraryTest, OcvArcDepth) { TEST(LibertyLibraryTest, DefaultOcvDerate) { LibertyLibrary lib("test_lib", "test.lib"); EXPECT_EQ(lib.defaultOcvDerate(), nullptr); - OcvDerate *derate = new OcvDerate(stringCopy("default_ocv")); + OcvDerate *derate = new OcvDerate("default_ocv"); lib.setDefaultOcvDerate(derate); EXPECT_EQ(lib.defaultOcvDerate(), derate); } @@ -2626,7 +2625,7 @@ TEST(LibertyLibraryTest, MakeScaledCell) { LibertyLibrary lib("test_lib", "test.lib"); LibertyCell *cell = lib.makeScaledCell("scaled_inv", "test.lib"); EXPECT_NE(cell, nullptr); - EXPECT_STREQ(cell->name(), "scaled_inv"); + EXPECT_EQ(cell->name(), "scaled_inv"); delete cell; } @@ -2666,7 +2665,7 @@ TEST(LibertyLibraryTest, TableTemplates) { TEST(TestCellTest, BasicConstruction) { LibertyLibrary lib("test_lib", "test.lib"); TestCell cell(&lib, "INV_X1", "test.lib"); - EXPECT_STREQ(cell.name(), "INV_X1"); + EXPECT_EQ(cell.name(), "INV_X1"); EXPECT_EQ(cell.libertyLibrary(), &lib); } @@ -2834,7 +2833,7 @@ TEST(TestCellTest, CellOcvDerate) { // Without cell-level derate, returns library default EXPECT_EQ(cell.ocvDerate(), nullptr); - OcvDerate *derate = new OcvDerate(stringCopy("cell_ocv")); + OcvDerate *derate = new OcvDerate("cell_ocv"); cell.setOcvDerate(derate); EXPECT_EQ(cell.ocvDerate(), derate); } @@ -2873,8 +2872,8 @@ TEST(TestCellTest, TimingArcSetCount) { //////////////////////////////////////////////////////////////// TEST(ScanSignalTypeTest, Names) { - EXPECT_NE(scanSignalTypeName(ScanSignalType::enable), nullptr); - EXPECT_NE(scanSignalTypeName(ScanSignalType::enable_inverted), nullptr); + EXPECT_FALSE(scanSignalTypeName(ScanSignalType::enable).empty()); + EXPECT_FALSE(scanSignalTypeName(ScanSignalType::enable_inverted).empty()); } //////////////////////////////////////////////////////////////// @@ -2979,8 +2978,8 @@ TEST(LibertyUtilTest, PortLibertyToSta) { } TEST(LibertyUtilTest, PwrGndTypeName) { - const char *name = pwrGndTypeName(PwrGndType::primary_power); - EXPECT_NE(name, nullptr); + const std::string &name = pwrGndTypeName(PwrGndType::primary_power); + EXPECT_FALSE(name.empty()); } TEST(LibertyUtilTest, FindPwrGndType) { @@ -3000,9 +2999,9 @@ TEST(ScaleFactorPvtTest, FindByName) { } TEST(ScaleFactorPvtTest, PvtToName) { - EXPECT_STREQ(scaleFactorPvtName(ScaleFactorPvt::process), "process"); - EXPECT_STREQ(scaleFactorPvtName(ScaleFactorPvt::volt), "volt"); - EXPECT_STREQ(scaleFactorPvtName(ScaleFactorPvt::temp), "temp"); + EXPECT_EQ(scaleFactorPvtName(ScaleFactorPvt::process), "process"); + EXPECT_EQ(scaleFactorPvtName(ScaleFactorPvt::volt), "volt"); + EXPECT_EQ(scaleFactorPvtName(ScaleFactorPvt::temp), "temp"); } //////////////////////////////////////////////////////////////// @@ -3029,16 +3028,16 @@ TEST(ScaleFactorTypeTest, FindByName) { } TEST(ScaleFactorTypeTest, TypeToName) { - EXPECT_STREQ(scaleFactorTypeName(ScaleFactorType::pin_cap), "pin_cap"); - EXPECT_STREQ(scaleFactorTypeName(ScaleFactorType::wire_cap), "wire_cap"); - EXPECT_STREQ(scaleFactorTypeName(ScaleFactorType::wire_res), "wire_res"); - EXPECT_STREQ(scaleFactorTypeName(ScaleFactorType::cell), "cell"); - EXPECT_STREQ(scaleFactorTypeName(ScaleFactorType::hold), "hold"); - EXPECT_STREQ(scaleFactorTypeName(ScaleFactorType::setup), "setup"); - EXPECT_STREQ(scaleFactorTypeName(ScaleFactorType::recovery), "recovery"); - EXPECT_STREQ(scaleFactorTypeName(ScaleFactorType::removal), "removal"); - EXPECT_STREQ(scaleFactorTypeName(ScaleFactorType::transition), "transition"); - EXPECT_STREQ(scaleFactorTypeName(ScaleFactorType::min_pulse_width), "min_pulse_width"); + EXPECT_EQ(scaleFactorTypeName(ScaleFactorType::pin_cap), "pin_cap"); + EXPECT_EQ(scaleFactorTypeName(ScaleFactorType::wire_cap), "wire_cap"); + EXPECT_EQ(scaleFactorTypeName(ScaleFactorType::wire_res), "wire_res"); + EXPECT_EQ(scaleFactorTypeName(ScaleFactorType::cell), "cell"); + EXPECT_EQ(scaleFactorTypeName(ScaleFactorType::hold), "hold"); + EXPECT_EQ(scaleFactorTypeName(ScaleFactorType::setup), "setup"); + EXPECT_EQ(scaleFactorTypeName(ScaleFactorType::recovery), "recovery"); + EXPECT_EQ(scaleFactorTypeName(ScaleFactorType::removal), "removal"); + EXPECT_EQ(scaleFactorTypeName(ScaleFactorType::transition), "transition"); + EXPECT_EQ(scaleFactorTypeName(ScaleFactorType::min_pulse_width), "min_pulse_width"); } TEST(ScaleFactorTypeTest, RiseFallSuffix) { @@ -3097,13 +3096,16 @@ TEST(PvtTest, Setters) { TEST(OperatingConditionsTest, NameOnlyConstructor) { OperatingConditions opcond("typical"); - EXPECT_STREQ(opcond.name(), "typical"); + EXPECT_EQ(opcond.name(), "typical"); } TEST(OperatingConditionsTest, FullConstructor) { - OperatingConditions opcond("worst", 1.0f, 0.9f, 125.0f, - WireloadTree::worst_case); - EXPECT_STREQ(opcond.name(), "worst"); + OperatingConditions opcond("worst"); + opcond.setProcess(1.0f); + opcond.setVoltage(0.9f); + opcond.setTemperature(125.0f); + opcond.setWireloadTree(WireloadTree::worst_case); + EXPECT_EQ(opcond.name(), "worst"); EXPECT_FLOAT_EQ(opcond.process(), 1.0f); EXPECT_FLOAT_EQ(opcond.voltage(), 0.9f); EXPECT_FLOAT_EQ(opcond.temperature(), 125.0f); @@ -3201,8 +3203,10 @@ TEST(ModeDefTest, DefineAndFindValue) { EXPECT_NE(mode, nullptr); FuncExpr *cond = FuncExpr::makeOne(); - ModeValueDef *valdef = mode->defineValue("test_value", cond, "A==1"); + ModeValueDef *valdef = mode->defineValue("test_value"); EXPECT_NE(valdef, nullptr); + valdef->setCond(cond); + valdef->setSdfCond("A==1"); EXPECT_EQ(valdef->value(), "test_value"); EXPECT_EQ(valdef->cond(), cond); EXPECT_EQ(valdef->sdfCond(), "A==1"); @@ -3211,8 +3215,8 @@ TEST(ModeDefTest, DefineAndFindValue) { EXPECT_EQ(found, valdef); EXPECT_EQ(mode->findValueDef("nonexistent"), nullptr); - const ModeValueMap *vals = mode->values(); - EXPECT_NE(vals, nullptr); + const ModeValueMap &vals = mode->values(); + EXPECT_FALSE(vals.empty()); } //////////////////////////////////////////////////////////////// @@ -3286,34 +3290,30 @@ TEST(TestCellTest, TimingArcSetsEmpty) { TEST(TestCellTest, FootprintDefault) { LibertyLibrary lib("test_lib", "test.lib"); TestCell cell(&lib, "CELL1", "test.lib"); - const char *fp = cell.footprint(); - // Empty string or nullptr for default - if (fp) { - EXPECT_EQ(fp, ""); - } + const std::string &fp = cell.footprint(); + // Empty string for default + EXPECT_TRUE(fp.empty()); } TEST(TestCellTest, SetFootprint) { LibertyLibrary lib("test_lib", "test.lib"); TestCell cell(&lib, "CELL1", "test.lib"); cell.setFootprint("INV_FP"); - EXPECT_STREQ(cell.footprint(), "INV_FP"); + EXPECT_EQ(cell.footprint(), "INV_FP"); } TEST(TestCellTest, UserFunctionClassDefault) { LibertyLibrary lib("test_lib", "test.lib"); TestCell cell(&lib, "CELL1", "test.lib"); - const char *ufc = cell.userFunctionClass(); - if (ufc) { - EXPECT_EQ(ufc, ""); - } + const std::string &ufc = cell.userFunctionClass(); + EXPECT_TRUE(ufc.empty()); } TEST(TestCellTest, SetUserFunctionClass) { LibertyLibrary lib("test_lib", "test.lib"); TestCell cell(&lib, "CELL1", "test.lib"); cell.setUserFunctionClass("inverter"); - EXPECT_STREQ(cell.userFunctionClass(), "inverter"); + EXPECT_EQ(cell.userFunctionClass(), "inverter"); } TEST(TestCellTest, SwitchCellTypeGetter) { @@ -3425,15 +3425,15 @@ TEST(TimingTypeTest, ScaleFactorTypeAdditional) { //////////////////////////////////////////////////////////////// TEST(ScanSignalTypeTest, AllNames) { - EXPECT_NE(scanSignalTypeName(ScanSignalType::enable), nullptr); - EXPECT_NE(scanSignalTypeName(ScanSignalType::enable_inverted), nullptr); - EXPECT_NE(scanSignalTypeName(ScanSignalType::clock), nullptr); - EXPECT_NE(scanSignalTypeName(ScanSignalType::clock_a), nullptr); - EXPECT_NE(scanSignalTypeName(ScanSignalType::clock_b), nullptr); - EXPECT_NE(scanSignalTypeName(ScanSignalType::input), nullptr); - EXPECT_NE(scanSignalTypeName(ScanSignalType::input_inverted), nullptr); - EXPECT_NE(scanSignalTypeName(ScanSignalType::output), nullptr); - EXPECT_NE(scanSignalTypeName(ScanSignalType::output_inverted), nullptr); + EXPECT_FALSE(scanSignalTypeName(ScanSignalType::enable).empty()); + EXPECT_FALSE(scanSignalTypeName(ScanSignalType::enable_inverted).empty()); + EXPECT_FALSE(scanSignalTypeName(ScanSignalType::clock).empty()); + EXPECT_FALSE(scanSignalTypeName(ScanSignalType::clock_a).empty()); + EXPECT_FALSE(scanSignalTypeName(ScanSignalType::clock_b).empty()); + EXPECT_FALSE(scanSignalTypeName(ScanSignalType::input).empty()); + EXPECT_FALSE(scanSignalTypeName(ScanSignalType::input_inverted).empty()); + EXPECT_FALSE(scanSignalTypeName(ScanSignalType::output).empty()); + EXPECT_FALSE(scanSignalTypeName(ScanSignalType::output_inverted).empty()); } //////////////////////////////////////////////////////////////// @@ -3441,16 +3441,16 @@ TEST(ScanSignalTypeTest, AllNames) { //////////////////////////////////////////////////////////////// TEST(LibertyUtilTest, PwrGndTypeAllNames) { - EXPECT_NE(pwrGndTypeName(PwrGndType::primary_power), nullptr); - EXPECT_NE(pwrGndTypeName(PwrGndType::primary_ground), nullptr); - EXPECT_NE(pwrGndTypeName(PwrGndType::backup_power), nullptr); - EXPECT_NE(pwrGndTypeName(PwrGndType::backup_ground), nullptr); - EXPECT_NE(pwrGndTypeName(PwrGndType::internal_power), nullptr); - EXPECT_NE(pwrGndTypeName(PwrGndType::internal_ground), nullptr); - EXPECT_NE(pwrGndTypeName(PwrGndType::nwell), nullptr); - EXPECT_NE(pwrGndTypeName(PwrGndType::pwell), nullptr); - EXPECT_NE(pwrGndTypeName(PwrGndType::deepnwell), nullptr); - EXPECT_NE(pwrGndTypeName(PwrGndType::deeppwell), nullptr); + EXPECT_FALSE(pwrGndTypeName(PwrGndType::primary_power).empty()); + EXPECT_FALSE(pwrGndTypeName(PwrGndType::primary_ground).empty()); + EXPECT_FALSE(pwrGndTypeName(PwrGndType::backup_power).empty()); + EXPECT_FALSE(pwrGndTypeName(PwrGndType::backup_ground).empty()); + EXPECT_FALSE(pwrGndTypeName(PwrGndType::internal_power).empty()); + EXPECT_FALSE(pwrGndTypeName(PwrGndType::internal_ground).empty()); + EXPECT_FALSE(pwrGndTypeName(PwrGndType::nwell).empty()); + EXPECT_FALSE(pwrGndTypeName(PwrGndType::pwell).empty()); + EXPECT_FALSE(pwrGndTypeName(PwrGndType::deepnwell).empty()); + EXPECT_FALSE(pwrGndTypeName(PwrGndType::deeppwell).empty()); } TEST(LibertyUtilTest, FindPwrGndTypeAll) { @@ -3675,7 +3675,7 @@ TEST(Table0Test, ReportValue) { TestCell cell(&lib, "INV", "test.lib"); const Units *units = lib.units(); std::string report = tbl.reportValue("Power", &cell, nullptr, - 0.0f, nullptr, 0.0f, 0.0f, + 0.0f, "", 0.0f, 0.0f, units->powerUnit(), 3); EXPECT_FALSE(report.empty()); } diff --git a/network/test/cpp/TestNetwork.cc b/network/test/cpp/TestNetwork.cc index 2d4be8bc..f95223f1 100644 --- a/network/test/cpp/TestNetwork.cc +++ b/network/test/cpp/TestNetwork.cc @@ -1,5 +1,6 @@ #include #include +#include #include "VerilogNamespace.hh" #include "PortDirection.hh" #include "ConcreteLibrary.hh" @@ -97,7 +98,7 @@ protected: TEST_F(PortDirectionTest, InputSingleton) { PortDirection *dir = PortDirection::input(); EXPECT_NE(dir, nullptr); - EXPECT_STREQ(dir->name(), "input"); + EXPECT_EQ(dir->name(), "input"); EXPECT_EQ(dir->index(), 0); EXPECT_TRUE(dir->isInput()); EXPECT_FALSE(dir->isOutput()); @@ -112,7 +113,7 @@ TEST_F(PortDirectionTest, InputSingleton) { TEST_F(PortDirectionTest, OutputSingleton) { PortDirection *dir = PortDirection::output(); EXPECT_NE(dir, nullptr); - EXPECT_STREQ(dir->name(), "output"); + EXPECT_EQ(dir->name(), "output"); EXPECT_EQ(dir->index(), 1); EXPECT_TRUE(dir->isOutput()); EXPECT_FALSE(dir->isInput()); @@ -121,7 +122,7 @@ TEST_F(PortDirectionTest, OutputSingleton) { TEST_F(PortDirectionTest, TristateSingleton) { PortDirection *dir = PortDirection::tristate(); EXPECT_NE(dir, nullptr); - EXPECT_STREQ(dir->name(), "tristate"); + EXPECT_EQ(dir->name(), "tristate"); EXPECT_EQ(dir->index(), 2); EXPECT_TRUE(dir->isTristate()); EXPECT_FALSE(dir->isInput()); @@ -131,7 +132,7 @@ TEST_F(PortDirectionTest, TristateSingleton) { TEST_F(PortDirectionTest, BidirectSingleton) { PortDirection *dir = PortDirection::bidirect(); EXPECT_NE(dir, nullptr); - EXPECT_STREQ(dir->name(), "bidirect"); + EXPECT_EQ(dir->name(), "bidirect"); EXPECT_EQ(dir->index(), 3); EXPECT_TRUE(dir->isBidirect()); } @@ -139,7 +140,7 @@ TEST_F(PortDirectionTest, BidirectSingleton) { TEST_F(PortDirectionTest, InternalSingleton) { PortDirection *dir = PortDirection::internal(); EXPECT_NE(dir, nullptr); - EXPECT_STREQ(dir->name(), "internal"); + EXPECT_EQ(dir->name(), "internal"); EXPECT_EQ(dir->index(), 4); EXPECT_TRUE(dir->isInternal()); } @@ -147,7 +148,7 @@ TEST_F(PortDirectionTest, InternalSingleton) { TEST_F(PortDirectionTest, GroundSingleton) { PortDirection *dir = PortDirection::ground(); EXPECT_NE(dir, nullptr); - EXPECT_STREQ(dir->name(), "ground"); + EXPECT_EQ(dir->name(), "ground"); EXPECT_EQ(dir->index(), 5); EXPECT_TRUE(dir->isGround()); } @@ -155,7 +156,7 @@ TEST_F(PortDirectionTest, GroundSingleton) { TEST_F(PortDirectionTest, PowerSingleton) { PortDirection *dir = PortDirection::power(); EXPECT_NE(dir, nullptr); - EXPECT_STREQ(dir->name(), "power"); + EXPECT_EQ(dir->name(), "power"); EXPECT_EQ(dir->index(), 6); EXPECT_TRUE(dir->isPower()); } @@ -163,7 +164,7 @@ TEST_F(PortDirectionTest, PowerSingleton) { TEST_F(PortDirectionTest, UnknownSingleton) { PortDirection *dir = PortDirection::unknown(); EXPECT_NE(dir, nullptr); - EXPECT_STREQ(dir->name(), "unknown"); + EXPECT_EQ(dir->name(), "unknown"); EXPECT_EQ(dir->index(), 7); EXPECT_TRUE(dir->isUnknown()); } @@ -229,8 +230,8 @@ TEST_F(PortDirectionTest, IsPowerGround) { TEST(ConcreteLibraryTest, CreateAndFind) { ConcreteLibrary lib("test_lib", "test.lib", false); - EXPECT_STREQ(lib.name(), "test_lib"); - EXPECT_STREQ(lib.filename(), "test.lib"); + EXPECT_EQ(lib.name(), "test_lib"); + EXPECT_EQ(lib.filename(), "test.lib"); EXPECT_FALSE(lib.isLiberty()); } @@ -245,8 +246,8 @@ TEST(ConcreteLibraryTest, MakeCell) { ConcreteLibrary lib("test_lib", "test.lib", false); ConcreteCell *cell = lib.makeCell("INV", true, "inv.v"); EXPECT_NE(cell, nullptr); - EXPECT_STREQ(cell->name(), "INV"); - EXPECT_STREQ(cell->filename(), "inv.v"); + EXPECT_EQ(cell->name(), "INV"); + EXPECT_EQ(cell->filename(), "inv.v"); EXPECT_TRUE(cell->isLeaf()); EXPECT_EQ(cell->library(), &lib); @@ -299,7 +300,7 @@ TEST(ConcreteCellTest, MakePort) { ConcreteCell *cell = lib.makeCell("INV", true, ""); ConcretePort *port_a = cell->makePort("A"); EXPECT_NE(port_a, nullptr); - EXPECT_STREQ(port_a->name(), "A"); + EXPECT_EQ(port_a->name(), "A"); EXPECT_EQ(port_a->cell(), reinterpret_cast(cell)); ConcretePort *found = cell->findPort("A"); @@ -357,9 +358,9 @@ TEST(ConcreteCellTest, AttributeMap) { TEST(ConcreteCellTest, SetName) { ConcreteLibrary lib("test_lib", "test.lib", false); ConcreteCell *cell = lib.makeCell("OLD", true, ""); - EXPECT_STREQ(cell->name(), "OLD"); + EXPECT_EQ(cell->name(), "OLD"); cell->setName("NEW"); - EXPECT_STREQ(cell->name(), "NEW"); + EXPECT_EQ(cell->name(), "NEW"); } TEST(ConcreteCellTest, PortIterator) { @@ -646,10 +647,10 @@ TEST(ConcreteCellTest, MakeBusPortAscending) { TEST(ConcreteCellTest, Filename) { ConcreteLibrary lib("test_lib", "test.lib", false); ConcreteCell *cell = lib.makeCell("INV", true, "test_cell.v"); - EXPECT_STREQ(cell->filename(), "test_cell.v"); + EXPECT_EQ(cell->filename(), "test_cell.v"); ConcreteCell *cell2 = lib.makeCell("BUF", true, ""); - EXPECT_STREQ(cell2->filename(), ""); + EXPECT_EQ(cell2->filename(), ""); } TEST(ConcreteCellTest, FindCellsMatching) { @@ -692,8 +693,8 @@ TEST(ConcretePortTest, BusPortBusName) { lib.setBusBrkts('[', ']'); ConcreteCell *cell = lib.makeCell("REG", true, ""); ConcretePort *bus = cell->makeBusPort("D", 3, 0); - const char *bus_name = bus->busName(); - EXPECT_NE(bus_name, nullptr); + std::string bus_name = bus->busName(); + EXPECT_FALSE(bus_name.empty()); // Should contain bus bracket notation std::string name_str(bus_name); EXPECT_NE(name_str.find("["), std::string::npos); @@ -704,8 +705,8 @@ TEST(ConcretePortTest, ScalarBusName) { ConcreteCell *cell = lib.makeCell("INV", true, ""); ConcretePort *port = cell->makePort("A"); // Scalar port busName returns just the name - const char *bus_name = port->busName(); - EXPECT_STREQ(bus_name, "A"); + std::string bus_name = port->busName(); + EXPECT_EQ(bus_name, "A"); } TEST(ConcretePortTest, FindMember) { @@ -830,7 +831,7 @@ TEST(ConcreteLibraryTest, BusBracketsChange) { TEST(ConcreteLibraryTest, FilenameAndId) { ConcreteLibrary lib("test_lib", "test.lib", false); - EXPECT_STREQ(lib.filename(), "test.lib"); + EXPECT_EQ(lib.filename(), "test.lib"); // Library ID is a monotonically increasing counter EXPECT_GE(lib.id(), 0u); } @@ -878,14 +879,14 @@ TEST(PortDirectionExtraTest, DirectionNames) { if (PortDirection::input() == nullptr) { PortDirection::init(); } - EXPECT_STREQ(PortDirection::input()->name(), "input"); - EXPECT_STREQ(PortDirection::output()->name(), "output"); - EXPECT_STREQ(PortDirection::bidirect()->name(), "bidirect"); - EXPECT_STREQ(PortDirection::tristate()->name(), "tristate"); - EXPECT_STREQ(PortDirection::internal()->name(), "internal"); - EXPECT_STREQ(PortDirection::ground()->name(), "ground"); - EXPECT_STREQ(PortDirection::power()->name(), "power"); - EXPECT_STREQ(PortDirection::unknown()->name(), "unknown"); + EXPECT_EQ(PortDirection::input()->name(), "input"); + EXPECT_EQ(PortDirection::output()->name(), "output"); + EXPECT_EQ(PortDirection::bidirect()->name(), "bidirect"); + EXPECT_EQ(PortDirection::tristate()->name(), "tristate"); + EXPECT_EQ(PortDirection::internal()->name(), "internal"); + EXPECT_EQ(PortDirection::ground()->name(), "ground"); + EXPECT_EQ(PortDirection::power()->name(), "power"); + EXPECT_EQ(PortDirection::unknown()->name(), "unknown"); } TEST(PortDirectionExtraTest, FindAllByName) { @@ -940,7 +941,7 @@ TEST(ConcreteCellTest, GroupBusPorts) { cell->makePort("CLK"); // groupBusPorts should group D[0]-D[3] into bus D - cell->groupBusPorts('[', ']', [](const char*) { return true; }); + cell->groupBusPorts('[', ']', [](std::string_view) { return true; }); // After grouping, we should find the bus port D ConcretePort *bus = cell->findPort("D"); @@ -969,7 +970,7 @@ TEST(ConcreteNetworkTest, MakeLibrary) { EXPECT_EQ(found, lib); // Library name - EXPECT_STREQ(network.name(lib), "test_lib"); + EXPECT_EQ(network.name(lib), "test_lib"); } TEST(ConcreteNetworkTest, LibraryIterator) { @@ -1008,7 +1009,7 @@ TEST(ConcreteNetworkTest, CellName) { Cell *cell = network.findCell(lib, "INV_X1"); EXPECT_NE(cell, nullptr); - EXPECT_STREQ(network.name(cell), "INV_X1"); + EXPECT_EQ(network.name(cell), "INV_X1"); } TEST(ConcreteNetworkTest, CellIsLeaf) { @@ -1052,7 +1053,7 @@ TEST(ConcreteNetworkTest, PortProperties) { ConcretePort *a = ccell->makePort("A"); Port *port = reinterpret_cast(a); - EXPECT_STREQ(network.name(port), "A"); + EXPECT_EQ(network.name(port), "A"); EXPECT_FALSE(network.isBus(port)); EXPECT_FALSE(network.isBundle(port)); } @@ -1068,7 +1069,7 @@ TEST(ConcreteNetworkTest, FindPort) { Cell *cell = reinterpret_cast(ccell); Port *found = network.findPort(cell, "A"); EXPECT_NE(found, nullptr); - EXPECT_STREQ(network.name(found), "A"); + EXPECT_EQ(network.name(found), "A"); Port *not_found = network.findPort(cell, "B"); EXPECT_EQ(not_found, nullptr); @@ -1102,7 +1103,7 @@ TEST(ConcreteNetworkTest, FindLibraryByName) { TEST(ConcreteNetworkTest, LibraryName) { ConcreteNetwork network; Library *lib = network.makeLibrary("test_name_lib", "test.lib"); - EXPECT_STREQ(network.name(lib), "test_name_lib"); + EXPECT_EQ(network.name(lib), "test_name_lib"); } TEST(ConcreteNetworkTest, LibraryId) { @@ -1151,7 +1152,7 @@ TEST(ConcreteNetworkTest, CellNameViaNetwork) { ConcreteNetwork network; Library *lib = network.makeLibrary("nm_lib", "nm.lib"); Cell *cell = network.makeCell(lib, "OR2_X1", true, "nm.lib"); - EXPECT_STREQ(network.name(cell), "OR2_X1"); + EXPECT_EQ(network.name(cell), "OR2_X1"); } TEST(ConcreteNetworkTest, CellIdViaNetwork) { @@ -1167,7 +1168,7 @@ TEST(ConcreteNetworkTest, SetCellName) { Library *lib = network.makeLibrary("rn_lib", "rn.lib"); Cell *cell = network.makeCell(lib, "OLD_NAME", true, "rn.lib"); network.setName(cell, "NEW_NAME"); - EXPECT_STREQ(network.name(cell), "NEW_NAME"); + EXPECT_EQ(network.name(cell), "NEW_NAME"); } TEST(ConcreteNetworkTest, SetIsLeaf) { @@ -1210,7 +1211,7 @@ TEST(ConcreteNetworkTest, CellFilename) { ConcreteNetwork network; Library *lib = network.makeLibrary("fn_lib", "fn.lib"); Cell *cell = network.makeCell(lib, "CELL1", true, "fn.lib"); - EXPECT_STREQ(network.filename(cell), "fn.lib"); + EXPECT_EQ(network.filename(cell), "fn.lib"); } TEST(ConcreteNetworkTest, DeleteCell) { @@ -1343,8 +1344,8 @@ TEST_F(ConcreteNetworkLinkedTest, IsTopInstance) { } TEST_F(ConcreteNetworkLinkedTest, InstanceName) { - EXPECT_STREQ(network_.name(u1_), "u1"); - EXPECT_STREQ(network_.name(u2_), "u2"); + EXPECT_EQ(network_.name(u1_), "u1"); + EXPECT_EQ(network_.name(u2_), "u2"); } TEST_F(ConcreteNetworkLinkedTest, InstanceId) { @@ -1356,12 +1357,12 @@ TEST_F(ConcreteNetworkLinkedTest, InstanceId) { TEST_F(ConcreteNetworkLinkedTest, InstanceCell) { Cell *cell = network_.cell(u1_); EXPECT_NE(cell, nullptr); - EXPECT_STREQ(network_.name(cell), "INV"); + EXPECT_EQ(network_.name(cell), "INV"); } TEST_F(ConcreteNetworkLinkedTest, InstanceCellName) { - const char *name = network_.cellName(u1_); - EXPECT_STREQ(name, "INV"); + std::string name = network_.cellName(u1_); + EXPECT_EQ(name, "INV"); } TEST_F(ConcreteNetworkLinkedTest, InstanceParent) { @@ -1388,9 +1389,9 @@ TEST_F(ConcreteNetworkLinkedTest, InstanceFindChild) { } TEST_F(ConcreteNetworkLinkedTest, InstancePathName) { - const char *path = network_.pathName(u1_); - EXPECT_NE(path, nullptr); - EXPECT_STREQ(path, "u1"); + std::string path = network_.pathName(u1_); + EXPECT_FALSE(path.empty()); + EXPECT_EQ(path, "u1"); } TEST_F(ConcreteNetworkLinkedTest, ChildIterator) { @@ -1447,7 +1448,7 @@ TEST_F(ConcreteNetworkLinkedTest, PinNet) { TEST_F(ConcreteNetworkLinkedTest, PinPort) { Port *port = network_.port(pin_u1_a_); EXPECT_NE(port, nullptr); - EXPECT_STREQ(network_.name(port), "A"); + EXPECT_EQ(network_.name(port), "A"); } TEST_F(ConcreteNetworkLinkedTest, PinDirection) { @@ -1473,18 +1474,18 @@ TEST_F(ConcreteNetworkLinkedTest, PinVertexId) { TEST_F(ConcreteNetworkLinkedTest, PinName) { const Network &net = network_; - const char *name = net.name(pin_u1_a_); - EXPECT_NE(name, nullptr); + std::string name = net.name(pin_u1_a_); + EXPECT_FALSE(name.empty()); } TEST_F(ConcreteNetworkLinkedTest, PinPortName) { - const char *pname = network_.portName(pin_u1_a_); - EXPECT_STREQ(pname, "A"); + std::string pname = network_.portName(pin_u1_a_); + EXPECT_EQ(pname, "A"); } TEST_F(ConcreteNetworkLinkedTest, PinPathName) { - const char *path = network_.pathName(pin_u1_a_); - EXPECT_NE(path, nullptr); + std::string path = network_.pathName(pin_u1_a_); + EXPECT_FALSE(path.empty()); } TEST_F(ConcreteNetworkLinkedTest, PinIsLeaf) { @@ -1517,7 +1518,7 @@ TEST_F(ConcreteNetworkLinkedTest, FindPinByPort) { // Net tests TEST_F(ConcreteNetworkLinkedTest, NetName) { - EXPECT_STREQ(network_.name(net1_), "n1"); + EXPECT_EQ(network_.name(net1_), "n1"); } TEST_F(ConcreteNetworkLinkedTest, NetId) { @@ -1531,8 +1532,8 @@ TEST_F(ConcreteNetworkLinkedTest, NetInstance) { } TEST_F(ConcreteNetworkLinkedTest, NetPathName) { - const char *path = network_.pathName(net1_); - EXPECT_NE(path, nullptr); + std::string path = network_.pathName(net1_); + EXPECT_FALSE(path.empty()); } TEST_F(ConcreteNetworkLinkedTest, NetIsPowerGround) { @@ -1628,7 +1629,7 @@ TEST_F(ConcreteNetworkLinkedTest, ReplaceCell) { network_.disconnectPin(pin_u1_y_); network_.replaceCell(u1_, buf_cell); Cell *new_cell = network_.cell(u1_); - EXPECT_STREQ(network_.name(new_cell), "BUF"); + EXPECT_EQ(network_.name(new_cell), "BUF"); } // Network pathName comparisons @@ -1666,35 +1667,31 @@ TEST_F(ConcreteNetworkLinkedTest, PathNameCmpNet) { // Network: pathNameFirst / pathNameLast TEST_F(ConcreteNetworkLinkedTest, PathNameFirst) { - char *first = nullptr; - char *tail = nullptr; + std::string first; + std::string tail; network_.pathNameFirst("a/b/c", first, tail); - if (first) { - EXPECT_STREQ(first, "a"); - EXPECT_STREQ(tail, "b/c"); - delete [] first; - delete [] tail; + if (!first.empty()) { + EXPECT_EQ(first, "a"); + EXPECT_EQ(tail, "b/c"); } } TEST_F(ConcreteNetworkLinkedTest, PathNameLast) { - char *head = nullptr; - char *last = nullptr; + std::string head; + std::string last; network_.pathNameLast("a/b/c", head, last); - if (last) { - EXPECT_STREQ(last, "c"); - EXPECT_STREQ(head, "a/b"); - delete [] head; - delete [] last; + if (!last.empty()) { + EXPECT_EQ(last, "c"); + EXPECT_EQ(head, "a/b"); } } TEST_F(ConcreteNetworkLinkedTest, PathNameFirstNoDivider) { - char *first = nullptr; - char *tail = nullptr; + std::string first; + std::string tail; network_.pathNameFirst("simple", first, tail); - EXPECT_EQ(first, nullptr); - EXPECT_EQ(tail, nullptr); + EXPECT_TRUE(first.empty()); + EXPECT_TRUE(tail.empty()); } // Network: pathDivider / pathEscape @@ -2027,8 +2024,8 @@ TEST_F(ConcreteNetworkLinkedTest, SortByPathNameInstances) { inst_set.insert(u1_); InstanceSeq sorted = sortByPathName(&inst_set, &network_); EXPECT_EQ(sorted.size(), 2u); - EXPECT_STREQ(network_.name(sorted[0]), "u1"); - EXPECT_STREQ(network_.name(sorted[1]), "u2"); + EXPECT_EQ(network_.name(sorted[0]), "u1"); + EXPECT_EQ(network_.name(sorted[1]), "u2"); } TEST_F(ConcreteNetworkLinkedTest, SortByPathNameNets) { @@ -2049,8 +2046,8 @@ TEST_F(ConcreteNetworkLinkedTest, SortByNamePorts) { port_set.insert(port_a); PortSeq sorted = sortByName(&port_set, &network_); EXPECT_EQ(sorted.size(), 2u); - EXPECT_STREQ(network_.name(sorted[0]), "A"); - EXPECT_STREQ(network_.name(sorted[1]), "Y"); + EXPECT_EQ(network_.name(sorted[0]), "A"); + EXPECT_EQ(network_.name(sorted[1]), "Y"); } // NetworkCmp comparator constructors @@ -2212,8 +2209,8 @@ TEST_F(ConcreteNetworkLinkedTest, PortFromToIndexViaNetwork) { TEST_F(ConcreteNetworkLinkedTest, PortBusNameViaNetwork) { Cell *inv_cell = network_.findCell(lib_, "INV"); Port *port_a = network_.findPort(inv_cell, "A"); - const char *bus_name = network_.busName(port_a); - EXPECT_STREQ(bus_name, "A"); + std::string bus_name = network_.busName(port_a); + EXPECT_EQ(bus_name, "A"); } TEST_F(ConcreteNetworkLinkedTest, PortFindBusBitViaNetwork) { @@ -2308,7 +2305,7 @@ TEST_F(ConcreteNetworkLinkedTest, GroupBusPortsViaNetwork) { ConcreteLibrary *clib = reinterpret_cast(lib_); clib->setBusBrkts('[', ']'); - network_.groupBusPorts(cell, [](const char*) { return true; }); + network_.groupBusPorts(cell, [](std::string_view) { return true; }); Port *bus = network_.findPort(cell, "D"); EXPECT_NE(bus, nullptr); if (bus) { @@ -2558,29 +2555,29 @@ TEST_F(ConcreteNetworkLinkedTest, PortDirectionAccess) { // Network: various accessor methods TEST_F(ConcreteNetworkLinkedTest, LibraryNameAccess) { - EXPECT_STREQ(network_.name(lib_), "test_lib"); + EXPECT_EQ(network_.name(lib_), "test_lib"); } TEST_F(ConcreteNetworkLinkedTest, CellNameAccess) { Cell *inv_cell = network_.findCell(lib_, "INV"); - EXPECT_STREQ(network_.name(inv_cell), "INV"); + EXPECT_EQ(network_.name(inv_cell), "INV"); } TEST_F(ConcreteNetworkLinkedTest, PortNameAccess) { Cell *inv_cell = network_.findCell(lib_, "INV"); Port *port_a = network_.findPort(inv_cell, "A"); - EXPECT_STREQ(network_.name(port_a), "A"); + EXPECT_EQ(network_.name(port_a), "A"); } TEST_F(ConcreteNetworkLinkedTest, NetNameAccess) { - EXPECT_STREQ(network_.name(net1_), "n1"); + EXPECT_EQ(network_.name(net1_), "n1"); } // Network: cell filename TEST_F(ConcreteNetworkLinkedTest, CellFilename) { Cell *inv_cell = network_.findCell(lib_, "INV"); - const char *fn = network_.filename(inv_cell); - EXPECT_STREQ(fn, "test.lib"); + std::string_view fn = network_.filename(inv_cell); + EXPECT_EQ(fn, "test.lib"); } // PinSet default constructor diff --git a/parasitics/test/cpp/TestParasitics.cc b/parasitics/test/cpp/TestParasitics.cc index eddb6967..6ca11f6c 100644 --- a/parasitics/test/cpp/TestParasitics.cc +++ b/parasitics/test/cpp/TestParasitics.cc @@ -1,3 +1,5 @@ +#include + #include #include "StringUtil.hh" #include "MinMax.hh" @@ -41,132 +43,114 @@ class SpefNamespaceTest : public ::testing::Test {}; // Basic identity: no dividers or escapes needed TEST_F(SpefNamespaceTest, SpefToStaSimpleName) { - char *result = spefToSta("net1", '/', '/', '\\'); - EXPECT_STREQ(result, "net1"); - delete[] result; + std::string result = spefToSta("net1", '/', '/', '\\'); + EXPECT_EQ(result, "net1"); } TEST_F(SpefNamespaceTest, StaToSpefSimpleName) { - char *result = staToSpef("net1", '/', '/', '\\'); - EXPECT_STREQ(result, "net1"); - delete[] result; + std::string result = staToSpef("net1", '/', '/', '\\'); + EXPECT_EQ(result, "net1"); } // SPEF divider to STA divider translation TEST_F(SpefNamespaceTest, SpefToStaDividerTranslation) { // SPEF uses '.' as divider, STA uses '/' - char *result = spefToSta("top.sub.net", '.', '/', '\\'); - EXPECT_STREQ(result, "top/sub/net"); - delete[] result; + std::string result = spefToSta("top.sub.net", '.', '/', '\\'); + EXPECT_EQ(result, "top/sub/net"); } TEST_F(SpefNamespaceTest, StaToSpefDividerTranslation) { // STA uses '/' as divider, SPEF uses '.' - char *result = staToSpef("top/sub/net", '.', '/', '\\'); - EXPECT_STREQ(result, "top.sub.net"); - delete[] result; + std::string result = staToSpef("top/sub/net", '.', '/', '\\'); + EXPECT_EQ(result, "top.sub.net"); } // Escaped divider in SPEF TEST_F(SpefNamespaceTest, SpefToStaEscapedDivider) { // In SPEF, "\." is an escaped divider - char *result = spefToSta("top\\.net", '.', '/', '\\'); - EXPECT_STREQ(result, "top\\/net"); - delete[] result; + std::string result = spefToSta("top\\.net", '.', '/', '\\'); + EXPECT_EQ(result, "top\\/net"); } // Escaped brackets in SPEF TEST_F(SpefNamespaceTest, SpefToStaEscapedBracket) { - char *result = spefToSta("bus\\[0\\]", '.', '/', '\\'); - EXPECT_STREQ(result, "bus\\[0\\]"); - delete[] result; + std::string result = spefToSta("bus\\[0\\]", '.', '/', '\\'); + EXPECT_EQ(result, "bus\\[0\\]"); } // STA to SPEF escaped brackets TEST_F(SpefNamespaceTest, StaToSpefEscapedBracket) { - char *result = staToSpef("bus\\[0\\]", '.', '/', '\\'); - EXPECT_STREQ(result, "bus\\[0\\]"); - delete[] result; + std::string result = staToSpef("bus\\[0\\]", '.', '/', '\\'); + EXPECT_EQ(result, "bus\\[0\\]"); } // SPEF escaped backslash TEST_F(SpefNamespaceTest, SpefToStaEscapedBackslash) { // "\\" in SPEF means literal backslash - char *result = spefToSta("name\\\\end", '.', '/', '\\'); - EXPECT_STREQ(result, "name\\\\end"); - delete[] result; + std::string result = spefToSta("name\\\\end", '.', '/', '\\'); + EXPECT_EQ(result, "name\\\\end"); } // SPEF escape of non-special character TEST_F(SpefNamespaceTest, SpefToStaEscapedNonSpecial) { // "\a" - 'a' is not divider, not bracket, not backslash - char *result = spefToSta("\\a", '.', '/', '\\'); - EXPECT_STREQ(result, "a"); - delete[] result; + std::string result = spefToSta("\\a", '.', '/', '\\'); + EXPECT_EQ(result, "a"); } // STA to SPEF escaping non-alphanumeric characters TEST_F(SpefNamespaceTest, StaToSpefSpecialChars) { // '@' should get escaped in SPEF - char *result = staToSpef("net@1", '.', '/', '\\'); - EXPECT_STREQ(result, "net\\@1"); - delete[] result; + std::string result = staToSpef("net@1", '.', '/', '\\'); + EXPECT_EQ(result, "net\\@1"); } // STA to SPEF: escape for path_escape + non-special char TEST_F(SpefNamespaceTest, StaToSpefEscapedNonSpecial) { // "\\a" - escape + 'a' (not divider, not bracket) - char *result = staToSpef("\\a", '.', '/', '\\'); - EXPECT_STREQ(result, "a"); - delete[] result; + std::string result = staToSpef("\\a", '.', '/', '\\'); + EXPECT_EQ(result, "a"); } // Empty string TEST_F(SpefNamespaceTest, SpefToStaEmpty) { - char *result = spefToSta("", '.', '/', '\\'); - EXPECT_STREQ(result, ""); - delete[] result; + std::string result = spefToSta("", '.', '/', '\\'); + EXPECT_EQ(result, ""); } TEST_F(SpefNamespaceTest, StaToSpefEmpty) { - char *result = staToSpef("", '.', '/', '\\'); - EXPECT_STREQ(result, ""); - delete[] result; + std::string result = staToSpef("", '.', '/', '\\'); + EXPECT_EQ(result, ""); } // Different divider characters TEST_F(SpefNamespaceTest, SpefToStaColonDivider) { - char *result = spefToSta("a:b:c", ':', '.', '\\'); - EXPECT_STREQ(result, "a.b.c"); - delete[] result; + std::string result = spefToSta("a:b:c", ':', '.', '\\'); + EXPECT_EQ(result, "a.b.c"); } TEST_F(SpefNamespaceTest, StaToSpefColonDivider) { - char *result = staToSpef("a.b.c", ':', '.', '\\'); - EXPECT_STREQ(result, "a:b:c"); - delete[] result; + std::string result = staToSpef("a.b.c", ':', '.', '\\'); + EXPECT_EQ(result, "a:b:c"); } // Underscores and digits should pass through in staToSpef TEST_F(SpefNamespaceTest, StaToSpefAlphanumUnderscore) { - char *result = staToSpef("abc_123_XYZ", '.', '/', '\\'); - EXPECT_STREQ(result, "abc_123_XYZ"); - delete[] result; + std::string result = staToSpef("abc_123_XYZ", '.', '/', '\\'); + EXPECT_EQ(result, "abc_123_XYZ"); } // Multiple consecutive dividers TEST_F(SpefNamespaceTest, SpefToStaMultipleDividers) { - char *result = spefToSta("a..b", '.', '/', '\\'); - EXPECT_STREQ(result, "a//b"); - delete[] result; + std::string result = spefToSta("a..b", '.', '/', '\\'); + EXPECT_EQ(result, "a//b"); } // STA escaped divider (path_escape + path_divider) TEST_F(SpefNamespaceTest, StaToSpefEscapedDivider) { // "\/" in STA namespace => "\." in SPEF namespace - char *result = staToSpef("\\/", '.', '/', '\\'); - EXPECT_STREQ(result, "\\."); - delete[] result; + std::string result = staToSpef("\\/", '.', '/', '\\'); + EXPECT_EQ(result, "\\."); } //////////////////////////////////////////////////////////////// @@ -2137,7 +2121,7 @@ TEST_F(DesignParasiticsTest, TimingWithParasitics) { waveform->push_back(0.0f); waveform->push_back(250.0f); - sta_->makeClock("clk", clk_pins, false, 500.0f, waveform, nullptr, + sta_->makeClock("clk", clk_pins, false, 500.0f, waveform, "", sta_->cmdMode()); // Run timing update to exercise delay calculation with parasitics diff --git a/power/test/cpp/TestPower.cc b/power/test/cpp/TestPower.cc index 2c37eb01..f5ee8a83 100644 --- a/power/test/cpp/TestPower.cc +++ b/power/test/cpp/TestPower.cc @@ -231,31 +231,31 @@ TEST_F(PwrActivityTest, OriginName) { PwrActivity activity; activity.setOrigin(PwrActivityOrigin::global); - EXPECT_STREQ(activity.originName(), "global"); + EXPECT_EQ(activity.originName(), "global"); activity.setOrigin(PwrActivityOrigin::input); - EXPECT_STREQ(activity.originName(), "input"); + EXPECT_EQ(activity.originName(), "input"); activity.setOrigin(PwrActivityOrigin::user); - EXPECT_STREQ(activity.originName(), "user"); + EXPECT_EQ(activity.originName(), "user"); activity.setOrigin(PwrActivityOrigin::vcd); - EXPECT_STREQ(activity.originName(), "vcd"); + EXPECT_EQ(activity.originName(), "vcd"); activity.setOrigin(PwrActivityOrigin::saif); - EXPECT_STREQ(activity.originName(), "saif"); + EXPECT_EQ(activity.originName(), "saif"); activity.setOrigin(PwrActivityOrigin::propagated); - EXPECT_STREQ(activity.originName(), "propagated"); + EXPECT_EQ(activity.originName(), "propagated"); activity.setOrigin(PwrActivityOrigin::clock); - EXPECT_STREQ(activity.originName(), "clock"); + EXPECT_EQ(activity.originName(), "clock"); activity.setOrigin(PwrActivityOrigin::constant); - EXPECT_STREQ(activity.originName(), "constant"); + EXPECT_EQ(activity.originName(), "constant"); activity.setOrigin(PwrActivityOrigin::unknown); - EXPECT_STREQ(activity.originName(), "unknown"); + EXPECT_EQ(activity.originName(), "unknown"); } TEST_F(PwrActivityTest, VerySmallDensityClipped) { @@ -346,15 +346,15 @@ TEST_F(PowerResultTest, MultipleIncrements) { TEST_F(PwrActivityTest, OriginNames) { // Test all origin name strings - EXPECT_STREQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::unknown).originName(), "unknown"); - EXPECT_STREQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::global).originName(), "global"); - EXPECT_STREQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::input).originName(), "input"); - EXPECT_STREQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::user).originName(), "user"); - EXPECT_STREQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::vcd).originName(), "vcd"); - EXPECT_STREQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::saif).originName(), "saif"); - EXPECT_STREQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::propagated).originName(), "propagated"); - EXPECT_STREQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::clock).originName(), "clock"); - EXPECT_STREQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::constant).originName(), "constant"); + EXPECT_EQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::unknown).originName(), "unknown"); + EXPECT_EQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::global).originName(), "global"); + EXPECT_EQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::input).originName(), "input"); + EXPECT_EQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::user).originName(), "user"); + EXPECT_EQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::vcd).originName(), "vcd"); + EXPECT_EQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::saif).originName(), "saif"); + EXPECT_EQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::propagated).originName(), "propagated"); + EXPECT_EQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::clock).originName(), "clock"); + EXPECT_EQ(PwrActivity(0.0f, 0.0f, PwrActivityOrigin::constant).originName(), "constant"); } // Construct and test with explicit density/duty @@ -597,15 +597,15 @@ TEST_F(PwrActivityTest, NegativeNearThreshold) { // Test PwrActivity originName for all origins // Covers: PwrActivity::originName exhaustive TEST_F(PwrActivityTest, OriginNameExhaustive) { - EXPECT_STREQ(PwrActivity(0, 0, PwrActivityOrigin::unknown).originName(), "unknown"); - EXPECT_STREQ(PwrActivity(0, 0, PwrActivityOrigin::global).originName(), "global"); - EXPECT_STREQ(PwrActivity(0, 0, PwrActivityOrigin::input).originName(), "input"); - EXPECT_STREQ(PwrActivity(0, 0, PwrActivityOrigin::user).originName(), "user"); - EXPECT_STREQ(PwrActivity(0, 0, PwrActivityOrigin::vcd).originName(), "vcd"); - EXPECT_STREQ(PwrActivity(0, 0, PwrActivityOrigin::saif).originName(), "saif"); - EXPECT_STREQ(PwrActivity(0, 0, PwrActivityOrigin::propagated).originName(), "propagated"); - EXPECT_STREQ(PwrActivity(0, 0, PwrActivityOrigin::clock).originName(), "clock"); - EXPECT_STREQ(PwrActivity(0, 0, PwrActivityOrigin::constant).originName(), "constant"); + EXPECT_EQ(PwrActivity(0, 0, PwrActivityOrigin::unknown).originName(), "unknown"); + EXPECT_EQ(PwrActivity(0, 0, PwrActivityOrigin::global).originName(), "global"); + EXPECT_EQ(PwrActivity(0, 0, PwrActivityOrigin::input).originName(), "input"); + EXPECT_EQ(PwrActivity(0, 0, PwrActivityOrigin::user).originName(), "user"); + EXPECT_EQ(PwrActivity(0, 0, PwrActivityOrigin::vcd).originName(), "vcd"); + EXPECT_EQ(PwrActivity(0, 0, PwrActivityOrigin::saif).originName(), "saif"); + EXPECT_EQ(PwrActivity(0, 0, PwrActivityOrigin::propagated).originName(), "propagated"); + EXPECT_EQ(PwrActivity(0, 0, PwrActivityOrigin::clock).originName(), "clock"); + EXPECT_EQ(PwrActivity(0, 0, PwrActivityOrigin::constant).originName(), "constant"); } //////////////////////////////////////////////////////////////// diff --git a/sdc/test/cpp/TestSdcClasses.cc b/sdc/test/cpp/TestSdcClasses.cc index 66ee9cf1..de5cc696 100644 --- a/sdc/test/cpp/TestSdcClasses.cc +++ b/sdc/test/cpp/TestSdcClasses.cc @@ -3,6 +3,7 @@ #include #include #include +#include #include "Transition.hh" #include "MinMax.hh" #include "ExceptionPath.hh" @@ -217,13 +218,13 @@ protected: // FalsePath with min_max variations TEST_F(SdcExceptionPathTest, FalsePathMinMaxMin) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::min(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::min(), true, ""); EXPECT_TRUE(fp.matches(MinMax::min(), false)); EXPECT_FALSE(fp.matches(MinMax::max(), false)); } TEST_F(SdcExceptionPathTest, FalsePathMinMaxMax) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::max(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::max(), true, ""); EXPECT_FALSE(fp.matches(MinMax::min(), false)); EXPECT_TRUE(fp.matches(MinMax::max(), false)); } @@ -231,12 +232,12 @@ TEST_F(SdcExceptionPathTest, FalsePathMinMaxMax) { // FalsePath with comment TEST_F(SdcExceptionPathTest, FalsePathWithComment) { FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, "test comment"); - EXPECT_STREQ(fp.comment(), "test comment"); + EXPECT_EQ(fp.comment(), "test comment"); } // FalsePath priority constructor TEST_F(SdcExceptionPathTest, FalsePathWithPriority) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, 1234, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, 1234, ""); EXPECT_EQ(fp.priority(), 1234); } @@ -244,145 +245,145 @@ TEST_F(SdcExceptionPathTest, FalsePathWithPriority) { TEST_F(SdcExceptionPathTest, PathDelayWithComment) { PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, false, 1.0e-9f, true, "path delay comment"); - EXPECT_STREQ(pd.comment(), "path delay comment"); + EXPECT_EQ(pd.comment(), "path delay comment"); } // MultiCyclePath with comment TEST_F(SdcExceptionPathTest, MultiCyclePathWithComment) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), false, 2, true, "mcp comment"); - EXPECT_STREQ(mcp.comment(), "mcp comment"); + EXPECT_EQ(mcp.comment(), "mcp comment"); EXPECT_FALSE(mcp.useEndClk()); } // GroupPath with comment TEST_F(SdcExceptionPathTest, GroupPathWithComment) { GroupPath gp("gp", false, nullptr, nullptr, nullptr, true, "gp comment"); - EXPECT_STREQ(gp.comment(), "gp comment"); + EXPECT_EQ(gp.comment(), "gp comment"); } // GroupPath overrides TEST_F(SdcExceptionPathTest, GroupPathOverridesSameNameDefault) { - GroupPath gp1("reg", true, nullptr, nullptr, nullptr, true, nullptr); - GroupPath gp2("reg", true, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp1("reg", true, nullptr, nullptr, nullptr, true, ""); + GroupPath gp2("reg", true, nullptr, nullptr, nullptr, true, ""); EXPECT_TRUE(gp1.overrides(&gp2)); } TEST_F(SdcExceptionPathTest, GroupPathNotOverridesDifferentName) { - GroupPath gp1("reg1", false, nullptr, nullptr, nullptr, true, nullptr); - GroupPath gp2("reg2", false, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp1("reg1", false, nullptr, nullptr, nullptr, true, ""); + GroupPath gp2("reg2", false, nullptr, nullptr, nullptr, true, ""); EXPECT_FALSE(gp1.overrides(&gp2)); } TEST_F(SdcExceptionPathTest, GroupPathNotOverridesDifferentType) { - GroupPath gp("gp", false, nullptr, nullptr, nullptr, true, nullptr); - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + GroupPath gp("gp", false, nullptr, nullptr, nullptr, true, ""); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_FALSE(gp.overrides(&fp)); } // GroupPath mergeable TEST_F(SdcExceptionPathTest, GroupPathMergeableSameName) { - GroupPath gp1("grp", false, nullptr, nullptr, nullptr, true, nullptr); - GroupPath gp2("grp", false, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp1("grp", false, nullptr, nullptr, nullptr, true, ""); + GroupPath gp2("grp", false, nullptr, nullptr, nullptr, true, ""); EXPECT_TRUE(gp1.mergeable(&gp2)); } TEST_F(SdcExceptionPathTest, GroupPathNotMergeableDifferentName) { - GroupPath gp1("grp1", false, nullptr, nullptr, nullptr, true, nullptr); - GroupPath gp2("grp2", false, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp1("grp1", false, nullptr, nullptr, nullptr, true, ""); + GroupPath gp2("grp2", false, nullptr, nullptr, nullptr, true, ""); EXPECT_FALSE(gp1.mergeable(&gp2)); } // PathDelay overrides TEST_F(SdcExceptionPathTest, PathDelayOverridesPathDelay) { PathDelay pd1(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 5.0e-9f, true, nullptr); + 5.0e-9f, true, ""); PathDelay pd2(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 10.0e-9f, true, nullptr); + 10.0e-9f, true, ""); EXPECT_TRUE(pd1.overrides(&pd2)); } TEST_F(SdcExceptionPathTest, PathDelayNotOverridesFalsePath) { PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 5.0e-9f, true, nullptr); - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + 5.0e-9f, true, ""); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_FALSE(pd.overrides(&fp)); } // PathDelay mergeable TEST_F(SdcExceptionPathTest, PathDelayMergeableSame) { PathDelay pd1(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 5.0e-9f, true, nullptr); + 5.0e-9f, true, ""); PathDelay pd2(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 5.0e-9f, true, nullptr); + 5.0e-9f, true, ""); EXPECT_TRUE(pd1.mergeable(&pd2)); } TEST_F(SdcExceptionPathTest, PathDelayNotMergeableDifferentDelay) { PathDelay pd1(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 5.0e-9f, true, nullptr); + 5.0e-9f, true, ""); PathDelay pd2(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 10.0e-9f, true, nullptr); + 10.0e-9f, true, ""); EXPECT_FALSE(pd1.mergeable(&pd2)); } TEST_F(SdcExceptionPathTest, PathDelayNotMergeableDifferentIgnoreLatency) { PathDelay pd1(nullptr, nullptr, nullptr, MinMax::max(), true, false, - 5.0e-9f, true, nullptr); + 5.0e-9f, true, ""); PathDelay pd2(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 5.0e-9f, true, nullptr); + 5.0e-9f, true, ""); EXPECT_FALSE(pd1.mergeable(&pd2)); } // MultiCyclePath overrides TEST_F(SdcExceptionPathTest, MultiCyclePathOverrides) { MultiCyclePath mcp1(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 3, true, nullptr); + true, 3, true, ""); MultiCyclePath mcp2(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 3, true, nullptr); + true, 3, true, ""); EXPECT_TRUE(mcp1.overrides(&mcp2)); } TEST_F(SdcExceptionPathTest, MultiCyclePathNotOverridesFalsePath) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 3, true, nullptr); - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + true, 3, true, ""); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_FALSE(mcp.overrides(&fp)); } // MultiCyclePath mergeable TEST_F(SdcExceptionPathTest, MultiCyclePathMergeable) { MultiCyclePath mcp1(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 3, true, nullptr); + true, 3, true, ""); MultiCyclePath mcp2(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 3, true, nullptr); + true, 3, true, ""); EXPECT_TRUE(mcp1.mergeable(&mcp2)); } TEST_F(SdcExceptionPathTest, MultiCyclePathNotMergeableDifferentMultiplier) { MultiCyclePath mcp1(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 3, true, nullptr); + true, 3, true, ""); MultiCyclePath mcp2(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 5, true, nullptr); + true, 5, true, ""); EXPECT_FALSE(mcp1.mergeable(&mcp2)); } // FalsePath overrides TEST_F(SdcExceptionPathTest, FalsePathOverrides) { - FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); - FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); + FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_TRUE(fp1.overrides(&fp2)); } TEST_F(SdcExceptionPathTest, FalsePathNotOverridesDifferentMinMax) { - FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::min(), true, nullptr); - FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::max(), true, nullptr); + FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::min(), true, ""); + FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::max(), true, ""); EXPECT_FALSE(fp1.overrides(&fp2)); } // ExceptionPath hash TEST_F(SdcExceptionPathTest, DifferentTypeDifferentHash) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); FilterPath flp(nullptr, nullptr, nullptr, true); // Different type priorities generally produce different hashes // (but not guaranteed - just verify the function works) @@ -400,7 +401,7 @@ TEST_F(SdcExceptionPathTest, FromThruToPriorityNone) { // ExceptionState tests TEST_F(SdcExceptionPathTest, StateComplete) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); ExceptionState *state = fp.firstState(); EXPECT_NE(state, nullptr); EXPECT_TRUE(state->isComplete()); @@ -409,7 +410,7 @@ TEST_F(SdcExceptionPathTest, StateComplete) { } TEST_F(SdcExceptionPathTest, StateSetNextState) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); ExceptionState *state = fp.firstState(); // Verify default next state is null EXPECT_EQ(state->nextState(), nullptr); @@ -417,9 +418,9 @@ TEST_F(SdcExceptionPathTest, StateSetNextState) { // ExceptionStateLess TEST_F(SdcExceptionPathTest, StateLessComparison) { - FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); fp1.setId(10); - FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); fp2.setId(20); ExceptionState *s1 = fp1.firstState(); @@ -537,7 +538,7 @@ protected: // Just test that the comparator class can be instantiated // (actual Clock objects require Sdc which requires full setup) TEST_F(ClockCmpTest, ClkNameLessInstantiation) { - ClkNameLess less; + ClockNameLess less; EXPECT_NE(&less, nullptr); } @@ -1285,7 +1286,7 @@ TEST_F(ClockGatingCheckTest, SetMargins) { class TestableSdcCmdComment : public SdcCmdComment { public: TestableSdcCmdComment() : SdcCmdComment() {} - TestableSdcCmdComment(const char *comment) : SdcCmdComment(comment) {} + TestableSdcCmdComment(std::string_view comment) : SdcCmdComment(comment) {} ~TestableSdcCmdComment() {} }; @@ -1293,46 +1294,46 @@ class SdcCmdCommentTest : public ::testing::Test {}; TEST_F(SdcCmdCommentTest, DefaultConstruction) { TestableSdcCmdComment scc; - EXPECT_EQ(scc.comment(), nullptr); + EXPECT_TRUE(scc.comment().empty()); } TEST_F(SdcCmdCommentTest, CommentConstruction) { TestableSdcCmdComment scc("test comment"); - EXPECT_STREQ(scc.comment(), "test comment"); + EXPECT_EQ(scc.comment(), "test comment"); } TEST_F(SdcCmdCommentTest, EmptyCommentConstruction) { TestableSdcCmdComment scc(""); - EXPECT_EQ(scc.comment(), nullptr); + EXPECT_TRUE(scc.comment().empty()); } -TEST_F(SdcCmdCommentTest, NullCommentConstruction) { - TestableSdcCmdComment scc(nullptr); - EXPECT_EQ(scc.comment(), nullptr); +TEST_F(SdcCmdCommentTest, EmptyStringViewConstruction) { + TestableSdcCmdComment scc(std::string_view{}); + EXPECT_TRUE(scc.comment().empty()); } TEST_F(SdcCmdCommentTest, SetComment) { TestableSdcCmdComment scc; - scc.setComment("new comment"); - EXPECT_STREQ(scc.comment(), "new comment"); + scc.setComment(std::string("new comment")); + EXPECT_EQ(scc.comment(), "new comment"); } -TEST_F(SdcCmdCommentTest, SetCommentNull) { +TEST_F(SdcCmdCommentTest, SetCommentEmptyStringView) { TestableSdcCmdComment scc("original"); - scc.setComment(nullptr); - EXPECT_EQ(scc.comment(), nullptr); + scc.setComment(std::string_view{}); + EXPECT_TRUE(scc.comment().empty()); } TEST_F(SdcCmdCommentTest, SetCommentEmpty) { TestableSdcCmdComment scc("original"); - scc.setComment(""); - EXPECT_EQ(scc.comment(), nullptr); + scc.setComment(std::string("")); + EXPECT_TRUE(scc.comment().empty()); } TEST_F(SdcCmdCommentTest, SetCommentReplace) { TestableSdcCmdComment scc("first"); - scc.setComment("second"); - EXPECT_STREQ(scc.comment(), "second"); + scc.setComment(std::string("second")); + EXPECT_EQ(scc.comment(), "second"); } //////////////////////////////////////////////////////////////// @@ -1614,7 +1615,7 @@ TEST_F(SdcInitTest, MakeClockNoPins) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("test_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("test_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("test_clk"); @@ -1626,7 +1627,7 @@ TEST_F(SdcInitTest, MakeClockAndRemove) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("clk1", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("clk1", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("clk1"); @@ -1640,12 +1641,12 @@ TEST_F(SdcInitTest, MultipleClocksQuery) { FloatSeq *wave1 = new FloatSeq; wave1->push_back(0.0); wave1->push_back(5.0); - sta_->makeClock("clk_a", nullptr, false, 10.0, wave1, nullptr, sta_->cmdMode()); + sta_->makeClock("clk_a", nullptr, false, 10.0, wave1, "", sta_->cmdMode()); FloatSeq *wave2 = new FloatSeq; wave2->push_back(0.0); wave2->push_back(2.5); - sta_->makeClock("clk_b", nullptr, false, 5.0, wave2, nullptr, sta_->cmdMode()); + sta_->makeClock("clk_b", nullptr, false, 5.0, wave2, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); ClockSeq clks = sdc->clocks(); @@ -1657,11 +1658,11 @@ TEST_F(SdcInitTest, ClockProperties) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("prop_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("prop_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("prop_clk"); - EXPECT_STREQ(clk->name(), "prop_clk"); + EXPECT_EQ(clk->name(), "prop_clk"); EXPECT_FLOAT_EQ(clk->period(), 10.0); EXPECT_FALSE(clk->isPropagated()); EXPECT_FALSE(clk->isGenerated()); @@ -1674,7 +1675,7 @@ TEST_F(SdcInitTest, ClockSlew) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("slew_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("slew_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("slew_clk"); @@ -1695,7 +1696,7 @@ TEST_F(SdcInitTest, ClockLatencyOnClock) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("lat_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("lat_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("lat_clk"); @@ -1717,7 +1718,7 @@ TEST_F(SdcInitTest, ClockInsertionOnClock) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("ins_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("ins_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("ins_clk"); @@ -1741,7 +1742,7 @@ TEST_F(SdcInitTest, ClockUncertainty) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("unc_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("unc_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("unc_clk"); @@ -1755,12 +1756,12 @@ TEST_F(SdcInitTest, InterClockUncertainty) { FloatSeq *wave1 = new FloatSeq; wave1->push_back(0.0); wave1->push_back(5.0); - sta_->makeClock("iuc_clk1", nullptr, false, 10.0, wave1, nullptr, sta_->cmdMode()); + sta_->makeClock("iuc_clk1", nullptr, false, 10.0, wave1, "", sta_->cmdMode()); FloatSeq *wave2 = new FloatSeq; wave2->push_back(0.0); wave2->push_back(2.5); - sta_->makeClock("iuc_clk2", nullptr, false, 5.0, wave2, nullptr, sta_->cmdMode()); + sta_->makeClock("iuc_clk2", nullptr, false, 5.0, wave2, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk1 = sdc->findClock("iuc_clk1"); @@ -1791,12 +1792,12 @@ TEST_F(SdcInitTest, ClockGroupsOperations) { FloatSeq *wave1 = new FloatSeq; wave1->push_back(0.0); wave1->push_back(5.0); - sta_->makeClock("grp_clk1", nullptr, false, 10.0, wave1, nullptr, sta_->cmdMode()); + sta_->makeClock("grp_clk1", nullptr, false, 10.0, wave1, "", sta_->cmdMode()); FloatSeq *wave2 = new FloatSeq; wave2->push_back(0.0); wave2->push_back(2.5); - sta_->makeClock("grp_clk2", nullptr, false, 5.0, wave2, nullptr, sta_->cmdMode()); + sta_->makeClock("grp_clk2", nullptr, false, 5.0, wave2, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk1 = sdc->findClock("grp_clk1"); @@ -1804,7 +1805,7 @@ TEST_F(SdcInitTest, ClockGroupsOperations) { ASSERT_NE(clk1, nullptr); ASSERT_NE(clk2, nullptr); - ClockGroups *groups = sta_->makeClockGroups("grp1", true, false, false, false, nullptr, sta_->cmdSdc()); + ClockGroups *groups = sta_->makeClockGroups("grp1", true, false, false, false, "", sta_->cmdSdc()); ASSERT_NE(groups, nullptr); ClockSet *clk_set = new ClockSet; clk_set->insert(clk1); @@ -1821,7 +1822,7 @@ TEST_F(SdcInitTest, ClockPropagation) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("prop_clk2", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("prop_clk2", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("prop_clk2"); @@ -1860,7 +1861,7 @@ TEST_F(SdcInitTest, ClockGatingCheckWithClock) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("cgc_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("cgc_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("cgc_clk"); @@ -1879,13 +1880,13 @@ TEST_F(SdcInitTest, ClockGatingCheckWithClock) { TEST_F(SdcInitTest, MakeFalsePath) { Sdc *sdc = sta_->cmdSdc(); size_t before = sdc->exceptions().size(); - sta_->makeFalsePath(nullptr, nullptr, nullptr, MinMaxAll::all(), nullptr, sta_->cmdSdc()); + sta_->makeFalsePath(nullptr, nullptr, nullptr, MinMaxAll::all(), "", sta_->cmdSdc()); EXPECT_GT(sdc->exceptions().size(), before); } // Group path TEST_F(SdcInitTest, MakeGroupPath) { - sta_->makeGroupPath("test_group", false, nullptr, nullptr, nullptr, nullptr, sta_->cmdSdc()); + sta_->makeGroupPath("test_group", false, nullptr, nullptr, nullptr, "", sta_->cmdSdc()); EXPECT_TRUE(sta_->isPathGroupName("test_group", sta_->cmdSdc())); } @@ -1894,7 +1895,7 @@ TEST_F(SdcInitTest, LatchBorrowLimitClock) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("lbl_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("lbl_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("lbl_clk"); @@ -1908,7 +1909,7 @@ TEST_F(SdcInitTest, MinPulseWidthClock) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("mpw_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("mpw_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("mpw_clk"); @@ -1926,7 +1927,7 @@ TEST_F(SdcInitTest, SlewLimitClock) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("sl_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("sl_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("sl_clk"); @@ -1986,7 +1987,7 @@ TEST_F(SdcInitTest, MakeMulticyclePath) { MinMaxAll::all(), true, // use_end_clk 2, // path_multiplier - nullptr, sta_->cmdSdc()); + "", sta_->cmdSdc()); EXPECT_GT(sdc->exceptions().size(), before); } @@ -1994,7 +1995,7 @@ TEST_F(SdcInitTest, MakeMulticyclePath) { TEST_F(SdcInitTest, ResetPath) { Sdc *sdc = sta_->cmdSdc(); size_t before = sdc->exceptions().size(); - sta_->makeFalsePath(nullptr, nullptr, nullptr, MinMaxAll::all(), nullptr, sta_->cmdSdc()); + sta_->makeFalsePath(nullptr, nullptr, nullptr, MinMaxAll::all(), "", sta_->cmdSdc()); size_t after_make = sdc->exceptions().size(); EXPECT_GT(after_make, before); ASSERT_NO_THROW((sta_->resetPath(nullptr, nullptr, nullptr, MinMaxAll::all(), sta_->cmdSdc()))); @@ -2006,7 +2007,7 @@ TEST_F(SdcInitTest, ClockWaveformDetails) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(3.0); - sta_->makeClock("wave_clk", nullptr, false, 8.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("wave_clk", nullptr, false, 8.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("wave_clk"); @@ -2026,7 +2027,7 @@ TEST_F(SdcInitTest, ClockEdges) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("edge_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("edge_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("edge_clk"); @@ -2061,17 +2062,17 @@ TEST_F(SdcInitTest, MultipleClockRemoval) { FloatSeq *w1 = new FloatSeq; w1->push_back(0.0); w1->push_back(5.0); - sta_->makeClock("rm_clk1", nullptr, false, 10.0, w1, nullptr, sta_->cmdMode()); + sta_->makeClock("rm_clk1", nullptr, false, 10.0, w1, "", sta_->cmdMode()); FloatSeq *w2 = new FloatSeq; w2->push_back(0.0); w2->push_back(2.5); - sta_->makeClock("rm_clk2", nullptr, false, 5.0, w2, nullptr, sta_->cmdMode()); + sta_->makeClock("rm_clk2", nullptr, false, 5.0, w2, "", sta_->cmdMode()); FloatSeq *w3 = new FloatSeq; w3->push_back(0.0); w3->push_back(1.0); - sta_->makeClock("rm_clk3", nullptr, false, 2.0, w3, nullptr, sta_->cmdMode()); + sta_->makeClock("rm_clk3", nullptr, false, 2.0, w3, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); EXPECT_EQ(sdc->clocks().size(), 3u); @@ -2113,7 +2114,7 @@ TEST_F(SdcInitTest, DisabledPortsFromTo) { // ExceptionPath: clone, asString, typeString, tighterThan TEST_F(SdcInitTest, FalsePathClone) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); ExceptionPath *cloned = fp.clone(nullptr, nullptr, nullptr, true); EXPECT_NE(cloned, nullptr); EXPECT_TRUE(cloned->isFalse()); @@ -2122,7 +2123,7 @@ TEST_F(SdcInitTest, FalsePathClone) { TEST_F(SdcInitTest, PathDelayClone) { PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 5.0e-9f, true, nullptr); + 5.0e-9f, true, ""); ExceptionPath *cloned = pd.clone(nullptr, nullptr, nullptr, true); EXPECT_NE(cloned, nullptr); EXPECT_TRUE(cloned->isPathDelay()); @@ -2132,7 +2133,7 @@ TEST_F(SdcInitTest, PathDelayClone) { TEST_F(SdcInitTest, MultiCyclePathClone) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 3, true, nullptr); + true, 3, true, ""); ExceptionPath *cloned = mcp.clone(nullptr, nullptr, nullptr, true); EXPECT_NE(cloned, nullptr); EXPECT_TRUE(cloned->isMultiCycle()); @@ -2141,7 +2142,7 @@ TEST_F(SdcInitTest, MultiCyclePathClone) { } TEST_F(SdcInitTest, GroupPathClone) { - GroupPath gp("grp", false, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp("grp", false, nullptr, nullptr, nullptr, true, ""); ExceptionPath *cloned = gp.clone(nullptr, nullptr, nullptr, true); EXPECT_NE(cloned, nullptr); EXPECT_TRUE(cloned->isGroupPath()); @@ -2158,28 +2159,28 @@ TEST_F(SdcInitTest, FilterPathClone) { } TEST_F(SdcInitTest, FalsePathAsString) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); std::string str = fp.to_string(sta_->cmdNetwork()); EXPECT_FALSE(str.empty()); } TEST_F(SdcInitTest, PathDelayAsString) { PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 1.0e-9f, true, nullptr); + 1.0e-9f, true, ""); std::string str = pd.to_string(sta_->cmdNetwork()); EXPECT_FALSE(str.empty()); } TEST_F(SdcInitTest, MultiCyclePathAsString) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 2, true, nullptr); + true, 2, true, ""); std::string str = mcp.to_string(sta_->cmdNetwork()); EXPECT_FALSE(str.empty()); } // ExceptionPath type predicates TEST_F(SdcInitTest, ExceptionTypePredicates) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_TRUE(fp.isFalse()); EXPECT_FALSE(fp.isLoop()); EXPECT_FALSE(fp.isMultiCycle()); @@ -2189,13 +2190,13 @@ TEST_F(SdcInitTest, ExceptionTypePredicates) { EXPECT_EQ(fp.type(), ExceptionPathType::false_path); PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 1.0e-9f, true, nullptr); + 1.0e-9f, true, ""); EXPECT_TRUE(pd.isPathDelay()); EXPECT_FALSE(pd.isFalse()); EXPECT_EQ(pd.type(), ExceptionPathType::path_delay); MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 2, true, nullptr); + true, 2, true, ""); EXPECT_TRUE(mcp.isMultiCycle()); EXPECT_EQ(mcp.type(), ExceptionPathType::multi_cycle); @@ -2203,23 +2204,23 @@ TEST_F(SdcInitTest, ExceptionTypePredicates) { EXPECT_TRUE(flp.isFilter()); EXPECT_EQ(flp.type(), ExceptionPathType::filter); - GroupPath gp("g", false, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp("g", false, nullptr, nullptr, nullptr, true, ""); EXPECT_TRUE(gp.isGroupPath()); EXPECT_EQ(gp.type(), ExceptionPathType::group_path); } // ExceptionPath tighterThan TEST_F(SdcInitTest, FalsePathTighterThan) { - FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); - FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); + FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_FALSE(fp1.tighterThan(&fp2)); } TEST_F(SdcInitTest, PathDelayTighterThan) { PathDelay pd1(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 5.0e-9f, true, nullptr); + 5.0e-9f, true, ""); PathDelay pd2(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 10.0e-9f, true, nullptr); + 10.0e-9f, true, ""); // Smaller delay is tighter for max EXPECT_TRUE(pd1.tighterThan(&pd2)); EXPECT_FALSE(pd2.tighterThan(&pd1)); @@ -2227,9 +2228,9 @@ TEST_F(SdcInitTest, PathDelayTighterThan) { TEST_F(SdcInitTest, MultiCyclePathTighterThan) { MultiCyclePath mcp1(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 2, true, nullptr); + true, 2, true, ""); MultiCyclePath mcp2(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 5, true, nullptr); + true, 5, true, ""); EXPECT_TRUE(mcp1.tighterThan(&mcp2)); } @@ -2240,28 +2241,28 @@ TEST_F(SdcInitTest, FilterPathTighterThan) { } TEST_F(SdcInitTest, GroupPathTighterThan) { - GroupPath gp1("g1", false, nullptr, nullptr, nullptr, true, nullptr); - GroupPath gp2("g2", false, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp1("g1", false, nullptr, nullptr, nullptr, true, ""); + GroupPath gp2("g2", false, nullptr, nullptr, nullptr, true, ""); EXPECT_FALSE(gp1.tighterThan(&gp2)); } // ExceptionPath typePriority TEST_F(SdcInitTest, ExceptionTypePriority) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_EQ(fp.typePriority(), ExceptionPath::falsePathPriority()); PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 1.0e-9f, true, nullptr); + 1.0e-9f, true, ""); EXPECT_EQ(pd.typePriority(), ExceptionPath::pathDelayPriority()); MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 2, true, nullptr); + true, 2, true, ""); EXPECT_EQ(mcp.typePriority(), ExceptionPath::multiCyclePathPriority()); FilterPath flp(nullptr, nullptr, nullptr, true); EXPECT_EQ(flp.typePriority(), ExceptionPath::filterPathPriority()); - GroupPath gp("g", false, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp("g", false, nullptr, nullptr, nullptr, true, ""); EXPECT_EQ(gp.typePriority(), ExceptionPath::groupPathPriority()); } @@ -2282,7 +2283,7 @@ TEST_F(SdcInitTest, LoopPathMergeable) { // ExceptionPath setId and priority TEST_F(SdcInitTest, ExceptionPathSetIdPriority) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); fp.setId(42); EXPECT_EQ(fp.id(), 42u); fp.setPriority(5000); @@ -2291,7 +2292,7 @@ TEST_F(SdcInitTest, ExceptionPathSetIdPriority) { // ExceptionPath default handlers TEST_F(SdcInitTest, ExceptionPathDefaultHandlers) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_FALSE(fp.useEndClk()); EXPECT_EQ(fp.pathMultiplier(), 0); EXPECT_FLOAT_EQ(fp.delay(), 0.0f); @@ -2304,12 +2305,12 @@ TEST_F(SdcInitTest, ExceptionPathDefaultHandlers) { // PathDelay ignoreClkLatency and breakPath TEST_F(SdcInitTest, PathDelayIgnoreAndBreak) { PathDelay pd1(nullptr, nullptr, nullptr, MinMax::max(), true, true, - 1.0e-9f, true, nullptr); + 1.0e-9f, true, ""); EXPECT_TRUE(pd1.ignoreClkLatency()); EXPECT_TRUE(pd1.breakPath()); PathDelay pd2(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 1.0e-9f, true, nullptr); + 1.0e-9f, true, ""); EXPECT_FALSE(pd2.ignoreClkLatency()); EXPECT_FALSE(pd2.breakPath()); } @@ -2317,7 +2318,7 @@ TEST_F(SdcInitTest, PathDelayIgnoreAndBreak) { // MultiCyclePath priority with MinMax TEST_F(SdcInitTest, MultiCyclePathPriorityWithMinMax) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 3, true, nullptr); + true, 3, true, ""); int p_min = mcp.priority(MinMax::min()); int p_max = mcp.priority(MinMax::max()); EXPECT_GE(p_min, 0); @@ -2327,23 +2328,23 @@ TEST_F(SdcInitTest, MultiCyclePathPriorityWithMinMax) { // MultiCyclePath pathMultiplier with MinMax TEST_F(SdcInitTest, MultiCyclePathMultiplierWithMinMax) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 4, true, nullptr); + true, 4, true, ""); EXPECT_EQ(mcp.pathMultiplier(MinMax::max()), 4); } // MultiCyclePath matches min_max exactly TEST_F(SdcInitTest, MultiCyclePathMatchesExact) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::min(), - true, 3, true, nullptr); + true, 3, true, ""); EXPECT_TRUE(mcp.matches(MinMax::min(), true)); EXPECT_FALSE(mcp.matches(MinMax::max(), true)); } // GroupPath isDefault TEST_F(SdcInitTest, GroupPathIsDefault) { - GroupPath gp1("reg", true, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp1("reg", true, nullptr, nullptr, nullptr, true, ""); EXPECT_TRUE(gp1.isDefault()); - GroupPath gp2("cust", false, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp2("cust", false, nullptr, nullptr, nullptr, true, ""); EXPECT_FALSE(gp2.isDefault()); } @@ -2356,7 +2357,7 @@ TEST_F(SdcInitTest, FilterPathOverrides) { TEST_F(SdcInitTest, FilterPathNotOverridesDifferent) { FilterPath flp(nullptr, nullptr, nullptr, true); - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_FALSE(flp.overrides(&fp)); } @@ -2369,14 +2370,14 @@ TEST_F(SdcInitTest, FilterPathMergeable) { // ExceptionPtIterator TEST_F(SdcInitTest, ExceptionPtIteratorNoPoints) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); ExceptionPtIterator iter(&fp); EXPECT_FALSE(iter.hasNext()); } // ExceptionPath from/thrus/to accessors TEST_F(SdcInitTest, ExceptionPathAccessors) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_EQ(fp.from(), nullptr); EXPECT_EQ(fp.thrus(), nullptr); EXPECT_EQ(fp.to(), nullptr); @@ -2385,7 +2386,7 @@ TEST_F(SdcInitTest, ExceptionPathAccessors) { // ExceptionPath firstPt with no points TEST_F(SdcInitTest, ExceptionPathFirstPtNull) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_EQ(fp.firstPt(), nullptr); } @@ -2526,7 +2527,7 @@ TEST_F(SdcInitTest, SdcSlewLimitPort) { FloatSeq *wave = new FloatSeq; wave->push_back(0.0); wave->push_back(5.0); - sta_->makeClock("sl_test_clk", nullptr, false, 10.0, wave, nullptr, sta_->cmdMode()); + sta_->makeClock("sl_test_clk", nullptr, false, 10.0, wave, "", sta_->cmdMode()); Clock *clk = sdc->findClock("sl_test_clk"); sdc->setSlewLimit(clk, RiseFallBoth::riseFall(), PathClkOrData::clk, MinMax::max(), 2.0); @@ -2544,7 +2545,7 @@ TEST_F(SdcInitTest, ClockPeriodAfterCreate) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("sp_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("sp_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("sp_clk"); EXPECT_FLOAT_EQ(clk->period(), 10.0); @@ -2556,7 +2557,7 @@ TEST_F(SdcInitTest, ClockWaveformInvalid) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("wi_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("wi_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("wi_clk"); EXPECT_TRUE(clk->waveformValid()); @@ -2569,7 +2570,7 @@ TEST_F(SdcInitTest, ClockSetAddToPins) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("atp_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("atp_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("atp_clk"); clk->setAddToPins(true); @@ -2583,7 +2584,7 @@ TEST_F(SdcInitTest, ClockIdealGenerated) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("ig_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("ig_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("ig_clk"); EXPECT_TRUE(clk->isIdeal()); @@ -2595,7 +2596,7 @@ TEST_F(SdcInitTest, ClockIndex) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("idx_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("idx_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("idx_clk"); EXPECT_GE(clk->index(), 0); @@ -2606,7 +2607,7 @@ TEST_F(SdcInitTest, ClockEdgeDetails) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("ced_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("ced_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("ced_clk"); ClockEdge *rise = clk->edge(RiseFall::rise()); @@ -2631,7 +2632,7 @@ TEST_F(SdcInitTest, ClockSlewSetGet) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("csl_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("csl_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("csl_clk"); clk->setSlew(RiseFallBoth::riseFall(), MinMaxAll::all(), 0.5); @@ -2657,7 +2658,7 @@ TEST_F(SdcInitTest, ClockUncertaintySetGet) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("cu_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("cu_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("cu_clk"); clk->setUncertainty(SetupHoldAll::all(), 0.1); @@ -2676,7 +2677,7 @@ TEST_F(SdcInitTest, ClockSlewLimitSetGet) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("csl2_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("csl2_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("csl2_clk"); clk->setSlewLimit(RiseFallBoth::riseFall(), PathClkOrData::clk, @@ -2694,17 +2695,17 @@ TEST_F(SdcInitTest, SdcFindClocksMatching) { FloatSeq *wave = new FloatSeq; wave->push_back(0.0); wave->push_back(5.0); - sta_->makeClock("match_clk1", nullptr, false, 10.0, wave, nullptr, sta_->cmdMode()); + sta_->makeClock("match_clk1", nullptr, false, 10.0, wave, "", sta_->cmdMode()); FloatSeq *wave2 = new FloatSeq; wave2->push_back(0.0); wave2->push_back(2.5); - sta_->makeClock("match_clk2", nullptr, false, 5.0, wave2, nullptr, sta_->cmdMode()); + sta_->makeClock("match_clk2", nullptr, false, 5.0, wave2, "", sta_->cmdMode()); FloatSeq *wave3 = new FloatSeq; wave3->push_back(0.0); wave3->push_back(1.0); - sta_->makeClock("other_clk", nullptr, false, 2.0, wave3, nullptr, sta_->cmdMode()); + sta_->makeClock("other_clk", nullptr, false, 2.0, wave3, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); PatternMatch pattern("match_*"); @@ -2717,19 +2718,19 @@ TEST_F(SdcInitTest, SdcSortedClocks) { FloatSeq *wave1 = new FloatSeq; wave1->push_back(0.0); wave1->push_back(5.0); - sta_->makeClock("b_clk", nullptr, false, 10.0, wave1, nullptr, sta_->cmdMode()); + sta_->makeClock("b_clk", nullptr, false, 10.0, wave1, "", sta_->cmdMode()); FloatSeq *wave2 = new FloatSeq; wave2->push_back(0.0); wave2->push_back(2.5); - sta_->makeClock("a_clk", nullptr, false, 5.0, wave2, nullptr, sta_->cmdMode()); + sta_->makeClock("a_clk", nullptr, false, 5.0, wave2, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); ClockSeq sorted = sdc->sortedClocks(); EXPECT_EQ(sorted.size(), 2u); // Should be sorted by name: a_clk before b_clk - EXPECT_STREQ(sorted[0]->name(), "a_clk"); - EXPECT_STREQ(sorted[1]->name(), "b_clk"); + EXPECT_EQ(sorted[0]->name(), "a_clk"); + EXPECT_EQ(sorted[1]->name(), "b_clk"); } // Sdc: defaultArrivalClock @@ -2778,7 +2779,7 @@ TEST_F(SdcInitTest, SdcGroupPathsAccessor) { auto &gp = sdc->groupPaths(); EXPECT_TRUE(gp.empty()); - sta_->makeGroupPath("test_grp", false, nullptr, nullptr, nullptr, nullptr, sta_->cmdSdc()); + sta_->makeGroupPath("test_grp", false, nullptr, nullptr, nullptr, "", sta_->cmdSdc()); EXPECT_FALSE(sdc->groupPaths().empty()); } @@ -2844,7 +2845,7 @@ TEST_F(SdcInitTest, SdcMakeExceptionFromThruTo) { TEST_F(SdcInitTest, SdcMakePathDelay) { ASSERT_NO_THROW(( [&](){ sta_->makePathDelay(nullptr, nullptr, nullptr, - MinMax::max(), false, false, 5.0e-9f, nullptr, sta_->cmdSdc()); + MinMax::max(), false, false, 5.0e-9f, "", sta_->cmdSdc()); }() )); } @@ -2864,12 +2865,12 @@ TEST_F(SdcInitTest, SdcSameClockGroup) { FloatSeq *wave1 = new FloatSeq; wave1->push_back(0.0); wave1->push_back(5.0); - sta_->makeClock("scg_clk1", nullptr, false, 10.0, wave1, nullptr, sta_->cmdMode()); + sta_->makeClock("scg_clk1", nullptr, false, 10.0, wave1, "", sta_->cmdMode()); FloatSeq *wave2 = new FloatSeq; wave2->push_back(0.0); wave2->push_back(2.5); - sta_->makeClock("scg_clk2", nullptr, false, 5.0, wave2, nullptr, sta_->cmdMode()); + sta_->makeClock("scg_clk2", nullptr, false, 5.0, wave2, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk1 = sdc->findClock("scg_clk1"); @@ -2954,7 +2955,7 @@ TEST_F(SdcInitTest, CycleAcctingFunctorsCompile) { FloatSeq *wave = new FloatSeq; wave->push_back(0.0); wave->push_back(4.0); - sta_->makeClock("cycle_functor_clk", nullptr, false, 8.0, wave, nullptr, sta_->cmdMode()); + sta_->makeClock("cycle_functor_clk", nullptr, false, 8.0, wave, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("cycle_functor_clk"); ASSERT_NE(clk, nullptr); @@ -2975,12 +2976,12 @@ TEST_F(SdcInitTest, ClockComparisons) { FloatSeq *wave1 = new FloatSeq; wave1->push_back(0.0); wave1->push_back(5.0); - sta_->makeClock("cmp_a", nullptr, false, 10.0, wave1, nullptr, sta_->cmdMode()); + sta_->makeClock("cmp_a", nullptr, false, 10.0, wave1, "", sta_->cmdMode()); FloatSeq *wave2 = new FloatSeq; wave2->push_back(0.0); wave2->push_back(2.5); - sta_->makeClock("cmp_b", nullptr, false, 5.0, wave2, nullptr, sta_->cmdMode()); + sta_->makeClock("cmp_b", nullptr, false, 5.0, wave2, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clkA = sdc->findClock("cmp_a"); @@ -3006,12 +3007,12 @@ TEST_F(SdcInitTest, ClockNameLessComparison) { FloatSeq *wave1 = new FloatSeq; wave1->push_back(0.0); wave1->push_back(5.0); - sta_->makeClock("alpha_clk", nullptr, false, 10.0, wave1, nullptr, sta_->cmdMode()); + sta_->makeClock("alpha_clk", nullptr, false, 10.0, wave1, "", sta_->cmdMode()); FloatSeq *wave2 = new FloatSeq; wave2->push_back(0.0); wave2->push_back(2.5); - sta_->makeClock("beta_clk", nullptr, false, 5.0, wave2, nullptr, sta_->cmdMode()); + sta_->makeClock("beta_clk", nullptr, false, 5.0, wave2, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *alpha = sdc->findClock("alpha_clk"); @@ -3021,7 +3022,7 @@ TEST_F(SdcInitTest, ClockNameLessComparison) { EXPECT_TRUE(less(alpha, beta)); EXPECT_FALSE(less(beta, alpha)); - ClkNameLess clk_less; + ClockNameLess clk_less; EXPECT_TRUE(clk_less(alpha, beta)); EXPECT_FALSE(clk_less(beta, alpha)); } @@ -3031,12 +3032,12 @@ TEST_F(SdcInitTest, InterClockUncertaintyLessComparison) { FloatSeq *wave1 = new FloatSeq; wave1->push_back(0.0); wave1->push_back(5.0); - sta_->makeClock("icul_clk1", nullptr, false, 10.0, wave1, nullptr, sta_->cmdMode()); + sta_->makeClock("icul_clk1", nullptr, false, 10.0, wave1, "", sta_->cmdMode()); FloatSeq *wave2 = new FloatSeq; wave2->push_back(0.0); wave2->push_back(2.5); - sta_->makeClock("icul_clk2", nullptr, false, 5.0, wave2, nullptr, sta_->cmdMode()); + sta_->makeClock("icul_clk2", nullptr, false, 5.0, wave2, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk1 = sdc->findClock("icul_clk1"); @@ -3057,12 +3058,12 @@ TEST_F(SdcInitTest, ClockSortByName) { FloatSeq *wave1 = new FloatSeq; wave1->push_back(0.0); wave1->push_back(5.0); - sta_->makeClock("zz_clk", nullptr, false, 10.0, wave1, nullptr, sta_->cmdMode()); + sta_->makeClock("zz_clk", nullptr, false, 10.0, wave1, "", sta_->cmdMode()); FloatSeq *wave2 = new FloatSeq; wave2->push_back(0.0); wave2->push_back(2.5); - sta_->makeClock("aa_clk", nullptr, false, 5.0, wave2, nullptr, sta_->cmdMode()); + sta_->makeClock("aa_clk", nullptr, false, 5.0, wave2, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *zz = sdc->findClock("zz_clk"); @@ -3073,8 +3074,8 @@ TEST_F(SdcInitTest, ClockSortByName) { clk_set.insert(aa); ClockSeq sorted = sortByName(&clk_set); EXPECT_EQ(sorted.size(), 2u); - EXPECT_STREQ(sorted[0]->name(), "aa_clk"); - EXPECT_STREQ(sorted[1]->name(), "zz_clk"); + EXPECT_EQ(sorted[0]->name(), "aa_clk"); + EXPECT_EQ(sorted[1]->name(), "zz_clk"); } // logicValueString @@ -3106,7 +3107,7 @@ TEST_F(SdcInitTest, FilterPathResetMatch) { // ExceptionPath hash with missing pt TEST_F(SdcInitTest, ExceptionPathHashMissingPt) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); size_t h = fp.hash(nullptr); EXPECT_GE(h, 0u); } @@ -3116,7 +3117,7 @@ TEST_F(SdcInitTest, ClockSetSlew) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("slew_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("slew_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("slew_clk"); clk->setSlew(RiseFallBoth::riseFall(), MinMaxAll::all(), 0.5); @@ -3135,7 +3136,7 @@ TEST_F(SdcInitTest, ClockSetUncertainty) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("unc_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("unc_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("unc_clk"); clk->setUncertainty(MinMax::max(), 0.1f); @@ -3154,7 +3155,7 @@ TEST_F(SdcInitTest, ClockSetSlewLimit) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("sl_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("sl_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("sl_clk"); clk->setSlewLimit(RiseFallBoth::riseFall(), PathClkOrData::clk, @@ -3172,7 +3173,7 @@ TEST_F(SdcInitTest, ClockIsGeneratedFalse) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("gen_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("gen_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("gen_clk"); EXPECT_FALSE(clk->isGenerated()); @@ -3183,7 +3184,7 @@ TEST_F(SdcInitTest, ClockEdgeProperties) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("edge_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("edge_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("edge_clk"); ClockEdge *rise_edge = clk->edge(RiseFall::rise()); @@ -3204,11 +3205,11 @@ TEST_F(SdcInitTest, ClkEdgeCmpLess) { FloatSeq *waveform1 = new FloatSeq; waveform1->push_back(0.0); waveform1->push_back(2.5); - sta_->makeClock("cmp_clk1", nullptr, false, 5.0, waveform1, nullptr, sta_->cmdMode()); + sta_->makeClock("cmp_clk1", nullptr, false, 5.0, waveform1, "", sta_->cmdMode()); FloatSeq *waveform2 = new FloatSeq; waveform2->push_back(0.0); waveform2->push_back(5.0); - sta_->makeClock("cmp_clk2", nullptr, false, 10.0, waveform2, nullptr, sta_->cmdMode()); + sta_->makeClock("cmp_clk2", nullptr, false, 10.0, waveform2, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk1 = sdc->findClock("cmp_clk1"); Clock *clk2 = sdc->findClock("cmp_clk2"); @@ -3227,11 +3228,11 @@ TEST_F(SdcInitTest, InterClockUncertaintyOps) { FloatSeq *waveform1 = new FloatSeq; waveform1->push_back(0.0); waveform1->push_back(2.5); - sta_->makeClock("icu_clk1", nullptr, false, 5.0, waveform1, nullptr, sta_->cmdMode()); + sta_->makeClock("icu_clk1", nullptr, false, 5.0, waveform1, "", sta_->cmdMode()); FloatSeq *waveform2 = new FloatSeq; waveform2->push_back(0.0); waveform2->push_back(5.0); - sta_->makeClock("icu_clk2", nullptr, false, 10.0, waveform2, nullptr, sta_->cmdMode()); + sta_->makeClock("icu_clk2", nullptr, false, 10.0, waveform2, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk1 = sdc->findClock("icu_clk1"); Clock *clk2 = sdc->findClock("icu_clk2"); @@ -3259,8 +3260,8 @@ TEST_F(SdcInitTest, InterClockUncertaintyOps) { TEST_F(SdcInitTest, ExceptionPathLessComparator) { ASSERT_NO_THROW(( [&](){ ExceptionPathLess less(sta_->cmdNetwork()); - FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); - FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); + FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); fp1.setId(1); fp2.setId(2); less(&fp1, &fp2); @@ -3272,7 +3273,7 @@ TEST_F(SdcInitTest, ExceptionPtIteratorWithThrus) { ExceptionThruSeq *thrus = new ExceptionThruSeq; thrus->push_back(new ExceptionThru(nullptr, nullptr, nullptr, RiseFallBoth::riseFall(), true, nullptr)); - FalsePath fp(nullptr, thrus, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, thrus, nullptr, MinMaxAll::all(), true, ""); ExceptionPtIterator iter(&fp); int count = 0; while (iter.hasNext()) { @@ -3289,11 +3290,11 @@ TEST_F(SdcInitTest, ClockIndexLessComparator) { FloatSeq *waveform1 = new FloatSeq; waveform1->push_back(0.0); waveform1->push_back(2.5); - sta_->makeClock("idx_clk1", nullptr, false, 5.0, waveform1, nullptr, sta_->cmdMode()); + sta_->makeClock("idx_clk1", nullptr, false, 5.0, waveform1, "", sta_->cmdMode()); FloatSeq *waveform2 = new FloatSeq; waveform2->push_back(0.0); waveform2->push_back(5.0); - sta_->makeClock("idx_clk2", nullptr, false, 10.0, waveform2, nullptr, sta_->cmdMode()); + sta_->makeClock("idx_clk2", nullptr, false, 10.0, waveform2, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk1 = sdc->findClock("idx_clk1"); Clock *clk2 = sdc->findClock("idx_clk2"); @@ -3444,7 +3445,7 @@ TEST_F(SdcInitTest, CycleAcctingEdges) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("ca_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("ca_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("ca_clk"); ClockEdge *rise = clk->edge(RiseFall::rise()); @@ -3461,7 +3462,7 @@ TEST_F(SdcInitTest, CycleAcctingDefaultArrival) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("ca2_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("ca2_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("ca2_clk"); ClockEdge *rise = clk->edge(RiseFall::rise()); @@ -3477,7 +3478,7 @@ TEST_F(SdcInitTest, CycleAcctingHashEqualLess) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("cah_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("cah_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("cah_clk"); ClockEdge *rise = clk->edge(RiseFall::rise()); @@ -3928,7 +3929,7 @@ TEST_F(SdcInitTest, CycleAcctingConstruct) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("ca_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("ca_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("ca_clk"); EXPECT_NE(clk, nullptr); @@ -3946,7 +3947,7 @@ TEST_F(SdcInitTest, ClockIsVirtual) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("virt_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("virt_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("virt_clk"); EXPECT_NE(clk, nullptr); @@ -3959,7 +3960,7 @@ TEST_F(SdcInitTest, ClockDefaultPin) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("dp_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("dp_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Sdc *sdc = sta_->cmdSdc(); Clock *clk = sdc->findClock("dp_clk"); const Pin *dp = clk->defaultPin(); @@ -4100,7 +4101,7 @@ TEST_F(SdcInitTest, SdcRemoveClockGroups) { TEST_F(SdcInitTest, SdcRemoveClockGroupsLogicallyExclusive) { ASSERT_NO_THROW(( [&](){ Sdc *sdc = sta_->cmdSdc(); - sdc->makeClockGroups("le_grp", true, false, false, false, nullptr); + sdc->makeClockGroups("le_grp", true, false, false, false, ""); sdc->removeClockGroupsLogicallyExclusive("le_grp"); }() )); @@ -4109,7 +4110,7 @@ TEST_F(SdcInitTest, SdcRemoveClockGroupsLogicallyExclusive) { TEST_F(SdcInitTest, SdcRemoveClockGroupsPhysicallyExclusive) { ASSERT_NO_THROW(( [&](){ Sdc *sdc = sta_->cmdSdc(); - sdc->makeClockGroups("pe_grp", false, true, false, false, nullptr); + sdc->makeClockGroups("pe_grp", false, true, false, false, ""); sdc->removeClockGroupsPhysicallyExclusive("pe_grp"); }() )); @@ -4118,7 +4119,7 @@ TEST_F(SdcInitTest, SdcRemoveClockGroupsPhysicallyExclusive) { TEST_F(SdcInitTest, SdcRemoveClockGroupsAsynchronous) { ASSERT_NO_THROW(( [&](){ Sdc *sdc = sta_->cmdSdc(); - sdc->makeClockGroups("async_grp", false, false, true, false, nullptr); + sdc->makeClockGroups("async_grp", false, false, true, false, ""); sdc->removeClockGroupsAsynchronous("async_grp"); }() )); @@ -4263,7 +4264,7 @@ TEST_F(SdcInitTest, SdcSetClockSlew) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("slew_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("slew_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Clock *clk = sdc->findClock("slew_clk"); sdc->setClockSlew(clk, RiseFallBoth::riseFall(), MinMaxAll::all(), 0.1f); sdc->removeClockSlew(clk); @@ -4278,7 +4279,7 @@ TEST_F(SdcInitTest, SdcSetClockLatency) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("lat_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("lat_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Clock *clk = sdc->findClock("lat_clk"); sdc->setClockLatency(clk, nullptr, RiseFallBoth::riseFall(), MinMaxAll::all(), 0.5f); sdc->removeClockLatency(clk, nullptr); @@ -4292,7 +4293,7 @@ TEST_F(SdcInitTest, SdcClockLatencyQuery) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("latq_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("latq_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Clock *clk = sdc->findClock("latq_clk"); sdc->setClockLatency(clk, nullptr, RiseFallBoth::riseFall(), MinMaxAll::all(), 1.0f); float lat = sdc->clockLatency(clk, RiseFall::rise(), MinMax::max()); @@ -4305,7 +4306,7 @@ TEST_F(SdcInitTest, SdcSetClockInsertion) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("ins_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("ins_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Clock *clk = sdc->findClock("ins_clk"); sdc->setClockInsertion(clk, nullptr, RiseFallBoth::riseFall(), MinMaxAll::all(), EarlyLateAll::all(), 0.2f); @@ -4319,7 +4320,7 @@ TEST_F(SdcInitTest, SdcClockInsertionQuery) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("insq_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("insq_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Clock *clk = sdc->findClock("insq_clk"); sdc->setClockInsertion(clk, nullptr, RiseFallBoth::riseFall(), MinMaxAll::all(), EarlyLateAll::all(), 0.3f); @@ -4335,11 +4336,11 @@ TEST_F(SdcInitTest, SdcSetInterClockUncertainty) { FloatSeq *waveform1 = new FloatSeq; waveform1->push_back(0.0); waveform1->push_back(5.0); - sta_->makeClock("unc_clk1", nullptr, false, 10.0, waveform1, nullptr, sta_->cmdMode()); + sta_->makeClock("unc_clk1", nullptr, false, 10.0, waveform1, "", sta_->cmdMode()); FloatSeq *waveform2 = new FloatSeq; waveform2->push_back(0.0); waveform2->push_back(2.5); - sta_->makeClock("unc_clk2", nullptr, false, 5.0, waveform2, nullptr, sta_->cmdMode()); + sta_->makeClock("unc_clk2", nullptr, false, 5.0, waveform2, "", sta_->cmdMode()); Clock *clk1 = sdc->findClock("unc_clk1"); Clock *clk2 = sdc->findClock("unc_clk2"); sdc->setClockUncertainty(clk1, RiseFallBoth::riseFall(), @@ -4358,11 +4359,11 @@ TEST_F(SdcInitTest, SdcSameClockGroupNoGroups) { FloatSeq *waveform1 = new FloatSeq; waveform1->push_back(0.0); waveform1->push_back(5.0); - sta_->makeClock("scg_c1", nullptr, false, 10.0, waveform1, nullptr, sta_->cmdMode()); + sta_->makeClock("scg_c1", nullptr, false, 10.0, waveform1, "", sta_->cmdMode()); FloatSeq *waveform2 = new FloatSeq; waveform2->push_back(0.0); waveform2->push_back(5.0); - sta_->makeClock("scg_c2", nullptr, false, 10.0, waveform2, nullptr, sta_->cmdMode()); + sta_->makeClock("scg_c2", nullptr, false, 10.0, waveform2, "", sta_->cmdMode()); Clock *c1 = sdc->findClock("scg_c1"); Clock *c2 = sdc->findClock("scg_c2"); // Without groups, clocks are in same group @@ -4433,7 +4434,7 @@ TEST_F(SdcInitTest, SdcSetLatchBorrowLimitClock) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("lbl_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("lbl_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Clock *clk = sdc->findClock("lbl_clk"); sdc->setLatchBorrowLimit(clk, 3.0f); @@ -4447,7 +4448,7 @@ TEST_F(SdcInitTest, SdcSetMinPulseWidthClock) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("mpw_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("mpw_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Clock *clk = sdc->findClock("mpw_clk"); sdc->setMinPulseWidth(clk, RiseFallBoth::riseFall(), 1.0f); @@ -4485,7 +4486,7 @@ TEST_F(SdcInitTest, SdcSwapClockInsertions) { // ExceptionPath type queries TEST_F(SdcExceptionPathTest, FalsePathIsFalse) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_TRUE(fp.isFalse()); EXPECT_FALSE(fp.isMultiCycle()); EXPECT_FALSE(fp.isPathDelay()); @@ -4498,7 +4499,7 @@ TEST_F(SdcExceptionPathTest, FalsePathIsFalse) { TEST_F(SdcExceptionPathTest, MultiCyclePathIsMultiCycle) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - false, 2, true, nullptr); + false, 2, true, ""); EXPECT_TRUE(mcp.isMultiCycle()); EXPECT_FALSE(mcp.isFalse()); EXPECT_EQ(mcp.pathMultiplier(), 2); @@ -4507,13 +4508,13 @@ TEST_F(SdcExceptionPathTest, MultiCyclePathIsMultiCycle) { TEST_F(SdcExceptionPathTest, MultiCyclePathUseEndClk) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 3, true, nullptr); + true, 3, true, ""); EXPECT_TRUE(mcp.useEndClk()); } TEST_F(SdcExceptionPathTest, PathDelayIsPathDelay) { PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 5.0e-9f, true, nullptr); + 5.0e-9f, true, ""); EXPECT_TRUE(pd.isPathDelay()); EXPECT_FALSE(pd.isFalse()); EXPECT_FLOAT_EQ(pd.delay(), 5.0e-9f); @@ -4524,18 +4525,18 @@ TEST_F(SdcExceptionPathTest, PathDelayIsPathDelay) { TEST_F(SdcExceptionPathTest, PathDelayBreakPath) { PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, true, - 1.0e-9f, true, nullptr); + 1.0e-9f, true, ""); EXPECT_TRUE(pd.breakPath()); } TEST_F(SdcExceptionPathTest, PathDelayIgnoreClkLatency) { PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), true, false, - 1.0e-9f, true, nullptr); + 1.0e-9f, true, ""); EXPECT_TRUE(pd.ignoreClkLatency()); } TEST_F(SdcExceptionPathTest, GroupPathIsGroupPath) { - GroupPath gp("grp", false, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp("grp", false, nullptr, nullptr, nullptr, true, ""); EXPECT_TRUE(gp.isGroupPath()); EXPECT_FALSE(gp.isFalse()); EXPECT_EQ(gp.name(), "grp"); @@ -4544,13 +4545,13 @@ TEST_F(SdcExceptionPathTest, GroupPathIsGroupPath) { } TEST_F(SdcExceptionPathTest, GroupPathDefault) { - GroupPath gp("grp_def", true, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp("grp_def", true, nullptr, nullptr, nullptr, true, ""); EXPECT_TRUE(gp.isDefault()); } // ExceptionPath: priority and hash TEST_F(SdcExceptionPathTest, ExceptionPathPriority) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); int prio = fp.priority(MinMax::max()); // FalsePath has well-defined priority EXPECT_GT(prio, 0); @@ -4558,7 +4559,7 @@ TEST_F(SdcExceptionPathTest, ExceptionPathPriority) { // ExceptionPtIterator TEST_F(SdcExceptionPathTest, ExceptionPtIteratorEmpty) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); ExceptionPtIterator iter(&fp); // With all nullptr from/thru/to, should have no points EXPECT_FALSE(iter.hasNext()); @@ -4663,11 +4664,11 @@ TEST_F(SdcInitTest, ClockPairLessOp) { FloatSeq *w1 = new FloatSeq; w1->push_back(0.0); w1->push_back(5.0); - sta_->makeClock("cpl_c1", nullptr, false, 10.0, w1, nullptr, sta_->cmdMode()); + sta_->makeClock("cpl_c1", nullptr, false, 10.0, w1, "", sta_->cmdMode()); FloatSeq *w2 = new FloatSeq; w2->push_back(0.0); w2->push_back(5.0); - sta_->makeClock("cpl_c2", nullptr, false, 10.0, w2, nullptr, sta_->cmdMode()); + sta_->makeClock("cpl_c2", nullptr, false, 10.0, w2, "", sta_->cmdMode()); Clock *c1 = sdc->findClock("cpl_c1"); Clock *c2 = sdc->findClock("cpl_c2"); ClockPairLess cpl; @@ -4686,7 +4687,7 @@ TEST_F(SdcInitTest, SdcClockLatencyOnPin) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("clp_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("clp_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Clock *clk = sdc->findClock("clp_clk"); // Set latency on clock (no pin) sdc->setClockLatency(clk, nullptr, RiseFallBoth::riseFall(), @@ -4704,7 +4705,7 @@ TEST_F(SdcInitTest, SdcClockInsertionOnPin) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("cip_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("cip_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Clock *clk = sdc->findClock("cip_clk"); sdc->setClockInsertion(clk, nullptr, RiseFallBoth::riseFall(), MinMaxAll::all(), EarlyLateAll::all(), 0.4f); @@ -4723,7 +4724,7 @@ TEST_F(SdcInitTest, SdcClockInsertionScalarForm) { FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0); waveform->push_back(5.0); - sta_->makeClock("cis_clk", nullptr, false, 10.0, waveform, nullptr, sta_->cmdMode()); + sta_->makeClock("cis_clk", nullptr, false, 10.0, waveform, "", sta_->cmdMode()); Clock *clk = sdc->findClock("cis_clk"); sdc->setClockInsertion(clk, nullptr, RiseFall::rise(), MinMax::max(), EarlyLate::early(), 0.6f); @@ -4799,7 +4800,7 @@ TEST_F(SdcInitTest, SdcDeleteLoopExceptions) { TEST_F(SdcInitTest, SdcMakeFalsePath) { ASSERT_NO_THROW(( [&](){ Sdc *sdc = sta_->cmdSdc(); - sdc->makeFalsePath(nullptr, nullptr, nullptr, MinMaxAll::all(), nullptr); + sdc->makeFalsePath(nullptr, nullptr, nullptr, MinMaxAll::all(), ""); }() )); } @@ -4809,7 +4810,7 @@ TEST_F(SdcInitTest, SdcMakeMulticyclePath) { ASSERT_NO_THROW(( [&](){ Sdc *sdc = sta_->cmdSdc(); sdc->makeMulticyclePath(nullptr, nullptr, nullptr, MinMaxAll::all(), - false, 2, nullptr); + false, 2, ""); }() )); } @@ -4821,11 +4822,11 @@ TEST_F(SdcInitTest, SdcSameClockGroupExplicit) { FloatSeq *w1 = new FloatSeq; w1->push_back(0.0); w1->push_back(5.0); - sta_->makeClock("scge_c1", nullptr, false, 10.0, w1, nullptr, sta_->cmdMode()); + sta_->makeClock("scge_c1", nullptr, false, 10.0, w1, "", sta_->cmdMode()); FloatSeq *w2 = new FloatSeq; w2->push_back(0.0); w2->push_back(5.0); - sta_->makeClock("scge_c2", nullptr, false, 10.0, w2, nullptr, sta_->cmdMode()); + sta_->makeClock("scge_c2", nullptr, false, 10.0, w2, "", sta_->cmdMode()); Clock *c1 = sdc->findClock("scge_c1"); Clock *c2 = sdc->findClock("scge_c2"); bool same = sdc->sameClockGroupExplicit(c1, c2); diff --git a/sdf/test/cpp/TestSdf.cc b/sdf/test/cpp/TestSdf.cc index e99ae9db..9b0f8e1e 100644 --- a/sdf/test/cpp/TestSdf.cc +++ b/sdf/test/cpp/TestSdf.cc @@ -60,7 +60,7 @@ TEST_F(SdfSmokeTest, AllSdfTransitions) { // 0Z EXPECT_NE(Transition::tr0Z(), nullptr); - EXPECT_NE(Transition::tr0Z()->asInitFinalString(), nullptr); + EXPECT_FALSE(Transition::tr0Z()->asInitFinalString().empty()); // Z1 EXPECT_NE(Transition::trZ1(), nullptr); @@ -135,10 +135,10 @@ TEST_F(SdfSmokeTest, RiseFallFind) { // Test RiseFall names TEST_F(SdfSmokeTest, RiseFallNames) { - EXPECT_STREQ(RiseFall::rise()->name(), "rise"); - EXPECT_STREQ(RiseFall::fall()->name(), "fall"); - EXPECT_STREQ(RiseFall::rise()->shortName(), "^"); - EXPECT_STREQ(RiseFall::fall()->shortName(), "v"); + EXPECT_EQ(RiseFall::rise()->name(), "rise"); + EXPECT_EQ(RiseFall::fall()->name(), "fall"); + EXPECT_EQ(RiseFall::rise()->shortName(), "^"); + EXPECT_EQ(RiseFall::fall()->shortName(), "v"); } // Test RiseFall opposite @@ -160,8 +160,8 @@ TEST_F(SdfSmokeTest, RiseFallBothBasic) { EXPECT_NE(RiseFallBoth::fall(), nullptr); EXPECT_NE(RiseFallBoth::riseFall(), nullptr); - EXPECT_STREQ(RiseFallBoth::rise()->name(), "rise"); - EXPECT_STREQ(RiseFallBoth::fall()->name(), "fall"); + EXPECT_EQ(RiseFallBoth::rise()->name(), "rise"); + EXPECT_EQ(RiseFallBoth::fall()->name(), "fall"); } // Test RiseFallBoth matches @@ -174,8 +174,8 @@ TEST_F(SdfSmokeTest, RiseFallBothMatches) { // Test MinMax details TEST_F(SdfSmokeTest, MinMaxDetails) { - EXPECT_STREQ(MinMax::min()->to_string().c_str(), "min"); - EXPECT_STREQ(MinMax::max()->to_string().c_str(), "max"); + EXPECT_EQ(MinMax::min()->to_string(), "min"); + EXPECT_EQ(MinMax::max()->to_string(), "max"); EXPECT_EQ(MinMax::min()->index(), MinMax::minIndex()); EXPECT_EQ(MinMax::max()->index(), MinMax::maxIndex()); } @@ -326,18 +326,18 @@ TEST_F(SdfSmokeTest, AllTransitionSdfTripleIndex) { // Test all transition initFinal strings TEST_F(SdfSmokeTest, AllTransitionInitFinalString) { - EXPECT_STREQ(Transition::rise()->asInitFinalString(), "01"); - EXPECT_STREQ(Transition::fall()->asInitFinalString(), "10"); - EXPECT_STREQ(Transition::tr0Z()->asInitFinalString(), "0Z"); - EXPECT_STREQ(Transition::trZ1()->asInitFinalString(), "Z1"); - EXPECT_STREQ(Transition::tr1Z()->asInitFinalString(), "1Z"); - EXPECT_STREQ(Transition::trZ0()->asInitFinalString(), "Z0"); - EXPECT_STREQ(Transition::tr0X()->asInitFinalString(), "0X"); - EXPECT_STREQ(Transition::trX1()->asInitFinalString(), "X1"); - EXPECT_STREQ(Transition::tr1X()->asInitFinalString(), "1X"); - EXPECT_STREQ(Transition::trX0()->asInitFinalString(), "X0"); - EXPECT_STREQ(Transition::trXZ()->asInitFinalString(), "XZ"); - EXPECT_STREQ(Transition::trZX()->asInitFinalString(), "ZX"); + EXPECT_EQ(Transition::rise()->asInitFinalString(), "01"); + EXPECT_EQ(Transition::fall()->asInitFinalString(), "10"); + EXPECT_EQ(Transition::tr0Z()->asInitFinalString(), "0Z"); + EXPECT_EQ(Transition::trZ1()->asInitFinalString(), "Z1"); + EXPECT_EQ(Transition::tr1Z()->asInitFinalString(), "1Z"); + EXPECT_EQ(Transition::trZ0()->asInitFinalString(), "Z0"); + EXPECT_EQ(Transition::tr0X()->asInitFinalString(), "0X"); + EXPECT_EQ(Transition::trX1()->asInitFinalString(), "X1"); + EXPECT_EQ(Transition::tr1X()->asInitFinalString(), "1X"); + EXPECT_EQ(Transition::trX0()->asInitFinalString(), "X0"); + EXPECT_EQ(Transition::trXZ()->asInitFinalString(), "XZ"); + EXPECT_EQ(Transition::trZX()->asInitFinalString(), "ZX"); } // Test all transition asRiseFall @@ -416,16 +416,16 @@ TEST_F(SdfSmokeTest, MinMaxAllAsMinMax) { // Covers: SdfWriter::sdfEdge - exercises transition to SDF edge string mapping TEST_F(SdfSmokeTest, TransitionAsInitFinalString) { // SDF uses init/final transition string representation - EXPECT_NE(Transition::rise()->asInitFinalString(), nullptr); - EXPECT_NE(Transition::fall()->asInitFinalString(), nullptr); - EXPECT_NE(Transition::tr0Z()->asInitFinalString(), nullptr); - EXPECT_NE(Transition::trZ1()->asInitFinalString(), nullptr); - EXPECT_NE(Transition::tr1Z()->asInitFinalString(), nullptr); - EXPECT_NE(Transition::trZ0()->asInitFinalString(), nullptr); - EXPECT_NE(Transition::tr0X()->asInitFinalString(), nullptr); - EXPECT_NE(Transition::trX1()->asInitFinalString(), nullptr); - EXPECT_NE(Transition::tr1X()->asInitFinalString(), nullptr); - EXPECT_NE(Transition::trX0()->asInitFinalString(), nullptr); + EXPECT_FALSE(Transition::rise()->asInitFinalString().empty()); + EXPECT_FALSE(Transition::fall()->asInitFinalString().empty()); + EXPECT_FALSE(Transition::tr0Z()->asInitFinalString().empty()); + EXPECT_FALSE(Transition::trZ1()->asInitFinalString().empty()); + EXPECT_FALSE(Transition::tr1Z()->asInitFinalString().empty()); + EXPECT_FALSE(Transition::trZ0()->asInitFinalString().empty()); + EXPECT_FALSE(Transition::tr0X()->asInitFinalString().empty()); + EXPECT_FALSE(Transition::trX1()->asInitFinalString().empty()); + EXPECT_FALSE(Transition::tr1X()->asInitFinalString().empty()); + EXPECT_FALSE(Transition::trX0()->asInitFinalString().empty()); } // Test Transition asRiseFall for SDF edge transitions @@ -538,7 +538,7 @@ TEST_F(SdfSmokeTest, MinMaxAllRangeIndex) { TEST_F(SdfSmokeTest, MinMaxConstructorCoverage) { // The MinMax constructor is private; we verify it was called via singletons const MinMax *mn = MinMax::min(); - EXPECT_STREQ(mn->to_string().c_str(), "min"); + EXPECT_EQ(mn->to_string(), "min"); EXPECT_EQ(mn->index(), MinMax::minIndex()); EXPECT_GT(mn->initValue(), 0.0f); EXPECT_GT(mn->initValueInt(), 0); @@ -547,7 +547,7 @@ TEST_F(SdfSmokeTest, MinMaxConstructorCoverage) { EXPECT_FALSE(mn->compare(3.0f, 2.0f)); const MinMax *mx = MinMax::max(); - EXPECT_STREQ(mx->to_string().c_str(), "max"); + EXPECT_EQ(mx->to_string(), "max"); EXPECT_EQ(mx->index(), MinMax::maxIndex()); EXPECT_LT(mx->initValue(), 0.0f); EXPECT_LT(mx->initValueInt(), 0); @@ -1001,7 +1001,7 @@ TEST_F(SdfDesignTest, WriteThenReadSdf) { sta_->writeSdf(tmpfile, corner, '/', true, 3, false, true, true); // Now read it back - readSdf(tmpfile, nullptr, corner, false, false, + readSdf(tmpfile, "", corner, false, false, const_cast(MinMaxAll::all()), sta_); std::remove(tmpfile); @@ -1021,7 +1021,7 @@ TEST_F(SdfDesignTest, ReadSdfUnescapedDividers) { const char *tmpfile = "/tmp/test_r9_sdf_unesc.sdf"; sta_->writeSdf(tmpfile, corner, '/', true, 3, false, true, true); - readSdf(tmpfile, nullptr, corner, true, false, + readSdf(tmpfile, "", corner, true, false, const_cast(MinMaxAll::all()), sta_); std::remove(tmpfile); @@ -1041,7 +1041,7 @@ TEST_F(SdfDesignTest, ReadSdfIncrementalOnly) { const char *tmpfile = "/tmp/test_r9_sdf_incr.sdf"; sta_->writeSdf(tmpfile, corner, '/', true, 3, false, true, true); - readSdf(tmpfile, nullptr, corner, false, true, + readSdf(tmpfile, "", corner, false, true, const_cast(MinMaxAll::all()), sta_); std::remove(tmpfile); @@ -1061,7 +1061,7 @@ TEST_F(SdfDesignTest, ReadSdfCondUseMin) { const char *tmpfile = "/tmp/test_r9_sdf_cumin.sdf"; sta_->writeSdf(tmpfile, corner, '/', true, 3, false, true, true); - readSdf(tmpfile, nullptr, corner, false, false, + readSdf(tmpfile, "", corner, false, false, const_cast(MinMaxAll::min()), sta_); std::remove(tmpfile); @@ -1081,7 +1081,7 @@ TEST_F(SdfDesignTest, ReadSdfCondUseMax) { const char *tmpfile = "/tmp/test_r9_sdf_cumax.sdf"; sta_->writeSdf(tmpfile, corner, '/', true, 3, false, true, true); - readSdf(tmpfile, nullptr, corner, false, false, + readSdf(tmpfile, "", corner, false, false, const_cast(MinMaxAll::max()), sta_); std::remove(tmpfile); @@ -1101,7 +1101,7 @@ TEST_F(SdfDesignTest, ReadSdfCombinedOptions) { const char *tmpfile = "/tmp/test_r9_sdf_combined.sdf"; sta_->writeSdf(tmpfile, corner, '/', true, 3, false, true, true); - readSdf(tmpfile, nullptr, corner, true, true, + readSdf(tmpfile, "", corner, true, true, const_cast(MinMaxAll::all()), sta_); std::remove(tmpfile); @@ -1144,7 +1144,7 @@ TEST_F(SdfDesignTest, WriteSdfGzipThenRead) { const char *tmpfile = "/tmp/test_r9_sdf_gz.sdf.gz"; sta_->writeSdf(tmpfile, corner, '/', true, 3, true, true, true); - readSdf(tmpfile, nullptr, corner, false, false, + readSdf(tmpfile, "", corner, false, false, const_cast(MinMaxAll::all()), sta_); std::remove(tmpfile); @@ -1182,7 +1182,7 @@ TEST_F(SdfDesignTest, ReadSdfNonexistent) { Scene *corner = sta_->cmdScene(); // Attempt to read nonexistent SDF - should throw EXPECT_THROW( - readSdf("/tmp/nonexistent_r9.sdf", nullptr, corner, + readSdf("/tmp/nonexistent_r9.sdf", "", corner, false, false, const_cast(MinMaxAll::all()), sta_), FileNotReadable ); @@ -1195,7 +1195,7 @@ TEST_F(SdfSmokeTest, TransitionRiseProperties) { EXPECT_EQ(t->asRiseFall(), RiseFall::rise()); EXPECT_EQ(t->sdfTripleIndex(), RiseFall::riseIndex()); EXPECT_FALSE(t->to_string().empty()); - EXPECT_NE(t->asInitFinalString(), nullptr); + EXPECT_FALSE(t->asInitFinalString().empty()); } TEST_F(SdfSmokeTest, TransitionFallProperties) { @@ -1204,7 +1204,7 @@ TEST_F(SdfSmokeTest, TransitionFallProperties) { EXPECT_EQ(t->asRiseFall(), RiseFall::fall()); EXPECT_EQ(t->sdfTripleIndex(), RiseFall::fallIndex()); EXPECT_FALSE(t->to_string().empty()); - EXPECT_NE(t->asInitFinalString(), nullptr); + EXPECT_FALSE(t->asInitFinalString().empty()); } TEST_F(SdfSmokeTest, TransitionTristateProperties) { @@ -1418,7 +1418,7 @@ TEST_F(SdfDesignTest, ReadHandCraftedSdf) { fprintf(fp, ")\n"); fclose(fp); - readSdf(sdf_path, nullptr, corner, false, false, + readSdf(sdf_path, "", corner, false, false, const_cast(MinMaxAll::all()), sta_); std::remove(sdf_path); @@ -1455,7 +1455,7 @@ TEST_F(SdfDesignTest, ReadSdfEdgeIopath) { fprintf(fp, ")\n"); fclose(fp); - readSdf(sdf_path, nullptr, corner, false, false, + readSdf(sdf_path, "", corner, false, false, const_cast(MinMaxAll::all()), sta_); std::remove(sdf_path); @@ -1489,7 +1489,7 @@ TEST_F(SdfDesignTest, ReadSdfSetupHold) { fprintf(fp, ")\n"); fclose(fp); - readSdf(sdf_path, nullptr, corner, false, false, + readSdf(sdf_path, "", corner, false, false, const_cast(MinMaxAll::all()), sta_); std::remove(sdf_path); @@ -1523,7 +1523,7 @@ TEST_F(SdfDesignTest, ReadSdfRecRem) { fprintf(fp, ")\n"); fclose(fp); - readSdf(sdf_path, nullptr, corner, false, false, + readSdf(sdf_path, "", corner, false, false, const_cast(MinMaxAll::all()), sta_); std::remove(sdf_path); @@ -1557,7 +1557,7 @@ TEST_F(SdfDesignTest, ReadSdfWidth) { fprintf(fp, ")\n"); fclose(fp); - readSdf(sdf_path, nullptr, corner, false, false, + readSdf(sdf_path, "", corner, false, false, const_cast(MinMaxAll::all()), sta_); std::remove(sdf_path); @@ -1591,7 +1591,7 @@ TEST_F(SdfDesignTest, ReadSdfPeriod) { fprintf(fp, ")\n"); fclose(fp); - readSdf(sdf_path, nullptr, corner, false, false, + readSdf(sdf_path, "", corner, false, false, const_cast(MinMaxAll::all()), sta_); std::remove(sdf_path); @@ -1628,7 +1628,7 @@ TEST_F(SdfDesignTest, ReadSdfNochange) { // NOCHANGE is not supported and throws an exception EXPECT_THROW( - readSdf(sdf_path, nullptr, corner, false, false, + readSdf(sdf_path, "", corner, false, false, const_cast(MinMaxAll::all()), sta_), std::exception ); @@ -1666,7 +1666,7 @@ TEST_F(SdfDesignTest, ReadSdfInterconnect) { fprintf(fp, ")\n"); fclose(fp); - readSdf(sdf_path, nullptr, corner, false, false, + readSdf(sdf_path, "", corner, false, false, const_cast(MinMaxAll::all()), sta_); std::remove(sdf_path); diff --git a/search/test/cpp/TestSearchClasses.cc b/search/test/cpp/TestSearchClasses.cc index 8e1ccc19..5ead6736 100644 --- a/search/test/cpp/TestSearchClasses.cc +++ b/search/test/cpp/TestSearchClasses.cc @@ -170,14 +170,14 @@ TEST_F(PropertyValueTest, DefaultConstructor) { TEST_F(PropertyValueTest, StringConstructor) { PropertyValue pv("hello"); EXPECT_EQ(pv.type(), PropertyValue::Type::string); - EXPECT_STREQ(pv.stringValue(), "hello"); + EXPECT_EQ(pv.stringValue(), "hello"); } TEST_F(PropertyValueTest, StdStringConstructor) { std::string s("world"); PropertyValue pv(s); EXPECT_EQ(pv.type(), PropertyValue::Type::string); - EXPECT_STREQ(pv.stringValue(), "world"); + EXPECT_EQ(pv.stringValue(), "world"); } TEST_F(PropertyValueTest, BoolConstructorTrue) { @@ -275,7 +275,7 @@ TEST_F(PropertyValueTest, CopyConstructorString) { PropertyValue pv1("copy_test"); PropertyValue pv2(pv1); EXPECT_EQ(pv2.type(), PropertyValue::Type::string); - EXPECT_STREQ(pv2.stringValue(), "copy_test"); + EXPECT_EQ(pv2.stringValue(), "copy_test"); } TEST_F(PropertyValueTest, CopyConstructorFloat) { @@ -382,7 +382,7 @@ TEST_F(PropertyValueTest, MoveConstructorString) { PropertyValue pv1("move_test"); PropertyValue pv2(std::move(pv1)); EXPECT_EQ(pv2.type(), PropertyValue::Type::string); - EXPECT_STREQ(pv2.stringValue(), "move_test"); + EXPECT_EQ(pv2.stringValue(), "move_test"); } TEST_F(PropertyValueTest, MoveConstructorFloat) { @@ -480,7 +480,7 @@ TEST_F(PropertyValueTest, CopyAssignmentString) { PropertyValue pv2; pv2 = pv1; EXPECT_EQ(pv2.type(), PropertyValue::Type::string); - EXPECT_STREQ(pv2.stringValue(), "assign_test"); + EXPECT_EQ(pv2.stringValue(), "assign_test"); } TEST_F(PropertyValueTest, CopyAssignmentFloat) { @@ -591,7 +591,7 @@ TEST_F(PropertyValueTest, MoveAssignmentString) { PropertyValue pv2; pv2 = std::move(pv1); EXPECT_EQ(pv2.type(), PropertyValue::Type::string); - EXPECT_STREQ(pv2.stringValue(), "move_assign"); + EXPECT_EQ(pv2.stringValue(), "move_assign"); } TEST_F(PropertyValueTest, MoveAssignmentFloat) { @@ -950,7 +950,7 @@ protected: // FalsePath TEST_F(ExceptionPathTest, FalsePathBasic) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_TRUE(fp.isFalse()); EXPECT_FALSE(fp.isLoop()); EXPECT_FALSE(fp.isMultiCycle()); @@ -965,38 +965,38 @@ TEST_F(ExceptionPathTest, FalsePathBasic) { } TEST_F(ExceptionPathTest, FalsePathTypeString) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_EQ(fp.typePriority(), ExceptionPath::falsePathPriority()); } TEST_F(ExceptionPathTest, FalsePathTighterThan) { - FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); - FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); + FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); // FalsePath tighterThan always returns false EXPECT_FALSE(fp1.tighterThan(&fp2)); } TEST_F(ExceptionPathTest, FalsePathMatches) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_TRUE(fp.matches(MinMax::min(), false)); EXPECT_TRUE(fp.matches(MinMax::max(), false)); } TEST_F(ExceptionPathTest, FalsePathMatchesMinOnly) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::min(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::min(), true, ""); EXPECT_TRUE(fp.matches(MinMax::min(), false)); EXPECT_FALSE(fp.matches(MinMax::max(), false)); } TEST_F(ExceptionPathTest, FalsePathMergeable) { - FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); - FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); + FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_TRUE(fp1.mergeable(&fp2)); } TEST_F(ExceptionPathTest, FalsePathOverrides) { - FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); - FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); + FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_TRUE(fp1.overrides(&fp2)); } @@ -1026,7 +1026,7 @@ TEST_F(ExceptionPathTest, LoopPathNotMergeable) { // PathDelay TEST_F(ExceptionPathTest, PathDelayBasic) { PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 10.0e-9f, true, nullptr); + 10.0e-9f, true, ""); EXPECT_TRUE(pd.isPathDelay()); EXPECT_FALSE(pd.isFalse()); EXPECT_FALSE(pd.isMultiCycle()); @@ -1038,7 +1038,7 @@ TEST_F(ExceptionPathTest, PathDelayBasic) { TEST_F(ExceptionPathTest, PathDelayWithFlags) { PathDelay pd(nullptr, nullptr, nullptr, MinMax::min(), true, true, - 5.0e-9f, true, nullptr); + 5.0e-9f, true, ""); EXPECT_TRUE(pd.ignoreClkLatency()); EXPECT_TRUE(pd.breakPath()); EXPECT_FLOAT_EQ(pd.delay(), 5.0e-9f); @@ -1046,15 +1046,15 @@ TEST_F(ExceptionPathTest, PathDelayWithFlags) { TEST_F(ExceptionPathTest, PathDelayTypePriority) { PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 0.0f, true, nullptr); + 0.0f, true, ""); EXPECT_EQ(pd.typePriority(), ExceptionPath::pathDelayPriority()); } TEST_F(ExceptionPathTest, PathDelayTighterThanMax) { PathDelay pd1(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 5.0e-9f, true, nullptr); + 5.0e-9f, true, ""); PathDelay pd2(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 10.0e-9f, true, nullptr); + 10.0e-9f, true, ""); // For max, tighter means smaller delay EXPECT_TRUE(pd1.tighterThan(&pd2)); EXPECT_FALSE(pd2.tighterThan(&pd1)); @@ -1062,9 +1062,9 @@ TEST_F(ExceptionPathTest, PathDelayTighterThanMax) { TEST_F(ExceptionPathTest, PathDelayTighterThanMin) { PathDelay pd1(nullptr, nullptr, nullptr, MinMax::min(), false, false, - 10.0e-9f, true, nullptr); + 10.0e-9f, true, ""); PathDelay pd2(nullptr, nullptr, nullptr, MinMax::min(), false, false, - 5.0e-9f, true, nullptr); + 5.0e-9f, true, ""); // For min, tighter means larger delay EXPECT_TRUE(pd1.tighterThan(&pd2)); EXPECT_FALSE(pd2.tighterThan(&pd1)); @@ -1072,7 +1072,7 @@ TEST_F(ExceptionPathTest, PathDelayTighterThanMin) { TEST_F(ExceptionPathTest, PathDelayClone) { PathDelay pd(nullptr, nullptr, nullptr, MinMax::max(), true, true, - 7.0e-9f, true, nullptr); + 7.0e-9f, true, ""); ExceptionPath *clone = pd.clone(nullptr, nullptr, nullptr, true); EXPECT_TRUE(clone->isPathDelay()); EXPECT_FLOAT_EQ(clone->delay(), 7.0e-9f); @@ -1083,16 +1083,16 @@ TEST_F(ExceptionPathTest, PathDelayClone) { TEST_F(ExceptionPathTest, PathDelayOverrides) { PathDelay pd1(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 5.0e-9f, true, nullptr); + 5.0e-9f, true, ""); PathDelay pd2(nullptr, nullptr, nullptr, MinMax::max(), false, false, - 10.0e-9f, true, nullptr); + 10.0e-9f, true, ""); EXPECT_TRUE(pd1.overrides(&pd2)); } // MultiCyclePath TEST_F(ExceptionPathTest, MultiCyclePathBasic) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 3, true, nullptr); + true, 3, true, ""); EXPECT_TRUE(mcp.isMultiCycle()); EXPECT_FALSE(mcp.isFalse()); EXPECT_FALSE(mcp.isPathDelay()); @@ -1103,13 +1103,13 @@ TEST_F(ExceptionPathTest, MultiCyclePathBasic) { TEST_F(ExceptionPathTest, MultiCyclePathTypePriority) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - false, 2, true, nullptr); + false, 2, true, ""); EXPECT_EQ(mcp.typePriority(), ExceptionPath::multiCyclePathPriority()); } TEST_F(ExceptionPathTest, MultiCyclePathMultiplierAll) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 3, true, nullptr); + true, 3, true, ""); // When min_max_ is all and min_max arg is min, multiplier is 0 EXPECT_EQ(mcp.pathMultiplier(MinMax::min()), 0); // For max, returns the actual multiplier @@ -1118,14 +1118,14 @@ TEST_F(ExceptionPathTest, MultiCyclePathMultiplierAll) { TEST_F(ExceptionPathTest, MultiCyclePathMultiplierSpecific) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::max(), - true, 5, true, nullptr); + true, 5, true, ""); EXPECT_EQ(mcp.pathMultiplier(MinMax::min()), 5); EXPECT_EQ(mcp.pathMultiplier(MinMax::max()), 5); } TEST_F(ExceptionPathTest, MultiCyclePathPriorityAll) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 3, true, nullptr); + true, 3, true, ""); int base_priority = mcp.priority(); // priority(min_max) returns priority_ + 1 when min_max_ == all EXPECT_EQ(mcp.priority(MinMax::min()), base_priority + 1); @@ -1134,7 +1134,7 @@ TEST_F(ExceptionPathTest, MultiCyclePathPriorityAll) { TEST_F(ExceptionPathTest, MultiCyclePathPrioritySpecific) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::max(), - true, 3, true, nullptr); + true, 3, true, ""); int base_priority = mcp.priority(); // priority(min_max) returns priority_ + 2 when min_max_ matches EXPECT_EQ(mcp.priority(MinMax::max()), base_priority + 2); @@ -1144,7 +1144,7 @@ TEST_F(ExceptionPathTest, MultiCyclePathPrioritySpecific) { TEST_F(ExceptionPathTest, MultiCyclePathMatchesAll) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 3, true, nullptr); + true, 3, true, ""); EXPECT_TRUE(mcp.matches(MinMax::min(), false)); EXPECT_TRUE(mcp.matches(MinMax::max(), false)); EXPECT_TRUE(mcp.matches(MinMax::min(), true)); @@ -1153,7 +1153,7 @@ TEST_F(ExceptionPathTest, MultiCyclePathMatchesAll) { TEST_F(ExceptionPathTest, MultiCyclePathMatchesMaxSetup) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::max(), - true, 3, true, nullptr); + true, 3, true, ""); EXPECT_TRUE(mcp.matches(MinMax::max(), false)); EXPECT_TRUE(mcp.matches(MinMax::max(), true)); // For min path, not exact: should still match because multicycle setup @@ -1165,16 +1165,16 @@ TEST_F(ExceptionPathTest, MultiCyclePathMatchesMaxSetup) { TEST_F(ExceptionPathTest, MultiCyclePathTighterThan) { MultiCyclePath mcp1(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 2, true, nullptr); + true, 2, true, ""); MultiCyclePath mcp2(nullptr, nullptr, nullptr, MinMaxAll::all(), - true, 5, true, nullptr); + true, 5, true, ""); EXPECT_TRUE(mcp1.tighterThan(&mcp2)); EXPECT_FALSE(mcp2.tighterThan(&mcp1)); } TEST_F(ExceptionPathTest, MultiCyclePathClone) { MultiCyclePath mcp(nullptr, nullptr, nullptr, MinMaxAll::max(), - true, 4, true, nullptr); + true, 4, true, ""); ExceptionPath *clone = mcp.clone(nullptr, nullptr, nullptr, true); EXPECT_TRUE(clone->isMultiCycle()); EXPECT_EQ(clone->pathMultiplier(), 4); @@ -1228,7 +1228,7 @@ TEST_F(ExceptionPathTest, FilterPathClone) { // GroupPath TEST_F(ExceptionPathTest, GroupPathBasic) { - GroupPath gp("group1", false, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp("group1", false, nullptr, nullptr, nullptr, true, ""); EXPECT_TRUE(gp.isGroupPath()); EXPECT_FALSE(gp.isFalse()); EXPECT_FALSE(gp.isPathDelay()); @@ -1238,19 +1238,19 @@ TEST_F(ExceptionPathTest, GroupPathBasic) { } TEST_F(ExceptionPathTest, GroupPathDefault) { - GroupPath gp("default_group", true, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp("default_group", true, nullptr, nullptr, nullptr, true, ""); EXPECT_TRUE(gp.isDefault()); EXPECT_EQ(gp.name(), "default_group"); } TEST_F(ExceptionPathTest, GroupPathTypePriority) { - GroupPath gp("gp", false, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp("gp", false, nullptr, nullptr, nullptr, true, ""); EXPECT_EQ(gp.typePriority(), ExceptionPath::groupPathPriority()); } TEST_F(ExceptionPathTest, GroupPathTighterThan) { - GroupPath gp1("gp1", false, nullptr, nullptr, nullptr, true, nullptr); - GroupPath gp2("gp2", false, nullptr, nullptr, nullptr, true, nullptr); + GroupPath gp1("gp1", false, nullptr, nullptr, nullptr, true, ""); + GroupPath gp2("gp2", false, nullptr, nullptr, nullptr, true, ""); EXPECT_FALSE(gp1.tighterThan(&gp2)); } @@ -1277,14 +1277,14 @@ TEST_F(ExceptionPathTest, FromThruToPriority) { } TEST_F(ExceptionPathTest, SetId) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_EQ(fp.id(), 0u); fp.setId(42); EXPECT_EQ(fp.id(), 42u); } TEST_F(ExceptionPathTest, SetPriority) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); int orig_priority = fp.priority(); fp.setPriority(9999); EXPECT_EQ(fp.priority(), 9999); @@ -1292,12 +1292,12 @@ TEST_F(ExceptionPathTest, SetPriority) { } TEST_F(ExceptionPathTest, FirstPtNone) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_EQ(fp.firstPt(), nullptr); } TEST_F(ExceptionPathTest, FirstState) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); ExceptionState *state = fp.firstState(); EXPECT_NE(state, nullptr); // Should be complete since no from/thru/to @@ -1305,27 +1305,27 @@ TEST_F(ExceptionPathTest, FirstState) { } TEST_F(ExceptionPathTest, Hash) { - FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); - FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); + FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); // Same structure should produce same hash EXPECT_EQ(fp1.hash(), fp2.hash()); } TEST_F(ExceptionPathTest, MergeablePts) { - FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); - FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); + FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_TRUE(fp1.mergeablePts(&fp2)); } TEST_F(ExceptionPathTest, IntersectsPts) { - FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); - FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); + FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_TRUE(fp1.intersectsPts(&fp2, nullptr)); } // ExceptionState tests TEST_F(ExceptionPathTest, ExceptionStateBasic) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); ExceptionState *state = fp.firstState(); EXPECT_EQ(state->exception(), &fp); EXPECT_EQ(state->nextThru(), nullptr); @@ -1333,7 +1333,7 @@ TEST_F(ExceptionPathTest, ExceptionStateBasic) { } TEST_F(ExceptionPathTest, ExceptionStateHash) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); ExceptionState *state = fp.firstState(); // Hash should be deterministic size_t h = state->hash(); @@ -1341,9 +1341,9 @@ TEST_F(ExceptionPathTest, ExceptionStateHash) { } TEST_F(ExceptionPathTest, ExceptionStateLess) { - FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp1(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); fp1.setId(1); - FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp2(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); fp2.setId(2); ExceptionState *s1 = fp1.firstState(); ExceptionState *s2 = fp2.firstState(); @@ -1366,14 +1366,14 @@ TEST_F(ExceptionPathTest, CheckFromThrusToWithNulls) { // ExceptionPtIterator TEST_F(ExceptionPathTest, PtIteratorEmpty) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); ExceptionPtIterator iter(&fp); EXPECT_FALSE(iter.hasNext()); } // Default values TEST_F(ExceptionPathTest, DefaultValues) { - FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, nullptr); + FalsePath fp(nullptr, nullptr, nullptr, MinMaxAll::all(), true, ""); EXPECT_FALSE(fp.useEndClk()); EXPECT_EQ(fp.pathMultiplier(), 0); EXPECT_FLOAT_EQ(fp.delay(), 0.0f); diff --git a/spice/test/cpp/TestSpice.cc b/spice/test/cpp/TestSpice.cc index 41e5baf6..2526f3b3 100644 --- a/spice/test/cpp/TestSpice.cc +++ b/spice/test/cpp/TestSpice.cc @@ -336,10 +336,10 @@ TEST_F(SpiceSmokeTest, TransitionAsRiseFall) { } TEST_F(SpiceSmokeTest, TransitionInitFinalString) { - const char *rise_str = Transition::rise()->asInitFinalString(); - EXPECT_NE(rise_str, nullptr); - const char *fall_str = Transition::fall()->asInitFinalString(); - EXPECT_NE(fall_str, nullptr); + std::string rise_str = Transition::rise()->asInitFinalString(); + EXPECT_FALSE(rise_str.empty()); + std::string fall_str = Transition::fall()->asInitFinalString(); + EXPECT_FALSE(fall_str.empty()); } //////////////////////////////////////////////////////////////// @@ -587,8 +587,8 @@ TEST_F(SpiceSmokeTest, RiseFallBothRange) { // Test Transition init strings used in WriteSpice TEST_F(SpiceSmokeTest, TransitionInitFinalStrings) { - EXPECT_NE(Transition::rise()->asInitFinalString(), nullptr); - EXPECT_NE(Transition::fall()->asInitFinalString(), nullptr); + EXPECT_FALSE(Transition::rise()->asInitFinalString().empty()); + EXPECT_FALSE(Transition::fall()->asInitFinalString().empty()); } // Test MinMax initValue used in spice @@ -804,8 +804,8 @@ TEST_F(SpiceSmokeTest, MinMaxToString) { // Test RiseFall shortName // Covers: RiseFall::shortName TEST_F(SpiceSmokeTest, RiseFallShortName) { - EXPECT_STREQ(RiseFall::rise()->shortName(), "^"); - EXPECT_STREQ(RiseFall::fall()->shortName(), "v"); + EXPECT_EQ(RiseFall::rise()->shortName(), "^"); + EXPECT_EQ(RiseFall::fall()->shortName(), "v"); } //////////////////////////////////////////////////////////////// @@ -1424,7 +1424,7 @@ protected: FloatSeq *waveform = new FloatSeq; waveform->push_back(0.0f); waveform->push_back(5.0f); - sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, nullptr, + sta_->makeClock("clk", clk_pins, false, 10.0f, waveform, "", sta_->cmdMode()); Pin *in1 = network->findPin(top, "in1"); @@ -1510,7 +1510,7 @@ TEST_F(SpiceDesignTest, LibertyCellAccess) { ASSERT_NE(and1, nullptr); LibertyCell *cell = network->libertyCell(and1); ASSERT_NE(cell, nullptr); - EXPECT_STREQ(cell->name(), "AND2_X1"); + EXPECT_EQ(cell->name(), "AND2_X1"); } // Verify liberty cell ports (needed for SPICE subcircuit port mapping) @@ -1726,15 +1726,15 @@ TEST_F(SpiceDesignTest, InstanceCellName) { Network *network = sta_->cmdNetwork(); Instance *and1 = network->findInstance("and1"); ASSERT_NE(and1, nullptr); - const char *cell_name = network->cellName(and1); - ASSERT_NE(cell_name, nullptr); - EXPECT_STREQ(cell_name, "AND2_X1"); + std::string cell_name = network->cellName(and1); + EXPECT_FALSE(cell_name.empty()); + EXPECT_EQ(cell_name, "AND2_X1"); Instance *reg1 = network->findInstance("reg1"); ASSERT_NE(reg1, nullptr); cell_name = network->cellName(reg1); - ASSERT_NE(cell_name, nullptr); - EXPECT_STREQ(cell_name, "DFF_X1"); + EXPECT_FALSE(cell_name.empty()); + EXPECT_EQ(cell_name, "DFF_X1"); } // Verify print with SPICE subcircuit instance format for design cells @@ -1747,8 +1747,8 @@ TEST_F(SpiceDesignTest, StreamPrintSubcktInst) { Network *network = sta_->cmdNetwork(); Instance *and1 = network->findInstance("and1"); ASSERT_NE(and1, nullptr); - const char *inst_name = network->name(and1); - const char *cell_name = network->cellName(and1); + std::string inst_name = network->name(and1); + std::string cell_name = network->cellName(and1); std::ofstream out(tmpl); ASSERT_TRUE(out.is_open()); @@ -1770,10 +1770,10 @@ TEST_F(SpiceDesignTest, NetNamesForSpice) { ASSERT_NE(and1_zn, nullptr); Net *net = network->net(and1_zn); ASSERT_NE(net, nullptr); - const char *net_name = network->name(net); - EXPECT_NE(net_name, nullptr); + std::string net_name = network->name(net); + EXPECT_FALSE(net_name.empty()); // The net name should be "n1" (from the Verilog: wire n1) - EXPECT_STREQ(net_name, "n1"); + EXPECT_EQ(net_name, "n1"); } // Verify hold timing paths (for SPICE min-delay analysis) diff --git a/util/test/cpp/TestUtil.cc b/util/test/cpp/TestUtil.cc index ad45914b..6db10030 100644 --- a/util/test/cpp/TestUtil.cc +++ b/util/test/cpp/TestUtil.cc @@ -659,7 +659,7 @@ TEST(RiseFallValuesTest, OverwriteValue) TEST(PatternMatchClassTest, SimpleGlobConstructor) { PatternMatch pm("hello"); - EXPECT_STREQ(pm.pattern(), "hello"); + EXPECT_EQ(pm.pattern(), "hello"); EXPECT_FALSE(pm.isRegexp()); EXPECT_FALSE(pm.nocase()); EXPECT_EQ(pm.tclInterp(), nullptr); @@ -728,7 +728,7 @@ TEST(PatternMatchClassTest, InheritFromConstructor) { PatternMatch parent("base*", false, true, nullptr); PatternMatch child("child*", &parent); - EXPECT_STREQ(child.pattern(), "child*"); + EXPECT_EQ(child.pattern(), "child*"); EXPECT_FALSE(child.isRegexp()); EXPECT_TRUE(child.nocase()); EXPECT_TRUE(child.match("children")); @@ -1162,21 +1162,6 @@ TEST(ReportTest, LogAndConsoleSimultaneous) // Additional StringUtil tests //////////////////////////////////////////////////////////////// -TEST(StringUtilTest, StringCopy) -{ - const char *orig = "hello"; - char *copy = stringCopy(orig); - EXPECT_STREQ(copy, "hello"); - EXPECT_NE(copy, orig); - stringDelete(copy); -} - -TEST(StringUtilTest, StringCopyNull) -{ - char *copy = stringCopy(nullptr); - EXPECT_EQ(copy, nullptr); -} - TEST(StringUtilTest, StaFormat) { std::string s = sta::format("value={}", 42); @@ -1208,47 +1193,12 @@ TEST(StringUtilTest, StaFormatTmp) EXPECT_EQ(s, "tmp 42"); } -TEST(StringUtilTest, MakeTmpString) -{ - char *tmp = makeTmpString(100); - EXPECT_NE(tmp, nullptr); - // We can write to it - strcpy(tmp, "test"); - EXPECT_STREQ(tmp, "test"); -} - -TEST(StringUtilTest, MakeTmpStringFromStdString) -{ - std::string s = "hello"; - char *tmp = makeTmpString(s); - EXPECT_STREQ(tmp, "hello"); -} - -TEST(StringUtilTest, IsTmpString) -{ - char *tmp = makeTmpString(10); - strcpy(tmp, "test"); - EXPECT_TRUE(isTmpString(tmp)); - - char local[] = "local"; - EXPECT_FALSE(isTmpString(local)); -} - TEST(StringUtilTest, StringEqWithLength) { EXPECT_TRUE(stringEq("hello world", "hello", 5)); EXPECT_FALSE(stringEq("hello world", "hellx", 5)); } -TEST(StringUtilTest, StringEqIf) -{ - EXPECT_TRUE(stringEqIf(nullptr, nullptr)); - EXPECT_FALSE(stringEqIf(nullptr, "hello")); - EXPECT_FALSE(stringEqIf("hello", nullptr)); - EXPECT_TRUE(stringEqIf("hello", "hello")); - EXPECT_FALSE(stringEqIf("hello", "world")); -} - TEST(StringUtilTest, StringBeginEq) { EXPECT_TRUE(stringBeginEq("hello world", "hello")); @@ -1267,50 +1217,6 @@ TEST(StringUtilTest, StringEqual) EXPECT_FALSE(stringEqual("hello", "world")); } -TEST(StringUtilTest, StringEqualIf) -{ - EXPECT_TRUE(stringEqualIf(nullptr, nullptr)); - EXPECT_FALSE(stringEqualIf(nullptr, "hello")); - EXPECT_FALSE(stringEqualIf("hello", nullptr)); - EXPECT_TRUE(stringEqualIf("HELLO", "hello")); -} - -TEST(StringUtilTest, StringLess) -{ - EXPECT_TRUE(stringLess("abc", "def")); - EXPECT_FALSE(stringLess("def", "abc")); - EXPECT_FALSE(stringLess("abc", "abc")); -} - -TEST(StringUtilTest, StringLessIf) -{ - EXPECT_TRUE(stringLessIf(nullptr, "abc")); - EXPECT_FALSE(stringLessIf("abc", nullptr)); - EXPECT_FALSE(stringLessIf(nullptr, nullptr)); - EXPECT_TRUE(stringLessIf("abc", "def")); -} - -TEST(StringUtilTest, CharPtrLessComparator) -{ - CharPtrLess cmp; - EXPECT_TRUE(cmp("abc", "def")); - EXPECT_FALSE(cmp("def", "abc")); -} - -TEST(StringUtilTest, CharPtrCaseLessComparator) -{ - CharPtrCaseLess cmp; - EXPECT_TRUE(cmp("abc", "DEF")); - EXPECT_FALSE(cmp("DEF", "ABC")); -} - -TEST(StringUtilTest, StringLessIfComparator) -{ - StringLessIf cmp; - EXPECT_TRUE(cmp(nullptr, "abc")); - EXPECT_FALSE(cmp("abc", nullptr)); -} - //////////////////////////////////////////////////////////////// // Debug tests //////////////////////////////////////////////////////////////// @@ -1643,8 +1549,8 @@ TEST(TransitionCovTest, RiseFallBothToString) { EXPECT_EQ(RiseFallBoth::rise()->to_string(), "rise"); EXPECT_EQ(RiseFallBoth::fall()->to_string(), "fall"); - EXPECT_STREQ(RiseFallBoth::rise()->shortName(), "^"); - EXPECT_STREQ(RiseFallBoth::fall()->shortName(), "v"); + EXPECT_EQ(RiseFallBoth::rise()->shortName(), "^"); + EXPECT_EQ(RiseFallBoth::fall()->shortName(), "v"); } // RiseFallBoth::index @@ -1734,19 +1640,19 @@ TEST(TransitionCovTest, TransitionAsRiseFallExtra) // Transition asInitFinalString for various transitions TEST(TransitionCovTest, TransitionAsInitFinalString) { - EXPECT_STREQ(Transition::rise()->asInitFinalString(), "01"); - EXPECT_STREQ(Transition::fall()->asInitFinalString(), "10"); - EXPECT_STREQ(Transition::tr0Z()->asInitFinalString(), "0Z"); - EXPECT_STREQ(Transition::trZ1()->asInitFinalString(), "Z1"); - EXPECT_STREQ(Transition::tr1Z()->asInitFinalString(), "1Z"); - EXPECT_STREQ(Transition::trZ0()->asInitFinalString(), "Z0"); - EXPECT_STREQ(Transition::tr0X()->asInitFinalString(), "0X"); - EXPECT_STREQ(Transition::trX1()->asInitFinalString(), "X1"); - EXPECT_STREQ(Transition::tr1X()->asInitFinalString(), "1X"); - EXPECT_STREQ(Transition::trX0()->asInitFinalString(), "X0"); - EXPECT_STREQ(Transition::trXZ()->asInitFinalString(), "XZ"); - EXPECT_STREQ(Transition::trZX()->asInitFinalString(), "ZX"); - EXPECT_STREQ(Transition::riseFall()->asInitFinalString(), "**"); + EXPECT_EQ(Transition::rise()->asInitFinalString(), "01"); + EXPECT_EQ(Transition::fall()->asInitFinalString(), "10"); + EXPECT_EQ(Transition::tr0Z()->asInitFinalString(), "0Z"); + EXPECT_EQ(Transition::trZ1()->asInitFinalString(), "Z1"); + EXPECT_EQ(Transition::tr1Z()->asInitFinalString(), "1Z"); + EXPECT_EQ(Transition::trZ0()->asInitFinalString(), "Z0"); + EXPECT_EQ(Transition::tr0X()->asInitFinalString(), "0X"); + EXPECT_EQ(Transition::trX1()->asInitFinalString(), "X1"); + EXPECT_EQ(Transition::tr1X()->asInitFinalString(), "1X"); + EXPECT_EQ(Transition::trX0()->asInitFinalString(), "X0"); + EXPECT_EQ(Transition::trXZ()->asInitFinalString(), "XZ"); + EXPECT_EQ(Transition::trZX()->asInitFinalString(), "ZX"); + EXPECT_EQ(Transition::riseFall()->asInitFinalString(), "**"); } // Transition::sdfTripleIndex @@ -1791,27 +1697,6 @@ TEST(StringUtilCovTest, StaFormatArgs) EXPECT_EQ(s, "args test 42 hello"); } -// stringDeleteCheck (only for non-tmp strings - should not crash) -TEST(StringUtilCovTest, StringDeleteCheckNonTmp) -{ - ASSERT_NO_THROW(( [&](){ - char *s = stringCopy("not tmp"); - // This should not crash or exit; it's not a tmp string - stringDeleteCheck(s); - stringDelete(s); - - }() )); -} - -// Test that isTmpString returns false for heap-allocated strings -TEST(StringUtilCovTest, IsTmpStringHeap) -{ - char *s = new char[10]; - strcpy(s, "heap"); - EXPECT_FALSE(isTmpString(s)); - delete [] s; -} - // Long sta::format string TEST(StringUtilCovTest, LongStaFormat) { @@ -2298,31 +2183,6 @@ TEST(ReportStdCovTest, PrintErrorConsole) }() )); } -//////////////////////////////////////////////////////////////// -// StringUtil: makeTmpString(std::string&) and stringDeleteCheck -//////////////////////////////////////////////////////////////// - -TEST(StringUtilCovTest, MakeTmpStringStdString) -{ - std::string s = "test_tmp_string"; - char *tmp = makeTmpString(s); - EXPECT_STREQ(tmp, "test_tmp_string"); - EXPECT_TRUE(isTmpString(tmp)); -} - -// stringDeleteCheck for tmp string calls Report::critical which exits, -// so we cannot test that path. Test only with non-tmp strings. -TEST(StringUtilCovTest, StringDeleteCheckRegular) -{ - ASSERT_NO_THROW(( [&](){ - char *s = stringCopy("regular"); - // Should not crash - regular string can be deleted - stringDeleteCheck(s); - stringDelete(s); - - }() )); -} - // Test Report redirectStringPrint with empty string // Covers: Report::redirectStringPrint TEST(ReportCovTest, RedirectStringPrintEmpty) diff --git a/verilog/test/cpp/TestVerilog.cc b/verilog/test/cpp/TestVerilog.cc index cdcf8b29..c6b9998c 100644 --- a/verilog/test/cpp/TestVerilog.cc +++ b/verilog/test/cpp/TestVerilog.cc @@ -2187,8 +2187,8 @@ TEST_F(VerilogDesignTest, EnsureGraphVerify) { Instance *inst = child_iter->next(); Cell *cell = network->cell(inst); EXPECT_NE(cell, nullptr); - const char *cell_name = network->name(cell); - EXPECT_NE(cell_name, nullptr); + std::string cell_name = network->name(cell); + EXPECT_FALSE(cell_name.empty()); } delete child_iter; } From 6ca7cb55a4fa1ccdedf7bdaeeb35fed2cebfe2c7 Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Mon, 30 Mar 2026 21:49:10 +0000 Subject: [PATCH 9/9] update test infra 2 Signed-off-by: dsengupta0628 --- sdf/test/cpp/TestSdf.cc | 9 ++++----- search/test/cpp/TestSearchClasses.cc | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/sdf/test/cpp/TestSdf.cc b/sdf/test/cpp/TestSdf.cc index 9b0f8e1e..fc4e4b72 100644 --- a/sdf/test/cpp/TestSdf.cc +++ b/sdf/test/cpp/TestSdf.cc @@ -1599,7 +1599,7 @@ TEST_F(SdfDesignTest, ReadSdfPeriod) { // R11_8: Read SDF with NOCHANGE check // Covers: SdfReader::timingCheckNochange, notSupported -// NOCHANGE is not supported and throws, so we catch the exception +// NOCHANGE is not supported and issues a warning (no longer throws) TEST_F(SdfDesignTest, ReadSdfNochange) { ASSERT_TRUE(design_loaded_); sta_->ensureGraph(); @@ -1626,11 +1626,10 @@ TEST_F(SdfDesignTest, ReadSdfNochange) { fprintf(fp, ")\n"); fclose(fp); - // NOCHANGE is not supported and throws an exception - EXPECT_THROW( + // NOCHANGE is not supported; upstream now warns instead of throwing + EXPECT_NO_THROW( readSdf(sdf_path, "", corner, false, false, - const_cast(MinMaxAll::all()), sta_), - std::exception + const_cast(MinMaxAll::all()), sta_) ); std::remove(sdf_path); diff --git a/search/test/cpp/TestSearchClasses.cc b/search/test/cpp/TestSearchClasses.cc index 5ead6736..9a2fa983 100644 --- a/search/test/cpp/TestSearchClasses.cc +++ b/search/test/cpp/TestSearchClasses.cc @@ -168,7 +168,7 @@ TEST_F(PropertyValueTest, DefaultConstructor) { } TEST_F(PropertyValueTest, StringConstructor) { - PropertyValue pv("hello"); + PropertyValue pv(std::string_view("hello")); EXPECT_EQ(pv.type(), PropertyValue::Type::string); EXPECT_EQ(pv.stringValue(), "hello"); } @@ -272,7 +272,7 @@ TEST_F(PropertyValueTest, NullClockConstructor) { } TEST_F(PropertyValueTest, CopyConstructorString) { - PropertyValue pv1("copy_test"); + PropertyValue pv1(std::string_view("copy_test")); PropertyValue pv2(pv1); EXPECT_EQ(pv2.type(), PropertyValue::Type::string); EXPECT_EQ(pv2.stringValue(), "copy_test"); @@ -379,7 +379,7 @@ TEST_F(PropertyValueTest, CopyConstructorClock) { } TEST_F(PropertyValueTest, MoveConstructorString) { - PropertyValue pv1("move_test"); + PropertyValue pv1(std::string_view("move_test")); PropertyValue pv2(std::move(pv1)); EXPECT_EQ(pv2.type(), PropertyValue::Type::string); EXPECT_EQ(pv2.stringValue(), "move_test"); @@ -476,7 +476,7 @@ TEST_F(PropertyValueTest, MoveConstructorClock) { } TEST_F(PropertyValueTest, CopyAssignmentString) { - PropertyValue pv1("assign_test"); + PropertyValue pv1(std::string_view("assign_test")); PropertyValue pv2; pv2 = pv1; EXPECT_EQ(pv2.type(), PropertyValue::Type::string); @@ -501,7 +501,7 @@ TEST_F(PropertyValueTest, CopyAssignmentBool) { TEST_F(PropertyValueTest, CopyAssignmentNone) { PropertyValue pv1; - PropertyValue pv2("replace_me"); + PropertyValue pv2(std::string_view("replace_me")); pv2 = pv1; EXPECT_EQ(pv2.type(), PropertyValue::Type::none); } @@ -587,7 +587,7 @@ TEST_F(PropertyValueTest, CopyAssignmentClock) { } TEST_F(PropertyValueTest, MoveAssignmentString) { - PropertyValue pv1("move_assign"); + PropertyValue pv1(std::string_view("move_assign")); PropertyValue pv2; pv2 = std::move(pv1); EXPECT_EQ(pv2.type(), PropertyValue::Type::string); @@ -612,7 +612,7 @@ TEST_F(PropertyValueTest, MoveAssignmentBool) { TEST_F(PropertyValueTest, MoveAssignmentNone) { PropertyValue pv1; - PropertyValue pv2("stuff"); + PropertyValue pv2(std::string_view("stuff")); pv2 = std::move(pv1); EXPECT_EQ(pv2.type(), PropertyValue::Type::none); } @@ -704,12 +704,12 @@ TEST_F(PropertyValueTest, StringValueThrowsOnWrongType) { } TEST_F(PropertyValueTest, FloatValueThrowsOnWrongType) { - PropertyValue pv("not_a_float"); + PropertyValue pv(std::string_view("not_a_float")); EXPECT_THROW(pv.floatValue(), Exception); } TEST_F(PropertyValueTest, BoolValueThrowsOnWrongType) { - PropertyValue pv("not_a_bool"); + PropertyValue pv(std::string_view("not_a_bool")); EXPECT_THROW(pv.boolValue(), Exception); } @@ -903,7 +903,7 @@ TEST_F(PropertyValueTest, ToStringBoolFalse) { // to_string for string values TEST_F(PropertyValueTest, ToStringString) { - PropertyValue pv("test_str"); + PropertyValue pv(std::string_view("test_str")); EXPECT_EQ(pv.to_string(nullptr), "test_str"); }