void FileLine::operator delete(void* objp, size_t size) { if (!objp) return; FileLine* flp = static_cast<FileLine*>(objp); FileLineCheckSet::iterator it = fileLineLeakChecks.find(flp); if (it != fileLineLeakChecks.end()) { fileLineLeakChecks.erase(it); } else { flp->v3fatalSrc("Deleting FileLine object that was never tracked"); } ::operator delete(objp); }
int V3PreProcImp::getFinalToken(string& buf) { // Return the next user-visible token in the input stream. // Includes and such are handled here, and are never seen by the caller. if (!m_finAhead) { m_finAhead = true; m_finToken = getStateToken(); m_finBuf = string (yyourtext(), yyourleng()); } int tok = m_finToken; buf = m_finBuf; if (0 && debug()>=5) { string bufcln = V3PreLex::cleanDbgStrg(buf); fprintf (stderr,"%d: FIN: %-10s: %s\n", m_lexp->m_tokFilelinep->lineno(), tokenName(tok), bufcln.c_str()); } // Track `line const char* bufp = buf.c_str(); while (*bufp == '\n') bufp++; if ((tok == VP_TEXT || tok == VP_LINE) && 0==strncmp(bufp,"`line ",6)) { int enter; m_finFilelinep->lineDirective(bufp, enter/*ref*/); } else { if (m_finAtBol && !(tok==VP_TEXT && buf=="\n") && m_preprocp->lineDirectives()) { if (int outBehind = m_lexp->m_tokFilelinep->lineno() - m_finFilelinep->lineno()) { if (debug()>=5) fprintf(stderr,"%d: FIN: readjust, fin at %d request at %d\n", 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()); if (outBehind > 0 && outBehind <= (int)V3PreProc::NEWLINES_VS_TICKLINE) { // Output stream is behind, send newlines to get back in sync // (Most likely because we're completing a disabled `endif) if (m_preprocp->keepWhitespace()) { buf = string(outBehind,'\n'); return VP_TEXT; } } else { // Need to backup, use `line buf = m_finFilelinep->lineDirectiveStrg(0); return VP_LINE; } } } // Track newlines in prep for next token for (string::iterator cp=buf.begin(); cp!=buf.end(); ++cp) { if (*cp == '\n') { m_finAtBol = true; m_finFilelinep->linenoIncInPlace(); // Increment in place to avoid new/delete calls. It's private data. } else { m_finAtBol = false; } } } m_finAhead = false; // Consumed the token return tok; }
void boot(char** env) { // Create the implementation pointer if (env) {} if (!s_preprocp) { FileLine* cmdfl = new FileLine("COMMAND_LINE",0); s_preprocp = V3PreProc::createPreProc(cmdfl); s_preprocp->debug(debug()); // Default defines FileLine* prefl = new FileLine("INTERNAL_VERILATOR_DEFINE",0); s_preprocp->defineCmdLine(prefl,"VERILATOR", "1"); // LEAK_OK s_preprocp->defineCmdLine(prefl,"verilator", "1"); // LEAK_OK s_preprocp->defineCmdLine(prefl,"verilator3", "1"); // LEAK_OK s_preprocp->defineCmdLine(prefl,"systemc_clock", "/*verilator systemc_clock*/"); // LEAK_OK s_preprocp->defineCmdLine(prefl,"coverage_block_off", "/*verilator coverage_block_off*/"); // LEAK_OK if (prefl->language().systemVerilog()) { // Synthesis compatibility s_preprocp->defineCmdLine(prefl,"SYSTEMVERILOG", "1"); // LEAK_OK // IEEE predefined s_preprocp->defineCmdLine(prefl,"SV_COV_START", "0"); s_preprocp->defineCmdLine(prefl,"SV_COV_STOP", "1"); s_preprocp->defineCmdLine(prefl,"SV_COV_RESET", "2"); s_preprocp->defineCmdLine(prefl,"SV_COV_CHECK", "3"); s_preprocp->defineCmdLine(prefl,"SV_COV_MODULE", "10"); s_preprocp->defineCmdLine(prefl,"SV_COV_HIER", "11"); s_preprocp->defineCmdLine(prefl,"SV_COV_ASSERTION", "20"); s_preprocp->defineCmdLine(prefl,"SV_COV_FSM_STATE", "21"); s_preprocp->defineCmdLine(prefl,"SV_COV_STATEMENT", "22"); s_preprocp->defineCmdLine(prefl,"SV_COV_TOGGLE", "23"); s_preprocp->defineCmdLine(prefl,"SV_COV_OVERFLOW", "-2"); s_preprocp->defineCmdLine(prefl,"SV_COV_ERROR", "-1"); s_preprocp->defineCmdLine(prefl,"SV_COV_NOCOV", "0"); s_preprocp->defineCmdLine(prefl,"SV_COV_OK", "1"); s_preprocp->defineCmdLine(prefl,"SV_COV_PARTIAL", "2"); } } }
void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool inLibrary, const string& errmsg) { // "" for no error, make fake node string modname = V3Os::filenameNonExt(modfilename); UINFO(2,__FUNCTION__<<": "<<modname<<(inLibrary?" [LIB]":"")<<endl); m_fileline = new FileLine(fileline); m_inLibrary = inLibrary; // Set language standard up front if (!v3Global.opt.preprocOnly()) { // Leting lex parse this saves us from having to specially en/decode // 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 +<lang>ext+ options since it was first ecountered. FileLine *modfileline = new FileLine (modfilename, 0); modfileline->language(v3Global.opt.fileLanguage(modfilename)); ppPushText((string)"`begin_keywords \""+modfileline->language().ascii()+"\"\n"); } // Preprocess into m_ppBuffer bool ok = V3PreShell::preproc(fileline, modfilename, m_filterp, this, errmsg); if (!ok) { if (errmsg != "") return; // Threw error already // Create fake node for later error reporting AstNodeModule* nodep = new AstNotFoundModule(fileline, modname); v3Global.rootp()->addModulep(nodep); return; } if (v3Global.opt.preprocOnly() || v3Global.opt.keepTempFiles()) { // Create output file with all the preprocessor output we buffered up string vppfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_"+modname+".vpp"; ofstream* ofp = NULL; ostream* osp; bool noblanks = v3Global.opt.preprocOnly() && v3Global.opt.preprocNoLine(); if (v3Global.opt.preprocOnly()) { osp = &cout; } else { osp = ofp = V3File::new_ofstream(vppfilename); } if (osp->fail()) { fileline->v3error("Cannot write preprocessor output: "+vppfilename); return; } else { for (deque<string>::iterator it = m_ppBuffers.begin(); it!=m_ppBuffers.end(); ++it) { if (noblanks) { bool blank = true; for (string::iterator its = it->begin(); its != it->end(); ++its) { if (!isspace(*its) && *its!='\n') { blank=false; break; } } if (blank) continue; } *osp << *it; } if (ofp) { ofp->close(); delete ofp; VL_DANGLING(ofp); } } } // Parse it if (!v3Global.opt.preprocOnly()) { lexFile (modfilename); } }