@@ -535,8 +535,9 @@ absl::StatusOr<std::unique_ptr<Module>> Parser::ParseModule(
535535 XLS_ASSIGN_OR_RETURN (Function * fn,
536536 ParseFunction (*module_member_start_pos, is_public,
537537 *bindings, &name_to_fn));
538- XLS_ASSIGN_OR_RETURN (ModuleMember fn_or_wrapper,
539- ApplyFunctionAttributes (fn, pending_attributes));
538+ XLS_ASSIGN_OR_RETURN (
539+ ModuleMember fn_or_wrapper,
540+ ApplyFunctionAttributes (fn, pending_attributes, *bindings));
540541 XLS_RETURN_IF_ERROR (
541542 module_->AddTop (fn_or_wrapper, make_collision_error));
542543 break ;
@@ -653,11 +654,11 @@ absl::StatusOr<std::unique_ptr<Module>> Parser::ParseModule(
653654 // post-condition.
654655 XLS_RET_CHECK (AtEof ());
655656
656- XLS_RETURN_IF_ERROR (VerifyParentage (module_. get () ));
657+ XLS_RETURN_IF_ERROR (VerifyParentage (module_));
657658
658659 module_->set_span (Span (module_start_pos, GetPos ()));
659660
660- auto result = std::move (module_ );
661+ auto result = std::move (owned_module_ );
661662 module_ = nullptr ;
662663 return result;
663664}
@@ -1008,8 +1009,10 @@ absl::Status Parser::ApplyExternVerilogAttribute(Function* fn,
10081009}
10091010
10101011absl::StatusOr<ModuleMember> Parser::ApplyFunctionAttributes (
1011- Function* fn, std::vector<Attribute*> attributes) {
1012+ Function* fn, std::vector<Attribute*> attributes, Bindings& bindings ) {
10121013 bool is_test = false ;
1014+ bool is_fuzz_test = false ;
1015+ Attribute* fuzz_test_attribute = nullptr ;
10131016 std::optional<QuickCheckTestCases> quickcheck_test_cases;
10141017 std::vector<std::string> test_attributes;
10151018
@@ -1035,7 +1038,9 @@ absl::StatusOr<ModuleMember> Parser::ApplyFunctionAttributes(
10351038 is_test = true ;
10361039 break ;
10371040 case AttributeKind::kFuzzTest :
1041+ is_fuzz_test = true ;
10381042 XLS_RETURN_IF_ERROR (ValidateFuzzTestAttribute (*next));
1043+ fuzz_test_attribute = next;
10391044 test_attributes.push_back (next->ToString ());
10401045 break ;
10411046
@@ -1072,6 +1077,22 @@ absl::StatusOr<ModuleMember> Parser::ApplyFunctionAttributes(
10721077 tf->SetParentage (); // Ensure the function has its parent marked.
10731078 return tf;
10741079 }
1080+ if (is_fuzz_test) {
1081+ Span ft_span (fuzz_test_attribute->GetSpan ()->start (), fn->span ().limit ());
1082+ std::optional<XlsTuple*> domains = std::nullopt ;
1083+ for (const AttributeData::Argument& arg : fuzz_test_attribute->args ()) {
1084+ if (auto * kv = std::get_if<AttributeData::StringKeyValueArgument>(&arg)) {
1085+ if (kv->first == " domains" && kv->is_backticked ) {
1086+ XLS_ASSIGN_OR_RETURN (domains, ParseDomains (kv->second , bindings));
1087+ break ;
1088+ }
1089+ }
1090+ }
1091+ FuzzTestFunction* ft =
1092+ module_->Make <FuzzTestFunction>(ft_span, *fn, domains);
1093+ ft->SetParentage (); // Ensure the function has its parent marked.
1094+ return ft;
1095+ }
10751096
10761097 if (quickcheck_test_cases.has_value ()) {
10771098 const Span quickcheck_span (attributes[0 ]->GetSpan ()->start (),
@@ -1083,6 +1104,22 @@ absl::StatusOr<ModuleMember> Parser::ApplyFunctionAttributes(
10831104 return fn;
10841105}
10851106
1107+ absl::StatusOr<XlsTuple*> Parser::ParseDomains (std::string_view domains_str,
1108+ Bindings& bindings) {
1109+ std::string wrapped = absl::StrCat (" (" , domains_str, " )" );
1110+ Scanner domain_scanner (file_table (), scanner ().fileno (), wrapped);
1111+ Parser sub_parser (module_, &domain_scanner, parse_fn_stubs_);
1112+
1113+ XLS_ASSIGN_OR_RETURN (Expr * parsed, sub_parser.ParseExpression (bindings));
1114+
1115+ if (parsed->kind () == AstNodeKind::kXlsTuple ) {
1116+ return dynamic_cast <XlsTuple*>(parsed);
1117+ }
1118+ // If it's not already a tuple, wrap it in one.
1119+ return module_->Make <XlsTuple>(parsed->span (), std::vector<Expr*>{parsed},
1120+ /* has_trailing_comma=*/ false );
1121+ }
1122+
10861123template <typename T>
10871124absl::Status Parser::ApplyTypeAttributes (T* node,
10881125 std::vector<Attribute*> attributes) {
@@ -3105,12 +3142,12 @@ absl::StatusOr<Spawn*> Parser::ParseSpawn(Bindings& bindings) {
31053142 absl::StrCat (colon_ref->attr (), " .config" ));
31063143
31073144 ColonRef::Subject clone_subject =
3108- CloneSubject (module_. get () , colon_ref->subject ());
3145+ CloneSubject (module_, colon_ref->subject ());
31093146 next_ref =
31103147 module_->Make <ColonRef>(colon_ref->span (), clone_subject,
31113148 absl::StrCat (colon_ref->attr (), " .next" ));
31123149
3113- clone_subject = CloneSubject (module_. get () , colon_ref->subject ());
3150+ clone_subject = CloneSubject (module_, colon_ref->subject ());
31143151 init_ref =
31153152 module_->Make <ColonRef>(colon_ref->span (), clone_subject,
31163153 absl::StrCat (colon_ref->attr (), " .init" ));
@@ -3693,11 +3730,10 @@ absl::StatusOr<ModuleMember> Parser::ParseProcLike(const Pos& start_pos,
36933730 " Impl-style procs must use commas to separate members." );
36943731 }
36953732 // Assume this is an impl-style proc and return a `ProcDef` for it.
3696- ProcDef* proc_def =
3697- module_->Make <ProcDef>(span, name_def, std::move (parametric_bindings),
3698- ConvertProcMembersToStructMembers (
3699- module_.get (), proc_like_body.members ),
3700- is_public);
3733+ ProcDef* proc_def = module_->Make <ProcDef>(
3734+ span, name_def, std::move (parametric_bindings),
3735+ ConvertProcMembersToStructMembers (module_, proc_like_body.members ),
3736+ is_public);
37013737 outer_bindings.Add (name_def->identifier (), proc_def);
37023738 return proc_def;
37033739 }
0 commit comments