mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Internals: Parse lifetime directives; still unsupported.
This commit is contained in:
parent
87e1c36e4a
commit
70549e1a64
32
src/V3Ast.h
32
src/V3Ast.h
@ -94,6 +94,32 @@ inline std::ostream& operator<<(std::ostream& os, const AstType& rhs) { return o
|
||||
|
||||
//######################################################################
|
||||
|
||||
class VLifetime {
|
||||
public:
|
||||
enum en { NONE, AUTOMATIC, STATIC };
|
||||
enum en m_e;
|
||||
const char* ascii() const {
|
||||
static const char* const names[] = {"NONE", "VAUTOM", "VSTATIC"};
|
||||
return names[m_e];
|
||||
}
|
||||
inline VLifetime()
|
||||
: m_e(NONE) {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VLifetime(en _e)
|
||||
: m_e(_e) {}
|
||||
explicit inline VLifetime(int _e)
|
||||
: m_e(static_cast<en>(_e)) {}
|
||||
operator en() const { return m_e; }
|
||||
bool isNone() const { return m_e == NONE; }
|
||||
bool isAutomatic() const { return m_e == AUTOMATIC; }
|
||||
bool isStatic() const { return m_e == STATIC; }
|
||||
};
|
||||
inline bool operator==(const VLifetime& lhs, const VLifetime& rhs) { return lhs.m_e == rhs.m_e; }
|
||||
inline bool operator==(const VLifetime& lhs, VLifetime::en rhs) { return lhs.m_e == rhs; }
|
||||
inline bool operator==(VLifetime::en lhs, const VLifetime& rhs) { return lhs == rhs.m_e; }
|
||||
|
||||
//######################################################################
|
||||
|
||||
class VSigning {
|
||||
public:
|
||||
enum en {
|
||||
@ -2575,6 +2601,7 @@ private:
|
||||
bool m_dpiTask : 1; // DPI import task (vs. void function)
|
||||
bool m_isConstructor : 1; // Class constructor
|
||||
bool m_pure : 1; // DPI import pure (vs. virtual pure)
|
||||
VLifetime m_lifetime; // Lifetime
|
||||
public:
|
||||
AstNodeFTask(AstType t, FileLine* fl, const string& name, AstNode* stmtsp)
|
||||
: AstNode(t, fl)
|
||||
@ -2639,6 +2666,8 @@ public:
|
||||
bool isConstructor() const { return m_isConstructor; }
|
||||
void pure(bool flag) { m_pure = flag; }
|
||||
bool pure() const { return m_pure; }
|
||||
void lifetime(const VLifetime& flag) { m_lifetime = flag; }
|
||||
VLifetime lifetime() const { return m_lifetime; }
|
||||
};
|
||||
|
||||
class AstNodeFTaskRef : public AstNodeStmt {
|
||||
@ -2715,6 +2744,7 @@ private:
|
||||
int m_level; // 1=top module, 2=cell off top module, ...
|
||||
int m_varNum; // Incrementing variable number
|
||||
int m_typeNum; // Incrementing implicit type number
|
||||
VLifetime m_lifetime; // Lifetime
|
||||
VTimescale m_timeunit; // Global time unit
|
||||
VOptionBool m_unconnectedDrive; // State of `unconnected_drive
|
||||
public:
|
||||
@ -2766,6 +2796,8 @@ public:
|
||||
bool recursive() const { return m_recursive; }
|
||||
void recursiveClone(bool flag) { m_recursiveClone = flag; }
|
||||
bool recursiveClone() const { return m_recursiveClone; }
|
||||
void lifetime(const VLifetime& flag) { m_lifetime = flag; }
|
||||
VLifetime lifetime() const { return m_lifetime; }
|
||||
void timeunit(const VTimescale& flag) { m_timeunit = flag; }
|
||||
VTimescale timeunit() const { return m_timeunit; }
|
||||
void unconnectedDrive(const VOptionBool flag) { m_unconnectedDrive = flag; }
|
||||
|
@ -1437,6 +1437,7 @@ void AstVar::dump(std::ostream& str) const {
|
||||
}
|
||||
if (isDpiOpenArray()) str << " [DPIOPENA]";
|
||||
if (!attrClocker().unknown()) str << " [" << attrClocker().ascii() << "] ";
|
||||
if (!lifetime().isNone()) str << " [" << lifetime().ascii() << "] ";
|
||||
str << " " << varType();
|
||||
}
|
||||
void AstSenTree::dump(std::ostream& str) const {
|
||||
|
@ -1780,7 +1780,7 @@ private:
|
||||
bool m_attrSplitVar : 1; // declared with split_var metacomment
|
||||
bool m_fileDescr : 1; // File descriptor
|
||||
bool m_isConst : 1; // Table contains constant data
|
||||
bool m_isStatic : 1; // Static variable
|
||||
bool m_isStatic : 1; // Static C variable (for Verilog see instead isAutomatic)
|
||||
bool m_isPulldown : 1; // Tri0
|
||||
bool m_isPullup : 1; // Tri1
|
||||
bool m_isIfaceParent : 1; // dtype is reference to interface present in this module
|
||||
@ -1788,6 +1788,7 @@ private:
|
||||
bool m_noReset : 1; // Do not do automated reset/randomization
|
||||
bool m_noSubst : 1; // Do not substitute out references
|
||||
bool m_trace : 1; // Trace this variable
|
||||
VLifetime m_lifetime; // Lifetime
|
||||
VVarAttrClocker m_attrClocker;
|
||||
MTaskIdSet m_mtaskIds; // MTaskID's that read or write this var
|
||||
|
||||
@ -2037,6 +2038,8 @@ public:
|
||||
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
|
||||
VVarAttrClocker attrClocker() const { return m_attrClocker; }
|
||||
virtual string verilogKwd() const;
|
||||
void lifetime(const VLifetime& flag) { m_lifetime = flag; }
|
||||
VLifetime lifetime() const { return m_lifetime; }
|
||||
void propagateAttrFrom(AstVar* fromp) {
|
||||
// This is getting connected to fromp; keep attributes
|
||||
// Note the method below too
|
||||
|
@ -1006,6 +1006,7 @@ class LinkDotFindVisitor : public AstNVisitor {
|
||||
AstVar* newvarp = new AstVar(nodep->fileline(), AstVarType::VAR, nodep->name(),
|
||||
VFlagChildDType(), dtypep); // Not dtype resolved yet
|
||||
newvarp->direction(VDirection::OUTPUT);
|
||||
newvarp->lifetime(VLifetime::AUTOMATIC);
|
||||
newvarp->funcReturn(true);
|
||||
newvarp->trace(false); // Not user visible
|
||||
newvarp->attrIsolateAssign(nodep->attrIsolateAssign());
|
||||
|
@ -53,6 +53,7 @@ private:
|
||||
AstClass* m_classp; // Class we're inside
|
||||
AstNodeFTask* m_ftaskp; // Function or task we're inside
|
||||
AstNodeCoverOrAssert* m_assertp; // Current assertion
|
||||
VLifetime m_lifetime; // Propagating lifetime
|
||||
int m_senitemCvtNum; // Temporary signal counter
|
||||
|
||||
// METHODS
|
||||
@ -67,14 +68,30 @@ private:
|
||||
UINFO(8, "MODULE " << nodep << endl);
|
||||
if (nodep->dead()) return;
|
||||
AstNodeModule* origModp = m_modp;
|
||||
VLifetime origLifetime = m_lifetime;
|
||||
int origSenitemCvtNum = m_senitemCvtNum;
|
||||
{
|
||||
m_modp = nodep;
|
||||
m_senitemCvtNum = 0;
|
||||
m_lifetime = nodep->lifetime();
|
||||
if (m_lifetime.isNone()) m_lifetime = VLifetime::STATIC;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
m_modp = origModp;
|
||||
m_senitemCvtNum = origSenitemCvtNum;
|
||||
m_lifetime = origLifetime;
|
||||
}
|
||||
virtual void visit(AstClass* nodep) VL_OVERRIDE {
|
||||
AstClass* origClassp = m_classp;
|
||||
VLifetime origLifetime = m_lifetime;
|
||||
{
|
||||
m_classp = nodep;
|
||||
m_lifetime = nodep->lifetime();
|
||||
if (m_lifetime.isNone()) m_lifetime = VLifetime::AUTOMATIC;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
m_classp = origClassp;
|
||||
m_lifetime = origLifetime;
|
||||
}
|
||||
virtual void visit(AstInitial* nodep) VL_OVERRIDE {
|
||||
iterateChildren(nodep);
|
||||
@ -90,19 +107,12 @@ private:
|
||||
iterateChildren(nodep);
|
||||
m_assertp = NULL;
|
||||
}
|
||||
virtual void visit(AstClass* nodep) VL_OVERRIDE {
|
||||
AstClass* origClassp = m_classp;
|
||||
{
|
||||
m_classp = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
m_classp = origClassp;
|
||||
}
|
||||
virtual void visit(AstVar* nodep) VL_OVERRIDE {
|
||||
iterateChildren(nodep);
|
||||
if (m_classp && !nodep->isParam()) nodep->varType(AstVarType::MEMBER);
|
||||
if (m_classp && nodep->isParam()) nodep->v3error("Unsupported: class parameter");
|
||||
if (m_ftaskp) nodep->funcLocal(true);
|
||||
if (nodep->lifetime().isNone()) nodep->lifetime(m_lifetime);
|
||||
if (nodep->isSigModPublic()) {
|
||||
nodep->sigModPublic(false); // We're done with this attribute
|
||||
m_modp->modPublic(true); // Avoid flattening if signals are exposed
|
||||
@ -119,9 +129,15 @@ private:
|
||||
// NodeTask: Remember its name for later resolution
|
||||
// Remember the existing symbol table scope
|
||||
if (m_classp) nodep->classMethod(true);
|
||||
m_ftaskp = nodep;
|
||||
iterateChildren(nodep);
|
||||
VLifetime origLifetime = m_lifetime;
|
||||
{
|
||||
if (!nodep->lifetime().isNone()) m_lifetime = nodep->lifetime();
|
||||
if (m_lifetime.isNone()) m_lifetime = VLifetime::AUTOMATIC;
|
||||
m_ftaskp = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
m_ftaskp = NULL;
|
||||
m_lifetime = origLifetime;
|
||||
if (nodep->dpiExport()) { nodep->scopeNamep(new AstScopeName(nodep->fileline())); }
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep) VL_OVERRIDE {
|
||||
@ -472,13 +488,13 @@ private:
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit LinkResolveVisitor(AstNetlist* rootp) {
|
||||
explicit LinkResolveVisitor(AstNetlist* rootp)
|
||||
: m_lifetime(VLifetime::STATIC) { // Static outside a module/class
|
||||
m_classp = NULL;
|
||||
m_ftaskp = NULL;
|
||||
m_modp = NULL;
|
||||
m_assertp = NULL;
|
||||
m_senitemCvtNum = 0;
|
||||
//
|
||||
iterate(rootp);
|
||||
}
|
||||
virtual ~LinkResolveVisitor() {}
|
||||
|
@ -183,6 +183,7 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, const string& name,
|
||||
nodep->addAttrsp(attrsp);
|
||||
nodep->ansi(m_pinAnsi);
|
||||
nodep->declTyped(m_varDeclTyped);
|
||||
nodep->lifetime(m_varLifetime);
|
||||
if (GRAMMARP->m_varDecl != AstVarType::UNKNOWN) nodep->combineType(GRAMMARP->m_varDecl);
|
||||
if (GRAMMARP->m_varIO != VDirection::NONE) {
|
||||
nodep->declDirection(GRAMMARP->m_varIO);
|
||||
|
@ -59,6 +59,7 @@ struct V3ParseBisonYYSType {
|
||||
VSigning::en signstate;
|
||||
V3ErrorCode::en errcodeen;
|
||||
AstAttrType::en attrtypeen;
|
||||
VLifetime::en lifetime;
|
||||
|
||||
AstNode* nodep;
|
||||
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
AstVarType m_varDecl; // Type for next signal declaration (reg/wire/etc)
|
||||
bool m_varDeclTyped; // Var got reg/wire for dedup check
|
||||
VDirection m_varIO; // Direction for next signal declaration (reg/wire/etc)
|
||||
VLifetime m_varLifetime; // Static/Automatic for next signal
|
||||
AstVar* m_varAttrp; // Current variable for attribute adding
|
||||
AstRange* m_gateRangep; // Current range for gate declarations
|
||||
AstCase* m_caseAttrp; // Current case statement for attribute adding
|
||||
@ -194,9 +195,11 @@ int V3ParseGrammar::s_modTypeImpNum = 0;
|
||||
#define VARRESET_NONLIST(decl) { GRAMMARP->m_pinNum=0; GRAMMARP->m_pinAnsi=false; \
|
||||
VARRESET(); VARDECL(decl); } // Not in a pinlist
|
||||
#define VARRESET() { VARDECL(UNKNOWN); VARIO(NONE); VARDTYPE_NDECL(NULL); \
|
||||
GRAMMARP->m_varLifetime = VLifetime::NONE; \
|
||||
GRAMMARP->m_varDeclTyped = false; }
|
||||
#define VARDECL(type) { GRAMMARP->setVarDecl(AstVarType::type); }
|
||||
#define VARIO(type) { GRAMMARP->m_varIO = VDirection::type; }
|
||||
#define VARLIFE(flag) { GRAMMARP->m_varLifetime = flag; }
|
||||
#define VARDTYPE(dtypep) { GRAMMARP->setDType(dtypep); GRAMMARP->m_varDeclTyped = true; }
|
||||
#define VARDTYPE_NDECL(dtypep) { GRAMMARP->setDType(dtypep); } // Port that is range or signed only (not a decl)
|
||||
|
||||
@ -794,6 +797,8 @@ class AstSenTree;
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
|
||||
%start source_text
|
||||
|
||||
@ -852,6 +857,7 @@ packageFront<modulep>:
|
||||
yPACKAGE lifetimeE idAny ';'
|
||||
{ $$ = new AstPackage($<fl>3, *$3);
|
||||
$$->inLibrary(true); // packages are always libraries; don't want to make them a "top"
|
||||
$$->lifetime($2);
|
||||
$$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
|
||||
$$->timeunit(PARSEP->timeLastUnit());
|
||||
PARSEP->rootp()->addModulep($$);
|
||||
@ -967,6 +973,7 @@ modFront<modulep>:
|
||||
// // any formal arguments, as the arguments must land in the new scope.
|
||||
yMODULE lifetimeE idAny
|
||||
{ $$ = new AstModule($<fl>3,*$3);
|
||||
$$->lifetime($2);
|
||||
$$->inLibrary(PARSEP->inLibrary() || PARSEP->inCellDefine());
|
||||
$$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
|
||||
$$->timeunit(PARSEP->timeLastUnit());
|
||||
@ -985,6 +992,7 @@ importsAndParametersE<nodep>: // IEEE: common part of module_declaration, interf
|
||||
udpFront<modulep>:
|
||||
yPRIMITIVE lifetimeE idAny
|
||||
{ $$ = new AstPrimitive($<fl>3, *$3); $$->inLibrary(true);
|
||||
$$->lifetime($2);
|
||||
$$->modTrace(false);
|
||||
$$->addStmtp(new AstPragma($<fl>3, AstPragmaType::INLINE_MODULE));
|
||||
GRAMMARP->m_tracingParse = false;
|
||||
@ -1167,6 +1175,7 @@ intFront<modulep>:
|
||||
yINTERFACE lifetimeE idAny/*new_interface*/
|
||||
{ $$ = new AstIface($<fl>3, *$3);
|
||||
$$->inLibrary(true);
|
||||
$$->lifetime($2);
|
||||
PARSEP->rootp()->addModulep($$);
|
||||
SYMP->pushNew($$); }
|
||||
;
|
||||
@ -1253,6 +1262,7 @@ program_declaration: // IEEE: program_declaration + program_nonansi_header + pr
|
||||
pgmFront<modulep>:
|
||||
yPROGRAM lifetimeE idAny/*new_program*/
|
||||
{ $$ = new AstModule($<fl>3,*$3);
|
||||
$$->lifetime($2);
|
||||
$$->inLibrary(PARSEP->inLibrary() || PARSEP->inCellDefine());
|
||||
$$->modTrace(GRAMMARP->allTracingOn($$->fileline()));
|
||||
$$->timeunit(PARSEP->timeLastUnit());
|
||||
@ -1885,19 +1895,33 @@ data_declarationVarFront: // IEEE: part of data_declaration
|
||||
//
|
||||
// // Expanded: "constE yVAR lifetimeE data_type"
|
||||
// // implicit_type expanded into /*empty*/ or "signingE rangeList"
|
||||
/**/ yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE($3); }
|
||||
| /**/ yVAR lifetimeE { VARRESET_NONLIST(VAR); VARDTYPE(new AstBasicDType($<fl>1, LOGIC_IMPLICIT)); }
|
||||
| /**/ yVAR lifetimeE signingE rangeList { /*VARRESET-in-ddVar*/ VARDTYPE(GRAMMARP->addRange(new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $3), $4,true)); }
|
||||
/**/ yVAR lifetimeE data_type
|
||||
{ VARRESET_NONLIST(VAR); VARLIFE($2); VARDTYPE($3); }
|
||||
| /**/ yVAR lifetimeE
|
||||
{ VARRESET_NONLIST(VAR); VARLIFE($2);
|
||||
VARDTYPE(new AstBasicDType($<fl>1, LOGIC_IMPLICIT)); }
|
||||
| /**/ yVAR lifetimeE signingE rangeList
|
||||
{ /*VARRESET-in-ddVar*/ VARLIFE($2);
|
||||
VARDTYPE(GRAMMARP->addRange(new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $3), $4,true)); }
|
||||
//
|
||||
// // implicit_type expanded into /*empty*/ or "signingE rangeList"
|
||||
| yCONST__ETC yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($<fl>2, VFlagChildDType(), $4)); }
|
||||
| yCONST__ETC yVAR lifetimeE { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($<fl>2, VFlagChildDType(), new AstBasicDType($<fl>2, LOGIC_IMPLICIT))); }
|
||||
| yCONST__ETC yVAR lifetimeE signingE rangeList { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($<fl>2, VFlagChildDType(), GRAMMARP->addRange(new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $4), $5,true))); }
|
||||
| yCONST__ETC yVAR lifetimeE data_type
|
||||
{ VARRESET_NONLIST(VAR); VARLIFE($3);
|
||||
VARDTYPE(new AstConstDType($<fl>2, VFlagChildDType(), $4)); }
|
||||
| yCONST__ETC yVAR lifetimeE
|
||||
{ VARRESET_NONLIST(VAR); VARLIFE($3);
|
||||
VARDTYPE(new AstConstDType($<fl>2, VFlagChildDType(), new AstBasicDType($<fl>2, LOGIC_IMPLICIT))); }
|
||||
| yCONST__ETC yVAR lifetimeE signingE rangeList
|
||||
{ VARRESET_NONLIST(VAR); VARLIFE($3);
|
||||
VARDTYPE(new AstConstDType($<fl>2, VFlagChildDType(),
|
||||
GRAMMARP->addRange(new AstBasicDType($<fl>2, LOGIC_IMPLICIT, $4), $5,true))); }
|
||||
//
|
||||
// // Expanded: "constE lifetimeE data_type"
|
||||
| /**/ data_type { VARRESET_NONLIST(VAR); VARDTYPE($1); }
|
||||
| /**/ lifetime data_type { VARRESET_NONLIST(VAR); VARDTYPE($2); }
|
||||
| yCONST__ETC lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE(new AstConstDType($<fl>1, VFlagChildDType(), $3)); }
|
||||
| /**/ lifetime data_type { VARRESET_NONLIST(VAR); VARLIFE($1); VARDTYPE($2); }
|
||||
| yCONST__ETC lifetimeE data_type
|
||||
{ VARRESET_NONLIST(VAR); VARLIFE($2);
|
||||
VARDTYPE(new AstConstDType($<fl>1, VFlagChildDType(), $3)); }
|
||||
// // = class_new is in variable_decl_assignment
|
||||
;
|
||||
|
||||
@ -1905,9 +1929,11 @@ data_declarationVarFrontClass: // IEEE: part of data_declaration (for class_prop
|
||||
// // VARRESET called before this rule
|
||||
// // yCONST is removed, added to memberQual rules
|
||||
// // implicit_type expanded into /*empty*/ or "signingE rangeList"
|
||||
yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE($3); }
|
||||
| yVAR lifetimeE { VARRESET_NONLIST(VAR); }
|
||||
| yVAR lifetimeE signingE rangeList { /*VARRESET-in-ddVar*/ VARDTYPE(GRAMMARP->addRange(new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $3), $4,true)); }
|
||||
yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARLIFE($2); VARDTYPE($3); }
|
||||
| yVAR lifetimeE { VARRESET_NONLIST(VAR); VARLIFE($2); }
|
||||
| yVAR lifetimeE signingE rangeList
|
||||
{ /*VARRESET-in-ddVar*/ VARDTYPE(GRAMMARP->addRange(new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $3), $4,true));
|
||||
VARLIFE($2); }
|
||||
//
|
||||
// // Expanded: "constE lifetimeE data_type"
|
||||
| data_type { VARRESET_NONLIST(VAR); VARDTYPE($1); }
|
||||
@ -3484,6 +3510,7 @@ list_of_argumentsE<nodep>: // IEEE: [list_of_arguments]
|
||||
task_declaration<ftaskp>: // ==IEEE: task_declaration
|
||||
yTASK lifetimeE taskId tfGuts yENDTASK endLabelE
|
||||
{ $$ = $3; $$->addStmtsp($4); SYMP->popScope($$);
|
||||
$$->lifetime($2);
|
||||
GRAMMARP->endLabel($<fl>6,$$,$6); }
|
||||
;
|
||||
|
||||
@ -3495,10 +3522,12 @@ task_prototype<ftaskp>: // ==IEEE: task_prototype
|
||||
function_declaration<ftaskp>: // IEEE: function_declaration + function_body_declaration
|
||||
yFUNCTION lifetimeE funcId funcIsolateE tfGuts yENDFUNCTION endLabelE
|
||||
{ $$ = $3; $3->attrIsolateAssign($4); $$->addStmtsp($5);
|
||||
$$->lifetime($2);
|
||||
SYMP->popScope($$);
|
||||
GRAMMARP->endLabel($<fl>7,$$,$7); }
|
||||
| yFUNCTION lifetimeE funcIdNew funcIsolateE tfGuts yENDFUNCTION endLabelE
|
||||
{ $$ = $3; $3->attrIsolateAssign($4); $$->addStmtsp($5);
|
||||
$$->lifetime($2);
|
||||
SYMP->popScope($$);
|
||||
GRAMMARP->endLabel($<fl>7,$$,$7); }
|
||||
;
|
||||
@ -3523,15 +3552,15 @@ method_prototype:
|
||||
| function_prototype { }
|
||||
;
|
||||
|
||||
lifetimeE: // IEEE: [lifetime]
|
||||
/* empty */ { }
|
||||
| lifetime { }
|
||||
lifetimeE<lifetime>: // IEEE: [lifetime]
|
||||
/* empty */ { $$ = VLifetime::NONE; }
|
||||
| lifetime { $$ = $1; }
|
||||
;
|
||||
|
||||
lifetime: // ==IEEE: lifetime
|
||||
lifetime<lifetime>: // ==IEEE: lifetime
|
||||
// // Note lifetime used by members is instead under memberQual
|
||||
ySTATIC__ETC { BBUNSUP($1, "Unsupported: Static in this context"); }
|
||||
| yAUTOMATIC { }
|
||||
ySTATIC__ETC { $$ = VLifetime::STATIC; BBUNSUP($1, "Unsupported: Static in this context"); }
|
||||
| yAUTOMATIC { $$ = VLifetime::AUTOMATIC; }
|
||||
;
|
||||
|
||||
taskId<ftaskp>:
|
||||
@ -5481,10 +5510,12 @@ class_declaration<nodep>: // ==IEEE: part of class_declaration
|
||||
classFront<classp>: // IEEE: part of class_declaration
|
||||
classVirtualE yCLASS lifetimeE idAny/*class_identifier*/
|
||||
{ $$ = new AstClass($2, *$4);
|
||||
$$->lifetime($3);
|
||||
SYMP->pushNew($<classp>$); }
|
||||
// // IEEE: part of interface_class_declaration
|
||||
| yINTERFACE yCLASS lifetimeE idAny/*class_identifier*/
|
||||
{ $$ = new AstClass($2, *$4);
|
||||
$$->lifetime($3);
|
||||
SYMP->pushNew($<classp>$);
|
||||
BBUNSUP($2, "Unsupported: interface classes"); }
|
||||
;
|
||||
|
Loading…
Reference in New Issue
Block a user