@@ -1667,7 +1667,7 @@ Parser<ManagedTokenSource>::parse_function_qualifiers ()
16671667template <typename ManagedTokenSource>
16681668tl::expected<AST::FunctionQualifiers, Parse::Error::Node>
16691669Parser<ManagedTokenSource>::function_qualifiers_from_keywords (
1670- location_t locus, std::vector<TokenId> keywords, std::string abi)
1670+ location_t locus, const std::vector<TokenId> keywords, std::string abi)
16711671{
16721672 Default default_status = Default::No;
16731673 Async async_status = Async::No;
@@ -1812,62 +1812,65 @@ Parser<ManagedTokenSource>::ensure_function_qualifier_order (
18121812 const size_t priority = token_priority (token_id);
18131813 if (priority <= last_priority)
18141814 {
1815- auto qualifiers_to_str = [] (const std::vector<TokenId> &token_ids) {
1816- std::ostringstream ss;
1815+ emit_function_qualifier_order_error_msg (locus, found_order);
1816+ return false ;
1817+ }
18171818
1818- for (auto id : token_ids)
1819- {
1820- if (ss.tellp () != 0 )
1821- ss << ' ' ;
1819+ last_priority = priority;
1820+ }
18221821
1823- if (id == IDENTIFIER)
1824- ss << Values::WeakKeywords::DEFAULT;
1825- else
1826- ss << token_id_keyword_string (id);
1827- }
1822+ return true ;
1823+ }
18281824
1829- return ss.str ();
1830- };
1825+ template <typename ManagedTokenSource>
1826+ void
1827+ Parser<ManagedTokenSource>::emit_function_qualifier_order_error_msg (
1828+ location_t locus, const std::vector<TokenId> &found_order)
1829+ {
1830+ std::vector<TokenId> expected_order
1831+ = {IDENTIFIER, CONST, ASYNC, UNSAFE, EXTERN_KW};
18311832
1832- std::vector<TokenId> expected_order
1833- = {IDENTIFIER, CONST, ASYNC, UNSAFE, EXTERN_KW};
1833+ // we only keep the qualifiers actually used in the offending code
1834+ std::vector<TokenId>::iterator token_id = expected_order.begin ();
1835+ while (token_id != expected_order.end ())
1836+ {
1837+ if (std::find (found_order.cbegin (), found_order.cend (), *token_id)
1838+ == found_order.cend ())
1839+ {
1840+ token_id = expected_order.erase (token_id);
1841+ }
1842+ else
1843+ {
1844+ ++token_id;
1845+ }
1846+ }
18341847
1835- // we only keep the qualifiers actually used in the offending code
1836- std::vector<TokenId>::const_iterator token_id
1837- = expected_order.cbegin ();
1838- while (token_id != expected_order.cend ())
1839- {
1840- if (std::find (found_order.cbegin (), found_order.cend (),
1841- *token_id)
1842- == found_order.cend ())
1843- {
1844- token_id = expected_order.erase (token_id);
1845- }
1846- else
1847- {
1848- ++token_id;
1849- }
1850- }
1848+ auto qualifiers_to_str = [] (const std::vector<TokenId> &token_ids) {
1849+ std::ostringstream ss;
18511850
1852- const std::string found_qualifiers = qualifiers_to_str (found_order);
1853- const std::string expected_qualifiers
1854- = qualifiers_to_str (expected_order);
1851+ for (auto id : token_ids)
1852+ {
1853+ if (ss.tellp () != 0 )
1854+ ss << ' ' ;
18551855
1856- location_t error_locus
1857- = make_location (locus, locus, lexer.peek_token ()->get_locus ());
1858- Error error (
1859- error_locus,
1860- " invalid order of function qualifiers; found %qs, expected %qs" ,
1861- found_qualifiers.c_str (), expected_qualifiers.c_str ());
1862- add_error (std::move (error));
1856+ if (id == IDENTIFIER)
1857+ ss << Values::WeakKeywords::DEFAULT;
1858+ else
1859+ ss << token_id_keyword_string (id);
1860+ }
18631861
1864- return false ;
1865- }
1862+ return ss. str () ;
1863+ };
18661864
1867- last_priority = priority ;
1868- }
1865+ const std::string found_qualifiers = qualifiers_to_str (found_order) ;
1866+ const std::string expected_qualifiers = qualifiers_to_str (expected_order);
18691867
1870- return true ;
1868+ location_t error_locus
1869+ = make_location (locus, locus, lexer.peek_token ()->get_locus ());
1870+ Error error (error_locus,
1871+ " invalid order of function qualifiers; found %qs, expected %qs" ,
1872+ found_qualifiers.c_str (), expected_qualifiers.c_str ());
1873+ add_error (std::move (error));
18711874}
18721875
18731876// Parses generic (lifetime or type) params inside angle brackets (optional).
0 commit comments