From 4f7c4a4a9a5ede796156a1cd1bfa6c09e4b54cdd Mon Sep 17 00:00:00 2001 From: Taichi Ishitani Date: Wed, 11 Dec 2024 14:30:01 +0900 Subject: [PATCH] fix issue that `generic_references` are unexpectedly cleared (refs: veryl-lang/veryl#1131) --- .../src/handlers/create_symbol_table.rs | 60 +++++++++++++------ .../testcases/sv/56_generic_interface.sv.map | 2 +- testcases/sv/56_generic_interface.sv | 16 ++++- testcases/veryl/56_generic_interface.veryl | 6 ++ 4 files changed, 62 insertions(+), 22 deletions(-) diff --git a/crates/analyzer/src/handlers/create_symbol_table.rs b/crates/analyzer/src/handlers/create_symbol_table.rs index 6d1dcfd0..8a8b7b32 100644 --- a/crates/analyzer/src/handlers/create_symbol_table.rs +++ b/crates/analyzer/src/handlers/create_symbol_table.rs @@ -32,6 +32,34 @@ use veryl_parser::veryl_token::{Token, TokenRange, TokenSource}; use veryl_parser::veryl_walker::{Handler, HandlerPoint}; use veryl_parser::ParolError; +#[derive(Default)] +struct GenericContext { + parameters: Vec>, + references: Vec>, +} + +impl GenericContext { + pub fn push(&mut self) { + self.parameters.push(Vec::new()); + self.references.push(Vec::new()); + } + + pub fn pop(&mut self) -> (Vec, Vec) { + ( + self.parameters.pop().unwrap(), + self.references.pop().unwrap(), + ) + } + + pub fn push_parameter(&mut self, id: SymbolId) { + self.parameters.last_mut().unwrap().push(id); + } + + pub fn push_reference(&mut self, path: GenericSymbolPath) { + self.references.last_mut().unwrap().push(path); + } +} + #[derive(Default)] pub struct CreateSymbolTable<'a> { pub errors: Vec, @@ -54,11 +82,10 @@ pub struct CreateSymbolTable<'a> { affiliation: Vec, connect_targets: Vec, connects: HashMap>, - generic_parameters: Vec>, parameters: Vec>, ports: Vec>, needs_default_generic_argument: bool, - generic_references: Vec, + generic_context: GenericContext, default_clock_candidates: Vec, defualt_reset_candidates: Vec, modport_member_ids: Vec, @@ -433,7 +460,7 @@ impl VerylGrammarTrait for CreateSymbolTable<'_> { HandlerPoint::After => { let path: GenericSymbolPath = arg.into(); if path.is_generic_reference() { - self.generic_references.push(path); + self.generic_context.push_reference(path); } } } @@ -790,15 +817,14 @@ impl VerylGrammarTrait for CreateSymbolTable<'_> { StructUnion::Union(_) => Some(StructOrUnion::InUnion), }; - self.generic_parameters.push(Vec::new()); + self.generic_context.push(); self.namespace.push(name); } HandlerPoint::After => { self.struct_or_union = None; self.namespace.pop(); - let generic_parameters: Vec<_> = self.generic_parameters.pop().unwrap(); - let generic_references: Vec<_> = self.generic_references.drain(..).collect(); + let (generic_parameters, generic_references) = self.generic_context.pop(); let members: Vec<_> = self.struct_union_members.drain(0..).flatten().collect(); let kind = match &*arg.struct_union { @@ -980,7 +1006,7 @@ impl VerylGrammarTrait for CreateSymbolTable<'_> { if let Some(id) = self.insert_symbol(&arg.identifier.identifier_token.token, kind, false) { - self.generic_parameters.last_mut().unwrap().push(id); + self.generic_context.push_parameter(id); } } else { self.errors.push(AnalyzerError::missing_default_argument( @@ -1091,7 +1117,7 @@ impl VerylGrammarTrait for CreateSymbolTable<'_> { match self.point { HandlerPoint::Before => { self.namespace.push(name); - self.generic_parameters.push(Vec::new()); + self.generic_context.push(); self.ports.push(Vec::new()); self.affiliation.push(VariableAffiliation::Function); } @@ -1099,8 +1125,7 @@ impl VerylGrammarTrait for CreateSymbolTable<'_> { self.namespace.pop(); self.affiliation.pop(); - let generic_parameters: Vec<_> = self.generic_parameters.pop().unwrap(); - let generic_references: Vec<_> = self.generic_references.drain(..).collect(); + let (generic_parameters, generic_references) = self.generic_context.pop(); let ports: Vec<_> = self.ports.pop().unwrap(); let ret = arg @@ -1165,7 +1190,7 @@ impl VerylGrammarTrait for CreateSymbolTable<'_> { match self.point { HandlerPoint::Before => { self.namespace.push(name); - self.generic_parameters.push(Vec::new()); + self.generic_context.push(); self.parameters.push(Vec::new()); self.ports.push(Vec::new()); self.affiliation.push(VariableAffiliation::Module); @@ -1180,8 +1205,7 @@ impl VerylGrammarTrait for CreateSymbolTable<'_> { self.affiliation.pop(); self.module_namspace_depth = 0; - let generic_parameters: Vec<_> = self.generic_parameters.pop().unwrap(); - let generic_references: Vec<_> = self.generic_references.drain(..).collect(); + let (generic_parameters, generic_references) = self.generic_context.pop(); let parameters: Vec<_> = self.parameters.pop().unwrap(); let ports: Vec<_> = self.ports.pop().unwrap(); @@ -1296,7 +1320,7 @@ impl VerylGrammarTrait for CreateSymbolTable<'_> { match self.point { HandlerPoint::Before => { self.namespace.push(name); - self.generic_parameters.push(Vec::new()); + self.generic_context.push(); self.parameters.push(Vec::new()); self.affiliation.push(VariableAffiliation::Intarface); self.function_ids.clear(); @@ -1308,8 +1332,7 @@ impl VerylGrammarTrait for CreateSymbolTable<'_> { self.namespace.pop(); self.affiliation.pop(); - let generic_parameters: Vec<_> = self.generic_parameters.pop().unwrap(); - let generic_references: Vec<_> = self.generic_references.drain(..).collect(); + let (generic_parameters, generic_references) = self.generic_context.pop(); let parameters: Vec<_> = self.parameters.pop().unwrap(); let range = @@ -1350,7 +1373,7 @@ impl VerylGrammarTrait for CreateSymbolTable<'_> { match self.point { HandlerPoint::Before => { self.namespace.push(name); - self.generic_parameters.push(Vec::new()); + self.generic_context.push(); self.affiliation.push(VariableAffiliation::Package); self.function_ids.clear(); @@ -1360,8 +1383,7 @@ impl VerylGrammarTrait for CreateSymbolTable<'_> { self.namespace.pop(); self.affiliation.pop(); - let generic_parameters: Vec<_> = self.generic_parameters.pop().unwrap(); - let generic_references: Vec<_> = self.generic_references.drain(..).collect(); + let (generic_parameters, generic_references) = self.generic_context.pop(); let range = TokenRange::new(&arg.package.package_token, &arg.r_brace.r_brace_token); diff --git a/testcases/map/testcases/sv/56_generic_interface.sv.map b/testcases/map/testcases/sv/56_generic_interface.sv.map index fae54d0e..0d4e5b5a 100644 --- a/testcases/map/testcases/sv/56_generic_interface.sv.map +++ b/testcases/map/testcases/sv/56_generic_interface.sv.map @@ -1 +1 @@ -{"version":3,"file":"56_generic_interface.sv.map","sources":["../../../veryl/56_generic_interface.veryl"],"names":["","module","Module56",";","import","veryl_testcase_Package56A::X","veryl_testcase___Interface56A__Package56A_X","u0","veryl_testcase___Interface56A__Package56B_X","u1","veryl_testcase___Interface56B__Package56A_X","u2","u3","veryl_testcase___Interface56B__3","u4","u5","logic","_a","=",".","_b","_c","endmodule","interface","[","]","endinterface","veryl_testcase_Package56B::X","3","package","Package56A","localparam","int unsigned","X","1","endpackage","Package56B","2"],"mappings":"AAAAA,AAAAC,sBAAOC,QAASC;IACZC,OAAOC,4BAAaF;IACpBH,AAASM,4CAAJC,KAAiCJ;IACtCH,AAASQ,4CAAJC,KAAiCN;IACtCH,AAASU,4CAAJC,KAAiCR;IACtCH,AAASU,4CAAJE,KAAiCT;IACtCH,AAASa,iCAAJC,KAAoBX;IACzBH,AAASU,4CAAJK,KAAqBZ;;IAElBa,MAAJC;mBAAUC,EAAEX,EAAEY,CAACF,EAAEd;IACba,MAAJI;mBAAUF,EAAEP,EAAEQ,CAACC,EAAEjB;IACba,MAAJK;mBAAUH,EAAEH,EAAEI,CAACC,EAAEjB;AACzBmB;;;AAGIC,qDAAmCpB;IAC3Ba,MAAKQ,CAACnB,gCAACoB,EAAXR,EAAYd;AACpBuB;;;AAFIH,qDAAmCpB;IAC3Ba,MAAKQ,CAACG,gCAACF,EAAXR,EAAYd;AACpBuB;;;AAGIH,qDAAuCpB;IAC/Ba,MAAKQ,CAACnB,gCAACoB,6BAAXL,EAAYjB;AACpBuB;AAFIH,0CAAuCpB;IAC/Ba,MAAKQ,CAACI,KAACH,6BAAXL,EAAYjB;AACpBuB;;AAEAG,uBAAQC,UAAW3B;IACf4B,WAASC,aAAHC,EAAOf,EAAEgB,CAAC/B;AACpBgC;;AAEAN,uBAAQO,UAAWjC;IACf4B,WAASC,aAAHC,EAAOf,EAAEmB,CAAClC;AACpBgC"} \ No newline at end of file +{"version":3,"file":"56_generic_interface.sv.map","sources":["../../../veryl/56_generic_interface.veryl"],"names":["","module","Module56",";","import","veryl_testcase_Package56A::X","veryl_testcase___Interface56A__Package56A_X","u0","veryl_testcase___Interface56A__Package56B_X","u1","veryl_testcase___Interface56B__Package56A_X","u2","u3","veryl_testcase___Interface56B__3","u4","u5","veryl_testcase___Module56Sub__1","u6","logic","_a","=",".","_b","_c","endmodule","veryl_testcase___Interface56A__1","u","function","f","(",")","endfunction","interface","[","]","endinterface","veryl_testcase_Package56B::X","1","3","package","Package56A","localparam","int unsigned","X","endpackage","Package56B","2"],"mappings":"AAAAA,AAAAC,sBAAOC,QAASC;IACZC,OAAOC,4BAAaF;IACpBH,AAASM,4CAAJC,KAAiCJ;IACtCH,AAASQ,4CAAJC,KAAiCN;IACtCH,AAASU,4CAAJC,KAAiCR;IACtCH,AAASU,4CAAJE,KAAiCT;IACtCH,AAASa,iCAAJC,KAAoBX;IACzBH,AAASU,4CAAJK,KAAqBZ;IAC1BH,AAASgB,gCAAJC,KAAoBd;;IAEjBe,MAAJC;mBAAUC,EAAEb,EAAEc,CAACF,EAAEhB;IACbe,MAAJI;mBAAUF,EAAET,EAAEU,CAACC,EAAEnB;IACbe,MAAJK;mBAAUH,EAAEL,EAAEM,CAACC,EAAEnB;AACzBqB;;AAEAvB,sCAA+BE;IAC3BH,AAAQyB,iCAAHC,IAAoBvB;IACzBwB,wBAASC,CAAEC,CAACC,GAAE9B;IAAC+B;AACnBP;;;AAGIQ,qDAAmC7B;IAC3Be,MAAKe,CAAC5B,gCAAC6B,6BAAXf,EAAYhB;AACpBgC;;;AAFIH,qDAAmC7B;IAC3Be,MAAKe,CAACG,gCAACF,6BAAXf,EAAYhB;AACpBgC;;;AAFIH,0CAAmC7B;IAC3Be,MAAKe,CAACI,KAACH,6BAAXf,EAAYhB;AACpBgC;;;AAGIH,qDAAuC7B;IAC/Be,MAAKe,CAAC5B,gCAAC6B,6BAAXZ,EAAYnB;AACpBgC;AAFIH,0CAAuC7B;IAC/Be,MAAKe,CAACK,KAACJ,6BAAXZ,EAAYnB;AACpBgC;;AAEAI,uBAAQC,UAAWrC;IACfsC,WAASC,aAAHC,EAAOvB,EAAEiB,CAAClC;AACpByC;;AAEAL,uBAAQM,UAAW1C;IACfsC,WAASC,aAAHC,EAAOvB,EAAE0B,CAAC3C;AACpByC"} \ No newline at end of file diff --git a/testcases/sv/56_generic_interface.sv b/testcases/sv/56_generic_interface.sv index 0d7afd7a..4abac69d 100644 --- a/testcases/sv/56_generic_interface.sv +++ b/testcases/sv/56_generic_interface.sv @@ -6,6 +6,7 @@ module veryl_testcase_Module56; veryl_testcase___Interface56B__Package56A_X u3 (); veryl_testcase___Interface56B__3 u4 (); veryl_testcase___Interface56B__Package56A_X u5 (); + veryl_testcase___Module56Sub__1 u6 (); logic _a; always_comb _a = u0._a; @@ -15,14 +16,25 @@ module veryl_testcase_Module56; always_comb _c = u5._b; endmodule +module veryl_testcase___Module56Sub__1; + veryl_testcase___Interface56A__1 u (); + function automatic void f() ; + endfunction +endmodule + /// Generic interface test for doc comment interface veryl_testcase___Interface56A__Package56A_X; - logic [veryl_testcase_Package56A::X-1:0] _a; + logic [veryl_testcase_Package56A::X-1:0] _a; endinterface /// Generic interface test for doc comment interface veryl_testcase___Interface56A__Package56B_X; - logic [veryl_testcase_Package56B::X-1:0] _a; + logic [veryl_testcase_Package56B::X-1:0] _a; +endinterface + +/// Generic interface test for doc comment +interface veryl_testcase___Interface56A__1; + logic [1-1:0] _a; endinterface /// Generic interface test for doc comment diff --git a/testcases/veryl/56_generic_interface.veryl b/testcases/veryl/56_generic_interface.veryl index 92fb7629..d5d97efc 100644 --- a/testcases/veryl/56_generic_interface.veryl +++ b/testcases/veryl/56_generic_interface.veryl @@ -6,12 +6,18 @@ module Module56 { inst u3: Interface56B::; inst u4: Interface56B::<>; inst u5: Interface56B::; + inst u6: Module56Sub::<1>; let _a: logic = u0._a; let _b: logic = u2._b; let _c: logic = u5._b; } +module Module56Sub:: { + inst u: Interface56A::; + function f () {} +} + /// Generic interface test for doc comment pub interface Interface56A:: { var _a: logic;