Newer
Older
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
, structPosition :: !C.Position
}
deriving (Show, Eq)
findStructs
:: forall m
. (Monoid m)
=> (Struct -> m)
-> Context
-> C.CExternalDeclaration C.NodeInfo
-> m
findStructs inject ctx = \case
C.CDeclExt decl -> findStructsInDeclaration decl
C.CFDefExt (C.CFunDef spec declr params stmt _ni) ->
findStructsInDeclarator declr
<> foldMap findStructsInSpecifier spec
<> foldMap findStructsInDeclaration params
<> findStructsInStatement stmt
C.CAsmExt _ _ -> mempty
where
toStruct (C.CStruct tag mid mfields _attr ni) = fromMaybe mempty do
fields <- mfields
pure $ inject (Struct sid (StructType tag mid fields') (C.posOf ni))
-- TODO currently we do not look for structs inside of expressions.
-- (Can hide in CCompoundLiterals)
findStructsInStatement = \case
C.CCompound _ blocks _ -> flip foldMap blocks \case
C.CBlockDecl decl -> findStructsInDeclaration decl
C.CBlockStmt stmt -> findStructsInStatement stmt
a@(C.CNestedFunDef _) -> notSupportedYet' a
C.CFor (C.CForDecl decl) _ _ _ _ ->
findStructsInDeclaration decl
_ow -> mempty
findStructsInDeclarator = \case
C.CDeclr _ dd Nothing [] _ -> flip foldMap dd \case
C.CPtrDeclr _ _ -> mempty
C.CArrDeclr{} -> mempty
C.CFunDeclr (C.CFunParamsOld _) _ _ -> mempty
C.CFunDeclr (C.CFunParamsNew params _) _ _ ->
foldMap findStructsInDeclaration params
findStructsInDeclaration = \case
C.CDecl spec items ni ->
foldMap findStructsInSpecifier spec <> flip foldMap items \case
C.CDeclarationItem d _minit _mexpr -> do
findStructsInDeclarator d
a@(C.CStaticAssert _ _ ni) -> notSupportedYet (a $> ()) ni
findStructsInSpecifier = \case
C.CTypeSpec (C.CSUType cu _) -> toStruct cu
_ow -> mempty
data Function = Function
{ funName :: !C.Ident
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
, funIsStatic :: !Bool
, funSize :: !Int
, funPosition :: !C.Position
}
deriving (Show, Eq)
findFunctions
:: (Monoid m)
=> (Function -> m)
-> Context
-> C.CExternalDeclaration C.NodeInfo
-> m
findFunctions inject ctx = \case
C.CFDefExt (C.CFunDef spec declr [] _ ni) ->
findFunctionsInDeclarator ni spec declr
-- # for now let's not anlyse function declarations.
C.CFDefExt def@(C.CFunDef{}) ->
notSupportedYet (void def) def
C.CDeclExt (C.CDecl spec items ni) -> flip foldMap items \case
C.CDeclarationItem declr Nothing Nothing ->
findFunctionsInDeclarator ni spec declr
_ow -> mempty
C.CDeclExt a@(C.CStaticAssert{}) ->
notSupportedYet (void a) a
C.CAsmExt _ _ -> mempty
where
findFunctionsInDeclarator ni spec = \case
decl@(C.CDeclr mid _ Nothing [] _) ->
case nonVoidTypeOfFromContext ctx spec decl of
TFun funType -> case mid of
Just funName -> inject Function{..}
where
funIsStatic = isStaticFromSpecs spec
funSize = fromMaybe 0 (C.lengthOfNode ni)
funPosition = C.posOf ni
Nothing -> mempty
_ow -> mempty
nonVoidTypeOfFromContext
:: (HasCallStack) => Context -> [C.CDeclarationSpecifier C.NodeInfo] -> C.CDeclarator C.NodeInfo -> Type
nonVoidTypeOfFromContext ctx spec decl =
fromVoid (notSupportedYet' decl) id $
typeOf
(\t -> fst <$> Map.lookup t (structs ctx))
(\t -> fst <$> Map.lookup t (typeDefs ctx))
spec
decl
baseTypeOfFromContext
:: (HasCallStack) => Context -> [C.CDeclarationSpecifier C.NodeInfo] -> Voidable
baseTypeOfFromContext ctx spec =
baseTypeOf
(\t -> fst <$> Map.lookup t (structs ctx))
(\t -> fst <$> Map.lookup t (typeDefs ctx))
spec
class Named f where
name :: f a -> Maybe (C.Identifier a)
instance Named C.CDeclarator where
name (C.CDeclr idx _ _ _ _) = idx
instance Named C.CDeclarationItem where
name = \case
C.CDeclarationItem decl _ _ -> name decl
C.CDeclarationExpr _ -> Nothing
includeTypeDef :: (Monad m) => C.CExternalDeclaration C.NodeInfo -> StateT Context m ()
includeTypeDef = \case
C.CDeclExt (C.CDecl (C.CStorageSpec (C.CTypedef _) : rst) items _) -> do
let [C.CDeclarationItem decl _ _] = items
modify'
( \ctx ->
addTypeDef
(fromMaybe (error "expected typedef to have a name") $ name decl)
(nonVoidTypeOfFromContext ctx rst decl, ITInline rst)
ctx
)
:: Context
-> [C.CDeclarationSpecifier C.NodeInfo]
-> Bool
containsStructDeclaration ctx =
any \case
C.CTypeSpec (C.CSUType (C.CStruct _ mid (Just _) _ _) _) -> case mid of
case lookupStruct ctx sid of
Just _ -> True
Nothing -> False
Nothing -> False
_ow -> False
-> [C.CDeclaration C.NodeInfo]
-> ([C.CDeclaration C.NodeInfo], [(C.Ident, InlineExpr)])
filterParams ctx typefilter params = flip evalState typefilter do
(params', mapping) <- flip mapAndUnzipM params \case
decl@(C.CDecl def items l) -> do
t' <- state (\(t : tps) -> (t, tps))
case t' of
Just t
| not (shouldDeleteDeclaration ctx decl) -> do
let defs = [(idx', IEKeep t) | i <- items, idx' <- maybeToList (name i)]
pure ([C.CDecl def items l], defs)
_ow -> do
let defs = [(idx', IEDelete) | i <- items, idx' <- maybeToList (name i)]
pure ([], defs)
filterStorageModifiers :: Bool -> [C.CDeclarationSpecifier C.NodeInfo] -> [C.CDeclarationSpecifier C.NodeInfo]
filterStorageModifiers isStatic = filter \case
C.CStorageSpec (C.CStatic _) -> isStatic
C.CFunSpec (C.CInlineQual _) -> isStatic
_ow -> True