diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index b459d85ff..1c8ec68a4 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -6095,7 +6095,7 @@ private: AstExecGraph* m_execGraphp; // Execution MTask graph for threads>1 mode public: AstNetlist() - : AstNode(new FileLine(FileLine::builtInFilename(), 0)) + : AstNode(new FileLine(FileLine::builtInFilename())) , m_typeTablep(NULL) , m_dollarUnitPkgp(NULL) , m_evalp(NULL) diff --git a/src/V3FileLine.h b/src/V3FileLine.h index 62c501dea..f0b4baba2 100644 --- a/src/V3FileLine.h +++ b/src/V3FileLine.h @@ -49,7 +49,7 @@ class FileLineSingleton { FileNameNumMap m_namemap; // filenameno for each filename std::deque m_names; // filename text for each filenameno std::deque m_languages; // language for each filenameno - // COSNTRUCTORS + // CONSTRUCTORS FileLineSingleton() { } ~FileLineSingleton() { } protected: @@ -70,21 +70,12 @@ protected: //! millions). To save space, per-file information (e.g. filename, source //! language is held in tables in the FileLineSingleton class. class FileLine { + // MEMBERS int m_lineno; // `line corrected line number int m_filenameno; // `line corrected filename number FileLine* m_parent; // Parent line that included this line std::bitset m_warnOn; -private: - struct EmptySecret {}; - inline static FileLineSingleton& singleton() { - static FileLineSingleton s; - return s; - } - inline static FileLine& defaultFileLine() { - static FileLine* defFilelinep = new FileLine(FileLine::EmptySecret()); - return *defFilelinep; - } protected: // User routines should never need to change line numbers // We are storing pointers, so we CAN'T change them after initial reading. @@ -93,15 +84,23 @@ protected: friend class V3PreLex; friend class V3PreProcImp; friend class V3PreShellImp; - void lineno(int num) { m_lineno = num; } - void language(V3LangCode lang) { singleton().numberToLang(m_filenameno, lang); } - void filename(const string& name) { m_filenameno = singleton().nameToNumber(name); } - void parent(FileLine* fileline) { m_parent = fileline; } - void lineDirective(const char* textp, int& enterExitRef); - void linenoInc() { m_lineno++; } - void linenoIncInPlace() { m_lineno++; } - FileLine* copyOrSameFileLine(); +private: + // CONSTRUCTORS + static FileLineSingleton& singleton() { + static FileLineSingleton s; + return s; + } + static FileLine& defaultFileLine() { + static FileLine* defFilelinep = new FileLine(FileLine::EmptySecret()); + return *defFilelinep; + } public: + FileLine(const string& filename) { + m_lineno = 0; + m_filenameno = singleton().nameToNumber(filename); + m_parent = NULL; + m_warnOn = defaultFileLine().m_warnOn; + } FileLine(const string& filename, int lineno) { m_lineno = lineno; m_filenameno = singleton().nameToNumber(filename); @@ -114,15 +113,23 @@ public: m_parent = fromp->m_parent; m_warnOn = fromp->m_warnOn; } + struct EmptySecret {}; // Constructor selection explicit FileLine(EmptySecret); - ~FileLine() { } - FileLine* create(const string& filename, int lineno) { return new FileLine(filename, lineno); } - FileLine* create(int lineno) { return create(filename(), lineno); } + FileLine* copyOrSameFileLine(); static void deleteAllRemaining(); + ~FileLine() { } #ifdef VL_LEAK_CHECKS static void* operator new(size_t size); static void operator delete(void* obj, size_t size); #endif + // METHODS + void lineno(int num) { m_lineno = num; } + void language(V3LangCode lang) { singleton().numberToLang(m_filenameno, lang); } + void filename(const string& name) { m_filenameno = singleton().nameToNumber(name); } + void parent(FileLine* fileline) { m_parent = fileline; } + void lineDirective(const char* textp, int& enterExitRef); + void linenoInc() { m_lineno++; } + void linenoIncInPlace() { m_lineno++; } int lineno() const { return m_lineno; } FileLine* parent() const { return m_parent; } @@ -188,9 +195,10 @@ public: /// When building an error, additional location for additional references /// Simplified information vs warnContextPrimary() to make dump clearer string warnContextSecondary() const { return warnContext(true); } - inline bool operator==(FileLine rhs) const { - return (m_lineno==rhs.m_lineno && m_filenameno==rhs.m_filenameno - && m_warnOn==rhs.m_warnOn); + bool operator==(FileLine rhs) const { + return (m_lineno == rhs.m_lineno + && m_filenameno == rhs.m_filenameno + && m_warnOn == rhs.m_warnOn); } private: void v3errorEndFatalGuts(std::ostringstream& str); diff --git a/src/V3Number_test.cpp b/src/V3Number_test.cpp index 9cb4cba2f..ba74f153b 100644 --- a/src/V3Number_test.cpp +++ b/src/V3Number_test.cpp @@ -38,7 +38,7 @@ void test(const string& lhss, const string& op, const string& rhss, const string char* r1 = strdup(rhss.c_str()); char* e1 = strdup(exps.c_str()); - FileLine fl = new FileLine(FileLine::builtInFinename(), 0); + FileLine fl = new FileLine(FileLine::builtInFinename()); V3Number lhnum (fl, l1); V3Number rhnum (fl, r1); diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 930006b42..73d883ee0 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1157,7 +1157,7 @@ void V3Options::parseOptsFile(FileLine* fl, const string& filename, bool rel) { whole_file += "\n"; // So string match below is simplified if (inCmt) fl->v3error("Unterminated /* comment inside -f file."); - fl = new FileLine(filename, 0); + fl = new FileLine(filename); // Split into argument list and process // Note we don't respect quotes. It seems most simulators dont. diff --git a/src/V3PreProc.cpp b/src/V3PreProc.cpp index be27ee6f2..d0f3f3f16 100644 --- a/src/V3PreProc.cpp +++ b/src/V3PreProc.cpp @@ -265,7 +265,7 @@ public: void configure(FileLine* filelinep) { // configure() separate from constructor to avoid calling abstract functions m_preprocp = this; // Silly, but to make code more similar to Verilog-Perl - m_finFilelinep = filelinep->create(1); + m_finFilelinep = new FileLine(filelinep->filename(), 1); // Create lexer m_lexp = new V3PreLex(this, filelinep); m_lexp->m_keepComments = m_preprocp->keepComments(); @@ -767,7 +767,7 @@ void V3PreProcImp::openFile(FileLine* fl, V3InFilter* filterp, const string& fil } // Create new stream structure - m_lexp->scanNewFile(m_preprocp->fileline()->create(filename, 1)); + m_lexp->scanNewFile(new FileLine(filename, 1)); addLineComment(1); // Enter // Filter all DOS CR's en-mass. This avoids bugs with lexing CRs in the wrong places. @@ -1460,8 +1460,8 @@ int V3PreProcImp::getFinalToken(string& buf) { m_lexp->m_tokFilelinep->lineno(), m_finFilelinep->lineno(), m_lexp->m_tokFilelinep->lineno()); } - m_finFilelinep = m_finFilelinep->create(m_lexp->m_tokFilelinep->filename(), - m_lexp->m_tokFilelinep->lineno()); + m_finFilelinep = new FileLine(m_lexp->m_tokFilelinep->filename(), + m_lexp->m_tokFilelinep->lineno()); if (outBehind > 0 && (outBehind <= static_cast(V3PreProc::NEWLINES_VS_TICKLINE))) { // Output stream is behind, send newlines to get back in sync diff --git a/src/V3PreShell.cpp b/src/V3PreShell.cpp index cf03b93dc..57b5a856b 100644 --- a/src/V3PreShell.cpp +++ b/src/V3PreShell.cpp @@ -60,11 +60,11 @@ protected: // Create the implementation pointer if (env) {} if (!s_preprocp) { - FileLine* cmdfl = new FileLine(FileLine::commandLineFilename(), 0); + FileLine* cmdfl = new FileLine(FileLine::commandLineFilename()); s_preprocp = V3PreProc::createPreProc(cmdfl); s_preprocp->debug(debug()); // Default defines - FileLine* prefl = new FileLine(FileLine::builtInFilename(), 0); + FileLine* prefl = new FileLine(FileLine::builtInFilename()); s_preprocp->defineCmdLine(prefl, "VERILATOR", "1"); // LEAK_OK s_preprocp->defineCmdLine(prefl, "verilator", "1"); // LEAK_OK s_preprocp->defineCmdLine(prefl, "verilator3", "1"); // LEAK_OK @@ -111,7 +111,7 @@ protected: // from the V3LangCode to the various Lex BEGIN states. The language // of this source file is updated here, in case there have been any // intervening +ext+ options since it was first ecountered. - FileLine* modfileline = new FileLine(modfilename, 0); + FileLine* modfileline = new FileLine(modfilename); modfileline->language(v3Global.opt.fileLanguage(modfilename)); V3Parse::ppPushText(parsep, (string("`begin_keywords \"") +modfileline->language().ascii()+"\"\n")); @@ -178,7 +178,7 @@ void V3PreShell::preprocInclude(FileLine* fl, const string& modname) { V3PreShellImp::s_preImp.preprocInclude(fl, modname); } void V3PreShell::defineCmdLine(const string& name, const string& value) { - FileLine* prefl = new FileLine(FileLine::commandLineFilename(), 0); + FileLine* prefl = new FileLine(FileLine::commandLineFilename()); V3PreShellImp::s_preprocp->defineCmdLine(prefl, name, value); } void V3PreShell::undef(const string& name) { diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 6c693b14b..a7c73173e 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -127,7 +127,7 @@ void V3Global::readFiles() { const V3StringList& vFiles = v3Global.opt.vFiles(); for (V3StringList::const_iterator it = vFiles.begin(); it != vFiles.end(); ++it) { string filename = *it; - parser.parseFile(new FileLine(FileLine::commandLineFilename(), 0), + parser.parseFile(new FileLine(FileLine::commandLineFilename()), filename, false, "Cannot find file containing module: "); } @@ -138,7 +138,7 @@ void V3Global::readFiles() { const V3StringSet& libraryFiles = v3Global.opt.libraryFiles(); for (V3StringSet::const_iterator it = libraryFiles.begin(); it != libraryFiles.end(); ++it) { string filename = *it; - parser.parseFile(new FileLine(FileLine::commandLineFilename(), 0), + parser.parseFile(new FileLine(FileLine::commandLineFilename()), filename, true, "Cannot find file containing library module: "); } @@ -584,7 +584,7 @@ int main(int argc, char** argv, char** env) { // Command option parsing v3Global.opt.bin(argv[0]); string argString = V3Options::argString(argc-1, argv+1); - v3Global.opt.parseOpts(new FileLine(FileLine::commandLineFilename(), 0), + v3Global.opt.parseOpts(new FileLine(FileLine::commandLineFilename()), argc-1, argv+1); if (!v3Global.opt.outFormatOk() && !v3Global.opt.preprocOnly()