diff --git a/Changes b/Changes index 9004a5a94..c8890afb2 100644 --- a/Changes +++ b/Changes @@ -3,6 +3,12 @@ Revision history for Verilator The contributors that suggested a given feature are shown in []. [by ...] indicates the contributor was also the author of the fix; Thanks! +* Verilator 3.656 2008/*** + +**** Fix Perl warning with --lint-only. [by Ding Xiaoliang] + +**** Avoid creating obj_dir with --lint-only. [Ding Xiaoliang] + * Verilator 3.656 2008/01/18 **** Wide VL_CONST_W_#X functions are now made automatically. [Bernard Deadman] diff --git a/bin/verilator b/bin/verilator index ae8a72f6e..213a693fe 100755 --- a/bin/verilator +++ b/bin/verilator @@ -91,6 +91,7 @@ if (! GetOptions ( "sp!" => sub {$Opt_Sp = 'sp';}, "sc!" => sub {$Opt_Sp = 'sc';}, "cc!" => sub {$Opt_Sp = 0;}, + "lint-only!" => sub {$Opt_Sp = 0;}, #"ignc!" => ..., # Undocumented debugging, disable $c but don't complain # Additional parameters "<>" => sub {}, # Ignored @@ -434,7 +435,7 @@ to gcc -MP option. =item --Mdir I Specifies the name of the Make object directory. All generated files will -be placed in this directory. +be placed in this directory. If not specified, "obj_dir" is used. =item --mod-prefix I diff --git a/src/V3File.cpp b/src/V3File.cpp index 974b9c18d..4afdc3266 100644 --- a/src/V3File.cpp +++ b/src/V3File.cpp @@ -23,6 +23,7 @@ #include "verilatedos.h" #include #include +#include #include #include #include diff --git a/src/V3File.h b/src/V3File.h index 84f0967e5..888bab9dc 100644 --- a/src/V3File.h +++ b/src/V3File.h @@ -46,7 +46,7 @@ public: return new_ofstream_nodepend (filename, append); } static ofstream* new_ofstream_nodepend(const string& filename, bool append=false) { - createMakeDir(); + if (filename != "/dev/null") createMakeDir(); if (append) { return new ofstream(filename.c_str(), ios::app); } else { @@ -54,7 +54,7 @@ public: } } static FILE* new_fopen_w(const string& filename) { - createMakeDir(); + if (filename != "/dev/null") createMakeDir(); addTgtDepend(filename); return fopen(filename.c_str(),"w"); } diff --git a/src/V3PreShell.cpp b/src/V3PreShell.cpp index 995311226..847b04bce 100644 --- a/src/V3PreShell.cpp +++ b/src/V3PreShell.cpp @@ -33,6 +33,7 @@ #include "V3PreShell.h" #include "V3PreProc.h" #include "V3File.h" +#include "V3Read.h" //###################################################################### @@ -64,38 +65,15 @@ protected: } } - void preproc (FileLine* fl, const string& modname, const string& vppFilename) { + void preproc (FileLine* fl, const string& modname, V3Read* readerp) { // Preprocess the given module, putting output in vppFilename - unlink(vppFilename.c_str()); UINFONL(1," Preprocessing "<fail()) { - fl->v3error("Cannot write preprocessor output: "+vppFilename); - return; - } - // Preprocess preprocOpen(fl, modname, "Cannot find file containing module: "); while (!s_preprocp->isEof()) { string line = s_preprocp->getline(); - *osp << line; - } - - // Close - if (ofp) { - ofp->close(); - delete ofp; - osp = ofp = NULL; + readerp->ppPushText(line); } } @@ -129,8 +107,8 @@ V3PreProc* V3PreShellImp::s_preprocp = NULL; void V3PreShell::boot(char** env) { V3PreShellImp::s_preImp.boot(env); } -void V3PreShell::preproc(FileLine* fl, const string& modname, const string& vppFilename) { - V3PreShellImp::s_preImp.preproc(fl, modname, vppFilename); +void V3PreShell::preproc(FileLine* fl, const string& modname, V3Read* readerp) { + V3PreShellImp::s_preImp.preproc(fl, modname, readerp); } void V3PreShell::preprocInclude(FileLine* fl, const string& modname) { V3PreShellImp::s_preImp.preprocInclude(fl, modname); diff --git a/src/V3PreShell.h b/src/V3PreShell.h index 2620c873a..a387d3a23 100644 --- a/src/V3PreShell.h +++ b/src/V3PreShell.h @@ -26,13 +26,15 @@ #include "verilatedos.h" #include "V3Error.h" +class V3Read; + //============================================================================ class V3PreShell { // Static class for calling preprocessor public: static void boot(char** env); - static void preproc(FileLine* fileline, const string& module, const string& vppFilename); + static void preproc(FileLine* fileline, const string& module, V3Read* readerp); static void preprocInclude(FileLine* fileline, const string& module); static string dependFiles() { return ""; } // Perl only static void define(const string& name, const string& value); diff --git a/src/V3Read.cpp b/src/V3Read.cpp index 02cbf5d7a..78bd78c6a 100644 --- a/src/V3Read.cpp +++ b/src/V3Read.cpp @@ -57,7 +57,7 @@ extern int yydebug; class V3Lexer : public V3LexerBase { public: // CONSTRUCTORS - V3Lexer(std::istream* arg_yyin) : V3LexerBase(arg_yyin) {} + V3Lexer() : V3LexerBase(NULL) {} ~V3Lexer() {} // METHODS void stateExitPsl() { @@ -91,6 +91,29 @@ V3Read::~V3Read() { parserClear(); } +int V3Read::ppInputToLex(char* buf, int max_size) { + int got = 0; + while (got < max_size // Haven't got enough + && !m_ppBuffers.empty()) { // And something buffered + string front = m_ppBuffers.front(); m_ppBuffers.pop_front(); + int len = front.length(); + if (len > (max_size-got)) { // Front string too big + string remainder = front.substr(max_size-got); + front = front.substr(0, max_size-got); + m_ppBuffers.push_front(remainder); // Put back remainder for next time + len = (max_size-got); + } + strncpy(buf+got, front.c_str(), len); + got += len; + } + if (debug()>=9) { + string out = string(buf,got); + cout<<" inputToLex got="<fail()) { + fileline->v3error("Cannot write preprocessor output: "+vppfilename); + return; + } else { + for (deque::iterator it = m_ppBuffers.begin(); it!=m_ppBuffers.end(); ++it) { + *osp << *it; + } + if (ofp) { + ofp->close(); + delete ofp; ofp = NULL; + } + } } - if (!v3Global.opt.keepTempFiles()) { // Must match new_ofstream_nodepend rule in V3PreShell.cpp - unlink (vppfilename.c_str()); + // Parse it + if (!v3Global.opt.preprocOnly()) { + lexFile (modfilename); } } -void V3Read::lexFile(const string& vppfilename, const string& modname) { - // Open the preprocess output - // Don't track a input dependency, as we created the file ourselves - ifstream* fsp = V3File::new_ifstream_nodepend(vppfilename); - if (fsp->fail()) { - m_fileline->v3fatal("Module "<warnResetDefault(); // Reenable warnings on each file if (m_lexerp) delete m_lexerp; // Restart from clean slate. - m_lexerp = new V3Lexer(fsp); + m_lexerp = new V3Lexer(); // if (debug()) { m_lexerp->set_debug(~0); } // if (debug()) yydebug = 1; - UINFO(4,"Lexing Done "<close(); delete fsp; fsp = NULL; } //====================================================================== diff --git a/src/V3Read.h b/src/V3Read.h index 7393dad8b..f66d3a49a 100644 --- a/src/V3Read.h +++ b/src/V3Read.h @@ -45,6 +45,7 @@ class V3Read { deque m_stringps; // Created strings for later cleanup deque m_numberps; // Created numbers for later cleanup deque m_lintState; // Current lint state for save/restore + deque m_ppBuffers; // Preprocessor->lex buffer of characters to process //int debug() { return 9; } protected: @@ -52,6 +53,7 @@ protected: friend class V3Lexer; friend class V3LexerBase; friend class FileLine; + friend class V3PreShellImp; int yylexThis(); static bool optPsl(); static void ppline (const char* text); @@ -64,6 +66,9 @@ protected: static bool popBeginKeywords() { if (s_readp->m_inBeginKwd) { s_readp->m_inBeginKwd--; return true; } else return false; } static int lastVerilogState() { return s_readp->m_lastVerilogState; } + void ppPushText(const string& text) { m_ppBuffers.push_back(text); } + int ppInputToLex(char* buf, int max_size); + public: // But for internal use only static string* newString(const string& text) { // Allocate a string, remembering it so we can reclaim storage at lex end @@ -100,6 +105,7 @@ public: // But for internal use only static void statePushVlg(); // Parser -> lexer communication static void statePop(); // Parser -> lexer communication static int stateVerilogRecent(); // Parser -> lexer communication + static int flexPpInputToLex(char* buf, int max_size) { return s_readp->ppInputToLex(buf,max_size); } public: // CREATORS @@ -118,7 +124,7 @@ public: void readFile(FileLine* fileline, const string& modname, bool inLibrary); private: - void lexFile(const string& vppfilename, const string& modname); + void lexFile(const string& modname); }; #endif // Guard diff --git a/src/Verilator.cpp b/src/Verilator.cpp index c1e399af7..564b73dab 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -464,6 +464,7 @@ void process () { V3EmitC::emitcSyms(); V3EmitC::emitcTrace(); } + // Unfortunately we have some lint checks in emitc. V3EmitC::emitc(); // Statistics diff --git a/src/verilog.l b/src/verilog.l index dd2e35ed8..6de8c680c 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -33,6 +33,9 @@ extern void yyerrorf(const char* format, ...); #define STATE_VERILOG_RECENT S05 // State name for most recent Verilog Version +#define YY_INPUT(buf,result,max_size) \ + result = V3Read::flexPpInputToLex(buf,max_size); + //====================================================================== #define NEXTLINE() {V3Read::incLineno();} diff --git a/test_regress/t/t_var_in_assign_bad.pl b/test_regress/t/t_var_in_assign_bad.pl index 12b622577..0a2972f2d 100755 --- a/test_regress/t/t_var_in_assign_bad.pl +++ b/test_regress/t/t_var_in_assign_bad.pl @@ -8,7 +8,7 @@ if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; } # General Public License or the Perl Artistic License. compile ( - v_flags2 => ["--lint-only"], + v_flags2 => ["--lint-only --Mdir obj_lint_only"], fails=>1, expect=> '%Error: t/t_var_in_assign_bad.v:\d+: Assigning to input variable: value @@ -16,5 +16,6 @@ compile ( %Error: Exiting due to.*', ) if $Last_Self->{v3}; +(!-d "obj_lint_only") or $Last_Self->error("%Error: lint-only shouldn't make output directory"); ok(1); 1;