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};
48use crate::lex::{Keyword, Punct, StrKind, StrLit, TokenKind};
49use crate::pp::{Origin, PackMap, Token};
50use crate::{Gating, Options, Standard};
51
52pub const NORETURN_BUILTIN: &str = "__cinrs_noreturn";
60
61fn int_expr(value: u128, range: SourceRange) -> Expr {
63 Expr {
64 kind: ExprKind::Int(crate::lex::IntLit {
65 value,
66 base: crate::lex::NumBase::Decimal,
67 unsigned: false,
68 long: crate::lex::LongKind::None,
69 text: value.to_string(),
70 }),
71 range,
72 }
73}
74
75#[derive(Debug)]
77#[must_use]
78pub struct Bail;
79
80type PResult<T> = Result<T, Bail>;
81
82#[derive(Clone, Copy, PartialEq, Eq, Debug)]
84enum SymKind {
85 Typedef,
86 Ordinary,
87}
88
89#[derive(Default)]
91struct Scope {
92 syms: HashMap<String, SymKind>,
93}
94
95pub fn parse(
107 tokens: &[Token],
108 unit_range: SourceRange,
109 packing: &PackMap,
110 options: &Options,
111 diags: &mut Diagnostics,
112) -> TranslationUnit {
113 let patched: Vec<Token>;
116 let tokens: &[Token] = if tokens.last().is_some_and(Token::is_eof) {
117 tokens
118 } else {
119 patched = tokens
120 .iter()
121 .cloned()
122 .chain(std::iter::once(Token {
123 kind: TokenKind::Eof,
124 range: SourceRange::at(unit_range.end),
125 origin: Origin::Source,
126 }))
127 .collect();
128 &patched
129 };
130 let last_range = tokens.first().map_or(unit_range, |t| t.range);
131 let mut builtins = Scope::default();
137 for name in VA_LIST_NAMES {
138 builtins.syms.insert((*name).to_owned(), SymKind::Typedef);
139 }
140 for (name, _) in INT128_TYPEDEF_NAMES {
144 builtins.syms.insert((*name).to_owned(), SymKind::Typedef);
145 }
146 let mut parser = Parser {
147 tokens,
148 pos: 0,
149 diags,
150 scopes: vec![builtins],
151 standard: options.standard,
152 gating: options.gating(),
153 in_extension: false,
154 packing,
155 last_range,
156 depth: 0,
157 records: Vec::new(),
158 enums: Vec::new(),
159 typeofs: Vec::new(),
160 label_addrs: 0,
161 };
162 parser.parse_translation_unit(unit_range)
163}
164
165const MAX_RECURSION_DEPTH: u32 = 200;
195
196const MAX_LABEL_CHAIN: usize = 4096;
204
205enum PendingLabel {
207 Ident { label: Ident },
209 Case { value: Expr, upper: Option<Expr> },
211 Default,
213}
214
215struct Parser<'a> {
216 tokens: &'a [Token],
217 pos: usize,
218 diags: &'a mut Diagnostics,
219 scopes: Vec<Scope>,
220 standard: Standard,
222 gating: Gating,
224 in_extension: bool,
227 packing: &'a PackMap,
229 last_range: SourceRange,
231 depth: u32,
233 records: Vec<RecordSpec>,
235 enums: Vec<EnumSpec>,
237 typeofs: Vec<TypeofOperand>,
239 label_addrs: u32,
251}
252
253impl Parser<'_> {
258 fn peek(&self) -> &Token {
259 &self.tokens[self.pos]
260 }
261
262 fn nth(&self, n: usize) -> &Token {
263 let i = (self.pos + n).min(self.tokens.len() - 1);
264 &self.tokens[i]
265 }
266
267 fn cur_range(&self) -> SourceRange {
268 self.peek().range
269 }
270
271 fn describe_cur(&self) -> String {
272 self.peek().kind.describe()
273 }
274
275 fn at_eof(&self) -> bool {
276 self.peek().is_eof()
277 }
278
279 fn at_punct(&self, p: Punct) -> bool {
280 self.peek().is_punct(p)
281 }
282
283 fn at_keyword(&self, k: Keyword) -> bool {
284 self.peek().is_keyword(k)
285 }
286
287 fn advance(&mut self) {
288 self.last_range = self.tokens[self.pos].range;
289 if self.pos + 1 < self.tokens.len() {
290 self.pos += 1;
291 }
292 }
293
294 fn bump_range(&mut self) -> SourceRange {
295 let range = self.cur_range();
296 self.advance();
297 range
298 }
299
300 fn eat_punct(&mut self, p: Punct) -> Option<SourceRange> {
301 self.at_punct(p).then(|| self.bump_range())
302 }
303
304 fn eat_keyword(&mut self, k: Keyword) -> Option<SourceRange> {
305 self.at_keyword(k).then(|| self.bump_range())
306 }
307
308 fn eat_ident(&mut self) -> Option<Ident> {
309 let name = self.peek().ident()?.to_owned();
310 let range = self.bump_range();
311 Some(Ident { name, range })
312 }
313
314 fn error(&mut self, range: SourceRange, message: impl Into<String>) {
315 self.diags.error(range, message);
316 }
317
318 fn error_bail(&mut self, range: SourceRange, message: impl Into<String>) -> Bail {
319 self.diags.error(range, message);
320 Bail
321 }
322
323 fn expect_punct(&mut self, p: Punct, ctx: &str) -> PResult<SourceRange> {
324 if self.at_punct(p) {
325 return Ok(self.bump_range());
326 }
327 let range = self.cur_range();
328 let found = self.describe_cur();
329 Err(self.error_bail(
330 range,
331 format!("expected '{}'{ctx}, found {found}", p.as_str()),
332 ))
333 }
334
335 fn expect_ident(&mut self, ctx: &str) -> PResult<Ident> {
336 if let Some(id) = self.eat_ident() {
337 return Ok(id);
338 }
339 let range = self.cur_range();
340 let found = self.describe_cur();
341 Err(self.error_bail(range, format!("expected identifier{ctx}, found {found}")))
342 }
343
344 fn span_to_here(&self, start: SourceRange) -> SourceRange {
346 start.join(self.last_range)
347 }
348
349 fn enter(&mut self) -> PResult<()> {
354 self.depth += 1;
355 if self.depth > MAX_RECURSION_DEPTH {
356 let range = self.cur_range();
357 return Err(self.error_bail(range, "this construct nests too deeply"));
358 }
359 Ok(())
360 }
361
362 fn leave(&mut self) {
364 self.depth = self.depth.saturating_sub(1);
365 }
366
367 fn require_standard(&mut self, needed: Standard, what: &str, range: SourceRange) {
380 if self.in_extension {
381 return;
382 }
383 if let Some(message) = self.gating.requires(what, needed) {
384 self.error(range, message);
385 }
386 }
387
388 fn require_keyword(&mut self, k: Keyword, range: SourceRange) {
390 let needed = k.since();
391 self.require_standard(needed, &format!("'{}'", k.as_str()), range);
392 }
393
394 fn newer_keyword_here(&self) -> Option<String> {
397 self.gating.newer_keyword(self.peek().ident()?)
398 }
399
400 fn gnu_leniency(&self) -> bool {
403 self.gating.dialect.is_gnu()
404 }
405
406 fn gnu_note(&self) -> String {
409 format!(
410 "GCC accepts this with a warning; write {} for the same leniency",
411 self.gating.standard.macro_name_in(crate::Dialect::Gnu)
412 )
413 }
414
415 fn error_gnu(&mut self, range: SourceRange, message: impl Into<String>) {
417 let note = self.gnu_note();
418 self.diags
419 .push(Diagnostic::error(range, message).with_note(note));
420 }
421}
422
423impl Parser<'_> {
428 fn push_scope(&mut self) {
429 self.scopes.push(Scope::default());
430 }
431
432 fn pop_scope(&mut self) {
433 self.scopes.pop();
434 }
435
436 fn declare(&mut self, name: &str, kind: SymKind) {
437 if let Some(scope) = self.scopes.last_mut() {
438 scope.syms.insert(name.to_owned(), kind);
439 }
440 }
441
442 fn is_typedef_name(&self, name: &str) -> bool {
444 for scope in self.scopes.iter().rev() {
445 if let Some(kind) = scope.syms.get(name) {
446 return *kind == SymKind::Typedef;
447 }
448 }
449 false
450 }
451}
452
453impl Parser<'_> {
458 fn at_attributes(&self) -> bool {
463 (self.at_punct(Punct::LBracket) && self.nth(1).is_punct(Punct::LBracket))
464 || self.at_keyword(Keyword::Attribute)
465 }
466
467 fn parse_attributes(&mut self) -> PResult<Attributes> {
477 let mut attrs = Attributes::default();
478 loop {
479 if self.at_keyword(Keyword::Attribute) {
480 let start = self.bump_range();
481 self.expect_punct(Punct::LParen, " after '__attribute__'")?;
482 self.expect_punct(Punct::LParen, " after '__attribute__('")?;
483 self.parse_attribute_list(&mut attrs, Punct::RParen)?;
484 self.expect_punct(Punct::RParen, " to close '__attribute__'")?;
485 self.expect_punct(Punct::RParen, " to close '__attribute__'")?;
486 let _ = start;
487 continue;
488 }
489 if self.at_punct(Punct::LBracket) && self.nth(1).is_punct(Punct::LBracket) {
490 let start = self.cur_range();
491 self.require_standard(Standard::C23, "an attribute specifier", start);
492 self.advance(); self.advance(); self.parse_attribute_list(&mut attrs, Punct::RBracket)?;
495 self.expect_punct(Punct::RBracket, " to close an attribute specifier")?;
496 self.expect_punct(Punct::RBracket, " to close an attribute specifier")?;
497 continue;
498 }
499 return Ok(attrs);
500 }
501 }
502
503 fn parse_attribute_list(&mut self, attrs: &mut Attributes, close: Punct) -> PResult<()> {
505 loop {
506 if self.at_punct(close) || self.at_eof() {
507 return Ok(());
508 }
509 if self.eat_punct(Punct::Comma).is_some() {
511 continue;
512 }
513 self.parse_one_attribute(attrs, close)?;
514 if self.eat_punct(Punct::Comma).is_none() {
515 return Ok(());
516 }
517 }
518 }
519
520 fn parse_one_attribute(&mut self, attrs: &mut Attributes, close: Punct) -> PResult<()> {
522 let start = self.cur_range();
523 let mut name = match &self.peek().kind {
526 TokenKind::Ident(name) => name.clone(),
527 TokenKind::Keyword(k) => k.as_str().to_owned(),
528 _ => {
529 let found = self.describe_cur();
530 return Err(self.error_bail(start, format!("expected an attribute, found {found}")));
531 }
532 };
533 self.advance();
534 let mut ours = false;
537 if self.at_punct(Punct::Colon) && self.nth(1).is_punct(Punct::Colon) {
538 self.advance();
539 self.advance();
540 let prefix = std::mem::take(&mut name);
541 name = match &self.peek().kind {
542 TokenKind::Ident(name) => name.clone(),
543 TokenKind::Keyword(k) => k.as_str().to_owned(),
544 _ => {
545 let found = self.describe_cur();
546 return Err(
547 self.error_bail(start, format!("expected an attribute, found {found}"))
548 );
549 }
550 };
551 self.advance();
552 if prefix == "cinrs" {
556 if gnu::cinrs_attribute(&name).is_none() {
557 self.skip_attribute_args()?;
558 let range = self.span_to_here(start);
559 self.error(
560 range,
561 format!(
562 "unknown 'cinrs' attribute '{name}'; the ones this crate has are {}",
563 Self::list_of_names(gnu::CINRS_ATTRIBUTES)
564 ),
565 );
566 return Ok(());
567 }
568 ours = true;
569 } else if prefix != "gnu" && prefix != "clang" {
570 self.skip_attribute_args()?;
571 return Ok(());
572 }
573 }
574
575 let known = if ours {
576 gnu::cinrs_attribute(&name)
577 } else {
578 gnu::attribute(&name)
579 };
580 match known {
584 Some(gnu::Attribute::Aligned) => {
585 let alignment = if self.at_punct(Punct::LParen) {
586 self.advance();
587 let expr = self.parse_conditional_expr()?;
588 self.expect_punct(Punct::RParen, " after the alignment")?;
589 AlignmentKind::Expr(expr)
590 } else {
591 AlignmentKind::Expr(int_expr(16, start))
594 };
595 let range = self.span_to_here(start);
596 attrs.aligned = Some(Alignment {
597 kind: alignment,
598 from_attribute: true,
599 range,
600 });
601 return Ok(());
602 }
603 Some(gnu::Attribute::Deprecated) => {
604 let message = self.attribute_string()?;
605 let range = self.span_to_here(start);
606 attrs.deprecated = Some(Spanned::new(message, range));
607 return Ok(());
608 }
609 Some(gnu::Attribute::Cleanup) => {
610 let func = self.attribute_identifier()?;
615 let range = self.span_to_here(start);
616 attrs.cleanup = Some(Cleanup { func, range });
617 return Ok(());
618 }
619 Some(gnu::Attribute::Mode) => {
620 let mode = self.attribute_identifier()?;
623 let range = self.span_to_here(start);
624 match mode {
625 Some(mode) => attrs.mode = Some(Spanned::new(mode.name, range)),
626 None => self.error(range, "'mode' takes one machine mode name"),
627 }
628 return Ok(());
629 }
630 Some(gnu::Attribute::Section) => {
631 let name = self.attribute_string()?;
632 let range = self.span_to_here(start);
633 match name {
634 Some(name) => attrs.section = Some(Spanned::new(name, range)),
635 None => self.error(range, "'section' takes one string literal"),
636 }
637 return Ok(());
638 }
639 _ => {}
640 }
641 self.skip_attribute_args()?;
642 let range = self.span_to_here(start);
643 match known {
644 Some(gnu::Attribute::Noreturn) => attrs.noreturn = attrs.noreturn.or(Some(range)),
645 Some(gnu::Attribute::AlwaysInline) => {
646 attrs.always_inline = attrs.always_inline.or(Some(range));
647 }
648 Some(gnu::Attribute::NoInline) => attrs.noinline = attrs.noinline.or(Some(range)),
649 Some(gnu::Attribute::Cold) => attrs.cold = attrs.cold.or(Some(range)),
650 Some(gnu::Attribute::Hot) => attrs.cold = None,
652 Some(gnu::Attribute::Packed) => attrs.packed = attrs.packed.or(Some(range)),
653 Some(gnu::Attribute::Constructor) => {
654 attrs.constructor = attrs.constructor.or(Some(range));
655 }
656 Some(gnu::Attribute::Destructor) => {
657 attrs.destructor = attrs.destructor.or(Some(range));
658 }
659 Some(gnu::Attribute::Safe) => attrs.safe = attrs.safe.or(Some(range)),
660 Some(gnu::Attribute::Weak) => attrs.weak = attrs.weak.or(Some(range)),
663 Some(gnu::Attribute::Fallthrough) | Some(gnu::Attribute::Ignored) => {}
666 Some(gnu::Attribute::Unsupported) => {
667 let reason = gnu::unsupported_reason(&name).unwrap_or("is not supported");
668 self.error(range, format!("'{name}' {reason}"));
669 }
670 _ => {}
673 }
674 let _ = close;
675 Ok(())
676 }
677
678 fn attribute_identifier(&mut self) -> PResult<Option<Ident>> {
681 if !self.at_punct(Punct::LParen) {
682 return Ok(None);
683 }
684 self.advance();
685 let name = match &self.peek().kind {
686 TokenKind::Ident(name) => {
687 let ident = Ident {
688 name: name.clone(),
689 range: self.cur_range(),
690 };
691 self.advance();
692 self.at_punct(Punct::RParen).then_some(ident)
694 }
695 _ => None,
696 };
697 let mut depth = 1i32;
698 while depth > 0 && !self.at_eof() {
699 if self.at_punct(Punct::LParen) {
700 depth += 1;
701 } else if self.at_punct(Punct::RParen) {
702 depth -= 1;
703 if depth == 0 {
704 self.advance();
705 break;
706 }
707 }
708 self.advance();
709 }
710 Ok(name)
711 }
712
713 fn attribute_string(&mut self) -> PResult<Option<String>> {
716 if !self.at_punct(Punct::LParen) {
717 return Ok(None);
718 }
719 self.advance();
720 let mut text = None;
721 if let TokenKind::Str(lit) = self.peek().kind.clone() {
722 let range = self.cur_range();
723 let literal = self.parse_string_literal(lit, range);
724 if let ExprKind::Str(lit) = literal.kind {
725 text = String::from_utf8(lit.values.iter().map(|v| *v as u8).collect()).ok();
726 }
727 }
728 let mut depth = 1i32;
730 while depth > 0 && !self.at_eof() {
731 if self.at_punct(Punct::LParen) {
732 depth += 1;
733 } else if self.at_punct(Punct::RParen) {
734 depth -= 1;
735 if depth == 0 {
736 self.advance();
737 break;
738 }
739 }
740 self.advance();
741 }
742 Ok(text)
743 }
744
745 fn skip_attribute_args(&mut self) -> PResult<()> {
747 if !self.at_punct(Punct::LParen) {
748 return Ok(());
749 }
750 let start = self.cur_range();
751 let mut depth = 0i32;
752 while !self.at_eof() {
753 if self.at_punct(Punct::LParen) {
754 depth += 1;
755 } else if self.at_punct(Punct::RParen) {
756 depth -= 1;
757 if depth == 0 {
758 self.advance();
759 return Ok(());
760 }
761 }
762 self.advance();
763 }
764 Err(self.error_bail(start, "unterminated attribute argument list"))
765 }
766
767 fn list_of_names(names: &[&str]) -> String {
770 let quoted: Vec<String> = names.iter().map(|name| format!("'{name}'")).collect();
771 match quoted.split_last() {
772 None => String::new(),
773 Some((last, [])) => last.clone(),
774 Some((last, rest)) => format!("{} and {last}", rest.join(", ")),
775 }
776 }
777
778 fn at_static_assert(&self) -> bool {
780 matches!(
781 self.peek().keyword(),
782 Some(Keyword::StaticAssert | Keyword::StaticAssertName)
783 )
784 }
785
786 fn parse_static_assert(&mut self) -> PResult<StaticAssert> {
789 let start = self.cur_range();
790 let keyword = self.peek().keyword().expect("the caller checked");
791 self.require_keyword(keyword, start);
792 self.advance();
793 let name = keyword.as_str();
794 self.expect_punct(Punct::LParen, &format!(" after '{name}'"))?;
795 let cond = self.parse_conditional_expr()?;
796 let mut message = None;
797 if self.eat_punct(Punct::Comma).is_some() {
798 let range = self.cur_range();
799 let TokenKind::Str(first) = self.peek().kind.clone() else {
800 let found = self.describe_cur();
801 return Err(self.error_bail(
802 range,
803 format!("expected a string literal as the message of '{name}', found {found}"),
804 ));
805 };
806 let literal = self.parse_string_literal(first, range);
807 if let ExprKind::Str(lit) = literal.kind {
808 message = Some(lit.text);
809 }
810 } else {
811 self.require_standard(
812 Standard::C23,
813 &format!("'{name}' without a message"),
814 self.span_to_here(start),
815 );
816 }
817 self.expect_punct(Punct::RParen, &format!(" to close '{name}'"))?;
818 self.expect_punct(Punct::Semi, &format!(" after '{name}'"))?;
819 Ok(StaticAssert {
820 cond,
821 message,
822 range: self.span_to_here(start),
823 })
824 }
825}
826
827impl Parser<'_> {
832 fn parse_translation_unit(&mut self, range: SourceRange) -> TranslationUnit {
833 let mut items = Vec::new();
834 while !self.at_eof() {
835 let before = self.pos;
836 self.depth = 0;
837 if self.at_punct(Punct::Semi) {
846 let range = self.bump_range();
847 if !self.gnu_leniency() {
848 self.error_gnu(range, "expected a declaration, found ';'");
849 }
850 continue;
851 }
852 match self.parse_external_decl() {
853 Ok(item) => items.push(item),
854 Err(Bail) => self.recover_top_level(before),
855 }
856 if self.pos == before {
857 self.advance();
858 }
859 }
860 TranslationUnit {
861 items,
862 records: std::mem::take(&mut self.records),
863 enums: std::mem::take(&mut self.enums),
864 typeofs: std::mem::take(&mut self.typeofs),
865 range,
866 }
867 }
868
869 fn depth_from(&self, start: usize) -> i32 {
872 let mut depth = 0i32;
873 for tok in &self.tokens[start.min(self.pos)..self.pos] {
874 match &tok.kind {
875 TokenKind::Punct(Punct::LBrace | Punct::LParen | Punct::LBracket) => depth += 1,
876 TokenKind::Punct(Punct::RBrace | Punct::RParen | Punct::RBracket) => depth -= 1,
877 _ => {}
878 }
879 }
880 depth.max(0)
881 }
882
883 fn recover_top_level(&mut self, decl_start: usize) {
890 let mut depth = self.depth_from(decl_start);
891 while !self.at_eof() {
892 match &self.peek().kind {
893 TokenKind::Punct(Punct::LBrace | Punct::LParen | Punct::LBracket) => {
894 depth += 1;
895 self.advance();
896 }
897 TokenKind::Punct(Punct::RBrace | Punct::RParen | Punct::RBracket) => {
898 let paren = self.at_punct(Punct::RParen) || self.at_punct(Punct::RBracket);
899 depth -= 1;
900 self.advance();
901 if depth <= 0 {
902 if self.eat_punct(Punct::Semi).is_some() {
906 return;
907 }
908 if paren && self.at_punct(Punct::LBrace) {
914 depth = 0;
915 continue;
916 }
917 return;
918 }
919 }
920 TokenKind::Punct(Punct::Semi) => {
921 self.advance();
922 if depth <= 0 {
923 return;
924 }
925 }
926 _ => self.advance(),
927 }
928 }
929 }
930
931 fn parse_external_decl(&mut self) -> PResult<ExternalDecl> {
932 let start = self.cur_range();
933 self.in_extension = false;
939 while self.eat_keyword(Keyword::Extension).is_some() {
940 self.in_extension = true;
941 }
942 let attrs = self.parse_attributes()?;
943 if self.at_static_assert() {
944 return Ok(ExternalDecl::StaticAssert(self.parse_static_assert()?));
945 }
946 let mut specs = self.parse_decl_specifiers(true)?;
947 specs.attrs.merge(attrs);
948 specs.noreturn = specs.noreturn.or(specs.attrs.noreturn);
949
950 if let Some(semi) = self.eat_punct(Punct::Semi) {
951 return Ok(ExternalDecl::Decl(Decl {
952 specifiers: specs,
953 declarators: Vec::new(),
954 range: start.join(semi),
955 }));
956 }
957
958 let mut first = self.parse_declarator(specs.base.clone(), false)?;
959 self.parse_declarator_tail(&mut first)?;
960
961 let looks_like_definition = matches!(first.ty.kind, TypeKind::Function(_))
962 && (self.at_punct(Punct::LBrace) || self.starts_declaration());
963 if looks_like_definition && !specs.is_typedef() {
964 return self.finish_function_def(specs, first, start);
965 }
966
967 let decl = self.finish_declaration(specs, Some(first), start)?;
968 Ok(ExternalDecl::Decl(decl))
969 }
970
971 fn parse_declarator_tail(&mut self, declarator: &mut DeclaratorResult) -> PResult<()> {
974 loop {
975 if self.at_keyword(Keyword::Asm) {
976 let start = self.cur_range();
977 self.advance();
978 self.expect_punct(Punct::LParen, " after 'asm'")?;
979 let range = self.cur_range();
980 let TokenKind::Str(lit) = self.peek().kind.clone() else {
981 let found = self.describe_cur();
982 return Err(self.error_bail(
983 range,
984 format!("expected the symbol name as a string literal, found {found}"),
985 ));
986 };
987 let literal = self.parse_string_literal(lit, range);
988 self.expect_punct(Punct::RParen, " after the symbol name")?;
989 if let ExprKind::Str(lit) = literal.kind
990 && let Ok(name) =
991 String::from_utf8(lit.values.iter().map(|v| *v as u8).collect())
992 {
993 declarator.asm_label = Some(Spanned::new(name, self.span_to_here(start)));
994 }
995 continue;
996 }
997 if self.at_attributes() {
998 let attrs = self.parse_attributes()?;
999 declarator.attrs.merge(attrs);
1000 continue;
1001 }
1002 return Ok(());
1003 }
1004 }
1005
1006 fn parse_kr_declaration_list(&mut self) -> PResult<Vec<Decl>> {
1015 let mut decls = Vec::new();
1016 loop {
1017 if self.at_static_assert() {
1018 let range = self.cur_range();
1019 self.error(
1020 range,
1021 "a static assertion is not allowed in the declaration list of an old-style \
1022 function definition; every declaration there has to declare one of the \
1023 parameters (C99 6.9.1p6)",
1024 );
1025 self.parse_static_assert()?;
1026 continue;
1027 }
1028 if !self.starts_declaration() {
1029 return Ok(decls);
1030 }
1031 decls.push(self.parse_declaration()?);
1032 }
1033 }
1034
1035 fn finish_function_def(
1036 &mut self,
1037 specs: DeclSpecifiers,
1038 declarator: DeclaratorResult,
1039 start: SourceRange,
1040 ) -> PResult<ExternalDecl> {
1041 let Some(name) = declarator.name.clone() else {
1042 return Err(self.error_bail(declarator.range, "function definition requires a name"));
1043 };
1044 self.declare(&name.name, SymKind::Ordinary);
1045
1046 self.push_scope();
1049 if let TypeKind::Function(ft) = &declarator.ty.kind {
1050 for param in &ft.params {
1051 if let Some(pname) = ¶m.name {
1052 self.scopes
1053 .last_mut()
1054 .expect("scope stack is never empty")
1055 .syms
1056 .insert(pname.name.clone(), SymKind::Ordinary);
1057 }
1058 }
1059 for kr in &ft.kr_names {
1060 self.scopes
1061 .last_mut()
1062 .expect("scope stack is never empty")
1063 .syms
1064 .insert(kr.name.clone(), SymKind::Ordinary);
1065 }
1066 }
1067
1068 let kr_decls = match self.parse_kr_declaration_list() {
1069 Ok(decls) => decls,
1070 Err(bail) => {
1071 self.pop_scope();
1072 return Err(bail);
1073 }
1074 };
1075
1076 let before = self.label_addrs;
1077 let body = match self.parse_compound_stmt() {
1078 Ok(body) => body,
1079 Err(bail) => {
1080 self.pop_scope();
1081 return Err(bail);
1082 }
1083 };
1084 self.pop_scope();
1085
1086 Ok(ExternalDecl::Function(FunctionDef {
1087 specifiers: specs,
1088 name,
1089 ty: declarator.ty,
1090 kr_decls,
1091 attrs: declarator.attrs,
1092 asm_label: declarator.asm_label,
1093 body,
1094 uses_label_addrs: self.label_addrs != before,
1095 range: self.span_to_here(start),
1096 }))
1097 }
1098
1099 fn finish_declaration(
1101 &mut self,
1102 specs: DeclSpecifiers,
1103 first: Option<DeclaratorResult>,
1104 start: SourceRange,
1105 ) -> PResult<Decl> {
1106 let is_typedef = specs.is_typedef();
1107 let mut declarators = Vec::new();
1108 let mut pending = first;
1109 loop {
1110 let mut declarator = match pending.take() {
1111 Some(d) => d,
1112 None => {
1113 let mut d = self.parse_declarator(specs.base.clone(), false)?;
1114 self.parse_declarator_tail(&mut d)?;
1115 d
1116 }
1117 };
1118 if let Some(name) = &declarator.name {
1119 let kind = if is_typedef {
1120 SymKind::Typedef
1121 } else {
1122 SymKind::Ordinary
1123 };
1124 self.declare(&name.name.clone(), kind);
1125 }
1126 let init = if self.eat_punct(Punct::Assign).is_some() {
1127 Some(self.parse_initializer()?)
1128 } else {
1129 None
1130 };
1131 if self.at_attributes() {
1133 let attrs = self.parse_attributes()?;
1134 declarator.attrs.merge(attrs);
1135 }
1136 let range = self.span_to_here(declarator.range);
1137 declarators.push(InitDeclarator {
1138 name: declarator.name,
1139 ty: declarator.ty,
1140 init,
1141 attrs: declarator.attrs,
1142 asm_label: declarator.asm_label,
1143 range,
1144 });
1145 if self.eat_punct(Punct::Comma).is_none() {
1146 break;
1147 }
1148 }
1149 let semi = self.expect_punct(Punct::Semi, " after declaration")?;
1150 Ok(Decl {
1151 specifiers: specs,
1152 declarators,
1153 range: start.join(semi),
1154 })
1155 }
1156
1157 fn parse_declaration(&mut self) -> PResult<Decl> {
1166 let enclosing = std::mem::take(&mut self.in_extension);
1171 let result = self.parse_declaration_inner();
1172 self.in_extension = enclosing;
1173 result
1174 }
1175
1176 fn parse_declaration_inner(&mut self) -> PResult<Decl> {
1177 let (specs, start) = self.parse_declaration_head()?;
1178 if let Some(semi) = self.eat_punct(Punct::Semi) {
1179 return Ok(Decl {
1180 specifiers: specs,
1181 declarators: Vec::new(),
1182 range: start.join(semi),
1183 });
1184 }
1185 self.finish_declaration(specs, None, start)
1186 }
1187
1188 fn parse_declaration_head(&mut self) -> PResult<(DeclSpecifiers, SourceRange)> {
1192 let start = self.cur_range();
1193 while self.eat_keyword(Keyword::Extension).is_some() {
1194 self.in_extension = true;
1195 }
1196 let attrs = self.parse_attributes()?;
1197 let mut specs = self.parse_decl_specifiers(true)?;
1198 specs.attrs.merge(attrs);
1199 specs.noreturn = specs.noreturn.or(specs.attrs.noreturn);
1200 Ok((specs, start))
1201 }
1202
1203 fn parse_block_declaration(&mut self) -> PResult<BlockItem> {
1209 let enclosing = std::mem::take(&mut self.in_extension);
1210 let result = self.parse_block_declaration_inner();
1211 self.in_extension = enclosing;
1212 result
1213 }
1214
1215 fn parse_block_declaration_inner(&mut self) -> PResult<BlockItem> {
1216 let (specs, start) = self.parse_declaration_head()?;
1217 if let Some(semi) = self.eat_punct(Punct::Semi) {
1218 return Ok(BlockItem::Decl(Decl {
1219 specifiers: specs,
1220 declarators: Vec::new(),
1221 range: start.join(semi),
1222 }));
1223 }
1224 let mut first = self.parse_declarator(specs.base.clone(), false)?;
1228 self.parse_declarator_tail(&mut first)?;
1229 if self.at_nested_function_body(&specs, &first) {
1230 return self
1231 .parse_nested_function(specs, first, start)
1232 .map(BlockItem::NestedFunction);
1233 }
1234 self.finish_declaration(specs, Some(first), start)
1235 .map(BlockItem::Decl)
1236 }
1237
1238 fn at_nested_function_body(
1247 &self,
1248 specs: &DeclSpecifiers,
1249 declarator: &DeclaratorResult,
1250 ) -> bool {
1251 declarator.name.is_some()
1252 && !specs.is_typedef()
1253 && matches!(declarator.ty.kind, TypeKind::Function(_))
1254 && (self.at_punct(Punct::LBrace) || self.at_kr_declaration_list())
1255 }
1256
1257 fn at_kr_declaration_list(&self) -> bool {
1264 let mut n = 0;
1265 while self.starts_decl_specifier(n) {
1266 let mut depth = 0i32;
1267 loop {
1268 let tok = self.nth(n);
1269 if tok.is_eof() {
1270 return false;
1271 }
1272 n += 1;
1273 match &tok.kind {
1274 TokenKind::Punct(Punct::LBrace | Punct::LParen | Punct::LBracket) => depth += 1,
1275 TokenKind::Punct(Punct::RBrace | Punct::RParen | Punct::RBracket) => {
1276 depth -= 1;
1277 if depth < 0 {
1278 return false;
1279 }
1280 }
1281 TokenKind::Punct(Punct::Semi) if depth == 0 => break,
1282 _ => {}
1283 }
1284 }
1285 }
1286 n > 0 && self.nth(n).is_punct(Punct::LBrace)
1287 }
1288
1289 fn parse_nested_function(
1299 &mut self,
1300 specs: DeclSpecifiers,
1301 declarator: DeclaratorResult,
1302 start: SourceRange,
1303 ) -> PResult<FunctionDef> {
1304 let name = declarator
1305 .name
1306 .clone()
1307 .expect("at_nested_function_body requires a name");
1308 self.declare(&name.name, SymKind::Ordinary);
1309
1310 self.push_scope();
1313 if let TypeKind::Function(ft) = &declarator.ty.kind {
1314 for param in &ft.params {
1315 if let Some(pname) = ¶m.name {
1316 self.scopes
1317 .last_mut()
1318 .expect("scope stack is never empty")
1319 .syms
1320 .insert(pname.name.clone(), SymKind::Ordinary);
1321 }
1322 }
1323 for kr in &ft.kr_names {
1324 self.scopes
1325 .last_mut()
1326 .expect("scope stack is never empty")
1327 .syms
1328 .insert(kr.name.clone(), SymKind::Ordinary);
1329 }
1330 }
1331
1332 let kr_decls = match self.parse_kr_declaration_list() {
1333 Ok(decls) => decls,
1334 Err(bail) => {
1335 self.pop_scope();
1336 return Err(bail);
1337 }
1338 };
1339
1340 let before = self.label_addrs;
1341 let body = match self.parse_compound_stmt() {
1342 Ok(body) => body,
1343 Err(bail) => {
1344 self.pop_scope();
1345 return Err(bail);
1346 }
1347 };
1348 self.pop_scope();
1349 let uses_label_addrs = self.label_addrs != before;
1350 self.label_addrs = before;
1353
1354 Ok(FunctionDef {
1355 specifiers: specs,
1356 name,
1357 ty: declarator.ty,
1358 kr_decls,
1359 attrs: declarator.attrs,
1360 asm_label: declarator.asm_label,
1361 body,
1362 uses_label_addrs,
1363 range: self.span_to_here(start),
1364 })
1365 }
1366}
1367
1368#[derive(Default)]
1374struct SpecCounts {
1375 void: u32,
1376 char: u32,
1377 short: u32,
1378 int: u32,
1379 long: u32,
1380 float: u32,
1381 double: u32,
1382 signed: u32,
1383 unsigned: u32,
1384 bool: u32,
1385 complex: u32,
1386 imaginary: u32,
1387 int128: u32,
1388}
1389
1390impl SpecCounts {
1391 fn any(&self) -> bool {
1392 self.void
1393 + self.char
1394 + self.short
1395 + self.int
1396 + self.long
1397 + self.float
1398 + self.double
1399 + self.signed
1400 + self.unsigned
1401 + self.bool
1402 + self.complex
1403 + self.imaginary
1404 + self.int128
1405 > 0
1406 }
1407}
1408
1409impl Parser<'_> {
1410 fn starts_declaration(&self) -> bool {
1412 self.starts_decl_specifier(0)
1413 }
1414
1415 fn starts_declarator(&self) -> bool {
1421 let tok = self.peek();
1422 tok.ident().is_some() || tok.is_punct(Punct::Star) || tok.is_punct(Punct::LParen)
1423 }
1424
1425 fn starts_decl_specifier(&self, n: usize) -> bool {
1428 let tok = self.nth(n);
1429 if let Some(k) = tok.keyword() {
1430 return matches!(
1431 k,
1432 Keyword::Typedef
1433 | Keyword::Extern
1434 | Keyword::Static
1435 | Keyword::Auto
1436 | Keyword::Register
1437 | Keyword::Const
1438 | Keyword::Volatile
1439 | Keyword::Restrict
1440 | Keyword::Inline
1441 | Keyword::Void
1442 | Keyword::Char
1443 | Keyword::Short
1444 | Keyword::Int
1445 | Keyword::Long
1446 | Keyword::Float
1447 | Keyword::Double
1448 | Keyword::Signed
1449 | Keyword::Unsigned
1450 | Keyword::Bool
1451 | Keyword::Complex
1452 | Keyword::Imaginary
1453 | Keyword::Struct
1454 | Keyword::Union
1455 | Keyword::Enum
1456 | Keyword::Alignas
1457 | Keyword::AlignasName
1458 | Keyword::Atomic
1459 | Keyword::BitInt
1460 | Keyword::Noreturn
1461 | Keyword::ThreadLocal
1462 | Keyword::ThreadLocalName
1463 | Keyword::Constexpr
1464 | Keyword::Typeof
1465 | Keyword::TypeofUnqual
1466 | Keyword::BoolName
1467 | Keyword::Attribute
1468 | Keyword::Extension
1469 | Keyword::TypeofGnu
1470 | Keyword::TypeofUnqualGnu
1471 | Keyword::AutoType
1472 | Keyword::ThreadGnu
1473 | Keyword::Int128
1474 | Keyword::InlineGnu
1475 | Keyword::RestrictGnu
1476 );
1477 }
1478 match tok.ident() {
1479 Some(NORETURN_BUILTIN) => true,
1480 Some(name) => self.is_typedef_name(name) && !self.nth(n + 1).is_punct(Punct::Colon),
1483 None => false,
1484 }
1485 }
1486
1487 fn eat_type_qualifier(&mut self) -> Option<TypeQualifiers> {
1488 let keyword = self.peek().keyword()?;
1489 let q = match keyword {
1490 Keyword::Const => TypeQualifiers {
1491 is_const: true,
1492 ..TypeQualifiers::NONE
1493 },
1494 Keyword::Volatile => TypeQualifiers {
1495 is_volatile: true,
1496 ..TypeQualifiers::NONE
1497 },
1498 Keyword::Restrict | Keyword::RestrictGnu => TypeQualifiers {
1499 is_restrict: true,
1500 ..TypeQualifiers::NONE
1501 },
1502 Keyword::Atomic if !self.at_atomic_specifier(0) => TypeQualifiers {
1506 is_atomic: true,
1507 ..TypeQualifiers::NONE
1508 },
1509 _ => return None,
1510 };
1511 if keyword == Keyword::Restrict {
1514 let range = self.cur_range();
1515 self.require_standard(Standard::C99, "'restrict'", range);
1516 }
1517 if keyword == Keyword::Atomic {
1518 let range = self.cur_range();
1519 self.require_keyword(Keyword::Atomic, range);
1520 }
1521 self.advance();
1522 Some(q)
1523 }
1524
1525 fn at_atomic_specifier(&self, n: usize) -> bool {
1532 self.nth(n).is_keyword(Keyword::Atomic)
1533 && self.nth(n + 1).is_punct(Punct::LParen)
1534 && self.starts_decl_specifier(n + 2)
1535 }
1536
1537 fn parse_type_qualifiers(&mut self) -> TypeQualifiers {
1538 let mut quals = TypeQualifiers::NONE;
1539 while let Some(q) = self.eat_type_qualifier() {
1540 quals = quals.merge(q);
1541 }
1542 quals
1543 }
1544
1545 fn parse_decl_specifiers(&mut self, allow_storage: bool) -> PResult<DeclSpecifiers> {
1548 let start = self.cur_range();
1549 let mut storage: Option<Spanned<StorageClass>> = None;
1550 let mut thread_local: Option<SourceRange> = None;
1551 let mut inline = false;
1552 let mut noreturn: Option<SourceRange> = None;
1553 let mut alignas: Vec<Alignment> = Vec::new();
1554 let mut attributes = Attributes::default();
1555 let mut quals = TypeQualifiers::NONE;
1556 let mut counts = SpecCounts::default();
1557 let mut tag: Option<Type> = None;
1558 let mut typedef_name: Option<Ident> = None;
1559 let mut auto_type: Option<SourceRange> = None;
1560 let mut auto_kw: Option<SourceRange> = None;
1564 let mut consumed_any = false;
1565
1566 loop {
1567 let has_type = counts.any() || tag.is_some() || typedef_name.is_some();
1568 if self.at_attributes() {
1571 let attrs = self.parse_attributes()?;
1572 noreturn = noreturn.or(attrs.noreturn);
1573 attributes.merge(attrs);
1574 consumed_any = true;
1575 continue;
1576 }
1577 if self.at_keyword(Keyword::Extension) {
1578 self.advance();
1579 self.in_extension = true;
1580 consumed_any = true;
1581 continue;
1582 }
1583 if let Some(k) = self.peek().keyword() {
1584 if matches!(
1588 k,
1589 Keyword::ThreadLocal | Keyword::ThreadLocalName | Keyword::ThreadGnu
1590 ) {
1591 let range = self.bump_range();
1592 self.require_keyword(k, range);
1593 consumed_any = true;
1594 if !allow_storage {
1595 self.error(
1596 range,
1597 format!("storage class '{}' is not allowed here", k.as_str()),
1598 );
1599 } else if thread_local.is_none() {
1600 thread_local = Some(range);
1601 }
1602 continue;
1603 }
1604 let storage_class = match k {
1605 Keyword::Typedef => Some(StorageClass::Typedef),
1606 Keyword::Extern => Some(StorageClass::Extern),
1607 Keyword::Static => Some(StorageClass::Static),
1608 Keyword::Auto => Some(StorageClass::Auto),
1609 Keyword::Register => Some(StorageClass::Register),
1610 Keyword::Constexpr => Some(StorageClass::Constexpr),
1611 _ => None,
1612 };
1613 if let Some(sc) = storage_class {
1614 let range = self.bump_range();
1615 self.require_keyword(k, range);
1616 consumed_any = true;
1617 let c23_auto = allow_storage
1629 && self.standard >= Standard::C23
1630 && (sc == StorageClass::Auto
1631 || matches!(
1632 storage,
1633 Some(Spanned {
1634 node: StorageClass::Auto,
1635 ..
1636 })
1637 ))
1638 && sc != StorageClass::Typedef
1639 && !matches!(
1640 storage,
1641 Some(Spanned {
1642 node: StorageClass::Typedef,
1643 ..
1644 })
1645 );
1646 let pairs_with_constexpr = |s: StorageClass| {
1656 matches!(
1657 s,
1658 StorageClass::Static | StorageClass::Register | StorageClass::Auto
1659 )
1660 };
1661 let c23_constexpr = allow_storage
1662 && self.standard >= Standard::C23
1663 && match (sc, storage.as_ref().map(|s| s.node)) {
1664 (StorageClass::Constexpr, Some(prev)) => pairs_with_constexpr(prev),
1665 (other, Some(StorageClass::Constexpr)) => pairs_with_constexpr(other),
1666 _ => false,
1667 };
1668 if sc == StorageClass::Auto {
1669 auto_kw = auto_kw.or(Some(range));
1670 }
1671 if !allow_storage {
1672 self.error(
1673 range,
1674 format!("storage class '{}' is not allowed here", sc.as_str()),
1675 );
1676 } else if c23_constexpr {
1677 if sc == StorageClass::Constexpr {
1678 storage = Some(Spanned::new(sc, range));
1679 }
1680 } else if c23_auto {
1681 if sc != StorageClass::Auto || storage.is_none() {
1687 storage = Some(Spanned::new(sc, range));
1688 }
1689 } else if let Some(prev) = &storage {
1690 self.error(
1691 range,
1692 format!(
1693 "cannot combine storage class '{}' with '{}'",
1694 sc.as_str(),
1695 prev.node.as_str()
1696 ),
1697 );
1698 } else {
1699 storage = Some(Spanned::new(sc, range));
1700 }
1701 continue;
1702 }
1703 if let Some(q) = self.eat_type_qualifier() {
1704 quals = quals.merge(q);
1705 consumed_any = true;
1706 continue;
1707 }
1708 if matches!(k, Keyword::Inline | Keyword::InlineGnu) {
1709 let range = self.bump_range();
1710 if k == Keyword::Inline {
1713 self.require_standard(Standard::C99, "'inline'", range);
1714 }
1715 inline = true;
1716 consumed_any = true;
1717 continue;
1718 }
1719 if k == Keyword::Noreturn {
1720 let range = self.bump_range();
1721 self.require_keyword(k, range);
1722 noreturn = noreturn.or(Some(range));
1723 consumed_any = true;
1724 continue;
1725 }
1726 if matches!(k, Keyword::Alignas | Keyword::AlignasName) {
1727 let spec = self.parse_alignment_specifier(k)?;
1731 alignas.push(spec);
1732 consumed_any = true;
1733 continue;
1734 }
1735 if k == Keyword::AutoType {
1738 let range = self.bump_range();
1739 auto_type = auto_type.or(Some(range));
1740 consumed_any = true;
1741 continue;
1742 }
1743 if matches!(
1744 k,
1745 Keyword::Typeof
1746 | Keyword::TypeofUnqual
1747 | Keyword::TypeofGnu
1748 | Keyword::TypeofUnqualGnu
1749 ) {
1750 let ty = self.parse_typeof_specifier(k)?;
1751 if tag.is_some() || has_type {
1752 self.error(ty.range, "two or more data types in declaration specifiers");
1753 } else {
1754 tag = Some(ty);
1755 }
1756 consumed_any = true;
1757 continue;
1758 }
1759 if k == Keyword::Atomic {
1763 let range = self.bump_range();
1764 self.require_keyword(k, range);
1765 self.expect_punct(Punct::LParen, " after '_Atomic'")?;
1766 let inner = self.parse_type_name()?;
1767 self.expect_punct(Punct::RParen, " after the type name")?;
1768 if tag.is_some() || has_type {
1769 self.error(range, "two or more data types in declaration specifiers");
1770 } else {
1771 tag = Some(inner.ty);
1772 }
1773 quals = quals.merge(TypeQualifiers {
1774 is_atomic: true,
1775 ..TypeQualifiers::NONE
1776 });
1777 consumed_any = true;
1778 continue;
1779 }
1780 if k == Keyword::BitInt {
1783 let range = self.bump_range();
1784 self.error(range, format!("'{}' is not supported yet", k.as_str()));
1785 if self.at_punct(Punct::LParen) {
1786 self.advance();
1787 let _ = self.parse_conditional_expr()?;
1788 self.expect_punct(Punct::RParen, " after the operand")?;
1789 }
1790 counts.int += 1;
1793 consumed_any = true;
1794 continue;
1795 }
1796 let counter = match k {
1797 Keyword::Void => Some(&mut counts.void),
1798 Keyword::Char => Some(&mut counts.char),
1799 Keyword::Short => Some(&mut counts.short),
1800 Keyword::Int => Some(&mut counts.int),
1801 Keyword::Long => Some(&mut counts.long),
1802 Keyword::Float => Some(&mut counts.float),
1803 Keyword::Double => Some(&mut counts.double),
1804 Keyword::Signed => Some(&mut counts.signed),
1805 Keyword::Unsigned => Some(&mut counts.unsigned),
1806 Keyword::Bool | Keyword::BoolName => Some(&mut counts.bool),
1807 Keyword::Complex => Some(&mut counts.complex),
1808 Keyword::Imaginary => Some(&mut counts.imaginary),
1809 Keyword::Int128 => Some(&mut counts.int128),
1810 _ => None,
1811 };
1812 if let Some(c) = counter {
1813 *c += 1;
1814 self.advance();
1815 consumed_any = true;
1816 continue;
1817 }
1818 if matches!(k, Keyword::Struct | Keyword::Union) {
1819 let ty = self.parse_record_specifier()?;
1820 if tag.is_some() || has_type {
1821 self.error(ty.range, "two or more data types in declaration specifiers");
1822 } else {
1823 tag = Some(ty);
1824 }
1825 consumed_any = true;
1826 continue;
1827 }
1828 if k == Keyword::Enum {
1829 let ty = self.parse_enum_specifier()?;
1830 if tag.is_some() || has_type {
1831 self.error(ty.range, "two or more data types in declaration specifiers");
1832 } else {
1833 tag = Some(ty);
1834 }
1835 consumed_any = true;
1836 continue;
1837 }
1838 break;
1839 }
1840
1841 if self.peek().ident() == Some(NORETURN_BUILTIN) {
1846 let range = self.bump_range();
1847 noreturn = noreturn.or(Some(range));
1848 consumed_any = true;
1849 continue;
1850 }
1851
1852 if !has_type
1857 && let Some(name) = self.peek().ident()
1858 && let Some(what) = extended_float_type(name)
1859 {
1860 let range = self.cur_range();
1861 return Err(self.error_bail(
1862 range,
1863 format!(
1864 "'{name}' is not supported: {what} has no Rust type to become, and \
1865 mapping it onto 'double' would compute and pass the wrong values"
1866 ),
1867 ));
1868 }
1869
1870 let is_typedef_use = match self.peek().ident() {
1873 Some(name) => !has_type && self.is_typedef_name(name),
1874 None => false,
1875 };
1876 if is_typedef_use {
1877 let id = self.eat_ident().expect("checked above");
1878 typedef_name = Some(id);
1879 consumed_any = true;
1880 continue;
1881 }
1882 break;
1883 }
1884
1885 if !consumed_any {
1886 let range = self.cur_range();
1887 if let Some(message) = self.newer_keyword_here() {
1892 return Err(self.error_bail(range, message));
1893 }
1894 if !self.starts_declarator() {
1902 let found = self.describe_cur();
1903 return Err(
1904 self.error_bail(range, format!("expected a declaration, found {found}"))
1905 );
1906 }
1907 }
1908
1909 let specs_range = if consumed_any {
1913 self.span_to_here(start)
1914 } else {
1915 self.cur_range()
1916 };
1917 let no_type = !counts.any() && tag.is_none() && typedef_name.is_none();
1920 let inferred = no_type
1921 && (auto_type.is_some() || (self.standard >= Standard::C23 && auto_kw.is_some()));
1922 let base = if inferred {
1923 Type::new(TypeKind::Auto, quals, specs_range)
1924 } else {
1925 self.build_base_type(&counts, tag, typedef_name, quals, specs_range)
1926 };
1927 if let Some(aligned) = attributes.aligned.clone() {
1930 alignas.push(aligned);
1931 }
1932
1933 Ok(DeclSpecifiers {
1934 storage,
1935 thread_local,
1936 inline,
1937 noreturn,
1938 alignas,
1939 attrs: attributes,
1940 base,
1941 range: specs_range,
1942 })
1943 }
1944
1945 fn parse_alignment_specifier(&mut self, keyword: Keyword) -> PResult<Alignment> {
1947 let start = self.cur_range();
1948 self.require_keyword(keyword, start);
1949 self.advance();
1950 let name = keyword.as_str();
1951 self.expect_punct(Punct::LParen, &format!(" after '{name}'"))?;
1952 let kind = if self.starts_declaration() {
1953 AlignmentKind::Type(Box::new(self.parse_type_name()?))
1954 } else {
1955 AlignmentKind::Expr(self.parse_conditional_expr()?)
1956 };
1957 self.expect_punct(Punct::RParen, &format!(" after the operand of '{name}'"))?;
1958 Ok(Alignment {
1959 kind,
1960 from_attribute: false,
1961 range: self.span_to_here(start),
1962 })
1963 }
1964
1965 fn parse_typeof_specifier(&mut self, keyword: Keyword) -> PResult<Type> {
1973 let start = self.cur_range();
1974 self.require_keyword(keyword, start);
1975 self.advance();
1976 let name = keyword.as_str();
1977 self.expect_punct(Punct::LParen, &format!(" after '{name}'"))?;
1978 let operand = if self.starts_declaration() {
1979 TypeofOperand::Type(self.parse_type_name()?)
1980 } else {
1981 TypeofOperand::Expr(self.parse_expr()?)
1982 };
1983 self.expect_punct(Punct::RParen, &format!(" after the operand of '{name}'"))?;
1984 let range = self.span_to_here(start);
1985 let id = self.add_typeof(operand);
1986 let unqual = matches!(keyword, Keyword::TypeofUnqual | Keyword::TypeofUnqualGnu);
1987 Ok(Type::plain(TypeKind::Typeof { id, unqual }, range))
1988 }
1989
1990 fn build_base_type(
1991 &mut self,
1992 counts: &SpecCounts,
1993 tag: Option<Type>,
1994 typedef_name: Option<Ident>,
1995 quals: TypeQualifiers,
1996 range: SourceRange,
1997 ) -> Type {
1998 if let Some(mut ty) = tag {
1999 if counts.any() || typedef_name.is_some() {
2000 self.error(range, "two or more data types in declaration specifiers");
2001 }
2002 ty.qualifiers = ty.qualifiers.merge(quals);
2003 return ty;
2004 }
2005 if let Some(name) = typedef_name {
2006 if counts.any() {
2007 self.error(range, "two or more data types in declaration specifiers");
2008 }
2009 return Type::new(TypeKind::Typedef(name), quals, range);
2010 }
2011 if !counts.any() {
2012 if !self.gating.implicit_int() {
2017 self.error(
2018 range,
2019 "type specifier missing; C99 does not support implicit 'int'",
2020 );
2021 }
2022 return Type::new(
2023 TypeKind::Int {
2024 sign: Sign::Signed,
2025 size: IntSize::Int,
2026 },
2027 quals,
2028 range,
2029 );
2030 }
2031 if counts.bool > 0 {
2032 self.require_standard(Standard::C99, "'_Bool'", range);
2033 }
2034 if counts.complex > 0 {
2035 self.require_standard(Standard::C99, "'_Complex'", range);
2036 }
2037 if counts.imaginary > 0 {
2038 self.require_standard(Standard::C99, "'_Imaginary'", range);
2039 }
2040 if counts.long > 1 {
2041 self.require_standard(Standard::C99, "'long long'", range);
2042 }
2043 if (counts.complex > 0 || counts.imaginary > 0)
2049 && counts.float == 0
2050 && counts.double == 0
2051 && counts.int
2052 + counts.char
2053 + counts.short
2054 + counts.long
2055 + counts.signed
2056 + counts.unsigned
2057 + counts.int128
2058 + counts.bool
2059 + counts.void
2060 > 0
2061 {
2062 self.error(
2063 range,
2064 "a complex integer type is a GNU extension that cinrs does not support; \
2065 the complex types are 'float _Complex', 'double _Complex' and \
2066 'long double _Complex'",
2067 );
2068 let kind = if counts.complex > 0 {
2069 TypeKind::Complex(FloatSize::Double)
2070 } else {
2071 TypeKind::Imaginary(FloatSize::Double)
2072 };
2073 return Type::new(kind, quals, range);
2074 }
2075
2076 let sign = if counts.unsigned > 0 {
2077 Some(Sign::Unsigned)
2078 } else if counts.signed > 0 {
2079 Some(Sign::Signed)
2080 } else {
2081 None
2082 };
2083 if counts.signed > 0 && counts.unsigned > 0 {
2084 self.error(range, "cannot combine 'signed' with 'unsigned'");
2085 }
2086
2087 let kind = if counts.void > 0 {
2088 if counts.void > 1 || counts.any_besides(&["void"]) {
2089 self.error(range, "cannot combine 'void' with other type specifiers");
2090 }
2091 TypeKind::Void
2092 } else if counts.bool > 0 {
2093 if counts.any_besides(&["_Bool"]) {
2094 self.error(range, "cannot combine '_Bool' with other type specifiers");
2095 }
2096 TypeKind::Bool
2097 } else if counts.char > 0 {
2098 if counts.any_besides(&["char", "signed", "unsigned"]) {
2099 self.error(range, "cannot combine 'char' with other type specifiers");
2100 }
2101 TypeKind::Char(sign)
2102 } else if counts.float > 0 || counts.double > 0 {
2103 let size = if counts.float > 0 {
2104 if counts.double > 0 {
2105 self.error(range, "cannot combine 'float' with 'double'");
2106 }
2107 if counts.long > 0 {
2108 self.error(range, "cannot combine 'long' with 'float'");
2109 }
2110 FloatSize::Float
2111 } else if counts.long > 0 {
2112 FloatSize::LongDouble
2113 } else {
2114 FloatSize::Double
2115 };
2116 if sign.is_some() {
2117 self.error(
2118 range,
2119 "cannot combine 'signed' or 'unsigned' with a floating type",
2120 );
2121 }
2122 if counts.complex > 0 {
2123 TypeKind::Complex(size)
2124 } else if counts.imaginary > 0 {
2125 TypeKind::Imaginary(size)
2126 } else {
2127 TypeKind::Float(size)
2128 }
2129 } else if counts.complex > 0 || counts.imaginary > 0 {
2130 if counts.complex > 0 {
2134 TypeKind::Complex(FloatSize::Double)
2135 } else {
2136 TypeKind::Imaginary(FloatSize::Double)
2137 }
2138 } else if counts.int128 > 0 {
2139 if counts.int128 > 1 || counts.any_besides(&["__int128", "signed", "unsigned"]) {
2142 self.error(
2143 range,
2144 "cannot combine '__int128' with other type specifiers",
2145 );
2146 }
2147 TypeKind::Int {
2148 sign: sign.unwrap_or(Sign::Signed),
2149 size: IntSize::Int128,
2150 }
2151 } else {
2152 let size = if counts.short > 0 {
2153 if counts.long > 0 {
2154 self.error(range, "cannot combine 'short' with 'long'");
2155 }
2156 IntSize::Short
2157 } else {
2158 match counts.long {
2159 0 => IntSize::Int,
2160 1 => IntSize::Long,
2161 2 => IntSize::LongLong,
2162 _ => {
2163 self.error(range, "'long long long' is too long for cinrs");
2164 IntSize::LongLong
2165 }
2166 }
2167 };
2168 TypeKind::Int {
2169 sign: sign.unwrap_or(Sign::Signed),
2170 size,
2171 }
2172 };
2173
2174 Type::new(kind, quals, range)
2175 }
2176}
2177
2178impl SpecCounts {
2179 fn any_besides(&self, allowed: &[&str]) -> bool {
2181 let all: [(&str, u32); 13] = [
2182 ("__int128", self.int128),
2183 ("void", self.void),
2184 ("char", self.char),
2185 ("short", self.short),
2186 ("int", self.int),
2187 ("long", self.long),
2188 ("float", self.float),
2189 ("double", self.double),
2190 ("signed", self.signed),
2191 ("unsigned", self.unsigned),
2192 ("_Bool", self.bool),
2193 ("_Complex", self.complex),
2194 ("_Imaginary", self.imaginary),
2195 ];
2196 all.iter()
2197 .any(|(name, count)| *count > 0 && !allowed.contains(name))
2198 }
2199}
2200
2201impl Parser<'_> {
2206 fn add_record(&mut self, spec: RecordSpec) -> RecordSpecId {
2208 let id = RecordSpecId(self.records.len() as u32);
2209 self.records.push(spec);
2210 id
2211 }
2212
2213 fn add_enum(&mut self, spec: EnumSpec) -> EnumSpecId {
2215 let id = EnumSpecId(self.enums.len() as u32);
2216 self.enums.push(spec);
2217 id
2218 }
2219
2220 fn add_typeof(&mut self, operand: TypeofOperand) -> TypeofId {
2222 let id = TypeofId(self.typeofs.len() as u32);
2223 self.typeofs.push(operand);
2224 id
2225 }
2226
2227 fn parse_record_specifier(&mut self) -> PResult<Type> {
2233 self.enter()?;
2234 let result = self.parse_record_specifier_inner();
2235 self.leave();
2236 result
2237 }
2238
2239 fn parse_record_specifier_inner(&mut self) -> PResult<Type> {
2240 let start = self.cur_range();
2241 let pack = self.packing.at(self.pos);
2244 let kind = match self.peek().keyword() {
2245 Some(Keyword::Struct) => RecordKind::Struct,
2246 Some(Keyword::Union) => RecordKind::Union,
2247 _ => unreachable!("caller checked the keyword"),
2248 };
2249 self.advance();
2250 let mut attrs = self.parse_attributes()?;
2251 let name = self.eat_ident();
2252 let mut asserts = Vec::new();
2253 let fields = if self.at_punct(Punct::LBrace) {
2254 let (fields, found) = self.parse_struct_body()?;
2255 asserts = found;
2256 Some(fields)
2257 } else {
2258 if name.is_none() {
2259 let range = self.cur_range();
2260 let found = self.describe_cur();
2261 return Err(self.error_bail(
2262 range,
2263 format!(
2264 "expected identifier or '{{' after '{}', found {found}",
2265 kind.as_str()
2266 ),
2267 ));
2268 }
2269 None
2270 };
2271 if self.at_attributes() {
2274 let after = self.parse_attributes()?;
2275 attrs.merge(after);
2276 }
2277 let range = self.span_to_here(start);
2278 let id = self.add_record(RecordSpec {
2279 kind,
2280 name,
2281 fields,
2282 asserts,
2283 attrs,
2284 pack,
2285 range,
2286 });
2287 Ok(Type::plain(TypeKind::Record(id), range))
2288 }
2289
2290 fn parse_struct_body(&mut self) -> PResult<(Vec<FieldDecl>, Vec<StaticAssert>)> {
2293 self.expect_punct(Punct::LBrace, " to open a member list")?;
2294 let mut fields = Vec::new();
2295 let mut asserts = Vec::new();
2296 while !self.at_punct(Punct::RBrace) && !self.at_eof() {
2297 let before = self.pos;
2298 if self.eat_punct(Punct::Semi).is_some() {
2300 continue;
2301 }
2302 if self.at_static_assert() {
2303 asserts.push(self.parse_static_assert()?);
2304 continue;
2305 }
2306 let start = self.cur_range();
2307 while self.eat_keyword(Keyword::Extension).is_some() {
2308 self.in_extension = true;
2309 }
2310 let leading = self.parse_attributes()?;
2311 let mut specs = self.parse_decl_specifiers(false)?;
2312 specs.attrs.merge(leading);
2313
2314 if self.at_punct(Punct::Semi) {
2315 let range = self.span_to_here(start);
2317 self.require_standard(Standard::C11, "an anonymous struct or union member", range);
2318 fields.push(FieldDecl {
2319 ty: specs.base.clone(),
2320 attrs: specs.attrs.clone(),
2321 specifiers: specs,
2322 name: None,
2323 bit_width: None,
2324 range,
2325 });
2326 self.expect_punct(Punct::Semi, " after member declaration")?;
2327 continue;
2328 }
2329
2330 loop {
2331 let (name, ty, dstart, mut attrs) = if self.at_punct(Punct::Colon) {
2332 (
2333 None,
2334 specs.base.clone(),
2335 self.cur_range(),
2336 Attributes::default(),
2337 )
2338 } else {
2339 let mut d = self.parse_declarator(specs.base.clone(), true)?;
2340 self.parse_declarator_tail(&mut d)?;
2341 (d.name, d.ty, d.range, d.attrs)
2342 };
2343 let bit_width = if self.eat_punct(Punct::Colon).is_some() {
2344 Some(self.parse_conditional_expr()?)
2345 } else {
2346 None
2347 };
2348 if self.at_attributes() {
2350 let after = self.parse_attributes()?;
2351 attrs.merge(after);
2352 }
2353 attrs.merge(specs.attrs.clone());
2354 let range = self.span_to_here(dstart);
2355 fields.push(FieldDecl {
2356 specifiers: specs.clone(),
2357 name,
2358 ty,
2359 bit_width,
2360 attrs,
2361 range,
2362 });
2363 if self.eat_punct(Punct::Comma).is_none() {
2364 break;
2365 }
2366 }
2367 self.expect_punct(Punct::Semi, " after member declaration")?;
2368 if self.pos == before {
2369 self.advance();
2370 }
2371 }
2372 self.expect_punct(Punct::RBrace, " to close a member list")?;
2373 Ok((fields, asserts))
2374 }
2375
2376 fn parse_enum_specifier(&mut self) -> PResult<Type> {
2377 let start = self.cur_range();
2378 self.advance(); let _ = self.parse_attributes()?;
2381 let name = self.eat_ident();
2382 let underlying = if self.at_punct(Punct::Colon) && self.starts_decl_specifier(1) {
2389 let colon = self.bump_range();
2390 self.require_standard(Standard::C23, "an enum with a fixed underlying type", colon);
2391 let specs = self.parse_decl_specifiers(false)?;
2392 Some(specs.base)
2393 } else {
2394 None
2395 };
2396 let enumerators = if self.at_punct(Punct::LBrace) {
2397 self.advance();
2398 let mut list = Vec::new();
2399 while !self.at_punct(Punct::RBrace) && !self.at_eof() {
2400 let ename = self.expect_ident(" in enumerator list")?;
2401 self.declare(&ename.name.clone(), SymKind::Ordinary);
2402 let _ = self.parse_attributes()?;
2404 let value = if self.eat_punct(Punct::Assign).is_some() {
2405 Some(self.parse_conditional_expr()?)
2406 } else {
2407 None
2408 };
2409 let range = self.span_to_here(ename.range);
2410 list.push(Enumerator {
2411 name: ename,
2412 value,
2413 range,
2414 });
2415 let Some(comma) = self.eat_punct(Punct::Comma) else {
2416 break;
2417 };
2418 if self.at_punct(Punct::RBrace) {
2419 self.require_standard(
2420 Standard::C99,
2421 "a trailing comma in an enumerator list",
2422 comma,
2423 );
2424 }
2425 }
2426 self.expect_punct(Punct::RBrace, " to close an enumerator list")?;
2427 Some(list)
2428 } else {
2429 if name.is_none() {
2430 let range = self.cur_range();
2431 let found = self.describe_cur();
2432 return Err(self.error_bail(
2433 range,
2434 format!("expected identifier or '{{' after 'enum', found {found}"),
2435 ));
2436 }
2437 None
2438 };
2439 let range = self.span_to_here(start);
2440 let id = self.add_enum(EnumSpec {
2441 name,
2442 enumerators,
2443 underlying,
2444 range,
2445 });
2446 Ok(Type::plain(TypeKind::Enum(id), range))
2447 }
2448}
2449
2450#[derive(Clone, Debug)]
2456pub struct DeclaratorResult {
2457 pub name: Option<Ident>,
2459 pub ty: Type,
2461 pub attrs: Attributes,
2463 pub asm_label: Option<Spanned<String>>,
2465 pub range: SourceRange,
2467}
2468
2469impl Parser<'_> {
2470 fn parse_declarator(&mut self, base: Type, allow_abstract: bool) -> PResult<DeclaratorResult> {
2475 self.enter()?;
2476 let result = self.parse_declarator_inner(base, allow_abstract);
2477 self.leave();
2478 result
2479 }
2480
2481 fn parse_declarator_inner(
2482 &mut self,
2483 base: Type,
2484 allow_abstract: bool,
2485 ) -> PResult<DeclaratorResult> {
2486 let start = self.cur_range();
2487 let leading = self.parse_attributes()?;
2490 let mut ty = base;
2491
2492 while self.at_punct(Punct::Star) {
2495 let star = self.bump_range();
2496 let mut quals = self.parse_type_qualifiers();
2497 while self.at_attributes() {
2499 let _ = self.parse_attributes()?;
2500 quals = quals.merge(self.parse_type_qualifiers());
2501 }
2502 let range = self.span_to_here(star);
2503 ty = Type::new(TypeKind::Pointer(Box::new(ty)), quals, range);
2504 }
2505
2506 if self.at_punct(Punct::LParen) && self.is_grouping_paren() {
2507 let save = self.pos;
2508 let balanced = self.skip_balanced_parens();
2509 if !balanced {
2510 let range = self.cur_range();
2511 return Err(self.error_bail(range, "unbalanced '(' in declarator"));
2512 }
2513 let rparen = self.pos - 1;
2514 ty = self.parse_type_suffix(ty)?;
2515 let after = self.pos;
2516 self.pos = save + 1;
2517 let inner = self.parse_declarator(ty, allow_abstract)?;
2518 if self.pos != rparen {
2519 let range = self.cur_range();
2520 let found = self.describe_cur();
2521 return Err(self.error_bail(
2522 range,
2523 format!("expected ')' after declarator, found {found}"),
2524 ));
2525 }
2526 self.pos = after;
2527 self.last_range = self.tokens[after - 1].range;
2528 let mut attrs = inner.attrs;
2529 attrs.merge(leading);
2530 return Ok(DeclaratorResult {
2531 name: inner.name,
2532 ty: inner.ty,
2533 attrs,
2534 asm_label: inner.asm_label,
2535 range: self.span_to_here(start),
2536 });
2537 }
2538
2539 let name = match self.eat_ident() {
2540 Some(id) => Some(id),
2541 None if allow_abstract => None,
2542 None => {
2543 let range = self.cur_range();
2544 let found = self.describe_cur();
2545 return Err(self.error_bail(
2546 range,
2547 format!("expected identifier in declarator, found {found}"),
2548 ));
2549 }
2550 };
2551 let mut attrs = self.parse_attributes()?;
2554 attrs.merge(leading);
2555 let ty = self.parse_type_suffix(ty)?;
2556 Ok(DeclaratorResult {
2557 name,
2558 ty,
2559 attrs,
2560 asm_label: None,
2561 range: self.span_to_here(start),
2562 })
2563 }
2564
2565 fn is_grouping_paren(&self) -> bool {
2572 let after = self.after_attributes(1);
2573 !self.nth(after).is_punct(Punct::RParen) && !self.starts_decl_specifier(after)
2574 }
2575
2576 fn after_attributes(&self, mut n: usize) -> usize {
2581 loop {
2582 let brackets =
2583 self.nth(n).is_punct(Punct::LBracket) && self.nth(n + 1).is_punct(Punct::LBracket);
2584 if !self.nth(n).is_keyword(Keyword::Attribute) && !brackets {
2585 return n;
2586 }
2587 let (open, close) = if brackets {
2588 (Punct::LBracket, Punct::RBracket)
2589 } else {
2590 (Punct::LParen, Punct::RParen)
2591 };
2592 let mut i = if brackets { n } else { n + 1 };
2593 let mut depth = 0i32;
2594 while !self.nth(i).is_eof() {
2595 if self.nth(i).is_punct(open) {
2596 depth += 1;
2597 } else if self.nth(i).is_punct(close) {
2598 depth -= 1;
2599 if depth == 0 {
2600 i += 1;
2601 break;
2602 }
2603 }
2604 i += 1;
2605 }
2606 if i <= n {
2607 return n;
2608 }
2609 n = i;
2610 }
2611 }
2612
2613 fn skip_balanced_parens(&mut self) -> bool {
2615 let mut depth = 0i32;
2616 while !self.at_eof() {
2617 if self.at_punct(Punct::LParen) {
2618 depth += 1;
2619 } else if self.at_punct(Punct::RParen) {
2620 depth -= 1;
2621 if depth == 0 {
2622 self.advance();
2623 return true;
2624 }
2625 }
2626 self.advance();
2627 }
2628 false
2629 }
2630
2631 fn parse_type_suffix(&mut self, ty: Type) -> PResult<Type> {
2636 if let Some(lb) = self.eat_punct(Punct::LBracket) {
2637 let mut is_static = false;
2638 let mut quals = TypeQualifiers::NONE;
2639 loop {
2640 if self.at_keyword(Keyword::Static) {
2641 self.advance();
2642 is_static = true;
2643 continue;
2644 }
2645 match self.eat_type_qualifier() {
2646 Some(q) => quals = quals.merge(q),
2647 None => break,
2648 }
2649 }
2650 if is_static {
2651 self.require_standard(
2652 Standard::C99,
2653 "'static' in an array parameter declarator",
2654 lb,
2655 );
2656 }
2657 let size = if self.at_punct(Punct::RBracket) {
2658 ArraySize::Unspecified
2659 } else if self.at_punct(Punct::Star) && self.nth(1).is_punct(Punct::RBracket) {
2660 let star = self.bump_range();
2661 self.require_standard(Standard::C99, "'[*]'", star);
2662 ArraySize::Star
2663 } else {
2664 ArraySize::Expr(Box::new(self.parse_assignment_expr()?))
2665 };
2666 let rb = self.expect_punct(Punct::RBracket, " after array bound")?;
2667 let elem = self.parse_type_suffix(ty)?;
2668 return Ok(Type::plain(
2669 TypeKind::Array {
2670 elem: Box::new(elem),
2671 size,
2672 qualifiers: quals,
2673 is_static,
2674 },
2675 lb.join(rb),
2676 ));
2677 }
2678
2679 if let Some(lp) = self.eat_punct(Punct::LParen) {
2680 let list = self.parse_param_list()?;
2681 let rp = self.expect_punct(Punct::RParen, " after parameter list")?;
2682 let ret = self.parse_type_suffix(ty)?;
2683 return Ok(Type::plain(
2684 TypeKind::Function(Box::new(FunctionType {
2685 ret,
2686 params: list.params,
2687 variadic: list.ellipsis.is_some(),
2688 ellipsis: list.ellipsis,
2689 has_prototype: list.has_prototype,
2690 kr_names: list.kr_names,
2691 old_style: false,
2692 })),
2693 lp.join(rp),
2694 ));
2695 }
2696
2697 Ok(ty)
2698 }
2699
2700 fn parse_param_list(&mut self) -> PResult<ParamList> {
2701 if self.at_punct(Punct::RParen) {
2702 return Ok(ParamList::default());
2703 }
2704 if self.at_keyword(Keyword::Void) && self.nth(1).is_punct(Punct::RParen) {
2706 self.advance();
2707 return Ok(ParamList {
2708 has_prototype: true,
2709 ..ParamList::default()
2710 });
2711 }
2712 let kr = match self.peek().ident() {
2714 Some(name) => !self.is_typedef_name(name),
2715 None => false,
2716 };
2717 if kr {
2718 let mut names = Vec::new();
2719 loop {
2720 names.push(self.expect_ident(" in parameter list")?);
2721 if self.eat_punct(Punct::Comma).is_none() {
2722 break;
2723 }
2724 }
2725 return Ok(ParamList {
2726 kr_names: names,
2727 ..ParamList::default()
2728 });
2729 }
2730
2731 self.push_scope();
2734 let result = self.parse_prototype_params();
2735 self.pop_scope();
2736 result
2737 }
2738
2739 fn parse_prototype_params(&mut self) -> PResult<ParamList> {
2740 let mut params = Vec::new();
2741 let mut ellipsis = None;
2742 loop {
2743 if self.at_punct(Punct::Ellipsis) {
2744 ellipsis = Some(self.bump_range());
2745 break;
2746 }
2747 let start = self.cur_range();
2748 let specs = self.parse_decl_specifiers(true)?;
2749 let declarator = self.parse_declarator(specs.base.clone(), true)?;
2750 if let Some(name) = &declarator.name {
2751 self.declare(&name.name.clone(), SymKind::Ordinary);
2752 }
2753 let range = self.span_to_here(start);
2754 for cleanup in [&declarator.attrs.cleanup, &specs.attrs.cleanup]
2759 .into_iter()
2760 .flatten()
2761 {
2762 self.error(
2763 cleanup.range,
2764 "'cleanup' attribute ignored on a parameter: it calls the function when \
2765 the object goes out of scope, and only an object with automatic storage \
2766 duration ever does",
2767 );
2768 }
2769 params.push(ParamDecl {
2770 specifiers: specs,
2771 name: declarator.name,
2772 ty: declarator.ty,
2773 range,
2774 });
2775 if self.eat_punct(Punct::Comma).is_none() {
2776 break;
2777 }
2778 }
2779 Ok(ParamList {
2780 params,
2781 ellipsis,
2782 has_prototype: true,
2783 kr_names: Vec::new(),
2784 })
2785 }
2786
2787 fn parse_type_name(&mut self) -> PResult<TypeName> {
2788 let start = self.cur_range();
2789 let specs = self.parse_decl_specifiers(false)?;
2790 let declarator = self.parse_declarator(specs.base.clone(), true)?;
2791 if let Some(name) = &declarator.name {
2792 let range = name.range;
2793 self.error(range, "a type name must not declare an identifier");
2794 }
2795 Ok(TypeName {
2796 specifiers: specs,
2797 ty: declarator.ty,
2798 range: self.span_to_here(start),
2799 })
2800 }
2801}
2802
2803#[derive(Default)]
2805struct ParamList {
2806 params: Vec<ParamDecl>,
2807 ellipsis: Option<SourceRange>,
2809 has_prototype: bool,
2810 kr_names: Vec<Ident>,
2811}
2812
2813impl Parser<'_> {
2818 fn parse_initializer(&mut self) -> PResult<Initializer> {
2819 self.enter()?;
2820 let result = self.parse_initializer_inner();
2821 self.leave();
2822 result
2823 }
2824
2825 fn parse_initializer_inner(&mut self) -> PResult<Initializer> {
2826 if self.at_punct(Punct::LBrace) {
2827 let start = self.cur_range();
2828 let items = self.parse_initializer_list()?;
2829 return Ok(Initializer {
2830 kind: InitializerKind::List(items),
2831 range: self.span_to_here(start),
2832 });
2833 }
2834 let expr = self.parse_assignment_expr()?;
2835 Ok(Initializer {
2836 range: expr.range,
2837 kind: InitializerKind::Expr(expr),
2838 })
2839 }
2840
2841 fn parse_initializer_list(&mut self) -> PResult<Vec<InitItem>> {
2842 let brace = self.expect_punct(Punct::LBrace, " to open an initializer list")?;
2843 if self.at_punct(Punct::RBrace) {
2844 let range = brace.join(self.cur_range());
2847 self.require_standard(Standard::C23, "an empty initializer", range);
2848 }
2849 let mut items = Vec::new();
2850 while !self.at_punct(Punct::RBrace) && !self.at_eof() {
2851 let start = self.cur_range();
2852 let mut designators = Vec::new();
2853 let mut old_style = false;
2856 if self.peek().ident().is_some() && self.nth(1).is_punct(Punct::Colon) {
2857 let field = self.eat_ident().expect("checked above");
2858 self.advance();
2859 designators.push(Designator::Field(field));
2860 old_style = true;
2861 }
2862 loop {
2863 if old_style {
2864 break;
2865 }
2866 if self.eat_punct(Punct::Dot).is_some() {
2867 let field = self.expect_ident(" after '.' in designator")?;
2868 designators.push(Designator::Field(field));
2869 } else if self.eat_punct(Punct::LBracket).is_some() {
2870 let index = self.parse_conditional_expr()?;
2871 if self.eat_punct(Punct::Ellipsis).is_some() {
2873 let high = self.parse_conditional_expr()?;
2874 self.expect_punct(Punct::RBracket, " after array designator")?;
2875 designators.push(Designator::Range(index, high));
2876 } else {
2877 self.expect_punct(Punct::RBracket, " after array designator")?;
2878 designators.push(Designator::Index(index));
2879 }
2880 } else {
2881 break;
2882 }
2883 }
2884 if !designators.is_empty() {
2885 let at = self.span_to_here(start);
2888 self.require_standard(Standard::C99, "a designated initializer", at);
2889 }
2890 if !designators.is_empty() && !old_style {
2891 self.expect_punct(Punct::Assign, " after designator")?;
2892 }
2893 let init = self.parse_initializer()?;
2894 items.push(InitItem {
2895 designators,
2896 init,
2897 range: self.span_to_here(start),
2898 });
2899 if self.eat_punct(Punct::Comma).is_none() {
2900 break;
2901 }
2902 }
2903 self.expect_punct(Punct::RBrace, " to close an initializer list")?;
2904 Ok(items)
2905 }
2906}
2907
2908impl Parser<'_> {
2913 fn parse_compound_stmt(&mut self) -> PResult<Block> {
2914 let start = self.expect_punct(Punct::LBrace, " to open a block")?;
2915 self.push_scope();
2916 let mut local_labels = Vec::new();
2920 while self.at_keyword(Keyword::Label) {
2921 self.advance();
2922 loop {
2923 match self.expect_ident(" in a '__label__' declaration") {
2924 Ok(name) => local_labels.push(name),
2925 Err(bail) => {
2926 self.pop_scope();
2927 return Err(bail);
2928 }
2929 }
2930 if self.eat_punct(Punct::Comma).is_none() {
2931 break;
2932 }
2933 }
2934 if let Err(bail) = self.expect_punct(Punct::Semi, " after '__label__'") {
2935 self.pop_scope();
2936 return Err(bail);
2937 }
2938 }
2939 let mut items = Vec::new();
2940 let mut saw_statement = false;
2944 while !self.at_punct(Punct::RBrace) && !self.at_eof() {
2945 let before = self.pos;
2946 if saw_statement && self.starts_declaration() {
2947 let at = self.cur_range();
2948 self.require_standard(Standard::C99, "a declaration after a statement", at);
2949 }
2950 let item = if self.at_static_assert() {
2951 self.parse_static_assert().map(BlockItem::StaticAssert)
2952 } else {
2953 match self.parse_attributes() {
2957 Ok(attrs) => {
2958 if self.starts_declaration() {
2959 self.parse_block_declaration().map(|mut item| {
2960 let specifiers = match &mut item {
2967 BlockItem::Decl(decl) => Some(&mut decl.specifiers),
2968 BlockItem::NestedFunction(def) => Some(&mut def.specifiers),
2969 _ => None,
2970 };
2971 if let Some(specifiers) = specifiers {
2972 specifiers.noreturn = specifiers.noreturn.or(attrs.noreturn);
2973 specifiers.attrs.merge(attrs);
2974 }
2975 item
2976 })
2977 } else {
2978 self.parse_stmt().map(BlockItem::Stmt)
2979 }
2980 }
2981 Err(bail) => Err(bail),
2982 }
2983 };
2984 match item {
2985 Ok(item) => {
2986 saw_statement |= matches!(item, BlockItem::Stmt(_));
2987 items.push(item);
2988 }
2989 Err(bail) => {
2990 self.pop_scope();
2991 return Err(bail);
2992 }
2993 }
2994 if self.pos == before {
2995 self.advance();
2996 }
2997 }
2998 self.pop_scope();
2999 let end = self.expect_punct(Punct::RBrace, " to close a block")?;
3000 Ok(Block {
3001 items,
3002 local_labels,
3003 range: start.join(end),
3004 })
3005 }
3006
3007 fn parse_stmt(&mut self) -> PResult<Stmt> {
3008 self.enter()?;
3009 let result = self.parse_stmt_inner();
3010 self.leave();
3011 result
3012 }
3013
3014 fn parse_stmt_inner(&mut self) -> PResult<Stmt> {
3022 let mut labels: Vec<(PendingLabel, SourceRange)> = Vec::new();
3023 let start = loop {
3024 let start = self.cur_range();
3025 let _ = self.parse_attributes()?;
3029 while self.eat_keyword(Keyword::Extension).is_some() {}
3032
3033 let label = if self.peek().ident().is_some() && self.nth(1).is_punct(Punct::Colon) {
3035 let label = self.eat_ident().expect("checked above");
3036 self.advance(); PendingLabel::Ident { label }
3038 } else if self.at_keyword(Keyword::Case) {
3039 self.advance();
3040 let value = self.parse_conditional_expr()?;
3041 let upper = if self.eat_punct(Punct::Ellipsis).is_some() {
3044 Some(self.parse_conditional_expr()?)
3045 } else {
3046 None
3047 };
3048 self.expect_punct(Punct::Colon, " after 'case' label")?;
3049 PendingLabel::Case { value, upper }
3050 } else if self.at_keyword(Keyword::Default) {
3051 self.advance();
3052 self.expect_punct(Punct::Colon, " after 'default' label")?;
3053 PendingLabel::Default
3054 } else {
3055 break start;
3056 };
3057 labels.push((label, start));
3058 if labels.len() > MAX_LABEL_CHAIN {
3059 let range = self.cur_range();
3060 return Err(self.error_bail(
3061 range,
3062 format!("more than {MAX_LABEL_CHAIN} labels on one statement"),
3063 ));
3064 }
3065 };
3066
3067 if !labels.is_empty() {
3068 return self.finish_labeled_stmt(labels);
3069 }
3070 self.parse_unlabeled_stmt(start)
3071 }
3072
3073 fn parse_unlabeled_stmt(&mut self, start: SourceRange) -> PResult<Stmt> {
3078 if self.at_keyword(Keyword::Asm) {
3081 return self.parse_asm_stmt();
3082 }
3083
3084 if self.at_punct(Punct::LBrace) {
3085 let block = self.parse_compound_stmt()?;
3086 return Ok(Stmt {
3087 range: block.range,
3088 kind: StmtKind::Compound(block),
3089 });
3090 }
3091
3092 if let Some(k) = self.peek().keyword() {
3093 match k {
3094 Keyword::If => return self.parse_if_stmt(),
3095 Keyword::Switch => {
3096 self.advance();
3097 self.expect_punct(Punct::LParen, " after 'switch'")?;
3098 let cond = self.parse_expr()?;
3099 self.expect_punct(Punct::RParen, " after switch condition")?;
3100 let body = self.parse_stmt()?;
3101 return Ok(Stmt {
3102 kind: StmtKind::Switch {
3103 cond,
3104 body: Box::new(body),
3105 },
3106 range: self.span_to_here(start),
3107 });
3108 }
3109 Keyword::While => {
3110 self.advance();
3111 self.expect_punct(Punct::LParen, " after 'while'")?;
3112 let cond = self.parse_expr()?;
3113 self.expect_punct(Punct::RParen, " after loop condition")?;
3114 let body = self.parse_stmt()?;
3115 return Ok(Stmt {
3116 kind: StmtKind::While {
3117 cond,
3118 body: Box::new(body),
3119 },
3120 range: self.span_to_here(start),
3121 });
3122 }
3123 Keyword::Do => {
3124 self.advance();
3125 let body = self.parse_stmt()?;
3126 self.expect_keyword(Keyword::While, " after 'do' body")?;
3127 self.expect_punct(Punct::LParen, " after 'while'")?;
3128 let cond = self.parse_expr()?;
3129 self.expect_punct(Punct::RParen, " after loop condition")?;
3130 self.expect_punct(Punct::Semi, " after 'do' statement")?;
3131 return Ok(Stmt {
3132 kind: StmtKind::DoWhile {
3133 body: Box::new(body),
3134 cond,
3135 },
3136 range: self.span_to_here(start),
3137 });
3138 }
3139 Keyword::For => return self.parse_for_stmt(),
3140 Keyword::Goto => {
3141 self.advance();
3142 if self.eat_punct(Punct::Star).is_some() {
3145 let target = self.parse_expr()?;
3146 self.expect_punct(Punct::Semi, " after 'goto' statement")?;
3147 return Ok(Stmt {
3148 kind: StmtKind::GotoPtr(target),
3149 range: self.span_to_here(start),
3150 });
3151 }
3152 let label = self.expect_ident(" after 'goto'")?;
3153 self.expect_punct(Punct::Semi, " after 'goto' statement")?;
3154 return Ok(Stmt {
3155 kind: StmtKind::Goto(label),
3156 range: self.span_to_here(start),
3157 });
3158 }
3159 Keyword::Continue => {
3160 self.advance();
3161 self.expect_punct(Punct::Semi, " after 'continue'")?;
3162 return Ok(Stmt {
3163 kind: StmtKind::Continue,
3164 range: self.span_to_here(start),
3165 });
3166 }
3167 Keyword::Break => {
3168 self.advance();
3169 self.expect_punct(Punct::Semi, " after 'break'")?;
3170 return Ok(Stmt {
3171 kind: StmtKind::Break,
3172 range: self.span_to_here(start),
3173 });
3174 }
3175 Keyword::Return => {
3176 self.advance();
3177 let value = if self.at_punct(Punct::Semi) {
3178 None
3179 } else {
3180 Some(self.parse_expr()?)
3181 };
3182 self.expect_punct(Punct::Semi, " after 'return' statement")?;
3183 return Ok(Stmt {
3184 kind: StmtKind::Return(value),
3185 range: self.span_to_here(start),
3186 });
3187 }
3188 _ => {}
3189 }
3190 }
3191
3192 if let Some(semi) = self.eat_punct(Punct::Semi) {
3193 return Ok(Stmt {
3194 kind: StmtKind::Expr(None),
3195 range: semi,
3196 });
3197 }
3198
3199 let expr = self.parse_expr()?;
3200 self.expect_punct(Punct::Semi, " after expression")?;
3201 Ok(Stmt {
3202 kind: StmtKind::Expr(Some(expr)),
3203 range: self.span_to_here(start),
3204 })
3205 }
3206
3207 fn finish_labeled_stmt(&mut self, labels: Vec<(PendingLabel, SourceRange)>) -> PResult<Stmt> {
3211 let colon = self.last_range;
3219 let (_, label_start) = labels.last().expect("a label chain is never empty");
3220 let what = if self.at_punct(Punct::RBrace) {
3221 Some("a label at the end of a compound statement")
3222 } else if self.starts_declaration() || self.at_static_assert() {
3223 Some("a label before a declaration")
3224 } else {
3225 None
3226 };
3227 let trailing = what.map(|what| (what, label_start.join(colon), colon));
3228 let mut stmt = match trailing {
3229 Some((what, at, colon)) => {
3230 self.require_standard(Standard::C23, what, at);
3231 Stmt {
3232 kind: StmtKind::Expr(None),
3233 range: colon,
3234 }
3235 }
3236 None => {
3237 let start = self.cur_range();
3238 self.parse_unlabeled_stmt(start)?
3239 }
3240 };
3241 let end = self.last_range;
3242 for (label, start) in labels.into_iter().rev() {
3243 let body = Box::new(stmt);
3244 let kind = match label {
3245 PendingLabel::Ident { label, .. } => StmtKind::Labeled { label, body },
3246 PendingLabel::Case { value, upper } => StmtKind::Case { value, upper, body },
3247 PendingLabel::Default => StmtKind::Default { body },
3248 };
3249 stmt = Stmt {
3250 kind,
3251 range: start.join(end),
3252 };
3253 }
3254 Ok(stmt)
3255 }
3256
3257 fn parse_asm_stmt(&mut self) -> PResult<Stmt> {
3265 let start = self.cur_range();
3266 self.advance();
3267 while matches!(
3269 self.peek().keyword(),
3270 Some(
3271 Keyword::Volatile
3272 | Keyword::Const
3273 | Keyword::Inline
3274 | Keyword::InlineGnu
3275 | Keyword::Goto
3276 )
3277 ) {
3278 self.advance();
3279 }
3280 if self.at_punct(Punct::LParen) {
3281 self.skip_attribute_args()?;
3282 }
3283 self.eat_punct(Punct::Semi);
3284 let range = self.span_to_here(start);
3285 self.error(range, "inline assembly is not supported");
3286 Ok(Stmt {
3287 kind: StmtKind::Error,
3288 range,
3289 })
3290 }
3291
3292 fn parse_if_stmt(&mut self) -> PResult<Stmt> {
3293 let start = self.cur_range();
3294 self.advance(); self.expect_punct(Punct::LParen, " after 'if'")?;
3296 let cond = self.parse_expr()?;
3297 self.expect_punct(Punct::RParen, " after if condition")?;
3298 let then_branch = Box::new(self.parse_stmt()?);
3299 let else_branch = if self.eat_keyword(Keyword::Else).is_some() {
3300 Some(Box::new(self.parse_stmt()?))
3301 } else {
3302 None
3303 };
3304 Ok(Stmt {
3305 kind: StmtKind::If {
3306 cond,
3307 then_branch,
3308 else_branch,
3309 },
3310 range: self.span_to_here(start),
3311 })
3312 }
3313
3314 fn parse_for_stmt(&mut self) -> PResult<Stmt> {
3315 let start = self.cur_range();
3316 self.advance(); self.expect_punct(Punct::LParen, " after 'for'")?;
3318 self.push_scope();
3320 let result = (|parser: &mut Self| {
3321 let init = if parser.at_punct(Punct::Semi) {
3322 parser.advance();
3323 ForInit::None
3324 } else if parser.at_static_assert() {
3325 ForInit::StaticAssert(parser.parse_static_assert()?)
3328 } else if parser.starts_declaration() {
3329 let at = parser.cur_range();
3330 parser.require_standard(Standard::C99, "a declaration in a 'for' clause", at);
3331 ForInit::Decl(Box::new(parser.parse_declaration()?))
3332 } else {
3333 let expr = parser.parse_expr()?;
3334 parser.expect_punct(Punct::Semi, " after 'for' initializer")?;
3335 ForInit::Expr(expr)
3336 };
3337 let cond = if parser.at_punct(Punct::Semi) {
3338 None
3339 } else {
3340 Some(parser.parse_expr()?)
3341 };
3342 parser.expect_punct(Punct::Semi, " after 'for' condition")?;
3343 let step = if parser.at_punct(Punct::RParen) {
3344 None
3345 } else {
3346 Some(parser.parse_expr()?)
3347 };
3348 parser.expect_punct(Punct::RParen, " after 'for' clauses")?;
3349 let body = parser.parse_stmt()?;
3350 Ok(StmtKind::For {
3351 init,
3352 cond,
3353 step,
3354 body: Box::new(body),
3355 })
3356 })(self);
3357 self.pop_scope();
3358 Ok(Stmt {
3359 kind: result?,
3360 range: self.span_to_here(start),
3361 })
3362 }
3363
3364 fn expect_keyword(&mut self, k: Keyword, ctx: &str) -> PResult<SourceRange> {
3365 if self.at_keyword(k) {
3366 return Ok(self.bump_range());
3367 }
3368 let range = self.cur_range();
3369 let found = self.describe_cur();
3370 Err(self.error_bail(
3371 range,
3372 format!("expected '{}'{ctx}, found {found}", k.as_str()),
3373 ))
3374 }
3375}
3376
3377fn binary_op(kind: &TokenKind) -> Option<(BinaryOp, u8)> {
3383 let TokenKind::Punct(p) = kind else {
3384 return None;
3385 };
3386 Some(match p {
3387 Punct::PipePipe => (BinaryOp::LogOr, 1),
3388 Punct::AmpAmp => (BinaryOp::LogAnd, 2),
3389 Punct::Pipe => (BinaryOp::BitOr, 3),
3390 Punct::Caret => (BinaryOp::BitXor, 4),
3391 Punct::Amp => (BinaryOp::BitAnd, 5),
3392 Punct::EqEq => (BinaryOp::Eq, 6),
3393 Punct::Ne => (BinaryOp::Ne, 6),
3394 Punct::Lt => (BinaryOp::Lt, 7),
3395 Punct::Gt => (BinaryOp::Gt, 7),
3396 Punct::Le => (BinaryOp::Le, 7),
3397 Punct::Ge => (BinaryOp::Ge, 7),
3398 Punct::Shl => (BinaryOp::Shl, 8),
3399 Punct::Shr => (BinaryOp::Shr, 8),
3400 Punct::Plus => (BinaryOp::Add, 9),
3401 Punct::Minus => (BinaryOp::Sub, 9),
3402 Punct::Star => (BinaryOp::Mul, 10),
3403 Punct::Slash => (BinaryOp::Div, 10),
3404 Punct::Percent => (BinaryOp::Rem, 10),
3405 _ => return None,
3406 })
3407}
3408
3409fn assign_op(kind: &TokenKind) -> Option<Option<BinaryOp>> {
3411 let TokenKind::Punct(p) = kind else {
3412 return None;
3413 };
3414 Some(match p {
3415 Punct::Assign => None,
3416 Punct::StarAssign => Some(BinaryOp::Mul),
3417 Punct::SlashAssign => Some(BinaryOp::Div),
3418 Punct::PercentAssign => Some(BinaryOp::Rem),
3419 Punct::PlusAssign => Some(BinaryOp::Add),
3420 Punct::MinusAssign => Some(BinaryOp::Sub),
3421 Punct::ShlAssign => Some(BinaryOp::Shl),
3422 Punct::ShrAssign => Some(BinaryOp::Shr),
3423 Punct::AmpAssign => Some(BinaryOp::BitAnd),
3424 Punct::CaretAssign => Some(BinaryOp::BitXor),
3425 Punct::PipeAssign => Some(BinaryOp::BitOr),
3426 _ => return None,
3427 })
3428}
3429
3430impl Parser<'_> {
3431 pub(crate) fn parse_expr(&mut self) -> PResult<Expr> {
3433 self.enter()?;
3434 let result = self.parse_expr_inner();
3435 self.leave();
3436 result
3437 }
3438
3439 fn parse_expr_inner(&mut self) -> PResult<Expr> {
3446 let mut lhs = self.parse_assignment_expr()?;
3447 while self.eat_punct(Punct::Comma).is_some() {
3448 let rhs = self.parse_assignment_expr()?;
3449 let range = lhs.range.join(rhs.range);
3450 lhs = Expr {
3451 kind: ExprKind::Comma {
3452 lhs: Box::new(lhs),
3453 rhs: Box::new(rhs),
3454 },
3455 range,
3456 };
3457 }
3458 Ok(lhs)
3459 }
3460
3461 fn parse_assignment_expr(&mut self) -> PResult<Expr> {
3470 let mut charged = 0u32;
3471 let result = self.assignment_chain(&mut charged);
3472 for _ in 0..charged {
3473 self.leave();
3474 }
3475 result
3476 }
3477
3478 fn assignment_chain(&mut self, charged: &mut u32) -> PResult<Expr> {
3480 let mut pending: Vec<(Expr, Option<BinaryOp>)> = Vec::new();
3481 let mut value = loop {
3482 let lhs = self.parse_conditional_expr()?;
3483 let Some(op) = assign_op(&self.peek().kind) else {
3484 break lhs;
3485 };
3486 self.advance();
3487 self.enter()?;
3488 *charged += 1;
3489 pending.push((lhs, op));
3490 };
3491 for (lhs, op) in pending.into_iter().rev() {
3492 let range = lhs.range.join(value.range);
3493 value = Expr {
3494 kind: ExprKind::Assign {
3495 op,
3496 lhs: Box::new(lhs),
3497 rhs: Box::new(value),
3498 },
3499 range,
3500 };
3501 }
3502 Ok(value)
3503 }
3504
3505 fn parse_conditional_expr(&mut self) -> PResult<Expr> {
3513 let mut charged = 0u32;
3514 let result = self.conditional_chain(&mut charged);
3515 for _ in 0..charged {
3516 self.leave();
3517 }
3518 result
3519 }
3520
3521 fn conditional_chain(&mut self, charged: &mut u32) -> PResult<Expr> {
3523 #[allow(clippy::type_complexity)]
3524 let mut pending: Vec<(Expr, Option<Box<Expr>>)> = Vec::new();
3525 let mut value = loop {
3526 let cond = self.parse_binary_expr(1)?;
3527 if self.eat_punct(Punct::Question).is_none() {
3528 break cond;
3529 }
3530 let then_expr = if self.at_punct(Punct::Colon) {
3533 None
3534 } else {
3535 Some(Box::new(self.parse_expr()?))
3536 };
3537 self.expect_punct(Punct::Colon, " in conditional expression")?;
3538 self.enter()?;
3539 *charged += 1;
3540 pending.push((cond, then_expr));
3541 };
3542 for (cond, then_expr) in pending.into_iter().rev() {
3543 let range = cond.range.join(value.range);
3544 value = Expr {
3545 kind: ExprKind::Conditional {
3546 cond: Box::new(cond),
3547 then_expr,
3548 else_expr: Box::new(value),
3549 },
3550 range,
3551 };
3552 }
3553 Ok(value)
3554 }
3555
3556 fn parse_binary_expr(&mut self, min_prec: u8) -> PResult<Expr> {
3563 let mut lhs = self.parse_cast_expr()?;
3564 while let Some((op, prec)) = binary_op(&self.peek().kind) {
3565 if prec < min_prec {
3566 break;
3567 }
3568 self.advance();
3569 let rhs = self.parse_binary_expr(prec + 1)?;
3570 let range = lhs.range.join(rhs.range);
3571 lhs = Expr {
3572 kind: ExprKind::Binary {
3573 op,
3574 lhs: Box::new(lhs),
3575 rhs: Box::new(rhs),
3576 },
3577 range,
3578 };
3579 }
3580 Ok(lhs)
3581 }
3582
3583 fn at_paren_type_name(&self) -> bool {
3587 if !self.at_punct(Punct::LParen) {
3588 return false;
3589 }
3590 let mut n = 1;
3596 while self.nth(n).keyword() == Some(Keyword::Extension) {
3597 n += 1;
3598 }
3599 self.starts_decl_specifier(n)
3600 }
3601
3602 fn parse_cast_expr(&mut self) -> PResult<Expr> {
3603 self.enter()?;
3604 let result = self.parse_cast_expr_inner();
3605 self.leave();
3606 result
3607 }
3608
3609 fn parse_cast_expr_inner(&mut self) -> PResult<Expr> {
3610 if !self.at_paren_type_name() {
3611 return self.parse_unary_expr();
3612 }
3613 let start = self.cur_range();
3614 self.advance(); let ty = self.parse_type_name()?;
3616 self.expect_punct(Punct::RParen, " after type name")?;
3617 if self.at_punct(Punct::LBrace) {
3618 let at = self.span_to_here(start);
3620 self.require_standard(Standard::C99, "a compound literal", at);
3621 let items = self.parse_initializer_list()?;
3622 let expr = Expr {
3623 kind: ExprKind::CompoundLiteral {
3624 ty: Box::new(ty),
3625 init: items,
3626 },
3627 range: self.span_to_here(start),
3628 };
3629 return self.parse_postfix_suffixes(expr);
3630 }
3631 let expr = self.parse_cast_expr()?;
3632 let range = start.join(expr.range);
3633 Ok(Expr {
3634 kind: ExprKind::Cast {
3635 ty: Box::new(ty),
3636 expr: Box::new(expr),
3637 },
3638 range,
3639 })
3640 }
3641
3642 fn parse_unary_expr(&mut self) -> PResult<Expr> {
3643 let start = self.cur_range();
3644
3645 if let Some(p) = match &self.peek().kind {
3646 TokenKind::Punct(p) => Some(*p),
3647 _ => None,
3648 } {
3649 let unary = match p {
3650 Punct::Amp => Some(UnaryOp::AddrOf),
3651 Punct::Star => Some(UnaryOp::Deref),
3652 Punct::Plus => Some(UnaryOp::Plus),
3653 Punct::Minus => Some(UnaryOp::Minus),
3654 Punct::Tilde => Some(UnaryOp::BitNot),
3655 Punct::Bang => Some(UnaryOp::LogNot),
3656 _ => None,
3657 };
3658 if let Some(op) = unary {
3659 self.advance();
3660 let operand = self.parse_cast_expr()?;
3661 let range = start.join(operand.range);
3662 return Ok(Expr {
3663 kind: ExprKind::Unary {
3664 op,
3665 operand: Box::new(operand),
3666 },
3667 range,
3668 });
3669 }
3670 if p == Punct::AmpAmp {
3675 self.advance();
3676 let label = self.expect_ident(" after '&&'")?;
3677 self.label_addrs += 1;
3678 let range = start.join(label.range);
3679 return Ok(Expr {
3680 kind: ExprKind::LabelAddr(label),
3681 range,
3682 });
3683 }
3684 if matches!(p, Punct::PlusPlus | Punct::MinusMinus) {
3685 self.advance();
3686 let op = if p == Punct::PlusPlus {
3687 IncDec::Inc
3688 } else {
3689 IncDec::Dec
3690 };
3691 let operand = self.parse_unary_expr()?;
3692 let range = start.join(operand.range);
3693 return Ok(Expr {
3694 kind: ExprKind::PreIncDec {
3695 op,
3696 operand: Box::new(operand),
3697 },
3698 range,
3699 });
3700 }
3701 }
3702
3703 if self.at_keyword(Keyword::Sizeof) {
3704 self.advance();
3705 if self.at_paren_type_name() {
3706 self.advance(); let ty = self.parse_type_name()?;
3708 self.expect_punct(Punct::RParen, " after type name")?;
3709 if self.at_punct(Punct::LBrace) {
3710 let at = self.span_to_here(start);
3712 self.require_standard(Standard::C99, "a compound literal", at);
3713 let items = self.parse_initializer_list()?;
3714 let literal = Expr {
3715 kind: ExprKind::CompoundLiteral {
3716 ty: Box::new(ty),
3717 init: items,
3718 },
3719 range: self.span_to_here(start),
3720 };
3721 let operand = self.parse_postfix_suffixes(literal)?;
3722 let range = start.join(operand.range);
3723 return Ok(Expr {
3724 kind: ExprKind::SizeofExpr(Box::new(operand)),
3725 range,
3726 });
3727 }
3728 return Ok(Expr {
3729 kind: ExprKind::SizeofType(Box::new(ty)),
3730 range: self.span_to_here(start),
3731 });
3732 }
3733 let operand = self.parse_unary_expr()?;
3734 let range = start.join(operand.range);
3735 return Ok(Expr {
3736 kind: ExprKind::SizeofExpr(Box::new(operand)),
3737 range,
3738 });
3739 }
3740
3741 if self.eat_keyword(Keyword::Extension).is_some() {
3746 return self.parse_unary_expr();
3747 }
3748 if let Some(k @ (Keyword::RealGnu | Keyword::ImagGnu)) = self.peek().keyword() {
3749 self.advance();
3750 let operand = self.parse_cast_expr()?;
3751 let range = start.join(operand.range);
3752 return Ok(Expr {
3753 kind: ExprKind::ComplexPart {
3754 real: k == Keyword::RealGnu,
3755 operand: Box::new(operand),
3756 },
3757 range,
3758 });
3759 }
3760
3761 if let Some(k @ (Keyword::Alignof | Keyword::AlignofName | Keyword::AlignofGnu)) =
3762 self.peek().keyword()
3763 {
3764 self.require_keyword(k, start);
3765 self.advance();
3766 if self.at_paren_type_name() {
3767 self.advance(); let ty = self.parse_type_name()?;
3769 self.expect_punct(Punct::RParen, " after type name")?;
3770 return Ok(Expr {
3771 kind: ExprKind::AlignofType(Box::new(ty)),
3772 range: self.span_to_here(start),
3773 });
3774 }
3775 let operand = self.parse_unary_expr()?;
3779 let range = start.join(operand.range);
3780 return Ok(Expr {
3781 kind: ExprKind::AlignofExpr(Box::new(operand)),
3782 range,
3783 });
3784 }
3785
3786 if self.at_va_arg() {
3787 return self.parse_va_arg();
3788 }
3789 if self.at_builtin("__builtin_offsetof") {
3790 return self.parse_offsetof();
3791 }
3792 if self.at_builtin("__builtin_types_compatible_p") {
3793 return self.parse_types_compatible();
3794 }
3795 if self.at_builtin("__builtin_choose_expr") {
3796 return self.parse_choose_expr();
3797 }
3798
3799 self.parse_postfix_expr()
3800 }
3801
3802 fn parse_types_compatible(&mut self) -> PResult<Expr> {
3804 let start = self.cur_range();
3805 self.advance(); self.advance(); let lhs = self.parse_type_name()?;
3808 self.expect_punct(
3809 Punct::Comma,
3810 " after the first type of '__builtin_types_compatible_p'",
3811 )?;
3812 let rhs = self.parse_type_name()?;
3813 self.expect_punct(
3814 Punct::RParen,
3815 " after the second type of '__builtin_types_compatible_p'",
3816 )?;
3817 let expr = Expr {
3818 kind: ExprKind::TypesCompatible {
3819 lhs: Box::new(lhs),
3820 rhs: Box::new(rhs),
3821 },
3822 range: self.span_to_here(start),
3823 };
3824 self.parse_postfix_suffixes(expr)
3825 }
3826
3827 fn parse_choose_expr(&mut self) -> PResult<Expr> {
3830 let start = self.cur_range();
3831 self.advance(); self.advance(); let cond = self.parse_assignment_expr()?;
3834 self.expect_punct(
3835 Punct::Comma,
3836 " after the condition of '__builtin_choose_expr'",
3837 )?;
3838 let then_expr = self.parse_assignment_expr()?;
3839 self.expect_punct(Punct::Comma, " in '__builtin_choose_expr'")?;
3840 let else_expr = self.parse_assignment_expr()?;
3841 self.expect_punct(Punct::RParen, " to close '__builtin_choose_expr'")?;
3842 let expr = Expr {
3843 kind: ExprKind::ChooseExpr {
3844 cond: Box::new(cond),
3845 then_expr: Box::new(then_expr),
3846 else_expr: Box::new(else_expr),
3847 },
3848 range: self.span_to_here(start),
3849 };
3850 self.parse_postfix_suffixes(expr)
3851 }
3852
3853 fn at_builtin(&self, name: &str) -> bool {
3859 self.peek().ident() == Some(name) && self.nth(1).is_punct(Punct::LParen)
3860 }
3861
3862 fn at_va_arg(&self) -> bool {
3864 self.at_builtin("__builtin_va_arg")
3865 }
3866
3867 fn parse_offsetof(&mut self) -> PResult<Expr> {
3875 let start = self.cur_range();
3876 self.advance(); self.advance(); let ty = self.parse_type_name()?;
3879 self.expect_punct(Punct::Comma, " after the type of 'offsetof'")?;
3880 let member = self.expect_ident(" as the member of 'offsetof'")?;
3881 let mut path = Vec::new();
3882 loop {
3883 if self.eat_punct(Punct::Dot).is_some() {
3884 path.push(Designator::Field(self.expect_ident(
3885 " after '.' in the member designator of 'offsetof'",
3886 )?));
3887 continue;
3888 }
3889 if self.eat_punct(Punct::LBracket).is_some() {
3890 path.push(Designator::Index(self.parse_expr()?));
3891 self.expect_punct(
3892 Punct::RBracket,
3893 " after the subscript in the member designator of 'offsetof'",
3894 )?;
3895 continue;
3896 }
3897 break;
3898 }
3899 self.expect_punct(Punct::RParen, " after the member of 'offsetof'")?;
3900 let expr = Expr {
3901 kind: ExprKind::OffsetOf {
3902 ty: Box::new(ty),
3903 member,
3904 path,
3905 },
3906 range: self.span_to_here(start),
3907 };
3908 self.parse_postfix_suffixes(expr)
3909 }
3910
3911 fn parse_va_arg(&mut self) -> PResult<Expr> {
3913 let start = self.cur_range();
3914 self.advance(); self.advance(); let ap = self.parse_assignment_expr()?;
3917 self.expect_punct(Punct::Comma, " after the argument list of 'va_arg'")?;
3918 let ty = self.parse_type_name()?;
3919 self.expect_punct(Punct::RParen, " after the type of 'va_arg'")?;
3920 let expr = Expr {
3921 kind: ExprKind::VaArg {
3922 ap: Box::new(ap),
3923 ty: Box::new(ty),
3924 },
3925 range: self.span_to_here(start),
3926 };
3927 self.parse_postfix_suffixes(expr)
3928 }
3929
3930 fn parse_postfix_expr(&mut self) -> PResult<Expr> {
3931 let primary = self.parse_primary_expr()?;
3932 self.parse_postfix_suffixes(primary)
3933 }
3934
3935 fn parse_postfix_suffixes(&mut self, expr: Expr) -> PResult<Expr> {
3943 let mut charged = 0u32;
3944 let result = self.postfix_suffixes(expr, &mut charged);
3945 for _ in 0..charged {
3946 self.leave();
3947 }
3948 result
3949 }
3950
3951 fn postfix_suffixes(&mut self, mut expr: Expr, charged: &mut u32) -> PResult<Expr> {
3953 let mut suffixes = 0usize;
3954 loop {
3955 if suffixes > 0 {
3959 self.enter()?;
3960 *charged += 1;
3961 }
3962 suffixes += 1;
3963 if self.eat_punct(Punct::LBracket).is_some() {
3964 let index = self.parse_expr()?;
3965 let rb = self.expect_punct(Punct::RBracket, " after subscript")?;
3966 expr = Expr {
3967 range: expr.range.join(rb),
3968 kind: ExprKind::Index {
3969 base: Box::new(expr),
3970 index: Box::new(index),
3971 },
3972 };
3973 continue;
3974 }
3975 if self.eat_punct(Punct::LParen).is_some() {
3976 let mut args = Vec::new();
3977 if !self.at_punct(Punct::RParen) {
3978 loop {
3979 args.push(self.parse_assignment_expr()?);
3980 if self.eat_punct(Punct::Comma).is_none() {
3981 break;
3982 }
3983 }
3984 }
3985 let rp = self.expect_punct(Punct::RParen, " after argument list")?;
3986 expr = Expr {
3987 range: expr.range.join(rp),
3988 kind: ExprKind::Call {
3989 callee: Box::new(expr),
3990 args,
3991 },
3992 };
3993 continue;
3994 }
3995 let arrow = if self.at_punct(Punct::Dot) {
3996 false
3997 } else if self.at_punct(Punct::Arrow) {
3998 true
3999 } else if self.at_punct(Punct::PlusPlus) || self.at_punct(Punct::MinusMinus) {
4000 let op = if self.at_punct(Punct::PlusPlus) {
4001 IncDec::Inc
4002 } else {
4003 IncDec::Dec
4004 };
4005 let range = expr.range.join(self.bump_range());
4006 expr = Expr {
4007 kind: ExprKind::PostIncDec {
4008 op,
4009 operand: Box::new(expr),
4010 },
4011 range,
4012 };
4013 continue;
4014 } else {
4015 break;
4016 };
4017 self.advance();
4018 let field = self.expect_ident(if arrow { " after '->'" } else { " after '.'" })?;
4019 expr = Expr {
4020 range: expr.range.join(field.range),
4021 kind: ExprKind::Member {
4022 base: Box::new(expr),
4023 arrow,
4024 field,
4025 },
4026 };
4027 }
4028 Ok(expr)
4029 }
4030
4031 fn parse_generic_selection(&mut self) -> PResult<Expr> {
4036 let start = self.cur_range();
4037 self.require_keyword(Keyword::Generic, start);
4038 self.advance();
4039 self.expect_punct(Punct::LParen, " after '_Generic'")?;
4040 let controlling = self.parse_assignment_expr()?;
4041 let mut assocs = Vec::new();
4042 while self.eat_punct(Punct::Comma).is_some() {
4043 let astart = self.cur_range();
4044 let ty = if self.eat_keyword(Keyword::Default).is_some() {
4045 None
4046 } else {
4047 Some(self.parse_type_name()?)
4048 };
4049 self.expect_punct(Punct::Colon, " after the type of a '_Generic' association")?;
4050 let value = self.parse_assignment_expr()?;
4051 assocs.push(GenericAssoc {
4052 ty,
4053 value,
4054 range: self.span_to_here(astart),
4055 });
4056 }
4057 let rparen = self.expect_punct(Punct::RParen, " to close '_Generic'")?;
4058 if assocs.is_empty() {
4059 self.error(
4060 start.join(rparen),
4061 "'_Generic' requires at least one association",
4062 );
4063 }
4064 Ok(Expr {
4065 kind: ExprKind::Generic {
4066 controlling: Box::new(controlling),
4067 assocs,
4068 },
4069 range: start.join(rparen),
4070 })
4071 }
4072
4073 fn parse_primary_expr(&mut self) -> PResult<Expr> {
4074 let range = self.cur_range();
4075 match self.peek().kind.clone() {
4076 TokenKind::Keyword(Keyword::Generic) => self.parse_generic_selection(),
4077 TokenKind::Keyword(k @ (Keyword::True | Keyword::False)) => {
4078 self.advance();
4079 Ok(Expr {
4080 kind: ExprKind::Bool(k == Keyword::True),
4081 range,
4082 })
4083 }
4084 TokenKind::Keyword(Keyword::Nullptr) => {
4085 self.advance();
4086 Ok(Expr {
4087 kind: ExprKind::Nullptr,
4088 range,
4089 })
4090 }
4091 TokenKind::Ident(name) => {
4092 self.advance();
4093 Ok(Expr {
4094 kind: ExprKind::Ident(Ident { name, range }),
4095 range,
4096 })
4097 }
4098 TokenKind::Int(lit) => {
4099 self.advance();
4100 Ok(Expr {
4101 kind: ExprKind::Int(lit),
4102 range,
4103 })
4104 }
4105 TokenKind::Float(lit) => {
4106 self.advance();
4107 Ok(Expr {
4108 kind: ExprKind::Float(lit),
4109 range,
4110 })
4111 }
4112 TokenKind::Char(lit) => {
4113 self.advance();
4114 Ok(Expr {
4115 kind: ExprKind::Char(lit),
4116 range,
4117 })
4118 }
4119 TokenKind::Str(first) => Ok(self.parse_string_literal(first, range)),
4120 TokenKind::Punct(Punct::LParen) => {
4121 self.advance();
4122 if self.at_punct(Punct::LBrace) {
4126 let block = self.parse_compound_stmt()?;
4127 let rp =
4128 self.expect_punct(Punct::RParen, " to close a statement expression")?;
4129 return Ok(Expr {
4130 kind: ExprKind::StmtExpr(Box::new(block)),
4131 range: range.join(rp),
4132 });
4133 }
4134 let inner = self.parse_expr()?;
4135 let rp = self.expect_punct(Punct::RParen, " after parenthesized expression")?;
4136 Ok(Expr {
4137 kind: inner.kind,
4138 range: range.join(rp),
4139 })
4140 }
4141 _ => {
4142 let found = self.describe_cur();
4143 Err(self.error_bail(range, format!("expected expression, found {found}")))
4144 }
4145 }
4146 }
4147
4148 fn parse_string_literal(&mut self, first: StrLit, first_range: SourceRange) -> Expr {
4156 self.advance();
4157 let mut kind = first.kind;
4158 let mut values = first.values;
4159 let mut text = first.text;
4160 let mut range = first_range;
4161 while let TokenKind::Str(next) = self.peek().kind.clone() {
4162 let piece_range = self.cur_range();
4163 if next.kind != kind {
4164 if kind == StrKind::Narrow {
4165 values = recode_from_narrow(&values, next.kind);
4166 kind = next.kind;
4167 } else if next.kind != StrKind::Narrow {
4168 self.error(
4169 piece_range,
4170 format!(
4171 "cannot concatenate a '{}' string literal with a '{}' one",
4172 kind.prefix(),
4173 next.kind.prefix()
4174 ),
4175 );
4176 }
4177 }
4178 if next.kind == kind || next.kind != StrKind::Narrow {
4179 values.extend_from_slice(&next.values);
4180 } else {
4181 values.extend(recode_from_narrow(&next.values, kind));
4182 }
4183 text.push(' ');
4184 text.push_str(&next.text);
4185 range = range.join(piece_range);
4186 self.advance();
4187 }
4188 Expr {
4189 kind: ExprKind::Str(StrLit { kind, values, text }),
4190 range,
4191 }
4192 }
4193}
4194
4195fn extended_float_type(name: &str) -> Option<&'static str> {
4207 match name {
4208 "__float128" | "_Float128" | "_Float128x" => Some("binary128"),
4209 "_Float64x" => Some("the extended-precision type behind 'long double'"),
4210 "__fp16" | "_Float16" => Some("binary16"),
4211 "__bf16" | "__bfloat16" => Some("bfloat16"),
4212 "_Float32" | "_Float32x" => Some("the TS 18661-3 spelling of a binary32 type"),
4216 "_Float64" => Some("the TS 18661-3 spelling of a binary64 type"),
4217 _ => None,
4218 }
4219}
4220
4221fn recode_from_narrow(values: &[u32], kind: StrKind) -> Vec<u32> {
4226 if kind == StrKind::Narrow || kind == StrKind::Utf8 {
4227 return values.to_vec();
4228 }
4229 let bytes: Vec<u8> = values.iter().map(|v| *v as u8).collect();
4230 let text = String::from_utf8_lossy(&bytes);
4231 let mut out = Vec::with_capacity(values.len());
4232 for ch in text.chars() {
4233 let value = ch as u32;
4234 if kind == StrKind::Utf16 && value > 0xffff {
4235 let v = value - 0x1_0000;
4236 out.push(0xd800 + (v >> 10));
4237 out.push(0xdc00 + (v & 0x3ff));
4238 } else {
4239 out.push(value);
4240 }
4241 }
4242 out
4243}