{-# LANGUAGE DeriveDataTypeable #-} ----------------------------------------------------------------------------- -- | -- 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 and several -- GNU extensions . ----------------------------------------------------------------------------- module Language.C.Syntax.AST ( -- * C translation units CTranslUnit(..), CExtDecl(..), -- * Declarations CFunDef(..), CDecl(..), CStructUnion(..), CStructTag(..), CEnum(..), -- * Declaration attributes CDeclSpec(..), partitionDeclSpecs, CStorageSpec(..), CTypeSpec(..), isSUEDef, CTypeQual(..), CAttr(..), -- * Declarators CDeclr(..),CDerivedDeclr(..),CArrSize(..), -- * Initialization CInit(..), CInitList, CDesignator(..), -- * Statements CStat(..), CBlockItem(..), CAsmStmt(..), CAsmOperand(..), -- * Expressions CExpr(..), CAssignOp(..), CBinaryOp(..), CUnaryOp(..), CBuiltin(..), -- * Constants CConst(..),CStrLit(..),cstringOfLit,liftStrLit, ) where import Data.List 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.Generics -- | 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. data CTranslUnit = CTranslUnit [CExtDecl] NodeInfo deriving (Data,Typeable {-! CNode !-}) -- | External C declaration (C99 6.9, K&R A10) -- -- Either a toplevel declaration, function definition or external assembler. data CExtDecl = CDeclExt CDecl | CFDefExt CFunDef | CAsmExt CStrLit deriving (Data,Typeable {-! CNode !-}) -- | 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. data CFunDef = CFunDef [CDeclSpec] -- type specifier and qualifier CDeclr -- declarator [CDecl] -- optional declaration list CStat -- compound statement NodeInfo deriving (Data,Typeable {-! CNode !-}) -- | 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) -- data CDecl = CDecl [CDeclSpec] -- type specifier and qualifier, __attribute__ [(Maybe CDeclr, -- declarator (may be omitted) Maybe CInit, -- optional initialize Maybe CExpr)] -- optional size (const expr) NodeInfo deriving (Data,Typeable {-! CNode !-}) -- | 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 []] data CDeclr = CDeclr (Maybe Ident) [CDerivedDeclr] (Maybe CStrLit) [CAttr] NodeInfo deriving (Data,Typeable {-! CNode !-}) -- | 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)@ data CDerivedDeclr = CPtrDeclr [CTypeQual] NodeInfo -- ^ Pointer declarator @CPtrDeclr tyquals declr@ | CArrDeclr [CTypeQual] (CArrSize) NodeInfo -- ^ Array declarator @CArrDeclr declr tyquals size-expr?@ | CFunDeclr (Either [Ident] ([CDecl],Bool)) [CAttr] NodeInfo -- ^ Function declarator @CFunDeclr declr (old-style-params | new-style-params) c-attrs@ deriving (Data,Typeable {-! CNode !-}) -- | Size of an array data CArrSize = CNoArrSize Bool -- ^ @CUnknownSize isCompleteType@ | CArrSize Bool CExpr -- ^ @CArrSize isStatic expr@ deriving (Data,Typeable) -- | C statement (K&R A9, C99 6.8) -- data CStat = CLabel Ident CStat [CAttr] NodeInfo -- ^ An (attributed) label followed by a statement | CCase CExpr CStat NodeInfo -- ^ A statement of the form @case expr : stmt@ | CCases CExpr CExpr CStat NodeInfo -- ^ A case range of the form @case lower ... upper : stmt@ | CDefault CStat NodeInfo -- ^ The default case @default : stmt@ | CExpr (Maybe CExpr) NodeInfo -- ^ A simple statement, that is in C: evaluating an expression with side-effects -- and discarding the result. | CCompound [Ident] [CBlockItem] NodeInfo -- ^ compound statement @CCompound localLabels blockItems at@ | CIf CExpr CStat (Maybe CStat) NodeInfo -- ^ conditional statement @CIf ifExpr thenStmt maybeElseStmt at@ | CSwitch CExpr CStat NodeInfo -- ^ switch statement @CSwitch selectorExpr switchStmt@, where @switchStmt@ usually includes -- /case/, /break/ and /default/ statements | CWhile CExpr CStat Bool NodeInfo -- ^ while or do-while statement @CWhile guard stmt isDoWhile at@ | CFor (Either (Maybe CExpr) CDecl) (Maybe CExpr) (Maybe CExpr) CStat NodeInfo -- ^ for statement @CFor init expr-2 expr-3 stmt@, where @init@ is either a declaration or -- initializing expression | CGoto Ident NodeInfo -- ^ goto statement @CGoto label@ | CGotoPtr CExpr NodeInfo -- ^ computed goto @CGotoPtr labelExpr@ | CCont NodeInfo -- ^ continue statement | CBreak NodeInfo -- ^ break statement | CReturn (Maybe CExpr)NodeInfo -- ^ return statement @CReturn returnExpr@ | CAsm CAsmStmt NodeInfo -- ^ assembly statement deriving (Data,Typeable {-! CNode !-}) -- | GNU Assembler statement -- -- > CAsmStatement 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 data CAsmStmt = CAsmStmt (Maybe CTypeQual) -- maybe volatile CStrLit -- assembler expression (String) [CAsmOperand] -- output operands [CAsmOperand] -- input operands [CStrLit] -- Clobbers NodeInfo deriving (Data,Typeable {-! CNode !-}) -- | Assembler operand -- -- @CAsmOperand argName? constraintExpr arg@ specifies an operand for an assembler -- statement. data CAsmOperand = CAsmOperand (Maybe Ident) -- argument name CStrLit -- constraint expr CExpr -- argument NodeInfo deriving (Data,Typeable {-! CNode !-}) -- | C99 Block items -- -- Things that may appear in compound statements: either statements, declarations -- or nested function definitions. data CBlockItem = CBlockStmt CStat -- ^ A statement | CBlockDecl CDecl -- ^ A local declaration | CNestedFunDef CFunDef -- ^ A nested function (GNU C) deriving (Data,Typeable {-! CNode !-}) -- | 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). data CDeclSpec = CStorageSpec CStorageSpec -- ^ storage-class specifier or typedef | CTypeSpec CTypeSpec -- ^ type name | CTypeQual CTypeQual -- ^ type qualifier deriving (Data,Typeable {-! CNode !-}) -- | Seperate the declaration specifiers -- -- Note that inline isn't actually a type qualifier, but a function specifier. -- @__attribute__@ of a declaration qualify declarations or declarators (but not types), -- and are therefore seperated as well. partitionDeclSpecs :: [CDeclSpec] -> ([CStorageSpec], [CAttr], [CTypeQual], [CTypeSpec], Bool) partitionDeclSpecs = foldr deals ([],[],[],[],False) where deals (CTypeQual (CInlineQual _)) (sts,ats,tqs,tss,_) = (sts,ats,tqs,tss,True) deals (CStorageSpec sp) (sts,ats,tqs,tss,inline) = (sp:sts,ats,tqs,tss,inline) deals (CTypeQual (CAttrQual attr)) (sts,ats,tqs,tss,inline) = (sts,attr:ats,tqs,tss,inline) deals (CTypeQual tq) (sts,ats,tqs,tss,inline) = (sts,ats,tq:tqs,tss,inline) deals (CTypeSpec ts) (sts,ats,tqs,tss,inline) = (sts,ats,tqs,ts:tss,inline) -- | C storage class specifier (and typedefs) (K&R A8.1, C99 6.7.1) data CStorageSpec = CAuto NodeInfo -- ^ auto | CRegister NodeInfo -- ^ register | CStatic NodeInfo -- ^ static | CExtern NodeInfo -- ^ extern | CTypedef NodeInfo -- ^ typedef | CThread NodeInfo -- ^ GNUC thread local storage deriving (Eq,Ord,Data,Typeable {-! CNode !-}) -- Compatibility instance (will be removed) so we do not violate the PvP for 0.3.2 instance Show CStorageSpec where show (CAuto _) = "auto" show (CRegister _) = "register" show (CStatic _) = "static" show (CExtern _) = "extern" show (CTypedef _) = "typedef" show (CThread _) = "__thread" -- | 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. data CTypeSpec = CVoidType NodeInfo | CCharType NodeInfo | CShortType NodeInfo | CIntType NodeInfo | CLongType NodeInfo | CFloatType NodeInfo | CDoubleType NodeInfo | CSignedType NodeInfo | CUnsigType NodeInfo | CBoolType NodeInfo | CComplexType NodeInfo | CSUType CStructUnion NodeInfo -- ^ Struct or Union specifier | CEnumType CEnum NodeInfo -- ^ Enumeration specifier | CTypeDef Ident NodeInfo -- ^ Typedef name | CTypeOfExpr CExpr NodeInfo -- ^ @typeof(expr)@ | CTypeOfType CDecl NodeInfo -- ^ @typeof(type)@ deriving (Data,Typeable {-! CNode !-}) -- | returns @True@ if the given typespec is a struct, union or enum /definition/ isSUEDef :: CTypeSpec -> Bool isSUEDef (CSUType (CStruct _ _ (Just _) _ _) _) = True isSUEDef (CEnumType (CEnum _ (Just _) _ _) _) = True isSUEDef _ = False -- | C type qualifiers (K&R A8.2, C99 6.7.3), function specifiers (C99 6.7.4), and attributes. -- -- @const@, @volatile@ and @restrict@ type qualifiers and @inline@ function specifier. -- Additionally, @__attribute__@ annotations for declarations and declarators. data CTypeQual = CConstQual NodeInfo | CVolatQual NodeInfo | CRestrQual NodeInfo | CInlineQual NodeInfo | CAttrQual CAttr deriving (Data,Typeable {-! CNode !-}) -- | 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 data CStructUnion = CStruct CStructTag (Maybe Ident) (Maybe [CDecl]) -- member declarations [CAttr] -- __attribute__s NodeInfo deriving (Data,Typeable {-! CNode !-}) -- | A tag to determine wheter we refer to a @struct@ or @union@, see 'CStructUnion'. data CStructTag = CStructTag | CUnionTag deriving (Eq,Data,Typeable) -- | 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 data CEnum = CEnum (Maybe Ident) (Maybe [(Ident, -- variant name Maybe CExpr)]) -- explicit variant value [CAttr] -- __attribute__s NodeInfo deriving (Data,Typeable {-! CNode !-}) -- | 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. data CInit = CInitExpr CExpr NodeInfo -- ^ assignment expression | CInitList CInitList NodeInfo -- ^ initialization list (see 'CInitList') deriving (Data,Typeable {-! CNode !-}) -- | 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 = [([CDesignator], CInit)] -- | 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. data CDesignator = CArrDesig CExpr NodeInfo -- ^ array position designator | CMemberDesig Ident NodeInfo -- ^ member designator | CRangeDesig CExpr CExpr NodeInfo -- ^ array range designator @CRangeDesig from to _@ (GNU C) deriving (Data,Typeable {-! CNode !-}) -- | @__attribute__@ annotations -- -- Those are of the form @CAttr attribute-name attribute-parameters@, -- and serve as generic properties of some syntax tree elements. data CAttr = CAttr Ident [CExpr] NodeInfo deriving (Data,Typeable {-! CNode !-}) -- | 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 -- data CExpr = CComma [CExpr] -- comma expression list, n >= 2 NodeInfo | CAssign CAssignOp -- assignment operator CExpr -- l-value CExpr -- r-value NodeInfo | CCond CExpr -- conditional (Maybe CExpr) -- true-expression (GNU allows omitting) CExpr -- false-expression NodeInfo | CBinary CBinaryOp -- binary operator CExpr -- lhs CExpr -- rhs NodeInfo | CCast CDecl -- type name CExpr NodeInfo | CUnary CUnaryOp -- unary operator CExpr NodeInfo | CSizeofExpr CExpr NodeInfo | CSizeofType CDecl -- type name NodeInfo | CAlignofExpr CExpr NodeInfo | CAlignofType CDecl -- type name NodeInfo | CComplexReal CExpr -- real part of complex number NodeInfo | CComplexImag CExpr -- imaginary part of complex number NodeInfo | CIndex CExpr -- array CExpr -- index NodeInfo | CCall CExpr -- function [CExpr] -- arguments NodeInfo | CMember CExpr -- structure Ident -- member name Bool -- deref structure? (True for `->') NodeInfo | CVar Ident -- identifier (incl. enumeration const) NodeInfo | CConst CConst -- ^ integer, character, floating point and string constants | CCompoundLit CDecl CInitList -- type name & initialiser list NodeInfo -- ^ C99 compound literal | CStatExpr CStat NodeInfo -- ^ GNU C compound statement as expr | CLabAddrExpr Ident NodeInfo -- ^ GNU C address of label | CBuiltinExpr CBuiltin -- ^ builtin expressions, see 'CBuiltin' deriving (Data,Typeable {-! CNode !-}) -- | GNU Builtins, which cannot be typed in C99 data CBuiltin = CBuiltinVaArg CExpr CDecl NodeInfo -- ^ @(expr, type)@ | CBuiltinOffsetOf CDecl [CDesignator] NodeInfo -- ^ @(type, designator-list)@ | CBuiltinTypesCompatible CDecl CDecl NodeInfo -- ^ @(type,type)@ deriving (Data,Typeable {-! CNode !-}) -- | C constant (K&R A2.5 & A7.2) data CConst = CIntConst CInteger NodeInfo | CCharConst CChar NodeInfo | CFloatConst CFloat NodeInfo | CStrConst CString NodeInfo deriving (Data,Typeable {-! CNode !-}) -- | Attributed string literals data CStrLit = CStrLit CString NodeInfo deriving (Data,Typeable {-! CNode !-}) cstringOfLit :: CStrLit -> CString cstringOfLit (CStrLit cstr _) = cstr -- | Lift a string literal to a C constant liftStrLit :: CStrLit -> CConst liftStrLit (CStrLit str at) = CStrConst str at -------------------------------------------------------- -- DERIVES GENERATED CODE -- DO NOT MODIFY BELOW THIS LINE -- CHECKSUM: 1181183062 instance CNode CTranslUnit where nodeInfo (CTranslUnit _ nodeinfo) = nodeinfo instance Pos CTranslUnit where posOf x = posOfNode (nodeInfo x) instance CNode CExtDecl where nodeInfo (CDeclExt d) = nodeInfo d nodeInfo (CFDefExt d) = nodeInfo d nodeInfo (CAsmExt d) = nodeInfo d instance Pos CExtDecl where posOf x = posOfNode (nodeInfo x) instance CNode CFunDef where nodeInfo (CFunDef _ _ _ _ nodeinfo) = nodeinfo instance Pos CFunDef where posOf x = posOfNode (nodeInfo x) instance CNode CDecl where nodeInfo (CDecl _ _ nodeinfo) = nodeinfo instance Pos CDecl where posOf x = posOfNode (nodeInfo x) instance CNode CDeclr where nodeInfo (CDeclr _ _ _ _ nodeinfo) = nodeinfo instance Pos CDeclr where posOf x = posOfNode (nodeInfo x) instance CNode CDerivedDeclr where nodeInfo (CPtrDeclr _ nodeinfo) = nodeinfo nodeInfo (CArrDeclr _ _ nodeinfo) = nodeinfo nodeInfo (CFunDeclr _ _ nodeinfo) = nodeinfo instance Pos CDerivedDeclr where posOf x = posOfNode (nodeInfo x) instance CNode CStat where nodeInfo (CLabel _ _ _ nodeinfo) = nodeinfo nodeInfo (CCase _ _ nodeinfo) = nodeinfo nodeInfo (CCases _ _ _ nodeinfo) = nodeinfo nodeInfo (CDefault _ nodeinfo) = nodeinfo nodeInfo (CExpr _ nodeinfo) = nodeinfo nodeInfo (CCompound _ _ nodeinfo) = nodeinfo nodeInfo (CIf _ _ _ nodeinfo) = nodeinfo nodeInfo (CSwitch _ _ nodeinfo) = nodeinfo nodeInfo (CWhile _ _ _ nodeinfo) = nodeinfo nodeInfo (CFor _ _ _ _ nodeinfo) = nodeinfo nodeInfo (CGoto _ nodeinfo) = nodeinfo nodeInfo (CGotoPtr _ nodeinfo) = nodeinfo nodeInfo (CCont nodeinfo) = nodeinfo nodeInfo (CBreak nodeinfo) = nodeinfo nodeInfo (CReturn _ nodeinfo) = nodeinfo nodeInfo (CAsm _ nodeinfo) = nodeinfo instance Pos CStat where posOf x = posOfNode (nodeInfo x) instance CNode CAsmStmt where nodeInfo (CAsmStmt _ _ _ _ _ nodeinfo) = nodeinfo instance Pos CAsmStmt where posOf x = posOfNode (nodeInfo x) instance CNode CAsmOperand where nodeInfo (CAsmOperand _ _ _ nodeinfo) = nodeinfo instance Pos CAsmOperand where posOf x = posOfNode (nodeInfo x) instance CNode CBlockItem where nodeInfo (CBlockStmt d) = nodeInfo d nodeInfo (CBlockDecl d) = nodeInfo d nodeInfo (CNestedFunDef d) = nodeInfo d instance Pos CBlockItem where posOf x = posOfNode (nodeInfo x) instance CNode CDeclSpec where nodeInfo (CStorageSpec d) = nodeInfo d nodeInfo (CTypeSpec d) = nodeInfo d nodeInfo (CTypeQual d) = nodeInfo d instance Pos CDeclSpec where posOf x = posOfNode (nodeInfo x) instance CNode CStorageSpec where nodeInfo (CAuto nodeinfo) = nodeinfo nodeInfo (CRegister nodeinfo) = nodeinfo nodeInfo (CStatic nodeinfo) = nodeinfo nodeInfo (CExtern nodeinfo) = nodeinfo nodeInfo (CTypedef nodeinfo) = nodeinfo nodeInfo (CThread nodeinfo) = nodeinfo instance Pos CStorageSpec where posOf x = posOfNode (nodeInfo x) instance CNode CTypeSpec where nodeInfo (CVoidType nodeinfo) = nodeinfo nodeInfo (CCharType nodeinfo) = nodeinfo nodeInfo (CShortType nodeinfo) = nodeinfo nodeInfo (CIntType nodeinfo) = nodeinfo nodeInfo (CLongType nodeinfo) = nodeinfo nodeInfo (CFloatType nodeinfo) = nodeinfo nodeInfo (CDoubleType nodeinfo) = nodeinfo nodeInfo (CSignedType nodeinfo) = nodeinfo nodeInfo (CUnsigType nodeinfo) = nodeinfo nodeInfo (CBoolType nodeinfo) = nodeinfo nodeInfo (CComplexType nodeinfo) = nodeinfo nodeInfo (CSUType _ nodeinfo) = nodeinfo nodeInfo (CEnumType _ nodeinfo) = nodeinfo nodeInfo (CTypeDef _ nodeinfo) = nodeinfo nodeInfo (CTypeOfExpr _ nodeinfo) = nodeinfo nodeInfo (CTypeOfType _ nodeinfo) = nodeinfo instance Pos CTypeSpec where posOf x = posOfNode (nodeInfo x) instance CNode CTypeQual where nodeInfo (CConstQual nodeinfo) = nodeinfo nodeInfo (CVolatQual nodeinfo) = nodeinfo nodeInfo (CRestrQual nodeinfo) = nodeinfo nodeInfo (CInlineQual nodeinfo) = nodeinfo nodeInfo (CAttrQual d) = nodeInfo d instance Pos CTypeQual where posOf x = posOfNode (nodeInfo x) instance CNode CStructUnion where nodeInfo (CStruct _ _ _ _ nodeinfo) = nodeinfo instance Pos CStructUnion where posOf x = posOfNode (nodeInfo x) instance CNode CEnum where nodeInfo (CEnum _ _ _ nodeinfo) = nodeinfo instance Pos CEnum where posOf x = posOfNode (nodeInfo x) instance CNode CInit where nodeInfo (CInitExpr _ nodeinfo) = nodeinfo nodeInfo (CInitList _ nodeinfo) = nodeinfo instance Pos CInit where posOf x = posOfNode (nodeInfo x) instance CNode CDesignator where nodeInfo (CArrDesig _ nodeinfo) = nodeinfo nodeInfo (CMemberDesig _ nodeinfo) = nodeinfo nodeInfo (CRangeDesig _ _ nodeinfo) = nodeinfo instance Pos CDesignator where posOf x = posOfNode (nodeInfo x) instance CNode CAttr where nodeInfo (CAttr _ _ nodeinfo) = nodeinfo instance Pos CAttr where posOf x = posOfNode (nodeInfo x) instance CNode CExpr where nodeInfo (CComma _ nodeinfo) = nodeinfo nodeInfo (CAssign _ _ _ nodeinfo) = nodeinfo nodeInfo (CCond _ _ _ nodeinfo) = nodeinfo nodeInfo (CBinary _ _ _ nodeinfo) = nodeinfo nodeInfo (CCast _ _ nodeinfo) = nodeinfo nodeInfo (CUnary _ _ nodeinfo) = nodeinfo nodeInfo (CSizeofExpr _ nodeinfo) = nodeinfo nodeInfo (CSizeofType _ nodeinfo) = nodeinfo nodeInfo (CAlignofExpr _ nodeinfo) = nodeinfo nodeInfo (CAlignofType _ nodeinfo) = nodeinfo nodeInfo (CComplexReal _ nodeinfo) = nodeinfo nodeInfo (CComplexImag _ nodeinfo) = nodeinfo nodeInfo (CIndex _ _ nodeinfo) = nodeinfo nodeInfo (CCall _ _ nodeinfo) = nodeinfo nodeInfo (CMember _ _ _ nodeinfo) = nodeinfo nodeInfo (CVar _ nodeinfo) = nodeinfo nodeInfo (CConst d) = nodeInfo d nodeInfo (CCompoundLit _ _ nodeinfo) = nodeinfo nodeInfo (CStatExpr _ nodeinfo) = nodeinfo nodeInfo (CLabAddrExpr _ nodeinfo) = nodeinfo nodeInfo (CBuiltinExpr d) = nodeInfo d instance Pos CExpr where posOf x = posOfNode (nodeInfo x) instance CNode CBuiltin where nodeInfo (CBuiltinVaArg _ _ nodeinfo) = nodeinfo nodeInfo (CBuiltinOffsetOf _ _ nodeinfo) = nodeinfo nodeInfo (CBuiltinTypesCompatible _ _ nodeinfo) = nodeinfo instance Pos CBuiltin where posOf x = posOfNode (nodeInfo x) instance CNode CConst where nodeInfo (CIntConst _ nodeinfo) = nodeinfo nodeInfo (CCharConst _ nodeinfo) = nodeinfo nodeInfo (CFloatConst _ nodeinfo) = nodeinfo nodeInfo (CStrConst _ nodeinfo) = nodeinfo instance Pos CConst where posOf x = posOfNode (nodeInfo x) instance CNode CStrLit where nodeInfo (CStrLit _ nodeinfo) = nodeinfo instance Pos CStrLit where posOf x = posOfNode (nodeInfo x)