Skip to main content

rucc_sema/check/
ty.rs

1//! Turning what a declaration wrote into a type: the specifiers, then the declarator.
2//!
3//! Design: `spec/07-types-and-semantics.md` section 7.1.
4//!
5//! A C declaration says its type in two halves that are read in opposite directions. The
6//! specifiers are a set and are read together, so `unsigned static const long int` is a
7//! perfectly ordinary `static const unsigned long`. The declarator is a sequence and is read
8//! outward from the name, so `int (*f[3])(char)` says that `f` is an array of three pointers to
9//! functions taking `char` and returning `int`. This is the one place that knows both, and
10//! everything downstream asks the type table rather than reading a specifier list again.
11//!
12//! # Two directions, one fold
13//!
14//! [`Derived`](rucc_ast::Derived) is already in the spoken order, nearest the name first, which
15//! the parser produced by pushing while it descended into the parentheses. So the type is built
16//! by folding that list from its far end onto the type the specifiers named, and the step
17//! nearest the name is applied last. That is why the loop below runs backwards and why the
18//! index being zero is worth a name: an array is only allowed to say `static` or carry
19//! qualifiers when it is the step nearest the name of a parameter, which is what makes
20//! `void f(int a[const 3])` legal and `int a[const 3];` not.
21//!
22//! # What is not here yet
23//!
24//! The attributes a member carries. `_Alignas` on a member, `packed` on a member or on the
25//! record, and the `#pragma pack` around it are each a number
26//! [`FieldDecl`](rucc_types::FieldDecl) already has a place for, and none of them is filled in,
27//! because what fills them in is attribute checking rather than type building.
28//!
29//! `auto` as a type specifier needs the initializer that it takes its type from, so it waits on
30//! initialization. `_Complex` on an integer type, which gcc accepts, has no type to build
31//! because [`TypeKind::Complex`](rucc_types::TypeKind::Complex) holds a floating kind, and
32//! `_Imaginary` is a keyword gcc has never implemented either.
33
34use std::collections::{HashMap, HashSet};
35
36use rucc_ast::{
37    self as ast, ArraySize, Complexity, Derived, ParamKind, Scalar, TypeSpec, TypeofArg,
38};
39use rucc_base::float::Format;
40use rucc_base::{Idx, Symbol, sym};
41use rucc_diag::{Diagnostic, Span};
42use rucc_session::Std;
43use rucc_target::{TargetInfo, VaList};
44use rucc_types::{
45    ArrayLen, FieldDecl, FloatKind, FunctionType, IntKind, Qualifiers, RecordKind, RecordOptions,
46    TypeId, adjust_parameter, is_complete, is_function, is_integer, is_pointer, is_void, layout,
47};
48
49use crate::check::Checker;
50use crate::decl::DeclId;
51use crate::scope::{Binding, Tag, TagKind};
52
53mod tag;
54
55/// The widest `_BitInt` there is, which is the width the constant folding can hold.
56///
57/// This is not gcc's number. gcc 16 has `__BITINT_MAXWIDTH__` at sixty five thousand five
58/// hundred and thirty five, which its own arbitrary precision arithmetic can fold and this
59/// compiler's hundred and twenty eight bit constants cannot. Widening it is a change to
60/// [`Const`](crate::Const) rather than to this, and until that happens the limit is reported
61/// where a wider one is written rather than silently truncated. `__BITINT_MAXWIDTH__` in
62/// `rucc-pp` is this same number and has to be changed with it.
63const MAX_BIT_INT_WIDTH: u32 = 128;
64
65/// What the type builder has worked out already and is not going to work out twice.
66#[derive(Debug, Default)]
67pub(crate) struct Built {
68    /// What each specifier list turned out to name.
69    ///
70    /// The declarators of one declaration share one specifier list, and `struct { int x; } a, b;`
71    /// declares one structure and not two, so building the type a second time is not a slow way
72    /// to get the same answer, it is a different answer. Every specifier list is written at one
73    /// place in the source and is checked once, so remembering what it named is enough.
74    specified: HashMap<ast::DeclSpecsId, TypeId>,
75    /// The tag types whose body has been read.
76    ///
77    /// This is what tells a redefinition from a completion, and the type table cannot answer it
78    /// on its own. A record is complete exactly when its body has been read, but C23's
79    /// `enum E : int;` is a complete type that has never had one, so `enum E : int;` followed by
80    /// `enum E : int { A };` is a definition of something already complete and is allowed.
81    defined: HashSet<TypeId>,
82    /// What the named parameters of each prototype were declared as, by the first parameter of
83    /// the list.
84    ///
85    /// A function definition binds these again in the body's scope, so that the `n` a prototype
86    /// saw in `void f(int n, int a[n])` and the `n` the body assigns to are one declaration
87    /// rather than two that happen to share a name. The key is the first parameter because a run
88    /// of indices is not something a map can be keyed by, and a prototype always has at least one
89    /// parameter in it: `(void)` and `()` are parameter lists of other kinds.
90    params: HashMap<Idx<ast::Param>, Vec<DeclId>>,
91    /// The target's `__builtin_va_list`, once something has asked for it.
92    ///
93    /// Every mention of the keyword names one type, so this is not only a cache. On the targets
94    /// where the type is a record, building it a second time would build a second record, and
95    /// two records with the same members are still two types, so `va_list a, b; a = b;` would
96    /// stop being an assignment and start being a diagnostic.
97    va_list: Option<TypeId>,
98}
99
100/// Who a declaration is about, for the diagnostics that name it.
101///
102/// gcc writes every one of these two ways, once for a declarator with a name and once for the
103/// abstract declarator of a type name: `declaration of 'a' as array of voids` against
104/// `declaration of type name as array of voids`. The two are kept together here so that a
105/// message cannot be written in only one of its forms.
106#[derive(Debug, Clone, Copy)]
107struct Subject {
108    /// The name, absent in an abstract declarator.
109    name: Option<Symbol>,
110    /// What a diagnostic about the declarator points at.
111    span: Span,
112}
113
114/// What one mention of a tag turned out to be.
115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
116enum TagUse {
117    /// The tag names a type already, which is that type.
118    Known(TypeId),
119    /// The tag names nothing yet, so this mention is what declares it.
120    New,
121    /// There was no tag, so there is nothing to bind and a fresh type every time.
122    Anonymous,
123    /// The tag names something of another kind, which has been reported.
124    Wrong,
125}
126
127/// Where a declarator is being read, which decides what it is allowed to say.
128#[derive(Debug, Clone, Copy, Default)]
129pub(in crate::check) struct Place {
130    /// Whether this declarator is a function parameter, which is what lets its outermost array
131    /// carry `static` and qualifiers, since those belong to the pointer it becomes.
132    parameter: bool,
133    /// Whether this declarator is a member of a structure or a union, which is what names the
134    /// place in the one message that has to name it.
135    member: bool,
136    /// Whether this declarator is inside a function prototype, which is the only place `[*]`
137    /// means anything.
138    prototype: bool,
139}
140
141/// A member of a structure or a union, which is the one place that is named by a constant.
142pub(in crate::check) const MEMBER: Place =
143    Place { parameter: false, member: true, prototype: false };
144
145impl Checker<'_> {
146    /// The type a type name names, which is a cast, a `sizeof` or a `_Generic` association.
147    pub fn type_name(&mut self, id: ast::TypeNameId) -> TypeId {
148        let name = self.ast[id];
149        self.declared_type(name.specs, name.declarator)
150    }
151
152    /// The type one declarator of one declaration declares.
153    ///
154    /// Always gives back a type. A declarator that does not check is reported and answered with
155    /// the nearest thing that does, so that the declaration around it is still checked instead
156    /// of collapsing, which is the same rule the expressions follow with their poisoned nodes.
157    pub fn declared_type(
158        &mut self,
159        specs: ast::DeclSpecsId,
160        declarator: ast::DeclaratorId,
161    ) -> TypeId {
162        self.build_type(specs, declarator, Place::default())
163    }
164
165    /// The type a declaration with no declarator names, which is what declares a tag.
166    ///
167    /// `struct S { int x; };` builds and lays out the record even though there is nothing for it
168    /// to be the type of, since that is where its members are checked.
169    pub(in crate::check) fn declared_specs(&mut self, specs: ast::DeclSpecsId) -> TypeId {
170        let span = self.ast[specs].span;
171        self.specified_type(specs, Subject { name: None, span }, Place::default())
172    }
173
174    /// Declares a typedef name in the current scope.
175    ///
176    /// Public for the same reason [`Checker::declare_object`] is: a caller that checks one
177    /// expression rather than a translation unit still needs a way to say that a name the
178    /// parser already decided was a type is one.
179    pub fn declare_typedef(&mut self, name: Symbol, ty: TypeId) {
180        self.scopes.declare(name, Binding::Typedef(ty));
181    }
182
183    /// The specifiers and the declarator, in the place they were written.
184    fn build_type(
185        &mut self,
186        specs: ast::DeclSpecsId,
187        declarator: ast::DeclaratorId,
188        place: Place,
189    ) -> TypeId {
190        let node = self.ast[declarator];
191        let subject = Subject {
192            name: node.name,
193            span: if node.name.is_some() { node.name_span } else { node.span },
194        };
195        let base = self.specified_type(specs, subject, place);
196        self.derive(base, declarator, subject, place)
197    }
198
199    /// The type the specifiers alone name, qualifiers included.
200    ///
201    /// Answered once per specifier list rather than once per declarator, because the
202    /// declarators of one declaration share one list and `struct { int x; } a, b;` declares one
203    /// structure. Building it twice would not be a slow way to the same answer, it would be two
204    /// structures and a second warning about anything the specifiers themselves got wrong.
205    fn specified_type(&mut self, id: ast::DeclSpecsId, subject: Subject, place: Place) -> TypeId {
206        if let Some(&ty) = self.built.specified.get(&id) {
207            return ty;
208        }
209        let specs = self.ast[id];
210        let base = self.type_spec(specs.ty, specs.span, subject, place);
211        let ty = self.qualify(base, specs.quals, specs.span);
212        self.built.specified.insert(id, ty);
213        ty
214    }
215
216    /// The type a single type specifier names.
217    fn type_spec(&mut self, spec: TypeSpec, span: Span, subject: Subject, place: Place) -> TypeId {
218        match spec {
219            TypeSpec::None => {
220                let what = match subject.name {
221                    Some(name) => format!("in declaration of '{}'", self.text(name)),
222                    None => String::new(),
223                };
224                let message = format!("type defaults to 'int' {what}");
225                self.report(
226                    Diagnostic::error(message.trim_end().to_string(), subject.span)
227                        .with_code("E0526"),
228                );
229                self.int()
230            }
231            TypeSpec::Builtin(builtin) => match builtin.resolve() {
232                Some(basic) => self.basic_type(basic.scalar, basic.complexity, span),
233                None => {
234                    self.report(
235                        Diagnostic::error(
236                            "two or more data types in declaration specifiers".to_string(),
237                            span,
238                        )
239                        .with_code("E0525"),
240                    );
241                    self.int()
242                }
243            },
244            TypeSpec::Record { kind, tag, fields, attrs, pack } => {
245                self.record_spec(kind, tag, fields, attrs, pack, span)
246            }
247            TypeSpec::Enum { tag, enumerators, underlying, .. } => {
248                self.enum_spec(tag, enumerators, underlying, span)
249            }
250            TypeSpec::Typedef(name) => match self.scopes.lookup(name) {
251                Some(Binding::Typedef(ty)) => ty,
252                // The parser only writes this down for a name its own scope stack said was a
253                // type, so the two disagreeing means a declaration was checked in one and not
254                // in the other. Reported rather than assumed, since the alternative is a
255                // declaration that silently means something else.
256                _ => {
257                    let name = self.text(name).to_owned();
258                    self.report(
259                        Diagnostic::error(format!("unknown type name '{name}'"), span)
260                            .with_code("E0546"),
261                    );
262                    self.int()
263                }
264            },
265            TypeSpec::Typeof { unqual, operand } => self.typeof_type(unqual, operand),
266            TypeSpec::Atomic(inner) => {
267                let inner = self.type_name(inner);
268                self.atomic_type(inner, span)
269            }
270            TypeSpec::VaList => self.va_list_type(),
271            TypeSpec::Auto(which) => {
272                // The deduction itself is in `check/decl.rs`, which takes the declaration apart
273                // before it asks for a type at all. What reaches here is the specifier written
274                // where nothing deduces anything, and the two places that can happen are a
275                // member and a parameter: a type name cannot be written with it, and every
276                // other declaration goes through the deduction. gcc turns both away in its
277                // parser and says so in terms of its grammar. clang says what is wrong with the
278                // declaration instead, and that is the wording used here.
279                let spelled = which.spelling();
280                let place = if place.member { "struct member" } else { "function prototype" };
281                self.report(
282                    Diagnostic::error(format!("'{spelled}' not allowed in {place}"), span)
283                        .with_code("E0651"),
284                );
285                self.int()
286            }
287        }
288    }
289
290    /// One of the types a keyword or a run of keywords names.
291    fn basic_type(&mut self, scalar: Scalar, complexity: Complexity, span: Span) -> TypeId {
292        let kind = int_kind(scalar);
293        let float = float_kind(scalar, self.cx.target);
294
295        match complexity {
296            Complexity::Real => match (scalar, kind, float) {
297                (Scalar::Void, _, _) => self.types.void(),
298                (Scalar::Bool, _, _) => self.types.boolean(),
299                (Scalar::BitInt { width, unsigned }, _, _) => self.bit_int_type(width, !unsigned),
300                (_, Some(kind), _) => self.types.int(kind),
301                (_, _, Some(kind)) => self.types.float(kind),
302                // A floating type the target does not have. `_Float128x` is one no target gcc
303                // supports has, and `__float80` is one only x86 has, and gcc turns both of them
304                // away in the same words.
305                (Scalar::Float128x | Scalar::Float80, _, _) => {
306                    self.unavailable_type(spell_scalar(scalar), span);
307                    self.types.float(FloatKind::Double)
308                }
309                // The decimal floating types are named by keywords the lexer and the parser
310                // both know and are deferred past 1.0 by `spec/19-open-questions.md`, so one of
311                // them is refused where it is written rather than given a type it is not.
312                _ => {
313                    self.unsupported_type(&format!("the type `{}`", spell_scalar(scalar)), span);
314                    self.types.float(FloatKind::Double)
315                }
316            },
317            Complexity::Complex => match float {
318                Some(kind) => self.types.complex(kind),
319                // gcc accepts `_Complex int`. There is no type for it here, since a complex
320                // type holds a floating kind, and inventing one for a GNU extension nothing
321                // uses is not worth what it costs every reader of that enum.
322                None => {
323                    let what = format!("`_Complex` on the type `{}`", spell_scalar(scalar));
324                    self.unsupported_type(&what, span);
325                    self.types.complex(FloatKind::Double)
326                }
327            },
328            // gcc parses this keyword and has never implemented the type behind it.
329            Complexity::Imaginary => {
330                self.unsupported_type("`_Imaginary`", span);
331                self.types.complex(float.unwrap_or(FloatKind::Double))
332            }
333        }
334    }
335
336    /// `__builtin_va_list`, which is the one type the target names rather than the source.
337    ///
338    /// Built once and remembered, since every mention of the keyword is the same type and the
339    /// record ones would otherwise be a new record each time. The members are the psABI's, named
340    /// as the psABI names them: nothing here reads them, and a program that prints a `va_list`
341    /// in a debugger reads all of them.
342    pub(crate) fn va_list_type(&mut self) -> TypeId {
343        if let Some(ty) = self.built.va_list {
344            return ty;
345        }
346        let ty = match self.cx.target.va_list {
347            VaList::CharPointer => {
348                let elem = self.types.int(IntKind::Char);
349                self.types.pointer(elem)
350            }
351            VaList::VoidPointer => {
352                let elem = self.types.void();
353                self.types.pointer(elem)
354            }
355            VaList::SysV => {
356                let uint = self.types.int(IntKind::UInt);
357                let void = self.types.void();
358                let ptr = self.types.pointer(void);
359                let record = self.builtin_record(
360                    sym::VA_LIST_TAG,
361                    &[
362                        (sym::GP_OFFSET, uint),
363                        (sym::FP_OFFSET, uint),
364                        (sym::OVERFLOW_ARG_AREA, ptr),
365                        (sym::REG_SAVE_AREA, ptr),
366                    ],
367                );
368                // The array of one is the whole reason a SysV `va_list` can be handed to
369                // `vfprintf` and come back moved on: what is passed is the address of the one
370                // element, so the callee reads and writes the caller's list rather than a copy.
371                self.types.array(record, ArrayLen::Fixed(1))
372            }
373            VaList::Aapcs => {
374                let int = self.types.int(IntKind::Int);
375                let void = self.types.void();
376                let ptr = self.types.pointer(void);
377                self.builtin_record(
378                    sym::VA_LIST,
379                    &[
380                        (sym::STACK, ptr),
381                        (sym::GR_TOP, ptr),
382                        (sym::VR_TOP, ptr),
383                        (sym::GR_OFFS, int),
384                        (sym::VR_OFFS, int),
385                    ],
386                )
387            }
388        };
389        self.built.va_list = Some(ty);
390        ty
391    }
392
393    /// A complete record the compiler builds itself, with a tag and ordinary members.
394    ///
395    /// Not put in the tag scope. A program that writes `struct __va_list_tag` is writing about a
396    /// tag of its own, which is what gcc's own headers do not do and what the one program that
397    /// does would have meant either way.
398    fn builtin_record(&mut self, tag: Symbol, members: &[(Symbol, TypeId)]) -> TypeId {
399        let id = self.types.declare_record(RecordKind::Struct, Some(tag));
400        let decls: Vec<FieldDecl> =
401            members.iter().map(|&(name, ty)| FieldDecl::new(Some(name), ty)).collect();
402        let laid_out = rucc_types::layout_record(
403            &self.types,
404            RecordKind::Struct,
405            &decls,
406            &RecordOptions::default(),
407            self.cx.target,
408        )
409        .expect("a record of pointers and integers lays out");
410        self.types.complete_record(id, laid_out);
411        self.types.record(id)
412    }
413
414    /// `typeof(x)` or `typeof(T)`, and the C23 spelling that takes the qualifiers off.
415    fn typeof_type(&mut self, unqual: bool, operand: TypeofArg) -> TypeId {
416        // The expression is checked and never evaluated, 6.7.2.5p3. Checking it is what gives
417        // it a type at all, and an array or a function keeps its own type here, since nothing
418        // has asked for its value and it is the asking that decays it.
419        let ty = match operand {
420            TypeofArg::Expr(expr) => {
421                let node = self.expr(expr);
422                self.tast[node].ty
423            }
424            TypeofArg::Type(name) => self.type_name(name),
425        };
426        if !unqual {
427            return ty;
428        }
429        // `typeof_unqual` takes off the qualifiers and `_Atomic` with them, which is the one
430        // place the two spellings of `_Atomic` are told apart again.
431        let bare = match self.types.kind(self.types.canonical(ty)) {
432            rucc_types::TypeKind::Atomic(inner) => inner,
433            _ => ty,
434        };
435        self.types.unqualified(bare)
436    }
437
438    /// `_BitInt(N)`, whose width is a constant expression and has a range.
439    ///
440    /// A signed one is never narrower than two bits, because one of them is the sign and a type
441    /// with no value bits is not a type. An unsigned one may be a single bit, and
442    /// `unsigned _BitInt(1)` holding nothing but zero and one is a legal, if peculiar, type.
443    fn bit_int_type(&mut self, width: ast::ExprId, signed: bool) -> TypeId {
444        let value = self.expr(width);
445        let span = self.tast.expr_span(value);
446        let Ok(bits) = self.eval_integer(value) else {
447            // Poisoned or not a constant. The second case is worth its own sentence, since
448            // `_BitInt(n)` reads as if it might be a variably modified type and is not.
449            if !self.is_poisoned(value) {
450                self.report(
451                    Diagnostic::error(
452                        "'_BitInt' argument is not an integer constant expression".to_string(),
453                        span,
454                    )
455                    .with_code("E0529"),
456                );
457            }
458            return self.int();
459        };
460        if bits <= 0 {
461            let message = format!(
462                "'_BitInt' argument '{bits}' is not a positive integer constant expression"
463            );
464            self.report(Diagnostic::error(message, span).with_code("E0529"));
465            return self.int();
466        }
467        if signed && bits < 2 {
468            let message = "'signed _BitInt' argument must be at least 2".to_string();
469            self.report(Diagnostic::error(message, span).with_code("E0529"));
470            return self.int();
471        }
472        if bits > i128::from(MAX_BIT_INT_WIDTH) {
473            let message = format!(
474                "'_BitInt' argument '{bits}' is larger than 'BITINT_MAXWIDTH' '{MAX_BIT_INT_WIDTH}'"
475            );
476            self.report(Diagnostic::error(message, span).with_code("E0529"));
477            return self.int();
478        }
479        let bits = u32::try_from(bits).unwrap_or(MAX_BIT_INT_WIDTH);
480        self.types.bit_int(signed, bits)
481    }
482
483    /// `_Atomic(T)`, which is a type and not a qualifier and which two things cannot be.
484    fn atomic_type(&mut self, inner: TypeId, span: Span) -> TypeId {
485        let canonical = self.types.canonical(inner);
486        let what = if rucc_types::is_array(&self.types, canonical) {
487            "'_Atomic'-qualified array type"
488        } else if is_function(&self.types, canonical) {
489            "'_Atomic'-qualified function type"
490        } else if !self.types.quals(inner).is_none() {
491            "'_Atomic' applied to a qualified type"
492        } else {
493            return self.types.atomic(inner);
494        };
495        self.report(Diagnostic::error(what.to_string(), span).with_code("E0527"));
496        inner
497    }
498
499    /// A `struct` or a `union`, referred to by tag or declared by one.
500    fn record_spec(
501        &mut self,
502        kind: ast::RecordKind,
503        tag: Option<Symbol>,
504        fields: Option<ast::MemberList>,
505        attrs: ast::AttrList,
506        pack: Option<u32>,
507        span: Span,
508    ) -> TypeId {
509        let (kind, tag_kind) = match kind {
510            ast::RecordKind::Struct => (RecordKind::Struct, TagKind::Struct),
511            ast::RecordKind::Union => (RecordKind::Union, TagKind::Union),
512        };
513        let Some(members) = fields else {
514            return match self.tag_use(tag, tag_kind, span) {
515                TagUse::Known(ty) => ty,
516                found => {
517                    let id = self.types.declare_record(kind, tag);
518                    let ty = self.types.record(id);
519                    self.bind_tag(found, tag, tag_kind, ty);
520                    ty
521                }
522            };
523        };
524        // The tag is bound before the members are read, which is what makes
525        // `struct S { struct S *next; };` refer to the structure being defined rather than
526        // declare a second one inside it.
527        let (id, ty) = self.record_defined(kind, tag, tag_kind, span);
528        self.built.defined.insert(ty);
529        self.record_body(id, kind, members, attrs, pack, span);
530        ty
531    }
532
533    /// An `enum`, referred to by tag or declared by one, with C23's underlying type.
534    fn enum_spec(
535        &mut self,
536        tag: Option<Symbol>,
537        enumerators: Option<ast::EnumeratorList>,
538        underlying: Option<ast::TypeNameId>,
539        span: Span,
540    ) -> TypeId {
541        let underlying = underlying.map(|name| {
542            let ty = self.type_name(name);
543            if is_integer(&self.types, self.types.canonical(ty)) {
544                return ty;
545            }
546            self.report(
547                Diagnostic::error("invalid 'enum' underlying type".to_string(), span)
548                    .with_code("E0530"),
549            );
550            self.int()
551        });
552
553        let Some(list) = enumerators else {
554            return match self.tag_use(tag, TagKind::Enum, span) {
555                TagUse::Known(ty) => ty,
556                found => {
557                    let id = self.types.declare_enum(tag);
558                    // An enumeration whose representation the program wrote is complete from the
559                    // point it says so, which is the whole reason C23 lets it be written:
560                    // `enum E : int;` is a forward declaration usable by value straight away.
561                    if let Some(underlying) = underlying {
562                        self.types.complete_enum(id, underlying, true);
563                    }
564                    let ty = self.types.enumeration(id);
565                    self.bind_tag(found, tag, TagKind::Enum, ty);
566                    ty
567                }
568            };
569        };
570        let (id, ty) = self.enum_defined(tag, span);
571        self.built.defined.insert(ty);
572        self.enum_body(id, list, underlying, span);
573        ty
574    }
575
576    /// What a mention of a tag turns out to be.
577    ///
578    /// Which scope a tag goes in is not decided here. `struct S;` on its own declares a new type
579    /// in the current scope even where an outer one is visible, and `struct S *p;` refers to
580    /// whatever `S` already means, and the difference is whether the declaration had any
581    /// declarators, which is a fact about the declaration and not about the type. So this asks
582    /// the whole stack, and the declaration checking that knows the difference will ask
583    /// [`Scopes::tag_here`](crate::Scopes::tag_here) before it gets here.
584    fn tag_use(&mut self, tag: Option<Symbol>, kind: TagKind, span: Span) -> TagUse {
585        // No tag is nothing to look up and nothing to bind: the type is reachable only through
586        // the declarators of the one declaration that wrote it.
587        let Some(name) = tag else { return TagUse::Anonymous };
588        match self.scopes.tag(name) {
589            Some(found) if found.kind == kind => TagUse::Known(found.ty),
590            Some(_) => {
591                let spelled = self.text(name).to_owned();
592                self.report(
593                    Diagnostic::error(format!("'{spelled}' defined as wrong kind of tag"), span)
594                        .with_code("E0531"),
595                );
596                TagUse::Wrong
597            }
598            None => TagUse::New,
599        }
600    }
601
602    /// Binds a tag to the type just built for it, where this mention is what declares it.
603    fn bind_tag(&mut self, found: TagUse, tag: Option<Symbol>, kind: TagKind, ty: TypeId) {
604        // A tag that already means something else keeps meaning it. Rebinding would turn one
605        // diagnostic into one per use, and the uses that follow were written against the
606        // declaration that is already there.
607        if !matches!(found, TagUse::New) {
608            return;
609        }
610        if let Some(name) = tag {
611            self.scopes.declare_tag(name, Tag { kind, ty });
612        }
613    }
614
615    /// The qualifiers a specifier list or a pointer wrote, applied to the type they qualify.
616    pub(in crate::check) fn qualify(
617        &mut self,
618        ty: TypeId,
619        quals: ast::Quals,
620        span: Span,
621    ) -> TypeId {
622        // `_Atomic` written where a qualifier goes qualifies whatever the declarator arrives at,
623        // and it constructs a type rather than adding a bit to one, which is why it is applied
624        // before the qualifiers rather than beside them.
625        let ty = if quals.has(ast::Quals::ATOMIC) { self.atomic_type(ty, span) } else { ty };
626        let mut result = Qualifiers::NONE;
627        if quals.has(ast::Quals::CONST) {
628            result = result.with(Qualifiers::CONST);
629        }
630        if quals.has(ast::Quals::VOLATILE) {
631            result = result.with(Qualifiers::VOLATILE);
632        }
633        if quals.has(ast::Quals::RESTRICT) {
634            if is_pointer(&self.types, self.types.canonical(ty)) {
635                result = result.with(Qualifiers::RESTRICT);
636            } else {
637                self.report(
638                    Diagnostic::error("invalid use of 'restrict'".to_string(), span)
639                        .with_code("E0528"),
640                );
641            }
642        }
643        self.types.qualified(ty, result)
644    }
645
646    /// Folds the declarator onto the type the specifiers named.
647    fn derive(
648        &mut self,
649        base: TypeId,
650        declarator: ast::DeclaratorId,
651        subject: Subject,
652        place: Place,
653    ) -> TypeId {
654        // The tree outlives the checker's own borrows, so taking the reference out first is
655        // what lets the loop below call methods that take the checker mutably.
656        let ast = self.ast;
657        let steps = &ast[ast[declarator].derived];
658        let mut ty = base;
659        for (index, step) in steps.iter().enumerate().rev() {
660            // Nearest the name, which is the step a parameter's adjustment applies to and the
661            // only one allowed to write `static` or a qualifier inside its brackets.
662            let nearest = index == 0;
663            ty = match *step {
664                Derived::Pointer { quals, .. } => {
665                    let pointer = self.types.pointer(ty);
666                    self.qualify(pointer, quals, subject.span)
667                }
668                Derived::Array { size, quals, has_static } => {
669                    if (!quals.is_none() || has_static) && !(place.parameter && nearest) {
670                        self.report(
671                            Diagnostic::error(
672                                "static or type qualifiers in non-parameter array declarator"
673                                    .to_string(),
674                                subject.span,
675                            )
676                            .with_code("E0540"),
677                        );
678                    }
679                    self.array_of(ty, size, subject, place)
680                }
681                Derived::Function { params, variadic, kind } => {
682                    self.function_of(ty, params, variadic, kind, subject)
683                }
684            };
685        }
686        ty
687    }
688
689    /// An array of the element type the steps closer to the name arrived at.
690    fn array_of(
691        &mut self,
692        elem: TypeId,
693        size: ArraySize,
694        subject: Subject,
695        place: Place,
696    ) -> TypeId {
697        let canonical = self.types.canonical(elem);
698        let bad = if is_void(&self.types, canonical) {
699            Some(("as array of voids", "E0532"))
700        } else if is_function(&self.types, canonical) {
701            Some(("as array of functions", "E0533"))
702        } else {
703            None
704        };
705        if let Some((what, code)) = bad {
706            let who = self.declaration_of(subject);
707            self.report(Diagnostic::error(format!("{who} {what}"), subject.span).with_code(code));
708            return elem;
709        }
710        if !is_complete(&self.types, canonical) {
711            let spelled = self.spell(elem);
712            self.report(
713                Diagnostic::error(
714                    format!("array type has incomplete element type '{spelled}'"),
715                    subject.span,
716                )
717                .with_code("E0534"),
718            );
719            return elem;
720        }
721        let len = self.array_len(elem, size, subject, place);
722        self.types.array(elem, len)
723    }
724
725    /// How many elements an array has, which is four different answers and three diagnostics.
726    fn array_len(
727        &mut self,
728        elem: TypeId,
729        size: ArraySize,
730        subject: Subject,
731        place: Place,
732    ) -> ArrayLen {
733        let expr = match size {
734            ArraySize::Unspecified => return ArrayLen::Unknown,
735            ArraySize::Star if place.prototype => return ArrayLen::Star,
736            ArraySize::Star => {
737                self.report(
738                    Diagnostic::error(
739                        "'[*]' not allowed in other than function prototype scope".to_string(),
740                        subject.span,
741                    )
742                    .with_code("E0539"),
743                );
744                return ArrayLen::Unknown;
745            }
746            ArraySize::Expr(expr) => expr,
747        };
748
749        let value = self.expr(expr);
750        if self.is_poisoned(value) {
751            return ArrayLen::Unknown;
752        }
753        // As a value, since this is a size and not an object, and because the same node is what
754        // `sizeof` of the array is built out of: the walk to the IR evaluates it once where the
755        // declaration is and answers with that afterwards, which only works if both are it.
756        let value = self.value(value);
757        let span = self.tast.expr_span(value);
758        if !is_integer(&self.types, self.types.canonical(self.tast[value].ty)) {
759            self.report(
760                Diagnostic::error("size of array has non-integer type".to_string(), span)
761                    .with_code("E0535"),
762            );
763            return ArrayLen::Unknown;
764        }
765
766        match self.eval_integer(value) {
767            Ok(count) if count < 0 => {
768                let who = self.array_named(subject);
769                self.report(
770                    Diagnostic::error(format!("size of {who} is negative"), span)
771                        .with_code("E0536"),
772                );
773                ArrayLen::Unknown
774            }
775            Ok(count) => {
776                let count = u64::try_from(count).unwrap_or(u64::MAX);
777                if self.too_large(elem, count) {
778                    let who = self.array_named(subject);
779                    let max = self.cx.target.max_object_size();
780                    let message = format!("size of {who} exceeds maximum object size '{max}'");
781                    self.report(Diagnostic::error(message, span).with_code("E0537"));
782                    return ArrayLen::Unknown;
783                }
784                ArrayLen::Fixed(count)
785            }
786            // A size that is not a constant is a variable length array, which is a type and not
787            // an error, except where there is no run time to evaluate it in.
788            Err(failure) => {
789                if failure.poisoned {
790                    return ArrayLen::Unknown;
791                }
792                if self.scopes.at_file_scope() {
793                    let who = match subject.name {
794                        Some(name) => format!("'{}'", self.text(name)),
795                        None => "type name".to_string(),
796                    };
797                    self.report(
798                        Diagnostic::error(
799                            format!("variably modified {who} at file scope"),
800                            subject.span,
801                        )
802                        .with_code("E0538"),
803                    );
804                    return ArrayLen::Unknown;
805                }
806                ArrayLen::Variable(self.tast.add_vla(value))
807            }
808        }
809    }
810
811    /// Whether an array of this many of these does not fit in an object.
812    fn too_large(&self, elem: TypeId, count: u64) -> bool {
813        let Ok(elem) = layout(&self.types, elem, self.cx.target) else {
814            return false;
815        };
816        // A zero sized element is a GNU empty structure, and any number of them is nothing.
817        elem.size != 0 && count > self.cx.target.max_object_size() / elem.size
818    }
819
820    /// A function taking these parameters and returning the type the steps arrived at.
821    fn function_of(
822        &mut self,
823        ret: TypeId,
824        params: ast::ParamList,
825        variadic: bool,
826        kind: ParamKind,
827        subject: Subject,
828    ) -> TypeId {
829        let canonical = self.types.canonical(ret);
830        let bad = if rucc_types::is_array(&self.types, canonical) {
831            Some(("an array", "E0542"))
832        } else if is_function(&self.types, canonical) {
833            Some(("a function", "E0541"))
834        } else {
835            None
836        };
837        let ret = match bad {
838            Some((what, code)) => {
839                let who = self.declared_as(subject);
840                self.report(
841                    Diagnostic::error(format!("{who} as function returning {what}"), subject.span)
842                        .with_code(code),
843                );
844                self.int()
845            }
846            None => ret,
847        };
848
849        let (params, prototyped) = match kind {
850            ParamKind::Void => (Vec::new(), true),
851            // `int f()` says nothing about the parameters before C23 and says there are none
852            // from C23 onwards, and which of those it means is visible in every call.
853            ParamKind::Empty => (Vec::new(), self.cx.std == Std::C23),
854            // An old-style definition's identifier list has no types in it at all. They arrive
855            // in the declarations between the parenthesis and the body, which is the function
856            // definition's business rather than this one's.
857            ParamKind::Identifiers => (Vec::new(), false),
858            ParamKind::Prototype => (self.prototype(params), true),
859        };
860        self.types.function(FunctionType { ret, params, variadic, prototyped })
861    }
862
863    /// The parameter types of a prototype, adjusted the way a parameter is.
864    fn prototype(&mut self, params: ast::ParamList) -> Vec<TypeId> {
865        let ast = self.ast;
866        let list = &ast[params];
867        // A prototype is a scope of its own, which is what makes the `n` in
868        // `void f(int n, int a[n])` mean the parameter and what makes it gone by the next
869        // declaration. A parameter is declared after its own type is built, since a name is not
870        // in scope for the declarator that declares it.
871        self.scopes.push();
872        let mut types = Vec::with_capacity(list.len());
873        let mut declared = Vec::new();
874        for (index, param) in list.iter().enumerate() {
875            let ty = match param.specs {
876                Some(specs) => self.build_type(
877                    specs,
878                    param.declarator,
879                    Place { parameter: true, member: false, prototype: true },
880                ),
881                // An identifier list, which the caller told apart by its kind and which cannot
882                // reach here. Its parameters have no specifiers at all.
883                None => self.int(),
884            };
885            let declarator = ast[param.declarator];
886            let span = if declarator.name.is_some() { declarator.name_span } else { param.span };
887            self.check_void_parameter(ty, declarator.name, index, span);
888
889            // The type the function has and the type the object has are two different types,
890            // and the difference is the qualifiers. `void f(const int x)` is compatible with
891            // `void f(int x)`, because a `const` there is a promise the function makes to
892            // itself and says nothing to a caller, and inside the body `x = 1` is still an
893            // assignment to a read-only object. So the list gets the adjusted type and the
894            // declaration gets the written one.
895            let adjusted = adjust_parameter(&mut self.types, ty);
896            // Which of the two the object gets is decided by the written type and not by the
897            // declarator, because a `typedef int matrix[2][3];` puts an array parameter there
898            // with no brackets in sight. An array and a function are the adjusted type either
899            // way, since a pointer is what the object is: `sizeof m` inside the body is the
900            // size of a pointer, and a compiler that answers with the array says twenty four.
901            let written = self.types.canonical(ty);
902            let object = if rucc_types::is_array(&self.types, written) {
903                // The qualifiers in `int a[const 3]` are the pointer's, since the array is not
904                // what the parameter has: they were written inside the brackets and belong
905                // outside them. They are the object's alone and never the function type's.
906                match ast[declarator.derived].first() {
907                    Some(&Derived::Array { quals, .. }) => self.qualify(adjusted, quals, span),
908                    _ => adjusted,
909                }
910            } else if is_function(&self.types, written) {
911                adjusted
912            } else {
913                ty
914            };
915            types.push(adjusted);
916
917            // The adjusted type and not the written one, because that is what the parameter is:
918            // `sizeof a` inside `void f(int a[3])` is the size of a pointer, and a compiler that
919            // declares the array here says twelve.
920            match declarator.name {
921                // The second of two parameters with one name, which is an error and still an
922                // object the call passes. It goes in the list without the name, since the name
923                // means the first one and the list has to stay as long as the types are.
924                Some(name) if self.scopes.lookup_here(name).is_some() => {
925                    let spelled = self.text(name).to_owned();
926                    self.report(
927                        Diagnostic::error(format!("redefinition of parameter '{spelled}'"), span)
928                            .with_code("E0545"),
929                    );
930                    declared.push(self.unnamed_object(object, span));
931                }
932                Some(name) => declared.push(self.declare_object(name, object, span)),
933                // C23 6.7.7.4p1 lets a definition leave a parameter unnamed, which gcc has taken
934                // for far longer than that. The object is passed either way and the list is what
935                // says what the function takes and in what order, so a declaration goes in for
936                // it: a list one short of the types is a definition whose entry block cannot be
937                // built, which is what `int f(int a, int) { return a; }` used to be refused as.
938                None => declared.push(self.unnamed_object(object, span)),
939            }
940        }
941        self.scopes.pop();
942        if let Some(first) = params.iter().next() {
943            self.built.params.insert(first, declared);
944        }
945        types
946    }
947
948    /// The parameter types of an old-style definition, read out of the declarations written
949    /// between its identifier list and its body.
950    ///
951    /// This is the one place a parameter is declared in two halves. The identifier list gives the
952    /// names and their order and says nothing about types, 6.7.6.3p14, and the declarations under
953    /// it give the types in whatever order they were written, 6.9.1p6. So the two can disagree in
954    /// every way two lists can, and each of those is a diagnostic gcc has a sentence for.
955    ///
956    /// The objects are stashed the way a prototype's are, so that the definition binds these same
957    /// declarations in its body rather than a second set that happens to share their names.
958    /// Nothing comes back: what the function's parameters are is a separate question, because the
959    /// answer to it is the promoted types and a prototype in scope can overrule even those.
960    pub(in crate::check) fn identifier_list(
961        &mut self,
962        params: ast::ParamList,
963        declarations: ast::DeclList,
964    ) {
965        let names = self.parameter_names(params);
966        // A scope of their own, which closes here, and the body opens another and binds these
967        // same declarations in it. A tag declared under the list is therefore not in reach of the
968        // body, so `int f(a) struct s { int x; } a; { struct s c; }` is an incomplete type in the
969        // body. gcc puts the list and the body in one scope and takes it; clang does what this
970        // does. Nothing can name such a tag from outside anyway, so there is nothing an old file
971        // could be relying on, and putting the two in one scope means opening it before the
972        // function's own name is merged into the scope outside it.
973        self.scopes.push();
974        let mut written = vec![None; names.len()];
975        let ids: Vec<ast::DeclId> = self.ast[declarations].to_vec();
976        for id in ids {
977            self.old_style_declaration(id, &names, &mut written);
978        }
979        let mut declared = Vec::with_capacity(names.len());
980        for (index, &(name, span)) in names.iter().enumerate() {
981            let ty = match written[index] {
982                Some(ty) => ty,
983                None => {
984                    // No declaration for this name, so it is an `int`. C89 said so and gcc still
985                    // takes it in that dialect; every dialect after it removed the rule, and gcc
986                    // reports it as an error rather than a warning from C99 onwards.
987                    if self.cx.std >= Std::C99 {
988                        let spelled = self.text(name).to_owned();
989                        self.report(
990                            Diagnostic::error(
991                                format!("type of '{spelled}' defaults to 'int'"),
992                                span,
993                            )
994                            .with_code("E0526"),
995                        );
996                    }
997                    self.int()
998                }
999            };
1000            let object = adjust_parameter(&mut self.types, ty);
1001            declared.push(self.declare_object(name, object, span));
1002        }
1003        self.scopes.pop();
1004        if let Some(first) = params.iter().next() {
1005            self.built.params.insert(first, declared);
1006        }
1007    }
1008
1009    /// The same function type again, taking these parameters.
1010    ///
1011    /// Still unprototyped, because an identifier list is not a prototype and a call through one
1012    /// is not checked against anything, 6.7.6.3p14. What the parameters are there for is the
1013    /// comparison against a prototype in 6.7.6.3p15 and the definition's own lowering, which has
1014    /// to know what its parameters are to have anywhere to put them.
1015    pub(in crate::check) fn function_taking(&mut self, ty: TypeId, params: Vec<TypeId>) -> TypeId {
1016        let canonical = self.types.canonical(ty);
1017        let rucc_types::TypeKind::Function(id) = self.types.kind(canonical) else {
1018            // The declarator did not end in a parameter list after all, which the parser has
1019            // already said something about.
1020            return ty;
1021        };
1022        let signature = FunctionType { params, ..self.types.signature(id).clone() };
1023        self.types.function(signature)
1024    }
1025
1026    /// The names of an identifier list, in order and with the repeats taken out.
1027    fn parameter_names(&mut self, params: ast::ParamList) -> Vec<(Symbol, Span)> {
1028        let ast = self.ast;
1029        let mut names: Vec<(Symbol, Span)> = Vec::with_capacity(params.len());
1030        for param in &ast[params] {
1031            let declarator = ast[param.declarator];
1032            // The parser only puts a named declarator in an identifier list, since a list of
1033            // anything else is a prototype.
1034            let Some(name) = declarator.name else { continue };
1035            if names.iter().any(|&(seen, _)| seen == name) {
1036                let spelled = self.text(name).to_owned();
1037                self.report(
1038                    Diagnostic::error(
1039                        format!("multiple parameters named '{spelled}'"),
1040                        declarator.name_span,
1041                    )
1042                    .with_code("E0545"),
1043                );
1044                continue;
1045            }
1046            names.push((name, declarator.name_span));
1047        }
1048        names
1049    }
1050
1051    /// One of the declarations under an identifier list, giving types to the names it mentions.
1052    ///
1053    /// A declaration that names no declarator is kept rather than refused, because
1054    /// `int f(a) struct s { int x; } a; {}` declares the tag there and the body can use it.
1055    fn old_style_declaration(
1056        &mut self,
1057        id: ast::DeclId,
1058        names: &[(Symbol, Span)],
1059        written: &mut [Option<TypeId>],
1060    ) {
1061        let ast::Decl::Var { specs, declarators } = self.ast[id] else {
1062            // A `static_assert`, an `asm` or a stray `;`, none of which declares a parameter.
1063            // Checked so that whatever is in it is still looked at, and then let alone.
1064            self.check_decl(id);
1065            return;
1066        };
1067        if self.ast[declarators].is_empty() {
1068            self.declared_specs(specs);
1069            return;
1070        }
1071        for index in 0..declarators.len() {
1072            let item = self.ast[declarators][index];
1073            let ty = self.build_type(
1074                specs,
1075                item.declarator,
1076                Place { parameter: true, member: false, prototype: false },
1077            );
1078            let declarator = self.ast[item.declarator];
1079            let span = if declarator.name.is_some() { declarator.name_span } else { item.span };
1080            let Some(name) = declarator.name else {
1081                self.report(
1082                    Diagnostic::error("declaration for a parameter with no name".to_string(), span)
1083                        .with_code("E0682"),
1084                );
1085                continue;
1086            };
1087            let spelled = self.text(name).to_owned();
1088            // `register` is the one storage class a parameter may be declared with, 6.9.1p6,
1089            // and it says nothing this compiler acts on.
1090            if !matches!(self.ast[specs].storage, None | Some(ast::StorageClass::Register)) {
1091                self.report(
1092                    Diagnostic::error(
1093                        format!("storage class specified for parameter '{spelled}'"),
1094                        span,
1095                    )
1096                    .with_code("E0682"),
1097                );
1098            }
1099            if item.init.is_some() {
1100                self.report(
1101                    Diagnostic::error(format!("parameter '{spelled}' is initialized"), span)
1102                        .with_code("E0682"),
1103                );
1104            }
1105            let Some(at) = names.iter().position(|&(seen, _)| seen == name) else {
1106                self.report(
1107                    Diagnostic::error(
1108                        format!("declaration for parameter '{spelled}' but no such parameter"),
1109                        span,
1110                    )
1111                    .with_code("E0682"),
1112                );
1113                continue;
1114            };
1115            if written[at].is_some() {
1116                self.report(
1117                    Diagnostic::error(format!("redefinition of parameter '{spelled}'"), span)
1118                        .with_code("E0545"),
1119                );
1120                continue;
1121            }
1122            written[at] = Some(ty);
1123        }
1124    }
1125
1126    /// The default argument promotions applied to a type, 6.5.2.2p6.
1127    ///
1128    /// The integer promotions and `float` widened to `double`. This is the type version of what
1129    /// [`Checker::default_promote`](crate::check::Checker) does to an argument, and it is here
1130    /// because an old-style definition has to say what its parameters are before there is any
1131    /// call to promote the arguments of.
1132    pub(in crate::check) fn default_promoted(&mut self, ty: TypeId) -> TypeId {
1133        let promoted = rucc_types::promote(&mut self.types, ty, self.cx.target);
1134        let canonical = self.types.canonical(promoted);
1135        if self.types.kind(canonical) == rucc_types::TypeKind::Float(FloatKind::Float) {
1136            return self.types.float(FloatKind::Double);
1137        }
1138        promoted
1139    }
1140
1141    /// The parameters a prototype declared, for the definition that binds them again.
1142    ///
1143    /// Empty for a list this has not seen, which is every list that is not a prototype.
1144    pub(in crate::check) fn prototype_params(&self, params: ast::ParamList) -> Vec<DeclId> {
1145        params
1146            .iter()
1147            .next()
1148            .and_then(|first| self.built.params.get(&first))
1149            .cloned()
1150            .unwrap_or_default()
1151    }
1152
1153    /// A parameter declared `void`, which is one thing when it stands alone and two mistakes
1154    /// otherwise.
1155    fn check_void_parameter(&mut self, ty: TypeId, name: Option<Symbol>, index: usize, span: Span) {
1156        if !is_void(&self.types, self.types.canonical(ty)) {
1157            return;
1158        }
1159        let position = index + 1;
1160        match name {
1161            Some(name) => {
1162                let spelled = self.text(name).to_owned();
1163                self.report(
1164                    Diagnostic::warning(
1165                        format!("parameter {position} ('{spelled}') has void type"),
1166                        span,
1167                    )
1168                    .with_code("E0544"),
1169                );
1170            }
1171            // `(void)` on its own is a parameter list and not a parameter, and the parser
1172            // already told the two apart, so an unnamed one here has something beside it.
1173            None => {
1174                self.report(
1175                    Diagnostic::error("'void' must be the only parameter".to_string(), span)
1176                        .with_code("E0543"),
1177                );
1178            }
1179        }
1180    }
1181
1182    /// `declaration of 'a'`, or the abstract declarator's version of the same phrase.
1183    fn declaration_of(&self, subject: Subject) -> String {
1184        match subject.name {
1185            Some(name) => format!("declaration of '{}'", self.text(name)),
1186            None => "declaration of type name".to_string(),
1187        }
1188    }
1189
1190    /// `'f' declared`, or the abstract declarator's version.
1191    fn declared_as(&self, subject: Subject) -> String {
1192        match subject.name {
1193            Some(name) => format!("'{}' declared", self.text(name)),
1194            None => "type name declared".to_string(),
1195        }
1196    }
1197
1198    /// `array 'a'`, or the abstract declarator's version.
1199    fn array_named(&self, subject: Subject) -> String {
1200        match subject.name {
1201            Some(name) => format!("array '{}'", self.text(name)),
1202            None => "unnamed array".to_string(),
1203        }
1204    }
1205
1206    /// Reports something the type builder does not do yet.
1207    fn unsupported_type(&mut self, what: &str, span: Span) {
1208        self.report(
1209            Diagnostic::error(format!("{what} is not supported yet"), span).with_code("E0519"),
1210        );
1211    }
1212
1213    /// A type the target does not have, which is not the same thing as one not written yet.
1214    fn unavailable_type(&mut self, name: &str, span: Span) {
1215        self.report(
1216            Diagnostic::error(format!("'{name}' is not supported on this target"), span)
1217                .with_code("E0589"),
1218        );
1219    }
1220}
1221
1222/// The integer type a built-in names, if it names one.
1223fn int_kind(scalar: Scalar) -> Option<IntKind> {
1224    // `bool` is missing on purpose. It is an integer type in C and its own kind here, since it
1225    // is the one integer type where the conversion is not a truncation.
1226    let kind = match scalar {
1227        Scalar::Char => IntKind::Char,
1228        Scalar::SignedChar => IntKind::SChar,
1229        Scalar::UnsignedChar => IntKind::UChar,
1230        Scalar::Short => IntKind::Short,
1231        Scalar::UnsignedShort => IntKind::UShort,
1232        Scalar::Int => IntKind::Int,
1233        Scalar::UnsignedInt => IntKind::UInt,
1234        Scalar::Long => IntKind::Long,
1235        Scalar::UnsignedLong => IntKind::ULong,
1236        Scalar::LongLong => IntKind::LongLong,
1237        Scalar::UnsignedLongLong => IntKind::ULongLong,
1238        Scalar::Int128 => IntKind::Int128,
1239        Scalar::UnsignedInt128 => IntKind::UInt128,
1240        _ => return None,
1241    };
1242    Some(kind)
1243}
1244
1245/// The floating type a built-in names, if the target has it.
1246///
1247/// The two that depend on the target are the ones spelled for a format rather than for a rank.
1248/// `__float80` is gcc's name for the x87 type and exists only where that type does, and there
1249/// it is the same type as `long double` rather than a second one beside it, which is what gcc
1250/// makes it and what `_Generic` can be used to see. `_Float128x` is a type no target gcc
1251/// supports has at all, which is why it is missing here rather than mapped to something.
1252fn float_kind(scalar: Scalar, target: &TargetInfo) -> Option<FloatKind> {
1253    match scalar {
1254        Scalar::Float => Some(FloatKind::Float),
1255        Scalar::Double => Some(FloatKind::Double),
1256        Scalar::LongDouble => Some(FloatKind::LongDouble),
1257        Scalar::Float16 => Some(FloatKind::Float16),
1258        Scalar::Float32 => Some(FloatKind::Float32),
1259        Scalar::Float64 => Some(FloatKind::Float64),
1260        Scalar::Float128 => Some(FloatKind::Float128),
1261        Scalar::Float32x => Some(FloatKind::Float32x),
1262        Scalar::Float64x => Some(FloatKind::Float64x),
1263        Scalar::Float80 if target.long_double_format == Format::X87Extended => {
1264            Some(FloatKind::LongDouble)
1265        }
1266        _ => None,
1267    }
1268}
1269
1270/// How a built-in type is spelled, for the ones that have no type to be given.
1271fn spell_scalar(scalar: Scalar) -> &'static str {
1272    match scalar {
1273        Scalar::Void => "void",
1274        Scalar::Bool => "bool",
1275        Scalar::Char => "char",
1276        Scalar::SignedChar => "signed char",
1277        Scalar::UnsignedChar => "unsigned char",
1278        Scalar::Short => "short",
1279        Scalar::UnsignedShort => "unsigned short",
1280        Scalar::Int => "int",
1281        Scalar::UnsignedInt => "unsigned int",
1282        Scalar::Long => "long",
1283        Scalar::UnsignedLong => "unsigned long",
1284        Scalar::LongLong => "long long",
1285        Scalar::UnsignedLongLong => "unsigned long long",
1286        Scalar::Int128 => "__int128",
1287        Scalar::UnsignedInt128 => "unsigned __int128",
1288        // Without the width, which is an expression rather than a number until it is checked
1289        // and which no message this spells out has room for.
1290        Scalar::BitInt { unsigned: false, .. } => "_BitInt",
1291        Scalar::BitInt { unsigned: true, .. } => "unsigned _BitInt",
1292        Scalar::Float => "float",
1293        Scalar::Double => "double",
1294        Scalar::LongDouble => "long double",
1295        Scalar::Float16 => "_Float16",
1296        Scalar::Float32 => "_Float32",
1297        Scalar::Float64 => "_Float64",
1298        Scalar::Float128 => "_Float128",
1299        Scalar::Float32x => "_Float32x",
1300        Scalar::Float64x => "_Float64x",
1301        Scalar::Float128x => "_Float128x",
1302        Scalar::Float80 => "__float80",
1303        Scalar::Decimal32 => "_Decimal32",
1304        Scalar::Decimal64 => "_Decimal64",
1305        Scalar::Decimal128 => "_Decimal128",
1306    }
1307}
1308
1309/// The fixture the child module's tests use as well, which is why several of the helpers
1310/// below are visible outside this module.
1311#[cfg(test)]
1312mod tests {
1313    use rucc_ast::{Builtin, BuiltinSet, DeclSpecs, DeclSpecsId, Declarator, DeclaratorId, Quals};
1314    use rucc_base::Interner;
1315    use rucc_lex::{IntConstant, IntConstantType, Remarks};
1316    use rucc_target::{TargetInfo, Triple};
1317    use rucc_types::{TypeKind, spell};
1318
1319    use super::*;
1320    use crate::check::Context;
1321
1322    /// The untyped tree a test checks, built by hand.
1323    ///
1324    /// The same shape as the expression tests next door and for the same reason: the checker
1325    /// borrows the interner for as long as it lives, so everything a test needs to name is
1326    /// named before the checker exists.
1327    pub(super) struct Fixture {
1328        pub(super) ast: rucc_ast::Ast,
1329        names: Interner,
1330        target: TargetInfo,
1331    }
1332
1333    impl Fixture {
1334        pub(super) fn new() -> Fixture {
1335            Fixture::for_target("x86_64-unknown-linux-gnu")
1336        }
1337
1338        /// The same, for a test whose answer is a property of the target.
1339        pub(super) fn for_target(triple: &str) -> Fixture {
1340            let target = TargetInfo::new(triple.parse::<Triple>().expect("a triple"));
1341            Fixture { ast: rucc_ast::Ast::new(), names: Interner::new(), target }
1342        }
1343
1344        pub(super) fn name(&mut self, text: &str) -> Symbol {
1345            self.names.intern(text)
1346        }
1347
1348        /// A specifier list naming a built-in type, as the keywords that were written.
1349        pub(super) fn keywords(&mut self, written: &[BuiltinSet]) -> DeclSpecsId {
1350            let mut builtin = Builtin::NONE;
1351            for &keyword in written {
1352                builtin = builtin.add(keyword).expect("a keyword written once");
1353            }
1354            self.specs(TypeSpec::Builtin(builtin), Quals::NONE)
1355        }
1356
1357        /// `int`, which is what most of these declarations are made of.
1358        pub(super) fn int_specs(&mut self) -> DeclSpecsId {
1359            self.keywords(&[BuiltinSet::INT])
1360        }
1361
1362        pub(super) fn specs(&mut self, ty: TypeSpec, quals: Quals) -> DeclSpecsId {
1363            let mut specs = DeclSpecs::empty(Span::DUMMY);
1364            specs.ty = ty;
1365            specs.quals = quals;
1366            self.ast.add_specs(specs)
1367        }
1368
1369        pub(super) fn declarator(
1370            &mut self,
1371            name: Option<&str>,
1372            derived: &[Derived],
1373        ) -> DeclaratorId {
1374            let name = name.map(|text| self.name(text));
1375            let derived = self.ast.add_derived_list(derived);
1376            self.ast.add_declarator(Declarator {
1377                name,
1378                name_span: Span::DUMMY,
1379                derived,
1380                span: Span::DUMMY,
1381            })
1382        }
1383
1384        /// A type name, which is a specifier list and an abstract declarator.
1385        pub(super) fn type_name(
1386            &mut self,
1387            specs: DeclSpecsId,
1388            derived: &[Derived],
1389        ) -> ast::TypeNameId {
1390            let declarator = self.declarator(None, derived);
1391            self.ast.add_type_name(ast::TypeName { specs, declarator, span: Span::DUMMY })
1392        }
1393
1394        /// An integer constant, for the array bounds and the `_BitInt` widths.
1395        pub(super) fn int(&mut self, value: u128) -> ast::ExprId {
1396            let ty = IntConstantType::Standard(IntKind::Int);
1397            let id = self.ast.add_int(IntConstant { value, ty, remarks: Remarks::default() });
1398            self.ast.expr(ast::Expr::Int(id), Span::DUMMY)
1399        }
1400
1401        fn use_name(&mut self, text: &str) -> ast::ExprId {
1402            let name = self.name(text);
1403            self.ast.expr(ast::Expr::Name(name), Span::DUMMY)
1404        }
1405
1406        pub(super) fn checker(&self) -> Checker<'_> {
1407            Checker::new(&self.ast, Context::new(&self.names, &self.target, Std::C23))
1408        }
1409    }
1410
1411    /// A fixed array bound, which is the common case and three lines every time.
1412    fn fixed(fixture: &mut Fixture, count: u128) -> Derived {
1413        let size = fixture.int(count);
1414        Derived::Array { size: ArraySize::Expr(size), quals: Quals::NONE, has_static: false }
1415    }
1416
1417    /// A pointer with no qualifiers on it.
1418    fn pointer() -> Derived {
1419        Derived::Pointer { quals: Quals::NONE, attrs: rucc_ast::AttrList::EMPTY }
1420    }
1421
1422    /// `_BitInt(width)`, with `unsigned` written next to it or not.
1423    fn bit_int(width: ast::ExprId, unsigned: bool) -> TypeSpec {
1424        let mut builtin = Builtin::NONE.add_bit_int(width).expect("`_BitInt` rejected");
1425        if unsigned {
1426            builtin = builtin.add(BuiltinSet::UNSIGNED).expect("`unsigned` rejected");
1427        }
1428        TypeSpec::Builtin(builtin)
1429    }
1430
1431    /// How a built type is written, which is what almost every assertion here is about.
1432    pub(super) fn spelled(checker: &Checker<'_>, ty: TypeId) -> String {
1433        spell(&checker.types, checker.cx.names, ty)
1434    }
1435
1436    /// The type a declaration declares, as it would be written.
1437    fn built(checker: &mut Checker<'_>, specs: DeclSpecsId, declarator: DeclaratorId) -> String {
1438        let ty = checker.declared_type(specs, declarator);
1439        spelled(checker, ty)
1440    }
1441
1442    /// What was reported, as the messages alone.
1443    pub(super) fn messages(checker: &Checker<'_>) -> Vec<String> {
1444        checker.errors.diagnostics().iter().map(|d| d.message.clone()).collect()
1445    }
1446
1447    /// The one message that was reported, which is what most of these tests expect.
1448    pub(super) fn message(checker: &Checker<'_>) -> String {
1449        let mut reported = messages(checker);
1450        assert_eq!(reported.len(), 1, "expected exactly one diagnostic, got {reported:?}");
1451        reported.pop().expect("one message")
1452    }
1453
1454    #[test]
1455    fn the_keywords_of_a_specifier_list_name_one_type_between_them() {
1456        let mut fixture = Fixture::new();
1457        let long = fixture.keywords(&[BuiltinSet::UNSIGNED, BuiltinSet::LONG, BuiltinSet::INT]);
1458        let double = fixture.keywords(&[BuiltinSet::LONG, BuiltinSet::DOUBLE]);
1459        let void = fixture.keywords(&[BuiltinSet::VOID]);
1460        let plain = fixture.declarator(Some("x"), &[]);
1461
1462        let mut checker = fixture.checker();
1463        assert_eq!(built(&mut checker, long, plain), "unsigned long");
1464        assert_eq!(built(&mut checker, double, plain), "long double");
1465        assert_eq!(built(&mut checker, void, plain), "void");
1466        assert!(messages(&checker).is_empty());
1467    }
1468
1469    #[test]
1470    fn each_spelling_of_a_floating_type_names_a_type_of_its_own() {
1471        let mut fixture = Fixture::new();
1472        let written = [
1473            (BuiltinSet::FLOAT16, "_Float16"),
1474            (BuiltinSet::FLOAT32, "_Float32"),
1475            (BuiltinSet::FLOAT64, "_Float64"),
1476            (BuiltinSet::FLOAT128, "_Float128"),
1477            (BuiltinSet::FLOAT32X, "_Float32x"),
1478            (BuiltinSet::FLOAT64X, "_Float64x"),
1479        ];
1480        let specs: Vec<_> =
1481            written.iter().map(|&(keyword, _)| fixture.keywords(&[keyword])).collect();
1482        // `__float80` is gcc's name for the x87 type on the target that has one, and there it
1483        // is the same type as `long double` rather than a second type beside it.
1484        let float80 = fixture.keywords(&[BuiltinSet::FLOAT80]);
1485        let plain = fixture.declarator(Some("x"), &[]);
1486
1487        let mut checker = fixture.checker();
1488        for (specs, expected) in specs.into_iter().zip(written.iter().map(|&(_, name)| name)) {
1489            assert_eq!(built(&mut checker, specs, plain), expected);
1490        }
1491        assert_eq!(built(&mut checker, float80, plain), "long double");
1492        assert!(messages(&checker).is_empty());
1493    }
1494
1495    #[test]
1496    fn a_floating_type_the_target_does_not_have_is_refused_rather_than_given_another_one() {
1497        // `_Float128x` is a type no target gcc supports has at all, and `__float80` is one that
1498        // only x86 has. gcc turns both of them away in the same words, and the wording is worth
1499        // keeping apart from the one for a type this compiler has not written yet: nothing here
1500        // is coming later, the machine does not have the type.
1501        let mut fixture = Fixture::for_target("aarch64-apple-darwin");
1502        let float128x = fixture.keywords(&[BuiltinSet::FLOAT128X]);
1503        let float80 = fixture.keywords(&[BuiltinSet::FLOAT80]);
1504        let plain = fixture.declarator(Some("x"), &[]);
1505
1506        let mut checker = fixture.checker();
1507        // A `double`, so that the declaration is still a declaration and the uses of the name
1508        // that follow are one error rather than one each.
1509        assert_eq!(built(&mut checker, float128x, plain), "double");
1510        assert_eq!(built(&mut checker, float80, plain), "double");
1511        assert_eq!(
1512            messages(&checker),
1513            [
1514                "'_Float128x' is not supported on this target",
1515                "'__float80' is not supported on this target",
1516            ]
1517        );
1518    }
1519
1520    #[test]
1521    fn a_decimal_floating_type_is_recognised_and_says_it_is_not_written_yet() {
1522        // Deferred past 1.0 by `spec/19-open-questions.md`. The keyword is in the table and the
1523        // parser takes it, so the message has to be the one that says so rather than the one
1524        // for a keyword nobody has heard of.
1525        let mut fixture = Fixture::new();
1526        let specs = fixture.keywords(&[BuiltinSet::DECIMAL64]);
1527        let plain = fixture.declarator(Some("x"), &[]);
1528
1529        let mut checker = fixture.checker();
1530        assert_eq!(built(&mut checker, specs, plain), "double");
1531        assert_eq!(message(&checker), "the type `_Decimal64` is not supported yet");
1532    }
1533
1534    #[test]
1535    fn keywords_that_name_no_type_between_them_are_one_message_and_not_one_per_keyword() {
1536        let mut fixture = Fixture::new();
1537        // `short double`, which gcc reports once at the specifier list rather than at the
1538        // keyword, because the keyword that was wrong depends on which one was meant.
1539        let specs = fixture.keywords(&[BuiltinSet::SHORT, BuiltinSet::DOUBLE]);
1540        let plain = fixture.declarator(Some("x"), &[]);
1541
1542        let mut checker = fixture.checker();
1543        let ty = checker.declared_type(specs, plain);
1544        assert_eq!(spelled(&checker, ty), "int");
1545        assert_eq!(message(&checker), "two or more data types in declaration specifiers");
1546    }
1547
1548    #[test]
1549    fn a_declaration_with_no_type_at_all_is_an_int_and_a_warning_that_says_whose() {
1550        let mut fixture = Fixture::new();
1551        // Two declarations rather than two declarators of one, since the specifiers of one
1552        // declaration are read once however many names it declares.
1553        let specs = fixture.specs(TypeSpec::None, Quals::CONST);
1554        let again = fixture.specs(TypeSpec::None, Quals::NONE);
1555        let named = fixture.declarator(Some("x"), &[]);
1556        let abstracted = fixture.declarator(None, &[]);
1557
1558        let mut checker = fixture.checker();
1559        let ty = checker.declared_type(specs, named);
1560        assert_eq!(spelled(&checker, ty), "const int");
1561        checker.declared_type(again, abstracted);
1562        assert_eq!(
1563            messages(&checker),
1564            ["type defaults to 'int' in declaration of 'x'", "type defaults to 'int'"]
1565        );
1566    }
1567
1568    #[test]
1569    fn a_declarator_is_folded_from_the_far_end_so_the_step_nearest_the_name_wins() {
1570        let mut fixture = Fixture::new();
1571        let specs = fixture.int_specs();
1572        let char_specs = fixture.keywords(&[BuiltinSet::CHAR]);
1573        let parameter = fixture.declarator(None, &[]);
1574        let params = fixture.ast.add_param_list(&[ast::Param {
1575            specs: Some(char_specs),
1576            declarator: parameter,
1577            attrs: rucc_ast::AttrList::EMPTY,
1578            span: Span::DUMMY,
1579        }]);
1580        // `int (*f[3])(char)`: an array of three pointers to functions, which is the order the
1581        // derivations are written in and the reverse of the order they are applied.
1582        let three = fixed(&mut fixture, 3);
1583        let call = Derived::Function { params, variadic: false, kind: ParamKind::Prototype };
1584        let f = fixture.declarator(Some("f"), &[three, pointer(), call]);
1585
1586        let mut checker = fixture.checker();
1587        let ty = checker.declared_type(specs, f);
1588        assert_eq!(spelled(&checker, ty), "int (*[3])(char)");
1589        assert!(messages(&checker).is_empty());
1590    }
1591
1592    #[test]
1593    fn the_qualifiers_of_a_pointer_are_the_pointers_and_not_the_pointees() {
1594        let mut fixture = Fixture::new();
1595        let konst = fixture.specs(
1596            TypeSpec::Builtin(Builtin::NONE.add(BuiltinSet::INT).expect("int")),
1597            Quals::CONST,
1598        );
1599        let plain = fixture.int_specs();
1600        // `const int *p`, which is a pointer to a constant.
1601        let to_const = fixture.declarator(Some("p"), &[pointer()]);
1602        // `int *const p`, which is a constant pointer.
1603        let const_pointer = fixture.declarator(
1604            Some("p"),
1605            &[Derived::Pointer { quals: Quals::CONST, attrs: rucc_ast::AttrList::EMPTY }],
1606        );
1607
1608        let mut checker = fixture.checker();
1609        assert_eq!(built(&mut checker, konst, to_const), "const int *");
1610        assert_eq!(built(&mut checker, plain, const_pointer), "int *const");
1611        assert!(messages(&checker).is_empty());
1612    }
1613
1614    #[test]
1615    fn restrict_is_only_for_a_pointer_and_says_so_where_it_is_not() {
1616        let mut fixture = Fixture::new();
1617        let specs = fixture.specs(TypeSpec::None, Quals::RESTRICT);
1618        let plain = fixture.declarator(Some("x"), &[]);
1619        let restricted =
1620            Derived::Pointer { quals: Quals::RESTRICT, attrs: rucc_ast::AttrList::EMPTY };
1621        let int_specs = fixture.int_specs();
1622        let p = fixture.declarator(Some("p"), &[restricted]);
1623
1624        let mut checker = fixture.checker();
1625        assert_eq!(built(&mut checker, int_specs, p), "int *restrict");
1626        checker.declared_type(specs, plain);
1627        assert!(
1628            messages(&checker).contains(&"invalid use of 'restrict'".to_string()),
1629            "got {:?}",
1630            messages(&checker)
1631        );
1632    }
1633
1634    #[test]
1635    fn an_array_of_something_there_can_be_no_array_of_says_which_it_was() {
1636        let mut fixture = Fixture::new();
1637        let void = fixture.keywords(&[BuiltinSet::VOID]);
1638        let int = fixture.int_specs();
1639        let three = fixed(&mut fixture, 3);
1640        let params = fixture.ast.add_param_list(&[]);
1641        let call = Derived::Function { params, variadic: false, kind: ParamKind::Void };
1642
1643        let voids = fixture.declarator(Some("a"), &[three]);
1644        let functions = fixture.declarator(Some("a"), &[three, call]);
1645        let anonymous = fixture.declarator(None, &[three]);
1646
1647        let mut checker = fixture.checker();
1648        checker.declared_type(void, voids);
1649        checker.declared_type(int, functions);
1650        checker.declared_type(void, anonymous);
1651        assert_eq!(
1652            messages(&checker),
1653            [
1654                "declaration of 'a' as array of voids",
1655                "declaration of 'a' as array of functions",
1656                "declaration of type name as array of voids",
1657            ]
1658        );
1659    }
1660
1661    #[test]
1662    fn an_array_of_a_tag_that_has_no_definition_yet_names_the_type_it_cannot_size() {
1663        let mut fixture = Fixture::new();
1664        let tag = fixture.name("S");
1665        let specs = fixture.specs(
1666            TypeSpec::Record {
1667                kind: ast::RecordKind::Struct,
1668                tag: Some(tag),
1669                fields: None,
1670                attrs: rucc_ast::AttrList::EMPTY,
1671                pack: None,
1672            },
1673            Quals::NONE,
1674        );
1675        let three = fixed(&mut fixture, 3);
1676        let array = fixture.declarator(Some("a"), &[three]);
1677        let star = fixture.declarator(Some("p"), &[pointer()]);
1678
1679        let mut checker = fixture.checker();
1680        // A pointer to an incomplete type is perfectly ordinary, and both mentions of the tag
1681        // are the same type, which is what makes the pointer usable once the definition lands.
1682        let pointer_ty = checker.declared_type(specs, star);
1683        assert_eq!(spelled(&checker, pointer_ty), "struct S *");
1684        checker.declared_type(specs, array);
1685        assert_eq!(message(&checker), "array type has incomplete element type 'struct S'");
1686    }
1687
1688    #[test]
1689    fn an_array_bound_is_folded_and_a_negative_one_is_refused() {
1690        let mut fixture = Fixture::new();
1691        let specs = fixture.int_specs();
1692        let zero = fixed(&mut fixture, 0);
1693        let four = fixed(&mut fixture, 4);
1694        let negative = {
1695            let one = fixture.int(1);
1696            let size = fixture
1697                .ast
1698                .expr(ast::Expr::Unary { op: rucc_ast::UnaryOp::Minus, operand: one }, Span::DUMMY);
1699            Derived::Array { size: ArraySize::Expr(size), quals: Quals::NONE, has_static: false }
1700        };
1701        let sized = fixture.declarator(Some("a"), &[four]);
1702        // `int a[0]`, which gcc accepts in silence as an extension and which a great deal of
1703        // real code uses as a flexible array member before C99 gave it a spelling.
1704        let empty = fixture.declarator(Some("a"), &[zero]);
1705        let unspecified = fixture.declarator(
1706            Some("a"),
1707            &[Derived::Array {
1708                size: ArraySize::Unspecified,
1709                quals: Quals::NONE,
1710                has_static: false,
1711            }],
1712        );
1713        let backwards = fixture.declarator(Some("a"), &[negative]);
1714
1715        let mut checker = fixture.checker();
1716        assert_eq!(built(&mut checker, specs, sized), "int[4]");
1717        assert_eq!(built(&mut checker, specs, empty), "int[0]");
1718        assert_eq!(built(&mut checker, specs, unspecified), "int[]");
1719        assert!(messages(&checker).is_empty());
1720
1721        checker.declared_type(specs, backwards);
1722        assert_eq!(message(&checker), "size of array 'a' is negative");
1723    }
1724
1725    #[test]
1726    fn an_array_too_large_to_be_an_object_is_measured_in_its_elements() {
1727        let mut fixture = Fixture::new();
1728        let specs = fixture.int_specs();
1729        // Four times this is one element past the largest object, and the count on its own is
1730        // not, which is what makes the check about the element type and not about the bound.
1731        let count = u128::from(fixture.target.max_object_size() / 4 + 1);
1732        let huge = fixed(&mut fixture, count);
1733        let a = fixture.declarator(Some("a"), &[huge]);
1734
1735        let mut checker = fixture.checker();
1736        checker.declared_type(specs, a);
1737        assert_eq!(
1738            message(&checker),
1739            "size of array 'a' exceeds maximum object size '9223372036854775807'"
1740        );
1741    }
1742
1743    #[test]
1744    fn a_bound_that_is_not_a_constant_is_a_variable_length_array_where_there_is_a_run_time() {
1745        let mut fixture = Fixture::new();
1746        let specs = fixture.int_specs();
1747        let n = fixture.use_name("n");
1748        let variable =
1749            Derived::Array { size: ArraySize::Expr(n), quals: Quals::NONE, has_static: false };
1750        let a = fixture.declarator(Some("a"), &[variable]);
1751        let name = fixture.name("n");
1752
1753        let mut checker = fixture.checker();
1754        let int = checker.int();
1755        checker.declare_object(name, int, Span::DUMMY);
1756        // At file scope there is nothing to evaluate the bound in, which is the error gcc
1757        // gives, and the type is not built rather than built wrong.
1758        checker.declared_type(specs, a);
1759        assert_eq!(message(&checker), "variably modified 'a' at file scope");
1760
1761        checker.scopes.push();
1762        let ty = checker.declared_type(specs, a);
1763        assert_eq!(spelled(&checker, ty), "int[*]");
1764        // Two arrays written the same way are still two types, because the two bounds are
1765        // evaluated at two different moments and may not agree.
1766        let again = checker.declared_type(specs, a);
1767        assert_ne!(ty, again);
1768        assert_eq!(
1769            checker.tast.vla_size(vla_id(&checker, ty)),
1770            checker.tast.vla_size(vla_id(&checker, ty))
1771        );
1772    }
1773
1774    /// The identity of the variable length array a type is, which the assertions above want.
1775    fn vla_id(checker: &Checker<'_>, ty: TypeId) -> rucc_types::VlaId {
1776        match checker.types.kind(checker.types.canonical(ty)) {
1777            TypeKind::Array { len: ArrayLen::Variable(id), .. } => id,
1778            other => panic!("expected a variable length array, got {other:?}"),
1779        }
1780    }
1781
1782    #[test]
1783    fn a_star_bound_is_only_a_type_inside_a_prototype() {
1784        let mut fixture = Fixture::new();
1785        let specs = fixture.int_specs();
1786        let star = Derived::Array { size: ArraySize::Star, quals: Quals::NONE, has_static: false };
1787        let parameter = fixture.declarator(Some("a"), &[star]);
1788        let params = fixture.ast.add_param_list(&[ast::Param {
1789            specs: Some(specs),
1790            declarator: parameter,
1791            attrs: rucc_ast::AttrList::EMPTY,
1792            span: Span::DUMMY,
1793        }]);
1794        let call = Derived::Function { params, variadic: false, kind: ParamKind::Prototype };
1795        let f = fixture.declarator(Some("f"), &[call]);
1796
1797        let mut checker = fixture.checker();
1798        // Inside the prototype it is a type, and the parameter it is on is adjusted to a
1799        // pointer the same way any other array parameter is.
1800        let ty = checker.declared_type(specs, f);
1801        assert_eq!(spelled(&checker, ty), "int(int *)");
1802        assert!(messages(&checker).is_empty());
1803
1804        checker.declared_type(specs, parameter);
1805        assert_eq!(message(&checker), "'[*]' not allowed in other than function prototype scope");
1806    }
1807
1808    #[test]
1809    fn a_deduced_type_on_a_parameter_names_nothing_and_says_where_it_was_written() {
1810        let mut fixture = Fixture::new();
1811        // A parameter has no initializer to deduce from, so there is nothing here for either
1812        // spelling to mean and the parameter is an `int` so that the rest is still checked.
1813        let specs = fixture.int_specs();
1814        let deduced = fixture.specs(TypeSpec::Auto(ast::Deduction::Auto), Quals::NONE);
1815        let parameter = fixture.declarator(Some("p"), &[]);
1816        let params = fixture.ast.add_param_list(&[ast::Param {
1817            specs: Some(deduced),
1818            declarator: parameter,
1819            attrs: rucc_ast::AttrList::EMPTY,
1820            span: Span::DUMMY,
1821        }]);
1822        let call = Derived::Function { params, variadic: false, kind: ParamKind::Prototype };
1823        let f = fixture.declarator(Some("f"), &[call]);
1824
1825        let mut checker = fixture.checker();
1826        let ty = checker.declared_type(specs, f);
1827        assert_eq!(spelled(&checker, ty), "int(int)");
1828        assert_eq!(message(&checker), "'auto' not allowed in function prototype");
1829    }
1830
1831    #[test]
1832    fn the_qualifiers_inside_a_parameters_brackets_are_the_object_s_and_not_the_type_s() {
1833        let mut fixture = Fixture::new();
1834        let specs = fixture.int_specs();
1835        let three = fixture.int(3);
1836        let qualified =
1837            Derived::Array { size: ArraySize::Expr(three), quals: Quals::CONST, has_static: true };
1838        let parameter = fixture.declarator(Some("a"), &[qualified]);
1839        let params = fixture.ast.add_param_list(&[ast::Param {
1840            specs: Some(specs),
1841            declarator: parameter,
1842            attrs: rucc_ast::AttrList::EMPTY,
1843            span: Span::DUMMY,
1844        }]);
1845        let call = Derived::Function { params, variadic: false, kind: ParamKind::Prototype };
1846        let f = fixture.declarator(Some("f"), &[call]);
1847
1848        let mut checker = fixture.checker();
1849        // `void f(int a[static const 3])`. The object `a` is an `int *const` and the function
1850        // takes an `int *`, because a qualifier on a parameter is dropped from the type: gcc
1851        // matches this declaration against `void f(int *)` and answers a `_Generic` the same
1852        // way. What the qualifier does reach is the body, where `a = 0` is an assignment to a
1853        // read-only object, and the declaration the body binds is checked in `decl.rs`.
1854        let ty = checker.declared_type(specs, f);
1855        assert_eq!(spelled(&checker, ty), "int(int *)");
1856        assert!(messages(&checker).is_empty());
1857
1858        // The same brackets on something that is not a parameter mean nothing at all.
1859        checker.declared_type(specs, parameter);
1860        assert_eq!(
1861            message(&checker),
1862            "static or type qualifiers in non-parameter array declarator"
1863        );
1864    }
1865
1866    #[test]
1867    fn a_function_cannot_return_a_function_or_an_array_and_the_message_names_which() {
1868        let mut fixture = Fixture::new();
1869        let specs = fixture.int_specs();
1870        let params = fixture.ast.add_param_list(&[]);
1871        let call = Derived::Function { params, variadic: false, kind: ParamKind::Void };
1872        let three = fixed(&mut fixture, 3);
1873
1874        let returns_function = fixture.declarator(Some("f"), &[call, call]);
1875        let returns_array = fixture.declarator(Some("f"), &[call, three]);
1876        let anonymous = fixture.declarator(None, &[call, three]);
1877
1878        let mut checker = fixture.checker();
1879        checker.declared_type(specs, returns_function);
1880        checker.declared_type(specs, returns_array);
1881        checker.declared_type(specs, anonymous);
1882        assert_eq!(
1883            messages(&checker),
1884            [
1885                "'f' declared as function returning a function",
1886                "'f' declared as function returning an array",
1887                "type name declared as function returning an array",
1888            ]
1889        );
1890    }
1891
1892    #[test]
1893    fn an_empty_parameter_list_says_nothing_before_c23_and_says_none_from_it() {
1894        let mut fixture = Fixture::new();
1895        let specs = fixture.int_specs();
1896        let params = fixture.ast.add_param_list(&[]);
1897        let empty = Derived::Function { params, variadic: false, kind: ParamKind::Empty };
1898        let f = fixture.declarator(Some("f"), &[empty]);
1899
1900        let mut checker = fixture.checker();
1901        assert_eq!(built(&mut checker, specs, f), "int(void)");
1902
1903        let mut old = fixture.checker();
1904        old.cx.std = Std::C17;
1905        assert_eq!(built(&mut old, specs, f), "int()");
1906        assert!(messages(&old).is_empty());
1907    }
1908
1909    #[test]
1910    fn a_parameter_of_type_void_is_only_a_parameter_list_when_it_is_the_whole_of_one() {
1911        let mut fixture = Fixture::new();
1912        let int = fixture.int_specs();
1913        let void = fixture.keywords(&[BuiltinSet::VOID]);
1914        let named = fixture.declarator(Some("v"), &[]);
1915        let unnamed = fixture.declarator(None, &[]);
1916        let param = |declarator| ast::Param {
1917            specs: Some(void),
1918            declarator,
1919            attrs: rucc_ast::AttrList::EMPTY,
1920            span: Span::DUMMY,
1921        };
1922        let params = fixture.ast.add_param_list(&[param(named), param(unnamed)]);
1923        let call = Derived::Function { params, variadic: false, kind: ParamKind::Prototype };
1924        let f = fixture.declarator(Some("f"), &[call]);
1925
1926        let mut checker = fixture.checker();
1927        checker.declared_type(int, f);
1928        assert_eq!(
1929            messages(&checker),
1930            ["parameter 1 ('v') has void type", "'void' must be the only parameter"]
1931        );
1932    }
1933
1934    #[test]
1935    fn a_parameter_is_in_scope_for_the_parameters_after_it_and_gone_after_the_prototype() {
1936        let mut fixture = Fixture::new();
1937        let specs = fixture.int_specs();
1938        let n = fixture.declarator(Some("n"), &[]);
1939        let bound = fixture.use_name("n");
1940        let a = fixture.declarator(
1941            Some("a"),
1942            &[Derived::Array {
1943                size: ArraySize::Expr(bound),
1944                quals: Quals::NONE,
1945                has_static: false,
1946            }],
1947        );
1948        let param = |declarator| ast::Param {
1949            specs: Some(specs),
1950            declarator,
1951            attrs: rucc_ast::AttrList::EMPTY,
1952            span: Span::DUMMY,
1953        };
1954        let params = fixture.ast.add_param_list(&[param(n), param(a)]);
1955        let call = Derived::Function { params, variadic: false, kind: ParamKind::Prototype };
1956        let f = fixture.declarator(Some("f"), &[call]);
1957        let name = fixture.name("n");
1958
1959        let mut checker = fixture.checker();
1960        // A prototype is a scope of its own, so the `n` in the bound is the parameter and the
1961        // whole thing is a prototype rather than a use of an undeclared name.
1962        let ty = checker.declared_type(specs, f);
1963        assert_eq!(spelled(&checker, ty), "int(int, int *)");
1964        assert!(messages(&checker).is_empty());
1965        assert!(checker.scopes.lookup(name).is_none());
1966    }
1967
1968    #[test]
1969    fn a_parameter_declared_twice_in_one_prototype_is_reported_once() {
1970        let mut fixture = Fixture::new();
1971        let specs = fixture.int_specs();
1972        let a = fixture.declarator(Some("a"), &[]);
1973        let param = ast::Param {
1974            specs: Some(specs),
1975            declarator: a,
1976            attrs: rucc_ast::AttrList::EMPTY,
1977            span: Span::DUMMY,
1978        };
1979        let params = fixture.ast.add_param_list(&[param, param]);
1980        let call = Derived::Function { params, variadic: false, kind: ParamKind::Prototype };
1981        let f = fixture.declarator(Some("f"), &[call]);
1982
1983        let mut checker = fixture.checker();
1984        checker.declared_type(specs, f);
1985        assert_eq!(message(&checker), "redefinition of parameter 'a'");
1986    }
1987
1988    #[test]
1989    fn a_tag_names_the_same_type_every_time_and_one_kind_of_thing_only() {
1990        let mut fixture = Fixture::new();
1991        let tag = fixture.name("S");
1992        let record = |kind| TypeSpec::Record {
1993            kind,
1994            tag: Some(tag),
1995            fields: None,
1996            attrs: rucc_ast::AttrList::EMPTY,
1997            pack: None,
1998        };
1999        let structure = fixture.specs(record(ast::RecordKind::Struct), Quals::NONE);
2000        let onion = fixture.specs(record(ast::RecordKind::Union), Quals::NONE);
2001        let plain = fixture.declarator(None, &[]);
2002
2003        let mut checker = fixture.checker();
2004        let first = checker.declared_type(structure, plain);
2005        let second = checker.declared_type(structure, plain);
2006        assert_eq!(first, second);
2007        assert!(messages(&checker).is_empty());
2008
2009        let wrong = checker.declared_type(onion, plain);
2010        assert_eq!(message(&checker), "'S' defined as wrong kind of tag");
2011        // The tag keeps meaning what it did, so the declarations after this one are checked
2012        // against the definition that is there rather than against a second one.
2013        assert_ne!(wrong, first);
2014        assert_eq!(checker.declared_type(structure, plain), first);
2015    }
2016
2017    #[test]
2018    fn an_anonymous_tag_is_a_new_type_every_time_it_is_written() {
2019        let mut fixture = Fixture::new();
2020        let anonymous = |fixture: &mut Fixture| {
2021            fixture.specs(
2022                TypeSpec::Record {
2023                    kind: ast::RecordKind::Struct,
2024                    tag: None,
2025                    fields: None,
2026                    attrs: rucc_ast::AttrList::EMPTY,
2027                    pack: None,
2028                },
2029                Quals::NONE,
2030            )
2031        };
2032        let specs = anonymous(&mut fixture);
2033        let written_again = anonymous(&mut fixture);
2034        let plain = fixture.declarator(None, &[]);
2035
2036        let mut checker = fixture.checker();
2037        let first = checker.declared_type(specs, plain);
2038        let second = checker.declared_type(written_again, plain);
2039        assert_ne!(first, second);
2040        // And one that was written once is one type however many names it declares, which is
2041        // what makes `struct { int x; } a, b;` two objects of the same type.
2042        assert_eq!(checker.declared_type(specs, plain), first);
2043    }
2044
2045    #[test]
2046    fn an_enumeration_with_the_underlying_type_written_is_complete_from_there() {
2047        let mut fixture = Fixture::new();
2048        let long = fixture.keywords(&[BuiltinSet::LONG]);
2049        let long_name = fixture.type_name(long, &[]);
2050        let tag = fixture.name("E");
2051        let fixed_enum = fixture.specs(
2052            TypeSpec::Enum {
2053                tag: Some(tag),
2054                enumerators: None,
2055                underlying: Some(long_name),
2056                attrs: rucc_ast::AttrList::EMPTY,
2057            },
2058            Quals::NONE,
2059        );
2060        let plain = fixture.declarator(None, &[]);
2061
2062        let mut checker = fixture.checker();
2063        let ty = checker.declared_type(fixed_enum, plain);
2064        assert_eq!(spelled(&checker, ty), "enum E");
2065        assert!(is_complete(&checker.types, ty));
2066        assert!(messages(&checker).is_empty());
2067    }
2068
2069    #[test]
2070    fn an_enumeration_cannot_be_kept_in_something_that_is_not_an_integer_type() {
2071        let mut fixture = Fixture::new();
2072        let double = fixture.keywords(&[BuiltinSet::DOUBLE]);
2073        let double_name = fixture.type_name(double, &[]);
2074        let specs = fixture.specs(
2075            TypeSpec::Enum {
2076                tag: None,
2077                enumerators: None,
2078                underlying: Some(double_name),
2079                attrs: rucc_ast::AttrList::EMPTY,
2080            },
2081            Quals::NONE,
2082        );
2083        let plain = fixture.declarator(None, &[]);
2084
2085        let mut checker = fixture.checker();
2086        checker.declared_type(specs, plain);
2087        assert_eq!(message(&checker), "invalid 'enum' underlying type");
2088    }
2089
2090    #[test]
2091    fn atomic_is_a_type_and_not_a_qualifier_and_two_things_cannot_be_one() {
2092        let mut fixture = Fixture::new();
2093        let int = fixture.int_specs();
2094        let konst = fixture.specs(
2095            TypeSpec::Builtin(Builtin::NONE.add(BuiltinSet::INT).expect("int")),
2096            Quals::CONST,
2097        );
2098        let plain_name = fixture.type_name(int, &[]);
2099        let three = fixed(&mut fixture, 3);
2100        let array_name = fixture.type_name(int, &[three]);
2101        let params = fixture.ast.add_param_list(&[]);
2102        let call = Derived::Function { params, variadic: false, kind: ParamKind::Void };
2103        let function_name = fixture.type_name(int, &[call]);
2104        let const_name = fixture.type_name(konst, &[]);
2105
2106        let atomic = |fixture: &mut Fixture, name| {
2107            let specs = fixture.specs(TypeSpec::Atomic(name), Quals::NONE);
2108            let declarator = fixture.declarator(None, &[]);
2109            (specs, declarator)
2110        };
2111        let (plain, hole) = atomic(&mut fixture, plain_name);
2112        let (array, _) = atomic(&mut fixture, array_name);
2113        let (function, _) = atomic(&mut fixture, function_name);
2114        let (qualified, _) = atomic(&mut fixture, const_name);
2115
2116        let mut checker = fixture.checker();
2117        assert_eq!(built(&mut checker, plain, hole), "_Atomic(int)");
2118        assert!(messages(&checker).is_empty());
2119
2120        checker.declared_type(array, hole);
2121        checker.declared_type(function, hole);
2122        checker.declared_type(qualified, hole);
2123        assert_eq!(
2124            messages(&checker),
2125            [
2126                "'_Atomic'-qualified array type",
2127                "'_Atomic'-qualified function type",
2128                "'_Atomic' applied to a qualified type",
2129            ]
2130        );
2131    }
2132
2133    #[test]
2134    fn a_bit_int_is_as_wide_as_it_says_within_the_range_there_is() {
2135        let mut fixture = Fixture::new();
2136        let widths = [37, 1, 200, 0];
2137        let specs: Vec<_> = widths
2138            .iter()
2139            .map(|&width| {
2140                let expr = fixture.int(width);
2141                fixture.specs(bit_int(expr, false), Quals::NONE)
2142            })
2143            .collect();
2144        let plain = fixture.declarator(None, &[]);
2145
2146        let mut checker = fixture.checker();
2147        assert_eq!(built(&mut checker, specs[0], plain), "_BitInt(37)");
2148        assert!(messages(&checker).is_empty());
2149
2150        checker.declared_type(specs[1], plain);
2151        checker.declared_type(specs[2], plain);
2152        checker.declared_type(specs[3], plain);
2153        assert_eq!(
2154            messages(&checker),
2155            [
2156                "'signed _BitInt' argument must be at least 2",
2157                "'_BitInt' argument '200' is larger than 'BITINT_MAXWIDTH' '128'",
2158                "'_BitInt' argument '0' is not a positive integer constant expression",
2159            ]
2160        );
2161    }
2162
2163    #[test]
2164    fn an_unsigned_bit_int_holds_one_bit_where_a_signed_one_cannot() {
2165        let mut fixture = Fixture::new();
2166        let one = fixture.int(1);
2167        let unsigned = fixture.specs(bit_int(one, true), Quals::NONE);
2168        let eight = fixture.int(8);
2169        let wide = fixture.specs(bit_int(eight, true), Quals::NONE);
2170        let plain = fixture.declarator(None, &[]);
2171
2172        let mut checker = fixture.checker();
2173        assert_eq!(built(&mut checker, unsigned, plain), "unsigned _BitInt(1)");
2174        assert_eq!(built(&mut checker, wide, plain), "unsigned _BitInt(8)");
2175        assert!(messages(&checker).is_empty());
2176    }
2177
2178    #[test]
2179    fn a_bit_int_next_to_anything_but_a_sign_names_no_type() {
2180        let mut fixture = Fixture::new();
2181        let width = fixture.int(8);
2182        let mut both = Builtin::NONE.add(BuiltinSet::LONG).expect("`long` rejected");
2183        both = both.add_bit_int(width).expect("`_BitInt` rejected");
2184        let specs = fixture.specs(TypeSpec::Builtin(both), Quals::NONE);
2185        let plain = fixture.declarator(None, &[]);
2186
2187        let mut checker = fixture.checker();
2188        checker.declared_type(specs, plain);
2189        assert_eq!(messages(&checker), ["two or more data types in declaration specifiers"]);
2190    }
2191
2192    #[test]
2193    fn a_typedef_name_is_the_type_it_was_declared_for_and_keeps_its_own_spelling() {
2194        let mut fixture = Fixture::new();
2195        let word = fixture.name("word");
2196        let specs = fixture.specs(TypeSpec::Typedef(word), Quals::CONST);
2197        let p = fixture.declarator(Some("p"), &[pointer()]);
2198
2199        let mut checker = fixture.checker();
2200        let long = checker.types.int(IntKind::Long);
2201        let alias = checker.types.typedef(word, long);
2202        checker.declare_typedef(word, alias);
2203
2204        let ty = checker.declared_type(specs, p);
2205        assert_eq!(spelled(&checker, ty), "const word *");
2206        assert!(messages(&checker).is_empty());
2207    }
2208
2209    #[test]
2210    fn typeof_takes_the_type_of_an_expression_it_does_not_evaluate() {
2211        let mut fixture = Fixture::new();
2212        let x = fixture.use_name("x");
2213        let plain = fixture
2214            .specs(TypeSpec::Typeof { unqual: false, operand: TypeofArg::Expr(x) }, Quals::NONE);
2215        let bare = fixture
2216            .specs(TypeSpec::Typeof { unqual: true, operand: TypeofArg::Expr(x) }, Quals::NONE);
2217        let hole = fixture.declarator(None, &[]);
2218        let name = fixture.name("x");
2219
2220        let mut checker = fixture.checker();
2221        let int = checker.int();
2222        let konst = checker.types.qualified(int, Qualifiers::CONST);
2223        checker.declare_object(name, konst, Span::DUMMY);
2224
2225        assert_eq!(built(&mut checker, plain, hole), "const int");
2226        // `typeof_unqual` is the one that takes them off, which is what makes it worth having.
2227        assert_eq!(built(&mut checker, bare, hole), "int");
2228        assert!(messages(&checker).is_empty());
2229    }
2230}