packages feed

clang-pure 0.2.0.1 → 0.2.0.2

raw patch · 8 files changed

+143/−45 lines, 8 filesdep ~basedep ~bytestringnew-component:exe:list-structsPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

Dependency ranges changed: base, bytestring

API changes (from Hackage documentation)

+ Language.C.Clang.Cursor: TypeLayoutErrorDependent :: TypeLayoutError
+ Language.C.Clang.Cursor: TypeLayoutErrorIncomplete :: TypeLayoutError
+ Language.C.Clang.Cursor: TypeLayoutErrorInvalid :: TypeLayoutError
+ Language.C.Clang.Cursor: cursorDescendants :: Cursor -> [Cursor]
+ Language.C.Clang.Cursor: cursorDescendantsF :: Fold Cursor Cursor
+ Language.C.Clang.Cursor: data TypeLayoutError
+ Language.C.Clang.Cursor: offsetOfField :: Cursor -> Either TypeLayoutError Word64
+ Language.C.Clang.Cursor.Typed: TypeLayoutErrorDependent :: TypeLayoutError
+ Language.C.Clang.Cursor.Typed: TypeLayoutErrorIncomplete :: TypeLayoutError
+ Language.C.Clang.Cursor.Typed: TypeLayoutErrorInvalid :: TypeLayoutError
+ Language.C.Clang.Cursor.Typed: cursorDescendants :: CursorK kind -> [Cursor]
+ Language.C.Clang.Cursor.Typed: cursorDescendantsF :: Fold (CursorK kind) Cursor
+ Language.C.Clang.Cursor.Typed: data TypeLayoutError
+ Language.C.Clang.Cursor.Typed: instance GHC.Show.Show (Language.C.Clang.Cursor.Typed.CursorK kind)
+ Language.C.Clang.Cursor.Typed: instance Language.C.Clang.Cursor.Typed.HasSpelling 'Language.C.Clang.Internal.Types.FieldDecl
+ Language.C.Clang.Cursor.Typed: instance Language.C.Clang.Cursor.Typed.HasSpelling 'Language.C.Clang.Internal.Types.StructDecl
+ Language.C.Clang.Cursor.Typed: offsetOfField :: CursorK FieldDecl -> Either TypeLayoutError Word64

Files

app/FindClasses.hs view
@@ -64,4 +64,4 @@ findClass :: HasClass -> Cursor -> HMS.HashMap CursorKind Bool findClass HasClass {..} root = HMS.fromListWith combineResults kindResults   where-    kindResults = root ^.. cosmosOf cursorChildrenF . to (\c -> ( cursorKind c, predicate c ) )+    kindResults = root ^.. cursorDescendantsF . to (\c -> ( cursorKind c, predicate c ) )
clang-pure.cabal view
@@ -1,5 +1,5 @@ name:                  clang-pure-version:               0.2.0.1+version:               0.2.0.2 synopsis:              Pure C++ code analysis with libclang description:   Pure C++ code analysis with libclang.@@ -74,6 +74,15 @@  executable list-fun-types   main-is:             ListTypes.hs+  build-depends:       base, clang-pure, lens, bytestring+  hs-source-dirs:      examples+  buildable:           False+  ghc-options:         -Wall -O2+  if impl(ghc >= 8.0.0)+    ghc-options: -fno-warn-redundant-constraints++executable list-structs+  main-is:             ListStructs.hs   build-depends:       base, clang-pure, lens, bytestring   hs-source-dirs:      examples   buildable:           False
+ examples/ListStructs.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE OverloadedStrings #-}++import           Language.C.Clang+import           Language.C.Clang.Cursor.Typed+import           Control.Lens+import qualified Data.ByteString.Char8 as BS+import           Data.Monoid+import           Data.Word+import           System.Environment++data CField = CField+  { cFieldName :: BS.ByteString+  , cFieldOffset :: Word64+  , cFieldType :: Type+  } deriving (Show)++data CStruct = CStruct+  { cStructName :: BS.ByteString+  , cStructFields :: [ CField ]+  } deriving (Show)++main :: IO ()+main = do+  args <- getArgs+  case args of+    path : clangArgs -> do+      idx <- createIndex+      tu <- parseTranslationUnit idx path clangArgs++      let toCField fieldDecC = do+            offset <- offsetOfField fieldDecC+            return $ CField+              { cFieldName = cursorSpelling fieldDecC+              , cFieldOffset = offset+              , cFieldType = cursorType fieldDecC+              }++      let toCStruct structDecC = do+            let fieldDecs =+                  structDecC+                    ^.. cursorDescendantsF+                      . folding (matchKind @'FieldDecl)+            cFields <- traverse toCField fieldDecs+            return $ CStruct (cursorSpelling structDecC) cFields++      let cStructs =+            translationUnitCursor tu+              ^.. cursorDescendantsF+                . folding (matchKind @'StructDecl)+                . to toCStruct+                . _Right++      print cStructs++    _ -> putStrLn "usage: list-structs path [clang opts]"
examples/ListTypes.hs view
@@ -1,30 +1,8 @@-{--Copyright 2014 Google Inc. All Rights Reserved.--Licensed under the Apache License, Version 2.0 (the "License");-you may not use this file except in compliance with the License.-You may obtain a copy of the License at--    http://www.apache.org/licenses/LICENSE-2.0--Unless required by applicable law or agreed to in writing, software-distributed under the License is distributed on an "AS IS" BASIS,-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.-See the License for the specific language governing permissions and-limitations under the License.--}--{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE ViewPatterns #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE OverloadedStrings #-}  import           Language.C.Clang-import qualified Language.C.Clang.Cursor as UT import           Language.C.Clang.Cursor.Typed import           Control.Lens import qualified Data.ByteString.Char8 as BS@@ -39,7 +17,7 @@       idx <- createIndex       tu <- parseTranslationUnit idx path clangArgs       let funDecs =-              cosmosOnOf cursorChildrenF UT.cursorChildrenF         -- fold over cursors recursively+              cursorDescendantsF                                    -- fold over cursors recursively             . folding (matchKind @'FunctionDecl)                    -- find only FunctionDecls...             . filtered (isFromMainFile . rangeStart . cursorExtent) -- ...that are actually in the given file             . to (\funDec -> cursorSpelling funDec <> " :: " <> typeSpelling (cursorType funDec))
src/Language/C/Clang/Cursor.hs view
@@ -27,20 +27,38 @@   , cursorTranslationUnit   , cursorChildrenF   , cursorChildren+  , cursorDescendantsF+  , cursorDescendants   , cursorSpelling   , cursorExtent   , cursorUSR   , cursorReferenced   , cursorType   , cursorKind++  , TypeLayoutError(..)+  , offsetOfField   , CursorKind(..)   ) where +import Data.Functor.Contravariant+import Lens.Micro+import Lens.Micro.Contra+ import Language.C.Clang.Internal.FFI import Language.C.Clang.Internal.Types -import Lens.Micro- cursorChildren :: Cursor -> [ Cursor ] cursorChildren = toListOf cursorChildrenF++cosmosOf :: (Applicative f, Contravariant f) => LensLike' f a a -> LensLike' f a a+cosmosOf d f s = f s *> d (cosmosOf d f) s++-- | `Fold` over a `Cursor` and all of its descendants recursively.+cursorDescendantsF :: Fold Cursor Cursor+cursorDescendantsF = cosmosOf cursorChildrenF++-- | List a `Cursor` and all of its descendants recursively.+cursorDescendants :: Cursor -> [ Cursor ]+cursorDescendants = toListOf cursorDescendantsF
src/Language/C/Clang/Cursor/Typed.hs view
@@ -23,11 +23,16 @@    , cursorChildrenF   , cursorChildren+  , cursorDescendantsF+  , cursorDescendants    , cursorExtent    , cursorSpelling +  , TypeLayoutError(..)+  , offsetOfField+   , HasType   , HasChildren   , HasExtent@@ -39,19 +44,19 @@ import           Data.Functor.Contravariant import           Data.Maybe import           Data.Singletons+import           Data.Word import           Lens.Micro.Contra  import qualified Language.C.Clang.Cursor as UT import           Language.C.Clang.Cursor ( cursorKind, Cursor, CursorKind(..) ) import           Language.C.Clang.Location-import           Language.C.Clang.Type-import           Language.C.Clang.TranslationUnit+import           Language.C.Clang.Internal.Types  import           Language.C.Clang.Internal.Refs (Clang)  -- | A `Cursor` with a statically known `CursorKind`. newtype CursorK (kind :: CursorKind) = CursorK { withoutKind :: Cursor }-  deriving (Eq, Clang)+  deriving (Eq, Clang, Show)  -- | Match a `Cursor` as a particular `CursorKind`. You can use the @TypeApplications@ extension to easily specify the `CursorKind` you want: @matchKind \@'StructDecl@. matchKind :: forall kind. SingI kind => Cursor -> Maybe (CursorK kind)@@ -77,6 +82,14 @@ cursorChildren :: HasChildren kind => CursorK kind -> [ Cursor ] cursorChildren = UT.cursorChildren . withoutKind +-- | `Fold` over a `CursorK` and all of its descendants recursively.+cursorDescendantsF :: Fold (CursorK kind) Cursor+cursorDescendantsF = to withoutKind . UT.cursorDescendantsF++-- | List a `CursorK` and all of its descendants recursively.+cursorDescendants :: CursorK kind -> [ Cursor ]+cursorDescendants = UT.cursorDescendants . withoutKind+ class HasExtent (kind :: CursorKind)  cursorExtent :: HasExtent kind => CursorK kind -> SourceRange@@ -87,6 +100,9 @@ cursorSpelling :: HasSpelling kind => CursorK kind -> BS.ByteString cursorSpelling = UT.cursorSpelling . withoutKind +offsetOfField :: CursorK 'FieldDecl -> Either TypeLayoutError Word64+offsetOfField = UT.offsetOfField . withoutKind+ -- instances derived experimentally with the find-classes executable instance HasChildren 'ArraySubscriptExpr instance HasChildren 'BinaryOperator@@ -274,6 +290,7 @@ instance HasSpelling 'ConversionFunction instance HasSpelling 'Destructor instance HasSpelling 'EnumConstantDecl+instance HasSpelling 'FieldDecl instance HasSpelling 'FunctionDecl instance HasSpelling 'FunctionTemplate instance HasSpelling 'MemberRef@@ -281,6 +298,7 @@ instance HasSpelling 'NamespaceRef instance HasSpelling 'OverloadedDeclRef instance HasSpelling 'StringLiteral+instance HasSpelling 'StructDecl instance HasSpelling 'TemplateRef instance HasSpelling 'TranslationUnit instance HasSpelling 'TypeRef
src/Language/C/Clang/Internal/FFI.hsc view
@@ -78,17 +78,20 @@ parseTranslationUnit idx path args = do   tun <- newNode idx $ \idxp ->     withCString path $ \cPath -> do-      cArgs <- VS.fromList <$> traverse newCString args-      ( tup, cres ) <- C.withPtr $ \tupp -> [C.exp| int {-        clang_parseTranslationUnit2(-          $(CXIndex idxp),-          $(char* cPath),-          $vec-ptr:(const char * const * cArgs), $vec-len:cArgs,-          NULL, 0,-          0,-          $(CXTranslationUnit *tupp))-        } |]-      traverse_ free $ VS.toList cArgs+      ( tup, cres ) <- bracket+        (traverse newCString args)+        (traverse_ free) $+        \cArgList -> do+          let cArgs = VS.fromList cArgList+          C.withPtr $ \tupp -> [C.exp| int {+            clang_parseTranslationUnit2(+              $(CXIndex idxp),+              $(char* cPath),+              $vec-ptr:(const char * const * cArgs), $vec-len:cArgs,+              NULL, 0,+              0,+              $(CXTranslationUnit *tupp))+            } |]       let res = parseClangError cres       when (res /= Success) $ throwIO res       return ( tup, clang_disposeTranslationUnit tup )@@ -131,10 +134,10 @@ withCXString :: (Ptr CXString -> IO ()) -> IO ByteString withCXString f = allocaBytes (#size CXString) $ \cxsp -> do   f cxsp-  cs <- [C.exp| const char * { clang_getCString(*$(CXString *cxsp)) } |]-  s <- BS.packCString cs-  [C.exp| void { clang_disposeString(*$(CXString *cxsp)) } |]-  return s+  bracket+    [C.exp| const char * { clang_getCString(*$(CXString *cxsp)) } |]+    (\_ -> [C.exp| void { clang_disposeString(*$(CXString *cxsp)) } |]) $+    \cs -> BS.packCString cs  cursorSpelling :: Cursor -> ByteString cursorSpelling c = uderef c $ \cp -> withCXString $ \cxsp ->@@ -607,3 +610,12 @@     "File { fileName = "     ++ show (fileName f)     ++ "}"++offsetOfField :: Cursor -> Either TypeLayoutError Word64+offsetOfField c = uderef c $ \cp -> do+  res <- [C.exp| long long { clang_Cursor_getOffsetOfField(*$(CXCursor* cp)) } |]+  return $ case res of+    #{const CXTypeLayoutError_Invalid} -> Left TypeLayoutErrorInvalid+    #{const CXTypeLayoutError_Incomplete} -> Left TypeLayoutErrorIncomplete+    #{const CXTypeLayoutError_Dependent} -> Left TypeLayoutErrorDependent+    n -> Right (fromIntegral n)
src/Language/C/Clang/Internal/Types.hs view
@@ -343,3 +343,9 @@ type instance RefOf Token = CXToken type instance ParentOf Token = TranslationUnit data Token = Token TokenSet Int++data TypeLayoutError+  = TypeLayoutErrorInvalid+  | TypeLayoutErrorIncomplete+  | TypeLayoutErrorDependent+    deriving (Eq, Ord, Show)