Skip to main content

oak_c/ast/
declaration_nodes.rs

1use super::*;
2
3/// Represents a canonical C type.
4#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5#[derive(Debug, Clone, PartialEq)]
6pub enum Type {
7    /// A primitive type (int, char, etc.) or a struct/union/enum.
8    Base(TypeSpecifier),
9    /// A pointer type.
10    Pointer(Box<Type>),
11    /// An array type.
12    Array {
13        /// The type of elements in the array.
14        element_type: Box<Type>,
15        /// The size of the array, if specified.
16        size: Option<Box<Expression>>,
17    },
18    /// A function type.
19    Function {
20        /// The return type of the function.
21        return_type: Box<Type>,
22        /// The types of the parameters.
23        parameters: Vec<Type>,
24        /// Whether the function is variadic.
25        variadic: bool,
26    },
27}
28
29/// External declaration.
30#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
31#[derive(Debug, Clone, PartialEq)]
32pub enum ExternalDeclaration {
33    /// Function definition.
34    FunctionDefinition(FunctionDefinition),
35    /// Declaration.
36    Declaration(Declaration),
37}
38
39impl ExternalDeclaration {
40    /// Returns the source span of the external declaration.
41    pub fn span(&self) -> core::range::Range<usize> {
42        match self {
43            Self::FunctionDefinition(n) => n.span.clone(),
44            Self::Declaration(n) => n.span.clone(),
45        }
46    }
47}
48
49/// Function definition.
50#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
51#[derive(Debug, Clone, PartialEq)]
52pub struct FunctionDefinition {
53    /// Declaration specifiers (e.g., return type, storage class).
54    pub declaration_specifiers: Vec<DeclarationSpecifier>,
55    /// The declarator for the function.
56    pub declarator: Declarator,
57    /// The body of the function.
58    pub compound_statement: CompoundStatement,
59    /// The source span of the function definition.
60    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
61    pub span: core::range::Range<usize>,
62}
63
64/// Declaration.
65#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
66#[derive(Debug, Clone, PartialEq)]
67pub struct Declaration {
68    /// Declaration specifiers.
69    pub declaration_specifiers: Vec<DeclarationSpecifier>,
70    /// List of declarators being initialized.
71    pub init_declarators: Vec<InitDeclarator>,
72    /// The source span of the declaration.
73    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
74    pub span: core::range::Range<usize>,
75}
76
77/// Declaration specifier.
78#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
79#[derive(Debug, Clone, PartialEq)]
80pub enum DeclarationSpecifier {
81    /// Storage class specifier (e.g., `static`, `extern`).
82    StorageClassSpecifier(StorageClassSpecifier),
83    /// Type specifier (e.g., `int`, `char`).
84    TypeSpecifier(TypeSpecifier),
85    /// Type qualifier (e.g., `const`, `volatile`).
86    TypeQualifier(TypeQualifier),
87    /// Function specifier (e.g., `inline`).
88    FunctionSpecifier(FunctionSpecifier),
89}
90
91impl DeclarationSpecifier {
92    /// Returns the source span of the declaration specifier.
93    pub fn span(&self) -> core::range::Range<usize> {
94        match self {
95            Self::StorageClassSpecifier(n) => n.span(),
96            Self::TypeSpecifier(n) => n.span(),
97            Self::TypeQualifier(n) => n.span(),
98            Self::FunctionSpecifier(n) => n.span(),
99        }
100    }
101}
102
103/// Storage class specifier.
104#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
105#[derive(Debug, Clone, PartialEq)]
106pub enum StorageClassSpecifier {
107    /// `typedef`
108    Typedef {
109        /// Source span.
110        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
111        span: core::range::Range<usize>,
112    },
113    /// `extern`
114    Extern {
115        /// Source span.
116        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
117        span: core::range::Range<usize>,
118    },
119    /// `static`
120    Static {
121        /// Source span.
122        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
123        span: core::range::Range<usize>,
124    },
125    /// `auto`
126    Auto {
127        /// Source span.
128        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
129        span: core::range::Range<usize>,
130    },
131    /// `register`
132    Register {
133        /// Source span.
134        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
135        span: core::range::Range<usize>,
136    },
137}
138
139impl StorageClassSpecifier {
140    /// Returns the source span of the storage class specifier.
141    pub fn span(&self) -> core::range::Range<usize> {
142        match self {
143            Self::Typedef { span } => span.clone(),
144            Self::Extern { span } => span.clone(),
145            Self::Static { span } => span.clone(),
146            Self::Auto { span } => span.clone(),
147            Self::Register { span } => span.clone(),
148        }
149    }
150}
151
152/// Type specifier.
153#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
154#[derive(Debug, Clone, PartialEq)]
155pub enum TypeSpecifier {
156    /// `void`
157    Void {
158        /// Source span.
159        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
160        span: core::range::Range<usize>,
161    },
162    /// `char`
163    Char {
164        /// Source span.
165        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
166        span: core::range::Range<usize>,
167    },
168    /// `short`
169    Short {
170        /// Source span.
171        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
172        span: core::range::Range<usize>,
173    },
174    /// `int`
175    Int {
176        /// Source span.
177        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
178        span: core::range::Range<usize>,
179    },
180    /// `long`
181    Long {
182        /// Source span.
183        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
184        span: core::range::Range<usize>,
185    },
186    /// `float`
187    Float {
188        /// Source span.
189        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
190        span: core::range::Range<usize>,
191    },
192    /// `double`
193    Double {
194        /// Source span.
195        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
196        span: core::range::Range<usize>,
197    },
198    /// `signed`
199    Signed {
200        /// Source span.
201        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
202        span: core::range::Range<usize>,
203    },
204    /// `unsigned`
205    Unsigned {
206        /// Source span.
207        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
208        span: core::range::Range<usize>,
209    },
210    /// `_Bool`
211    Bool {
212        /// Source span.
213        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
214        span: core::range::Range<usize>,
215    },
216    /// `_Complex`
217    Complex {
218        /// Source span.
219        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
220        span: core::range::Range<usize>,
221    },
222    /// `_Imaginary`
223    Imaginary {
224        /// Source span.
225        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
226        span: core::range::Range<usize>,
227    },
228    /// A struct or union specifier.
229    StructOrUnion(StructOrUnionSpecifier),
230    /// An enum specifier.
231    Enum(EnumSpecifier),
232    /// A typedef name.
233    TypedefName(String, #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))] core::range::Range<usize>),
234}
235
236impl TypeSpecifier {
237    /// Returns the source span of the type specifier.
238    pub fn span(&self) -> core::range::Range<usize> {
239        match self {
240            Self::Void { span } => span.clone(),
241            Self::Char { span } => span.clone(),
242            Self::Short { span } => span.clone(),
243            Self::Int { span } => span.clone(),
244            Self::Long { span } => span.clone(),
245            Self::Float { span } => span.clone(),
246            Self::Double { span } => span.clone(),
247            Self::Signed { span } => span.clone(),
248            Self::Unsigned { span } => span.clone(),
249            Self::Bool { span } => span.clone(),
250            Self::Complex { span } => span.clone(),
251            Self::Imaginary { span } => span.clone(),
252            Self::StructOrUnion(n) => n.span.clone(),
253            Self::Enum(n) => n.span.clone(),
254            Self::TypedefName(_, span) => span.clone(),
255        }
256    }
257}
258
259/// Type qualifier.
260#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
261#[derive(Debug, Clone, PartialEq)]
262pub enum TypeQualifier {
263    /// `const`
264    Const {
265        /// Source span.
266        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
267        span: core::range::Range<usize>,
268    },
269    /// `restrict`
270    Restrict {
271        /// Source span.
272        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
273        span: core::range::Range<usize>,
274    },
275    /// `volatile`
276    Volatile {
277        /// Source span.
278        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
279        span: core::range::Range<usize>,
280    },
281}
282
283impl TypeQualifier {
284    /// Returns the source span of the type qualifier.
285    pub fn span(&self) -> core::range::Range<usize> {
286        match self {
287            Self::Const { span } => span.clone(),
288            Self::Restrict { span } => span.clone(),
289            Self::Volatile { span } => span.clone(),
290        }
291    }
292}
293
294/// Function specifier.
295#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
296#[derive(Debug, Clone, PartialEq)]
297pub enum FunctionSpecifier {
298    /// `inline`
299    Inline {
300        /// Source span.
301        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
302        span: core::range::Range<usize>,
303    },
304}
305
306impl FunctionSpecifier {
307    /// Returns the source span of the function specifier.
308    pub fn span(&self) -> core::range::Range<usize> {
309        match self {
310            Self::Inline { span } => span.clone(),
311        }
312    }
313}
314
315/// Struct or union specifier.
316#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
317#[derive(Debug, Clone, PartialEq)]
318pub struct StructOrUnionSpecifier {
319    /// Whether it's a struct or union.
320    pub kind: StructOrUnion,
321    /// Optional tag identifier.
322    pub identifier: Option<String>,
323    /// List of struct declarations.
324    pub struct_declarations: Vec<StructDeclaration>,
325    /// Source span.
326    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
327    pub span: core::range::Range<usize>,
328}
329
330/// Struct or union keyword.
331#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
332#[derive(Debug, Clone, PartialEq)]
333pub enum StructOrUnion {
334    /// `struct`
335    Struct {
336        /// Source span.
337        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
338        span: core::range::Range<usize>,
339    },
340    /// `union`
341    Union {
342        /// Source span.
343        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
344        span: core::range::Range<usize>,
345    },
346}
347
348impl StructOrUnion {
349    /// Returns the source span of the struct or union keyword.
350    pub fn span(&self) -> core::range::Range<usize> {
351        match self {
352            Self::Struct { span } => span.clone(),
353            Self::Union { span } => span.clone(),
354        }
355    }
356}
357
358/// Struct declaration.
359#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
360#[derive(Debug, Clone, PartialEq)]
361pub struct StructDeclaration {
362    /// List of specifiers and qualifiers.
363    pub specifier_qualifier_list: Vec<SpecifierQualifier>,
364    /// List of struct declarators.
365    pub struct_declarator_list: Vec<StructDeclarator>,
366    /// Source span.
367    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
368    pub span: core::range::Range<usize>,
369}
370
371/// Specifier or qualifier.
372#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
373#[derive(Debug, Clone, PartialEq)]
374pub enum SpecifierQualifier {
375    /// Type specifier.
376    TypeSpecifier(TypeSpecifier),
377    /// Type qualifier.
378    TypeQualifier(TypeQualifier),
379}
380
381impl SpecifierQualifier {
382    /// Returns the source span of the specifier or qualifier.
383    pub fn span(&self) -> core::range::Range<usize> {
384        match self {
385            Self::TypeSpecifier(n) => n.span(),
386            Self::TypeQualifier(n) => n.span(),
387        }
388    }
389}
390
391/// Struct declarator.
392#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
393#[derive(Debug, Clone, PartialEq)]
394pub struct StructDeclarator {
395    /// The declarator.
396    pub declarator: Option<Declarator>,
397    /// Optional bit-field width expression.
398    pub constant_expression: Option<Expression>,
399    /// Source span.
400    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
401    pub span: core::range::Range<usize>,
402}
403
404/// Enum specifier.
405#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
406#[derive(Debug, Clone, PartialEq)]
407pub struct EnumSpecifier {
408    /// Optional tag identifier.
409    pub identifier: Option<String>,
410    /// List of enumerators.
411    pub enumerators: Vec<Enumerator>,
412    /// Source span.
413    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
414    pub span: core::range::Range<usize>,
415}
416
417/// Enumerator.
418#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
419#[derive(Debug, Clone, PartialEq)]
420pub struct Enumerator {
421    /// Enumerator identifier.
422    pub identifier: String,
423    /// Optional constant expression value.
424    pub constant_expression: Option<Expression>,
425    /// Source span.
426    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
427    pub span: core::range::Range<usize>,
428}
429
430/// Init declarator.
431#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
432#[derive(Debug, Clone, PartialEq)]
433pub struct InitDeclarator {
434    /// The declarator.
435    pub declarator: Declarator,
436    /// Optional initializer.
437    pub initializer: Option<Initializer>,
438    /// Source span.
439    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
440    pub span: core::range::Range<usize>,
441}
442
443/// Declarator.
444#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
445#[derive(Debug, Clone, PartialEq)]
446pub struct Declarator {
447    /// Optional pointer prefix.
448    pub pointer: Option<Pointer>,
449    /// Direct declarator.
450    pub direct_declarator: DirectDeclarator,
451    /// Source span.
452    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
453    pub span: core::range::Range<usize>,
454}
455
456/// Pointer.
457#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
458#[derive(Debug, Clone, PartialEq)]
459pub struct Pointer {
460    /// List of type qualifiers for this pointer level.
461    pub type_qualifiers: Vec<TypeQualifier>,
462    /// Optional nested pointer (for `**`, etc.).
463    pub pointer: Option<Box<Pointer>>,
464    /// Source span.
465    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
466    pub span: core::range::Range<usize>,
467}
468
469/// Direct declarator.
470#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
471#[derive(Debug, Clone, PartialEq)]
472pub enum DirectDeclarator {
473    /// Identifier.
474    Identifier(String, #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))] core::range::Range<usize>),
475    /// Parenthesized declarator.
476    Declarator(Box<Declarator>, #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))] core::range::Range<usize>),
477    /// Array declarator.
478    Array {
479        /// The declarator being declared as an array.
480        direct_declarator: Box<DirectDeclarator>,
481        /// Type qualifiers inside `[]`.
482        type_qualifiers: Vec<TypeQualifier>,
483        /// Optional assignment expression for size.
484        assignment_expression: Option<Box<Expression>>,
485        /// Source span.
486        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
487        span: core::range::Range<usize>,
488    },
489    /// Function declarator.
490    Function {
491        /// The declarator being declared as a function.
492        direct_declarator: Box<DirectDeclarator>,
493        /// Parameter list.
494        parameter_list: ParameterList,
495        /// Source span.
496        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
497        span: core::range::Range<usize>,
498    },
499}
500
501impl DirectDeclarator {
502    /// Returns the source span of the direct declarator.
503    pub fn span(&self) -> core::range::Range<usize> {
504        match self {
505            Self::Identifier(_, span) => span.clone(),
506            Self::Declarator(n, _) => n.span.clone(),
507            Self::Array { span, .. } => span.clone(),
508            Self::Function { span, .. } => span.clone(),
509        }
510    }
511}
512
513/// Parameter list.
514#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
515#[derive(Debug, Clone, PartialEq)]
516pub struct ParameterList {
517    /// List of parameter declarations.
518    pub parameter_declarations: Vec<ParameterDeclaration>,
519    /// Whether the function is variadic (ends with `...`).
520    pub variadic: bool,
521    /// Source span.
522    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
523    pub span: core::range::Range<usize>,
524}
525
526/// Parameter declaration.
527#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
528#[derive(Debug, Clone, PartialEq)]
529pub struct ParameterDeclaration {
530    /// Declaration specifiers.
531    pub declaration_specifiers: Vec<DeclarationSpecifier>,
532    /// Optional declarator.
533    pub declarator: Option<Declarator>,
534    /// Optional abstract declarator.
535    pub abstract_declarator: Option<AbstractDeclarator>,
536    /// Source span.
537    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
538    pub span: core::range::Range<usize>,
539}
540
541/// Abstract declarator.
542#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
543#[derive(Debug, Clone, PartialEq)]
544pub struct AbstractDeclarator {
545    /// Optional pointer prefix.
546    pub pointer: Option<Pointer>,
547    /// Direct abstract declarator.
548    pub direct_abstract_declarator: Option<Box<DirectAbstractDeclarator>>,
549    /// Source span.
550    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
551    pub span: core::range::Range<usize>,
552}
553
554/// Direct abstract declarator.
555#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
556#[derive(Debug, Clone, PartialEq)]
557pub enum DirectAbstractDeclarator {
558    /// Parenthesized abstract declarator.
559    AbstractDeclarator(Box<AbstractDeclarator>),
560    /// Array abstract declarator.
561    Array {
562        /// Optional direct abstract declarator.
563        declarator: Option<Box<DirectAbstractDeclarator>>,
564        /// Optional size expression.
565        assignment_expression: Option<Box<Expression>>,
566        /// Source span.
567        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
568        span: core::range::Range<usize>,
569    },
570    /// Function abstract declarator.
571    Function {
572        /// Optional direct abstract declarator.
573        declarator: Option<Box<DirectAbstractDeclarator>>,
574        /// Parameter list.
575        parameter_list: Option<ParameterList>,
576        /// Source span.
577        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
578        span: core::range::Range<usize>,
579    },
580}
581
582impl DirectAbstractDeclarator {
583    /// Returns the source span of the direct abstract declarator.
584    pub fn span(&self) -> core::range::Range<usize> {
585        match self {
586            Self::AbstractDeclarator(n) => n.span.clone(),
587            Self::Array { span, .. } => span.clone(),
588            Self::Function { span, .. } => span.clone(),
589        }
590    }
591}
592
593/// Initializer.
594#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
595#[derive(Debug, Clone, PartialEq)]
596pub enum Initializer {
597    /// Assignment expression.
598    AssignmentExpression(Expression),
599    /// Initializer list `{ ... }`.
600    InitializerList(Vec<Initializer>, #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))] core::range::Range<usize>),
601}
602
603impl Initializer {
604    /// Returns the source span of the initializer.
605    pub fn span(&self) -> core::range::Range<usize> {
606        match self {
607            Self::AssignmentExpression(n) => n.span.clone(),
608            Self::InitializerList(_, span) => span.clone(),
609        }
610    }
611}