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