forked from cartazio/language-c
-
Notifications
You must be signed in to change notification settings - Fork 43
/
AST.hs
1460 lines (1320 loc) · 60.6 KB
/
AST.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeSynonymInstances #-}
-----------------------------------------------------------------------------
-- |
-- Module : Language.C.Syntax.AST
-- Copyright : (c) [1999..2007] Manuel M T Chakravarty
-- (c) 2008 Benedikt Huber
-- License : BSD-style
-- Maintainer : benedikt.huber@gmail.com
-- Stability : experimental
-- Portability : ghc
--
-- Abstract syntax of C source and header files.
--
-- The tree structure is based on the grammar in Appendix A of K&R. The
-- abstract syntax simplifies the concrete syntax by merging similar concrete
-- constructs into a single type of abstract tree structure: declarations are
-- merged with structure declarations, parameter declarations and type names,
-- and declarators are merged with abstract declarators.
--
-- With K&R we refer to ``The C Programming Language'', second edition, Brain
-- W. Kernighan and Dennis M. Ritchie, Prentice Hall, 1988. The AST supports all
-- of C99 <http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf> and several
-- GNU extensions <http://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html>.
-----------------------------------------------------------------------------
module Language.C.Syntax.AST (
-- * C translation units
CTranslUnit, CExtDecl,
CTranslationUnit(..), CExternalDeclaration(..),
-- * Declarations
CFunDef, CDecl, CStructUnion, CEnum,
CFunctionDef(..), CDeclaration(..),
CStructTag(..), CStructureUnion(..), CEnumeration(..),
-- * Declaration attributes
CDeclSpec, partitionDeclSpecs,
CStorageSpec, CTypeSpec, isSUEDef, CTypeQual, CFunSpec, CAlignSpec, CAttr,
CFunctionSpecifier(..), CDeclarationSpecifier(..), CStorageSpecifier(..), CTypeSpecifier(..),
CAlignmentSpecifier(..),
CTypeQualifier(..), CAttribute(..),
-- * Declarators
CDeclr,CDerivedDeclr,CArrSize,
CDeclarator(..), CDerivedDeclarator(..), CArraySize(..),
-- * Initialization
CInit, CInitList, CDesignator,
CInitializer(..), CInitializerList, CPartDesignator(..),
-- * Statements
CStat, CBlockItem, CAsmStmt, CAsmOperand,
CStatement(..), CCompoundBlockItem(..),
CAssemblyStatement(..), CAssemblyOperand(..),
-- * Expressions
CExpr, CExpression(..),
CAssignOp(..), CBinaryOp(..), CUnaryOp(..),
CBuiltin, CBuiltinThing(..),
-- * Constants
CConst, CStrLit, cstringOfLit, liftStrLit,
CConstant(..), CStringLiteral(..),
-- * Annoated type class
Annotated(..)
) where
import Language.C.Syntax.Constants
import Language.C.Syntax.Ops
import Language.C.Data.Ident
import Language.C.Data.Node
import Language.C.Data.Position
import Data.Data (Data)
import Data.Typeable (Typeable)
import GHC.Generics (Generic, Generic1)
import Control.DeepSeq (NFData)
-- | Complete C tranlsation unit (C99 6.9, K&R A10)
--
-- A complete C translation unit, for example representing a C header or source file.
-- It consists of a list of external (i.e. toplevel) declarations.
type CTranslUnit = CTranslationUnit NodeInfo
data CTranslationUnit a
= CTranslUnit [CExternalDeclaration a] a
deriving (Show, Data, Typeable, Generic, Generic1 {-! ,CNode ,Functor, Annotated !-})
instance NFData a => NFData (CTranslationUnit a)
-- | External C declaration (C99 6.9, K&R A10)
--
-- Either a toplevel declaration, function definition or external assembler.
type CExtDecl = CExternalDeclaration NodeInfo
data CExternalDeclaration a
= CDeclExt (CDeclaration a)
| CFDefExt (CFunctionDef a)
| CAsmExt (CStringLiteral a) a
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor, Annotated !-})
instance NFData a => NFData (CExternalDeclaration a)
-- | C function definition (C99 6.9.1, K&R A10.1)
--
-- A function definition is of the form @CFunDef specifiers declarator decllist? stmt@.
--
-- * @specifiers@ are the type and storage-class specifiers of the function.
-- The only storage-class specifiers allowed are /extern/ and /static/.
--
-- * The @declarator@ must be such that the declared identifier has /function type/.
-- The return type shall be void or an object type other than array type.
--
-- * The optional declaration list @decllist@ is for old-style function declarations.
--
-- * The statement @stmt@ is a compound statement.
type CFunDef = CFunctionDef NodeInfo
data CFunctionDef a
= CFunDef
[CDeclarationSpecifier a] -- type specifier and qualifier
(CDeclarator a) -- declarator
[CDeclaration a] -- optional declaration list
(CStatement a) -- compound statement
a
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CFunctionDef a)
-- | C declarations (K&R A8, C99 6.7), including structure declarations, parameter
-- declarations and type names.
--
-- A declaration is of the form @CDecl specifiers init-declarator-list@, where the form of the declarator list's
-- elements depends on the kind of declaration:
--
-- 1) Toplevel declarations (K&R A8, C99 6.7 declaration)
--
-- * C99 requires that there is at least one specifier, though this is merely a syntactic restriction
--
-- * at most one storage class specifier is allowed per declaration
--
-- * the elements of the non-empty @init-declarator-list@ are of the form @(Just declr, init?, Nothing)@.
-- The declarator @declr@ has to be present and non-abstract and the initialization expression is
-- optional.
--
-- 2) Structure declarations (K&R A8.3, C99 6.7.2.1 struct-declaration)
--
-- Those are the declarations of a structure's members.
--
-- * do not allow storage specifiers
--
-- * in strict C99, the list of declarators has to be non-empty
--
-- * the elements of @init-declarator-list@ are either of the form @(Just declr, Nothing, size?)@,
-- representing a member with optional bit-field size, or of the form @(Nothing, Nothing, Just size)@,
-- for unnamed bitfields. @declr@ has to be non-abstract.
--
-- * no member of a structure shall have incomplete type
--
-- 3) Parameter declarations (K&R A8.6.3, C99 6.7.5 parameter-declaration)
--
-- * @init-declarator-list@ must contain at most one triple of the form @(Just declr, Nothing, Nothing)@,
-- i.e. consist of a single declarator, which is allowed to be abstract (i.e. unnamed).
--
-- 4) Type names (A8.8, C99 6.7.6)
--
-- * do not allow storage specifiers
--
-- * @init-declarator-list@ must contain at most one triple of the form @(Just declr, Nothing, Nothing)@.
-- where @declr@ is an abstract declarator (i.e. doesn't contain a declared identifier)
--
type CDecl = CDeclaration NodeInfo
data CDeclaration a
= CDecl
[CDeclarationSpecifier a] -- type specifier and qualifier, __attribute__
[(Maybe (CDeclarator a), -- declarator (may be omitted)
Maybe (CInitializer a), -- optional initialize
Maybe (CExpression a))] -- optional size (const expr)
a -- annotation
| CStaticAssert
(CExpression a) -- assert expression
(CStringLiteral a) -- assert text
a -- annotation
deriving (Show, Data,Typeable, Generic {-! ,CNode ,Annotated !-})
instance NFData a => NFData (CDeclaration a)
-- Derive instance is a little bit ugly
instance Functor CDeclaration where
fmap f (CDecl specs declarators annot) =
CDecl (map (fmap f) specs) (map fmap3m declarators) (f annot)
where fmap3m (a,b,c) = (fmap (fmap f) a, fmap (fmap f) b, fmap (fmap f) c)
fmap f (CStaticAssert expression strlit annot) =
CStaticAssert (fmap f expression) (fmap f strlit) (f annot)
-- | C declarator (K&R A8.5, C99 6.7.5) and abstract declarator (K&R A8.8, C99 6.7.6)
--
-- A declarator declares a single object, function, or type. It is always associated with
-- a declaration ('CDecl'), which specifies the declaration's type and the additional storage qualifiers and
-- attributes, which apply to the declared object.
--
-- A declarator is of the form @CDeclr name? indirections asm-name? attrs _@, where
-- @name@ is the name of the declared object (missing for abstract declarators),
-- @declquals@ is a set of additional declaration specifiers,
-- @asm-name@ is the optional assembler name and attributes is a set of
-- attrs is a set of @__attribute__@ annotations for the declared object.
--
-- @indirections@ is a set of pointer, array and function declarators, which modify the type of the declared object as
-- described below. If the /declaration/ specifies the non-derived type @T@,
-- and we have @indirections = [D1, D2, ..., Dn]@ than the declared object has type
-- @(D1 `indirect` (D2 `indirect` ... (Dn `indirect` T)))@, where
--
-- * @(CPtrDeclr attrs) `indirect` T@ is /attributed pointer to T/
--
-- * @(CFunDeclr attrs) `indirect` T@ is /attributed function returning T/
--
-- * @(CArrayDeclr attrs) `indirect` T@ is /attributed array of elemements of type T/
--
-- Examples (simplified attributes):
--
-- * /x/ is an int
--
-- > int x;
-- > CDeclr "x" []
--
-- * /x/ is a restrict pointer to a const pointer to int
--
-- > const int * const * restrict x;
-- > CDeclr "x" [CPtrDeclr [restrict], CPtrDeclr [const]]
--
-- * /f/ is an function return a constant pointer to int
--
-- > int* const f();
-- > CDeclr "f" [CFunDeclr [],CPtrDeclr [const]]
--
-- * /f/ is a constant pointer to a function returning int
--
-- > int (* const f)(); ==>
-- > CDeclr "f" [CPtrDeclr [const], CFunDeclr []]
type CDeclr = CDeclarator NodeInfo
data CDeclarator a
= CDeclr (Maybe Ident) [CDerivedDeclarator a] (Maybe (CStringLiteral a)) [CAttribute a] a
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CDeclarator a)
-- | Derived declarators, see 'CDeclr'
--
-- Indirections are qualified using type-qualifiers and generic attributes, and additionally
--
-- * The size of an array is either a constant expression, variable length ('*') or missing; in the last case, the
-- type of the array is incomplete. The qualifier static is allowed for function arguments only, indicating that
-- the supplied argument is an array of at least the given size.
--
-- * New style parameter lists have the form @Right (declarations, isVariadic)@, old style parameter lists have the
-- form @Left (parameter-names)@
type CDerivedDeclr = CDerivedDeclarator NodeInfo
data CDerivedDeclarator a
= CPtrDeclr [CTypeQualifier a] a
-- ^ Pointer declarator @CPtrDeclr tyquals declr@
| CArrDeclr [CTypeQualifier a] (CArraySize a) a
-- ^ Array declarator @CArrDeclr declr tyquals size-expr?@
| CFunDeclr (Either [Ident] ([CDeclaration a],Bool)) [CAttribute a] a
-- ^ Function declarator @CFunDeclr declr (old-style-params | new-style-params) c-attrs@
deriving (Show, Data,Typeable, Generic {-! ,CNode , Annotated !-})
instance NFData a => NFData (CDerivedDeclarator a)
-- Derived instance relies on fmap2
instance Functor CDerivedDeclarator where
fmap _f (CPtrDeclr a1 a2) = CPtrDeclr (fmap (fmap _f) a1) (_f a2)
fmap _f (CArrDeclr a1 a2 a3)
= CArrDeclr (fmap (fmap _f) a1) (fmap _f a2) (_f a3)
fmap _f (CFunDeclr a1 a2 a3)
= CFunDeclr (fmap (fmapFirst (fmap (fmap _f))) a1) (fmap (fmap _f) a2)
(_f a3)
where fmapFirst f (a,b) = (f a, b)
-- | Size of an array
type CArrSize = CArraySize NodeInfo
data CArraySize a
= CNoArrSize Bool -- ^ @CUnknownSize isCompleteType@
| CArrSize Bool (CExpression a) -- ^ @CArrSize isStatic expr@
deriving (Show, Data,Typeable, Generic, Generic1 {-! , Functor !-})
instance NFData a => NFData (CArraySize a)
-- | C statement (K&R A9, C99 6.8)
--
type CStat = CStatement NodeInfo
data CStatement a
-- | An (attributed) label followed by a statement
= CLabel Ident (CStatement a) [CAttribute a] a
-- | A statement of the form @case expr : stmt@
| CCase (CExpression a) (CStatement a) a
-- | A case range of the form @case lower ... upper : stmt@
| CCases (CExpression a) (CExpression a) (CStatement a) a
-- | The default case @default : stmt@
| CDefault (CStatement a) a
-- | A simple statement, that is in C: evaluating an expression with
-- side-effects and discarding the result.
| CExpr (Maybe (CExpression a)) a
-- | compound statement @CCompound localLabels blockItems at@
| CCompound [Ident] [CCompoundBlockItem a] a
-- | conditional statement @CIf ifExpr thenStmt maybeElseStmt at@
| CIf (CExpression a) (CStatement a) (Maybe (CStatement a)) a
-- | switch statement @CSwitch selectorExpr switchStmt@, where
-- @switchStmt@ usually includes /case/, /break/ and /default/
-- statements
| CSwitch (CExpression a) (CStatement a) a
-- | while or do-while statement @CWhile guard stmt isDoWhile at@
| CWhile (CExpression a) (CStatement a) Bool a
-- | for statement @CFor init expr-2 expr-3 stmt@, where @init@ is
-- either a declaration or initializing expression
| CFor (Either (Maybe (CExpression a)) (CDeclaration a))
(Maybe (CExpression a))
(Maybe (CExpression a))
(CStatement a)
a
-- | goto statement @CGoto label@
| CGoto Ident a
-- | computed goto @CGotoPtr labelExpr@
| CGotoPtr (CExpression a) a
-- | continue statement
| CCont a
-- | break statement
| CBreak a
-- | return statement @CReturn returnExpr@
| CReturn (Maybe (CExpression a)) a
-- | assembly statement
| CAsm (CAssemblyStatement a) a
deriving (Show, Data,Typeable, Generic {-! , CNode , Annotated !-})
instance NFData a => NFData (CStatement a)
-- Derived instance relies on fmap2 :(
instance Functor CStatement where
fmap _f (CLabel a1 a2 a3 a4)
= CLabel a1 (fmap _f a2) (fmap (fmap _f) a3) (_f a4)
fmap _f (CCase a1 a2 a3) = CCase (fmap _f a1) (fmap _f a2) (_f a3)
fmap _f (CCases a1 a2 a3 a4)
= CCases (fmap _f a1) (fmap _f a2) (fmap _f a3) (_f a4)
fmap _f (CDefault a1 a2) = CDefault (fmap _f a1) (_f a2)
fmap _f (CExpr a1 a2) = CExpr (fmap (fmap _f) a1) (_f a2)
fmap _f (CCompound a1 a2 a3)
= CCompound a1 (fmap (fmap _f) a2) (_f a3)
fmap _f (CIf a1 a2 a3 a4)
= CIf (fmap _f a1) (fmap _f a2) (fmap (fmap _f) a3) (_f a4)
fmap _f (CSwitch a1 a2 a3)
= CSwitch (fmap _f a1) (fmap _f a2) (_f a3)
fmap _f (CWhile a1 a2 a3 a4)
= CWhile (fmap _f a1) (fmap _f a2) a3 (_f a4)
fmap _f (CFor a1 a2 a3 a4 a5)
= CFor (mapEither (fmap (fmap _f)) (fmap _f) a1)
(fmap (fmap _f) a2) (fmap (fmap _f) a3) (fmap _f a4)
(_f a5)
where mapEither f1 f2 = either (Left . f1) (Right . f2)
fmap _f (CGoto a1 a2) = CGoto a1 (_f a2)
fmap _f (CGotoPtr a1 a2) = CGotoPtr (fmap _f a1) (_f a2)
fmap _f (CCont a1) = CCont (_f a1)
fmap _f (CBreak a1) = CBreak (_f a1)
fmap _f (CReturn a1 a2) = CReturn (fmap (fmap _f) a1) (_f a2)
fmap _f (CAsm a1 a2) = CAsm (fmap _f a1) (_f a2)
-- | GNU Assembler statement
--
-- > CAssemblyStatement type-qual? asm-expr out-ops in-ops clobbers _
--
-- is an inline assembler statement.
-- The only type-qualifier (if any) allowed is /volatile/.
-- @asm-expr@ is the actual assembler epxression (a string), @out-ops@ and @in-ops@ are the input
-- and output operands of the statement.
-- @clobbers@ is a list of registers which are clobbered when executing the assembler statement
type CAsmStmt = CAssemblyStatement NodeInfo
data CAssemblyStatement a
= CAsmStmt
(Maybe (CTypeQualifier a)) -- maybe volatile
(CStringLiteral a) -- assembler expression (String)
[CAssemblyOperand a] -- output operands
[CAssemblyOperand a] -- input operands
[CStringLiteral a] -- Clobbers
a
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CAssemblyStatement a)
-- | Assembler operand
--
-- @CAsmOperand argName? constraintExpr arg@ specifies an operand for an assembler
-- statement.
type CAsmOperand = CAssemblyOperand NodeInfo
data CAssemblyOperand a
= CAsmOperand
(Maybe Ident) -- argument name
(CStringLiteral a) -- constraint expr
(CExpression a) -- argument
a
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CAssemblyOperand a)
-- | C99 Block items
--
-- Things that may appear in compound statements: either statements, declarations
-- or nested function definitions.
type CBlockItem = CCompoundBlockItem NodeInfo
data CCompoundBlockItem a
= CBlockStmt (CStatement a) -- ^ A statement
| CBlockDecl (CDeclaration a) -- ^ A local declaration
| CNestedFunDef (CFunctionDef a) -- ^ A nested function (GNU C)
deriving (Show, Data,Typeable, Generic, Generic1 {-! , CNode , Functor, Annotated !-})
instance NFData a => NFData (CCompoundBlockItem a)
-- | C declaration specifiers and qualifiers
--
-- Declaration specifiers include at most one storage-class specifier (C99 6.7.1),
-- type specifiers (6.7.2) and type qualifiers (6.7.3).
type CDeclSpec = CDeclarationSpecifier NodeInfo
data CDeclarationSpecifier a
= CStorageSpec (CStorageSpecifier a) -- ^ storage-class specifier or typedef
| CTypeSpec (CTypeSpecifier a) -- ^ type name
| CTypeQual (CTypeQualifier a) -- ^ type qualifier
| CFunSpec (CFunctionSpecifier a) -- ^ function specifier
| CAlignSpec (CAlignmentSpecifier a) -- ^ alignment specifier
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor, Annotated !-})
instance NFData a => NFData (CDeclarationSpecifier a)
-- | Separate the declaration specifiers
--
-- @__attribute__@ of a declaration qualify declarations or declarators (but not types),
-- and are therefore separated as well.
partitionDeclSpecs :: [CDeclarationSpecifier a]
-> ( [CStorageSpecifier a], [CAttribute a]
, [CTypeQualifier a], [CTypeSpecifier a]
, [CFunctionSpecifier a], [CAlignmentSpecifier a])
partitionDeclSpecs = foldr deals ([],[],[],[],[],[]) where
deals (CStorageSpec sp) (sts,ats,tqs,tss,fss,ass) = (sp:sts,ats,tqs,tss,fss,ass)
deals (CTypeQual (CAttrQual attr)) (sts,ats,tqs,tss,fss,ass) = (sts,attr:ats,tqs,tss,fss,ass)
deals (CTypeQual tq) (sts,ats,tqs,tss,fss,ass) = (sts,ats,tq:tqs,tss,fss,ass)
deals (CTypeSpec ts) (sts,ats,tqs,tss,fss,ass) = (sts,ats,tqs,ts:tss,fss,ass)
deals (CFunSpec fs) (sts,ats,tqs,tss,fss,ass) = (sts,ats,tqs,tss,fs:fss,ass)
deals (CAlignSpec as) (sts,ats,tqs,tss,fss,ass) = (sts,ats,tqs,tss,fss,as:ass)
-- | C storage class specifier (and typedefs) (K&R A8.1, C99 6.7.1)
type CStorageSpec = CStorageSpecifier NodeInfo
data CStorageSpecifier a
= CAuto a -- ^ auto
| CRegister a -- ^ register
| CStatic a -- ^ static
| CExtern a -- ^ extern
| CTypedef a -- ^ typedef
| CThread a -- ^ C11/GNUC thread local storage
| CClKernel a -- ^ OpenCL kernel function
| CClGlobal a -- ^ OpenCL __global variable
| CClLocal a -- ^ OpenCL __local variable
deriving (Show, Eq,Ord,Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CStorageSpecifier a)
-- | C type specifier (K&R A8.2, C99 6.7.2)
--
-- Type specifiers are either basic types such as @char@ or @int@,
-- @struct@, @union@ or @enum@ specifiers or typedef names.
--
-- As a GNU extension, a @typeof@ expression also is a type specifier.
type CTypeSpec = CTypeSpecifier NodeInfo
data CTypeSpecifier a
= CVoidType a
| CCharType a
| CShortType a
| CIntType a
| CLongType a
| CFloatType a
| CDoubleType a
| CSignedType a
| CUnsigType a
| CBoolType a
| CComplexType a
| CInt128Type a
| CFloatNType Int Bool a -- ^ IEC 60227: width (32,64,128), extended flag
| CSUType (CStructureUnion a) a -- ^ Struct or Union specifier
| CEnumType (CEnumeration a) a -- ^ Enumeration specifier
| CTypeDef Ident a -- ^ Typedef name
| CTypeOfExpr (CExpression a) a -- ^ @typeof(expr)@
| CTypeOfType (CDeclaration a) a -- ^ @typeof(type)@
| CAtomicType (CDeclaration a) a -- ^ @_Atomic(type)@
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CTypeSpecifier a)
-- | returns @True@ if the given typespec is a struct, union or enum /definition/
isSUEDef :: CTypeSpecifier a -> Bool
isSUEDef (CSUType (CStruct _ _ (Just _) _ _) _) = True
isSUEDef (CEnumType (CEnum _ (Just _) _ _) _) = True
isSUEDef _ = False
-- | C type qualifiers (K&R A8.2, C99 6.7.3) and attributes.
--
-- @const@, @volatile@ and @restrict@ type qualifiers
-- Additionally, @__attribute__@ annotations for declarations and declarators, and
-- function specifiers
type CTypeQual = CTypeQualifier NodeInfo
data CTypeQualifier a
= CConstQual a
| CVolatQual a
| CRestrQual a
| CAtomicQual a
| CAttrQual (CAttribute a)
| CNullableQual a
| CNonnullQual a
| CClRdOnlyQual a
| CClWrOnlyQual a
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CTypeQualifier a)
-- | C function specifiers (C99 6.7.4)
--
-- function specifiers @inline@ and @_Noreturn@
type CFunSpec = CFunctionSpecifier NodeInfo
data CFunctionSpecifier a
= CInlineQual a
| CNoreturnQual a
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CFunctionSpecifier a)
-- | C alignment specifiers (C99 6.7.5)
--
type CAlignSpec = CAlignmentSpecifier NodeInfo
data CAlignmentSpecifier a
= CAlignAsType (CDeclaration a) a -- ^ @_Alignas(type)@
| CAlignAsExpr (CExpression a) a -- ^ @_Alignas(expr)@
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CAlignmentSpecifier a)
-- | C structure or union specifiers (K&R A8.3, C99 6.7.2.1)
--
-- @CStruct tag identifier struct-decls c-attrs@ represents a struct or union specifier (depending on @tag@).
--
-- * either @identifier@ or the declaration list @struct-decls@ (or both) have to be present.
--
-- Example: in @struct foo x;@, the identifier is present, in @struct { int y; } x@ the declaration list, and
-- in @struct foo { int y; } x;@ both of them.
--
-- * @c-attrs@ is a list of @__attribute__@ annotations associated with the struct or union specifier
type CStructUnion = CStructureUnion NodeInfo
data CStructureUnion a
= CStruct
CStructTag
(Maybe Ident)
(Maybe [CDeclaration a]) -- member declarations
[CAttribute a] -- __attribute__s
a
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CStructureUnion a)
-- | A tag to determine wheter we refer to a @struct@ or @union@, see 'CStructUnion'.
data CStructTag = CStructTag
| CUnionTag
deriving (Show, Eq,Data,Typeable, Generic)
instance NFData CStructTag
-- | C enumeration specifier (K&R A8.4, C99 6.7.2.2)
--
-- @CEnum identifier enumerator-list attrs@ represent as enum specifier
--
-- * Either the identifier or the enumerator-list (or both) have to be present.
--
-- * If @enumerator-list@ is present, it has to be non-empty.
--
-- * The enumerator list is of the form @(enumeration-constant, enumeration-value?)@, where the latter
-- is an optional constant integral expression.
--
-- * @attrs@ is a list of @__attribute__@ annotations associated with the enumeration specifier
type CEnum = CEnumeration NodeInfo
data CEnumeration a
= CEnum
(Maybe Ident)
(Maybe [(Ident, -- variant name
Maybe (CExpression a))]) -- explicit variant value
[CAttribute a] -- __attribute__s
a
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CEnumeration a)
-- | C initialization (K&R A8.7, C99 6.7.8)
--
-- Initializers are either assignment expressions or initializer lists
-- (surrounded in curly braces), whose elements are themselves
-- initializers, paired with an optional list of designators.
type CInit = CInitializer NodeInfo
data CInitializer a
-- | assignment expression
= CInitExpr (CExpression a) a
-- | initialization list (see 'CInitList')
| CInitList (CInitializerList a) a
deriving (Show, Data,Typeable, Generic {-! ,CNode , Annotated !-})
instance NFData a => NFData (CInitializer a)
-- deriving Functor does not work (type synonym)
instance Functor CInitializer where
fmap _f (CInitExpr a1 a2) = CInitExpr (fmap _f a1) (_f a2)
fmap _f (CInitList a1 a2) = CInitList (fmapInitList _f a1) (_f a2)
fmapInitList :: (a->b) -> (CInitializerList a) -> (CInitializerList b)
fmapInitList _f = map (\(desigs, initializer) -> (fmap (fmap _f) desigs, fmap _f initializer))
-- | Initializer List
--
-- The members of an initializer list are of the form @(designator-list,initializer)@.
-- The @designator-list@ specifies one member of the compound type which is initialized.
-- It is allowed to be empty - in this case the initializer refers to the
-- ''next'' member of the compound type (see C99 6.7.8).
--
-- Examples (simplified expressions and identifiers):
--
-- > -- int x[3][4] = { [0][3] = 4, [2] = 5, 8 };
-- > -- corresponds to the assignments
-- > -- x[0][3] = 4; x[2][0] = 5; x[2][1] = 8;
-- > let init1 = ([CArrDesig 0, CArrDesig 3], CInitExpr 4)
-- > init2 = ([CArrDesig 2] , CInitExpr 5)
-- > init3 = ([] , CInitExpr 8)
-- > in CInitList [init1, init2, init3]
--
-- > -- struct { struct { int a[2]; int b[2]; int c[2]; } s; } x = { .s = { {2,3} , .c[0] = 1 } };
-- > -- corresponds to the assignments
-- > -- x.s.a[0] = 2; x.s.a[1] = 3; x.s.c[0] = 1;
-- > let init_s_0 = CInitList [ ([], CInitExpr 2), ([], CInitExpr 3)]
-- > init_s = CInitList [
-- > ([], init_s_0),
-- > ([CMemberDesig "c", CArrDesig 0], CInitExpr 1)
-- > ]
-- > in CInitList [(CMemberDesig "s", init_s)]
type CInitList = CInitializerList NodeInfo
type CInitializerList a = [([CPartDesignator a], CInitializer a)]
-- | Designators
--
-- A designator specifies a member of an object, either an element or range of an array,
-- or the named member of a struct \/ union.
type CDesignator = CPartDesignator NodeInfo
data CPartDesignator a
-- | array position designator
= CArrDesig (CExpression a) a
-- | member designator
| CMemberDesig Ident a
-- | array range designator @CRangeDesig from to _@ (GNU C)
| CRangeDesig (CExpression a) (CExpression a) a
deriving (Show, Data,Typeable, Generic {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CPartDesignator a)
-- | @__attribute__@ annotations
--
-- Those are of the form @CAttr attribute-name attribute-parameters@,
-- and serve as generic properties of some syntax tree elements.
type CAttr = CAttribute NodeInfo
data CAttribute a = CAttr Ident [CExpression a] a
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CAttribute a)
-- | C expression (K&R A7)
--
-- * these can be arbitrary expression, as the argument of `sizeof' can be
-- arbitrary, even if appearing in a constant expression
--
-- * GNU C extensions: @alignof@, @__real@, @__imag@, @({ stmt-expr })@, @&& label@ and built-ins
--
type CExpr = CExpression NodeInfo
data CExpression a
= CComma [CExpression a] -- comma expression list, n >= 2
a
| CAssign CAssignOp -- assignment operator
(CExpression a) -- l-value
(CExpression a) -- r-value
a
| CCond (CExpression a) -- conditional
(Maybe (CExpression a)) -- true-expression (GNU allows omitting)
(CExpression a) -- false-expression
a
| CBinary CBinaryOp -- binary operator
(CExpression a) -- lhs
(CExpression a) -- rhs
a
| CCast (CDeclaration a) -- type name
(CExpression a)
a
| CUnary CUnaryOp -- unary operator
(CExpression a)
a
| CSizeofExpr (CExpression a)
a
| CSizeofType (CDeclaration a) -- type name
a
| CAlignofExpr (CExpression a)
a
| CAlignofType (CDeclaration a) -- type name
a
| CComplexReal (CExpression a) -- real part of complex number
a
| CComplexImag (CExpression a) -- imaginary part of complex number
a
| CIndex (CExpression a) -- array
(CExpression a) -- index
a
| CCall (CExpression a) -- function
[CExpression a] -- arguments
a
| CMember (CExpression a) -- structure
Ident -- member name
Bool -- deref structure? (True for `->')
a
| CVar Ident -- identifier (incl. enumeration const)
a
| CConst (CConstant a) -- ^ integer, character, floating point and string constants
| CCompoundLit (CDeclaration a)
(CInitializerList a) -- type name & initialiser list
a -- ^ C99 compound literal
| CGenericSelection (CExpression a) [(Maybe (CDeclaration a), CExpression a)] a -- ^ C11 generic selection
| CStatExpr (CStatement a) a -- ^ GNU C compound statement as expr
| CLabAddrExpr Ident a -- ^ GNU C address of label
| CBuiltinExpr (CBuiltinThing a) -- ^ builtin expressions, see 'CBuiltin'
deriving (Data,Typeable,Show, Generic {-! ,CNode , Annotated !-})
instance NFData a => NFData (CExpression a)
-- deriving Functor does not work (type synonyms)
instance Functor CExpression where
fmap _f (CComma a1 a2) = CComma (fmap (fmap _f) a1) (_f a2)
fmap _f (CAssign a1 a2 a3 a4)
= CAssign a1 (fmap _f a2) (fmap _f a3) (_f a4)
fmap _f (CCond a1 a2 a3 a4)
= CCond (fmap _f a1) (fmap (fmap _f) a2) (fmap _f a3) (_f a4)
fmap _f (CBinary a1 a2 a3 a4)
= CBinary a1 (fmap _f a2) (fmap _f a3) (_f a4)
fmap _f (CCast a1 a2 a3) = CCast (fmap _f a1) (fmap _f a2) (_f a3)
fmap _f (CUnary a1 a2 a3) = CUnary a1 (fmap _f a2) (_f a3)
fmap _f (CSizeofExpr a1 a2) = CSizeofExpr (fmap _f a1) (_f a2)
fmap _f (CSizeofType a1 a2) = CSizeofType (fmap _f a1) (_f a2)
fmap _f (CAlignofExpr a1 a2) = CAlignofExpr (fmap _f a1) (_f a2)
fmap _f (CAlignofType a1 a2) = CAlignofType (fmap _f a1) (_f a2)
fmap _f (CComplexReal a1 a2) = CComplexReal (fmap _f a1) (_f a2)
fmap _f (CComplexImag a1 a2) = CComplexImag (fmap _f a1) (_f a2)
fmap _f (CIndex a1 a2 a3)
= CIndex (fmap _f a1) (fmap _f a2) (_f a3)
fmap _f (CCall a1 a2 a3)
= CCall (fmap _f a1) (fmap (fmap _f) a2) (_f a3)
fmap _f (CMember a1 a2 a3 a4) = CMember (fmap _f a1) a2 a3 (_f a4)
fmap _f (CVar a1 a2) = CVar a1 (_f a2)
fmap _f (CConst a1) = CConst (fmap _f a1)
fmap _f (CCompoundLit a1 a2 a3)
= CCompoundLit (fmap _f a1) (fmapInitList _f a2) (_f a3)
fmap _f (CStatExpr a1 a2) = CStatExpr (fmap _f a1) (_f a2)
fmap _f (CLabAddrExpr a1 a2) = CLabAddrExpr a1 (_f a2)
fmap _f (CBuiltinExpr a1) = CBuiltinExpr (fmap _f a1)
fmap _f (CGenericSelection expr list annot) =
CGenericSelection (fmap _f expr) (map fmap_helper list) (_f annot)
where
fmap_helper (ma1, a2) = (fmap (fmap _f) ma1, fmap _f a2)
-- | GNU Builtins, which cannot be typed in C99
type CBuiltin = CBuiltinThing NodeInfo
data CBuiltinThing a
= CBuiltinVaArg (CExpression a) (CDeclaration a) a -- ^ @(expr, type)@
| CBuiltinOffsetOf (CDeclaration a) [CPartDesignator a] a -- ^ @(type, designator-list)@
| CBuiltinTypesCompatible (CDeclaration a) (CDeclaration a) a -- ^ @(type,type)@
| CBuiltinConvertVector (CExpression a) (CDeclaration a) a -- ^ @(expr, type)@
deriving (Show, Data,Typeable, Generic {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CBuiltinThing a)
-- | C constant (K&R A2.5 & A7.2)
type CConst = CConstant NodeInfo
data CConstant a
= CIntConst CInteger a
| CCharConst CChar a
| CFloatConst CFloat a
| CStrConst CString a
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CConstant a)
-- | Attributed string literals
type CStrLit = CStringLiteral NodeInfo
data CStringLiteral a = CStrLit CString a
deriving (Show, Data,Typeable, Generic, Generic1 {-! ,CNode ,Functor ,Annotated !-})
instance NFData a => NFData (CStringLiteral a)
cstringOfLit :: CStringLiteral a -> CString
cstringOfLit (CStrLit cstr _) = cstr
-- | Lift a string literal to a C constant
liftStrLit :: CStringLiteral a -> CConstant a
liftStrLit (CStrLit str at) = CStrConst str at
-- | All AST nodes are annotated. Inspired by the Annotated
-- class of Niklas Broberg's haskell-src-exts package.
-- In principle, we could have Copointed superclass instead
-- of @ann@, for the price of another dependency.
class (Functor ast) => Annotated ast where
-- | get the annotation of an AST node
annotation :: ast a -> a
-- | change the annotation (non-recursively)
-- of an AST node. Use fmap for recursively
-- modifying the annotation.
amap :: (a->a) -> ast a -> ast a
-- fmap2 :: (a->a') -> (a,b) -> (a',b)
-- fmap2 f (a,b) = (f a, b)
-- Instances generated using derive-2.*
-- GENERATED START
instance CNode t1 => CNode (CTranslationUnit t1) where
nodeInfo (CTranslUnit _ n) = nodeInfo n
instance CNode t1 => Pos (CTranslationUnit t1) where
posOf x = posOf (nodeInfo x)
instance Functor CTranslationUnit where
fmap _f (CTranslUnit a1 a2)
= CTranslUnit (fmap (fmap _f) a1) (_f a2)
instance Annotated CTranslationUnit where
annotation (CTranslUnit _ n) = n
amap f (CTranslUnit a_1 a_2) = CTranslUnit a_1 (f a_2)
instance CNode t1 => CNode (CExternalDeclaration t1) where
nodeInfo (CDeclExt d) = nodeInfo d
nodeInfo (CFDefExt d) = nodeInfo d
nodeInfo (CAsmExt _ n) = nodeInfo n
instance CNode t1 => Pos (CExternalDeclaration t1) where
posOf x = posOf (nodeInfo x)
instance Functor CExternalDeclaration where
fmap _f (CDeclExt a1) = CDeclExt (fmap _f a1)
fmap _f (CFDefExt a1) = CFDefExt (fmap _f a1)
fmap _f (CAsmExt a1 a2) = CAsmExt (fmap _f a1) (_f a2)
instance Annotated CExternalDeclaration where
annotation (CDeclExt n) = annotation n
annotation (CFDefExt n) = annotation n
annotation (CAsmExt _ n) = n
amap f (CDeclExt n) = CDeclExt (amap f n)
amap f (CFDefExt n) = CFDefExt (amap f n)
amap f (CAsmExt a_1 a_2) = CAsmExt a_1 (f a_2)
instance CNode t1 => CNode (CFunctionDef t1) where
nodeInfo (CFunDef _ _ _ _ n) = nodeInfo n
instance CNode t1 => Pos (CFunctionDef t1) where
posOf x = posOf (nodeInfo x)
instance Functor CFunctionDef where
fmap _f (CFunDef a1 a2 a3 a4 a5)
= CFunDef (fmap (fmap _f) a1) (fmap _f a2) (fmap (fmap _f) a3)
(fmap _f a4)
(_f a5)
instance Annotated CFunctionDef where
annotation (CFunDef _ _ _ _ n) = n
amap f (CFunDef a_1 a_2 a_3 a_4 a_5)
= CFunDef a_1 a_2 a_3 a_4 (f a_5)
instance CNode t1 => CNode (CDeclaration t1) where
nodeInfo (CDecl _ _ n) = nodeInfo n
nodeInfo (CStaticAssert _ _ n) = nodeInfo n
instance CNode t1 => Pos (CDeclaration t1) where
posOf x = posOf (nodeInfo x)
instance Annotated CDeclaration where
annotation (CDecl _ _ n) = n
annotation (CStaticAssert _ _ n) = n
amap f (CDecl a_1 a_2 a_3) = CDecl a_1 a_2 (f a_3)
amap f (CStaticAssert a_1 a_2 a_3) = CStaticAssert a_1 a_2 (f a_3)
instance CNode t1 => CNode (CDeclarator t1) where
nodeInfo (CDeclr _ _ _ _ n) = nodeInfo n
instance CNode t1 => Pos (CDeclarator t1) where
posOf x = posOf (nodeInfo x)
instance Functor CDeclarator where
fmap _f (CDeclr a1 a2 a3 a4 a5)
= CDeclr a1 (fmap (fmap _f) a2) (fmap (fmap _f) a3)
(fmap (fmap _f) a4)
(_f a5)
instance Annotated CDeclarator where
annotation (CDeclr _ _ _ _ n) = n
amap f (CDeclr a_1 a_2 a_3 a_4 a_5)
= CDeclr a_1 a_2 a_3 a_4 (f a_5)
instance CNode t1 => CNode (CDerivedDeclarator t1) where
nodeInfo (CPtrDeclr _ n) = nodeInfo n
nodeInfo (CArrDeclr _ _ n) = nodeInfo n
nodeInfo (CFunDeclr _ _ n) = nodeInfo n
instance CNode t1 => Pos (CDerivedDeclarator t1) where
posOf x = posOf (nodeInfo x)
instance Annotated CDerivedDeclarator where
annotation (CPtrDeclr _ n) = n
annotation (CArrDeclr _ _ n) = n
annotation (CFunDeclr _ _ n) = n
amap f (CPtrDeclr a_1 a_2) = CPtrDeclr a_1 (f a_2)
amap f (CArrDeclr a_1 a_2 a_3) = CArrDeclr a_1 a_2 (f a_3)
amap f (CFunDeclr a_1 a_2 a_3) = CFunDeclr a_1 a_2 (f a_3)
instance Functor CArraySize where
fmap _ (CNoArrSize a1) = CNoArrSize a1
fmap _f (CArrSize a1 a2) = CArrSize a1 (fmap _f a2)
instance CNode t1 => CNode (CStatement t1) where
nodeInfo (CLabel _ _ _ n) = nodeInfo n
nodeInfo (CCase _ _ n) = nodeInfo n
nodeInfo (CCases _ _ _ n) = nodeInfo n
nodeInfo (CDefault _ n) = nodeInfo n
nodeInfo (CExpr _ n) = nodeInfo n
nodeInfo (CCompound _ _ n) = nodeInfo n
nodeInfo (CIf _ _ _ n) = nodeInfo n
nodeInfo (CSwitch _ _ n) = nodeInfo n
nodeInfo (CWhile _ _ _ n) = nodeInfo n
nodeInfo (CFor _ _ _ _ n) = nodeInfo n
nodeInfo (CGoto _ n) = nodeInfo n
nodeInfo (CGotoPtr _ n) = nodeInfo n
nodeInfo (CCont d) = nodeInfo d
nodeInfo (CBreak d) = nodeInfo d
nodeInfo (CReturn _ n) = nodeInfo n
nodeInfo (CAsm _ n) = nodeInfo n
instance CNode t1 => Pos (CStatement t1) where
posOf x = posOf (nodeInfo x)
instance Annotated CStatement where
annotation (CLabel _ _ _ n) = n
annotation (CCase _ _ n) = n
annotation (CCases _ _ _ n) = n
annotation (CDefault _ n) = n
annotation (CExpr _ n) = n
annotation (CCompound _ _ n) = n
annotation (CIf _ _ _ n) = n
annotation (CSwitch _ _ n) = n
annotation (CWhile _ _ _ n) = n
annotation (CFor _ _ _ _ n) = n
annotation (CGoto _ n) = n
annotation (CGotoPtr _ n) = n
annotation (CCont n) = n
annotation (CBreak n) = n
annotation (CReturn _ n) = n
annotation (CAsm _ n) = n
amap f (CLabel a_1 a_2 a_3 a_4) = CLabel a_1 a_2 a_3 (f a_4)
amap f (CCase a_1 a_2 a_3) = CCase a_1 a_2 (f a_3)
amap f (CCases a_1 a_2 a_3 a_4) = CCases a_1 a_2 a_3 (f a_4)
amap f (CDefault a_1 a_2) = CDefault a_1 (f a_2)
amap f (CExpr a_1 a_2) = CExpr a_1 (f a_2)
amap f (CCompound a_1 a_2 a_3) = CCompound a_1 a_2 (f a_3)
amap f (CIf a_1 a_2 a_3 a_4) = CIf a_1 a_2 a_3 (f a_4)
amap f (CSwitch a_1 a_2 a_3) = CSwitch a_1 a_2 (f a_3)
amap f (CWhile a_1 a_2 a_3 a_4) = CWhile a_1 a_2 a_3 (f a_4)
amap f (CFor a_1 a_2 a_3 a_4 a_5) = CFor a_1 a_2 a_3 a_4 (f a_5)
amap f (CGoto a_1 a_2) = CGoto a_1 (f a_2)
amap f (CGotoPtr a_1 a_2) = CGotoPtr a_1 (f a_2)
amap f (CCont a_1) = CCont (f a_1)
amap f (CBreak a_1) = CBreak (f a_1)
amap f (CReturn a_1 a_2) = CReturn a_1 (f a_2)
amap f (CAsm a_1 a_2) = CAsm a_1 (f a_2)
instance CNode t1 => CNode (CAssemblyStatement t1) where
nodeInfo (CAsmStmt _ _ _ _ _ n) = nodeInfo n
instance CNode t1 => Pos (CAssemblyStatement t1) where
posOf x = posOf (nodeInfo x)
instance Functor CAssemblyStatement where
fmap _f (CAsmStmt a1 a2 a3 a4 a5 a6)
= CAsmStmt (fmap (fmap _f) a1) (fmap _f a2) (fmap (fmap _f) a3)
(fmap (fmap _f) a4)
(fmap (fmap _f) a5)
(_f a6)
instance Annotated CAssemblyStatement where
annotation (CAsmStmt _ _ _ _ _ n) = n
amap f (CAsmStmt a_1 a_2 a_3 a_4 a_5 a_6)
= CAsmStmt a_1 a_2 a_3 a_4 a_5 (f a_6)
instance CNode t1 => CNode (CAssemblyOperand t1) where
nodeInfo (CAsmOperand _ _ _ n) = nodeInfo n
instance CNode t1 => Pos (CAssemblyOperand t1) where
posOf x = posOf (nodeInfo x)
instance Functor CAssemblyOperand where
fmap _f (CAsmOperand a1 a2 a3 a4)
= CAsmOperand a1 (fmap _f a2) (fmap _f a3) (_f a4)
instance Annotated CAssemblyOperand where
annotation (CAsmOperand _ _ _ n) = n
amap f (CAsmOperand a_1 a_2 a_3 a_4)
= CAsmOperand a_1 a_2 a_3 (f a_4)
instance CNode t1 => CNode (CCompoundBlockItem t1) where
nodeInfo (CBlockStmt d) = nodeInfo d
nodeInfo (CBlockDecl d) = nodeInfo d
nodeInfo (CNestedFunDef d) = nodeInfo d
instance CNode t1 => Pos (CCompoundBlockItem t1) where
posOf x = posOf (nodeInfo x)
instance Functor CCompoundBlockItem where