    {-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-}
    {-# OPTIONS -fno-warn-orphans #-}
    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Language.C.Analysis.Debug
    -- Copyright   :  (c) 2008 Benedikt Huber
    -- License     :  BSD-style
    -- Maintainer  :  benedikt.huber@gmail.com
    -- Stability   :  prototype
    -- Portability :  ghc
    --
    -- Pretty printing the semantic analysis representation.
    -- This is currently only intended for debugging purposes.
    -----------------------------------------------------------------------------
    module Language.C.Analysis.Debug (
    globalDeclStats,
    prettyAssocs, prettyAssocsWith,
    -- and many pretty instances
    )
    where
    import Language.C.Analysis.SemRep
    import Language.C.Analysis.Export
    import Language.C.Analysis.DefTable
    import Language.C.Analysis.NameSpaceMap

    import Language.C.Data
    import Language.C.Pretty

    import Prelude hiding ((<>))
    import Text.PrettyPrint.HughesPJ
    import Data.Map (Map) ; import qualified Data.Map as Map

    prettyAssocs :: (Pretty k, Pretty v) => String -> [(k,v)] -> Doc
    prettyAssocs :: forall k v. (Pretty k, Pretty v) => String -> [(k, v)] -> Doc
    prettyAssocs String
    label = String -> (k -> Doc) -> (v -> Doc) -> [(k, v)] -> Doc
    forall k v. String -> (k -> Doc) -> (v -> Doc) -> [(k, v)] -> Doc
    prettyAssocsWith String
    label k -> Doc
    forall p. Pretty p => p -> Doc
    pretty v -> Doc
    forall p. Pretty p => p -> Doc
    pretty
    prettyAssocsWith :: String -> (k -> Doc) -> (v -> Doc) -> [(k,v)] -> Doc
    prettyAssocsWith :: forall k v. String -> (k -> Doc) -> (v -> Doc) -> [(k, v)] -> Doc
    prettyAssocsWith String
    label k -> Doc
    prettyKey v -> Doc
    prettyVal [(k, v)]
    theMap =
        String -> Doc
    text String
    label Doc -> Doc -> Doc
    $$ Int -> Doc -> Doc
    nest Int
    8 ([Doc] -> Doc
    vcat ([Doc] -> Doc) -> [Doc] -> Doc
    forall a b. (a -> b) -> a -> b
    $ ((k, v) -> Doc) -> [(k, v)] -> [Doc]
    forall a b. (a -> b) -> [a] -> [b]
    map (k, v) -> Doc
    prettyEntry [(k, v)]
    theMap)
        where
        prettyEntry :: (k, v) -> Doc
    prettyEntry (k
    k,v
    v) = k -> Doc
    prettyKey k
    k Doc -> Doc -> Doc
    <+> String -> Doc
    text String
    " ~> " Doc -> Doc -> Doc
    <+> v -> Doc
    prettyVal v
    v

    instance Pretty DefTable where
        pretty :: DefTable -> Doc
    pretty DefTable
    dt = String -> Doc
    text String
    "DefTable" Doc -> Doc -> Doc
    $$ Int -> Doc -> Doc
    nest Int
    4 ([Doc] -> Doc
    vcat [Doc]
    defMaps)
            where
            defMaps :: [Doc]
    defMaps = [ String -> (DefTable -> NameSpaceMap Ident IdentEntry) -> Doc
    forall {k} {v}.
    (Pretty k, Pretty v, Ord k) =>
    String -> (DefTable -> NameSpaceMap k v) -> Doc
    prettyNSMap String
    "idents" DefTable -> NameSpaceMap Ident IdentEntry
    identDecls
                      , String -> (DefTable -> NameSpaceMap SUERef TagEntry) -> Doc
    forall {k} {v}.
    (Pretty k, Pretty v, Ord k) =>
    String -> (DefTable -> NameSpaceMap k v) -> Doc
    prettyNSMap String
    "tags" DefTable -> NameSpaceMap SUERef TagEntry
    tagDecls
                      , String -> (DefTable -> NameSpaceMap Ident Ident) -> Doc
    forall {k} {v}.
    (Pretty k, Pretty v, Ord k) =>
    String -> (DefTable -> NameSpaceMap k v) -> Doc
    prettyNSMap String
    "labels" DefTable -> NameSpaceMap Ident Ident
    labelDefs
                      , String -> (DefTable -> NameSpaceMap Ident MemberDecl) -> Doc
    forall {k} {v}.
    (Pretty k, Pretty v, Ord k) =>
    String -> (DefTable -> NameSpaceMap k v) -> Doc
    prettyNSMap String
    "members" DefTable -> NameSpaceMap Ident MemberDecl
    memberDecls
                      ]
            prettyNSMap :: String -> (DefTable -> NameSpaceMap k v) -> Doc
    prettyNSMap String
    label DefTable -> NameSpaceMap k v
    f = String -> [(k, v)] -> Doc
    forall k v. (Pretty k, Pretty v) => String -> [(k, v)] -> Doc
    prettyAssocs String
    label ([(k, v)] -> Doc)
    -> (NameSpaceMap k v -> [(k, v)]) -> NameSpaceMap k v -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NameSpaceMap k v -> [(k, v)]
    forall k a. Ord k => NameSpaceMap k a -> [(k, a)]
    nsMapToList (NameSpaceMap k v -> Doc) -> NameSpaceMap k v -> Doc
    forall a b. (a -> b) -> a -> b
    $ DefTable -> NameSpaceMap k v
    f DefTable
    dt

    instance Pretty GlobalDecls where
        pretty :: GlobalDecls -> Doc
    pretty GlobalDecls
    gd = String -> Doc
    text String
    "Global Declarations" Doc -> Doc -> Doc
    $$ (Int -> Doc -> Doc
    nest Int
    4 (Doc -> Doc) -> Doc -> Doc
    forall a b. (a -> b) -> a -> b
    $ [Doc] -> Doc
    vcat [Doc]
    declMaps)
            where
            declMaps :: [Doc]
    declMaps = [ String -> Map Ident Enumerator -> Doc
    forall t k. (Pretty t, Pretty k) => String -> Map k t -> Doc
    prettyMap String
    "enumerators" Map Ident Enumerator
    theEnums, String -> Map Ident Decl -> Doc
    forall t k. (Pretty t, Pretty k) => String -> Map k t -> Doc
    prettyMap String
    "declarations" Map Ident Decl
    theDecls,
                         String -> Map Ident ObjDef -> Doc
    forall t k. (Pretty t, Pretty k) => String -> Map k t -> Doc
    prettyMap String
    "objects" Map Ident ObjDef
    theObjs,  String -> Map Ident FunDef -> Doc
    forall t k. (Pretty t, Pretty k) => String -> Map k t -> Doc
    prettyMap String
    "functions" Map Ident FunDef
    theFuns,
                         String -> Map SUERef TagDef -> Doc
    forall t k. (Pretty t, Pretty k) => String -> Map k t -> Doc
    prettyMap String
    "tags"    (Map SUERef TagDef -> Doc) -> Map SUERef TagDef -> Doc
    forall a b. (a -> b) -> a -> b
    $ GlobalDecls -> Map SUERef TagDef
    gTags GlobalDecls
    gd,  String -> Map Ident TypeDef -> Doc
    forall t k. (Pretty t, Pretty k) => String -> Map k t -> Doc
    prettyMap String
    "typeDefs"  (Map Ident TypeDef -> Doc) -> Map Ident TypeDef -> Doc
    forall a b. (a -> b) -> a -> b
    $ GlobalDecls -> Map Ident TypeDef
    gTypeDefs GlobalDecls
    gd ]
            prettyMap :: (Pretty t, Pretty k) => String -> Map k t -> Doc
            prettyMap :: forall t k. (Pretty t, Pretty k) => String -> Map k t -> Doc
    prettyMap String
    label = String -> [(k, t)] -> Doc
    forall k v. (Pretty k, Pretty v) => String -> [(k, v)] -> Doc
    prettyAssocs String
    label ([(k, t)] -> Doc) -> (Map k t -> [(k, t)]) -> Map k t -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Map k t -> [(k, t)]
    forall k a. Map k a -> [(k, a)]
    Map.assocs
            (Map Ident Decl
    theDecls, (Map Ident Enumerator
    theEnums, Map Ident ObjDef
    theObjs, Map Ident FunDef
    theFuns)) = Bool
    -> Map Ident IdentDecl
    -> (Map Ident Decl,
        (Map Ident Enumerator, Map Ident ObjDef, Map Ident FunDef))
    splitIdentDecls Bool
    False (GlobalDecls -> Map Ident IdentDecl
    gObjs GlobalDecls
    gd)

    globalDeclStats :: (FilePath -> Bool) -> GlobalDecls -> [(String,Int)]
    globalDeclStats :: (String -> Bool) -> GlobalDecls -> [(String, Int)]
    globalDeclStats String -> Bool
    file_filter GlobalDecls
    gmap =
        [ (String
    "Enumeration Constants",Map Ident Enumerator -> Int
    forall k a. Map k a -> Int
    Map.size Map Ident Enumerator
    enumerators),
          (String
    "Total Object/Function Declarations",Map Ident Decl -> Int
    forall k a. Map k a -> Int
    Map.size Map Ident Decl
    all_decls),
          (String
    "Object definitions", Map Ident ObjDef -> Int
    forall k a. Map k a -> Int
    Map.size Map Ident ObjDef
    objDefs),
          (String
    "Function Definitions", Map Ident FunDef -> Int
    forall k a. Map k a -> Int
    Map.size Map Ident FunDef
    funDefs),
          (String
    "Tag definitions", Map SUERef TagDef -> Int
    forall k a. Map k a -> Int
    Map.size Map SUERef TagDef
    tagDefs),
          (String
    "TypeDefs", Map Ident TypeDef -> Int
    forall k a. Map k a -> Int
    Map.size Map Ident TypeDef
    typeDefs)
        ]
        where
        gmap' :: GlobalDecls
    gmap' = (DeclEvent -> Bool) -> GlobalDecls -> GlobalDecls
    filterGlobalDecls DeclEvent -> Bool
    forall n. CNode n => n -> Bool
    filterFile GlobalDecls
    gmap
        (Map Ident Decl
    all_decls,(Map Ident Enumerator
    enumerators,Map Ident ObjDef
    objDefs,Map Ident FunDef
    funDefs)) = Bool
    -> Map Ident IdentDecl
    -> (Map Ident Decl,
        (Map Ident Enumerator, Map Ident ObjDef, Map Ident FunDef))
    splitIdentDecls Bool
    True (GlobalDecls -> Map Ident IdentDecl
    gObjs GlobalDecls
    gmap')
        (Map SUERef TagDef
    tagDefs,Map Ident TypeDef
    typeDefs) = (GlobalDecls -> Map SUERef TagDef
    gTags GlobalDecls
    gmap', GlobalDecls -> Map Ident TypeDef
    gTypeDefs GlobalDecls
    gmap')
        filterFile :: (CNode n) => n -> Bool
        filterFile :: forall n. CNode n => n -> Bool
    filterFile = Bool -> (String -> Bool) -> Maybe String -> Bool
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Bool
    True String -> Bool
    file_filter (Maybe String -> Bool) -> (n -> Maybe String) -> n -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . NodeInfo -> Maybe String
    forall a. CNode a => a -> Maybe String
    fileOfNode (NodeInfo -> Maybe String) -> (n -> NodeInfo) -> n -> Maybe String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . n -> NodeInfo
    forall a. CNode a => a -> NodeInfo
    nodeInfo

    instance (Pretty a, Pretty b) => Pretty (Either a b) where
        pretty :: Either a b -> Doc
    pretty = (a -> Doc) -> (b -> Doc) -> Either a b -> Doc
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either a -> Doc
    forall p. Pretty p => p -> Doc
    pretty b -> Doc
    forall p. Pretty p => p -> Doc
    pretty
    instance Pretty TagFwdDecl where
        pretty :: TagFwdDecl -> Doc
    pretty (CompDecl CompTypeRef
    ct) = CompTypeRef -> Doc
    forall p. Pretty p => p -> Doc
    pretty CompTypeRef
    ct
        pretty (EnumDecl EnumTypeRef
    et) = EnumTypeRef -> Doc
    forall p. Pretty p => p -> Doc
    pretty EnumTypeRef
    et
    instance Pretty CompTyKind where
        pretty :: CompTyKind -> Doc
    pretty CompTyKind
    StructTag = String -> Doc
    text String
    "struct"
        pretty CompTyKind
    UnionTag = String -> Doc
    text String
    "union"
    instance Pretty CompTypeRef where
        pretty :: CompTypeRef -> Doc
    pretty (CompTypeRef SUERef
    sue CompTyKind
    kind NodeInfo
    _) = CompTyKind -> Doc
    forall p. Pretty p => p -> Doc
    pretty CompTyKind
    kind Doc -> Doc -> Doc
    <+> SUERef -> Doc
    forall p. Pretty p => p -> Doc
    pretty SUERef
    sue
    instance Pretty EnumTypeRef where
        pretty :: EnumTypeRef -> Doc
    pretty (EnumTypeRef SUERef
    sue NodeInfo
    _ ) = String -> Doc
    text String
    "enum" Doc -> Doc -> Doc
    <+> SUERef -> Doc
    forall p. Pretty p => p -> Doc
    pretty SUERef
    sue
    instance Pretty Ident where
        pretty :: Ident -> Doc
    pretty = String -> Doc
    text (String -> Doc) -> (Ident -> String) -> Ident -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Ident -> String
    identToString
    instance Pretty SUERef where
        pretty :: SUERef -> Doc
    pretty (AnonymousRef Name
    name) = String -> Doc
    text (String -> Doc) -> String -> Doc
    forall a b. (a -> b) -> a -> b
    $ String
    "$" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show (Name -> Int
    nameId Name
    name)
        pretty (NamedRef Ident
    ident) = Ident -> Doc
    forall p. Pretty p => p -> Doc
    pretty Ident
    ident
    instance Pretty TagDef where
        pretty :: TagDef -> Doc
    pretty (CompDef CompType
    compty) = CompType -> Doc
    forall p. Pretty p => p -> Doc
    pretty CompType
    compty
        pretty (EnumDef EnumType
    enumty) = EnumType -> Doc
    forall p. Pretty p => p -> Doc
    pretty EnumType
    enumty
    instance Pretty IdentDecl where
        pretty :: IdentDecl -> Doc
    pretty (Declaration Decl
    decl) = Decl -> Doc
    forall p. Pretty p => p -> Doc
    pretty Decl
    decl
        pretty (ObjectDef ObjDef
    odef) = ObjDef -> Doc
    forall p. Pretty p => p -> Doc
    pretty ObjDef
    odef
        pretty (FunctionDef FunDef
    fdef) = FunDef -> Doc
    forall p. Pretty p => p -> Doc
    pretty FunDef
    fdef
        pretty (EnumeratorDef Enumerator
    enumerator) = Enumerator -> Doc
    forall p. Pretty p => p -> Doc
    pretty Enumerator
    enumerator
    instance Pretty Decl where
        pretty :: Decl -> Doc
    pretty (Decl VarDecl
    vardecl NodeInfo
    _) =
            String -> Doc
    text String
    "declaration" Doc -> Doc -> Doc
    <+>
            VarDecl -> Doc
    forall p. Pretty p => p -> Doc
    pretty VarDecl
    vardecl
    instance Pretty TypeDef where
        pretty :: TypeDef -> Doc
    pretty (TypeDef Ident
    ident Type
    ty Attributes
    attrs NodeInfo
    _) =
            String -> Doc
    text String
    "typedef" Doc -> Doc -> Doc
    <+> Ident -> Doc
    forall p. Pretty p => p -> Doc
    pretty Ident
    ident Doc -> Doc -> Doc
    <+> String -> Doc
    text String
    "as"  Doc -> Doc -> Doc
    <+>
            Attributes -> Doc
    forall p. Pretty p => p -> Doc
    pretty Attributes
    attrs Doc -> Doc -> Doc
    <+> Type -> Doc
    forall p. Pretty p => p -> Doc
    pretty Type
    ty
    instance Pretty ObjDef where
        pretty :: ObjDef -> Doc
    pretty (ObjDef VarDecl
    vardecl Maybe Initializer
    init_opt NodeInfo
    _) =
            String -> Doc
    text String
    "object" Doc -> Doc -> Doc
    <+>
            VarDecl -> Doc
    forall p. Pretty p => p -> Doc
    pretty VarDecl
    vardecl Doc -> Doc -> Doc
    <+> Doc -> (Initializer -> Doc) -> Maybe Initializer -> Doc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Doc
    empty (((String -> Doc
    text String
    "=") Doc -> Doc -> Doc
    <+>) (Doc -> Doc) -> (Initializer -> Doc) -> Initializer -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Initializer -> Doc
    forall p. Pretty p => p -> Doc
    pretty) Maybe Initializer
    init_opt
    instance Pretty FunDef where
        pretty :: FunDef -> Doc
    pretty (FunDef VarDecl
    vardecl Stmt
    _stmt NodeInfo
    _) =
            String -> Doc
    text String
    "function" Doc -> Doc -> Doc
    <+>
            VarDecl -> Doc
    forall p. Pretty p => p -> Doc
    pretty VarDecl
    vardecl
    instance Pretty VarDecl where
        pretty :: VarDecl -> Doc
    pretty (VarDecl VarName
    name DeclAttrs
    attrs Type
    ty) =
            (([Doc] -> Doc
    hsep ([Doc] -> Doc) -> ([Doc] -> [Doc]) -> [Doc] -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Doc -> [Doc] -> [Doc]
    punctuate (String -> Doc
    text String
    " |")) [VarName -> Doc
    forall p. Pretty p => p -> Doc
    pretty VarName
    name, DeclAttrs -> Doc
    forall p. Pretty p => p -> Doc
    pretty DeclAttrs
    attrs, Type -> Doc
    forall p. Pretty p => p -> Doc
    pretty Type
    ty])
    instance Pretty ParamDecl where
        pretty :: ParamDecl -> Doc
    pretty (ParamDecl (VarDecl VarName
    name DeclAttrs
    declattrs Type
    ty) NodeInfo
    _) =
            DeclAttrs -> Doc
    forall p. Pretty p => p -> Doc
    pretty DeclAttrs
    declattrs Doc -> Doc -> Doc
    <+> VarName -> Doc
    forall p. Pretty p => p -> Doc
    pretty VarName
    name Doc -> Doc -> Doc
    <+> String -> Doc
    text String
    "::" Doc -> Doc -> Doc
    <+> Type -> Doc
    forall p. Pretty p => p -> Doc
    pretty Type
    ty
        pretty (AbstractParamDecl (VarDecl VarName
    name DeclAttrs
    declattrs Type
    ty) NodeInfo
    _) =
            String -> Doc
    text String
    "abstract" Doc -> Doc -> Doc
    <+> DeclAttrs -> Doc
    forall p. Pretty p => p -> Doc
    pretty DeclAttrs
    declattrs Doc -> Doc -> Doc
    <+> VarName -> Doc
    forall p. Pretty p => p -> Doc
    pretty VarName
    name Doc -> Doc -> Doc
    <+>
                 String -> Doc
    text String
    "::" Doc -> Doc -> Doc
    <+> Type -> Doc
    forall p. Pretty p => p -> Doc
    pretty Type
    ty
    instance Pretty DeclAttrs where
        pretty :: DeclAttrs -> Doc
    pretty (DeclAttrs FunctionAttrs
    fun_attrs Storage
    storage Attributes
    attrs) =
            [Doc] -> Doc
    hsep [ FunctionAttrs -> Doc
    forall p. Pretty p => p -> Doc
    pretty FunctionAttrs
    fun_attrs, Storage -> Doc
    forall p. Pretty p => p -> Doc
    pretty Storage
    storage, Attributes -> Doc
    forall p. Pretty p => p -> Doc
    pretty Attributes
    attrs]

    instance Pretty Type where
      pretty :: Type -> Doc
    pretty Type
    ty = CDecl -> Doc
    forall p. Pretty p => p -> Doc
    pretty (Type -> CDecl
    exportTypeDecl Type
    ty)
    instance Pretty TypeQuals where
        pretty :: TypeQuals -> Doc
    pretty TypeQuals
    tyQuals = [Doc] -> Doc
    hsep ([Doc] -> Doc) -> [Doc] -> Doc
    forall a b. (a -> b) -> a -> b
    $ ((String, TypeQuals -> Bool) -> Doc)
    -> [(String, TypeQuals -> Bool)] -> [Doc]
    forall a b. (a -> b) -> [a] -> [b]
    map (String, TypeQuals -> Bool) -> Doc
    showAttr [ (String
    "const",TypeQuals -> Bool
    constant),(String
    "volatile",TypeQuals -> Bool
    volatile),(String
    "restrict",TypeQuals -> Bool
    restrict) ]
            where showAttr :: (String, TypeQuals -> Bool) -> Doc
    showAttr (String
    str,TypeQuals -> Bool
    select) | TypeQuals -> Bool
    select TypeQuals
    tyQuals = String -> Doc
    text String
    str
                                        | Bool
    otherwise      = Doc
    empty

    instance Pretty CompType where
        pretty :: CompType -> Doc
    pretty (CompType SUERef
    sue_ref CompTyKind
    tag [MemberDecl]
    members Attributes
    attrs NodeInfo
    _node) =
            (String -> Doc
    text(String -> Doc) -> (CompTyKind -> String) -> CompTyKind -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .CompTyKind -> String
    forall a. Show a => a -> String
    show) CompTyKind
    tag Doc -> Doc -> Doc
    <+> SUERef -> Doc
    forall p. Pretty p => p -> Doc
    pretty SUERef
    sue_ref Doc -> Doc -> Doc
    <+>
            Doc -> Doc
    braces ([MemberDecl] -> Doc
    forall a. Pretty a => [a] -> Doc
    terminateSemi [MemberDecl]
    members) Doc -> Doc -> Doc
    <+>
            Attributes -> Doc
    forall p. Pretty p => p -> Doc
    pretty Attributes
    attrs

    instance Pretty MemberDecl where
        pretty :: MemberDecl -> Doc
    pretty (MemberDecl (VarDecl VarName
    name DeclAttrs
    declattrs Type
    ty) Maybe Expr
    bitfield NodeInfo
    _) =
            DeclAttrs -> Doc
    forall p. Pretty p => p -> Doc
    pretty DeclAttrs
    declattrs Doc -> Doc -> Doc
    <+> VarName -> Doc
    forall p. Pretty p => p -> Doc
    pretty VarName
    name Doc -> Doc -> Doc
    <+> String -> Doc
    text String
    "::" Doc -> Doc -> Doc
    <+> Type -> Doc
    forall p. Pretty p => p -> Doc
    pretty Type
    ty Doc -> Doc -> Doc
    <+>
            (Doc -> (Expr -> Doc) -> Maybe Expr -> Doc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Doc
    empty (\Expr
    bf -> String -> Doc
    text String
    ":" Doc -> Doc -> Doc
    <+> Expr -> Doc
    forall p. Pretty p => p -> Doc
    pretty Expr
    bf) Maybe Expr
    bitfield)
        pretty (AnonBitField Type
    ty Expr
    bitfield_sz NodeInfo
    _) =
            Type -> Doc
    forall p. Pretty p => p -> Doc
    pretty Type
    ty Doc -> Doc -> Doc
    <+> String -> Doc
    text String
    ":" Doc -> Doc -> Doc
    <+> Expr -> Doc
    forall p. Pretty p => p -> Doc
    pretty Expr
    bitfield_sz

    instance Pretty EnumType where
        pretty :: EnumType -> Doc
    pretty (EnumType SUERef
    sue_ref [Enumerator]
    enumerators Attributes
    attrs NodeInfo
    _) =
          String -> Doc
    text String
    "enum" Doc -> Doc -> Doc
    <+> SUERef -> Doc
    forall p. Pretty p => p -> Doc
    pretty SUERef
    sue_ref Doc -> Doc -> Doc
    <+> Doc -> Doc
    braces ([Doc] -> Doc
    terminateSemi_ ([Doc] -> Doc) -> [Doc] -> Doc
    forall a b. (a -> b) -> a -> b
    $ (Enumerator -> Doc) -> [Enumerator] -> [Doc]
    forall a b. (a -> b) -> [a] -> [b]
    map Enumerator -> Doc
    prettyEnr [Enumerator]
    enumerators) Doc -> Doc -> Doc
    <+> Attributes -> Doc
    forall p. Pretty p => p -> Doc
    pretty Attributes
    attrs
          where
          prettyEnr :: Enumerator -> Doc
    prettyEnr (Enumerator Ident
    ident Expr
    expr EnumType
    _enumty NodeInfo
    _) = Ident -> Doc
    forall p. Pretty p => p -> Doc
    pretty Ident
    ident Doc -> Doc -> Doc
    <+> String -> Doc
    text String
    " = " Doc -> Doc -> Doc
    <+> Expr -> Doc
    forall p. Pretty p => p -> Doc
    pretty Expr
    expr

    instance Pretty Enumerator where
        pretty :: Enumerator -> Doc
    pretty (Enumerator Ident
    ident Expr
    expr EnumType
    enumty NodeInfo
    _) = String -> Doc
    text String
    "<" Doc -> Doc -> Doc
    <> String -> Doc
    text String
    "econst" Doc -> Doc -> Doc
    <+> SUERef -> Doc
    forall p. Pretty p => p -> Doc
    pretty (EnumType -> SUERef
    forall a. HasSUERef a => a -> SUERef
    sueRef EnumType
    enumty) Doc -> Doc -> Doc
    <> String -> Doc
    text String
    ">" Doc -> Doc -> Doc
    <+>
                                                  Ident -> Doc
    forall p. Pretty p => p -> Doc
    pretty Ident
    ident Doc -> Doc -> Doc
    <+> String -> Doc
    text String
    " = " Doc -> Doc -> Doc
    <+> Expr -> Doc
    forall p. Pretty p => p -> Doc
    pretty Expr
    expr

    instance Pretty FunctionAttrs where
        pretty :: FunctionAttrs -> Doc
    pretty FunctionAttrs
    fattrs = [Doc] -> Doc
    hsep [(FunctionAttrs -> Bool) -> String -> Doc
    pIf FunctionAttrs -> Bool
    isInline String
    "inline", (FunctionAttrs -> Bool) -> String -> Doc
    pIf FunctionAttrs -> Bool
    isNoreturn String
    "_Noreturn"]
          where
            pIf :: (FunctionAttrs -> Bool) -> String -> Doc
    pIf FunctionAttrs -> Bool
    isMatch String
    txt = if FunctionAttrs -> Bool
    isMatch FunctionAttrs
    fattrs then String -> Doc
    text String
    txt else Doc
    empty

    instance Pretty Storage where
        pretty :: Storage -> Doc
    pretty Storage
    NoStorage = Doc
    empty
        pretty (Auto Bool
    reg) = String -> Doc
    text(String -> Doc) -> String -> Doc
    forall a b. (a -> b) -> a -> b
    $ if Bool
    reg then String
    "auto/register" else String
    "auto"
        pretty (Static Linkage
    linkage Bool
    thread_local) =
            ([Doc] -> Doc
    hcat ([Doc] -> Doc) -> ([Doc] -> [Doc]) -> [Doc] -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Doc -> [Doc] -> [Doc]
    punctuate (String -> Doc
    text String
    "/") ([Doc] -> Doc) -> [Doc] -> Doc
    forall a b. (a -> b) -> a -> b
    $ [ String -> Doc
    text String
    "static",Linkage -> Doc
    forall p. Pretty p => p -> Doc
    pretty Linkage
    linkage ])
            Doc -> Doc -> Doc
    <+> (if Bool
    thread_local then String -> Doc
    text String
    ", __thread" else Doc
    empty)
        pretty (FunLinkage Linkage
    linkage) = String -> Doc
    text String
    "function/" Doc -> Doc -> Doc
    <> Linkage -> Doc
    forall p. Pretty p => p -> Doc
    pretty Linkage
    linkage
    instance Pretty Linkage where
        pretty :: Linkage -> Doc
    pretty Linkage
    InternalLinkage = String -> Doc
    text String
    "internal"
        pretty Linkage
    ExternalLinkage = String -> Doc
    text String
    "external"
        pretty Linkage
    NoLinkage       = String -> Doc
    text String
    "local"
    instance Pretty VarName where
        pretty :: VarName -> Doc
    pretty VarName
    NoName = String -> Doc
    text String
    "<anonymous>"
        pretty (VarName Ident
    ident Maybe AsmName
    asmname_opt) = Ident -> Doc
    forall p. Pretty p => p -> Doc
    pretty Ident
    ident Doc -> Doc -> Doc
    <+> (Doc -> (AsmName -> Doc) -> Maybe AsmName -> Doc
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Doc
    empty AsmName -> Doc
    forall p. Pretty p => p -> Doc
    pAsmName Maybe AsmName
    asmname_opt)
            where pAsmName :: p -> Doc
    pAsmName p
    asmname = String -> Doc
    text String
    "" Doc -> Doc -> Doc
    <+> Doc -> Doc
    parens (String -> Doc
    text String
    "asmname" Doc -> Doc -> Doc
    <+> p -> Doc
    forall p. Pretty p => p -> Doc
    pretty p
    asmname)
    instance Pretty Attributes where
        pretty :: Attributes -> Doc
    pretty = Attributes -> Doc
    forall a. Pretty a => [a] -> Doc
    joinComma
    instance Pretty Attr where
        pretty :: Attr -> Doc
    pretty (Attr Ident
    ident [Expr]
    es NodeInfo
    _) = Ident -> Doc
    forall p. Pretty p => p -> Doc
    pretty Ident
    ident Doc -> Doc -> Doc
    <+> (if [Expr] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Expr]
    es then Doc
    empty else String -> Doc
    text String
    "(...)")

    joinComma :: (Pretty a) => [a] -> Doc
    joinComma :: forall a. Pretty a => [a] -> Doc
    joinComma = [Doc] -> Doc
    hsep ([Doc] -> Doc) -> ([a] -> [Doc]) -> [a] -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Doc -> [Doc] -> [Doc]
    punctuate Doc
    comma ([Doc] -> [Doc]) -> ([a] -> [Doc]) -> [a] -> [Doc]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> Doc) -> [a] -> [Doc]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> Doc
    forall p. Pretty p => p -> Doc
    pretty
    terminateSemi :: (Pretty a) => [a] -> Doc
    terminateSemi :: forall a. Pretty a => [a] -> Doc
    terminateSemi = [Doc] -> Doc
    terminateSemi_ ([Doc] -> Doc) -> ([a] -> [Doc]) -> [a] -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> Doc) -> [a] -> [Doc]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> Doc
    forall p. Pretty p => p -> Doc
    pretty
    terminateSemi_ :: [Doc] -> Doc
    terminateSemi_ :: [Doc] -> Doc
    terminateSemi_ = [Doc] -> Doc
    hsep ([Doc] -> Doc) -> ([Doc] -> [Doc]) -> [Doc] -> Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Doc -> Doc) -> [Doc] -> [Doc]
    forall a b. (a -> b) -> [a] -> [b]
    map (Doc -> Doc -> Doc
    <> Doc
    semi)