Fix multiple declarations on one enum, bug199
This commit is contained in:
parent
cdcb94751e
commit
eb63c8dcb8
|
|
@ -147,6 +147,33 @@ public:
|
||||||
virtual string name() const { return m_name; }
|
virtual string name() const { return m_name; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AstDefImplicitDType : public AstNodeDType {
|
||||||
|
// For parsing enum/struct/unions that are declared with a variable rather than typedef
|
||||||
|
// This allows "var enum {...} a,b" to share the enum definition for both variables
|
||||||
|
// After link, these become typedefs
|
||||||
|
private:
|
||||||
|
string m_name;
|
||||||
|
void* m_containerp; // In what scope is the name unique, so we can know what are duplicate definitions (arbitrary value)
|
||||||
|
public:
|
||||||
|
AstDefImplicitDType(FileLine* fl, const string& name, AstNode* containerp, AstNodeDType* dtypep)
|
||||||
|
: AstNodeDType(fl), m_name(name), m_containerp(containerp) {
|
||||||
|
setOp1p(dtypep);
|
||||||
|
widthSignedFrom(dtypep);
|
||||||
|
}
|
||||||
|
ASTNODE_NODE_FUNCS(DefImplicitDType, DEFIMPLICITDTYPE)
|
||||||
|
AstNodeDType* dtypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||||
|
AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable
|
||||||
|
void dtypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||||
|
void* containerp() const { return m_containerp; }
|
||||||
|
// METHODS
|
||||||
|
virtual AstBasicDType* basicp() const { return dtypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||||
|
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
||||||
|
virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); }
|
||||||
|
virtual int widthTotalBytes() const { return dtypep()->widthTotalBytes(); }
|
||||||
|
virtual string name() const { return m_name; }
|
||||||
|
void name(const string& flag) { m_name = flag; }
|
||||||
|
};
|
||||||
|
|
||||||
struct AstArrayDType : public AstNodeDType {
|
struct AstArrayDType : public AstNodeDType {
|
||||||
// Array data type, ie "some_dtype var_name [2:0]"
|
// Array data type, ie "some_dtype var_name [2:0]"
|
||||||
AstArrayDType(FileLine* fl, AstNodeDType* dtypep, AstRange* rangep)
|
AstArrayDType(FileLine* fl, AstNodeDType* dtypep, AstRange* rangep)
|
||||||
|
|
|
||||||
|
|
@ -50,12 +50,16 @@ private:
|
||||||
// AstNode::user() -> bool. True if processed
|
// AstNode::user() -> bool. True if processed
|
||||||
AstUser1InUse m_inuser1;
|
AstUser1InUse m_inuser1;
|
||||||
|
|
||||||
|
// TYPES
|
||||||
|
typedef map <pair<void*,string>,AstTypedef*> ImplTypedefMap;
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
string m_dotText; // Dotted module text we are building for a dotted node, passed up
|
string m_dotText; // Dotted module text we are building for a dotted node, passed up
|
||||||
bool m_inModDot; // We're inside module part of dotted name
|
bool m_inModDot; // We're inside module part of dotted name
|
||||||
AstParseRefExp m_exp; // Type of data we're looking for
|
AstParseRefExp m_exp; // Type of data we're looking for
|
||||||
AstText* m_baseTextp; // Lowest TEXT node that needs replacement with varref
|
AstText* m_baseTextp; // Lowest TEXT node that needs replacement with varref
|
||||||
AstVar* m_varp; // Variable we're under
|
AstVar* m_varp; // Variable we're under
|
||||||
|
ImplTypedefMap m_implTypedef; // Created typedefs for each <container,name>
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
static int debug() {
|
static int debug() {
|
||||||
|
|
@ -285,6 +289,41 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void visit(AstDefImplicitDType* nodep, AstNUser*) {
|
||||||
|
UINFO(8," DEFIMPLICIT "<<nodep<<endl);
|
||||||
|
// Must remember what names we've already created, and combine duplicates
|
||||||
|
// so that for "var enum {...} a,b" a & b will share a common typedef
|
||||||
|
// Unique name space under each containerp() so that an addition of a new type won't change every verilated module.
|
||||||
|
AstTypedef* defp = NULL;
|
||||||
|
ImplTypedefMap::iterator it = m_implTypedef.find(make_pair(nodep->containerp(), nodep->name()));
|
||||||
|
if (it != m_implTypedef.end()) {
|
||||||
|
defp = it->second;
|
||||||
|
} else {
|
||||||
|
// Definition must be inserted right after the variable (etc) that needed it
|
||||||
|
// AstVar, AstTypedef, AstNodeFTask are common containers
|
||||||
|
AstNode* backp = nodep->backp();
|
||||||
|
for (; backp; backp=nodep->backp()) {
|
||||||
|
if (backp->castVar()) break;
|
||||||
|
else if (backp->castTypedef()) break;
|
||||||
|
else if (backp->castNodeFTask()) break;
|
||||||
|
}
|
||||||
|
if (!backp) nodep->v3fatalSrc("Implicit enum/struct type created under unexpected node type");
|
||||||
|
AstNodeDType* dtypep = nodep->dtypep(); dtypep->unlinkFrBack();
|
||||||
|
if (backp->castTypedef()) { // A typedef doesn't need us to make yet another level of typedefing
|
||||||
|
// For typedefs just remove the AstRefDType level of abstraction
|
||||||
|
nodep->replaceWith(dtypep);
|
||||||
|
nodep->deleteTree(); nodep=NULL;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
defp = new AstTypedef(nodep->fileline(), nodep->name(), dtypep);
|
||||||
|
m_implTypedef.insert(make_pair(make_pair(nodep->containerp(), defp->name()), defp));
|
||||||
|
backp->addNextHere(defp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nodep->replaceWith(new AstRefDType(nodep->fileline(), defp->name()));
|
||||||
|
nodep->deleteTree(); nodep=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||||
// Default: Just iterate
|
// Default: Just iterate
|
||||||
checkExpected(nodep); // So we detect node types we forgot to list here
|
checkExpected(nodep); // So we detect node types we forgot to list here
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,8 @@ public:
|
||||||
int m_pinNum; // Pin number currently parsing
|
int m_pinNum; // Pin number currently parsing
|
||||||
string m_instModule; // Name of module referenced for instantiations
|
string m_instModule; // Name of module referenced for instantiations
|
||||||
AstPin* m_instParamp; // Parameters for instantiations
|
AstPin* m_instParamp; // Parameters for instantiations
|
||||||
|
AstNodeModule* m_modp; // Module
|
||||||
|
int m_modTypeImpNum; // Implicit type number, incremented each module
|
||||||
int m_uniqueAttr; // Bitmask of unique/priority keywords
|
int m_uniqueAttr; // Bitmask of unique/priority keywords
|
||||||
|
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
|
|
@ -70,6 +72,8 @@ public:
|
||||||
m_pinNum = -1;
|
m_pinNum = -1;
|
||||||
m_instModule;
|
m_instModule;
|
||||||
m_instParamp = NULL;
|
m_instParamp = NULL;
|
||||||
|
m_modp = NULL;
|
||||||
|
m_modTypeImpNum = 0;
|
||||||
m_varAttrp = NULL;
|
m_varAttrp = NULL;
|
||||||
m_caseAttrp = NULL;
|
m_caseAttrp = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -107,6 +111,7 @@ public:
|
||||||
pkgp = new AstPackage(fl, AstPackage::dollarUnitName());
|
pkgp = new AstPackage(fl, AstPackage::dollarUnitName());
|
||||||
pkgp->inLibrary(true); // packages are always libraries; don't want to make them a "top"
|
pkgp->inLibrary(true); // packages are always libraries; don't want to make them a "top"
|
||||||
pkgp->modTrace(false); // may reconsider later
|
pkgp->modTrace(false); // may reconsider later
|
||||||
|
GRAMMARP->m_modp = pkgp; GRAMMARP->m_modTypeImpNum = 0;
|
||||||
PARSEP->rootp()->addModulep(pkgp);
|
PARSEP->rootp()->addModulep(pkgp);
|
||||||
SYMP->reinsert(pkgp, SYMP->symRootp()); // Don't push/pop scope as they're global
|
SYMP->reinsert(pkgp, SYMP->symRootp()); // Don't push/pop scope as they're global
|
||||||
}
|
}
|
||||||
|
|
@ -583,6 +588,7 @@ packageFront<modulep>:
|
||||||
{ $$ = new AstPackage($1,*$2);
|
{ $$ = new AstPackage($1,*$2);
|
||||||
$$->inLibrary(true); // packages are always libraries; don't want to make them a "top"
|
$$->inLibrary(true); // packages are always libraries; don't want to make them a "top"
|
||||||
$$->modTrace(v3Global.opt.trace());
|
$$->modTrace(v3Global.opt.trace());
|
||||||
|
GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
|
||||||
PARSEP->rootp()->addModulep($$);
|
PARSEP->rootp()->addModulep($$);
|
||||||
SYMP->pushNew($$); }
|
SYMP->pushNew($$); }
|
||||||
;
|
;
|
||||||
|
|
@ -669,6 +675,7 @@ modFront<modulep>:
|
||||||
yMODULE lifetimeE idAny
|
yMODULE lifetimeE idAny
|
||||||
{ $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine());
|
{ $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine());
|
||||||
$$->modTrace(v3Global.opt.trace());
|
$$->modTrace(v3Global.opt.trace());
|
||||||
|
GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
|
||||||
PARSEP->rootp()->addModulep($$);
|
PARSEP->rootp()->addModulep($$);
|
||||||
SYMP->pushNew($$); }
|
SYMP->pushNew($$); }
|
||||||
;
|
;
|
||||||
|
|
@ -679,6 +686,7 @@ udpFront<modulep>:
|
||||||
$$->modTrace(false);
|
$$->modTrace(false);
|
||||||
$$->addStmtp(new AstPragma($1,AstPragmaType::INLINE_MODULE));
|
$$->addStmtp(new AstPragma($1,AstPragmaType::INLINE_MODULE));
|
||||||
PARSEP->fileline()->tracingOn(false);
|
PARSEP->fileline()->tracingOn(false);
|
||||||
|
GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
|
||||||
PARSEP->rootp()->addModulep($$);
|
PARSEP->rootp()->addModulep($$);
|
||||||
SYMP->pushNew($$); }
|
SYMP->pushNew($$); }
|
||||||
;
|
;
|
||||||
|
|
@ -834,6 +842,7 @@ pgmFront<modulep>:
|
||||||
yPROGRAM lifetimeE idAny/*new_program*/
|
yPROGRAM lifetimeE idAny/*new_program*/
|
||||||
{ $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine());
|
{ $$ = new AstModule($1,*$3); $$->inLibrary(PARSEP->inLibrary()||PARSEP->inCellDefine());
|
||||||
$$->modTrace(v3Global.opt.trace());
|
$$->modTrace(v3Global.opt.trace());
|
||||||
|
GRAMMARP->m_modp = $$; GRAMMARP->m_modTypeImpNum = 0;
|
||||||
PARSEP->rootp()->addModulep($$);
|
PARSEP->rootp()->addModulep($$);
|
||||||
SYMP->pushNew($$); }
|
SYMP->pushNew($$); }
|
||||||
;
|
;
|
||||||
|
|
@ -1060,7 +1069,7 @@ data_typeNoRef<dtypep>: // ==IEEE: data_type, excluding class_type etc referenc
|
||||||
//UNSUP { UNSUP }
|
//UNSUP { UNSUP }
|
||||||
//UNSUP yUNION taggedE packedSigningE '{' struct_union_memberList '}' packed_dimensionListE
|
//UNSUP yUNION taggedE packedSigningE '{' struct_union_memberList '}' packed_dimensionListE
|
||||||
//UNSUP { UNSUP }
|
//UNSUP { UNSUP }
|
||||||
| enumDecl { $$ = $1; }
|
| enumDecl { $$ = new AstDefImplicitDType($1->fileline(),"__typeimpenum"+cvtToStr(GRAMMARP->m_modTypeImpNum++),GRAMMARP->m_modp,$1); }
|
||||||
| ySTRING { $$ = new AstBasicDType($1,AstBasicDTypeKwd::STRING); }
|
| ySTRING { $$ = new AstBasicDType($1,AstBasicDTypeKwd::STRING); }
|
||||||
| yCHANDLE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::CHANDLE); }
|
| yCHANDLE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::CHANDLE); }
|
||||||
//UNSUP yEVENT { UNSUP }
|
//UNSUP yEVENT { UNSUP }
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ module t (/*AUTOARG*/
|
||||||
EP_State_DWAIT ,
|
EP_State_DWAIT ,
|
||||||
EP_State_DSHIFT0 ,
|
EP_State_DSHIFT0 ,
|
||||||
EP_State_DSHIFT1 ,
|
EP_State_DSHIFT1 ,
|
||||||
EP_State_DSHIFT15 } m_state_xr;
|
EP_State_DSHIFT15 } m_state_xr, m_state2_xr;
|
||||||
|
|
||||||
// Beginning of automatic ASCII enum decoding
|
// Beginning of automatic ASCII enum decoding
|
||||||
reg [79:0] m_stateAscii_xr; // Decode of m_state_xr
|
reg [79:0] m_stateAscii_xr; // Decode of m_state_xr
|
||||||
|
|
@ -49,21 +49,29 @@ module t (/*AUTOARG*/
|
||||||
//$write("%d %x %x %x\n", cyc, data, wrapcheck_a, wrapcheck_b);
|
//$write("%d %x %x %x\n", cyc, data, wrapcheck_a, wrapcheck_b);
|
||||||
if (cyc==1) begin
|
if (cyc==1) begin
|
||||||
m_state_xr <= EP_State_IDLE;
|
m_state_xr <= EP_State_IDLE;
|
||||||
|
m_state2_xr <= EP_State_IDLE;
|
||||||
end
|
end
|
||||||
if (cyc==2) begin
|
if (cyc==2) begin
|
||||||
if (m_stateAscii_xr != "idle ") $stop;
|
if (m_stateAscii_xr != "idle ") $stop;
|
||||||
m_state_xr <= EP_State_CMDSHIFT13;
|
m_state_xr <= EP_State_CMDSHIFT13;
|
||||||
|
if (m_state2_xr != EP_State_IDLE) $stop;
|
||||||
|
m_state2_xr <= EP_State_CMDSHIFT13;
|
||||||
end
|
end
|
||||||
if (cyc==3) begin
|
if (cyc==3) begin
|
||||||
if (m_stateAscii_xr != "cmdshift13") $stop;
|
if (m_stateAscii_xr != "cmdshift13") $stop;
|
||||||
m_state_xr <= EP_State_CMDSHIFT16;
|
m_state_xr <= EP_State_CMDSHIFT16;
|
||||||
|
if (m_state2_xr != EP_State_CMDSHIFT13) $stop;
|
||||||
|
m_state2_xr <= EP_State_CMDSHIFT16;
|
||||||
end
|
end
|
||||||
if (cyc==4) begin
|
if (cyc==4) begin
|
||||||
if (m_stateAscii_xr != "cmdshift16") $stop;
|
if (m_stateAscii_xr != "cmdshift16") $stop;
|
||||||
m_state_xr <= EP_State_DWAIT;
|
m_state_xr <= EP_State_DWAIT;
|
||||||
|
if (m_state2_xr != EP_State_CMDSHIFT16) $stop;
|
||||||
|
m_state2_xr <= EP_State_DWAIT;
|
||||||
end
|
end
|
||||||
if (cyc==9) begin
|
if (cyc==9) begin
|
||||||
if (m_stateAscii_xr != "dwait ") $stop;
|
if (m_stateAscii_xr != "dwait ") $stop;
|
||||||
|
if (m_state2_xr != EP_State_DWAIT) $stop;
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue