language-c-0.10.0: src/Language/C/Analysis/SemRep.hs
{-# LANGUAGE DeriveDataTypeable #-}
-----------------------------------------------------------------------------
-- |
-- Module : Language.C.Analysis.Syntax
-- Copyright : (c) 2008 Benedikt Huber
-- License : BSD-style
-- Maintainer : benedikt.huber@gmail.com
-- Stability : alpha
-- Portability : ghc
--
-- This module contains definitions for representing C translation units.
-- In contrast to 'Language.C.Syntax.AST', the representation tries to express the semantics of
-- of a translation unit.
---------------------------------------------------------------------------------------------------
module Language.C.Analysis.SemRep(
-- * Sums of tags and identifiers
TagDef(..),typeOfTagDef,
Declaration(..),declIdent,declName,declType,declAttrs,
IdentDecl(..),objKindDescr, splitIdentDecls,
-- * Global definitions
GlobalDecls(..),emptyGlobalDecls,filterGlobalDecls,mergeGlobalDecls,
-- * Events for visitors
DeclEvent(..),
-- * Declarations and definitions
Decl(..),
ObjDef(..),isTentative,
FunDef(..),
ParamDecl(..),MemberDecl(..),
TypeDef(..),identOfTypeDef,
VarDecl(..),
-- * Declaration attributes
DeclAttrs(..),isExtDecl,
FunctionAttrs(..), functionAttrs, noFunctionAttrs,
Storage(..),declStorage,ThreadLocal,Register,
Linkage(..),hasLinkage,declLinkage,
-- * Types
Type(..),
FunType(..),
ArraySize(..),
TypeDefRef(..),
TypeName(..),BuiltinType(..),
IntType(..),FloatType(..),
HasSUERef(..),HasCompTyKind(..),
CompTypeRef(..),CompType(..),typeOfCompDef,CompTyKind(..),
EnumTypeRef(..),EnumType(..),typeOfEnumDef,
Enumerator(..),
TypeQuals(..),noTypeQuals,mergeTypeQuals,
-- * Variable names
VarName(..),identOfVarName,isNoName,AsmName,
-- * Attributes (STUB, not yet analyzed)
Attr(..),Attributes,noAttributes,mergeAttributes,
-- * Statements and Expressions (STUB, aliases to Syntax)
Stmt,Expr,Initializer,AsmBlock,
)
where
import Language.C.Data
import Language.C.Syntax
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe
import Data.Data (Data)
-- | accessor class : struct\/union\/enum names
class HasSUERef a where
sueRef :: a -> SUERef
-- | accessor class : composite type tags (struct or union)
class HasCompTyKind a where
compTag :: a -> CompTyKind
-- | Composite type definitions (tags)
data TagDef = CompDef CompType --composite definition
| EnumDef EnumType --enum definition
deriving (Data {-! ,CNode !-}, Show)
instance HasSUERef TagDef where
sueRef (CompDef ct) = sueRef ct
sueRef (EnumDef et) = sueRef et
-- | return the type corresponding to a tag definition
typeOfTagDef :: TagDef -> TypeName
typeOfTagDef (CompDef comptype) = typeOfCompDef comptype
typeOfTagDef (EnumDef enumtype) = typeOfEnumDef enumtype
-- | All datatypes aggregating a declaration are instances of @Declaration@
class Declaration n where
-- | get the name, type and declaration attributes of a declaration or definition
getVarDecl :: n -> VarDecl
-- | get the declaration corresponding to a definition
declOfDef :: (Declaration n, CNode n) => n -> Decl
declOfDef def = let vd = getVarDecl def in Decl vd (nodeInfo def)
-- | get the variable identifier of a declaration (only safe if the
-- the declaration is known to have a name)
declIdent :: (Declaration n) => n -> Ident
declIdent = identOfVarName . declName
-- | get the variable name of a @Declaration@
declName :: (Declaration n) => n -> VarName
declName = (\(VarDecl n _ _) -> n) . getVarDecl
-- | get the type of a @Declaration@
declType :: (Declaration n) => n -> Type
declType = (\(VarDecl _ _ ty) -> ty) . getVarDecl
-- | get the declaration attributes of a @Declaration@
declAttrs :: (Declaration n) => n -> DeclAttrs
declAttrs = (\(VarDecl _ specs _) -> specs) . getVarDecl
instance (Declaration a, Declaration b) => Declaration (Either a b) where
getVarDecl = either getVarDecl getVarDecl
-- | identifiers, typedefs and enumeration constants (namespace sum)
data IdentDecl = Declaration Decl -- ^ object or function declaration
| ObjectDef ObjDef -- ^ object definition
| FunctionDef FunDef -- ^ function definition
| EnumeratorDef Enumerator -- ^ definition of an enumerator
deriving (Data {-! ,CNode !-}, Show)
instance Declaration IdentDecl where
getVarDecl (Declaration decl) = getVarDecl decl
getVarDecl (ObjectDef def) = getVarDecl def
getVarDecl (FunctionDef def) = getVarDecl def
getVarDecl (EnumeratorDef def) = getVarDecl def
-- | textual description of the kind of an object
objKindDescr :: IdentDecl -> String
objKindDescr (Declaration _ ) = "declaration"
objKindDescr (ObjectDef _) = "object definition"
objKindDescr (FunctionDef _) = "function definition"
objKindDescr (EnumeratorDef _) = "enumerator definition"
-- | @splitIdentDecls includeAllDecls@ splits a map of object, function and enumerator declarations and definitions into one map
-- holding declarations, and three maps for object definitions, enumerator definitions and function definitions.
-- If @includeAllDecls@ is @True@ all declarations are present in the first map, otherwise only those where no corresponding definition
-- is available.
splitIdentDecls :: Bool -> Map Ident IdentDecl -> (Map Ident Decl,
( Map Ident Enumerator,
Map Ident ObjDef,
Map Ident FunDef ) )
splitIdentDecls include_all = Map.foldrWithKey (if include_all then deal else deal') (Map.empty,(Map.empty,Map.empty,Map.empty))
where
deal ident entry (decls,defs) = (Map.insert ident (declOfDef entry) decls, addDef ident entry defs)
deal' ident (Declaration d) (decls,defs) = (Map.insert ident d decls,defs)
deal' ident def (decls,defs) = (decls, addDef ident def defs)
addDef ident entry (es,os,fs) =
case entry of
Declaration _ -> (es,os,fs)
EnumeratorDef e -> (Map.insert ident e es,os,fs)
ObjectDef o -> (es,Map.insert ident o os,fs)
FunctionDef f -> (es, os,Map.insert ident f fs)
-- | global declaration\/definition table returned by the analysis
data GlobalDecls = GlobalDecls {
gObjs :: Map Ident IdentDecl,
gTags :: Map SUERef TagDef,
gTypeDefs :: Map Ident TypeDef
}
-- | empty global declaration table
emptyGlobalDecls :: GlobalDecls
emptyGlobalDecls = GlobalDecls Map.empty Map.empty Map.empty
-- | filter global declarations
filterGlobalDecls :: (DeclEvent -> Bool) -> GlobalDecls -> GlobalDecls
filterGlobalDecls decl_filter gmap = GlobalDecls
{
gObjs = Map.filter (decl_filter . DeclEvent) (gObjs gmap),
gTags = Map.filter (decl_filter . TagEvent) (gTags gmap),
gTypeDefs = Map.filter (decl_filter . TypeDefEvent) (gTypeDefs gmap)
}
-- | merge global declarations
mergeGlobalDecls :: GlobalDecls -> GlobalDecls -> GlobalDecls
mergeGlobalDecls gmap1 gmap2 = GlobalDecls
{
gObjs = Map.union (gObjs gmap1) (gObjs gmap2),
gTags = Map.union (gTags gmap1) (gTags gmap2),
gTypeDefs = Map.union (gTypeDefs gmap1) (gTypeDefs gmap2)
}
-- * Events
-- | Declaration events
--
-- Those events are reported to callbacks, which are executed during the traversal.
data DeclEvent =
TagEvent TagDef
-- ^ file-scope struct\/union\/enum event
| DeclEvent IdentDecl
-- ^ file-scope declaration or definition
| ParamEvent ParamDecl
-- ^ parameter declaration
| LocalEvent IdentDecl
-- ^ local variable declaration or definition
| TypeDefEvent TypeDef
-- ^ a type definition
| AsmEvent AsmBlock
-- ^ assembler block
deriving ({-! CNode !-})
-- * Declarations and definitions
-- | Declarations, which aren't definitions
data Decl = Decl VarDecl NodeInfo
deriving (Data {-! ,CNode !-}, Show)
instance Declaration Decl where
getVarDecl (Decl vd _) = vd
-- | Object Definitions
--
-- An object definition is a declaration together with an initializer.
--
-- If the initializer is missing, it is a tentative definition, i.e. a
-- definition which might be overriden later on.
data ObjDef = ObjDef VarDecl (Maybe Initializer) NodeInfo
deriving (Data {-! ,CNode !-}, Show)
instance Declaration ObjDef where
getVarDecl (ObjDef vd _ _) = vd
-- | Returns @True@ if the given object definition is tentative.
isTentative :: ObjDef -> Bool
isTentative (ObjDef decl init_opt _) | isExtDecl decl = isNothing init_opt
| otherwise = False
-- | Function definitions
--
-- A function definition is a declaration together with a statement (the function body).
data FunDef = FunDef VarDecl Stmt NodeInfo
deriving (Data {-! ,CNode !-}, Show)
instance Declaration FunDef where
getVarDecl (FunDef vd _ _) = vd
-- | Parameter declaration
data ParamDecl = ParamDecl VarDecl NodeInfo
| AbstractParamDecl VarDecl NodeInfo
deriving (Data {-! ,CNode !-}, Show)
instance Declaration ParamDecl where
getVarDecl (ParamDecl vd _) = vd
getVarDecl (AbstractParamDecl vd _) = vd
-- | Struct\/Union member declaration
data MemberDecl = MemberDecl VarDecl (Maybe Expr) NodeInfo
-- ^ @MemberDecl vardecl bitfieldsize node@
| AnonBitField Type Expr NodeInfo
-- ^ @AnonBitField typ size@
deriving (Data {-! ,CNode !-}, Show)
instance Declaration MemberDecl where
getVarDecl (MemberDecl vd _ _) = vd
getVarDecl (AnonBitField ty _ _) = VarDecl NoName (DeclAttrs noFunctionAttrs NoStorage []) ty
-- | @typedef@ definitions.
--
-- The identifier is a new name for the given type.
data TypeDef = TypeDef Ident Type Attributes NodeInfo
deriving (Data {-! ,CNode !-}, Show)
-- | return the idenitifier of a @typedef@
identOfTypeDef :: TypeDef -> Ident
identOfTypeDef (TypeDef ide _ _ _) = ide
-- | Generic variable declarations
data VarDecl = VarDecl VarName DeclAttrs Type
deriving (Data, Show)
instance Declaration VarDecl where
getVarDecl = id
-- @isExtDecl d@ returns true if the declaration has /linkage/
isExtDecl :: (Declaration n) => n -> Bool
isExtDecl = hasLinkage . declStorage
-- | Declaration attributes of the form @DeclAttrs isInlineFunction storage linkage attrs@
--
-- They specify the storage and linkage of a declared object.
data DeclAttrs = DeclAttrs FunctionAttrs Storage Attributes
-- ^ @DeclAttrs fspecs storage attrs@
deriving (Data, Show)
-- | get the 'Storage' of a declaration
declStorage :: (Declaration d) => d -> Storage
declStorage d = case declAttrs d of (DeclAttrs _ st _) -> st
-- | get the `function attributes' of a declaration
functionAttrs :: (Declaration d) => d -> FunctionAttrs
functionAttrs d = case declAttrs d of (DeclAttrs fa _ _) -> fa
-- Function attributes (inline, noreturn)
data FunctionAttrs = FunctionAttrs { isInline :: Bool, isNoreturn :: Bool }
deriving (Eq, Ord, Data, Show)
noFunctionAttrs :: FunctionAttrs
noFunctionAttrs = FunctionAttrs { isInline = False, isNoreturn = False }
-- In C we have
-- Identifiers can either have internal, external or no linkage
-- (same object everywhere, same object within the translation unit, unique).
-- * top-level identifiers
-- static : internal linkage (objects and function defs)
-- extern : linkage of prior declaration (if specified), external linkage otherwise
-- no-spec: external linkage
-- * storage duration
-- * static storage duration: objects with external or internal linkage, or local ones with the static keyword
-- * automatic storage duration: otherwise (register)
-- See http://publications.gbdirect.co.uk/c_book/chapter8/declarations_and_definitions.html, Table 8.1, 8.2
-- | Storage duration and linkage of a variable
data Storage = NoStorage -- ^ no storage
| Auto Register -- ^ automatic storage (optional: register)
| Static Linkage ThreadLocal -- ^ static storage, linkage spec and thread local specifier (gnu c)
| FunLinkage Linkage -- ^ function, either internal or external linkage
deriving (Data, Show, Eq, Ord)
type ThreadLocal = Bool
type Register = Bool
-- | Linkage: Either no linkage, internal to the translation unit or external
data Linkage = NoLinkage | InternalLinkage | ExternalLinkage
deriving (Data, Show, Eq, Ord)
-- | return @True@ if the object has linkage
hasLinkage :: Storage -> Bool
hasLinkage (Auto _) = False
hasLinkage (Static NoLinkage _) = False
hasLinkage _ = True
-- | Get the linkage of a definition
declLinkage :: (Declaration d) => d -> Linkage
declLinkage decl =
case declStorage decl of
NoStorage -> undefined
Auto _ -> NoLinkage
Static linkage _ -> linkage
FunLinkage linkage -> linkage
-- * types
-- | types of C objects
data Type =
DirectType TypeName TypeQuals Attributes
-- ^ a non-derived type
| PtrType Type TypeQuals Attributes
-- ^ pointer type
| ArrayType Type ArraySize TypeQuals Attributes
-- ^ array type
| FunctionType FunType Attributes
-- ^ function type
| TypeDefType TypeDefRef TypeQuals Attributes
-- ^ a defined type
deriving (Data, Show)
-- | Function types are of the form @FunType return-type params isVariadic@.
--
-- If the parameter types aren't yet known, the function has type @FunTypeIncomplete type attrs@.
data FunType = FunType Type [ParamDecl] Bool
| FunTypeIncomplete Type
deriving (Data, Show)
-- | An array type may either have unknown size or a specified array size, the latter either variable or constant.
-- Furthermore, when used as a function parameters, the size may be qualified as /static/.
-- In a function prototype, the size may be `Unspecified variable size' (@[*]@).
data ArraySize = UnknownArraySize Bool
-- ^ @UnknownArraySize is-starred@
| ArraySize Bool Expr
-- ^ @FixedSizeArray is-static size-expr@
deriving (Data, Show)
-- | normalized type representation
data TypeName =
TyVoid
| TyIntegral IntType
| TyFloating FloatType
| TyComplex FloatType
| TyComp CompTypeRef
| TyEnum EnumTypeRef
| TyBuiltin BuiltinType
deriving (Data, Show)
-- | Builtin type (va_list, anything)
data BuiltinType = TyVaList
| TyAny
deriving (Data, Show)
-- | typdef references
-- If the actual type is known, it is attached for convenience
data TypeDefRef = TypeDefRef Ident Type NodeInfo
deriving (Data {-! ,CNode !-}, Show)
-- | integral types (C99 6.7.2.2)
data IntType =
TyBool
| TyChar
| TySChar
| TyUChar
| TyShort
| TyUShort
| TyInt
| TyUInt
| TyInt128
| TyUInt128
| TyLong
| TyULong
| TyLLong
| TyULLong
deriving (Data, Eq, Ord)
instance Show IntType where
show TyBool = "_Bool"
show TyChar = "char"
show TySChar = "signed char"
show TyUChar = "unsigned char"
show TyShort = "short"
show TyUShort = "unsigned short"
show TyInt = "int"
show TyUInt = "unsigned int"
show TyInt128 = "__int128"
show TyUInt128 = "unsigned __int128"
show TyLong = "long"
show TyULong = "unsigned long"
show TyLLong = "long long"
show TyULLong = "unsigned long long"
-- | floating point type (C99 6.7.2.2)
data FloatType =
TyFloat
| TyDouble
| TyLDouble
| TyBFloat16
| TyFloatN Int Bool
deriving (Data, Eq, Ord)
instance Show FloatType where
show TyFloat = "float"
show TyDouble = "double"
show TyLDouble = "long double"
show TyBFloat16 = "__bf16"
show (TyFloatN n x) = "_Float" ++ (show n) ++ (if x then "x" else "")
-- | composite type declarations
data CompTypeRef = CompTypeRef SUERef CompTyKind NodeInfo
deriving (Data {-! ,CNode !-}, Show)
instance HasSUERef CompTypeRef where sueRef (CompTypeRef ref _ _) = ref
instance HasCompTyKind CompTypeRef where compTag (CompTypeRef _ tag _) = tag
data EnumTypeRef = EnumTypeRef SUERef NodeInfo
deriving (Data {-! ,CNode !-}, Show)
instance HasSUERef EnumTypeRef where sueRef (EnumTypeRef ref _) = ref
-- | Composite type (struct or union).
data CompType = CompType SUERef CompTyKind [MemberDecl] Attributes NodeInfo
deriving (Data {-! ,CNode !-}, Show)
instance HasSUERef CompType where sueRef (CompType ref _ _ _ _) = ref
instance HasCompTyKind CompType where compTag (CompType _ tag _ _ _) = tag
-- | return the type of a composite type definition
typeOfCompDef :: CompType -> TypeName
typeOfCompDef (CompType ref tag _ _ _) = TyComp (CompTypeRef ref tag undefNode)
-- | a tag to determine wheter we refer to a @struct@ or @union@, see 'CompType'.
data CompTyKind = StructTag
| UnionTag
deriving (Eq,Ord,Data)
instance Show CompTyKind where
show StructTag = "struct"
show UnionTag = "union"
-- | Representation of C enumeration types
data EnumType = EnumType SUERef [Enumerator] Attributes NodeInfo
-- ^ @EnumType name enumeration-constants attrs node@
deriving (Data {-! ,CNode !-}, Show)
instance HasSUERef EnumType where sueRef (EnumType ref _ _ _) = ref
-- | return the type of an enum definition
typeOfEnumDef :: EnumType -> TypeName
typeOfEnumDef (EnumType ref _ _ _) = TyEnum (EnumTypeRef ref undefNode)
-- | An Enumerator consists of an identifier, a constant expressions and the link to its type
data Enumerator = Enumerator Ident Expr EnumType NodeInfo
deriving (Data {-! ,CNode !-}, Show)
instance Declaration Enumerator where
getVarDecl (Enumerator ide _ enumty _) =
VarDecl
(VarName ide Nothing)
(DeclAttrs noFunctionAttrs NoStorage [])
(DirectType (typeOfEnumDef enumty) noTypeQuals noAttributes)
-- | Type qualifiers: constant, volatile and restrict
data TypeQuals = TypeQuals { constant :: Bool, volatile :: Bool,
restrict :: Bool, atomic :: Bool,
nullable :: Bool, nonnull :: Bool,
clrdonly :: Bool, clwronly :: Bool }
deriving (Data, Show)
instance Eq TypeQuals where
(==) (TypeQuals c1 v1 r1 a1 n1 nn1 rd1 wr1) (TypeQuals c2 v2 r2 a2 n2 nn2 rd2 wr2) =
c1 == c2 && v1 == v2 && r1 == r2 && a1 == a2 && n1 == n2 && nn1 == nn2
&& rd1 == rd2 && wr1 == wr2
instance Ord TypeQuals where
(<=) (TypeQuals c1 v1 r1 a1 n1 nn1 rd1 wr1) (TypeQuals c2 v2 r2 a2 n2 nn2 rd2 wr2) =
c1 <= c2 && v1 <= v2 && r1 <= r2 && a1 <= a2 && n1 <= n2 && nn1 <= nn2
&& rd1 <= rd2 && wr1 <= wr2
-- | no type qualifiers
noTypeQuals :: TypeQuals
noTypeQuals = TypeQuals False False False False False False False False
-- | merge (/&&/) two type qualifier sets
mergeTypeQuals :: TypeQuals -> TypeQuals -> TypeQuals
mergeTypeQuals (TypeQuals c1 v1 r1 a1 n1 nn1 rd1 wr1) (TypeQuals c2 v2 r2 a2 n2 nn2 rd2 wr2) =
TypeQuals (c1 && c2) (v1 && v2) (r1 && r2) (a1 && a2) (n1 && n2) (nn1 && nn2)
(rd1 && rd2) (wr1 && wr2)
-- * initializers
-- | 'Initializer' is currently an alias for 'CInit'.
--
-- We're planning a normalized representation, but this depends on the implementation of
-- constant expression evaluation
type Initializer = CInit
-- | Normalized C Initializers
-- * If the expression has scalar type, the initializer is an expression
-- * If the expression has struct type, the initializer is a map from designators to initializers
-- * If the expression has array type, the initializer is a list of values
-- Not implemented yet, as it depends on constant expression evaluation
-- * names and attributes
-- | @VarName name assembler-name@ is a name of an declared object
data VarName = VarName Ident (Maybe AsmName)
| NoName
deriving (Data, Show)
identOfVarName :: VarName -> Ident
identOfVarName NoName = error "identOfVarName: NoName"
identOfVarName (VarName ident _) = ident
isNoName :: VarName -> Bool
isNoName NoName = True
isNoName _ = False
-- | Top level assembler block (alias for @CStrLit@)
type AsmBlock = CStrLit
-- | Assembler name (alias for @CStrLit@)
type AsmName = CStrLit
-- | @__attribute__@ annotations
--
-- Those are of the form @Attr attribute-name attribute-parameters@,
-- and serve as generic properties of some syntax tree elements.
--
-- Some examples:
--
-- * labels can be attributed with /unused/ to indicate that their not used
--
-- * struct definitions can be attributed with /packed/ to tell the compiler to use the most compact representation
--
-- * declarations can be attributed with /deprecated/
--
-- * function declarations can be attributes with /noreturn/ to tell the compiler that the function will never return,
--
-- * or with /const/ to indicate that it is a pure function
--
-- /TODO/: ultimatively, we want to parse attributes and represent them in a typed way
data Attr = Attr Ident [Expr] NodeInfo
deriving (Data {-! ,CNode !-}, Show)
type Attributes = [Attr]
-- |Empty attribute list
noAttributes :: Attributes
noAttributes = []
-- |Merge attribute lists
-- /TODO/: currently does not remove duplicates
mergeAttributes :: Attributes -> Attributes -> Attributes
mergeAttributes = (++)
-- * statements and expressions (Type aliases)
-- | 'Stmt' is an alias for 'CStat' (Syntax)
type Stmt = CStat
-- | 'Expr' is currently an alias for 'CExpr' (Syntax)
type Expr = CExpr
-- GENERATED START
instance CNode TagDef where
nodeInfo (CompDef d) = nodeInfo d
nodeInfo (EnumDef d) = nodeInfo d
instance Pos TagDef where
posOf x = posOf (nodeInfo x)
instance CNode IdentDecl where
nodeInfo (Declaration d) = nodeInfo d
nodeInfo (ObjectDef d) = nodeInfo d
nodeInfo (FunctionDef d) = nodeInfo d
nodeInfo (EnumeratorDef d) = nodeInfo d
instance Pos IdentDecl where
posOf x = posOf (nodeInfo x)
instance CNode DeclEvent where
nodeInfo (TagEvent d) = nodeInfo d
nodeInfo (DeclEvent d) = nodeInfo d
nodeInfo (ParamEvent d) = nodeInfo d
nodeInfo (LocalEvent d) = nodeInfo d
nodeInfo (TypeDefEvent d) = nodeInfo d
nodeInfo (AsmEvent d) = nodeInfo d
instance Pos DeclEvent where
posOf x = posOf (nodeInfo x)
instance CNode Decl where
nodeInfo (Decl _ n) = n
instance Pos Decl where
posOf x = posOf (nodeInfo x)
instance CNode ObjDef where
nodeInfo (ObjDef _ _ n) = n
instance Pos ObjDef where
posOf x = posOf (nodeInfo x)
instance CNode FunDef where
nodeInfo (FunDef _ _ n) = n
instance Pos FunDef where
posOf x = posOf (nodeInfo x)
instance CNode ParamDecl where
nodeInfo (ParamDecl _ n) = n
nodeInfo (AbstractParamDecl _ n) = n
instance Pos ParamDecl where
posOf x = posOf (nodeInfo x)
instance CNode MemberDecl where
nodeInfo (MemberDecl _ _ n) = n
nodeInfo (AnonBitField _ _ n) = n
instance Pos MemberDecl where
posOf x = posOf (nodeInfo x)
instance CNode TypeDef where
nodeInfo (TypeDef _ _ _ n) = n
instance Pos TypeDef where
posOf x = posOf (nodeInfo x)
instance CNode TypeDefRef where
nodeInfo (TypeDefRef _ _ n) = n
instance Pos TypeDefRef where
posOf x = posOf (nodeInfo x)
instance CNode CompTypeRef where
nodeInfo (CompTypeRef _ _ n) = n
instance Pos CompTypeRef where
posOf x = posOf (nodeInfo x)
instance CNode EnumTypeRef where
nodeInfo (EnumTypeRef _ n) = n
instance Pos EnumTypeRef where
posOf x = posOf (nodeInfo x)
instance CNode CompType where
nodeInfo (CompType _ _ _ _ n) = n
instance Pos CompType where
posOf x = posOf (nodeInfo x)
instance CNode EnumType where
nodeInfo (EnumType _ _ _ n) = n
instance Pos EnumType where
posOf x = posOf (nodeInfo x)
instance CNode Enumerator where
nodeInfo (Enumerator _ _ _ n) = n
instance Pos Enumerator where
posOf x = posOf (nodeInfo x)
instance CNode Attr where
nodeInfo (Attr _ _ n) = n
instance Pos Attr where
posOf x = posOf (nodeInfo x)
-- GENERATED STOP