lang_c/
ast.rs

1//! Abstract syntax tree
2//!
3//! Types in this module represent various pieces a C program can
4//! contain after preprocessing phase. They mostly follow C11 grammar
5//! naming conventions.
6//!
7//! References to C11 standard given in parenthesis refer to the
8//! [ISO/IEC 9899:201x
9//! draft](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf)
10//! published on April 12, 2011.
11//!
12//! A number of GNU extensions to the standard C are included here.
13//! Types, struct fields or enum variants specific to GNU are marked as
14//! "GNU extension" with a link to the relevant section of gcc
15//! documentation. Supported extensions are:
16//!
17//! - attributes in various positions
18//! - inline assembly statements and asm labels
19//! - extensions to the initializer list syntax
20//! - statement expressions
21//! - `typeof` type specifiers
22
23use span::Node;
24
25// From 6.4 Lexical elements
26
27/// Variable, function and other names that are not type names
28///
29/// (C11 6.4.2)
30#[derive(Debug, PartialEq, Eq, Hash, Clone)]
31pub struct Identifier {
32    pub name: String,
33}
34
35/// Constant literals
36///
37/// C11 places string literals under primary expressions, thus they
38/// are not included here.
39///
40/// (C11 6.4.4)
41#[derive(Debug, PartialEq, Eq, Hash, Clone)]
42pub enum Constant {
43    Integer(Integer),
44    Float(Float),
45    Character(String),
46}
47
48/// Integer number literal
49///
50/// (C11 6.4.4.1)
51#[derive(Debug, PartialEq, Eq, Hash, Clone)]
52pub struct Integer {
53    pub base: IntegerBase,
54    pub number: Box<str>,
55    pub suffix: IntegerSuffix,
56}
57
58/// Base of the integer literal
59///
60/// (C11 6.4.4.1)
61#[derive(Debug, PartialEq, Eq, Hash, Clone)]
62pub enum IntegerBase {
63    Decimal,
64    Octal,
65    Hexadecimal,
66    /// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html)
67    Binary,
68}
69
70/// Suffix of an integer literal
71///
72/// (C11 6.4.4.1)
73#[derive(Debug, PartialEq, Eq, Hash, Clone)]
74pub struct IntegerSuffix {
75    /// Minimum size of the integer literal
76    pub size: IntegerSize,
77    /// Integer literal has unsigned type
78    pub unsigned: bool,
79    /// Integer literal is an imaginary part of a complex number
80    ///
81    /// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Complex.html) suffixes `i` and `j`.
82    pub imaginary: bool,
83}
84
85/// Size part of a integer literal suffix
86///
87/// (C11 6.4.4.1)
88#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
89pub enum IntegerSize {
90    /// no `l` or `ll`
91    Int = 0,
92    /// `l`
93    Long,
94    /// `ll`
95    LongLong,
96}
97
98/// Floating point number literal
99///
100/// (C11 6.4.4.2)
101#[derive(Debug, PartialEq, Eq, Hash, Clone)]
102pub struct Float {
103    pub base: FloatBase,
104    pub number: Box<str>,
105    pub suffix: FloatSuffix,
106}
107
108/// Floating point number base
109///
110/// (C11 6.4.4.2)
111#[derive(Debug, PartialEq, Eq, Hash, Clone)]
112pub enum FloatBase {
113    Decimal,
114    Hexadecimal,
115}
116
117/// Floating point number suffix
118///
119/// (C11 6.4.4.2)
120#[derive(Debug, PartialEq, Eq, Hash, Clone)]
121pub struct FloatSuffix {
122    pub format: FloatFormat,
123    /// Integer literal is an imaginary part of a complex number
124    ///
125    /// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Complex.html) suffixes `i` and `j`.
126    pub imaginary: bool,
127}
128
129/// Floating point literal format specified by the suffix
130///
131/// (C11 6.4.4.2)
132#[derive(Debug, PartialEq, Eq, Hash, Clone)]
133pub enum FloatFormat {
134    /// `f` suffix
135    Float,
136    /// no suffix
137    Double,
138    /// `l` suffix
139    LongDouble,
140    /// [ISO/IEC TS 18661-2:2015](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1912.pdf)
141    /// `df`, `dd`, `dl` suffixes
142    ///
143    /// [ISO/IEC TS 18661-3:2015](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1945.pdf)
144    /// `fN`, `fNx`, `dN`, `dNx` suffixes
145    TS18661Format(TS18661FloatType),
146}
147
148/// String literal
149///
150/// (C11 6.4.5)
151pub type StringLiteral = Vec<String>;
152
153// From 6.5 Expressions
154
155/// Expressions
156///
157/// (C11 6.5)
158#[derive(Debug, PartialEq, Clone)]
159pub enum Expression {
160    /// Identifier
161    ///
162    /// May be a variable, function name or enumerator. The latter is
163    /// different from the standard, where enumerators are classified
164    /// as constants.
165    ///
166    /// (C11 6.5.1)
167    Identifier(Box<Node<Identifier>>),
168    /// Numeric and character constants
169    ///
170    /// Enumerator constants, being valid identifiers, are reprented
171    /// as `Identifier` in this enum.
172    ///
173    /// (C11 6.5.1)
174    Constant(Box<Node<Constant>>),
175
176    /// String literal
177    ///
178    /// (C11 6.5.1)
179    StringLiteral(Box<Node<StringLiteral>>),
180
181    /// Generic selection
182    ///
183    /// (C11 6.5.1.1)
184    GenericSelection(Box<Node<GenericSelection>>),
185
186    /// Structure and union members
187    ///
188    /// Both direct (`.`) and indirect (`->`) access.
189    ///
190    /// (C11 6.5.2)
191    Member(Box<Node<MemberExpression>>),
192
193    /// Function call expression
194    ///
195    /// (C11 6.5.2)
196    Call(Box<Node<CallExpression>>),
197
198    /// Compound literal
199    ///
200    /// (C11 6.5.2)
201    CompoundLiteral(Box<Node<CompoundLiteral>>),
202
203    /// Size of a type
204    ///
205    /// (C11 6.5.3)
206    SizeOfTy(Box<Node<SizeOfTy>>),
207
208    /// Size of a unary expression
209    ///
210    /// (C11 6.5.3)
211    SizeOfVal(Box<Node<SizeOfVal>>),
212
213    /// Alignment of a type
214    ///
215    /// (C11 6.5.3)
216    AlignOf(Box<Node<AlignOf>>),
217
218    /// Unary operators
219    ///
220    /// This represents both postfix and prefix unary oprators. Postfix expressions that take
221    /// additional operands are represented by a separate entry in this enum.
222    ///
223    /// (C11 6.5.2, c11 6.5.3)
224    UnaryOperator(Box<Node<UnaryOperatorExpression>>),
225
226    /// Cast expression
227    ///
228    /// `(type) expr`
229    ///
230    /// (C11 6.5.4)
231    Cast(Box<Node<CastExpression>>),
232
233    /// Binary operators
234    ///
235    /// All of C binary operators that can be applied to two expressions.
236    ///
237    /// (C11 6.5.5 -- 6.5.16)
238    BinaryOperator(Box<Node<BinaryOperatorExpression>>),
239
240    /// Conditional operator
241    ///
242    /// (C11 6.5.15)
243    Conditional(Box<Node<ConditionalExpression>>),
244
245    /// Comma operator
246    ///
247    /// (C11 6.5.17)
248    Comma(Box<Vec<Node<Expression>>>),
249
250    /// Member offset expression
251    ///
252    /// Result of expansion of `offsetof` macro.
253    ///
254    /// (C11 7.19 §3).
255    OffsetOf(Box<Node<OffsetOfExpression>>),
256
257    /// Variable argument list access
258    ///
259    /// Result of expansion of `va_arg` macro.
260    ///
261    /// (C11 7.16.1.1).
262    VaArg(Box<Node<VaArgExpression>>),
263
264    /// Statement expression
265    ///
266    /// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html)
267    Statement(Box<Node<Statement>>),
268}
269
270/// Struct or union member access
271#[derive(Debug, PartialEq, Eq, Hash, Clone)]
272pub enum MemberOperator {
273    /// `expression.identifier`
274    Direct,
275    /// `expression->identifier`
276    Indirect,
277}
278
279/// Generic selection expression
280///
281/// (C11 6.5.1.1)
282#[derive(Debug, PartialEq, Clone)]
283pub struct GenericSelection {
284    pub expression: Box<Node<Expression>>,
285    pub associations: Vec<Node<GenericAssociation>>,
286}
287
288/// Single element of a generic selection expression
289///
290/// (C11 6.5.1.1)
291#[derive(Debug, PartialEq, Clone)]
292pub enum GenericAssociation {
293    Type(Node<GenericAssociationType>),
294    Default(Box<Node<Expression>>),
295}
296
297/// Type match case in a generic selection expression
298///
299/// (C11 6.5.1.1)
300#[derive(Debug, PartialEq, Clone)]
301pub struct GenericAssociationType {
302    pub type_name: Node<TypeName>,
303    pub expression: Box<Node<Expression>>,
304}
305
306/// Structure and union members
307///
308/// Both direct (`.`) and indirect (`->`) access.
309///
310/// (C11 6.5.2)
311#[derive(Debug, PartialEq, Clone)]
312pub struct MemberExpression {
313    pub operator: Node<MemberOperator>,
314    pub expression: Box<Node<Expression>>,
315    pub identifier: Node<Identifier>,
316}
317
318/// Function call expression
319///
320/// (C11 6.5.2)
321#[derive(Debug, PartialEq, Clone)]
322pub struct CallExpression {
323    pub callee: Box<Node<Expression>>,
324    pub arguments: Vec<Node<Expression>>,
325}
326
327/// Compound literal
328///
329/// (C11 6.5.2)
330#[derive(Debug, PartialEq, Clone)]
331pub struct CompoundLiteral {
332    pub type_name: Node<TypeName>,
333    pub initializer_list: Vec<Node<InitializerListItem>>,
334}
335
336/// SizeOf a type
337///
338/// (C11 6.5.3)
339#[derive(Debug, PartialEq, Clone)]
340pub struct SizeOfTy(pub Node<TypeName>);
341
342/// Size of an unary expression
343///
344/// (C11 6.5.3)
345#[derive(Debug, PartialEq, Clone)]
346pub struct SizeOfVal(pub Box<Node<Expression>>);
347
348/// Alignment of a type
349///
350/// (C11 6.5.3)
351#[derive(Debug, PartialEq, Clone)]
352pub struct AlignOf(pub Box<Node<TypeName>>);
353
354/// All operators with one operand
355///
356/// (C11 6.5)
357#[derive(Debug, PartialEq, Eq, Hash, Clone)]
358pub enum UnaryOperator {
359    /// `operand++`
360    PostIncrement,
361    /// `operand--`
362    PostDecrement,
363    /// `++operand`
364    PreIncrement,
365    /// `--operand`
366    PreDecrement,
367    /// `&operand`
368    Address,
369    /// `*operand`
370    Indirection,
371    /// `+operand`
372    Plus,
373    /// `-operand`
374    Minus,
375    /// `~operand`
376    Complement,
377    /// `!operand`
378    Negate,
379}
380
381/// Unary operator expression
382///
383/// This represents both postfix and prefix unary oprators. Postfix expressions that take
384/// additional operands are represented by a separate entry in this enum.
385///
386/// (C11 6.5.2, c11 6.5.3)
387#[derive(Debug, PartialEq, Clone)]
388pub struct UnaryOperatorExpression {
389    pub operator: Node<UnaryOperator>,
390    pub operand: Box<Node<Expression>>,
391}
392
393/// Cast expression
394///
395/// `(type) expr`
396///
397/// (C11 6.5.4)
398#[derive(Debug, PartialEq, Clone)]
399pub struct CastExpression {
400    pub type_name: Node<TypeName>,
401    pub expression: Box<Node<Expression>>,
402}
403
404/// All operators with two operands
405///
406/// (C11 6.5)
407#[derive(Debug, PartialEq, Eq, Hash, Clone)]
408pub enum BinaryOperator {
409    /// `lhs[rhs]`
410    Index,
411    /// `lhs * rhs`
412    Multiply,
413    /// `lhs / rhs`
414    Divide,
415    /// `lhs % rhs`
416    Modulo,
417    /// `lhs + rhs`
418    Plus,
419    /// `lhs - rhs`
420    Minus,
421    /// `lhs << rhs`
422    ShiftLeft,
423    /// `lhs >> rhs`
424    ShiftRight,
425    /// `lhs < rhs`
426    Less,
427    /// `lhs > rhs`
428    Greater,
429    /// `lhs <= rhs`
430    LessOrEqual,
431    /// `lhs >= rhs`
432    GreaterOrEqual,
433    /// `lhs == rhs`
434    Equals,
435    /// `lhs != rhs`
436    NotEquals,
437    /// `lhs & rhs`
438    BitwiseAnd,
439    /// `lhs ^ rhs`
440    BitwiseXor,
441    /// `lhs | rhs`
442    BitwiseOr,
443    /// `lhs && rhs`
444    LogicalAnd,
445    /// `lhs || rhs`
446    LogicalOr,
447    /// `lhs = rhs`
448    Assign,
449    /// `lhs *= rhs`
450    AssignMultiply,
451    /// `lhs /= rhs`
452    AssignDivide,
453    /// `lhs %= rhs`
454    AssignModulo,
455    /// `lhs += rhs`
456    AssignPlus,
457    /// `lhs -= rhs`
458    AssignMinus,
459    /// `lhs <<= rhs`
460    AssignShiftLeft,
461    /// `lhs >>= rhs`
462    AssignShiftRight,
463    /// `lhs &= rhs`
464    AssignBitwiseAnd,
465    /// `lhs ^= rhs`
466    AssignBitwiseXor,
467    /// `lhs |= rhs`
468    AssignBitwiseOr,
469}
470
471/// Binary operators
472///
473/// All of C binary operators that can be applied to two expressions.
474///
475/// (C11 6.5.5 -- 6.5.16)
476#[derive(Debug, PartialEq, Clone)]
477pub struct BinaryOperatorExpression {
478    pub operator: Node<BinaryOperator>,
479    pub lhs: Box<Node<Expression>>,
480    pub rhs: Box<Node<Expression>>,
481}
482
483/// Conditional operator
484///
485/// (C11 6.5.15)
486#[derive(Debug, PartialEq, Clone)]
487pub struct ConditionalExpression {
488    pub condition: Box<Node<Expression>>,
489    pub then_expression: Box<Node<Expression>>,
490    pub else_expression: Box<Node<Expression>>,
491}
492
493/// Variable argument list access
494///
495/// Result of expansion of `va_arg` macro.
496///
497/// (C11 7.16.1.1).
498#[derive(Debug, PartialEq, Clone)]
499pub struct VaArgExpression {
500    pub va_list: Box<Node<Expression>>,
501    pub type_name: Node<TypeName>,
502}
503
504/// Member offset expression
505///
506/// Result of expansion of `offsetof` macro.
507///
508/// (C11 7.19 §3).
509#[derive(Debug, PartialEq, Clone)]
510pub struct OffsetOfExpression {
511    pub type_name: Node<TypeName>,
512    pub designator: Node<OffsetDesignator>,
513}
514
515/// Offset designator in a `offsetof` macro expansion
516///
517/// (C11 7.19 §3).
518#[derive(Debug, PartialEq, Clone)]
519pub struct OffsetDesignator {
520    pub base: Node<Identifier>,
521    pub members: Vec<Node<OffsetMember>>,
522}
523
524/// Single element of an offset designator
525///
526/// (C11 7.19 §3).
527#[derive(Debug, PartialEq, Clone)]
528pub enum OffsetMember {
529    Member(Node<Identifier>),
530    IndirectMember(Node<Identifier>),
531    Index(Node<Expression>),
532}
533
534// From 6.7 Declarations
535
536/// Variable, function or type declaration
537///
538/// (C11 6.7)
539#[derive(Debug, PartialEq, Clone)]
540pub struct Declaration {
541    pub specifiers: Vec<Node<DeclarationSpecifier>>,
542    pub declarators: Vec<Node<InitDeclarator>>,
543}
544
545/// Common part of a declaration
546///
547/// These apply to all declarators in a declaration.
548///
549/// (C11 6.7)
550#[derive(Debug, PartialEq, Clone)]
551pub enum DeclarationSpecifier {
552    StorageClass(Node<StorageClassSpecifier>),
553    TypeSpecifier(Node<TypeSpecifier>),
554    TypeQualifier(Node<TypeQualifier>),
555    Function(Node<FunctionSpecifier>),
556    Alignment(Node<AlignmentSpecifier>),
557    /// Vendor-specific declaration extensions that can be mixed with standard specifiers
558    Extension(Vec<Node<Extension>>),
559}
560
561/// Defines a single name in a declaration
562///
563/// (C11 6.7.6)
564#[derive(Debug, PartialEq, Clone)]
565pub struct InitDeclarator {
566    pub declarator: Node<Declarator>,
567    pub initializer: Option<Node<Initializer>>,
568}
569
570// From 6.7.1
571
572/// Storage class
573///
574/// (C11 6.7.1)
575#[derive(Debug, PartialEq, Eq, Hash, Clone)]
576pub enum StorageClassSpecifier {
577    /// `typedef`
578    Typedef,
579    /// `extern`
580    Extern,
581    /// `static`
582    Static,
583    /// `_Thread_local`
584    ThreadLocal,
585    /// `auto`
586    Auto,
587    /// `register`
588    Register,
589}
590
591// From 6.7.2
592
593/// Type specifier
594///
595/// (C11 6.7.2)
596#[derive(Debug, PartialEq, Clone)]
597pub enum TypeSpecifier {
598    /// `void`
599    Void,
600    /// `char`
601    Char,
602    /// `short`
603    Short,
604    /// `int`
605    Int,
606    /// `long`
607    Long,
608    /// `float`
609    Float,
610    /// `double`
611    Double,
612    /// `signed`
613    ///
614    /// `__signed`, `__signed__` (GNU extension)
615    Signed,
616    /// `unsigned`
617    Unsigned,
618    /// `_Bool`
619    Bool,
620    /// `_Complex`
621    ///
622    /// `__complex`, `__complex__` (GNU extension)
623    Complex,
624    /// `_Atomic(typename)`
625    Atomic(Node<TypeName>),
626    /// `struct identifier { … }`
627    ///
628    /// `union identifier { … }`
629    Struct(Node<StructType>),
630    /// `enum identifier { … }`
631    Enum(Node<EnumType>),
632    /// Name of a previously defined type
633    TypedefName(Node<Identifier>),
634    /// Specifies type of another type or expression
635    ///
636    /// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Typeof.html)
637    TypeOf(Node<TypeOf>),
638    /// Floating point types with guaranteed width and representation
639    ///
640    /// `_Float16`, `_Float32`, `_Float64`, `_Float128`
641    ///
642    /// `_Float16x`, `_Float32x`, `_Float64x`, `_Float128x`
643    ///
644    /// `_Decimal16`, `_Decimal32`, `_Decimal64`, `_Decimal128`
645    ///
646    /// `_Decimal16x`, `_Decimal32x`, `_Decimal64x`, `_Decimal128x`
647    ///
648    /// [ISO/IEC TS 18661-3:2015](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1945.pdf)
649    TS18661Float(TS18661FloatType),
650}
651
652/// Floating point type with guaranteed width and format
653///
654/// [ISO/IEC TS 18661-3:2015](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1945.pdf)
655#[derive(Debug, PartialEq, Eq, Hash, Clone)]
656pub struct TS18661FloatType {
657    pub format: TS18661FloatFormat,
658    pub width: usize,
659}
660
661/// Floating point formats
662///
663/// [ISO/IEC TS 18661-3:2015](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1945.pdf)
664#[derive(Debug, PartialEq, Eq, Hash, Clone)]
665pub enum TS18661FloatFormat {
666    BinaryInterchange,
667    BinaryExtended,
668    DecimalInterchange,
669    DecimalExtended,
670}
671
672// From 6.7.2.1
673
674/// Structure or union type specifier
675///
676/// (C11 6.7.2.1)
677#[derive(Debug, PartialEq, Clone)]
678pub struct StructType {
679    pub kind: Node<StructKind>,
680    pub identifier: Option<Node<Identifier>>,
681    /// List of structure of union members, when present.
682    ///
683    /// A [GNU extension](https://gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/Empty-Structures.html) allows the list to be empty.
684    pub declarations: Option<Vec<Node<StructDeclaration>>>,
685}
686
687/// The only difference between a `struct` and a `union`
688///
689/// (C11 6.7.2.1)
690#[derive(Debug, PartialEq, Eq, Hash, Clone)]
691pub enum StructKind {
692    Struct,
693    Union,
694}
695
696/// Single declaration in a struct or a union
697///
698/// (C11 6.7.2.1)
699#[derive(Debug, PartialEq, Clone)]
700pub enum StructDeclaration {
701    Field(Node<StructField>),
702    StaticAssert(Node<StaticAssert>),
703}
704
705/// Struct field declaration
706#[derive(Debug, PartialEq, Clone)]
707pub struct StructField {
708    pub specifiers: Vec<Node<SpecifierQualifier>>,
709    pub declarators: Vec<Node<StructDeclarator>>,
710}
711
712/// Type and qualifiers for a struct declaration
713///
714/// C11 also uses this type in a few other places.
715///
716/// (C11 6.7.2.1)
717#[derive(Debug, PartialEq, Clone)]
718pub enum SpecifierQualifier {
719    TypeSpecifier(Node<TypeSpecifier>),
720    TypeQualifier(Node<TypeQualifier>),
721    Extension(Vec<Node<Extension>>),
722}
723
724/// Field declarator for a struct or a union
725///
726/// (C11 6.7.2.1)
727#[derive(Debug, PartialEq, Clone)]
728pub struct StructDeclarator {
729    pub declarator: Option<Node<Declarator>>,
730    pub bit_width: Option<Box<Node<Expression>>>,
731}
732
733// From 6.7.2.2
734
735/// Enumeration type specifier
736///
737/// (C11 6.7.2.2)
738#[derive(Debug, PartialEq, Clone)]
739pub struct EnumType {
740    pub identifier: Option<Node<Identifier>>,
741    pub enumerators: Vec<Node<Enumerator>>,
742}
743
744/// Single constant inside a `enum` definition
745///
746/// (C11 6.7.2.2)
747#[derive(Debug, PartialEq, Clone)]
748pub struct Enumerator {
749    pub identifier: Node<Identifier>,
750    pub expression: Option<Box<Node<Expression>>>,
751    pub extensions: Vec<Node<Extension>>,
752}
753
754// From 6.7.3
755
756/// Type qualifier
757///
758/// (C11 6.7.3)
759#[derive(Debug, PartialEq, Eq, Hash, Clone)]
760pub enum TypeQualifier {
761    /// `const`
762    ///
763    /// `__const` (GNU extension)
764    Const,
765    /// `restrict`
766    ///
767    /// `__restrict`, `__restrict__` (GNU extension)
768    Restrict,
769    /// `volatile`
770    ///
771    /// `__volatile`, `__volatile__` (GNU extension)
772    Volatile,
773    /// '_Nonnull' (Clang extension)
774    ///
775    /// [Clang extension](https://clang.llvm.org/docs/AttributeReference.html)
776    Nonnull,
777    /// '_Null_unspecified' (Clang extension)
778    ///
779    /// [Clang extension](https://clang.llvm.org/docs/AttributeReference.html)
780    NullUnspecified,
781    /// '_Nullable' (Clang extension)
782    ///
783    /// [Clang extension](https://clang.llvm.org/docs/AttributeReference.html)
784    Nullable,
785    /// `_Atomic`
786    Atomic,
787}
788
789// From 6.7.4
790
791/// Function specifier
792///
793/// (C11 6.7.4)
794#[derive(Debug, PartialEq, Eq, Hash, Clone)]
795pub enum FunctionSpecifier {
796    /// `inline`
797    ///
798    /// `__inline`, `__inline__` (GNU extension)
799    Inline,
800    /// `_Noreturn`
801    Noreturn,
802}
803
804// From 6.7.5
805
806/// Alignment specifier
807///
808/// (C11 6.7.5)
809#[derive(Debug, PartialEq, Clone)]
810pub enum AlignmentSpecifier {
811    /// `_Alignas(typename)`
812    Type(Node<TypeName>),
813    /// `_Alignas(expression)`
814    Constant(Box<Node<Expression>>),
815}
816
817// From 6.7.6 Declarators
818
819/// Single item in a declaration
820///
821/// Represents both normal and abstract declarators.
822///
823/// (C11 6.7.6, 6.7.7)
824#[derive(Debug, PartialEq, Clone)]
825pub struct Declarator {
826    /// What is being declared
827    pub kind: Node<DeclaratorKind>,
828    /// Contains pointer, array and function declarator elements
829    pub derived: Vec<Node<DerivedDeclarator>>,
830    /// Vendor-specific extensions
831    pub extensions: Vec<Node<Extension>>,
832}
833
834/// Name of a declarator
835///
836/// (C11 6.7.6, 6.7.7)
837#[derive(Debug, PartialEq, Clone)]
838pub enum DeclaratorKind {
839    /// Unnamed declarator
840    ///
841    /// E.g. part of a function prototype without parameter names.
842    Abstract,
843    /// Named declarator
844    ///
845    /// E.g. a variable or a named function parameter.
846    Identifier(Node<Identifier>),
847    /// Nested declarator
848    ///
849    /// Any group of parenthesis inside a declarator. E.g. pointer to
850    /// a function.
851    Declarator(Box<Node<Declarator>>),
852}
853
854/// Modifies declarator type
855///
856/// (C11 6.7.6)
857#[derive(Debug, PartialEq, Clone)]
858pub enum DerivedDeclarator {
859    /// `* qualifiers …`
860    Pointer(Vec<Node<PointerQualifier>>),
861    /// `… []`
862    Array(Node<ArrayDeclarator>),
863    /// `… ( parameters )`
864    Function(Node<FunctionDeclarator>),
865    /// `… ( identifiers )`
866    KRFunction(Vec<Node<Identifier>>),
867    /// `^ qualifiers …`
868    ///
869    /// [Clang extension](https://clang.llvm.org/docs/BlockLanguageSpec.html)
870    Block(Vec<Node<PointerQualifier>>),
871}
872
873/// Array part of a declarator
874#[derive(Debug, PartialEq, Clone)]
875pub struct ArrayDeclarator {
876    pub qualifiers: Vec<Node<TypeQualifier>>,
877    pub size: ArraySize,
878}
879
880/// Function parameter part of a declarator
881#[derive(Debug, PartialEq, Clone)]
882pub struct FunctionDeclarator {
883    pub parameters: Vec<Node<ParameterDeclaration>>,
884    pub ellipsis: Ellipsis,
885}
886
887/// List of qualifiers that can follow a `*` in a declaration
888///
889/// (C11 6.7.6.1)
890#[derive(Debug, PartialEq, Clone)]
891pub enum PointerQualifier {
892    TypeQualifier(Node<TypeQualifier>),
893    Extension(Vec<Node<Extension>>),
894}
895
896/// Size of an array in a declaration
897///
898/// (C11 6.7.6.2)
899#[derive(Debug, PartialEq, Clone)]
900pub enum ArraySize {
901    /// `[]`
902    Unknown,
903    /// `[*]`
904    VariableUnknown,
905    /// `[10]`
906    VariableExpression(Box<Node<Expression>>),
907    /// `[static 10]`
908    StaticExpression(Box<Node<Expression>>),
909}
910
911/// Complete parameter declaration in a function prototype or declaration
912///
913/// This is so called "new-style" or "C89" parameter declaration that
914/// follows in parenthesis after a function name. "Old-style" or "K&R"
915/// function parameter declarations are collected in the
916/// `FunctionDefinition::declarations` field.
917///
918/// (C11 6.7.6.3)
919#[derive(Debug, PartialEq, Clone)]
920pub struct ParameterDeclaration {
921    pub specifiers: Vec<Node<DeclarationSpecifier>>,
922    pub declarator: Option<Node<Declarator>>,
923    pub extensions: Vec<Node<Extension>>,
924}
925
926/// Whether function signature ends with a `...`
927#[derive(Debug, PartialEq, Eq, Hash, Clone)]
928pub enum Ellipsis {
929    Some,
930    None,
931}
932
933// From 6.7.7 Type names
934
935/// References to types outside of declarations
936///
937/// Type names contain only abstract declarators.
938///
939/// (C11 6.7.7)
940#[derive(Debug, PartialEq, Clone)]
941pub struct TypeName {
942    pub specifiers: Vec<Node<SpecifierQualifier>>,
943    pub declarator: Option<Node<Declarator>>,
944}
945
946// From 6.7.9 Initialization
947
948/// Value that is assigned immediately in a declaration
949///
950/// (C11 6.7.9)
951#[derive(Debug, PartialEq, Clone)]
952pub enum Initializer {
953    Expression(Box<Node<Expression>>),
954    List(Vec<Node<InitializerListItem>>),
955}
956
957/// Initializes one field or array element in a initializer list
958///
959/// (C11 6.7.9)
960#[derive(Debug, PartialEq, Clone)]
961pub struct InitializerListItem {
962    pub designation: Vec<Node<Designator>>,
963    pub initializer: Box<Node<Initializer>>,
964}
965
966/// Single element of an designation in an initializer
967#[derive(Debug, PartialEq, Clone)]
968pub enum Designator {
969    /// Array element
970    ///
971    /// `{ [expression] = … }`
972    ///
973    /// `{ [expression] … }` (obsolete GNU extension)
974    Index(Node<Expression>),
975
976    /// Struct or union member
977    ///
978    /// `{ .identifier = … }`
979    ///
980    /// `{ identifier: … }` (obsolete GNU extension)
981    Member(Node<Identifier>),
982
983    /// Range of array elements
984    ///
985    /// `{ [from ... to] … }`
986    /// ([GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html#Designated-Inits))
987    Range(Node<RangeDesignator>),
988}
989
990/// Range array designator in an initializer
991///
992/// `[from ... to]`
993///
994/// ([GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html#Designated-Inits))
995#[derive(Debug, PartialEq, Clone)]
996pub struct RangeDesignator {
997    pub from: Node<Expression>,
998    pub to: Node<Expression>,
999}
1000
1001// From 6.7.10 Static assertions
1002
1003/// Static assertion
1004///
1005/// (C11 6.7.10)
1006#[derive(Debug, PartialEq, Clone)]
1007pub struct StaticAssert {
1008    pub expression: Box<Node<Expression>>,
1009    pub message: Node<StringLiteral>,
1010}
1011
1012// From 6.8 Statement
1013
1014/// Element of a function body
1015///
1016/// (C11 6.8)
1017#[derive(Debug, PartialEq, Clone)]
1018pub enum Statement {
1019    Labeled(Node<LabeledStatement>),
1020    Compound(Vec<Node<BlockItem>>),
1021    Expression(Option<Box<Node<Expression>>>),
1022    If(Node<IfStatement>),
1023    Switch(Node<SwitchStatement>),
1024    While(Node<WhileStatement>),
1025    DoWhile(Node<DoWhileStatement>),
1026    For(Node<ForStatement>),
1027    Goto(Node<Identifier>),
1028    Continue,
1029    Break,
1030    Return(Option<Box<Node<Expression>>>),
1031    /// Vendor specific inline assembly extensions
1032    Asm(Node<AsmStatement>),
1033}
1034
1035/// Labeled statement
1036///
1037/// (C11 6.8.1)
1038#[derive(Debug, PartialEq, Clone)]
1039pub struct LabeledStatement {
1040    pub label: Node<Label>,
1041    pub statement: Box<Node<Statement>>,
1042}
1043
1044/// If statement
1045///
1046/// (C11 6.8.4)
1047#[derive(Debug, PartialEq, Clone)]
1048pub struct IfStatement {
1049    pub condition: Box<Node<Expression>>,
1050    pub then_statement: Box<Node<Statement>>,
1051    pub else_statement: Option<Box<Node<Statement>>>,
1052}
1053
1054/// Switch statement
1055///
1056/// (C11 6.8.4)
1057#[derive(Debug, PartialEq, Clone)]
1058pub struct SwitchStatement {
1059    pub expression: Box<Node<Expression>>,
1060    pub statement: Box<Node<Statement>>,
1061}
1062
1063/// While statement
1064///
1065/// (C11 6.8.5)
1066#[derive(Debug, PartialEq, Clone)]
1067pub struct WhileStatement {
1068    pub expression: Box<Node<Expression>>,
1069    pub statement: Box<Node<Statement>>,
1070}
1071
1072/// Do statement
1073///
1074/// (C11 6.8.5)
1075#[derive(Debug, PartialEq, Clone)]
1076pub struct DoWhileStatement {
1077    pub statement: Box<Node<Statement>>,
1078    pub expression: Box<Node<Expression>>,
1079}
1080
1081/// For statement
1082///
1083/// (C11 6.8.5)
1084#[derive(Debug, PartialEq, Clone)]
1085pub struct ForStatement {
1086    pub initializer: Node<ForInitializer>,
1087    pub condition: Option<Box<Node<Expression>>>,
1088    pub step: Option<Box<Node<Expression>>>,
1089    pub statement: Box<Node<Statement>>,
1090}
1091
1092/// Statement labels for `goto` and `switch`
1093#[derive(Debug, PartialEq, Clone)]
1094pub enum Label {
1095    /// Goto label
1096    ///
1097    /// `ident: …`
1098    Identifier(Node<Identifier>),
1099    /// Case in a `switch` statement
1100    ///
1101    /// `case 'a': …`
1102    Case(Box<Node<Expression>>),
1103    /// Case with a range in a `switch` statement
1104    ///
1105    /// `case 'a' ... 'z': …`
1106    ///
1107    /// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html)
1108    CaseRange(Node<CaseRange>),
1109    /// Default case in a `switch` statement
1110    ///
1111    /// `default: …`
1112    Default,
1113}
1114
1115/// Case range expression
1116///
1117/// `from ... to`
1118///
1119/// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html)
1120#[derive(Debug, PartialEq, Clone)]
1121pub struct CaseRange {
1122    pub low: Box<Node<Expression>>,
1123    pub high: Box<Node<Expression>>,
1124}
1125
1126/// First element of a `for` statement
1127#[derive(Debug, PartialEq, Clone)]
1128pub enum ForInitializer {
1129    /// `for(; …)`
1130    Empty,
1131    /// `for(a = 1; …)`
1132    Expression(Box<Node<Expression>>),
1133    /// `for(int a = 1; …)`
1134    Declaration(Node<Declaration>),
1135    /// `for(_StaticAssert(…); …)`
1136    StaticAssert(Node<StaticAssert>),
1137}
1138
1139// From 6.8.2
1140
1141/// Element of a compound statement
1142#[derive(Debug, PartialEq, Clone)]
1143pub enum BlockItem {
1144    Declaration(Node<Declaration>),
1145    StaticAssert(Node<StaticAssert>),
1146    Statement(Node<Statement>),
1147}
1148
1149// From 6.9 External definitions
1150
1151/// Entire C source file after preprocessing
1152///
1153/// (C11 6.9)
1154#[derive(Debug, PartialEq, Clone)]
1155pub struct TranslationUnit(pub Vec<Node<ExternalDeclaration>>);
1156
1157/// Top-level elements of a C program
1158///
1159/// (C11 6.9)
1160#[derive(Debug, PartialEq, Clone)]
1161pub enum ExternalDeclaration {
1162    Declaration(Node<Declaration>),
1163    StaticAssert(Node<StaticAssert>),
1164    FunctionDefinition(Node<FunctionDefinition>),
1165}
1166
1167/// Function definition
1168///
1169/// (C11 6.9.1)
1170#[derive(Debug, PartialEq, Clone)]
1171pub struct FunctionDefinition {
1172    /// Return type of the function, possibly mixed with other specifiers
1173    pub specifiers: Vec<Node<DeclarationSpecifier>>,
1174    /// Contains function name and parameter list
1175    pub declarator: Node<Declarator>,
1176    /// K&R style parameter type definitions (C11 6.9.1 §6)
1177    pub declarations: Vec<Node<Declaration>>,
1178    /// Body of the function.
1179    pub statement: Node<Statement>,
1180}
1181
1182// Syntax extensions
1183
1184/// Extended vendor-specific syntax that does not fit elsewhere
1185#[derive(Debug, PartialEq, Clone)]
1186pub enum Extension {
1187    /// Attributes
1188    ///
1189    /// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html)
1190    Attribute(Attribute),
1191    /// Assembler name for an object
1192    ///
1193    /// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Asm-Labels.html)
1194    AsmLabel(Node<StringLiteral>),
1195    /// Platform availability
1196    ///
1197    /// [Clang extension](https://clang.llvm.org/docs/AttributeReference.html#availability)
1198    AvailabilityAttribute(Node<AvailabilityAttribute>),
1199}
1200
1201/// Attributes
1202///
1203/// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html)
1204#[derive(Debug, PartialEq, Clone)]
1205pub struct Attribute {
1206    pub name: Node<String>,
1207    pub arguments: Vec<Node<Expression>>,
1208}
1209
1210/// Platform availability attribute
1211///
1212/// [Clang extension](https://clang.llvm.org/docs/AttributeReference.html#availability)
1213#[derive(Debug, PartialEq, Clone)]
1214pub struct AvailabilityAttribute {
1215    pub platform: Node<Identifier>,
1216    pub clauses: Vec<Node<AvailabilityClause>>,
1217}
1218
1219/// Platfrom availability attribute clause
1220///
1221/// [Clang extension](https://clang.llvm.org/docs/AttributeReference.html#availability)
1222#[derive(Debug, PartialEq, Clone)]
1223pub enum AvailabilityClause {
1224    Introduced(Node<AvailabilityVersion>),
1225    Deprecated(Node<AvailabilityVersion>),
1226    Obsoleted(Node<AvailabilityVersion>),
1227    Unavailable,
1228    Message(Node<StringLiteral>),
1229    Replacement(Node<StringLiteral>),
1230}
1231
1232/// Platfrom version inside availability attribute
1233///
1234/// [Clang extension](https://clang.llvm.org/docs/AttributeReference.html#availability)
1235#[derive(Debug, PartialEq, Eq, Hash, Clone)]
1236pub struct AvailabilityVersion {
1237    pub major: String,
1238    pub minor: Option<String>,
1239    pub subminor: Option<String>,
1240}
1241
1242/// Inline assembler
1243#[derive(Debug, PartialEq, Clone)]
1244pub enum AsmStatement {
1245    /// Basic asm statement with just source code
1246    ///
1247    /// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html)
1248    GnuBasic(Node<StringLiteral>),
1249
1250    /// Extended statement that has access to C variables
1251    ///
1252    /// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html)
1253    GnuExtended(GnuExtendedAsmStatement),
1254}
1255
1256/// Extended statement that has access to C variables
1257///
1258/// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html)
1259#[derive(Debug, PartialEq, Clone)]
1260pub struct GnuExtendedAsmStatement {
1261    pub qualifier: Option<Node<TypeQualifier>>,
1262    pub template: Node<StringLiteral>,
1263    pub outputs: Vec<Node<GnuAsmOperand>>,
1264    pub inputs: Vec<Node<GnuAsmOperand>>,
1265    pub clobbers: Vec<Node<StringLiteral>>,
1266}
1267
1268/// Single input or output operand specifier for GNU extended asm statement
1269///
1270/// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Output-Operands)
1271#[derive(Debug, PartialEq, Clone)]
1272pub struct GnuAsmOperand {
1273    pub symbolic_name: Option<Node<Identifier>>,
1274    pub constraints: Node<StringLiteral>,
1275    pub variable_name: Node<Expression>,
1276}
1277
1278/// Type of an expression or type
1279///
1280/// [GNU extension](https://gcc.gnu.org/onlinedocs/gcc/Typeof.html)
1281#[derive(Debug, PartialEq, Clone)]
1282pub enum TypeOf {
1283    Expression(Node<Expression>),
1284    Type(Node<TypeName>),
1285}