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");
	    }
	}
    }
Beispiel #4
0
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);
    }
}