Disable symbol from parser: Support redeclaring type as non-type; major parsing change (#2412).

This commit is contained in:
Wilson Snyder 2025-05-17 22:21:14 -04:00
parent 2c465d9741
commit 6bb16d6c52
35 changed files with 263 additions and 198 deletions

View File

@ -1,11 +0,0 @@
.. comment: generated by t_lint_pkgnodecl_bad
.. code-block:: sv
:linenos:
:emphasize-lines: 2
module t;
initial Pkg::hello(); //<--- Warning
endmodule
package Pkg;
function void hello(); endfunction
endpackage

View File

@ -1,4 +0,0 @@
.. comment: generated by t_lint_pkgnodecl_bad
.. code-block::
%Error-PKGNODECL: example.v:1:12 Package/class 'Pkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3)

View File

@ -1401,23 +1401,11 @@ List Of Warnings
.. option:: PKGNODECL .. option:: PKGNODECL
An error that a package/class appears to have been referenced that has Never issued since version 5.038. Historically an error that a
not yet been declared. According to IEEE 1800-2023 26.3, all packages package/class appears to have been referenced that has not yet been
must be declared before being used. declared. According to IEEE 1800-2023 26.3, all packages must be
declared before being used. However, several standard libraries
Faulty example: including UVM violate this, and other tools do not warn.
.. include:: ../../docs/gen/ex_PKGNODECL_faulty.rst
Results in:
.. include:: ../../docs/gen/ex_PKGNODECL_msg.rst
Often the package is declared in its own header file. In this case add
an include of that package header file to the referencing file. (And
make sure you have header guards in the package's header file to prevent
multiple declarations of the package.)
.. option:: PORTSHORT .. option:: PORTSHORT

View File

@ -2128,6 +2128,9 @@ protected:
// Use instead isSame(), this is for each Ast* class, and assumes node is of same type // Use instead isSame(), this is for each Ast* class, and assumes node is of same type
virtual bool sameNode(const AstNode*) const { return true; } virtual bool sameNode(const AstNode*) const { return true; }
// Generated by 'astgen'. If do an oldp->replaceNode(newp), would cause a broken()
virtual bool wouldBreakGen(const AstNode* const oldp,
const AstNode* const newp) const = 0; // Generated by 'astgen'
public: public:
// ACCESSORS // ACCESSORS
@ -2527,6 +2530,8 @@ public:
virtual const char* broken() const { return nullptr; } virtual const char* broken() const { return nullptr; }
// Generated by 'astgen'. Calls 'broken()', which can be used to add extra checks // Generated by 'astgen'. Calls 'broken()', which can be used to add extra checks
virtual const char* brokenGen() const = 0; // Generated by 'astgen' virtual const char* brokenGen() const = 0; // Generated by 'astgen'
// If do a this->replaceNode(newp), would cause a broken()
bool wouldBreak(const AstNode* const newp) const { return backp()->wouldBreakGen(this, newp); }
// INVOKERS // INVOKERS
virtual void accept(VNVisitorConst& v) = 0; virtual void accept(VNVisitorConst& v) = 0;

View File

@ -742,10 +742,10 @@ public:
class AstCellRef final : public AstNodeExpr { class AstCellRef final : public AstNodeExpr {
// As-of-yet unlinkable reference into a cell // As-of-yet unlinkable reference into a cell
// @astgen op1 := cellp : AstNode // @astgen op1 := cellp : AstNode
// @astgen op2 := exprp : AstNodeExpr // @astgen op2 := exprp : AstNode<AstNodeExpr|AstNodeDType>
string m_name; // Cell name string m_name; // Cell name
public: public:
AstCellRef(FileLine* fl, const string& name, AstNode* cellp, AstNodeExpr* exprp) AstCellRef(FileLine* fl, const string& name, AstNode* cellp, AstNode* exprp)
: ASTGEN_SUPER_CellRef(fl) : ASTGEN_SUPER_CellRef(fl)
, m_name{name} { , m_name{name} {
this->cellp(cellp); this->cellp(cellp);
@ -1206,8 +1206,8 @@ public:
class AstDot final : public AstNodeExpr { class AstDot final : public AstNodeExpr {
// A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef // A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef
// These are eliminated in the link stage // These are eliminated in the link stage
// @astgen op1 := lhsp : AstNodeExpr // @astgen op1 := lhsp : AstNode<AstNodeExpr|AstNodeDType>
// @astgen op2 := rhsp : AstNodeExpr // @astgen op2 := rhsp : AstNode<AstNodeExpr|AstNodeDType>
// //
// We don't have a list of elements as it's probably legal to do '(foo.bar).(baz.bap)' // We don't have a list of elements as it's probably legal to do '(foo.bar).(baz.bap)'
const bool m_colon; // Is a "::" instead of a "." (lhs must be package/class) const bool m_colon; // Is a "::" instead of a "." (lhs must be package/class)

View File

@ -529,7 +529,10 @@ public:
"Unsupported: Interfaced port on top level module"); "Unsupported: Interfaced port on top level module");
} }
ifacerefp->v3error("Parent instance's interface is not found: " ifacerefp->v3error("Parent instance's interface is not found: "
<< AstNode::prettyNameQ(ifacerefp->ifaceName())); << AstNode::prettyNameQ(ifacerefp->ifaceName()) << '\n'
<< ifacerefp->warnMore()
<< "... Perhaps intended an interface instantiation but "
"are missing parenthesis (IEEE 1800-2023 25.3)?");
} else { } else {
ifacerefp->v3warn( ifacerefp->v3warn(
E_UNSUPPORTED, E_UNSUPPORTED,
@ -1550,11 +1553,11 @@ class LinkDotFindVisitor final : public VNVisitor {
if (tdefp && tdefp->name() == nodep->name() && m_statep->forPrimary()) { if (tdefp && tdefp->name() == nodep->name() && m_statep->forPrimary()) {
UINFO(8, "Replacing type of" << nodep << endl UINFO(8, "Replacing type of" << nodep << endl
<< " with " << tdefp << endl); << " with " << tdefp << endl);
AstNodeDType* const newType = tdefp->childDTypep(); AstNodeDType* const newDtp = tdefp->childDTypep();
AstNodeDType* const oldType = nodep->childDTypep(); AstNodeDType* const oldDtp = nodep->childDTypep();
oldType->replaceWith(newType->cloneTree(false)); oldDtp->replaceWith(newDtp->cloneTree(false));
oldType->deleteTree(); oldDtp->deleteTree();
} }
} }
} }
@ -2477,7 +2480,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
} }
void checkNoDot(AstNode* nodep) { void checkNoDot(AstNode* nodep) {
if (VL_UNLIKELY(m_ds.m_dotPos != DP_NONE)) { if (VL_UNLIKELY(m_ds.m_dotPos != DP_NONE)) {
// UINFO(9, indent() << "ds=" << m_ds.ascii() << endl); UINFO(9, indent() << "ds=" << m_ds.ascii() << endl);
nodep->v3error("Syntax error: Not expecting " nodep->v3error("Syntax error: Not expecting "
<< nodep->type() << " under a " << nodep->backp()->type() << nodep->type() << " under a " << nodep->backp()->type()
<< " in dotted expression\n" << " in dotted expression\n"
@ -2608,6 +2611,15 @@ class LinkDotResolveVisitor final : public VNVisitor {
symIterateNull(nodep, m_statep->getNodeSym(nodep)); symIterateNull(nodep, m_statep->getNodeSym(nodep));
} }
void replaceWithCheckBreak(AstNode* oldp, AstNodeDType* newp) {
// Flag now to avoid V3Broken throwing an internal error
if (oldp->wouldBreak(newp)) {
newp->v3error(
"Data type used where a non-data type is expected: " << newp->prettyNameQ());
}
oldp->replaceWith(newp);
}
// Marks the current module to be revisited after the initial AST iteration // Marks the current module to be revisited after the initial AST iteration
void revisitLater(AstNode* deferredNodep) { void revisitLater(AstNode* deferredNodep) {
// Need to revisit entire module to build up all the necessary context // Need to revisit entire module to build up all the necessary context
@ -2951,7 +2963,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
nodep->replaceWith(newp); nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
} else { // Dot midpoint } else { // Dot midpoint
AstNodeExpr* newp = nodep->rhsp()->unlinkFrBack(); AstNode* newp = nodep->rhsp()->unlinkFrBack();
if (m_ds.m_unresolvedCell) { if (m_ds.m_unresolvedCell) {
AstCellRef* const crp = new AstCellRef{ AstCellRef* const crp = new AstCellRef{
nodep->fileline(), nodep->name(), nodep->lhsp()->unlinkFrBack(), newp}; nodep->fileline(), nodep->name(), nodep->lhsp()->unlinkFrBack(), newp};
@ -3059,7 +3071,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
return; return;
} else if (m_ds.m_dotPos == DP_MEMBER) { } else if (m_ds.m_dotPos == DP_MEMBER) {
// Found a Var, everything following is membership. {scope}.{var}.HERE {member} // Found a Var, everything following is membership. {scope}.{var}.HERE {member}
AstNodeExpr* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack(); AstNodeExpr* const varEtcp = VN_AS(m_ds.m_dotp->lhsp()->unlinkFrBack(), NodeExpr);
AstNodeExpr* const newp AstNodeExpr* const newp
= new AstMemberSel{nodep->fileline(), varEtcp, VFlagChildDType{}, nodep->name()}; = new AstMemberSel{nodep->fileline(), varEtcp, VFlagChildDType{}, nodep->name()};
if (m_ds.m_dotErr) { if (m_ds.m_dotErr) {
@ -3348,6 +3360,14 @@ class LinkDotResolveVisitor final : public VNVisitor {
ok = true; ok = true;
m_ds.m_dotPos = DP_MEMBER; m_ds.m_dotPos = DP_MEMBER;
m_ds.m_dotText = ""; m_ds.m_dotText = "";
} else if (AstClass* const defp = VN_CAST(foundp->nodep(), Class)) {
if (allowVar) {
AstRefDType* const newp = new AstRefDType{nodep->fileline(), nodep->name()};
replaceWithCheckBreak(nodep, newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
ok = true;
m_ds.m_dotText = "";
}
} else if (AstEnumItem* const valuep = VN_CAST(foundp->nodep(), EnumItem)) { } else if (AstEnumItem* const valuep = VN_CAST(foundp->nodep(), EnumItem)) {
if (allowVar) { if (allowVar) {
AstNode* const newp AstNode* const newp
@ -3386,6 +3406,22 @@ class LinkDotResolveVisitor final : public VNVisitor {
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
} }
} }
} else if (AstTypedef* const defp = VN_CAST(foundp->nodep(), Typedef)) {
ok = m_ds.m_dotPos == DP_NONE || m_ds.m_dotPos == DP_SCOPE;
if (ok) {
AstRefDType* const refp = new AstRefDType{nodep->fileline(), nodep->name()};
refp->typedefp(defp);
replaceWithCheckBreak(nodep, refp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
}
} else if (AstParamTypeDType* const defp = VN_CAST(foundp->nodep(), ParamTypeDType)) {
ok = (m_ds.m_dotPos == DP_NONE || m_ds.m_dotPos == DP_SCOPE);
if (ok) {
AstRefDType* const refp = new AstRefDType{nodep->fileline(), nodep->name()};
refp->refDTypep(defp);
replaceWithCheckBreak(nodep, refp);
VL_DO_DANGLING(pushDeletep(nodep), nodep);
}
} }
if (!ok) { if (!ok) {
if (m_insideClassExtParam) { if (m_insideClassExtParam) {
@ -3795,7 +3831,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_MEMBER) { } else if (m_ds.m_dotp && m_ds.m_dotPos == DP_MEMBER) {
// Found a Var, everything following is method call. // Found a Var, everything following is method call.
// {scope}.{var}.HERE {method} ( ARGS ) // {scope}.{var}.HERE {method} ( ARGS )
AstNodeExpr* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack(); AstNodeExpr* const varEtcp = VN_AS(m_ds.m_dotp->lhsp()->unlinkFrBack(), NodeExpr);
AstNodeExpr* argsp = nullptr; AstNodeExpr* argsp = nullptr;
if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext(); if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext();
AstNode* const newp = new AstMethodCall{nodep->fileline(), varEtcp, VFlagChildDType{}, AstNode* const newp = new AstMethodCall{nodep->fileline(), varEtcp, VFlagChildDType{},
@ -4373,7 +4409,7 @@ class LinkDotResolveVisitor final : public VNVisitor {
} }
VL_DO_DANGLING(cpackagep->unlinkFrBack()->deleteTree(), cpackagep); VL_DO_DANGLING(cpackagep->unlinkFrBack()->deleteTree(), cpackagep);
} }
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) { if (m_ds.m_dotp && (m_ds.m_dotPos == DP_PACKAGE || m_ds.m_dotPos == DP_SCOPE)) {
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(), UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(),
"Bad package link"); "Bad package link");
auto* const cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef); auto* const cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef);

View File

@ -196,7 +196,6 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, const string& name,
if (GRAMMARP->m_varIO == VDirection::NONE // In non-ANSI port list if (GRAMMARP->m_varIO == VDirection::NONE // In non-ANSI port list
&& GRAMMARP->m_varDecl == VVarType::PORT) { && GRAMMARP->m_varDecl == VVarType::PORT) {
// Just a port list with variable name (not v2k format); AstPort already created // Just a port list with variable name (not v2k format); AstPort already created
if (dtypep) fileline->v3warn(E_UNSUPPORTED, "Unsupported: Ranges ignored in port-lists");
if (arrayp) VL_DO_DANGLING(arrayp->deleteTree(), arrayp); if (arrayp) VL_DO_DANGLING(arrayp->deleteTree(), arrayp);
if (attrsp) { if (attrsp) {
// TODO: Merge attributes across list? Or warn attribute is ignored // TODO: Merge attributes across list? Or warn attribute is ignored

View File

@ -429,6 +429,35 @@ size_t V3ParseImp::tokenPipeScanIdInst(size_t depthIn) {
return depth; return depth;
} }
size_t V3ParseImp::tokenPipeScanIdType(size_t depthIn) {
// Search around IEEE data type identifier
// Return location of following token, or input if not found
// tokenPipeScanIdCell has precedence over this search
// yaID/*type_identifier*/ [ '#' '('...')' ] [{ '['...']' }] yaID/*identifier*/
// assignment_pattern_expression:
// yaID/*type_identifier*/ [ '#' '('...')' ] [{ '['...']' }] yP_TICKBRA
// class_type parameter_value_assignment // often followed by ) as in e.g. ClsA#(ClsB#(...))
// yaID/*type_identifier*/ '#' '('...')' [^ '::']
// and caller must check does NOT match tokenPipeScanIdCell
size_t depth = depthIn;
// UINFO(9, "tokenPipeScanType START d="
// << depth << " " << V3ParseImp::tokenName(tokenPeekp(depth)->token) << endl);
if (tokenPeekp(depth)->token == '#' && tokenPeekp(depth + 1)->token == '(') {
depth = tokenPipeScanParam(depth, false);
// Not :: as then it's a yaID__CC, we'll parse that in tokenPipeScanId
if (tokenPeekp(depth)->token != yP_COLONCOLON) return depth;
}
depth = tokenPipeScanBracket(depth); // [ '['..']' ]*
if (tokenPeekp(depth)->token != yaID__LEX && tokenPeekp(depth)->token != yP_TICKBRA)
return depthIn;
++depth;
// UINFO(9, "tokenPipeScanType MATCH\n");
return depth;
}
size_t V3ParseImp::tokenPipeScanBracket(size_t inDepth) { size_t V3ParseImp::tokenPipeScanBracket(size_t inDepth) {
// Return location of following token, or input if not found // Return location of following token, or input if not found
// [ '['...']' ]* // [ '['...']' ]*
@ -531,6 +560,7 @@ int V3ParseImp::tokenPipelineId(int token) {
if (m_tokenLastBison.token != '@' && m_tokenLastBison.token != '#' if (m_tokenLastBison.token != '@' && m_tokenLastBison.token != '#'
&& m_tokenLastBison.token != '.') { && m_tokenLastBison.token != '.') {
if (const size_t depth = tokenPipeScanIdInst(0)) return yaID__aINST; if (const size_t depth = tokenPipeScanIdInst(0)) return yaID__aINST;
if (const size_t depth = tokenPipeScanIdType(0)) return yaID__aTYPE;
} }
if (nexttok == '#') { // e.g. class_type parameter_value_assignment '::' if (nexttok == '#') { // e.g. class_type parameter_value_assignment '::'
const size_t depth = tokenPipeScanParam(0, false); const size_t depth = tokenPipeScanParam(0, false);
@ -683,6 +713,8 @@ void V3ParseImp::tokenPipelineSym() {
foundp = V3ParseImp::parsep()->symp()->symCurrentp()->findIdFallback(*(yylval.strp)); foundp = V3ParseImp::parsep()->symp()->symCurrentp()->findIdFallback(*(yylval.strp));
} }
if (!foundp && !m_afterColonColon) { // Check if the symbol can be found in std if (!foundp && !m_afterColonColon) { // Check if the symbol can be found in std
// The following keywords from this file are hardcoded for detection in the parser:
// "mailbox", "process", "randomize", "semaphore", "std"
AstPackage* const stdpkgp = v3Global.rootp()->stdPackagep(); AstPackage* const stdpkgp = v3Global.rootp()->stdPackagep();
if (stdpkgp) { if (stdpkgp) {
VSymEnt* const stdsymp = stdpkgp->user4u().toSymEnt(); VSymEnt* const stdsymp = stdpkgp->user4u().toSymEnt();
@ -694,36 +726,11 @@ void V3ParseImp::tokenPipelineSym() {
yylval.scp = scp; yylval.scp = scp;
UINFO(7, " tokenPipelineSym: Found " << scp << endl); UINFO(7, " tokenPipelineSym: Found " << scp << endl);
if (token == yaID__LEX) { // i.e. not yaID__CC if (token == yaID__LEX) { // i.e. not yaID__CC
if (VN_IS(scp, Typedef)) { token = yaID__ETC;
token = yaID__aTYPE;
} else if (VN_IS(scp, TypedefFwd)) {
token = yaID__aTYPE;
} else if (VN_IS(scp, Class)) {
token = yaID__aTYPE;
} else if (VN_IS(scp, Package)) {
token = yaID__ETC;
} else {
token = yaID__ETC;
}
} }
} else { // Not found } else { // Not found
yylval.scp = nullptr; yylval.scp = nullptr;
if (token == yaID__CC) { if (token == yaID__LEX) token = yaID__ETC;
if (!m_afterColonColon && !v3Global.opt.bboxUnsup()) {
// IEEE does require this, but we may relax this as UVM breaks it, so allow
// bbox for today
// We'll get a parser error eventually but might not be obvious
// is missing package, and this confuses people
static int warned = false;
if (!warned++) {
yylval.fl->v3warn(PKGNODECL, "Package/class '" + *yylval.strp
+ "' not found, and needs to be "
"predeclared (IEEE 1800-2023 26.3)");
}
}
} else if (token == yaID__LEX) {
token = yaID__ETC;
}
} }
} }
m_afterColonColon = token == yP_COLONCOLON; m_afterColonColon = token == yP_COLONCOLON;

View File

@ -316,6 +316,7 @@ private:
int tokenPipelineId(int token) VL_MT_DISABLED; int tokenPipelineId(int token) VL_MT_DISABLED;
void tokenPipelineSym() VL_MT_DISABLED; void tokenPipelineSym() VL_MT_DISABLED;
size_t tokenPipeScanIdInst(size_t depth) VL_MT_DISABLED; size_t tokenPipeScanIdInst(size_t depth) VL_MT_DISABLED;
size_t tokenPipeScanIdType(size_t depth) VL_MT_DISABLED;
size_t tokenPipeScanBracket(size_t depth) VL_MT_DISABLED; size_t tokenPipeScanBracket(size_t depth) VL_MT_DISABLED;
size_t tokenPipeScanParam(size_t depth, bool forInst) VL_MT_DISABLED; size_t tokenPipeScanParam(size_t depth, bool forInst) VL_MT_DISABLED;
size_t tokenPipeScanTypeEq(size_t depth) VL_MT_DISABLED; size_t tokenPipeScanTypeEq(size_t depth) VL_MT_DISABLED;

View File

@ -968,7 +968,31 @@ def write_ast_impl(filename):
emitBlock("));\n") emitBlock("));\n")
# Node's broken rules can be specialized by declaring broken() # Node's broken rules can be specialized by declaring broken()
emitBlock(" return Ast{t}::broken();\n", t=node.name) emitBlock(" return Ast{t}::broken();\n", t=node.name)
emitBlock("}}\n", t=node.name) emitBlock("}}\n")
emitBlock(
"bool Ast{t}::wouldBreakGen(const AstNode* const oldp, const AstNode* const newp) const {{\n",
t=node.name)
for i in range(1, 5):
op = node.getOp(i)
if op is None:
continue
name, _, _, legals = op
if legals != '':
# 'this' is a parent, where oldp replacing newp as op1p, must follow op1p's rules
# Could also be on a list, we don't check for speed reasons and as V3Broken doesn't
emitBlock(" if (oldp == op{i}p() && !(", i=i)
eor = ""
for legal in legals.split('|'):
emitBlock("{eor}privateTypeTest<Ast{legal}>(newp)",
eor=eor,
name=name,
legal=legal)
eor = " || "
emitBlock(")) return true;\n")
# Node's broken rules can be specialized by declaring broken()
emitBlock(" return false;\n")
emitBlock("}}\n")
emitBlock("void Ast{t}::cloneRelinkGen() {{\n", t=node.name) emitBlock("void Ast{t}::cloneRelinkGen() {{\n", t=node.name)
if node.superClass.name != 'Node': if node.superClass.name != 'Node':
@ -1042,6 +1066,7 @@ def write_ast_macros(filename):
Ast{t}* clonep() const {{ return static_cast<Ast{t}*>(AstNode::clonep()); }} Ast{t}* clonep() const {{ return static_cast<Ast{t}*>(AstNode::clonep()); }}
Ast{t}* addNext(Ast{t}* nodep) {{ return static_cast<Ast{t}*>(AstNode::addNext(this, nodep)); }} Ast{t}* addNext(Ast{t}* nodep) {{ return static_cast<Ast{t}*>(AstNode::addNext(this, nodep)); }}
const char* brokenGen() const override; const char* brokenGen() const override;
bool wouldBreakGen(const AstNode* const oldp, const AstNode* const newp) const override;
void cloneRelinkGen() override; void cloneRelinkGen() override;
void dumpTreeJsonOpGen(std::ostream& str, const string& indent) const override; void dumpTreeJsonOpGen(std::ostream& str, const string& indent) const override;
void dumpJsonGen(std::ostream& str) const; void dumpJsonGen(std::ostream& str) const;

View File

@ -1552,15 +1552,11 @@ port<nodep>: // ==IEEE: port
// // IEEE: interface_port_header port_identifier { unpacked_dimension } // // IEEE: interface_port_header port_identifier { unpacked_dimension }
// // Expanded interface_port_header // // Expanded interface_port_header
// // We use instantCb here because the non-port form looks just like a module instantiation // // We use instantCb here because the non-port form looks just like a module instantiation
portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE //
{ // VAR for now, but V3LinkCells may call setIfcaeRef on it later // // Looks identical to variable_declaration, so V3LinkDot must resolve when ID known
$$ = $3; VARDECL(VAR); VARIO(NONE); // // NO: portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE
// Although know it's an interface, use AstRefDType for forward compatibility //
// with future parser. V3LinkCells will convert to AstIfaceRefDType. portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig variable_dimensionListE sigAttrListE
AstNodeDType* const dtp = new AstRefDType{$<fl>2, *$2};
VARDTYPE(dtp);
addNextNull($$, VARDONEP($$, $4, $5)); }
| portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig variable_dimensionListE sigAttrListE
{ // VAR for now, but V3LinkCells may call setIfcaeRef on it later { // VAR for now, but V3LinkCells may call setIfcaeRef on it later
$$ = $5; VARDECL(VAR); VARIO(NONE); $$ = $5; VARDECL(VAR); VARIO(NONE);
AstNodeDType* const dtp = new AstIfaceRefDType{$<fl>2, $<fl>4, "", *$2, *$4}; AstNodeDType* const dtp = new AstIfaceRefDType{$<fl>2, $<fl>4, "", *$2, *$4};
@ -1615,17 +1611,20 @@ port<nodep>: // ==IEEE: port
// // IEEE: portDirNetE data_type '.' portSig -> handled with AstDot in expr. // // IEEE: portDirNetE data_type '.' portSig -> handled with AstDot in expr.
// //
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE | portDirNetE data_type portSig variable_dimensionListE sigAttrListE
{ $$ = $3; VARDTYPE($2); VARIOANSI(); addNextNull($$, VARDONEP($$, $4, $5)); } { $$ = $3; VARDTYPE($2); VARIOANSI();
addNextNull($$, VARDONEP($$, $4, $5)); }
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr | portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
{ $$ = $3; VARDTYPE($2); VARIOANSI(); { $$ = $3; VARDTYPE($2); VARIOANSI();
if (AstVar* vp = VARDONEP($$, $4, $5)) { addNextNull($$, vp); vp->valuep($7); } } if (AstVar* vp = VARDONEP($$, $4, $5)) { addNextNull($$, vp); vp->valuep($7); } }
| portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE | portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE
{ $$ = $4; VARDTYPE($3); VARIOANSI(); addNextNull($$, VARDONEP($$, $5, $6)); } { $$ = $4; VARDTYPE($3); VARIOANSI();
addNextNull($$, VARDONEP($$, $5, $6)); }
| portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr | portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
{ $$ = $4; VARDTYPE($3); VARIOANSI(); { $$ = $4; VARDTYPE($3); VARIOANSI();
if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } } if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } }
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE | portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE
{ $$ = $4; VARDTYPE($3); VARIOANSI(); addNextNull($$, VARDONEP($$, $5, $6)); } { $$ = $4; VARDTYPE($3); VARIOANSI();
addNextNull($$, VARDONEP($$, $5, $6)); }
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE '=' constExpr | portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE '=' constExpr
{ $$ = $4; VARDTYPE($3); VARIOANSI(); { $$ = $4; VARDTYPE($3); VARIOANSI();
if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } } if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } }
@ -2105,13 +2104,10 @@ port_declaration<nodep>: // ==IEEE: port_declaration
// //
// // IEEE: interface_port_declaration // // IEEE: interface_port_declaration
// // IEEE: interface_identifier list_of_interface_identifiers // // IEEE: interface_identifier list_of_interface_identifiers
| id/*interface*/ //
/*mid*/ { VARRESET_NONLIST(VVarType::IFACEREF); // // Identical to variable_declaration, resolve in V3LinkDot when id known
AstIfaceRefDType* const dtp = new AstIfaceRefDType{$<fl>1, "", *$1}; // // NO: id/*interface*/ mpInstnameList
dtp->isPortDecl(true); //
VARDTYPE(dtp); }
/*cont*/ mpInstnameList
{ $$ = VARDONEP($3, nullptr, nullptr); }
// // IEEE: interface_port_declaration // // IEEE: interface_port_declaration
// // IEEE: interface_identifier '.' modport_identifier list_of_interface_identifiers // // IEEE: interface_identifier '.' modport_identifier list_of_interface_identifiers
| id/*interface*/ '.' idAny/*modport*/ | id/*interface*/ '.' idAny/*modport*/
@ -4585,9 +4581,10 @@ exprOrDataType<nodep>: // expr | data_type: combined to prevent conflic
// // data_type includes id that overlaps expr, so special flavor // // data_type includes id that overlaps expr, so special flavor
// // data_type expanded: // // data_type expanded:
| data_typeNoRef { $$ = $1; } | data_typeNoRef { $$ = $1; }
| packageClassScopeE idType packed_dimensionListE //
{ AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, $1, nullptr}; // // Conflicts with non-type id, resolved in V3LinkDot
$$ = GRAMMARP->createArray(refp, $3, true); } // // NO: packageClassScopeE idType packed_dimensionListE
//
| packageClassScopeE idType parameter_value_assignmentClass packed_dimensionListE | packageClassScopeE idType parameter_value_assignmentClass packed_dimensionListE
{ AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, $1, $3}; { AstRefDType* const refp = new AstRefDType{$<fl>2, *$2, $1, $3};
$$ = GRAMMARP->createArray(refp, $4, true); } $$ = GRAMMARP->createArray(refp, $4, true); }
@ -5153,8 +5150,8 @@ expr<nodeExprp>: // IEEE: part of expression/constant_expression/
{ $$ = new AstCast{$2, $4, VFlagChildDType{}, $1}; } { $$ = new AstCast{$2, $4, VFlagChildDType{}, $1}; }
// // expanded from simple_type ps_type_identifier (part of simple_type) // // expanded from simple_type ps_type_identifier (part of simple_type)
// // expanded from simple_type ps_parameter_identifier (part of simple_type) // // expanded from simple_type ps_parameter_identifier (part of simple_type)
| packageClassScopeE idType yP_TICK '(' expr ')' // // Causes conflict, so handled post-parse
{ $$ = new AstCastParse{$3, $5, new AstRefDType{$<fl>2, *$2, $1, nullptr}}; } // // NO: packageClassScopeE idType yP_TICK '(' expr ')'
// //
| yTYPE__ETC '(' exprOrDataType ')' yP_TICK '(' expr ')' | yTYPE__ETC '(' exprOrDataType ')' yP_TICK '(' expr ')'
{ $$ = new AstCast{$1, $7, VFlagChildDType{}, { $$ = new AstCast{$1, $7, VFlagChildDType{},

View File

@ -405,11 +405,8 @@
%Warning-COVERIGN: t/t_covergroup_unsup.v:164:18: Ignoring unsupported: covergroup within class %Warning-COVERIGN: t/t_covergroup_unsup.v:164:18: Ignoring unsupported: covergroup within class
164 | covergroup cov1 @m_z; 164 | covergroup cov1 @m_z;
| ^~~~ | ^~~~
%Error: t/t_covergroup_unsup.v:169:28: syntax error, unexpected '=', expecting IDENTIFIER or do or final or randomize %Error: t/t_covergroup_unsup.v:169:23: Can't find definition of variable: 'cov1'
169 | function new(); cov1 = new; endfunction 169 | function new(); cov1 = new; endfunction
| ^ | ^~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Internal Error: t/t_covergroup_unsup.v:160:4: ../V3ParseSym.h:#: Symbols suggest ending FUNC 'new' but parser thinks ending CLASS 'CgCls' %Error: Exiting due to
160 | class CgCls;
| ^~~~~
... This fatal error may be caused by the earlier error(s); resolve those first.

View File

@ -53,11 +53,14 @@ for s in [
'Illegal +: or -: select; type already selected, or bad dimension: ', 'Illegal +: or -: select; type already selected, or bad dimension: ',
'Illegal bit or array select; type already selected, or bad dimension: ', 'Illegal bit or array select; type already selected, or bad dimension: ',
'Illegal range select; type already selected, or bad dimension: ', 'Illegal range select; type already selected, or bad dimension: ',
'Interface port ',
'Interface port declaration ',
'Modport item is not a function/task: ', 'Modport item is not a function/task: ',
'Modport item is not a variable: ', 'Modport item is not a variable: ',
'Modport item not found: ', 'Modport item not found: ',
'Modport not referenced as <interface>.', 'Modport not referenced as <interface>.',
'Modport not referenced from underneath an interface: ', 'Modport not referenced from underneath an interface: ',
'Non-interface used as an interface: ',
'Parameter type pin value isn\'t a type: Param ', 'Parameter type pin value isn\'t a type: Param ',
'Parameter type variable isn\'t a type: Param ', 'Parameter type variable isn\'t a type: Param ',
'Pattern replication value of 0 is not legal.', 'Pattern replication value of 0 is not legal.',

View File

@ -1,8 +1,3 @@
%Error: t/t_inst_paren_bad.v:11:4: Non-interface used as an interface: 'sub'
: ... Perhaps intended an instantiation but are missing parenthesis (IEEE 1800-2023 23.3.2)?
11 | sub sub_inst;
| ^~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Warning-MULTITOP: t/t_inst_paren_bad.v:10:8: Multiple top level modules %Warning-MULTITOP: t/t_inst_paren_bad.v:10:8: Multiple top level modules
: ... Suggest see manual; fix the duplicates, or use --top-module to select top. : ... Suggest see manual; fix the duplicates, or use --top-module to select top.
... For warning description see https://verilator.org/warn/MULTITOP?v=latest ... For warning description see https://verilator.org/warn/MULTITOP?v=latest
@ -13,4 +8,8 @@
: ... Top module 't' : ... Top module 't'
10 | module t( ); 10 | module t( );
| ^ | ^
%Error: t/t_inst_paren_bad.v:11:4: Can't find typedef/interface: 'sub'
11 | sub sub_inst;
| ^~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to %Error: Exiting due to

View File

@ -1,17 +1,11 @@
%Error: t/t_interface_missing_bad.v:14:13: Pin is not an in/out/inout/interface: 'foo'
14 | foo_intf foo
| ^~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: t/t_interface_missing_bad.v:14:4: Can't find typedef/interface: 'foo_intf' %Error: t/t_interface_missing_bad.v:14:4: Can't find typedef/interface: 'foo_intf'
14 | foo_intf foo 14 | foo_intf foo
| ^~~~~~~~ | ^~~~~~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: t/t_interface_missing_bad.v:20:4: Cannot find file containing interface: 'foo_intf' %Error: t/t_interface_missing_bad.v:20:4: Cannot find file containing interface: 'foo_intf'
20 | foo_intf the_foo (); 20 | foo_intf the_foo ();
| ^~~~~~~~ | ^~~~~~~~
%Error: t/t_interface_missing_bad.v:25:15: Found definition of 'the_foo' as a CELL but expected a variable %Error: t/t_interface_missing_bad.v:25:15: Found definition of 'the_foo' as a CELL but expected a variable
25 | .foo (the_foo) 25 | .foo (the_foo)
| ^~~~~~~ | ^~~~~~~
%Error: t/t_interface_missing_bad.v:25:10: Instance attempts to connect to 'foo', but it is a variable
25 | .foo (the_foo)
| ^~~
%Error: Exiting due to %Error: Exiting due to

View File

@ -1,6 +1,6 @@
%Error: t/t_interface_paren_missing_bad.v:13:9: Interface port declaration 'intf_i' doesn't have corresponding port %Error: t/t_interface_paren_missing_bad.v:13:4: Parent instance's interface is not found: 'intf'
: ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)?
13 | intf intf_i; 13 | intf intf_i;
| ^~~~~~ | ^~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to %Error: Exiting due to

View File

@ -3,6 +3,7 @@
| ^~~~~~ | ^~~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: t/t_interface_top_bad.v:17:4: Parent instance's interface is not found: 'ifc' %Error: t/t_interface_top_bad.v:17:4: Parent instance's interface is not found: 'ifc'
: ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)?
17 | ifc.counter_mp c_data 17 | ifc.counter_mp c_data
| ^~~ | ^~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.

View File

@ -2,8 +2,4 @@
46 | typedef ifc_if.struct_t struct_t; 46 | typedef ifc_if.struct_t struct_t;
| ^~~~~~~ | ^~~~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: t/t_interface_typedef.v:51:16: syntax error, unexpected IDENTIFIER
51 | struct_t substruct;
| ^~~~~~~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to %Error: Exiting due to

View File

@ -1,4 +1,5 @@
%Error: t/t_interface_typo_bad.v:14:4: Parent instance's interface is not found: 'foo_intf' %Error: t/t_interface_typo_bad.v:14:4: Parent instance's interface is not found: 'foo_intf'
: ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)?
14 | foo_intf foo 14 | foo_intf foo
| ^~~~~~~~ | ^~~~~~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.

View File

@ -1,5 +1,11 @@
%Error: t/t_lint_implicit_type_bad.v:15:11: syntax error, unexpected IDENTIFIER-for-type %Error: t/t_lint_implicit_type_bad.v:15:11: Data type used where a non-data type is expected: 'imp_typedef_conflict'
15 | assign imp_typedef_conflict = 1'b1; 15 | assign imp_typedef_conflict = 1'b1;
| ^~~~~~~~~~~~~~~~~~~~ | ^~~~~~~~~~~~~~~~~~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: t/t_lint_implicit_type_bad.v:16:11: Data type used where a non-data type is expected: 'imp_Cls_conflict'
16 | assign imp_Cls_conflict = 1'b1;
| ^~~~~~~~~~~~~~~~
%Error: t/t_lint_implicit_type_bad.v:17:11: Data type used where a non-data type is expected: 'imp_PARAM_conflict'
17 | assign imp_PARAM_conflict = 1'b1;
| ^~~~~~~~~~~~~~~~~~
%Error: Exiting due to %Error: Exiting due to

View File

@ -12,7 +12,7 @@ import vltest_bootstrap
test.scenarios('vlt') test.scenarios('vlt')
# --debug-check adds extra internal message, otherwise golden log would vary # --debug-check adds extra internal message, otherwise golden log would vary
test.lint(verilator_flags2=["--lint-only --debug-check -Wall -Wno-DECLFILENAME"], test.lint(verilator_flags2=["--lint-only --no-debug-check -Wall -Wno-DECLFILENAME"],
fails=True, fails=True,
expect_filename=test.golden_filename) expect_filename=test.golden_filename)

View File

@ -1,7 +1,3 @@
%Error-PKGNODECL: t/t_lint_import_name2_bad.v:7:8: Package/class 'missing' not found, and needs to be predeclared (IEEE 1800-2023 26.3)
7 | import missing::sigs;
| ^~~~~~~
... For error description see https://verilator.org/warn/PKGNODECL?v=latest
%Error: t/t_lint_import_name2_bad.v:7:8: Importing from missing package 'missing' %Error: t/t_lint_import_name2_bad.v:7:8: Importing from missing package 'missing'
7 | import missing::sigs; 7 | import missing::sigs;
| ^~~~~~~ | ^~~~~~~

View File

@ -1,9 +1,5 @@
%Error-PKGNODECL: t/t_lint_pkg_colon_bad.v:7:17: Package/class 'mispkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3) %Error: t/t_lint_pkg_colon_bad.v:8:8: syntax error, unexpected IDENTIFIER-::, expecting IDENTIFIER or do or final or randomize
7 | module t (input mispkg::foo_t a); 8 | reg mispkgb::bar_t b;
| ^~~~~~ | ^~~~~~~
... For error description see https://verilator.org/warn/PKGNODECL?v=latest
%Error: t/t_lint_pkg_colon_bad.v:7:25: syntax error, unexpected IDENTIFIER, expecting IDENTIFIER-for-type
7 | module t (input mispkg::foo_t a);
| ^~~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to %Error: Exiting due to

View File

@ -1,5 +0,0 @@
%Error-PKGNODECL: t/t_lint_pkgnodecl_bad.v:8:12: Package/class 'Pkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3)
8 | initial Pkg::hello();
| ^~~
... For error description see https://verilator.org/warn/PKGNODECL?v=latest
%Error: Exiting due to

View File

@ -1,29 +0,0 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('linter')
root = ".."
if not os.path.exists(root + "/.git"):
test.skip("Not in a git repository")
test.lint(fails=True, expect_filename=test.golden_filename)
test.extract(in_filename=test.top_filename,
out_filename=root + "/docs/gen/ex_PKGNODECL_faulty.rst",
lines="7-12")
test.extract(in_filename=test.golden_filename,
out_filename=root + "/docs/gen/ex_PKGNODECL_msg.rst",
lines="1")
test.passes()

View File

@ -1,12 +0,0 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2012 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t;
initial Pkg::hello(); //<--- Warning
endmodule
package Pkg;
function void hello(); endfunction
endpackage

View File

@ -1,7 +1,3 @@
%Error-PKGNODECL: t/t_no_std_bad.v:9:11: Package/class 'std' not found, and needs to be predeclared (IEEE 1800-2023 26.3)
9 | import std::*;
| ^~~
... For error description see https://verilator.org/warn/PKGNODECL?v=latest
%Error: t/t_no_std_bad.v:9:11: Importing from missing package 'std' %Error: t/t_no_std_bad.v:9:11: Importing from missing package 'std'
9 | import std::*; 9 | import std::*;
| ^~~ | ^~~

View File

@ -1,5 +1,5 @@
%Error-PKGNODECL: t/t_package_alone_bad.v:7:8: Package/class 'pkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3) %Error: t/t_package_alone_bad.v:7:13: Export package not found: 'pkg'
7 | export pkg::something; 7 | export pkg::something;
| ^~~ | ^~~~~~~~~
... For error description see https://verilator.org/warn/PKGNODECL?v=latest ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to %Error: Exiting due to

View File

@ -1,8 +1,24 @@
%Error: t/t_parse_sync_bad2.v:17:16: syntax error, unexpected IDENTIFIER %Error: t/t_parse_sync_bad2.v:9:15: Can't find typedef/interface: 'unknown'
17 | Invalid1 invalid1; 9 | typedef unknown defu;
| ^~~~~~~~ | ^~~~~~~
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: t/t_parse_sync_bad2.v:20:16: syntax error, unexpected IDENTIFIER %Error: t/t_parse_sync_bad2.v:17:7: Can't find typedef/interface: 'Invalid1'
17 | Invalid1 invalid1;
| ^~~~~~~~
%Error-UNSUPPORTED: t/t_parse_sync_bad2.v:18:12: Unsupported: Multiple '::' package/class reference
18 | pkg::cls::defi valid1;
| ^~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: t/t_parse_sync_bad2.v:18:17: Can't find typedef/interface: 'defi'
18 | pkg::cls::defi valid1;
| ^~~~
%Error-UNSUPPORTED: t/t_parse_sync_bad2.v:19:12: Unsupported: Multiple '::' package/class reference
19 | pkg::cls::defu valid2;
| ^~~
%Error: t/t_parse_sync_bad2.v:19:17: Can't find typedef/interface: 'defu'
19 | pkg::cls::defu valid2;
| ^~~~
%Error: t/t_parse_sync_bad2.v:20:7: Can't find typedef/interface: 'Invalid2'
20 | Invalid2 invalid2; 20 | Invalid2 invalid2;
| ^~~~~~~~ | ^~~~~~~~
%Error: Exiting due to %Error: Exiting due to

View File

@ -1,4 +1,4 @@
%Error: t/t_pp_circ_subst_bad.v:8:80001: Too many preprocessor tokens on a line (>40000); perhaps recursive `define %Error: t/t_pp_circ_subst_bad.v:8:80001: Too many preprocessor tokens on a line (>40000); perhaps recursive `define
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: t/t_pp_circ_subst_bad.v:8:1: syntax error, unexpected IDENTIFIER %Error: t/t_pp_circ_subst_bad.v:8:5: syntax error, unexpected IDENTIFIER-for-type, expecting IDENTIFIER or do or final or randomize
%Error: Exiting due to %Error: Exiting due to

View File

@ -1,4 +1,4 @@
%Error: t/t_pp_circ_subst_bad.v:8:40002: Too many preprocessor tokens on a line (>20000); perhaps recursive `define %Error: t/t_pp_circ_subst_bad.v:8:40002: Too many preprocessor tokens on a line (>20000); perhaps recursive `define
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: t/t_pp_circ_subst_bad.v:8:1: syntax error, unexpected IDENTIFIER %Error: t/t_pp_circ_subst_bad.v:8:5: syntax error, unexpected IDENTIFIER-for-type, expecting IDENTIFIER or do or final or randomize
%Error: Exiting due to %Error: Exiting due to

View File

@ -1,4 +1,4 @@
%Error: t/t_preproc_inc_inc_bad.vh:11:1: syntax error, unexpected endmodule, expecting IDENTIFIER or randomize %Error: t/t_preproc_inc_inc_bad.vh:11:1: syntax error, unexpected endmodule, expecting '('
11 | endmodule 11 | endmodule
| ^~~~~~~~~ | ^~~~~~~~~
t/t_preproc_inc_bad.v:10:1: ... note: In file included from 't_preproc_inc_bad.v' t/t_preproc_inc_bad.v:10:1: ... note: In file included from 't_preproc_inc_bad.v'

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile()
test.execute()
test.passes()

View File

@ -0,0 +1,49 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// Use this file as a template for submitting bugs, etc.
// This module takes a single clock input, and should either
// $write("*-* All Finished *-*\n");
// $finish;
// on success, or $stop.
//
// The code as shown applies a random vector to the Test
// module, then calculates a CRC on the Test module's outputs.
//
// **If you do not wish for your code to be released to the public
// please note it here, otherwise:**
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
class Cls;
endclass
package Pkg;
// Issue #2956
typedef string STYPE;
typedef string line;
task automatic testf;
inout STYPE line;
endtask
endpackage
module t;
localparam type T = Cls;
// Issue #2412
typedef T this_thing; // this_thing now a type
function T newer();
T this_thing; // this_thing now a class reference
this_thing = new;
return this_thing;
endfunction
initial begin
Cls c;
c = newer();
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -2,7 +2,7 @@
12 | int above; 12 | int above;
| ^~~~~ | ^~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: t/t_vams_kwd_bad.v:12:13: syntax error, unexpected ';', expecting IDENTIFIER or randomize %Error: t/t_vams_kwd_bad.v:12:13: syntax error, unexpected ';', expecting '('
12 | int above; 12 | int above;
| ^ | ^
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.