本文整理汇总了C++中AstNode::nextp方法的典型用法代码示例。如果您正苦于以下问题:C++ AstNode::nextp方法的具体用法?C++ AstNode::nextp怎么用?C++ AstNode::nextp使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类AstNode
的用法示例。
在下文中一共展示了AstNode::nextp方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: visit
virtual void visit(AstWhile* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (m_varModeCheck || m_varModeReplace) {
} else {
// Constify before unroll call, as it may change what is underneath.
if (nodep->precondsp()) V3Const::constifyEdit(nodep->precondsp()); // precondsp may change
if (nodep->condp()) V3Const::constifyEdit(nodep->condp()); // condp may change
// Grab initial value
AstNode* initp = NULL; // Should be statement before the while.
if (nodep->backp()->nextp() == nodep) initp=nodep->backp();
if (initp) { V3Const::constifyEdit(initp); VL_DANGLING(initp); }
if (nodep->backp()->nextp() == nodep) initp=nodep->backp();
// Grab assignment
AstNode* incp = NULL; // Should be last statement
if (nodep->incsp()) V3Const::constifyEdit(nodep->incsp());
if (nodep->incsp()) incp = nodep->incsp();
else {
for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {}
if (incp) { V3Const::constifyEdit(incp); VL_DANGLING(incp); }
for (incp = nodep->bodysp(); incp && incp->nextp(); incp = incp->nextp()) {} // Again, as may have changed
}
// And check it
if (forUnrollCheck(nodep, initp,
nodep->precondsp(), nodep->condp(),
incp, nodep->bodysp())) {
pushDeletep(nodep); VL_DANGLING(nodep); // Did replacement
}
}
}
示例2: visit
virtual void visit(AstGenCase* nodep, AstNUser*) {
UINFO(9," GENCASE "<<nodep<<endl);
AstNode* keepp = NULL;
nodep->exprp()->iterateAndNext(*this);
V3Case::caseLint(nodep);
V3Width::widthParamsEdit(nodep); // Param typed widthing will NOT recurse the body,
// don't trigger errors yet.
V3Const::constifyParamsEdit(nodep->exprp()); // exprp may change
AstConst* exprp = nodep->exprp()->castConst();
// Constify
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstNode* ep = itemp->condsp(); ep; ) {
AstNode* nextp = ep->nextp(); //May edit list
ep->iterateAndNext(*this);
V3Const::constifyParamsEdit(ep); ep=NULL; // ep may change
// cppcheck-suppress redundantAssignment
ep = nextp;
}
}
// Item match
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
if (!itemp->isDefault()) {
for (AstNode* ep = itemp->condsp(); ep; ep=ep->nextp()) {
if (AstConst* ccondp = ep->castConst()) {
V3Number match (nodep->fileline(), 1);
match.opEq(ccondp->num(), exprp->num());
if (!keepp && match.isNeqZero()) {
keepp = itemp->bodysp();
}
} else {
itemp->v3error("Generate Case item does not evaluate to constant");
}
}
}
}
// Else default match
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
if (itemp->isDefault()) {
if (!keepp) keepp=itemp->bodysp();
}
}
// Replace
if (keepp) {
keepp->unlinkFrBackWithNext();
nodep->replaceWith(keepp);
}
else nodep->unlinkFrBack();
nodep->deleteTree(); nodep=NULL;
}
示例3: visit
virtual void visit(AstUdpTable* nodep, AstNUser*) {
UINFO(5,"UDPTABLE "<<nodep<<endl);
if (!v3Global.opt.bboxUnsup()) {
// We don't warn until V3Inst, so that UDPs that are in libraries and
// never used won't result in any warnings.
} else {
// Massive hack, just tie off all outputs so our analysis can proceed
AstVar* varoutp = NULL;
for (AstNode* stmtp = m_modp->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* varp = stmtp->castVar()) {
if (varp->isInput()) {
} else if (varp->isOutput()) {
if (varoutp) { varp->v3error("Multiple outputs not allowed in udp modules"); }
varoutp = varp;
// Tie off
m_modp->addStmtp(new AstAssignW(varp->fileline(),
new AstVarRef(varp->fileline(), varp, true),
new AstConst(varp->fileline(), AstConst::LogicFalse())));
} else {
varp->v3error("Only inputs and outputs are allowed in udp modules");
}
}
}
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
}
}
示例4: repairCache
void AstTypeTable::repairCache() {
// After we mass-change widthMin in V3WidthCommit, we need to correct the table.
clearCache();
for (AstNode* nodep = typesp(); nodep; nodep=nodep->nextp()) {
if (AstBasicDType* bdtypep = nodep->castBasicDType()) {
(void)findInsertSameDType(bdtypep);
}
}
}
示例5: visit
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
AstNode* pinp = nodep->pinsp();
AstNodeFTask* taskp = nodep->taskp();
// We'll deal with mismatching pins later
if (!taskp) return;
for (AstNode* stmtp = taskp->stmtsp(); stmtp && pinp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (portp->isIO()) {
if (portp->isInput()) {
pinp->iterate(*this);
} else { // Output or Inout
m_setRefLvalue = true;
pinp->iterate(*this);
m_setRefLvalue = false;
}
// Advance pin
pinp = pinp->nextp();
}
}
}
}
示例6: findAddLabel
AstJumpLabel* findAddLabel(AstNode* nodep, bool endOfIter) {
// Put label under given node, and if WHILE optionally at end of iteration
UINFO(4,"Create label for "<<nodep<<endl);
if (nodep->castJumpLabel()) return nodep->castJumpLabel(); // Done
AstNode* underp = NULL;
bool under_and_next = true;
if (nodep->castBegin()) underp = nodep->castBegin()->stmtsp();
else if (nodep->castNodeFTask()) underp = nodep->castNodeFTask()->stmtsp();
else if (nodep->castWhile()) {
if (endOfIter) {
// Note we jump to end of bodysp; a FOR loop has its increment under incsp() which we don't skip
underp = nodep->castWhile()->bodysp();
} else {
underp = nodep; under_and_next=false; // IE we skip the entire while
}
}
else {
nodep->v3fatalSrc("Unknown jump point for break/disable/continue");
return NULL;
}
// Skip over variables as we'll just move them in a momement
// Also this would otherwise prevent us from using a label twice
// see t_func_return test.
while (underp && underp->castVar()) underp = underp->nextp();
if (underp) UINFO(5," Underpoint is "<<underp<<endl);
if (!underp) {
nodep->v3fatalSrc("Break/disable/continue not under expected statement");
return NULL;
} else if (underp->castJumpLabel()) {
return underp->castJumpLabel();
} else { // Move underp stuff to be under a new label
AstJumpLabel* labelp = new AstJumpLabel(nodep->fileline(), NULL);
AstNRelinker repHandle;
if (under_and_next) underp->unlinkFrBackWithNext(&repHandle);
else underp->unlinkFrBack(&repHandle);
repHandle.relink(labelp);
labelp->addStmtsp(underp);
// Keep any AstVars under the function not under the new JumpLabel
for (AstNode* nextp, *varp=underp; varp; varp = nextp) {
nextp = varp->nextp();
if (varp->castVar()) {
labelp->addPrev(varp->unlinkFrBack());
}
}
return labelp;
}
}
示例7: emitDpiImp
void EmitCSyms::emitDpiImp() {
UINFO(6,__FUNCTION__<<": "<<endl);
string filename = v3Global.opt.makeDir()+"/"+topClassName()+"__Dpi.cpp";
AstCFile* cfilep = newCFile(filename, false/*slow*/, true/*source*/);
cfilep->support(true);
V3OutCFile hf (filename);
m_ofp = &hf;
m_ofp->putsHeader();
puts("// DESCR" "IPTION: Verilator output: Implementation of DPI export functions.\n");
puts("//\n");
puts("// Verilator compiles this file in when DPI functions are used.\n");
puts("// If you have multiple Verilated designs with the same DPI exported\n");
puts("// function names, you will get multiple definition link errors from here.\n");
puts("// This is an unfortunate result of the DPI specification.\n");
puts("// To solve this, either\n");
puts("// 1. Call "+topClassName()+"::{export_function} instead,\n");
puts("// and do not even bother to compile this file\n");
puts("// or 2. Compile all __Dpi.cpp files in the same compiler run,\n");
puts("// and #ifdefs already inserted here will sort everything out.\n");
puts("\n");
puts("#include \""+topClassName()+"__Dpi.h\"\n");
puts("#include \""+topClassName()+".h\"\n");
puts("\n");
for (vector<AstCFunc*>::iterator it = m_dpis.begin(); it != m_dpis.end(); ++it) {
AstCFunc* nodep = *it;
if (nodep->dpiExportWrapper()) {
puts("#ifndef _VL_DPIDECL_"+nodep->name()+"\n");
puts("#define _VL_DPIDECL_"+nodep->name()+"\n");
puts(nodep->rtnTypeVoid()+" "+nodep->name()+" ("+cFuncArgs(nodep)+") {\n");
puts("// DPI Export at "+nodep->fileline()->ascii()+"\n");
puts("return "+topClassName()+"::"+nodep->name()+"(");
string args;
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* portp = stmtp->castVar()) {
if (portp->isIO() && !portp->isFuncReturn()) {
if (args != "") args+= ", ";
args += portp->name();
}
}
}
puts(args+");\n");
puts("}\n");
puts("#endif\n");
puts("\n");
}
}
}
示例8: makeSmallNames
void makeSmallNames(AstNodeModule* modp) {
vector<int> usedLetter; usedLetter.resize(256);
// Pass 1, assign first letter to each gparam's name
for (AstNode* stmtp = modp->stmtsp(); stmtp; stmtp=stmtp->nextp()) {
if (AstVar* varp = stmtp->castVar()) {
if (varp->isGParam()||varp->isIfaceRef()) {
char ch = varp->name()[0];
ch = toupper(ch); if (ch<'A' || ch>'Z') ch='Z';
varp->user4(usedLetter[static_cast<int>(ch)]*256 + ch);
usedLetter[static_cast<int>(ch)]++;
}
}
}
}
示例9: visit
virtual void visit(AstNodeModule* nodep, AstNUser*) {
// Create required blocks and add to module
string scopename;
if (!m_aboveScopep) scopename = "TOP";
else scopename = m_aboveScopep->name()+"."+m_aboveCellp->name();
UINFO(4," MOD AT "<<scopename<<" "<<nodep<<endl);
AstNode::user1ClearTree();
m_scopep = new AstScope((m_aboveCellp?(AstNode*)m_aboveCellp:(AstNode*)nodep)->fileline(),
nodep, scopename, m_aboveScopep, m_aboveCellp);
// Now for each child cell, iterate the module this cell points to
for (AstNode* cellnextp = nodep->stmtsp(); cellnextp; cellnextp=cellnextp->nextp()) {
if (AstCell* cellp = cellnextp->castCell()) {
AstScope* oldScopep = m_scopep;
AstCell* oldAbCellp = m_aboveCellp;
AstScope* oldAbScopep = m_aboveScopep;
{
m_aboveCellp = cellp;
m_aboveScopep = m_scopep;
AstNodeModule* modp = cellp->modp();
if (!modp) cellp->v3fatalSrc("Unlinked mod");
modp->accept(*this); // Recursive call to visit(AstNodeModule)
}
// Done, restore vars
m_scopep = oldScopep;
m_aboveCellp = oldAbCellp;
m_aboveScopep = oldAbScopep;
}
}
// Create scope for the current usage of this module
UINFO(4," back AT "<<scopename<<" "<<nodep<<endl);
AstNode::user1ClearTree();
m_modp = nodep;
if (m_modp->isTop()) {
AstTopScope* topscp = new AstTopScope(nodep->fileline(), m_scopep);
m_modp->addStmtp(topscp);
} else {
m_modp->addStmtp(m_scopep);
}
// Copy blocks into this scope
// If this is the first usage of the block ever, we can simply move the reference
nodep->iterateChildren(*this);
// ***Note m_scopep is passed back to the caller of the routine (above)
}
示例10: visit
// VISITORS //========== Case assertions
virtual void visit(AstCase* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (!nodep->user1Inc()) {
bool has_default=false;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
if (itemp->isDefault()) has_default=true;
}
if (nodep->fullPragma() || nodep->priorityPragma()) {
// Simply need to add a default if there isn't one already
++m_statAsFull;
if (!has_default) {
nodep->addItemsp(new AstCaseItem(nodep->fileline(), NULL/*DEFAULT*/,
newFireAssert(nodep, "synthesis full_case, but non-match found")));
}
}
if (nodep->parallelPragma() || nodep->uniquePragma() || nodep->unique0Pragma()) {
// Need to check that one, and only one of the case items match at any moment
// If there's a default, we allow none to match, else exactly one must match
++m_statAsFull;
if (!has_default && !nodep->itemsp()) {
// Not parallel, but harmlessly so.
} else {
AstNode* propp = NULL;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
AstNode* onep = new AstEq(icondp->fileline(),
nodep->exprp()->cloneTree(false),
icondp->cloneTree(false));
if (propp) propp = new AstConcat(icondp->fileline(), onep, propp);
else propp = onep;
}
}
bool allow_none = has_default || nodep->unique0Pragma();
AstNode* ohot = (allow_none
? (new AstOneHot0(nodep->fileline(), propp))->castNode()
: (new AstOneHot (nodep->fileline(), propp))->castNode());
AstIf* ifp = new AstIf (nodep->fileline(),
new AstLogNot (nodep->fileline(), ohot),
newFireAssert(nodep, "synthesis parallel_case, but multiple matches found"),
NULL);
ifp->branchPred(AstBranchPred::BP_UNLIKELY);
nodep->addNotParallelp(ifp);
}
}
}
}
示例11: visit
// VISITORS
virtual void visit(AstNodeModule* nodep, AstNUser*) {
allNodes(nodep);
if (!m_fast) {
nodep->iterateChildrenConst(*this);
} else {
for (AstNode* searchp = nodep->stmtsp(); searchp; searchp=searchp->nextp()) {
if (AstCFunc* funcp = searchp->castCFunc()) {
if (funcp->name() == "_eval") {
m_instrs=0;
m_counting = true;
funcp->iterateChildrenConst(*this);
m_counting = false;
}
}
}
}
}
示例12: visit
// Autoflush
virtual void visit(AstDisplay* nodep, AstNUser*) {
startStatement(nodep);
nodep->iterateChildren(*this);
m_stmtp = NULL;
if (v3Global.opt.autoflush()) {
AstNode* searchp = nodep->nextp();
while (searchp && searchp->castComment()) searchp = searchp->nextp();
if (searchp
&& searchp->castDisplay()
&& nodep->filep()->sameGateTree(searchp->castDisplay()->filep())) {
// There's another display next; we can just wait to flush
} else {
UINFO(4,"Autoflush "<<nodep<<endl);
nodep->addNextHere(new AstFFlush(nodep->fileline(),
nodep->filep()->cloneTree(true)));
}
}
}
示例13: clearCache
void AstTypeTable::clearCache() {
// When we mass-change widthMin in V3WidthCommit, we need to correct the table.
// Just clear out the maps; the search functions will be used to rebuild the map
for (int i=0; i<(int)(AstBasicDTypeKwd::_ENUM_MAX); ++i) {
m_basicps[i] = NULL;
}
for (int isbit=0; isbit<_IDX0_MAX; ++isbit) {
for (int numer=0; numer<AstNumeric::_ENUM_MAX; ++numer) {
LogicMap& mapr = m_logicMap[isbit][numer];
mapr.clear();
}
}
m_detailedMap.clear();
// Clear generic()'s so dead detection will work
for (AstNode* nodep = typesp(); nodep; nodep=nodep->nextp()) {
if (AstBasicDType* bdtypep = nodep->castBasicDType()) {
bdtypep->generic(false);
}
}
}
示例14: visit
virtual void visit(AstCell* nodep, AstNUser*) {
// Cell: Resolve its filename. If necessary, parse it.
if (nodep->user1SetOnce()) return; // AstBind and AstNodeModule may call a cell twice
if (!nodep->modp()) {
UINFO(4,"Link Cell: "<<nodep<<endl);
// Use findIdFallback instead of findIdFlat; it doesn't matter for now
// but we might support modules-under-modules someday.
AstNodeModule* modp = resolveModule(nodep,nodep->modName());
if (modp) {
nodep->modp(modp);
// Track module depths, so can sort list from parent down to children
new V3GraphEdge(&m_graph, vertex(m_modp), vertex(modp), 1, false);
}
}
// Remove AstCell(AstPin("",NULL)), it's a side effect of how we parse "()"
// the empty middle is identical to the empty rule that must find pins in "(,)".
if (nodep->pinsp() && !nodep->pinsp()->nextp()
&& nodep->pinsp()->name() == ""
&& !nodep->pinsp()->exprp()) {
pushDeletep(nodep->pinsp()->unlinkFrBackWithNext());
}
if (nodep->paramsp() && !nodep->paramsp()->nextp()
&& nodep->paramsp()->name() == ""
&& !nodep->paramsp()->exprp()) {
pushDeletep(nodep->paramsp()->unlinkFrBackWithNext());
}
// Convert .* to list of pins
bool pinStar = false;
for (AstPin* nextp, *pinp = nodep->pinsp(); pinp; pinp=nextp) {
nextp = pinp->nextp()->castPin();
if (pinp->dotStar()) {
if (pinStar) pinp->v3error("Duplicate .* in a cell");
pinStar = true;
// Done with this fake pin
pinp->unlinkFrBack()->deleteTree(); pinp=NULL;
}
}
// Convert unnamed pins to pin number based assignments
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
if (pinp->name()=="") pinp->name("__pinNumber"+cvtToStr(pinp->pinNum()));
}
for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) {
if (pinp->name()=="") pinp->name("__paramNumber"+cvtToStr(pinp->pinNum()));
}
if (nodep->modp()) {
// Note what pins exist
set<string> ports; // Symbol table of all connected port names
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
if (pinp->name()=="") pinp->v3error("Connect by position is illegal in .* connected cells");
if (!pinp->exprp()) pinp->v3warn(PINNOCONNECT,"Cell pin is not connected: "<<pinp->prettyName());
if (ports.find(pinp->name()) == ports.end()) {
ports.insert(pinp->name());
}
}
// We search ports, rather than in/out declarations as they aren't resolved yet,
// and it's easier to do it now than in V3LinkDot when we'd need to repeat steps.
for (AstNode* portnodep = nodep->modp()->stmtsp(); portnodep; portnodep=portnodep->nextp()) {
if (AstPort* portp = portnodep->castPort()) {
if (ports.find(portp->name()) == ports.end()
&& ports.find("__pinNumber"+cvtToStr(portp->pinNum())) == ports.end()) {
if (pinStar) {
UINFO(9," need .* PORT "<<portp<<endl);
// Create any not already connected
AstPin* newp = new AstPin(nodep->fileline(),0,portp->name(),
new AstVarRef(nodep->fileline(),portp->name(),false));
newp->svImplicit(true);
nodep->addPinsp(newp);
} else { // warn on the CELL that needs it, not the port
nodep->v3warn(PINMISSING, "Cell has missing pin: "<<portp->prettyName());
AstPin* newp = new AstPin(nodep->fileline(),0,portp->name(),NULL);
nodep->addPinsp(newp);
}
}
}
}
}
if (nodep->modp()->castIface()) {
// Cell really is the parent's instantiation of an interface, not a normal module
// Make sure we have a variable to refer to this cell, so can <ifacename>.<innermember>
// in the same way that a child does. Rename though to avoid conflict with cell.
// This is quite similar to how classes work; when unpacked classes are better supported
// may remap interfaces to be more like a class.
if (!nodep->hasIfaceVar()) {
string varName = nodep->name()+"__Viftop"; // V3LinkDot looks for this naming
AstIfaceRefDType* idtypep = new AstIfaceRefDType(nodep->fileline(), nodep->name(), nodep->modp()->name());
idtypep->cellp(nodep); // Only set when real parent cell known
idtypep->ifacep(NULL); // cellp overrides
AstVar* varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName, VFlagChildDType(), idtypep);
varp->isIfaceParent(true);
nodep->addNextHere(varp);
nodep->hasIfaceVar(true);
}
}
if (nodep->modp()) {
nodep->iterateChildren(*this);
}
UINFO(4," Link Cell done: "<<nodep<<endl);
}
示例15: replaceCaseComplicated
void replaceCaseComplicated(AstCase* nodep) {
// CASEx(cexpr,ITEM(icond1,istmts1),ITEM(icond2,istmts2),ITEM(default,istmts3))
// -> IF((cexpr==icond1),istmts1,
// IF((EQ (AND MASK cexpr) (AND MASK icond1)
// ,istmts2, istmts3
AstNode* cexprp = nodep->exprp()->unlinkFrBack();
// We'll do this in two stages. First stage, convert the conditions to
// the appropriate IF AND terms.
if (debug()>=9) nodep->dumpTree(cout," _comp_IN: ");
bool hadDefault = false;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
if (!itemp->condsp()) {
// Default clause. Just make true, we'll optimize it away later
itemp->condsp(new AstConst(itemp->fileline(), AstConst::LogicTrue()));
hadDefault = true;
} else {
// Expressioned clause
AstNode* icondNextp = NULL;
AstNode* ifexprp = NULL; // If expression to test
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondNextp) {
icondNextp = icondp->nextp();
icondp->unlinkFrBack();
AstNode* condp = NULL; // Default is to use and1p/and2p
AstConst* iconstp = icondp->castConst();
if (iconstp && neverItem(nodep, iconstp)) {
// X in casez can't ever be executed
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
// For simplicity, make expression that is not equal, and let later
// optimizations remove it
condp = new AstConst(itemp->fileline(), AstConst::LogicFalse());
} else if (AstInsideRange* irangep = icondp->castInsideRange()) {
// Similar logic in V3Width::visit(AstInside)
AstNode* ap = AstGte::newTyped(itemp->fileline(),
cexprp->cloneTree(false),
irangep->lhsp()->unlinkFrBack());
AstNode* bp = AstLte::newTyped(itemp->fileline(),
cexprp->cloneTree(false),
irangep->rhsp()->unlinkFrBack());
condp = new AstAnd(itemp->fileline(), ap, bp);
} else if (iconstp && iconstp->num().isFourState()
&& (nodep->casex() || nodep->casez() || nodep->caseInside())) {
V3Number nummask (itemp->fileline(), iconstp->width());
nummask.opBitsNonX(iconstp->num());
V3Number numval (itemp->fileline(), iconstp->width());
numval.opBitsOne(iconstp->num());
AstNode* and1p = new AstAnd(itemp->fileline(), cexprp->cloneTree(false),
new AstConst(itemp->fileline(), nummask));
AstNode* and2p = new AstAnd(itemp->fileline(),
new AstConst(itemp->fileline(), numval),
new AstConst(itemp->fileline(), nummask));
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
} else {
// Not a caseX mask, we can simply build CASEEQ(cexpr icond)
AstNode* and1p = cexprp->cloneTree(false);
AstNode* and2p = icondp;
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
}
if (!ifexprp) {
ifexprp = condp;
} else {
ifexprp = new AstLogOr(itemp->fileline(), ifexprp, condp);
}
}
// Replace expression in tree
itemp->condsp(ifexprp);
}
}
cexprp->deleteTree(); cexprp=NULL;
if (!hadDefault) {
// If there was no default, add a empty one, this greatly simplifies below code
// and constant propagation will just eliminate it for us later.
nodep->addItemsp(new AstCaseItem(nodep->fileline(),
new AstConst(nodep->fileline(), AstConst::LogicTrue()),
NULL));
}
if (debug()>=9) nodep->dumpTree(cout," _comp_COND: ");
// Now build the IF statement tree
// The tree can be quite huge. Pull ever group of 8 out, and make a OR tree.
// This reduces the depth for the bottom elements, at the cost of some of the top elements.
// If we ever have profiling data, we should pull out the most common item from here and
// instead make it the first IF branch.
int depth = 0;
AstNode* grouprootp = NULL;
AstIf* groupnextp = NULL;
AstIf* itemnextp = NULL;
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
AstNode* istmtsp = itemp->bodysp(); // Maybe null -- no action.
if (istmtsp) istmtsp->unlinkFrBackWithNext();
// Expressioned clause
AstNode* ifexprp = itemp->condsp()->unlinkFrBack();
{ // Prepare for next group
if (++depth > CASE_ENCODER_GROUP_DEPTH) depth = 1;
if (depth == 1) { // First group or starting new group
itemnextp = NULL;
AstIf* newp = new AstIf(itemp->fileline(), ifexprp->cloneTree(true), NULL, NULL);
if (groupnextp) groupnextp->addElsesp(newp);
else grouprootp = newp;
groupnextp = newp;
//.........这里部分代码省略.........