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