libclang-bindings-0.1.0.0: src/Clang/HighLevel/Evaluate.hs
module Clang.HighLevel.Evaluate (
-- * Types
EvalResult(..)
-- * API
, clang_evaluate
) where
import Control.Monad.Catch
import Control.Monad.IO.Class
import Foreign.C qualified as C
import Clang.Enum.Simple
import Clang.LowLevel.Core
{-------------------------------------------------------------------------------
Types
-------------------------------------------------------------------------------}
-- | Evaluation result
data EvalResult =
-- | Result as an 'Integer'
EvalResultInteger Integer
| -- | Result as a 'C.CDouble'
EvalResultCDouble C.CDouble
| -- | Result as a 'String'
EvalResultString String
deriving stock (Show)
{-------------------------------------------------------------------------------
API
-------------------------------------------------------------------------------}
-- | Evaluate a statement, variable (initializer), or expression
--
-- LLVM/Clang documentation is sparse, and enumeration 'CXEvalResultKind'
-- specifies kinds that do not exactly match the API for getting evaluation
-- results. Any use of this function should be tested thoroughly.
clang_evaluate :: (MonadIO m, MonadMask m) => CXCursor -> m (Maybe EvalResult)
clang_evaluate cursor =
bracket (clang_Cursor_Evaluate cursor) clang_EvalResult_dispose $ \er ->
(fromSimpleEnum <$> clang_EvalResult_getKind er) >>= \case
Left{} -> return Nothing
Right CXEval_UnExposed -> return Nothing
Right CXEval_Int -> fmap (Just . EvalResultInteger) $ do
isUnsigned <- clang_EvalResult_isUnsignedInt er
if isUnsigned
then toInteger <$> clang_EvalResult_getAsUnsigned er
else toInteger <$> clang_EvalResult_getAsLongLong er
Right CXEval_Float ->
Just . EvalResultCDouble <$> clang_EvalResult_getAsDouble er
Right{} ->
Just . EvalResultString <$> clang_EvalResult_getAsStr er