Internals: Split large method function. No functional change.

This commit is contained in:
Wilson Snyder 2019-11-16 14:40:45 -05:00
parent c36d9a68f5
commit ce5a70fbca
1 changed files with 138 additions and 138 deletions

View File

@ -1632,6 +1632,21 @@ private:
AstBasicDType* basicp = fromDtp ? fromDtp->basicp() : NULL; AstBasicDType* basicp = fromDtp ? fromDtp->basicp() : NULL;
UINFO(9," from dt "<<fromDtp<<endl); UINFO(9," from dt "<<fromDtp<<endl);
if (AstEnumDType* adtypep = VN_CAST(fromDtp, EnumDType)) { if (AstEnumDType* adtypep = VN_CAST(fromDtp, EnumDType)) {
methodCallEnum(nodep, adtypep);
}
else if (AstUnpackArrayDType* adtypep = VN_CAST(fromDtp, UnpackArrayDType)) {
methodCallUnpack(nodep, adtypep);
}
else if (basicp && basicp->isString()) {
methodCallString(nodep, basicp);
}
else {
nodep->v3error("Unsupported: Member call on non-enum object '"
<<nodep->fromp()->prettyTypeName()
<<"' which is a '"<<nodep->fromp()->dtypep()->prettyTypeName()<<"'");
}
}
void methodCallEnum(AstMethodSel* nodep, AstEnumDType* adtypep) {
// Method call on enum without following parenthesis, e.g. "ENUM.next" // Method call on enum without following parenthesis, e.g. "ENUM.next"
// Convert this into a method call, and let that visitor figure out what to do next // Convert this into a method call, and let that visitor figure out what to do next
if (adtypep) {} if (adtypep) {}
@ -1647,22 +1662,21 @@ private:
newp = new AstConst(nodep->fileline(), AstConst::Signed32(), items); newp = new AstConst(nodep->fileline(), AstConst::Signed32(), items);
} else if (nodep->name() == "first") { } else if (nodep->name() == "first") {
AstEnumItem* itemp = adtypep->itemsp(); AstEnumItem* itemp = adtypep->itemsp();
if (!itemp) newp = new AstConst( if (!itemp) newp = new AstConst(nodep->fileline(), AstConst::Signed32(),
nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do 0); // Spec doesn't say what to do
else newp = VN_CAST(itemp->valuep()->cloneTree(false), Const); // A const else newp = VN_CAST(itemp->valuep()->cloneTree(false), Const); // A const
} else if (nodep->name() == "last") { } else if (nodep->name() == "last") {
AstEnumItem* itemp = adtypep->itemsp(); AstEnumItem* itemp = adtypep->itemsp();
while (itemp && itemp->nextp()) itemp = VN_CAST(itemp->nextp(), EnumItem); while (itemp && itemp->nextp()) itemp = VN_CAST(itemp->nextp(), EnumItem);
if (!itemp) newp = new AstConst( if (!itemp) newp = new AstConst(nodep->fileline(), AstConst::Signed32(),
nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do 0); // Spec doesn't say what to do
else newp = VN_CAST(itemp->valuep()->cloneTree(false), Const); // A const else newp = VN_CAST(itemp->valuep()->cloneTree(false), Const); // A const
} }
UASSERT_OBJ(newp, nodep, "Enum method (perhaps enum item) not const"); UASSERT_OBJ(newp, nodep, "Enum method (perhaps enum item) not const");
newp->fileline(nodep->fileline()); // Use method's filename/line number to be clearer; may have warning disables newp->fileline(nodep->fileline()); // Use method's filename/line number to be clearer;
nodep->replaceWith(newp); // may have warning disables
pushDeletep(nodep); VL_DANGLING(nodep); nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
} } else if (nodep->name() == "name"
else if (nodep->name() == "name"
|| nodep->name() == "next" || nodep->name() == "next"
|| nodep->name() == "prev") { || nodep->name() == "prev") {
AstAttrType attrType; AstAttrType attrType;
@ -1675,7 +1689,7 @@ private:
nodep->v3error("Arguments passed to enum.name method, but it does not take arguments"); nodep->v3error("Arguments passed to enum.name method, but it does not take arguments");
} else if (nodep->pinsp() } else if (nodep->pinsp()
&& !(VN_IS(VN_CAST(nodep->pinsp(), Arg)->exprp(), Const) && !(VN_IS(VN_CAST(nodep->pinsp(), Arg)->exprp(), Const)
&& VN_CAST(VN_CAST(nodep->pinsp(), Arg)->exprp(), Const)->toUInt()==1 && VN_CAST(VN_CAST(nodep->pinsp(), Arg)->exprp(), Const)->toUInt() == 1
&& !nodep->pinsp()->nextp())) { && !nodep->pinsp()->nextp())) {
nodep->v3error("Unsupported: Arguments passed to enum.next method"); nodep->v3error("Unsupported: Arguments passed to enum.next method");
} }
@ -1687,39 +1701,33 @@ private:
// a map for when the value is many bits and sparse. // a map for when the value is many bits and sparse.
uint64_t msbdim = 0; uint64_t msbdim = 0;
{ {
for (AstEnumItem* itemp = adtypep->itemsp(); for (AstEnumItem* itemp = adtypep->itemsp(); itemp;
itemp; itemp = VN_CAST(itemp->nextp(), EnumItem)) { itemp = VN_CAST(itemp->nextp(), EnumItem)) {
const AstConst* vconstp = VN_CAST(itemp->valuep(), Const); const AstConst* vconstp = VN_CAST(itemp->valuep(), Const);
UASSERT_OBJ(vconstp, nodep, "Enum item without constified value"); UASSERT_OBJ(vconstp, nodep, "Enum item without constified value");
if (vconstp->toUQuad() >= msbdim) msbdim = vconstp->toUQuad(); if (vconstp->toUQuad() >= msbdim) msbdim = vconstp->toUQuad();
} }
if (adtypep->itemsp()->width() > 64 || msbdim >= (1<<16)) { if (adtypep->itemsp()->width() > 64 || msbdim >= (1 << 16)) {
nodep->v3error("Unsupported; enum next/prev method on enum with > 10 bits"); nodep->v3error("Unsupported; enum next/prev method on enum with > 10 bits");
return; return;
} }
} }
int selwidth = V3Number::log2b(msbdim)+1; // Width to address a bit int selwidth = V3Number::log2b(msbdim) + 1; // Width to address a bit
AstVar* varp = enumVarp(adtypep, attrType, (VL_ULL(1)<<selwidth)-1); AstVar* varp = enumVarp(adtypep, attrType, (VL_ULL(1) << selwidth) - 1);
AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false); AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false);
varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp()); varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp());
AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, AstNode* newp = new AstArraySel(
nodep->fileline(), varrefp,
// Select in case widths are // Select in case widths are
// off due to msblen!=width // off due to msblen!=width
new AstSel(nodep->fileline(), new AstSel(nodep->fileline(), nodep->fromp()->unlinkFrBack(), 0, selwidth));
nodep->fromp()->unlinkFrBack(),
0, selwidth));
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
} else { } else {
nodep->v3error("Unknown built-in enum method "<<nodep->prettyNameQ()); nodep->v3error("Unknown built-in enum method " << nodep->prettyNameQ());
} }
} }
else if (AstUnpackArrayDType* arrayType = VN_CAST(fromDtp, UnpackArrayDType)) { void methodCallUnpack(AstMethodSel* nodep, AstUnpackArrayDType* adtypep) {
enum { enum { UNKNOWN = 0, ARRAY_OR, ARRAY_AND, ARRAY_XOR } methodId;
UNKNOWN = 0,
ARRAY_OR,
ARRAY_AND,
ARRAY_XOR
} methodId;
methodId = UNKNOWN; methodId = UNKNOWN;
if (nodep->name() == "or") methodId = ARRAY_OR; if (nodep->name() == "or") methodId = ARRAY_OR;
@ -1728,10 +1736,9 @@ private:
if (methodId) { if (methodId) {
if (nodep->pinsp()) nodep->v3error("Arguments passed to array method, but it does not take arguments"); if (nodep->pinsp()) nodep->v3error("Arguments passed to array method, but it does not take arguments");
FileLine* fl = nodep->fileline(); FileLine* fl = nodep->fileline();
AstNode* newp = NULL; AstNode* newp = NULL;
for (int i = 0; i < arrayType->elementsConst(); ++i) { for (int i = 0; i < adtypep->elementsConst(); ++i) {
AstNode* arrayRef = nodep->fromp()->cloneTree(false); AstNode* arrayRef = nodep->fromp()->cloneTree(false);
AstNode* selector = new AstArraySel(fl, arrayRef, i); AstNode* selector = new AstArraySel(fl, arrayRef, i);
if (!newp) { if (!newp) {
@ -1747,12 +1754,11 @@ private:
} }
nodep->replaceWith(newp); nodep->replaceWith(newp);
nodep->deleteTree(); VL_DANGLING(nodep); nodep->deleteTree(); VL_DANGLING(nodep);
} } else {
else { nodep->v3error("Unknown built-in array method " << nodep->prettyNameQ());
nodep->v3error("Unknown built-in array method "<<nodep->prettyNameQ());
} }
} }
else if (basicp && basicp->isString()) { void methodCallString(AstMethodSel* nodep, AstBasicDType* adtypep) {
// Method call on string // Method call on string
if (nodep->name() == "len") { if (nodep->name() == "len") {
// Constant value // Constant value
@ -1774,12 +1780,6 @@ private:
nodep->v3error("Unsupported: built-in string method "<<nodep->prettyNameQ()); nodep->v3error("Unsupported: built-in string method "<<nodep->prettyNameQ());
} }
} }
else {
nodep->v3error("Unsupported: Member call on non-enum object '"
<<nodep->fromp()->prettyTypeName()
<<"' which is a '"<<nodep->fromp()->dtypep()->prettyTypeName()<<"'");
}
}
virtual void visit(AstPattern* nodep) { virtual void visit(AstPattern* nodep) {
if (nodep->didWidthAndSet()) return; if (nodep->didWidthAndSet()) return;