1use std::collections::HashMap;
42
43use crate::ast::*;
44use crate::capture::SourceRange;
45use crate::diag::{Diagnostic, Diagnostics};
46use crate::gnu;
47use crate::ir::{INT128_TYPEDEF_NAMES, VA_LIST_NAMES, X86_VECTOR_TYPEDEF_NAMES};
48use crate::lex::{Keyword, Punct, StrKind, StrLit, TokenKind};
49use crate::pp::{Origin, PackMap, TargetOptionMap, Token};
50use crate::target::Arch;
51use crate::{Gating, Options, Standard};
52
53pub const NORETURN_BUILTIN: &str = "__cinrs_noreturn";
61
62fn int_expr(value: u128, range: SourceRange) -> Expr {
64 Expr {
65 kind: ExprKind::Int(crate::lex::IntLit {
66 value,
67 base: crate::lex::NumBase::Decimal,
68 unsigned: false,
69 long: crate::lex::LongKind::None,
70 text: value.to_string(),
71 }),
72 range,
73 }
74}
75
76#[derive(Debug)]
78#[must_use]
79pub struct Bail;
80
81type PResult<T> = Result<T, Bail>;
82
83#[derive(Clone, Copy, PartialEq, Eq, Debug)]
85enum SymKind {
86 Typedef,
87 Ordinary,
88}
89
90#[derive(Default)]
92struct Scope {
93 syms: HashMap<String, SymKind>,
94}
95
96pub fn parse(
108 tokens: &[Token],
109 unit_range: SourceRange,
110 packing: &PackMap,
111 targets: &TargetOptionMap,
112 options: &Options,
113 diags: &mut Diagnostics,
114) -> TranslationUnit {
115 let patched: Vec<Token>;
118 let tokens: &[Token] = if tokens.last().is_some_and(Token::is_eof) {
119 tokens
120 } else {
121 patched = tokens
122 .iter()
123 .cloned()
124 .chain(std::iter::once(Token {
125 kind: TokenKind::Eof,
126 range: SourceRange::at(unit_range.end),
127 origin: Origin::Source,
128 }))
129 .collect();
130 &patched
131 };
132 let last_range = tokens.first().map_or(unit_range, |t| t.range);
133 let mut builtins = Scope::default();
139 for name in VA_LIST_NAMES {
140 builtins.syms.insert((*name).to_owned(), SymKind::Typedef);
141 }
142 for (name, _) in INT128_TYPEDEF_NAMES {
146 builtins.syms.insert((*name).to_owned(), SymKind::Typedef);
147 }
148 if matches!(options.target.arch, Arch::X86 | Arch::X86_64) {
156 for (name, _) in X86_VECTOR_TYPEDEF_NAMES {
157 builtins.syms.insert((*name).to_owned(), SymKind::Typedef);
158 }
159 }
160 let mut parser = Parser {
161 tokens,
162 pos: 0,
163 diags,
164 scopes: vec![builtins],
165 standard: options.standard,
166 gating: options.gating(),
167 in_extension: false,
168 packing,
169 targets,
170 decl_start: 0,
171 last_range,
172 depth: 0,
173 records: Vec::new(),
174 enums: Vec::new(),
175 typeofs: Vec::new(),
176 label_addrs: 0,
177 };
178 parser.parse_translation_unit(unit_range)
179}
180
181const MAX_RECURSION_DEPTH: u32 = 200;
211
212const MAX_LABEL_CHAIN: usize = 4096;
220
221enum PendingLabel {
223 Ident { label: Ident },
225 Case { value: Expr, upper: Option<Expr> },
227 Default,
229}
230
231struct Parser<'a> {
232 tokens: &'a [Token],
233 pos: usize,
234 diags: &'a mut Diagnostics,
235 scopes: Vec<Scope>,
236 standard: Standard,
238 gating: Gating,
240 in_extension: bool,
243 packing: &'a PackMap,
245 targets: &'a TargetOptionMap,
247 decl_start: usize,
250 last_range: SourceRange,
252 depth: u32,
254 records: Vec<RecordSpec>,
256 enums: Vec<EnumSpec>,
258 typeofs: Vec<TypeofOperand>,
260 label_addrs: u32,
272}
273
274impl Parser<'_> {
279 fn peek(&self) -> &Token {
280 &self.tokens[self.pos]
281 }
282
283 fn nth(&self, n: usize) -> &Token {
284 let i = (self.pos + n).min(self.tokens.len() - 1);
285 &self.tokens[i]
286 }
287
288 fn cur_range(&self) -> SourceRange {
289 self.peek().range
290 }
291
292 fn describe_cur(&self) -> String {
293 self.peek().kind.describe()
294 }
295
296 fn at_eof(&self) -> bool {
297 self.peek().is_eof()
298 }
299
300 fn at_punct(&self, p: Punct) -> bool {
301 self.peek().is_punct(p)
302 }
303
304 fn at_keyword(&self, k: Keyword) -> bool {
305 self.peek().is_keyword(k)
306 }
307
308 fn advance(&mut self) {
309 self.last_range = self.tokens[self.pos].range;
310 if self.pos + 1 < self.tokens.len() {
311 self.pos += 1;
312 }
313 }
314
315 fn bump_range(&mut self) -> SourceRange {
316 let range = self.cur_range();
317 self.advance();
318 range
319 }
320
321 fn eat_punct(&mut self, p: Punct) -> Option<SourceRange> {
322 self.at_punct(p).then(|| self.bump_range())
323 }
324
325 fn eat_keyword(&mut self, k: Keyword) -> Option<SourceRange> {
326 self.at_keyword(k).then(|| self.bump_range())
327 }
328
329 fn eat_ident(&mut self) -> Option<Ident> {
330 let name = self.peek().ident()?.to_owned();
331 let range = self.bump_range();
332 Some(Ident { name, range })
333 }
334
335 fn error(&mut self, range: SourceRange, message: impl Into<String>) {
336 self.diags.error(range, message);
337 }
338
339 fn error_bail(&mut self, range: SourceRange, message: impl Into<String>) -> Bail {
340 self.diags.error(range, message);
341 Bail
342 }
343
344 fn expect_punct(&mut self, p: Punct, ctx: &str) -> PResult<SourceRange> {
345 if self.at_punct(p) {
346 return Ok(self.bump_range());
347 }
348 let range = self.cur_range();
349 let found = self.describe_cur();
350 Err(self.error_bail(
351 range,
352 format!("expected '{}'{ctx}, found {found}", p.as_str()),
353 ))
354 }
355
356 fn expect_ident(&mut self, ctx: &str) -> PResult<Ident> {
357 if let Some(id) = self.eat_ident() {
358 return Ok(id);
359 }
360 let range = self.cur_range();
361 let found = self.describe_cur();
362 Err(self.error_bail(range, format!("expected identifier{ctx}, found {found}")))
363 }
364
365 fn span_to_here(&self, start: SourceRange) -> SourceRange {
367 start.join(self.last_range)
368 }
369
370 fn enter(&mut self) -> PResult<()> {
375 self.depth += 1;
376 if self.depth > MAX_RECURSION_DEPTH {
377 let range = self.cur_range();
378 return Err(self.error_bail(range, "this construct nests too deeply"));
379 }
380 Ok(())
381 }
382
383 fn leave(&mut self) {
385 self.depth = self.depth.saturating_sub(1);
386 }
387
388 fn require_standard(&mut self, needed: Standard, what: &str, range: SourceRange) {
401 if self.in_extension {
402 return;
403 }
404 if let Some(message) = self.gating.requires(what, needed) {
405 self.error(range, message);
406 }
407 }
408
409 fn require_keyword(&mut self, k: Keyword, range: SourceRange) {
411 let needed = k.since();
412 self.require_standard(needed, &format!("'{}'", k.as_str()), range);
413 }
414
415 fn newer_keyword_here(&self) -> Option<String> {
418 self.gating.newer_keyword(self.peek().ident()?)
419 }
420
421 fn gnu_leniency(&self) -> bool {
424 self.gating.dialect.is_gnu()
425 }
426
427 fn gnu_note(&self) -> String {
430 format!(
431 "GCC accepts this with a warning; write {} for the same leniency",
432 self.gating.standard.macro_name_in(crate::Dialect::Gnu)
433 )
434 }
435
436 fn error_gnu(&mut self, range: SourceRange, message: impl Into<String>) {
438 let note = self.gnu_note();
439 self.diags
440 .push(Diagnostic::error(range, message).with_note(note));
441 }
442}
443
444impl Parser<'_> {
449 fn push_scope(&mut self) {
450 self.scopes.push(Scope::default());
451 }
452
453 fn pop_scope(&mut self) {
454 self.scopes.pop();
455 }
456
457 fn declare(&mut self, name: &str, kind: SymKind) {
458 if let Some(scope) = self.scopes.last_mut() {
459 scope.syms.insert(name.to_owned(), kind);
460 }
461 }
462
463 fn is_typedef_name(&self, name: &str) -> bool {
465 for scope in self.scopes.iter().rev() {
466 if let Some(kind) = scope.syms.get(name) {
467 return *kind == SymKind::Typedef;
468 }
469 }
470 false
471 }
472}
473
474impl Parser<'_> {
479 fn at_attributes(&self) -> bool {
484 (self.at_punct(Punct::LBracket) && self.nth(1).is_punct(Punct::LBracket))
485 || self.at_keyword(Keyword::Attribute)
486 }
487
488 fn parse_attributes(&mut self) -> PResult<Attributes> {
498 let mut attrs = Attributes::default();
499 loop {
500 if self.at_keyword(Keyword::Attribute) {
501 let start = self.bump_range();
502 self.expect_punct(Punct::LParen, " after '__attribute__'")?;
503 self.expect_punct(Punct::LParen, " after '__attribute__('")?;
504 self.parse_attribute_list(&mut attrs, Punct::RParen)?;
505 self.expect_punct(Punct::RParen, " to close '__attribute__'")?;
506 self.expect_punct(Punct::RParen, " to close '__attribute__'")?;
507 let _ = start;
508 continue;
509 }
510 if self.at_punct(Punct::LBracket) && self.nth(1).is_punct(Punct::LBracket) {
511 let start = self.cur_range();
512 self.require_standard(Standard::C23, "an attribute specifier", start);
513 self.advance(); self.advance(); self.parse_attribute_list(&mut attrs, Punct::RBracket)?;
516 self.expect_punct(Punct::RBracket, " to close an attribute specifier")?;
517 self.expect_punct(Punct::RBracket, " to close an attribute specifier")?;
518 continue;
519 }
520 return Ok(attrs);
521 }
522 }
523
524 fn parse_attribute_list(&mut self, attrs: &mut Attributes, close: Punct) -> PResult<()> {
526 loop {
527 if self.at_punct(close) || self.at_eof() {
528 return Ok(());
529 }
530 if self.eat_punct(Punct::Comma).is_some() {
532 continue;
533 }
534 self.parse_one_attribute(attrs, close)?;
535 if self.eat_punct(Punct::Comma).is_none() {
536 return Ok(());
537 }
538 }
539 }
540
541 fn parse_one_attribute(&mut self, attrs: &mut Attributes, close: Punct) -> PResult<()> {
543 let start = self.cur_range();
544 let mut name = match &self.peek().kind {
547 TokenKind::Ident(name) => name.clone(),
548 TokenKind::Keyword(k) => k.as_str().to_owned(),
549 _ => {
550 let found = self.describe_cur();
551 return Err(self.error_bail(start, format!("expected an attribute, found {found}")));
552 }
553 };
554 self.advance();
555 let mut ours = false;
558 if self.at_punct(Punct::Colon) && self.nth(1).is_punct(Punct::Colon) {
559 self.advance();
560 self.advance();
561 let prefix = std::mem::take(&mut name);
562 name = match &self.peek().kind {
563 TokenKind::Ident(name) => name.clone(),
564 TokenKind::Keyword(k) => k.as_str().to_owned(),
565 _ => {
566 let found = self.describe_cur();
567 return Err(
568 self.error_bail(start, format!("expected an attribute, found {found}"))
569 );
570 }
571 };
572 self.advance();
573 if prefix == "cinrs" {
577 if gnu::cinrs_attribute(&name).is_none() {
578 self.skip_attribute_args()?;
579 let range = self.span_to_here(start);
580 self.error(
581 range,
582 format!(
583 "unknown 'cinrs' attribute '{name}'; the ones this crate has are {}",
584 Self::list_of_names(gnu::CINRS_ATTRIBUTES)
585 ),
586 );
587 return Ok(());
588 }
589 ours = true;
590 } else if prefix != "gnu" && prefix != "clang" {
591 self.skip_attribute_args()?;
592 return Ok(());
593 }
594 }
595
596 let known = if ours {
597 gnu::cinrs_attribute(&name)
598 } else {
599 gnu::attribute(&name)
600 };
601 match known {
605 Some(gnu::Attribute::Aligned) => {
606 let alignment = if self.at_punct(Punct::LParen) {
607 self.advance();
608 let expr = self.parse_conditional_expr()?;
609 self.expect_punct(Punct::RParen, " after the alignment")?;
610 AlignmentKind::Expr(expr)
611 } else {
612 AlignmentKind::Expr(int_expr(16, start))
615 };
616 let range = self.span_to_here(start);
617 attrs.aligned = Some(Alignment {
618 kind: alignment,
619 from_attribute: true,
620 range,
621 });
622 return Ok(());
623 }
624 Some(gnu::Attribute::Deprecated) => {
625 let message = self.attribute_string()?;
626 let range = self.span_to_here(start);
627 attrs.deprecated = Some(Spanned::new(message, range));
628 return Ok(());
629 }
630 Some(gnu::Attribute::Cleanup) => {
631 let func = self.attribute_identifier()?;
636 let range = self.span_to_here(start);
637 attrs.cleanup = Some(Cleanup { func, range });
638 return Ok(());
639 }
640 Some(gnu::Attribute::Mode) => {
641 let mode = self.attribute_identifier()?;
644 let range = self.span_to_here(start);
645 match mode {
646 Some(mode) => attrs.mode = Some(Spanned::new(mode.name, range)),
647 None => self.error(range, "'mode' takes one machine mode name"),
648 }
649 return Ok(());
650 }
651 Some(gnu::Attribute::Section) => {
652 let name = self.attribute_string()?;
653 let range = self.span_to_here(start);
654 match name {
655 Some(name) => attrs.section = Some(Spanned::new(name, range)),
656 None => self.error(range, "'section' takes one string literal"),
657 }
658 return Ok(());
659 }
660 Some(gnu::Attribute::Target) => {
661 let text = self.attribute_strings()?;
665 let range = self.span_to_here(start);
666 if text.is_empty() {
667 self.error(
668 range,
669 "'target' takes one or more string literals naming an instruction set, \
670 as in target(\"avx2\")",
671 );
672 return Ok(());
673 }
674 for part in text.iter().flat_map(|s| s.split(',')) {
675 let part = part.trim();
676 if !part.is_empty() {
677 attrs.target.push(Spanned::new(part.to_owned(), range));
678 }
679 }
680 return Ok(());
681 }
682 _ => {}
683 }
684 self.skip_attribute_args()?;
685 let range = self.span_to_here(start);
686 match known {
687 Some(gnu::Attribute::Noreturn) => attrs.noreturn = attrs.noreturn.or(Some(range)),
688 Some(gnu::Attribute::AlwaysInline) => {
689 attrs.always_inline = attrs.always_inline.or(Some(range));
690 }
691 Some(gnu::Attribute::NoInline) => attrs.noinline = attrs.noinline.or(Some(range)),
692 Some(gnu::Attribute::Cold) => attrs.cold = attrs.cold.or(Some(range)),
693 Some(gnu::Attribute::Hot) => attrs.cold = None,
695 Some(gnu::Attribute::Packed) => attrs.packed = attrs.packed.or(Some(range)),
696 Some(gnu::Attribute::Constructor) => {
697 attrs.constructor = attrs.constructor.or(Some(range));
698 }
699 Some(gnu::Attribute::Destructor) => {
700 attrs.destructor = attrs.destructor.or(Some(range));
701 }
702 Some(gnu::Attribute::Safe) => attrs.safe = attrs.safe.or(Some(range)),
703 Some(gnu::Attribute::Weak) => attrs.weak = attrs.weak.or(Some(range)),
706 Some(gnu::Attribute::Fallthrough) | Some(gnu::Attribute::Ignored) => {}
709 Some(gnu::Attribute::Unsupported) => {
710 let reason = gnu::unsupported_reason(&name).unwrap_or("is not supported");
711 self.error(range, format!("'{name}' {reason}"));
712 }
713 _ => {}
716 }
717 let _ = close;
718 Ok(())
719 }
720
721 fn attribute_identifier(&mut self) -> PResult<Option<Ident>> {
724 if !self.at_punct(Punct::LParen) {
725 return Ok(None);
726 }
727 self.advance();
728 let name = match &self.peek().kind {
729 TokenKind::Ident(name) => {
730 let ident = Ident {
731 name: name.clone(),
732 range: self.cur_range(),
733 };
734 self.advance();
735 self.at_punct(Punct::RParen).then_some(ident)
737 }
738 _ => None,
739 };
740 let mut depth = 1i32;
741 while depth > 0 && !self.at_eof() {
742 if self.at_punct(Punct::LParen) {
743 depth += 1;
744 } else if self.at_punct(Punct::RParen) {
745 depth -= 1;
746 if depth == 0 {
747 self.advance();
748 break;
749 }
750 }
751 self.advance();
752 }
753 Ok(name)
754 }
755
756 fn attribute_strings(&mut self) -> PResult<Vec<String>> {
761 let mut out = Vec::new();
762 if !self.at_punct(Punct::LParen) {
763 return Ok(out);
764 }
765 self.advance();
766 let mut depth = 1i32;
767 while depth > 0 && !self.at_eof() {
768 if let TokenKind::Str(lit) = self.peek().kind.clone() {
769 let range = self.cur_range();
770 let literal = self.parse_string_literal(lit, range);
771 if let ExprKind::Str(lit) = literal.kind
772 && let Ok(text) =
773 String::from_utf8(lit.values.iter().map(|v| *v as u8).collect())
774 {
775 out.push(text);
776 }
777 continue;
779 }
780 if self.at_punct(Punct::LParen) {
781 depth += 1;
782 } else if self.at_punct(Punct::RParen) {
783 depth -= 1;
784 if depth == 0 {
785 self.advance();
786 break;
787 }
788 }
789 self.advance();
790 }
791 Ok(out)
792 }
793
794 fn attribute_string(&mut self) -> PResult<Option<String>> {
797 if !self.at_punct(Punct::LParen) {
798 return Ok(None);
799 }
800 self.advance();
801 let mut text = None;
802 if let TokenKind::Str(lit) = self.peek().kind.clone() {
803 let range = self.cur_range();
804 let literal = self.parse_string_literal(lit, range);
805 if let ExprKind::Str(lit) = literal.kind {
806 text = String::from_utf8(lit.values.iter().map(|v| *v as u8).collect()).ok();
807 }
808 }
809 let mut depth = 1i32;
811 while depth > 0 && !self.at_eof() {
812 if self.at_punct(Punct::LParen) {
813 depth += 1;
814 } else if self.at_punct(Punct::RParen) {
815 depth -= 1;
816 if depth == 0 {
817 self.advance();
818 break;
819 }
820 }
821 self.advance();
822 }
823 Ok(text)
824 }
825
826 fn skip_attribute_args(&mut self) -> PResult<()> {
828 if !self.at_punct(Punct::LParen) {
829 return Ok(());
830 }
831 let start = self.cur_range();
832 let mut depth = 0i32;
833 while !self.at_eof() {
834 if self.at_punct(Punct::LParen) {
835 depth += 1;
836 } else if self.at_punct(Punct::RParen) {
837 depth -= 1;
838 if depth == 0 {
839 self.advance();
840 return Ok(());
841 }
842 }
843 self.advance();
844 }
845 Err(self.error_bail(start, "unterminated attribute argument list"))
846 }
847
848 fn list_of_names(names: &[&str]) -> String {
851 let quoted: Vec<String> = names.iter().map(|name| format!("'{name}'")).collect();
852 match quoted.split_last() {
853 None => String::new(),
854 Some((last, [])) => last.clone(),
855 Some((last, rest)) => format!("{} and {last}", rest.join(", ")),
856 }
857 }
858
859 fn at_static_assert(&self) -> bool {
861 matches!(
862 self.peek().keyword(),
863 Some(Keyword::StaticAssert | Keyword::StaticAssertName)
864 )
865 }
866
867 fn parse_static_assert(&mut self) -> PResult<StaticAssert> {
870 let start = self.cur_range();
871 let keyword = self.peek().keyword().expect("the caller checked");
872 self.require_keyword(keyword, start);
873 self.advance();
874 let name = keyword.as_str();
875 self.expect_punct(Punct::LParen, &format!(" after '{name}'"))?;
876 let cond = self.parse_conditional_expr()?;
877 let mut message = None;
878 if self.eat_punct(Punct::Comma).is_some() {
879 let range = self.cur_range();
880 let TokenKind::Str(first) = self.peek().kind.clone() else {
881 let found = self.describe_cur();
882 return Err(self.error_bail(
883 range,
884 format!("expected a string literal as the message of '{name}', found {found}"),
885 ));
886 };
887 let literal = self.parse_string_literal(first, range);
888 if let ExprKind::Str(lit) = literal.kind {
889 message = Some(lit.text);
890 }
891 } else {
892 self.require_standard(
893 Standard::C23,
894 &format!("'{name}' without a message"),
895 self.span_to_here(start),
896 );
897 }
898 self.expect_punct(Punct::RParen, &format!(" to close '{name}'"))?;
899 self.expect_punct(Punct::Semi, &format!(" after '{name}'"))?;
900 Ok(StaticAssert {
901 cond,
902 message,
903 range: self.span_to_here(start),
904 })
905 }
906}
907
908impl Parser<'_> {
913 fn parse_translation_unit(&mut self, range: SourceRange) -> TranslationUnit {
914 let mut items = Vec::new();
915 while !self.at_eof() {
916 let before = self.pos;
917 self.depth = 0;
918 if self.at_punct(Punct::Semi) {
927 let range = self.bump_range();
928 if !self.gnu_leniency() {
929 self.error_gnu(range, "expected a declaration, found ';'");
930 }
931 continue;
932 }
933 self.decl_start = before;
940 match self.parse_external_decl() {
941 Ok(item) => items.push(item),
942 Err(Bail) => self.recover_top_level(before),
943 }
944 if self.pos == before {
945 self.advance();
946 }
947 }
948 TranslationUnit {
949 items,
950 records: std::mem::take(&mut self.records),
951 enums: std::mem::take(&mut self.enums),
952 typeofs: std::mem::take(&mut self.typeofs),
953 range,
954 }
955 }
956
957 fn depth_from(&self, start: usize) -> i32 {
960 let mut depth = 0i32;
961 for tok in &self.tokens[start.min(self.pos)..self.pos] {
962 match &tok.kind {
963 TokenKind::Punct(Punct::LBrace | Punct::LParen | Punct::LBracket) => depth += 1,
964 TokenKind::Punct(Punct::RBrace | Punct::RParen | Punct::RBracket) => depth -= 1,
965 _ => {}
966 }
967 }
968 depth.max(0)
969 }
970
971 fn recover_top_level(&mut self, decl_start: usize) {
978 let mut depth = self.depth_from(decl_start);
979 while !self.at_eof() {
980 match &self.peek().kind {
981 TokenKind::Punct(Punct::LBrace | Punct::LParen | Punct::LBracket) => {
982 depth += 1;
983 self.advance();
984 }
985 TokenKind::Punct(Punct::RBrace | Punct::RParen | Punct::RBracket) => {
986 let paren = self.at_punct(Punct::RParen) || self.at_punct(Punct::RBracket);
987 depth -= 1;
988 self.advance();
989 if depth <= 0 {
990 if self.eat_punct(Punct::Semi).is_some() {
994 return;
995 }
996 if paren && self.at_punct(Punct::LBrace) {
1002 depth = 0;
1003 continue;
1004 }
1005 return;
1006 }
1007 }
1008 TokenKind::Punct(Punct::Semi) => {
1009 self.advance();
1010 if depth <= 0 {
1011 return;
1012 }
1013 }
1014 _ => self.advance(),
1015 }
1016 }
1017 }
1018
1019 fn parse_external_decl(&mut self) -> PResult<ExternalDecl> {
1020 let start = self.cur_range();
1021 self.in_extension = false;
1027 while self.eat_keyword(Keyword::Extension).is_some() {
1028 self.in_extension = true;
1029 }
1030 let attrs = self.parse_attributes()?;
1031 if self.at_static_assert() {
1032 return Ok(ExternalDecl::StaticAssert(self.parse_static_assert()?));
1033 }
1034 let mut specs = self.parse_decl_specifiers(true)?;
1035 specs.attrs.merge(attrs);
1036 specs.noreturn = specs.noreturn.or(specs.attrs.noreturn);
1037
1038 if let Some(semi) = self.eat_punct(Punct::Semi) {
1039 return Ok(ExternalDecl::Decl(Decl {
1040 specifiers: specs,
1041 declarators: Vec::new(),
1042 range: start.join(semi),
1043 }));
1044 }
1045
1046 let mut first = self.parse_declarator(specs.base.clone(), false)?;
1047 self.parse_declarator_tail(&mut first)?;
1048
1049 let looks_like_definition = matches!(first.ty.kind, TypeKind::Function(_))
1050 && (self.at_punct(Punct::LBrace) || self.starts_declaration());
1051 if looks_like_definition && !specs.is_typedef() {
1052 return self.finish_function_def(specs, first, start);
1053 }
1054
1055 let decl = self.finish_declaration(specs, Some(first), start)?;
1056 Ok(ExternalDecl::Decl(decl))
1057 }
1058
1059 fn parse_declarator_tail(&mut self, declarator: &mut DeclaratorResult) -> PResult<()> {
1062 loop {
1063 if self.at_keyword(Keyword::Asm) {
1064 let start = self.cur_range();
1065 self.advance();
1066 self.expect_punct(Punct::LParen, " after 'asm'")?;
1067 let range = self.cur_range();
1068 let TokenKind::Str(lit) = self.peek().kind.clone() else {
1069 let found = self.describe_cur();
1070 return Err(self.error_bail(
1071 range,
1072 format!("expected the symbol name as a string literal, found {found}"),
1073 ));
1074 };
1075 let literal = self.parse_string_literal(lit, range);
1076 self.expect_punct(Punct::RParen, " after the symbol name")?;
1077 if let ExprKind::Str(lit) = literal.kind
1078 && let Ok(name) =
1079 String::from_utf8(lit.values.iter().map(|v| *v as u8).collect())
1080 {
1081 declarator.asm_label = Some(Spanned::new(name, self.span_to_here(start)));
1082 }
1083 continue;
1084 }
1085 if self.at_attributes() {
1086 let attrs = self.parse_attributes()?;
1087 declarator.attrs.merge(attrs);
1088 continue;
1089 }
1090 return Ok(());
1091 }
1092 }
1093
1094 fn parse_kr_declaration_list(&mut self) -> PResult<Vec<Decl>> {
1103 let mut decls = Vec::new();
1104 loop {
1105 if self.at_static_assert() {
1106 let range = self.cur_range();
1107 self.error(
1108 range,
1109 "a static assertion is not allowed in the declaration list of an old-style \
1110 function definition; every declaration there has to declare one of the \
1111 parameters (C99 6.9.1p6)",
1112 );
1113 self.parse_static_assert()?;
1114 continue;
1115 }
1116 if !self.starts_declaration() {
1117 return Ok(decls);
1118 }
1119 decls.push(self.parse_declaration()?);
1120 }
1121 }
1122
1123 fn finish_function_def(
1124 &mut self,
1125 specs: DeclSpecifiers,
1126 declarator: DeclaratorResult,
1127 start: SourceRange,
1128 ) -> PResult<ExternalDecl> {
1129 let Some(name) = declarator.name.clone() else {
1130 return Err(self.error_bail(declarator.range, "function definition requires a name"));
1131 };
1132 self.declare(&name.name, SymKind::Ordinary);
1133
1134 self.push_scope();
1137 if let TypeKind::Function(ft) = &declarator.ty.kind {
1138 for param in &ft.params {
1139 if let Some(pname) = ¶m.name {
1140 self.scopes
1141 .last_mut()
1142 .expect("scope stack is never empty")
1143 .syms
1144 .insert(pname.name.clone(), SymKind::Ordinary);
1145 }
1146 }
1147 for kr in &ft.kr_names {
1148 self.scopes
1149 .last_mut()
1150 .expect("scope stack is never empty")
1151 .syms
1152 .insert(kr.name.clone(), SymKind::Ordinary);
1153 }
1154 }
1155
1156 let kr_decls = match self.parse_kr_declaration_list() {
1157 Ok(decls) => decls,
1158 Err(bail) => {
1159 self.pop_scope();
1160 return Err(bail);
1161 }
1162 };
1163
1164 let before = self.label_addrs;
1165 let body = match self.parse_compound_stmt() {
1166 Ok(body) => body,
1167 Err(bail) => {
1168 self.pop_scope();
1169 return Err(bail);
1170 }
1171 };
1172 self.pop_scope();
1173
1174 let mut attrs = declarator.attrs;
1175 if attrs.target.is_empty() && specs.attrs.target.is_empty() && !self.targets.is_empty() {
1184 for (feature, range) in self.targets.at(self.decl_start) {
1185 attrs.target.push(Spanned::new(feature.clone(), *range));
1186 }
1187 }
1188 Ok(ExternalDecl::Function(FunctionDef {
1189 specifiers: specs,
1190 name,
1191 ty: declarator.ty,
1192 kr_decls,
1193 attrs,
1194 asm_label: declarator.asm_label,
1195 body,
1196 uses_label_addrs: self.label_addrs != before,
1197 range: self.span_to_here(start),
1198 }))
1199 }
1200
1201 fn finish_declaration(
1203 &mut self,
1204 specs: DeclSpecifiers,
1205 first: Option<DeclaratorResult>,
1206 start: SourceRange,
1207 ) -> PResult<Decl> {
1208 let is_typedef = specs.is_typedef();
1209 let mut declarators = Vec::new();
1210 let mut pending = first;
1211 loop {
1212 let mut declarator = match pending.take() {
1213 Some(d) => d,
1214 None => {
1215 let mut d = self.parse_declarator(specs.base.clone(), false)?;
1216 self.parse_declarator_tail(&mut d)?;
1217 d
1218 }
1219 };
1220 if let Some(name) = &declarator.name {
1221 let kind = if is_typedef {
1222 SymKind::Typedef
1223 } else {
1224 SymKind::Ordinary
1225 };
1226 self.declare(&name.name.clone(), kind);
1227 }
1228 let init = if self.eat_punct(Punct::Assign).is_some() {
1229 Some(self.parse_initializer()?)
1230 } else {
1231 None
1232 };
1233 if self.at_attributes() {
1235 let attrs = self.parse_attributes()?;
1236 declarator.attrs.merge(attrs);
1237 }
1238 let range = self.span_to_here(declarator.range);
1239 declarators.push(InitDeclarator {
1240 name: declarator.name,
1241 ty: declarator.ty,
1242 init,
1243 attrs: declarator.attrs,
1244 asm_label: declarator.asm_label,
1245 range,
1246 });
1247 if self.eat_punct(Punct::Comma).is_none() {
1248 break;
1249 }
1250 }
1251 let semi = self.expect_punct(Punct::Semi, " after declaration")?;
1252 Ok(Decl {
1253 specifiers: specs,
1254 declarators,
1255 range: start.join(semi),
1256 })
1257 }
1258
1259 fn parse_declaration(&mut self) -> PResult<Decl> {
1268 let enclosing = std::mem::take(&mut self.in_extension);
1273 let result = self.parse_declaration_inner();
1274 self.in_extension = enclosing;
1275 result
1276 }
1277
1278 fn parse_declaration_inner(&mut self) -> PResult<Decl> {
1279 let (specs, start) = self.parse_declaration_head()?;
1280 if let Some(semi) = self.eat_punct(Punct::Semi) {
1281 return Ok(Decl {
1282 specifiers: specs,
1283 declarators: Vec::new(),
1284 range: start.join(semi),
1285 });
1286 }
1287 self.finish_declaration(specs, None, start)
1288 }
1289
1290 fn parse_declaration_head(&mut self) -> PResult<(DeclSpecifiers, SourceRange)> {
1294 let start = self.cur_range();
1295 while self.eat_keyword(Keyword::Extension).is_some() {
1296 self.in_extension = true;
1297 }
1298 let attrs = self.parse_attributes()?;
1299 let mut specs = self.parse_decl_specifiers(true)?;
1300 specs.attrs.merge(attrs);
1301 specs.noreturn = specs.noreturn.or(specs.attrs.noreturn);
1302 Ok((specs, start))
1303 }
1304
1305 fn parse_block_declaration(&mut self) -> PResult<BlockItem> {
1311 let enclosing = std::mem::take(&mut self.in_extension);
1312 let result = self.parse_block_declaration_inner();
1313 self.in_extension = enclosing;
1314 result
1315 }
1316
1317 fn parse_block_declaration_inner(&mut self) -> PResult<BlockItem> {
1318 let (specs, start) = self.parse_declaration_head()?;
1319 if let Some(semi) = self.eat_punct(Punct::Semi) {
1320 return Ok(BlockItem::Decl(Decl {
1321 specifiers: specs,
1322 declarators: Vec::new(),
1323 range: start.join(semi),
1324 }));
1325 }
1326 let mut first = self.parse_declarator(specs.base.clone(), false)?;
1330 self.parse_declarator_tail(&mut first)?;
1331 if self.at_nested_function_body(&specs, &first) {
1332 return self
1333 .parse_nested_function(specs, first, start)
1334 .map(BlockItem::NestedFunction);
1335 }
1336 self.finish_declaration(specs, Some(first), start)
1337 .map(BlockItem::Decl)
1338 }
1339
1340 fn at_nested_function_body(
1349 &self,
1350 specs: &DeclSpecifiers,
1351 declarator: &DeclaratorResult,
1352 ) -> bool {
1353 declarator.name.is_some()
1354 && !specs.is_typedef()
1355 && matches!(declarator.ty.kind, TypeKind::Function(_))
1356 && (self.at_punct(Punct::LBrace) || self.at_kr_declaration_list())
1357 }
1358
1359 fn at_kr_declaration_list(&self) -> bool {
1366 let mut n = 0;
1367 while self.starts_decl_specifier(n) {
1368 let mut depth = 0i32;
1369 loop {
1370 let tok = self.nth(n);
1371 if tok.is_eof() {
1372 return false;
1373 }
1374 n += 1;
1375 match &tok.kind {
1376 TokenKind::Punct(Punct::LBrace | Punct::LParen | Punct::LBracket) => depth += 1,
1377 TokenKind::Punct(Punct::RBrace | Punct::RParen | Punct::RBracket) => {
1378 depth -= 1;
1379 if depth < 0 {
1380 return false;
1381 }
1382 }
1383 TokenKind::Punct(Punct::Semi) if depth == 0 => break,
1384 _ => {}
1385 }
1386 }
1387 }
1388 n > 0 && self.nth(n).is_punct(Punct::LBrace)
1389 }
1390
1391 fn parse_nested_function(
1401 &mut self,
1402 specs: DeclSpecifiers,
1403 declarator: DeclaratorResult,
1404 start: SourceRange,
1405 ) -> PResult<FunctionDef> {
1406 let name = declarator
1407 .name
1408 .clone()
1409 .expect("at_nested_function_body requires a name");
1410 self.declare(&name.name, SymKind::Ordinary);
1411
1412 self.push_scope();
1415 if let TypeKind::Function(ft) = &declarator.ty.kind {
1416 for param in &ft.params {
1417 if let Some(pname) = ¶m.name {
1418 self.scopes
1419 .last_mut()
1420 .expect("scope stack is never empty")
1421 .syms
1422 .insert(pname.name.clone(), SymKind::Ordinary);
1423 }
1424 }
1425 for kr in &ft.kr_names {
1426 self.scopes
1427 .last_mut()
1428 .expect("scope stack is never empty")
1429 .syms
1430 .insert(kr.name.clone(), SymKind::Ordinary);
1431 }
1432 }
1433
1434 let kr_decls = match self.parse_kr_declaration_list() {
1435 Ok(decls) => decls,
1436 Err(bail) => {
1437 self.pop_scope();
1438 return Err(bail);
1439 }
1440 };
1441
1442 let before = self.label_addrs;
1443 let body = match self.parse_compound_stmt() {
1444 Ok(body) => body,
1445 Err(bail) => {
1446 self.pop_scope();
1447 return Err(bail);
1448 }
1449 };
1450 self.pop_scope();
1451 let uses_label_addrs = self.label_addrs != before;
1452 self.label_addrs = before;
1455
1456 Ok(FunctionDef {
1457 specifiers: specs,
1458 name,
1459 ty: declarator.ty,
1460 kr_decls,
1461 attrs: declarator.attrs,
1462 asm_label: declarator.asm_label,
1463 body,
1464 uses_label_addrs,
1465 range: self.span_to_here(start),
1466 })
1467 }
1468}
1469
1470#[derive(Default)]
1476struct SpecCounts {
1477 void: u32,
1478 char: u32,
1479 short: u32,
1480 int: u32,
1481 long: u32,
1482 float: u32,
1483 double: u32,
1484 signed: u32,
1485 unsigned: u32,
1486 bool: u32,
1487 complex: u32,
1488 imaginary: u32,
1489 int128: u32,
1490 floatn: u32,
1493 floatn_size: Option<FloatSize>,
1494}
1495
1496impl SpecCounts {
1497 fn any(&self) -> bool {
1498 self.void
1499 + self.char
1500 + self.short
1501 + self.int
1502 + self.long
1503 + self.float
1504 + self.double
1505 + self.signed
1506 + self.unsigned
1507 + self.bool
1508 + self.complex
1509 + self.imaginary
1510 + self.int128
1511 + self.floatn
1512 > 0
1513 }
1514}
1515
1516impl Parser<'_> {
1517 fn starts_declaration(&self) -> bool {
1519 self.starts_decl_specifier(0)
1520 }
1521
1522 fn starts_declarator(&self) -> bool {
1528 let tok = self.peek();
1529 tok.ident().is_some() || tok.is_punct(Punct::Star) || tok.is_punct(Punct::LParen)
1530 }
1531
1532 fn starts_decl_specifier(&self, n: usize) -> bool {
1535 let tok = self.nth(n);
1536 if let Some(k) = tok.keyword() {
1537 return matches!(
1538 k,
1539 Keyword::Typedef
1540 | Keyword::Extern
1541 | Keyword::Static
1542 | Keyword::Auto
1543 | Keyword::Register
1544 | Keyword::Const
1545 | Keyword::Volatile
1546 | Keyword::Restrict
1547 | Keyword::Inline
1548 | Keyword::Void
1549 | Keyword::Char
1550 | Keyword::Short
1551 | Keyword::Int
1552 | Keyword::Long
1553 | Keyword::Float
1554 | Keyword::Double
1555 | Keyword::Signed
1556 | Keyword::Unsigned
1557 | Keyword::Bool
1558 | Keyword::Complex
1559 | Keyword::Imaginary
1560 | Keyword::Struct
1561 | Keyword::Union
1562 | Keyword::Enum
1563 | Keyword::Alignas
1564 | Keyword::AlignasName
1565 | Keyword::Atomic
1566 | Keyword::BitInt
1567 | Keyword::Noreturn
1568 | Keyword::ThreadLocal
1569 | Keyword::ThreadLocalName
1570 | Keyword::Constexpr
1571 | Keyword::Typeof
1572 | Keyword::TypeofUnqual
1573 | Keyword::BoolName
1574 | Keyword::Attribute
1575 | Keyword::Extension
1576 | Keyword::TypeofGnu
1577 | Keyword::TypeofUnqualGnu
1578 | Keyword::AutoType
1579 | Keyword::ThreadGnu
1580 | Keyword::Int128
1581 | Keyword::InlineGnu
1582 | Keyword::RestrictGnu
1583 );
1584 }
1585 match tok.ident() {
1586 Some(NORETURN_BUILTIN) => true,
1587 Some(name) if floatn_type(name).is_some() && !self.is_typedef_name(name) => true,
1588 Some(name) => self.is_typedef_name(name) && !self.nth(n + 1).is_punct(Punct::Colon),
1591 None => false,
1592 }
1593 }
1594
1595 fn eat_type_qualifier(&mut self) -> Option<TypeQualifiers> {
1596 let keyword = self.peek().keyword()?;
1597 let q = match keyword {
1598 Keyword::Const => TypeQualifiers {
1599 is_const: true,
1600 ..TypeQualifiers::NONE
1601 },
1602 Keyword::Volatile => TypeQualifiers {
1603 is_volatile: true,
1604 ..TypeQualifiers::NONE
1605 },
1606 Keyword::Restrict | Keyword::RestrictGnu => TypeQualifiers {
1607 is_restrict: true,
1608 ..TypeQualifiers::NONE
1609 },
1610 Keyword::Atomic if !self.at_atomic_specifier(0) => TypeQualifiers {
1614 is_atomic: true,
1615 ..TypeQualifiers::NONE
1616 },
1617 _ => return None,
1618 };
1619 if keyword == Keyword::Restrict {
1622 let range = self.cur_range();
1623 self.require_standard(Standard::C99, "'restrict'", range);
1624 }
1625 if keyword == Keyword::Atomic {
1626 let range = self.cur_range();
1627 self.require_keyword(Keyword::Atomic, range);
1628 }
1629 self.advance();
1630 Some(q)
1631 }
1632
1633 fn at_atomic_specifier(&self, n: usize) -> bool {
1640 self.nth(n).is_keyword(Keyword::Atomic)
1641 && self.nth(n + 1).is_punct(Punct::LParen)
1642 && self.starts_decl_specifier(n + 2)
1643 }
1644
1645 fn parse_type_qualifiers(&mut self) -> TypeQualifiers {
1646 let mut quals = TypeQualifiers::NONE;
1647 while let Some(q) = self.eat_type_qualifier() {
1648 quals = quals.merge(q);
1649 }
1650 quals
1651 }
1652
1653 fn parse_decl_specifiers(&mut self, allow_storage: bool) -> PResult<DeclSpecifiers> {
1656 let start = self.cur_range();
1657 let mut storage: Option<Spanned<StorageClass>> = None;
1658 let mut thread_local: Option<SourceRange> = None;
1659 let mut inline = false;
1660 let mut noreturn: Option<SourceRange> = None;
1661 let mut alignas: Vec<Alignment> = Vec::new();
1662 let mut attributes = Attributes::default();
1663 let mut quals = TypeQualifiers::NONE;
1664 let mut counts = SpecCounts::default();
1665 let mut tag: Option<Type> = None;
1666 let mut typedef_name: Option<Ident> = None;
1667 let mut auto_type: Option<SourceRange> = None;
1668 let mut auto_kw: Option<SourceRange> = None;
1672 let mut consumed_any = false;
1673
1674 loop {
1675 let has_type = counts.any() || tag.is_some() || typedef_name.is_some();
1676 if self.at_attributes() {
1679 let attrs = self.parse_attributes()?;
1680 noreturn = noreturn.or(attrs.noreturn);
1681 attributes.merge(attrs);
1682 consumed_any = true;
1683 continue;
1684 }
1685 if self.at_keyword(Keyword::Extension) {
1686 self.advance();
1687 self.in_extension = true;
1688 consumed_any = true;
1689 continue;
1690 }
1691 if let Some(k) = self.peek().keyword() {
1692 if matches!(
1696 k,
1697 Keyword::ThreadLocal | Keyword::ThreadLocalName | Keyword::ThreadGnu
1698 ) {
1699 let range = self.bump_range();
1700 self.require_keyword(k, range);
1701 consumed_any = true;
1702 if !allow_storage {
1703 self.error(
1704 range,
1705 format!("storage class '{}' is not allowed here", k.as_str()),
1706 );
1707 } else if thread_local.is_none() {
1708 thread_local = Some(range);
1709 }
1710 continue;
1711 }
1712 let storage_class = match k {
1713 Keyword::Typedef => Some(StorageClass::Typedef),
1714 Keyword::Extern => Some(StorageClass::Extern),
1715 Keyword::Static => Some(StorageClass::Static),
1716 Keyword::Auto => Some(StorageClass::Auto),
1717 Keyword::Register => Some(StorageClass::Register),
1718 Keyword::Constexpr => Some(StorageClass::Constexpr),
1719 _ => None,
1720 };
1721 if let Some(sc) = storage_class {
1722 let range = self.bump_range();
1723 self.require_keyword(k, range);
1724 consumed_any = true;
1725 let c23_auto = allow_storage
1737 && self.standard >= Standard::C23
1738 && (sc == StorageClass::Auto
1739 || matches!(
1740 storage,
1741 Some(Spanned {
1742 node: StorageClass::Auto,
1743 ..
1744 })
1745 ))
1746 && sc != StorageClass::Typedef
1747 && !matches!(
1748 storage,
1749 Some(Spanned {
1750 node: StorageClass::Typedef,
1751 ..
1752 })
1753 );
1754 let pairs_with_constexpr = |s: StorageClass| {
1764 matches!(
1765 s,
1766 StorageClass::Static | StorageClass::Register | StorageClass::Auto
1767 )
1768 };
1769 let c23_constexpr = allow_storage
1770 && self.standard >= Standard::C23
1771 && match (sc, storage.as_ref().map(|s| s.node)) {
1772 (StorageClass::Constexpr, Some(prev)) => pairs_with_constexpr(prev),
1773 (other, Some(StorageClass::Constexpr)) => pairs_with_constexpr(other),
1774 _ => false,
1775 };
1776 if sc == StorageClass::Auto {
1777 auto_kw = auto_kw.or(Some(range));
1778 }
1779 if !allow_storage {
1780 self.error(
1781 range,
1782 format!("storage class '{}' is not allowed here", sc.as_str()),
1783 );
1784 } else if c23_constexpr {
1785 if sc == StorageClass::Constexpr {
1786 storage = Some(Spanned::new(sc, range));
1787 }
1788 } else if c23_auto {
1789 if sc != StorageClass::Auto || storage.is_none() {
1795 storage = Some(Spanned::new(sc, range));
1796 }
1797 } else if let Some(prev) = &storage {
1798 self.error(
1799 range,
1800 format!(
1801 "cannot combine storage class '{}' with '{}'",
1802 sc.as_str(),
1803 prev.node.as_str()
1804 ),
1805 );
1806 } else {
1807 storage = Some(Spanned::new(sc, range));
1808 }
1809 continue;
1810 }
1811 if let Some(q) = self.eat_type_qualifier() {
1812 quals = quals.merge(q);
1813 consumed_any = true;
1814 continue;
1815 }
1816 if matches!(k, Keyword::Inline | Keyword::InlineGnu) {
1817 let range = self.bump_range();
1818 if k == Keyword::Inline {
1821 self.require_standard(Standard::C99, "'inline'", range);
1822 }
1823 inline = true;
1824 consumed_any = true;
1825 continue;
1826 }
1827 if k == Keyword::Noreturn {
1828 let range = self.bump_range();
1829 self.require_keyword(k, range);
1830 noreturn = noreturn.or(Some(range));
1831 consumed_any = true;
1832 continue;
1833 }
1834 if matches!(k, Keyword::Alignas | Keyword::AlignasName) {
1835 let spec = self.parse_alignment_specifier(k)?;
1839 alignas.push(spec);
1840 consumed_any = true;
1841 continue;
1842 }
1843 if k == Keyword::AutoType {
1846 let range = self.bump_range();
1847 auto_type = auto_type.or(Some(range));
1848 consumed_any = true;
1849 continue;
1850 }
1851 if matches!(
1852 k,
1853 Keyword::Typeof
1854 | Keyword::TypeofUnqual
1855 | Keyword::TypeofGnu
1856 | Keyword::TypeofUnqualGnu
1857 ) {
1858 let ty = self.parse_typeof_specifier(k)?;
1859 if tag.is_some() || has_type {
1860 self.error(ty.range, "two or more data types in declaration specifiers");
1861 } else {
1862 tag = Some(ty);
1863 }
1864 consumed_any = true;
1865 continue;
1866 }
1867 if k == Keyword::Atomic {
1871 let range = self.bump_range();
1872 self.require_keyword(k, range);
1873 self.expect_punct(Punct::LParen, " after '_Atomic'")?;
1874 let inner = self.parse_type_name()?;
1875 self.expect_punct(Punct::RParen, " after the type name")?;
1876 if tag.is_some() || has_type {
1877 self.error(range, "two or more data types in declaration specifiers");
1878 } else {
1879 tag = Some(inner.ty);
1880 }
1881 quals = quals.merge(TypeQualifiers {
1882 is_atomic: true,
1883 ..TypeQualifiers::NONE
1884 });
1885 consumed_any = true;
1886 continue;
1887 }
1888 if k == Keyword::BitInt {
1891 let range = self.bump_range();
1892 self.error(range, format!("'{}' is not supported yet", k.as_str()));
1893 if self.at_punct(Punct::LParen) {
1894 self.advance();
1895 let _ = self.parse_conditional_expr()?;
1896 self.expect_punct(Punct::RParen, " after the operand")?;
1897 }
1898 counts.int += 1;
1901 consumed_any = true;
1902 continue;
1903 }
1904 let counter = match k {
1905 Keyword::Void => Some(&mut counts.void),
1906 Keyword::Char => Some(&mut counts.char),
1907 Keyword::Short => Some(&mut counts.short),
1908 Keyword::Int => Some(&mut counts.int),
1909 Keyword::Long => Some(&mut counts.long),
1910 Keyword::Float => Some(&mut counts.float),
1911 Keyword::Double => Some(&mut counts.double),
1912 Keyword::Signed => Some(&mut counts.signed),
1913 Keyword::Unsigned => Some(&mut counts.unsigned),
1914 Keyword::Bool | Keyword::BoolName => Some(&mut counts.bool),
1915 Keyword::Complex => Some(&mut counts.complex),
1916 Keyword::Imaginary => Some(&mut counts.imaginary),
1917 Keyword::Int128 => Some(&mut counts.int128),
1918 _ => None,
1919 };
1920 if let Some(c) = counter {
1921 *c += 1;
1922 self.advance();
1923 consumed_any = true;
1924 continue;
1925 }
1926 if matches!(k, Keyword::Struct | Keyword::Union) {
1927 let ty = self.parse_record_specifier()?;
1928 if tag.is_some() || has_type {
1929 self.error(ty.range, "two or more data types in declaration specifiers");
1930 } else {
1931 tag = Some(ty);
1932 }
1933 consumed_any = true;
1934 continue;
1935 }
1936 if k == Keyword::Enum {
1937 let ty = self.parse_enum_specifier()?;
1938 if tag.is_some() || has_type {
1939 self.error(ty.range, "two or more data types in declaration specifiers");
1940 } else {
1941 tag = Some(ty);
1942 }
1943 consumed_any = true;
1944 continue;
1945 }
1946 break;
1947 }
1948
1949 if self.peek().ident() == Some(NORETURN_BUILTIN) {
1954 let range = self.bump_range();
1955 noreturn = noreturn.or(Some(range));
1956 consumed_any = true;
1957 continue;
1958 }
1959
1960 if tag.is_none()
1970 && typedef_name.is_none()
1971 && !counts.any_besides(&["_Complex"])
1972 && let Some(name) = self.peek().ident()
1973 && !self.is_typedef_name(name)
1974 && let Some(size) = floatn_type(name)
1975 {
1976 self.advance();
1977 counts.floatn += 1;
1978 counts.floatn_size = Some(size);
1979 consumed_any = true;
1980 continue;
1981 }
1982
1983 if !has_type
1991 && let Some(name) = self.peek().ident()
1992 && !self.is_typedef_name(name)
1993 && let Some(what) = extended_float_type(name)
1994 {
1995 let range = self.cur_range();
1996 return Err(self.error_bail(
1997 range,
1998 format!(
1999 "'{name}' is not supported: {what} has no Rust type to become, and \
2000 mapping it onto 'double' would compute and pass the wrong values"
2001 ),
2002 ));
2003 }
2004
2005 let is_typedef_use = match self.peek().ident() {
2008 Some(name) => !has_type && self.is_typedef_name(name),
2009 None => false,
2010 };
2011 if is_typedef_use {
2012 let id = self.eat_ident().expect("checked above");
2013 typedef_name = Some(id);
2014 consumed_any = true;
2015 continue;
2016 }
2017 break;
2018 }
2019
2020 if !consumed_any {
2021 let range = self.cur_range();
2022 if let Some(message) = self.newer_keyword_here() {
2027 return Err(self.error_bail(range, message));
2028 }
2029 if !self.starts_declarator() {
2037 let found = self.describe_cur();
2038 return Err(
2039 self.error_bail(range, format!("expected a declaration, found {found}"))
2040 );
2041 }
2042 }
2043
2044 let specs_range = if consumed_any {
2048 self.span_to_here(start)
2049 } else {
2050 self.cur_range()
2051 };
2052 let no_type = !counts.any() && tag.is_none() && typedef_name.is_none();
2055 let inferred = no_type
2056 && (auto_type.is_some() || (self.standard >= Standard::C23 && auto_kw.is_some()));
2057 let base = if inferred {
2058 Type::new(TypeKind::Auto, quals, specs_range)
2059 } else {
2060 self.build_base_type(&counts, tag, typedef_name, quals, specs_range)
2061 };
2062 if let Some(aligned) = attributes.aligned.clone() {
2065 alignas.push(aligned);
2066 }
2067
2068 Ok(DeclSpecifiers {
2069 storage,
2070 thread_local,
2071 inline,
2072 noreturn,
2073 alignas,
2074 attrs: attributes,
2075 base,
2076 range: specs_range,
2077 })
2078 }
2079
2080 fn parse_alignment_specifier(&mut self, keyword: Keyword) -> PResult<Alignment> {
2082 let start = self.cur_range();
2083 self.require_keyword(keyword, start);
2084 self.advance();
2085 let name = keyword.as_str();
2086 self.expect_punct(Punct::LParen, &format!(" after '{name}'"))?;
2087 let kind = if self.starts_declaration() {
2088 AlignmentKind::Type(Box::new(self.parse_type_name()?))
2089 } else {
2090 AlignmentKind::Expr(self.parse_conditional_expr()?)
2091 };
2092 self.expect_punct(Punct::RParen, &format!(" after the operand of '{name}'"))?;
2093 Ok(Alignment {
2094 kind,
2095 from_attribute: false,
2096 range: self.span_to_here(start),
2097 })
2098 }
2099
2100 fn parse_typeof_specifier(&mut self, keyword: Keyword) -> PResult<Type> {
2108 let start = self.cur_range();
2109 self.require_keyword(keyword, start);
2110 self.advance();
2111 let name = keyword.as_str();
2112 self.expect_punct(Punct::LParen, &format!(" after '{name}'"))?;
2113 let operand = if self.starts_declaration() {
2114 TypeofOperand::Type(self.parse_type_name()?)
2115 } else {
2116 TypeofOperand::Expr(self.parse_expr()?)
2117 };
2118 self.expect_punct(Punct::RParen, &format!(" after the operand of '{name}'"))?;
2119 let range = self.span_to_here(start);
2120 let id = self.add_typeof(operand);
2121 let unqual = matches!(keyword, Keyword::TypeofUnqual | Keyword::TypeofUnqualGnu);
2122 Ok(Type::plain(TypeKind::Typeof { id, unqual }, range))
2123 }
2124
2125 fn build_base_type(
2126 &mut self,
2127 counts: &SpecCounts,
2128 tag: Option<Type>,
2129 typedef_name: Option<Ident>,
2130 quals: TypeQualifiers,
2131 range: SourceRange,
2132 ) -> Type {
2133 if let Some(mut ty) = tag {
2134 if counts.any() || typedef_name.is_some() {
2135 self.error(range, "two or more data types in declaration specifiers");
2136 }
2137 ty.qualifiers = ty.qualifiers.merge(quals);
2138 return ty;
2139 }
2140 if let Some(name) = typedef_name {
2141 if counts.any() {
2142 self.error(range, "two or more data types in declaration specifiers");
2143 }
2144 return Type::new(TypeKind::Typedef(name), quals, range);
2145 }
2146 if !counts.any() {
2147 if !self.gating.implicit_int() {
2152 self.error(
2153 range,
2154 "type specifier missing; C99 does not support implicit 'int'",
2155 );
2156 }
2157 return Type::new(
2158 TypeKind::Int {
2159 sign: Sign::Signed,
2160 size: IntSize::Int,
2161 },
2162 quals,
2163 range,
2164 );
2165 }
2166 if counts.bool > 0 {
2167 self.require_standard(Standard::C99, "'_Bool'", range);
2168 }
2169 if counts.complex > 0 {
2170 self.require_standard(Standard::C99, "'_Complex'", range);
2171 }
2172 if counts.imaginary > 0 {
2173 self.require_standard(Standard::C99, "'_Imaginary'", range);
2174 }
2175 if counts.long > 1 {
2176 self.require_standard(Standard::C99, "'long long'", range);
2177 }
2178 if (counts.complex > 0 || counts.imaginary > 0)
2184 && counts.float == 0
2185 && counts.double == 0
2186 && counts.int
2187 + counts.char
2188 + counts.short
2189 + counts.long
2190 + counts.signed
2191 + counts.unsigned
2192 + counts.int128
2193 + counts.bool
2194 + counts.void
2195 > 0
2196 {
2197 self.error(
2198 range,
2199 "a complex integer type is a GNU extension that cinrs does not support; \
2200 the complex types are 'float _Complex', 'double _Complex' and \
2201 'long double _Complex'",
2202 );
2203 let kind = if counts.complex > 0 {
2204 TypeKind::Complex(FloatSize::Double)
2205 } else {
2206 TypeKind::Imaginary(FloatSize::Double)
2207 };
2208 return Type::new(kind, quals, range);
2209 }
2210
2211 let sign = if counts.unsigned > 0 {
2212 Some(Sign::Unsigned)
2213 } else if counts.signed > 0 {
2214 Some(Sign::Signed)
2215 } else {
2216 None
2217 };
2218 if counts.signed > 0 && counts.unsigned > 0 {
2219 self.error(range, "cannot combine 'signed' with 'unsigned'");
2220 }
2221
2222 let kind = if counts.void > 0 {
2223 if counts.void > 1 || counts.any_besides(&["void"]) {
2224 self.error(range, "cannot combine 'void' with other type specifiers");
2225 }
2226 TypeKind::Void
2227 } else if counts.bool > 0 {
2228 if counts.any_besides(&["_Bool"]) {
2229 self.error(range, "cannot combine '_Bool' with other type specifiers");
2230 }
2231 TypeKind::Bool
2232 } else if counts.char > 0 {
2233 if counts.any_besides(&["char", "signed", "unsigned"]) {
2234 self.error(range, "cannot combine 'char' with other type specifiers");
2235 }
2236 TypeKind::Char(sign)
2237 } else if counts.floatn > 0 {
2238 let size = counts.floatn_size.expect("set with the count");
2239 if counts.floatn > 1 || counts.any_besides(&["_FloatN", "_Complex"]) {
2240 self.error(
2241 range,
2242 format!(
2243 "cannot combine '{}' with other type specifiers",
2244 size.as_str()
2245 ),
2246 );
2247 }
2248 if counts.complex > 0 {
2249 TypeKind::Complex(size)
2250 } else {
2251 TypeKind::Float(size)
2252 }
2253 } else if counts.float > 0 || counts.double > 0 {
2254 let size = if counts.float > 0 {
2255 if counts.double > 0 {
2256 self.error(range, "cannot combine 'float' with 'double'");
2257 }
2258 if counts.long > 0 {
2259 self.error(range, "cannot combine 'long' with 'float'");
2260 }
2261 FloatSize::Float
2262 } else if counts.long > 0 {
2263 FloatSize::LongDouble
2264 } else {
2265 FloatSize::Double
2266 };
2267 if sign.is_some() {
2268 self.error(
2269 range,
2270 "cannot combine 'signed' or 'unsigned' with a floating type",
2271 );
2272 }
2273 if counts.complex > 0 {
2274 TypeKind::Complex(size)
2275 } else if counts.imaginary > 0 {
2276 TypeKind::Imaginary(size)
2277 } else {
2278 TypeKind::Float(size)
2279 }
2280 } else if counts.complex > 0 || counts.imaginary > 0 {
2281 if counts.complex > 0 {
2285 TypeKind::Complex(FloatSize::Double)
2286 } else {
2287 TypeKind::Imaginary(FloatSize::Double)
2288 }
2289 } else if counts.int128 > 0 {
2290 if counts.int128 > 1 || counts.any_besides(&["__int128", "signed", "unsigned"]) {
2293 self.error(
2294 range,
2295 "cannot combine '__int128' with other type specifiers",
2296 );
2297 }
2298 TypeKind::Int {
2299 sign: sign.unwrap_or(Sign::Signed),
2300 size: IntSize::Int128,
2301 }
2302 } else {
2303 let size = if counts.short > 0 {
2304 if counts.long > 0 {
2305 self.error(range, "cannot combine 'short' with 'long'");
2306 }
2307 IntSize::Short
2308 } else {
2309 match counts.long {
2310 0 => IntSize::Int,
2311 1 => IntSize::Long,
2312 2 => IntSize::LongLong,
2313 _ => {
2314 self.error(range, "'long long long' is too long for cinrs");
2315 IntSize::LongLong
2316 }
2317 }
2318 };
2319 TypeKind::Int {
2320 sign: sign.unwrap_or(Sign::Signed),
2321 size,
2322 }
2323 };
2324
2325 Type::new(kind, quals, range)
2326 }
2327}
2328
2329impl SpecCounts {
2330 fn any_besides(&self, allowed: &[&str]) -> bool {
2332 let all: [(&str, u32); 14] = [
2333 ("__int128", self.int128),
2334 ("_FloatN", self.floatn),
2335 ("void", self.void),
2336 ("char", self.char),
2337 ("short", self.short),
2338 ("int", self.int),
2339 ("long", self.long),
2340 ("float", self.float),
2341 ("double", self.double),
2342 ("signed", self.signed),
2343 ("unsigned", self.unsigned),
2344 ("_Bool", self.bool),
2345 ("_Complex", self.complex),
2346 ("_Imaginary", self.imaginary),
2347 ];
2348 all.iter()
2349 .any(|(name, count)| *count > 0 && !allowed.contains(name))
2350 }
2351}
2352
2353impl Parser<'_> {
2358 fn add_record(&mut self, spec: RecordSpec) -> RecordSpecId {
2360 let id = RecordSpecId(self.records.len() as u32);
2361 self.records.push(spec);
2362 id
2363 }
2364
2365 fn add_enum(&mut self, spec: EnumSpec) -> EnumSpecId {
2367 let id = EnumSpecId(self.enums.len() as u32);
2368 self.enums.push(spec);
2369 id
2370 }
2371
2372 fn add_typeof(&mut self, operand: TypeofOperand) -> TypeofId {
2374 let id = TypeofId(self.typeofs.len() as u32);
2375 self.typeofs.push(operand);
2376 id
2377 }
2378
2379 fn parse_record_specifier(&mut self) -> PResult<Type> {
2385 self.enter()?;
2386 let result = self.parse_record_specifier_inner();
2387 self.leave();
2388 result
2389 }
2390
2391 fn parse_record_specifier_inner(&mut self) -> PResult<Type> {
2392 let start = self.cur_range();
2393 let pack = self.packing.at(self.pos);
2396 let kind = match self.peek().keyword() {
2397 Some(Keyword::Struct) => RecordKind::Struct,
2398 Some(Keyword::Union) => RecordKind::Union,
2399 _ => unreachable!("caller checked the keyword"),
2400 };
2401 self.advance();
2402 let mut attrs = self.parse_attributes()?;
2403 let name = self.eat_ident();
2404 let mut asserts = Vec::new();
2405 let fields = if self.at_punct(Punct::LBrace) {
2406 let (fields, found) = self.parse_struct_body()?;
2407 asserts = found;
2408 Some(fields)
2409 } else {
2410 if name.is_none() {
2411 let range = self.cur_range();
2412 let found = self.describe_cur();
2413 return Err(self.error_bail(
2414 range,
2415 format!(
2416 "expected identifier or '{{' after '{}', found {found}",
2417 kind.as_str()
2418 ),
2419 ));
2420 }
2421 None
2422 };
2423 if self.at_attributes() {
2426 let after = self.parse_attributes()?;
2427 attrs.merge(after);
2428 }
2429 let range = self.span_to_here(start);
2430 let id = self.add_record(RecordSpec {
2431 kind,
2432 name,
2433 fields,
2434 asserts,
2435 attrs,
2436 pack,
2437 range,
2438 });
2439 Ok(Type::plain(TypeKind::Record(id), range))
2440 }
2441
2442 fn parse_struct_body(&mut self) -> PResult<(Vec<FieldDecl>, Vec<StaticAssert>)> {
2445 self.expect_punct(Punct::LBrace, " to open a member list")?;
2446 let mut fields = Vec::new();
2447 let mut asserts = Vec::new();
2448 while !self.at_punct(Punct::RBrace) && !self.at_eof() {
2449 let before = self.pos;
2450 if self.eat_punct(Punct::Semi).is_some() {
2452 continue;
2453 }
2454 if self.at_static_assert() {
2455 asserts.push(self.parse_static_assert()?);
2456 continue;
2457 }
2458 let start = self.cur_range();
2459 while self.eat_keyword(Keyword::Extension).is_some() {
2460 self.in_extension = true;
2461 }
2462 let leading = self.parse_attributes()?;
2463 let mut specs = self.parse_decl_specifiers(false)?;
2464 specs.attrs.merge(leading);
2465
2466 if self.at_punct(Punct::Semi) {
2467 let range = self.span_to_here(start);
2469 self.require_standard(Standard::C11, "an anonymous struct or union member", range);
2470 fields.push(FieldDecl {
2471 ty: specs.base.clone(),
2472 attrs: specs.attrs.clone(),
2473 specifiers: specs,
2474 name: None,
2475 bit_width: None,
2476 range,
2477 });
2478 self.expect_punct(Punct::Semi, " after member declaration")?;
2479 continue;
2480 }
2481
2482 loop {
2483 let (name, ty, dstart, mut attrs) = if self.at_punct(Punct::Colon) {
2484 (
2485 None,
2486 specs.base.clone(),
2487 self.cur_range(),
2488 Attributes::default(),
2489 )
2490 } else {
2491 let mut d = self.parse_declarator(specs.base.clone(), true)?;
2492 self.parse_declarator_tail(&mut d)?;
2493 (d.name, d.ty, d.range, d.attrs)
2494 };
2495 let bit_width = if self.eat_punct(Punct::Colon).is_some() {
2496 Some(self.parse_conditional_expr()?)
2497 } else {
2498 None
2499 };
2500 if self.at_attributes() {
2502 let after = self.parse_attributes()?;
2503 attrs.merge(after);
2504 }
2505 attrs.merge(specs.attrs.clone());
2506 let range = self.span_to_here(dstart);
2507 fields.push(FieldDecl {
2508 specifiers: specs.clone(),
2509 name,
2510 ty,
2511 bit_width,
2512 attrs,
2513 range,
2514 });
2515 if self.eat_punct(Punct::Comma).is_none() {
2516 break;
2517 }
2518 }
2519 self.expect_punct(Punct::Semi, " after member declaration")?;
2520 if self.pos == before {
2521 self.advance();
2522 }
2523 }
2524 self.expect_punct(Punct::RBrace, " to close a member list")?;
2525 Ok((fields, asserts))
2526 }
2527
2528 fn parse_enum_specifier(&mut self) -> PResult<Type> {
2529 let start = self.cur_range();
2530 self.advance(); let _ = self.parse_attributes()?;
2533 let name = self.eat_ident();
2534 let underlying = if self.at_punct(Punct::Colon) && self.starts_decl_specifier(1) {
2541 let colon = self.bump_range();
2542 self.require_standard(Standard::C23, "an enum with a fixed underlying type", colon);
2543 let specs = self.parse_decl_specifiers(false)?;
2544 Some(specs.base)
2545 } else {
2546 None
2547 };
2548 let enumerators = if self.at_punct(Punct::LBrace) {
2549 self.advance();
2550 let mut list = Vec::new();
2551 while !self.at_punct(Punct::RBrace) && !self.at_eof() {
2552 let ename = self.expect_ident(" in enumerator list")?;
2553 self.declare(&ename.name.clone(), SymKind::Ordinary);
2554 let _ = self.parse_attributes()?;
2556 let value = if self.eat_punct(Punct::Assign).is_some() {
2557 Some(self.parse_conditional_expr()?)
2558 } else {
2559 None
2560 };
2561 let range = self.span_to_here(ename.range);
2562 list.push(Enumerator {
2563 name: ename,
2564 value,
2565 range,
2566 });
2567 let Some(comma) = self.eat_punct(Punct::Comma) else {
2568 break;
2569 };
2570 if self.at_punct(Punct::RBrace) {
2571 self.require_standard(
2572 Standard::C99,
2573 "a trailing comma in an enumerator list",
2574 comma,
2575 );
2576 }
2577 }
2578 self.expect_punct(Punct::RBrace, " to close an enumerator list")?;
2579 Some(list)
2580 } else {
2581 if name.is_none() {
2582 let range = self.cur_range();
2583 let found = self.describe_cur();
2584 return Err(self.error_bail(
2585 range,
2586 format!("expected identifier or '{{' after 'enum', found {found}"),
2587 ));
2588 }
2589 None
2590 };
2591 let range = self.span_to_here(start);
2592 let id = self.add_enum(EnumSpec {
2593 name,
2594 enumerators,
2595 underlying,
2596 range,
2597 });
2598 Ok(Type::plain(TypeKind::Enum(id), range))
2599 }
2600}
2601
2602#[derive(Clone, Debug)]
2608pub struct DeclaratorResult {
2609 pub name: Option<Ident>,
2611 pub ty: Type,
2613 pub attrs: Attributes,
2615 pub asm_label: Option<Spanned<String>>,
2617 pub range: SourceRange,
2619}
2620
2621impl Parser<'_> {
2622 fn parse_declarator(&mut self, base: Type, allow_abstract: bool) -> PResult<DeclaratorResult> {
2627 self.enter()?;
2628 let result = self.parse_declarator_inner(base, allow_abstract);
2629 self.leave();
2630 result
2631 }
2632
2633 fn parse_declarator_inner(
2634 &mut self,
2635 base: Type,
2636 allow_abstract: bool,
2637 ) -> PResult<DeclaratorResult> {
2638 let start = self.cur_range();
2639 let leading = self.parse_attributes()?;
2642 let mut ty = base;
2643
2644 while self.at_punct(Punct::Star) {
2647 let star = self.bump_range();
2648 let mut quals = self.parse_type_qualifiers();
2649 while self.at_attributes() {
2651 let _ = self.parse_attributes()?;
2652 quals = quals.merge(self.parse_type_qualifiers());
2653 }
2654 let range = self.span_to_here(star);
2655 ty = Type::new(TypeKind::Pointer(Box::new(ty)), quals, range);
2656 }
2657
2658 if self.at_punct(Punct::LParen) && self.is_grouping_paren() {
2659 let save = self.pos;
2660 let balanced = self.skip_balanced_parens();
2661 if !balanced {
2662 let range = self.cur_range();
2663 return Err(self.error_bail(range, "unbalanced '(' in declarator"));
2664 }
2665 let rparen = self.pos - 1;
2666 ty = self.parse_type_suffix(ty)?;
2667 let after = self.pos;
2668 self.pos = save + 1;
2669 let inner = self.parse_declarator(ty, allow_abstract)?;
2670 if self.pos != rparen {
2671 let range = self.cur_range();
2672 let found = self.describe_cur();
2673 return Err(self.error_bail(
2674 range,
2675 format!("expected ')' after declarator, found {found}"),
2676 ));
2677 }
2678 self.pos = after;
2679 self.last_range = self.tokens[after - 1].range;
2680 let mut attrs = inner.attrs;
2681 attrs.merge(leading);
2682 return Ok(DeclaratorResult {
2683 name: inner.name,
2684 ty: inner.ty,
2685 attrs,
2686 asm_label: inner.asm_label,
2687 range: self.span_to_here(start),
2688 });
2689 }
2690
2691 let name = match self.eat_ident() {
2692 Some(id) => Some(id),
2693 None if allow_abstract => None,
2694 None => {
2695 let range = self.cur_range();
2696 let found = self.describe_cur();
2697 return Err(self.error_bail(
2698 range,
2699 format!("expected identifier in declarator, found {found}"),
2700 ));
2701 }
2702 };
2703 let mut attrs = self.parse_attributes()?;
2706 attrs.merge(leading);
2707 let ty = self.parse_type_suffix(ty)?;
2708 Ok(DeclaratorResult {
2709 name,
2710 ty,
2711 attrs,
2712 asm_label: None,
2713 range: self.span_to_here(start),
2714 })
2715 }
2716
2717 fn is_grouping_paren(&self) -> bool {
2724 let after = self.after_attributes(1);
2725 !self.nth(after).is_punct(Punct::RParen) && !self.starts_decl_specifier(after)
2726 }
2727
2728 fn after_attributes(&self, mut n: usize) -> usize {
2733 loop {
2734 let brackets =
2735 self.nth(n).is_punct(Punct::LBracket) && self.nth(n + 1).is_punct(Punct::LBracket);
2736 if !self.nth(n).is_keyword(Keyword::Attribute) && !brackets {
2737 return n;
2738 }
2739 let (open, close) = if brackets {
2740 (Punct::LBracket, Punct::RBracket)
2741 } else {
2742 (Punct::LParen, Punct::RParen)
2743 };
2744 let mut i = if brackets { n } else { n + 1 };
2745 let mut depth = 0i32;
2746 while !self.nth(i).is_eof() {
2747 if self.nth(i).is_punct(open) {
2748 depth += 1;
2749 } else if self.nth(i).is_punct(close) {
2750 depth -= 1;
2751 if depth == 0 {
2752 i += 1;
2753 break;
2754 }
2755 }
2756 i += 1;
2757 }
2758 if i <= n {
2759 return n;
2760 }
2761 n = i;
2762 }
2763 }
2764
2765 fn skip_balanced_parens(&mut self) -> bool {
2767 let mut depth = 0i32;
2768 while !self.at_eof() {
2769 if self.at_punct(Punct::LParen) {
2770 depth += 1;
2771 } else if self.at_punct(Punct::RParen) {
2772 depth -= 1;
2773 if depth == 0 {
2774 self.advance();
2775 return true;
2776 }
2777 }
2778 self.advance();
2779 }
2780 false
2781 }
2782
2783 fn parse_type_suffix(&mut self, ty: Type) -> PResult<Type> {
2788 if let Some(lb) = self.eat_punct(Punct::LBracket) {
2789 let mut is_static = false;
2790 let mut quals = TypeQualifiers::NONE;
2791 loop {
2792 if self.at_keyword(Keyword::Static) {
2793 self.advance();
2794 is_static = true;
2795 continue;
2796 }
2797 match self.eat_type_qualifier() {
2798 Some(q) => quals = quals.merge(q),
2799 None => break,
2800 }
2801 }
2802 if is_static {
2803 self.require_standard(
2804 Standard::C99,
2805 "'static' in an array parameter declarator",
2806 lb,
2807 );
2808 }
2809 let size = if self.at_punct(Punct::RBracket) {
2810 ArraySize::Unspecified
2811 } else if self.at_punct(Punct::Star) && self.nth(1).is_punct(Punct::RBracket) {
2812 let star = self.bump_range();
2813 self.require_standard(Standard::C99, "'[*]'", star);
2814 ArraySize::Star
2815 } else {
2816 ArraySize::Expr(Box::new(self.parse_assignment_expr()?))
2817 };
2818 let rb = self.expect_punct(Punct::RBracket, " after array bound")?;
2819 let elem = self.parse_type_suffix(ty)?;
2820 return Ok(Type::plain(
2821 TypeKind::Array {
2822 elem: Box::new(elem),
2823 size,
2824 qualifiers: quals,
2825 is_static,
2826 },
2827 lb.join(rb),
2828 ));
2829 }
2830
2831 if let Some(lp) = self.eat_punct(Punct::LParen) {
2832 let list = self.parse_param_list()?;
2833 let rp = self.expect_punct(Punct::RParen, " after parameter list")?;
2834 let ret = self.parse_type_suffix(ty)?;
2835 return Ok(Type::plain(
2836 TypeKind::Function(Box::new(FunctionType {
2837 ret,
2838 params: list.params,
2839 variadic: list.ellipsis.is_some(),
2840 ellipsis: list.ellipsis,
2841 has_prototype: list.has_prototype,
2842 kr_names: list.kr_names,
2843 old_style: false,
2844 })),
2845 lp.join(rp),
2846 ));
2847 }
2848
2849 Ok(ty)
2850 }
2851
2852 fn parse_param_list(&mut self) -> PResult<ParamList> {
2853 if self.at_punct(Punct::RParen) {
2854 return Ok(ParamList::default());
2855 }
2856 if self.at_keyword(Keyword::Void) && self.nth(1).is_punct(Punct::RParen) {
2858 self.advance();
2859 return Ok(ParamList {
2860 has_prototype: true,
2861 ..ParamList::default()
2862 });
2863 }
2864 let kr = match self.peek().ident() {
2866 Some(name) => !self.is_typedef_name(name) && floatn_type(name).is_none(),
2867 None => false,
2868 };
2869 if kr {
2870 let mut names = Vec::new();
2871 loop {
2872 names.push(self.expect_ident(" in parameter list")?);
2873 if self.eat_punct(Punct::Comma).is_none() {
2874 break;
2875 }
2876 }
2877 return Ok(ParamList {
2878 kr_names: names,
2879 ..ParamList::default()
2880 });
2881 }
2882
2883 self.push_scope();
2886 let result = self.parse_prototype_params();
2887 self.pop_scope();
2888 result
2889 }
2890
2891 fn parse_prototype_params(&mut self) -> PResult<ParamList> {
2892 let mut params = Vec::new();
2893 let mut ellipsis = None;
2894 loop {
2895 if self.at_punct(Punct::Ellipsis) {
2896 ellipsis = Some(self.bump_range());
2897 break;
2898 }
2899 let start = self.cur_range();
2900 let specs = self.parse_decl_specifiers(true)?;
2901 let declarator = self.parse_declarator(specs.base.clone(), true)?;
2902 if let Some(name) = &declarator.name {
2903 self.declare(&name.name.clone(), SymKind::Ordinary);
2904 }
2905 let range = self.span_to_here(start);
2906 for cleanup in [&declarator.attrs.cleanup, &specs.attrs.cleanup]
2911 .into_iter()
2912 .flatten()
2913 {
2914 self.error(
2915 cleanup.range,
2916 "'cleanup' attribute ignored on a parameter: it calls the function when \
2917 the object goes out of scope, and only an object with automatic storage \
2918 duration ever does",
2919 );
2920 }
2921 params.push(ParamDecl {
2922 specifiers: specs,
2923 name: declarator.name,
2924 ty: declarator.ty,
2925 range,
2926 });
2927 if self.eat_punct(Punct::Comma).is_none() {
2928 break;
2929 }
2930 }
2931 Ok(ParamList {
2932 params,
2933 ellipsis,
2934 has_prototype: true,
2935 kr_names: Vec::new(),
2936 })
2937 }
2938
2939 fn parse_type_name(&mut self) -> PResult<TypeName> {
2940 let start = self.cur_range();
2941 let specs = self.parse_decl_specifiers(false)?;
2942 let declarator = self.parse_declarator(specs.base.clone(), true)?;
2943 if let Some(name) = &declarator.name {
2944 let range = name.range;
2945 self.error(range, "a type name must not declare an identifier");
2946 }
2947 Ok(TypeName {
2948 specifiers: specs,
2949 ty: declarator.ty,
2950 range: self.span_to_here(start),
2951 })
2952 }
2953}
2954
2955#[derive(Default)]
2957struct ParamList {
2958 params: Vec<ParamDecl>,
2959 ellipsis: Option<SourceRange>,
2961 has_prototype: bool,
2962 kr_names: Vec<Ident>,
2963}
2964
2965impl Parser<'_> {
2970 fn parse_initializer(&mut self) -> PResult<Initializer> {
2971 self.enter()?;
2972 let result = self.parse_initializer_inner();
2973 self.leave();
2974 result
2975 }
2976
2977 fn parse_initializer_inner(&mut self) -> PResult<Initializer> {
2978 if self.at_punct(Punct::LBrace) {
2979 let start = self.cur_range();
2980 let items = self.parse_initializer_list()?;
2981 return Ok(Initializer {
2982 kind: InitializerKind::List(items),
2983 range: self.span_to_here(start),
2984 });
2985 }
2986 let expr = self.parse_assignment_expr()?;
2987 Ok(Initializer {
2988 range: expr.range,
2989 kind: InitializerKind::Expr(expr),
2990 })
2991 }
2992
2993 fn parse_initializer_list(&mut self) -> PResult<Vec<InitItem>> {
2994 let brace = self.expect_punct(Punct::LBrace, " to open an initializer list")?;
2995 if self.at_punct(Punct::RBrace) {
2996 let range = brace.join(self.cur_range());
2999 self.require_standard(Standard::C23, "an empty initializer", range);
3000 }
3001 let mut items = Vec::new();
3002 while !self.at_punct(Punct::RBrace) && !self.at_eof() {
3003 let start = self.cur_range();
3004 let mut designators = Vec::new();
3005 let mut old_style = false;
3008 if self.peek().ident().is_some() && self.nth(1).is_punct(Punct::Colon) {
3009 let field = self.eat_ident().expect("checked above");
3010 self.advance();
3011 designators.push(Designator::Field(field));
3012 old_style = true;
3013 }
3014 loop {
3015 if old_style {
3016 break;
3017 }
3018 if self.eat_punct(Punct::Dot).is_some() {
3019 let field = self.expect_ident(" after '.' in designator")?;
3020 designators.push(Designator::Field(field));
3021 } else if self.eat_punct(Punct::LBracket).is_some() {
3022 let index = self.parse_conditional_expr()?;
3023 if self.eat_punct(Punct::Ellipsis).is_some() {
3025 let high = self.parse_conditional_expr()?;
3026 self.expect_punct(Punct::RBracket, " after array designator")?;
3027 designators.push(Designator::Range(index, high));
3028 } else {
3029 self.expect_punct(Punct::RBracket, " after array designator")?;
3030 designators.push(Designator::Index(index));
3031 }
3032 } else {
3033 break;
3034 }
3035 }
3036 if !designators.is_empty() {
3037 let at = self.span_to_here(start);
3040 self.require_standard(Standard::C99, "a designated initializer", at);
3041 }
3042 if !designators.is_empty() && !old_style {
3043 self.expect_punct(Punct::Assign, " after designator")?;
3044 }
3045 let init = self.parse_initializer()?;
3046 items.push(InitItem {
3047 designators,
3048 init,
3049 range: self.span_to_here(start),
3050 });
3051 if self.eat_punct(Punct::Comma).is_none() {
3052 break;
3053 }
3054 }
3055 self.expect_punct(Punct::RBrace, " to close an initializer list")?;
3056 Ok(items)
3057 }
3058}
3059
3060impl Parser<'_> {
3065 fn parse_compound_stmt(&mut self) -> PResult<Block> {
3066 let start = self.expect_punct(Punct::LBrace, " to open a block")?;
3067 self.push_scope();
3068 let mut local_labels = Vec::new();
3072 while self.at_keyword(Keyword::Label) {
3073 self.advance();
3074 loop {
3075 match self.expect_ident(" in a '__label__' declaration") {
3076 Ok(name) => local_labels.push(name),
3077 Err(bail) => {
3078 self.pop_scope();
3079 return Err(bail);
3080 }
3081 }
3082 if self.eat_punct(Punct::Comma).is_none() {
3083 break;
3084 }
3085 }
3086 if let Err(bail) = self.expect_punct(Punct::Semi, " after '__label__'") {
3087 self.pop_scope();
3088 return Err(bail);
3089 }
3090 }
3091 let mut items = Vec::new();
3092 let mut saw_statement = false;
3096 while !self.at_punct(Punct::RBrace) && !self.at_eof() {
3097 let before = self.pos;
3098 if saw_statement && self.starts_declaration() {
3099 let at = self.cur_range();
3100 self.require_standard(Standard::C99, "a declaration after a statement", at);
3101 }
3102 let item = if self.at_static_assert() {
3103 self.parse_static_assert().map(BlockItem::StaticAssert)
3104 } else {
3105 match self.parse_attributes() {
3109 Ok(attrs) => {
3110 if self.starts_declaration() {
3111 self.parse_block_declaration().map(|mut item| {
3112 let specifiers = match &mut item {
3119 BlockItem::Decl(decl) => Some(&mut decl.specifiers),
3120 BlockItem::NestedFunction(def) => Some(&mut def.specifiers),
3121 _ => None,
3122 };
3123 if let Some(specifiers) = specifiers {
3124 specifiers.noreturn = specifiers.noreturn.or(attrs.noreturn);
3125 specifiers.attrs.merge(attrs);
3126 }
3127 item
3128 })
3129 } else {
3130 self.parse_stmt().map(BlockItem::Stmt)
3131 }
3132 }
3133 Err(bail) => Err(bail),
3134 }
3135 };
3136 match item {
3137 Ok(item) => {
3138 saw_statement |= matches!(item, BlockItem::Stmt(_));
3139 items.push(item);
3140 }
3141 Err(bail) => {
3142 self.pop_scope();
3143 return Err(bail);
3144 }
3145 }
3146 if self.pos == before {
3147 self.advance();
3148 }
3149 }
3150 self.pop_scope();
3151 let end = self.expect_punct(Punct::RBrace, " to close a block")?;
3152 Ok(Block {
3153 items,
3154 local_labels,
3155 range: start.join(end),
3156 })
3157 }
3158
3159 fn parse_stmt(&mut self) -> PResult<Stmt> {
3160 self.enter()?;
3161 let result = self.parse_stmt_inner();
3162 self.leave();
3163 result
3164 }
3165
3166 fn parse_stmt_inner(&mut self) -> PResult<Stmt> {
3174 let mut labels: Vec<(PendingLabel, SourceRange)> = Vec::new();
3175 let start = loop {
3176 let start = self.cur_range();
3177 let _ = self.parse_attributes()?;
3181 while self.eat_keyword(Keyword::Extension).is_some() {}
3184
3185 let label = if self.peek().ident().is_some() && self.nth(1).is_punct(Punct::Colon) {
3187 let label = self.eat_ident().expect("checked above");
3188 self.advance(); PendingLabel::Ident { label }
3190 } else if self.at_keyword(Keyword::Case) {
3191 self.advance();
3192 let value = self.parse_conditional_expr()?;
3193 let upper = if self.eat_punct(Punct::Ellipsis).is_some() {
3196 Some(self.parse_conditional_expr()?)
3197 } else {
3198 None
3199 };
3200 self.expect_punct(Punct::Colon, " after 'case' label")?;
3201 PendingLabel::Case { value, upper }
3202 } else if self.at_keyword(Keyword::Default) {
3203 self.advance();
3204 self.expect_punct(Punct::Colon, " after 'default' label")?;
3205 PendingLabel::Default
3206 } else {
3207 break start;
3208 };
3209 labels.push((label, start));
3210 if labels.len() > MAX_LABEL_CHAIN {
3211 let range = self.cur_range();
3212 return Err(self.error_bail(
3213 range,
3214 format!("more than {MAX_LABEL_CHAIN} labels on one statement"),
3215 ));
3216 }
3217 };
3218
3219 if !labels.is_empty() {
3220 return self.finish_labeled_stmt(labels);
3221 }
3222 self.parse_unlabeled_stmt(start)
3223 }
3224
3225 fn parse_unlabeled_stmt(&mut self, start: SourceRange) -> PResult<Stmt> {
3230 if self.at_keyword(Keyword::Asm) {
3232 return self.parse_asm_stmt();
3233 }
3234
3235 if self.at_punct(Punct::LBrace) {
3236 let block = self.parse_compound_stmt()?;
3237 return Ok(Stmt {
3238 range: block.range,
3239 kind: StmtKind::Compound(block),
3240 });
3241 }
3242
3243 if let Some(k) = self.peek().keyword() {
3244 match k {
3245 Keyword::If => return self.parse_if_stmt(),
3246 Keyword::Switch => {
3247 self.advance();
3248 self.expect_punct(Punct::LParen, " after 'switch'")?;
3249 let cond = self.parse_expr()?;
3250 self.expect_punct(Punct::RParen, " after switch condition")?;
3251 let body = self.parse_stmt()?;
3252 return Ok(Stmt {
3253 kind: StmtKind::Switch {
3254 cond,
3255 body: Box::new(body),
3256 },
3257 range: self.span_to_here(start),
3258 });
3259 }
3260 Keyword::While => {
3261 self.advance();
3262 self.expect_punct(Punct::LParen, " after 'while'")?;
3263 let cond = self.parse_expr()?;
3264 self.expect_punct(Punct::RParen, " after loop condition")?;
3265 let body = self.parse_stmt()?;
3266 return Ok(Stmt {
3267 kind: StmtKind::While {
3268 cond,
3269 body: Box::new(body),
3270 },
3271 range: self.span_to_here(start),
3272 });
3273 }
3274 Keyword::Do => {
3275 self.advance();
3276 let body = self.parse_stmt()?;
3277 self.expect_keyword(Keyword::While, " after 'do' body")?;
3278 self.expect_punct(Punct::LParen, " after 'while'")?;
3279 let cond = self.parse_expr()?;
3280 self.expect_punct(Punct::RParen, " after loop condition")?;
3281 self.expect_punct(Punct::Semi, " after 'do' statement")?;
3282 return Ok(Stmt {
3283 kind: StmtKind::DoWhile {
3284 body: Box::new(body),
3285 cond,
3286 },
3287 range: self.span_to_here(start),
3288 });
3289 }
3290 Keyword::For => return self.parse_for_stmt(),
3291 Keyword::Goto => {
3292 self.advance();
3293 if self.eat_punct(Punct::Star).is_some() {
3296 let target = self.parse_expr()?;
3297 self.expect_punct(Punct::Semi, " after 'goto' statement")?;
3298 return Ok(Stmt {
3299 kind: StmtKind::GotoPtr(target),
3300 range: self.span_to_here(start),
3301 });
3302 }
3303 let label = self.expect_ident(" after 'goto'")?;
3304 self.expect_punct(Punct::Semi, " after 'goto' statement")?;
3305 return Ok(Stmt {
3306 kind: StmtKind::Goto(label),
3307 range: self.span_to_here(start),
3308 });
3309 }
3310 Keyword::Continue => {
3311 self.advance();
3312 self.expect_punct(Punct::Semi, " after 'continue'")?;
3313 return Ok(Stmt {
3314 kind: StmtKind::Continue,
3315 range: self.span_to_here(start),
3316 });
3317 }
3318 Keyword::Break => {
3319 self.advance();
3320 self.expect_punct(Punct::Semi, " after 'break'")?;
3321 return Ok(Stmt {
3322 kind: StmtKind::Break,
3323 range: self.span_to_here(start),
3324 });
3325 }
3326 Keyword::Return => {
3327 self.advance();
3328 let value = if self.at_punct(Punct::Semi) {
3329 None
3330 } else {
3331 Some(self.parse_expr()?)
3332 };
3333 self.expect_punct(Punct::Semi, " after 'return' statement")?;
3334 return Ok(Stmt {
3335 kind: StmtKind::Return(value),
3336 range: self.span_to_here(start),
3337 });
3338 }
3339 _ => {}
3340 }
3341 }
3342
3343 if let Some(semi) = self.eat_punct(Punct::Semi) {
3344 return Ok(Stmt {
3345 kind: StmtKind::Expr(None),
3346 range: semi,
3347 });
3348 }
3349
3350 let expr = self.parse_expr()?;
3351 self.expect_punct(Punct::Semi, " after expression")?;
3352 Ok(Stmt {
3353 kind: StmtKind::Expr(Some(expr)),
3354 range: self.span_to_here(start),
3355 })
3356 }
3357
3358 fn finish_labeled_stmt(&mut self, labels: Vec<(PendingLabel, SourceRange)>) -> PResult<Stmt> {
3362 let colon = self.last_range;
3370 let (_, label_start) = labels.last().expect("a label chain is never empty");
3371 let what = if self.at_punct(Punct::RBrace) {
3372 Some("a label at the end of a compound statement")
3373 } else if self.starts_declaration() || self.at_static_assert() {
3374 Some("a label before a declaration")
3375 } else {
3376 None
3377 };
3378 let trailing = what.map(|what| (what, label_start.join(colon), colon));
3379 let mut stmt = match trailing {
3380 Some((what, at, colon)) => {
3381 self.require_standard(Standard::C23, what, at);
3382 Stmt {
3383 kind: StmtKind::Expr(None),
3384 range: colon,
3385 }
3386 }
3387 None => {
3388 let start = self.cur_range();
3389 self.parse_unlabeled_stmt(start)?
3390 }
3391 };
3392 let end = self.last_range;
3393 for (label, start) in labels.into_iter().rev() {
3394 let body = Box::new(stmt);
3395 let kind = match label {
3396 PendingLabel::Ident { label, .. } => StmtKind::Labeled { label, body },
3397 PendingLabel::Case { value, upper } => StmtKind::Case { value, upper, body },
3398 PendingLabel::Default => StmtKind::Default { body },
3399 };
3400 stmt = Stmt {
3401 kind,
3402 range: start.join(end),
3403 };
3404 }
3405 Ok(stmt)
3406 }
3407
3408 fn parse_asm_stmt(&mut self) -> PResult<Stmt> {
3417 let start = self.cur_range();
3418 self.advance();
3419 let (mut volatile, mut inline, mut goto) = (false, false, false);
3420 loop {
3421 match self.peek().keyword() {
3422 Some(Keyword::Volatile) => volatile = true,
3423 Some(Keyword::Inline | Keyword::InlineGnu) => inline = true,
3424 Some(Keyword::Goto) => goto = true,
3425 Some(Keyword::Const) => {}
3427 _ => break,
3428 }
3429 self.advance();
3430 }
3431 self.expect_punct(Punct::LParen, " after 'asm'")?;
3432 let template = self.parse_asm_string("the assembler template")?;
3433 let mut asm = AsmStmt {
3434 volatile,
3435 inline,
3436 goto,
3437 template,
3438 extended: false,
3439 outputs: Vec::new(),
3440 inputs: Vec::new(),
3441 clobbers: Vec::new(),
3442 labels: Vec::new(),
3443 };
3444 let mut section = 0;
3447 while section < 4 && self.eat_punct(Punct::Colon).is_some() {
3448 asm.extended = true;
3449 section += 1;
3450 if self.at_punct(Punct::Colon) || self.at_punct(Punct::RParen) {
3451 continue;
3452 }
3453 loop {
3454 match section {
3455 1 => asm.outputs.push(self.parse_asm_operand()?),
3456 2 => asm.inputs.push(self.parse_asm_operand()?),
3457 3 => asm.clobbers.push(self.parse_asm_string("a clobber")?),
3458 _ => asm
3459 .labels
3460 .push(self.expect_ident(" as an 'asm goto' label")?),
3461 }
3462 if self.eat_punct(Punct::Comma).is_none() {
3463 break;
3464 }
3465 }
3466 }
3467 self.expect_punct(Punct::RParen, " after the 'asm' operands")?;
3468 self.expect_punct(Punct::Semi, " after the 'asm' statement")?;
3469 Ok(Stmt {
3470 kind: StmtKind::Asm(Box::new(asm)),
3471 range: self.span_to_here(start),
3472 })
3473 }
3474
3475 fn parse_asm_operand(&mut self) -> PResult<AsmOperand> {
3477 let name = if self.eat_punct(Punct::LBracket).is_some() {
3478 let name = self.expect_ident(" as the operand's symbolic name")?;
3479 self.expect_punct(Punct::RBracket, " after the operand's symbolic name")?;
3480 Some(name)
3481 } else {
3482 None
3483 };
3484 let constraint = self.parse_asm_string("the operand's constraint")?;
3485 self.expect_punct(Punct::LParen, " before the operand")?;
3486 let expr = self.parse_expr()?;
3487 self.expect_punct(Punct::RParen, " after the operand")?;
3488 Ok(AsmOperand {
3489 name,
3490 constraint,
3491 expr,
3492 })
3493 }
3494
3495 fn parse_asm_string(&mut self, what: &str) -> PResult<Spanned<String>> {
3498 let range = self.cur_range();
3499 let TokenKind::Str(lit) = self.peek().kind.clone() else {
3500 let found = self.describe_cur();
3501 return Err(self.error_bail(
3502 range,
3503 format!("expected {what} as a string literal, found {found}"),
3504 ));
3505 };
3506 let literal = self.parse_string_literal(lit, range);
3507 let ExprKind::Str(lit) = literal.kind else {
3508 unreachable!("parse_string_literal always yields a string literal");
3509 };
3510 if lit.kind != StrKind::Narrow {
3511 self.error(
3512 literal.range,
3513 format!(
3514 "{what} must be an ordinary string literal, not a '{}' one",
3515 lit.kind.prefix()
3516 ),
3517 );
3518 }
3519 let bytes: Vec<u8> = lit.values.iter().map(|v| *v as u8).collect();
3520 let text = String::from_utf8_lossy(&bytes).into_owned();
3521 Ok(Spanned::new(text, literal.range))
3522 }
3523
3524 fn parse_if_stmt(&mut self) -> PResult<Stmt> {
3525 let start = self.cur_range();
3526 self.advance(); self.expect_punct(Punct::LParen, " after 'if'")?;
3528 let cond = self.parse_expr()?;
3529 self.expect_punct(Punct::RParen, " after if condition")?;
3530 let then_branch = Box::new(self.parse_stmt()?);
3531 let else_branch = if self.eat_keyword(Keyword::Else).is_some() {
3532 Some(Box::new(self.parse_stmt()?))
3533 } else {
3534 None
3535 };
3536 Ok(Stmt {
3537 kind: StmtKind::If {
3538 cond,
3539 then_branch,
3540 else_branch,
3541 },
3542 range: self.span_to_here(start),
3543 })
3544 }
3545
3546 fn parse_for_stmt(&mut self) -> PResult<Stmt> {
3547 let start = self.cur_range();
3548 self.advance(); self.expect_punct(Punct::LParen, " after 'for'")?;
3550 self.push_scope();
3552 let result = (|parser: &mut Self| {
3553 let init = if parser.at_punct(Punct::Semi) {
3554 parser.advance();
3555 ForInit::None
3556 } else if parser.at_static_assert() {
3557 ForInit::StaticAssert(parser.parse_static_assert()?)
3560 } else if parser.starts_declaration() {
3561 let at = parser.cur_range();
3562 parser.require_standard(Standard::C99, "a declaration in a 'for' clause", at);
3563 ForInit::Decl(Box::new(parser.parse_declaration()?))
3564 } else {
3565 let expr = parser.parse_expr()?;
3566 parser.expect_punct(Punct::Semi, " after 'for' initializer")?;
3567 ForInit::Expr(expr)
3568 };
3569 let cond = if parser.at_punct(Punct::Semi) {
3570 None
3571 } else {
3572 Some(parser.parse_expr()?)
3573 };
3574 parser.expect_punct(Punct::Semi, " after 'for' condition")?;
3575 let step = if parser.at_punct(Punct::RParen) {
3576 None
3577 } else {
3578 Some(parser.parse_expr()?)
3579 };
3580 parser.expect_punct(Punct::RParen, " after 'for' clauses")?;
3581 let body = parser.parse_stmt()?;
3582 Ok(StmtKind::For {
3583 init,
3584 cond,
3585 step,
3586 body: Box::new(body),
3587 })
3588 })(self);
3589 self.pop_scope();
3590 Ok(Stmt {
3591 kind: result?,
3592 range: self.span_to_here(start),
3593 })
3594 }
3595
3596 fn expect_keyword(&mut self, k: Keyword, ctx: &str) -> PResult<SourceRange> {
3597 if self.at_keyword(k) {
3598 return Ok(self.bump_range());
3599 }
3600 let range = self.cur_range();
3601 let found = self.describe_cur();
3602 Err(self.error_bail(
3603 range,
3604 format!("expected '{}'{ctx}, found {found}", k.as_str()),
3605 ))
3606 }
3607}
3608
3609fn binary_op(kind: &TokenKind) -> Option<(BinaryOp, u8)> {
3615 let TokenKind::Punct(p) = kind else {
3616 return None;
3617 };
3618 Some(match p {
3619 Punct::PipePipe => (BinaryOp::LogOr, 1),
3620 Punct::AmpAmp => (BinaryOp::LogAnd, 2),
3621 Punct::Pipe => (BinaryOp::BitOr, 3),
3622 Punct::Caret => (BinaryOp::BitXor, 4),
3623 Punct::Amp => (BinaryOp::BitAnd, 5),
3624 Punct::EqEq => (BinaryOp::Eq, 6),
3625 Punct::Ne => (BinaryOp::Ne, 6),
3626 Punct::Lt => (BinaryOp::Lt, 7),
3627 Punct::Gt => (BinaryOp::Gt, 7),
3628 Punct::Le => (BinaryOp::Le, 7),
3629 Punct::Ge => (BinaryOp::Ge, 7),
3630 Punct::Shl => (BinaryOp::Shl, 8),
3631 Punct::Shr => (BinaryOp::Shr, 8),
3632 Punct::Plus => (BinaryOp::Add, 9),
3633 Punct::Minus => (BinaryOp::Sub, 9),
3634 Punct::Star => (BinaryOp::Mul, 10),
3635 Punct::Slash => (BinaryOp::Div, 10),
3636 Punct::Percent => (BinaryOp::Rem, 10),
3637 _ => return None,
3638 })
3639}
3640
3641fn assign_op(kind: &TokenKind) -> Option<Option<BinaryOp>> {
3643 let TokenKind::Punct(p) = kind else {
3644 return None;
3645 };
3646 Some(match p {
3647 Punct::Assign => None,
3648 Punct::StarAssign => Some(BinaryOp::Mul),
3649 Punct::SlashAssign => Some(BinaryOp::Div),
3650 Punct::PercentAssign => Some(BinaryOp::Rem),
3651 Punct::PlusAssign => Some(BinaryOp::Add),
3652 Punct::MinusAssign => Some(BinaryOp::Sub),
3653 Punct::ShlAssign => Some(BinaryOp::Shl),
3654 Punct::ShrAssign => Some(BinaryOp::Shr),
3655 Punct::AmpAssign => Some(BinaryOp::BitAnd),
3656 Punct::CaretAssign => Some(BinaryOp::BitXor),
3657 Punct::PipeAssign => Some(BinaryOp::BitOr),
3658 _ => return None,
3659 })
3660}
3661
3662impl Parser<'_> {
3663 pub(crate) fn parse_expr(&mut self) -> PResult<Expr> {
3665 self.enter()?;
3666 let result = self.parse_expr_inner();
3667 self.leave();
3668 result
3669 }
3670
3671 fn parse_expr_inner(&mut self) -> PResult<Expr> {
3678 let mut lhs = self.parse_assignment_expr()?;
3679 while self.eat_punct(Punct::Comma).is_some() {
3680 let rhs = self.parse_assignment_expr()?;
3681 let range = lhs.range.join(rhs.range);
3682 lhs = Expr {
3683 kind: ExprKind::Comma {
3684 lhs: Box::new(lhs),
3685 rhs: Box::new(rhs),
3686 },
3687 range,
3688 };
3689 }
3690 Ok(lhs)
3691 }
3692
3693 fn parse_assignment_expr(&mut self) -> PResult<Expr> {
3702 let mut charged = 0u32;
3703 let result = self.assignment_chain(&mut charged);
3704 for _ in 0..charged {
3705 self.leave();
3706 }
3707 result
3708 }
3709
3710 fn assignment_chain(&mut self, charged: &mut u32) -> PResult<Expr> {
3712 let mut pending: Vec<(Expr, Option<BinaryOp>)> = Vec::new();
3713 let mut value = loop {
3714 let lhs = self.parse_conditional_expr()?;
3715 let Some(op) = assign_op(&self.peek().kind) else {
3716 break lhs;
3717 };
3718 self.advance();
3719 self.enter()?;
3720 *charged += 1;
3721 pending.push((lhs, op));
3722 };
3723 for (lhs, op) in pending.into_iter().rev() {
3724 let range = lhs.range.join(value.range);
3725 value = Expr {
3726 kind: ExprKind::Assign {
3727 op,
3728 lhs: Box::new(lhs),
3729 rhs: Box::new(value),
3730 },
3731 range,
3732 };
3733 }
3734 Ok(value)
3735 }
3736
3737 fn parse_conditional_expr(&mut self) -> PResult<Expr> {
3745 let mut charged = 0u32;
3746 let result = self.conditional_chain(&mut charged);
3747 for _ in 0..charged {
3748 self.leave();
3749 }
3750 result
3751 }
3752
3753 fn conditional_chain(&mut self, charged: &mut u32) -> PResult<Expr> {
3755 #[allow(clippy::type_complexity)]
3756 let mut pending: Vec<(Expr, Option<Box<Expr>>)> = Vec::new();
3757 let mut value = loop {
3758 let cond = self.parse_binary_expr(1)?;
3759 if self.eat_punct(Punct::Question).is_none() {
3760 break cond;
3761 }
3762 let then_expr = if self.at_punct(Punct::Colon) {
3765 None
3766 } else {
3767 Some(Box::new(self.parse_expr()?))
3768 };
3769 self.expect_punct(Punct::Colon, " in conditional expression")?;
3770 self.enter()?;
3771 *charged += 1;
3772 pending.push((cond, then_expr));
3773 };
3774 for (cond, then_expr) in pending.into_iter().rev() {
3775 let range = cond.range.join(value.range);
3776 value = Expr {
3777 kind: ExprKind::Conditional {
3778 cond: Box::new(cond),
3779 then_expr,
3780 else_expr: Box::new(value),
3781 },
3782 range,
3783 };
3784 }
3785 Ok(value)
3786 }
3787
3788 fn parse_binary_expr(&mut self, min_prec: u8) -> PResult<Expr> {
3795 let mut lhs = self.parse_cast_expr()?;
3796 while let Some((op, prec)) = binary_op(&self.peek().kind) {
3797 if prec < min_prec {
3798 break;
3799 }
3800 self.advance();
3801 let rhs = self.parse_binary_expr(prec + 1)?;
3802 let range = lhs.range.join(rhs.range);
3803 lhs = Expr {
3804 kind: ExprKind::Binary {
3805 op,
3806 lhs: Box::new(lhs),
3807 rhs: Box::new(rhs),
3808 },
3809 range,
3810 };
3811 }
3812 Ok(lhs)
3813 }
3814
3815 fn at_paren_type_name(&self) -> bool {
3819 if !self.at_punct(Punct::LParen) {
3820 return false;
3821 }
3822 let mut n = 1;
3828 while self.nth(n).keyword() == Some(Keyword::Extension) {
3829 n += 1;
3830 }
3831 self.starts_decl_specifier(n)
3832 }
3833
3834 fn parse_cast_expr(&mut self) -> PResult<Expr> {
3835 self.enter()?;
3836 let result = self.parse_cast_expr_inner();
3837 self.leave();
3838 result
3839 }
3840
3841 fn parse_cast_expr_inner(&mut self) -> PResult<Expr> {
3842 if !self.at_paren_type_name() {
3843 return self.parse_unary_expr();
3844 }
3845 let start = self.cur_range();
3846 self.advance(); let ty = self.parse_type_name()?;
3848 self.expect_punct(Punct::RParen, " after type name")?;
3849 if self.at_punct(Punct::LBrace) {
3850 let at = self.span_to_here(start);
3852 self.require_standard(Standard::C99, "a compound literal", at);
3853 let items = self.parse_initializer_list()?;
3854 let expr = Expr {
3855 kind: ExprKind::CompoundLiteral {
3856 ty: Box::new(ty),
3857 init: items,
3858 },
3859 range: self.span_to_here(start),
3860 };
3861 return self.parse_postfix_suffixes(expr);
3862 }
3863 let expr = self.parse_cast_expr()?;
3864 let range = start.join(expr.range);
3865 Ok(Expr {
3866 kind: ExprKind::Cast {
3867 ty: Box::new(ty),
3868 expr: Box::new(expr),
3869 },
3870 range,
3871 })
3872 }
3873
3874 fn parse_unary_expr(&mut self) -> PResult<Expr> {
3875 let start = self.cur_range();
3876
3877 if let Some(p) = match &self.peek().kind {
3878 TokenKind::Punct(p) => Some(*p),
3879 _ => None,
3880 } {
3881 let unary = match p {
3882 Punct::Amp => Some(UnaryOp::AddrOf),
3883 Punct::Star => Some(UnaryOp::Deref),
3884 Punct::Plus => Some(UnaryOp::Plus),
3885 Punct::Minus => Some(UnaryOp::Minus),
3886 Punct::Tilde => Some(UnaryOp::BitNot),
3887 Punct::Bang => Some(UnaryOp::LogNot),
3888 _ => None,
3889 };
3890 if let Some(op) = unary {
3891 self.advance();
3892 let operand = self.parse_cast_expr()?;
3893 let range = start.join(operand.range);
3894 return Ok(Expr {
3895 kind: ExprKind::Unary {
3896 op,
3897 operand: Box::new(operand),
3898 },
3899 range,
3900 });
3901 }
3902 if p == Punct::AmpAmp {
3907 self.advance();
3908 let label = self.expect_ident(" after '&&'")?;
3909 self.label_addrs += 1;
3910 let range = start.join(label.range);
3911 return Ok(Expr {
3912 kind: ExprKind::LabelAddr(label),
3913 range,
3914 });
3915 }
3916 if matches!(p, Punct::PlusPlus | Punct::MinusMinus) {
3917 self.advance();
3918 let op = if p == Punct::PlusPlus {
3919 IncDec::Inc
3920 } else {
3921 IncDec::Dec
3922 };
3923 let operand = self.parse_unary_expr()?;
3924 let range = start.join(operand.range);
3925 return Ok(Expr {
3926 kind: ExprKind::PreIncDec {
3927 op,
3928 operand: Box::new(operand),
3929 },
3930 range,
3931 });
3932 }
3933 }
3934
3935 if self.at_keyword(Keyword::Sizeof) {
3936 self.advance();
3937 if self.at_paren_type_name() {
3938 self.advance(); let ty = self.parse_type_name()?;
3940 self.expect_punct(Punct::RParen, " after type name")?;
3941 if self.at_punct(Punct::LBrace) {
3942 let at = self.span_to_here(start);
3944 self.require_standard(Standard::C99, "a compound literal", at);
3945 let items = self.parse_initializer_list()?;
3946 let literal = Expr {
3947 kind: ExprKind::CompoundLiteral {
3948 ty: Box::new(ty),
3949 init: items,
3950 },
3951 range: self.span_to_here(start),
3952 };
3953 let operand = self.parse_postfix_suffixes(literal)?;
3954 let range = start.join(operand.range);
3955 return Ok(Expr {
3956 kind: ExprKind::SizeofExpr(Box::new(operand)),
3957 range,
3958 });
3959 }
3960 return Ok(Expr {
3961 kind: ExprKind::SizeofType(Box::new(ty)),
3962 range: self.span_to_here(start),
3963 });
3964 }
3965 let operand = self.parse_unary_expr()?;
3966 let range = start.join(operand.range);
3967 return Ok(Expr {
3968 kind: ExprKind::SizeofExpr(Box::new(operand)),
3969 range,
3970 });
3971 }
3972
3973 if self.eat_keyword(Keyword::Extension).is_some() {
3978 return self.parse_unary_expr();
3979 }
3980 if let Some(k @ (Keyword::RealGnu | Keyword::ImagGnu)) = self.peek().keyword() {
3981 self.advance();
3982 let operand = self.parse_cast_expr()?;
3983 let range = start.join(operand.range);
3984 return Ok(Expr {
3985 kind: ExprKind::ComplexPart {
3986 real: k == Keyword::RealGnu,
3987 operand: Box::new(operand),
3988 },
3989 range,
3990 });
3991 }
3992
3993 if let Some(k @ (Keyword::Alignof | Keyword::AlignofName | Keyword::AlignofGnu)) =
3994 self.peek().keyword()
3995 {
3996 self.require_keyword(k, start);
3997 self.advance();
3998 if self.at_paren_type_name() {
3999 self.advance(); let ty = self.parse_type_name()?;
4001 self.expect_punct(Punct::RParen, " after type name")?;
4002 return Ok(Expr {
4003 kind: ExprKind::AlignofType(Box::new(ty)),
4004 range: self.span_to_here(start),
4005 });
4006 }
4007 let operand = self.parse_unary_expr()?;
4011 let range = start.join(operand.range);
4012 return Ok(Expr {
4013 kind: ExprKind::AlignofExpr(Box::new(operand)),
4014 range,
4015 });
4016 }
4017
4018 if self.at_va_arg() {
4019 return self.parse_va_arg();
4020 }
4021 if self.at_builtin("__builtin_offsetof") {
4022 return self.parse_offsetof();
4023 }
4024 if self.at_builtin("__builtin_types_compatible_p") {
4025 return self.parse_types_compatible();
4026 }
4027 if self.at_builtin("__builtin_choose_expr") {
4028 return self.parse_choose_expr();
4029 }
4030
4031 self.parse_postfix_expr()
4032 }
4033
4034 fn parse_types_compatible(&mut self) -> PResult<Expr> {
4036 let start = self.cur_range();
4037 self.advance(); self.advance(); let lhs = self.parse_type_name()?;
4040 self.expect_punct(
4041 Punct::Comma,
4042 " after the first type of '__builtin_types_compatible_p'",
4043 )?;
4044 let rhs = self.parse_type_name()?;
4045 self.expect_punct(
4046 Punct::RParen,
4047 " after the second type of '__builtin_types_compatible_p'",
4048 )?;
4049 let expr = Expr {
4050 kind: ExprKind::TypesCompatible {
4051 lhs: Box::new(lhs),
4052 rhs: Box::new(rhs),
4053 },
4054 range: self.span_to_here(start),
4055 };
4056 self.parse_postfix_suffixes(expr)
4057 }
4058
4059 fn parse_choose_expr(&mut self) -> PResult<Expr> {
4062 let start = self.cur_range();
4063 self.advance(); self.advance(); let cond = self.parse_assignment_expr()?;
4066 self.expect_punct(
4067 Punct::Comma,
4068 " after the condition of '__builtin_choose_expr'",
4069 )?;
4070 let then_expr = self.parse_assignment_expr()?;
4071 self.expect_punct(Punct::Comma, " in '__builtin_choose_expr'")?;
4072 let else_expr = self.parse_assignment_expr()?;
4073 self.expect_punct(Punct::RParen, " to close '__builtin_choose_expr'")?;
4074 let expr = Expr {
4075 kind: ExprKind::ChooseExpr {
4076 cond: Box::new(cond),
4077 then_expr: Box::new(then_expr),
4078 else_expr: Box::new(else_expr),
4079 },
4080 range: self.span_to_here(start),
4081 };
4082 self.parse_postfix_suffixes(expr)
4083 }
4084
4085 fn at_builtin(&self, name: &str) -> bool {
4091 self.peek().ident() == Some(name) && self.nth(1).is_punct(Punct::LParen)
4092 }
4093
4094 fn at_va_arg(&self) -> bool {
4096 self.at_builtin("__builtin_va_arg")
4097 }
4098
4099 fn parse_offsetof(&mut self) -> PResult<Expr> {
4107 let start = self.cur_range();
4108 self.advance(); self.advance(); let ty = self.parse_type_name()?;
4111 self.expect_punct(Punct::Comma, " after the type of 'offsetof'")?;
4112 let member = self.expect_ident(" as the member of 'offsetof'")?;
4113 let mut path = Vec::new();
4114 loop {
4115 if self.eat_punct(Punct::Dot).is_some() {
4116 path.push(Designator::Field(self.expect_ident(
4117 " after '.' in the member designator of 'offsetof'",
4118 )?));
4119 continue;
4120 }
4121 if self.eat_punct(Punct::LBracket).is_some() {
4122 path.push(Designator::Index(self.parse_expr()?));
4123 self.expect_punct(
4124 Punct::RBracket,
4125 " after the subscript in the member designator of 'offsetof'",
4126 )?;
4127 continue;
4128 }
4129 break;
4130 }
4131 self.expect_punct(Punct::RParen, " after the member of 'offsetof'")?;
4132 let expr = Expr {
4133 kind: ExprKind::OffsetOf {
4134 ty: Box::new(ty),
4135 member,
4136 path,
4137 },
4138 range: self.span_to_here(start),
4139 };
4140 self.parse_postfix_suffixes(expr)
4141 }
4142
4143 fn parse_va_arg(&mut self) -> PResult<Expr> {
4145 let start = self.cur_range();
4146 self.advance(); self.advance(); let ap = self.parse_assignment_expr()?;
4149 self.expect_punct(Punct::Comma, " after the argument list of 'va_arg'")?;
4150 let ty = self.parse_type_name()?;
4151 self.expect_punct(Punct::RParen, " after the type of 'va_arg'")?;
4152 let expr = Expr {
4153 kind: ExprKind::VaArg {
4154 ap: Box::new(ap),
4155 ty: Box::new(ty),
4156 },
4157 range: self.span_to_here(start),
4158 };
4159 self.parse_postfix_suffixes(expr)
4160 }
4161
4162 fn parse_postfix_expr(&mut self) -> PResult<Expr> {
4163 let primary = self.parse_primary_expr()?;
4164 self.parse_postfix_suffixes(primary)
4165 }
4166
4167 fn parse_postfix_suffixes(&mut self, expr: Expr) -> PResult<Expr> {
4175 let mut charged = 0u32;
4176 let result = self.postfix_suffixes(expr, &mut charged);
4177 for _ in 0..charged {
4178 self.leave();
4179 }
4180 result
4181 }
4182
4183 fn postfix_suffixes(&mut self, mut expr: Expr, charged: &mut u32) -> PResult<Expr> {
4185 let mut suffixes = 0usize;
4186 loop {
4187 if suffixes > 0 {
4191 self.enter()?;
4192 *charged += 1;
4193 }
4194 suffixes += 1;
4195 if self.eat_punct(Punct::LBracket).is_some() {
4196 let index = self.parse_expr()?;
4197 let rb = self.expect_punct(Punct::RBracket, " after subscript")?;
4198 expr = Expr {
4199 range: expr.range.join(rb),
4200 kind: ExprKind::Index {
4201 base: Box::new(expr),
4202 index: Box::new(index),
4203 },
4204 };
4205 continue;
4206 }
4207 if self.eat_punct(Punct::LParen).is_some() {
4208 let mut args = Vec::new();
4209 if !self.at_punct(Punct::RParen) {
4210 loop {
4211 args.push(self.parse_assignment_expr()?);
4212 if self.eat_punct(Punct::Comma).is_none() {
4213 break;
4214 }
4215 }
4216 }
4217 let rp = self.expect_punct(Punct::RParen, " after argument list")?;
4218 expr = Expr {
4219 range: expr.range.join(rp),
4220 kind: ExprKind::Call {
4221 callee: Box::new(expr),
4222 args,
4223 },
4224 };
4225 continue;
4226 }
4227 let arrow = if self.at_punct(Punct::Dot) {
4228 false
4229 } else if self.at_punct(Punct::Arrow) {
4230 true
4231 } else if self.at_punct(Punct::PlusPlus) || self.at_punct(Punct::MinusMinus) {
4232 let op = if self.at_punct(Punct::PlusPlus) {
4233 IncDec::Inc
4234 } else {
4235 IncDec::Dec
4236 };
4237 let range = expr.range.join(self.bump_range());
4238 expr = Expr {
4239 kind: ExprKind::PostIncDec {
4240 op,
4241 operand: Box::new(expr),
4242 },
4243 range,
4244 };
4245 continue;
4246 } else {
4247 break;
4248 };
4249 self.advance();
4250 let field = self.expect_ident(if arrow { " after '->'" } else { " after '.'" })?;
4251 expr = Expr {
4252 range: expr.range.join(field.range),
4253 kind: ExprKind::Member {
4254 base: Box::new(expr),
4255 arrow,
4256 field,
4257 },
4258 };
4259 }
4260 Ok(expr)
4261 }
4262
4263 fn parse_generic_selection(&mut self) -> PResult<Expr> {
4268 let start = self.cur_range();
4269 self.require_keyword(Keyword::Generic, start);
4270 self.advance();
4271 self.expect_punct(Punct::LParen, " after '_Generic'")?;
4272 let controlling = self.parse_assignment_expr()?;
4273 let mut assocs = Vec::new();
4274 while self.eat_punct(Punct::Comma).is_some() {
4275 let astart = self.cur_range();
4276 let ty = if self.eat_keyword(Keyword::Default).is_some() {
4277 None
4278 } else {
4279 Some(self.parse_type_name()?)
4280 };
4281 self.expect_punct(Punct::Colon, " after the type of a '_Generic' association")?;
4282 let value = self.parse_assignment_expr()?;
4283 assocs.push(GenericAssoc {
4284 ty,
4285 value,
4286 range: self.span_to_here(astart),
4287 });
4288 }
4289 let rparen = self.expect_punct(Punct::RParen, " to close '_Generic'")?;
4290 if assocs.is_empty() {
4291 self.error(
4292 start.join(rparen),
4293 "'_Generic' requires at least one association",
4294 );
4295 }
4296 Ok(Expr {
4297 kind: ExprKind::Generic {
4298 controlling: Box::new(controlling),
4299 assocs,
4300 },
4301 range: start.join(rparen),
4302 })
4303 }
4304
4305 fn parse_primary_expr(&mut self) -> PResult<Expr> {
4306 let range = self.cur_range();
4307 match self.peek().kind.clone() {
4308 TokenKind::Keyword(Keyword::Generic) => self.parse_generic_selection(),
4309 TokenKind::Keyword(k @ (Keyword::True | Keyword::False)) => {
4310 self.advance();
4311 Ok(Expr {
4312 kind: ExprKind::Bool(k == Keyword::True),
4313 range,
4314 })
4315 }
4316 TokenKind::Keyword(Keyword::Nullptr) => {
4317 self.advance();
4318 Ok(Expr {
4319 kind: ExprKind::Nullptr,
4320 range,
4321 })
4322 }
4323 TokenKind::Ident(name) => {
4324 self.advance();
4325 Ok(Expr {
4326 kind: ExprKind::Ident(Ident { name, range }),
4327 range,
4328 })
4329 }
4330 TokenKind::Int(lit) => {
4331 self.advance();
4332 Ok(Expr {
4333 kind: ExprKind::Int(lit),
4334 range,
4335 })
4336 }
4337 TokenKind::Float(lit) => {
4338 self.advance();
4339 Ok(Expr {
4340 kind: ExprKind::Float(lit),
4341 range,
4342 })
4343 }
4344 TokenKind::Char(lit) => {
4345 self.advance();
4346 Ok(Expr {
4347 kind: ExprKind::Char(lit),
4348 range,
4349 })
4350 }
4351 TokenKind::Str(first) => Ok(self.parse_string_literal(first, range)),
4352 TokenKind::Punct(Punct::LParen) => {
4353 self.advance();
4354 if self.at_punct(Punct::LBrace) {
4358 let block = self.parse_compound_stmt()?;
4359 let rp =
4360 self.expect_punct(Punct::RParen, " to close a statement expression")?;
4361 return Ok(Expr {
4362 kind: ExprKind::StmtExpr(Box::new(block)),
4363 range: range.join(rp),
4364 });
4365 }
4366 let inner = self.parse_expr()?;
4367 let rp = self.expect_punct(Punct::RParen, " after parenthesized expression")?;
4368 Ok(Expr {
4369 kind: inner.kind,
4370 range: range.join(rp),
4371 })
4372 }
4373 _ => {
4374 let found = self.describe_cur();
4375 Err(self.error_bail(range, format!("expected expression, found {found}")))
4376 }
4377 }
4378 }
4379
4380 fn parse_string_literal(&mut self, first: StrLit, first_range: SourceRange) -> Expr {
4388 self.advance();
4389 let mut kind = first.kind;
4390 let mut values = first.values;
4391 let mut text = first.text;
4392 let mut range = first_range;
4393 while let TokenKind::Str(next) = self.peek().kind.clone() {
4394 let piece_range = self.cur_range();
4395 if next.kind != kind {
4396 if kind == StrKind::Narrow {
4397 values = recode_from_narrow(&values, next.kind);
4398 kind = next.kind;
4399 } else if next.kind != StrKind::Narrow {
4400 self.error(
4401 piece_range,
4402 format!(
4403 "cannot concatenate a '{}' string literal with a '{}' one",
4404 kind.prefix(),
4405 next.kind.prefix()
4406 ),
4407 );
4408 }
4409 }
4410 if next.kind == kind || next.kind != StrKind::Narrow {
4411 values.extend_from_slice(&next.values);
4412 } else {
4413 values.extend(recode_from_narrow(&next.values, kind));
4414 }
4415 text.push(' ');
4416 text.push_str(&next.text);
4417 range = range.join(piece_range);
4418 self.advance();
4419 }
4420 Expr {
4421 kind: ExprKind::Str(StrLit { kind, values, text }),
4422 range,
4423 }
4424 }
4425}
4426
4427fn floatn_type(name: &str) -> Option<FloatSize> {
4442 Some(match name {
4443 "_Float32" => FloatSize::Float32,
4444 "_Float64" => FloatSize::Float64,
4445 "_Float32x" => FloatSize::Float32x,
4446 "_Float64x" => FloatSize::Float64x,
4447 "_Float128" | "__float128" => FloatSize::Float128,
4448 _ => return None,
4449 })
4450}
4451
4452fn extended_float_type(name: &str) -> Option<&'static str> {
4460 match name {
4461 "_Float128x" => Some("an extended binary128 format (GCC has none either)"),
4462 "__fp16" | "_Float16" => Some("binary16"),
4463 "__bf16" | "__bfloat16" => Some("bfloat16"),
4464 _ => None,
4465 }
4466}
4467
4468fn recode_from_narrow(values: &[u32], kind: StrKind) -> Vec<u32> {
4473 if kind == StrKind::Narrow || kind == StrKind::Utf8 {
4474 return values.to_vec();
4475 }
4476 let bytes: Vec<u8> = values.iter().map(|v| *v as u8).collect();
4477 let text = String::from_utf8_lossy(&bytes);
4478 let mut out = Vec::with_capacity(values.len());
4479 for ch in text.chars() {
4480 let value = ch as u32;
4481 if kind == StrKind::Utf16 && value > 0xffff {
4482 let v = value - 0x1_0000;
4483 out.push(0xd800 + (v >> 10));
4484 out.push(0xdc00 + (v & 0x3ff));
4485 } else {
4486 out.push(value);
4487 }
4488 }
4489 out
4490}