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}