/libraries/base/GHC/Stack.hs

https://github.com/jberthold/ghc · Haskell · 104 lines · 49 code · 12 blank · 43 comment · 5 complexity · f7c4daf72b3f36fb3a71982a609aa2e4 MD5 · raw file

  1. {-# LANGUAGE Trustworthy #-}
  2. -----------------------------------------------------------------------------
  3. -- |
  4. -- Module : GHC.Stack
  5. -- Copyright : (c) The University of Glasgow 2011
  6. -- License : see libraries/base/LICENSE
  7. --
  8. -- Maintainer : cvs-ghc@haskell.org
  9. -- Stability : internal
  10. -- Portability : non-portable (GHC Extensions)
  11. --
  12. -- Access to GHC's call-stack simulation
  13. --
  14. -- @since 4.5.0.0
  15. -----------------------------------------------------------------------------
  16. {-# LANGUAGE MagicHash, NoImplicitPrelude, ImplicitParams, RankNTypes #-}
  17. module GHC.Stack (
  18. errorWithStackTrace,
  19. -- * Profiling call stacks
  20. currentCallStack,
  21. whoCreated,
  22. -- * HasCallStack call stacks
  23. CallStack, HasCallStack, callStack, emptyCallStack, freezeCallStack,
  24. fromCallSiteList, getCallStack, popCallStack, prettyCallStack,
  25. pushCallStack, withFrozenCallStack,
  26. -- * Source locations
  27. SrcLoc(..), prettySrcLoc,
  28. -- * Internals
  29. CostCentreStack,
  30. CostCentre,
  31. getCurrentCCS,
  32. getCCSOf,
  33. clearCCS,
  34. ccsCC,
  35. ccsParent,
  36. ccLabel,
  37. ccModule,
  38. ccSrcSpan,
  39. ccsToStrings,
  40. renderStack
  41. ) where
  42. import GHC.Stack.CCS
  43. import GHC.Stack.Types
  44. import GHC.IO
  45. import GHC.Base
  46. import GHC.List
  47. import GHC.Exception
  48. -- | Like the function 'error', but appends a stack trace to the error
  49. -- message if one is available.
  50. --
  51. -- @since 4.7.0.0
  52. {-# DEPRECATED errorWithStackTrace "'error' appends the call stack now" #-}
  53. -- DEPRECATED in 8.0.1
  54. errorWithStackTrace :: String -> a
  55. errorWithStackTrace x = unsafeDupablePerformIO $ do
  56. stack <- ccsToStrings =<< getCurrentCCS x
  57. if null stack
  58. then throwIO (ErrorCall x)
  59. else throwIO (ErrorCallWithLocation x (renderStack stack))
  60. -- | Pop the most recent call-site off the 'CallStack'.
  61. --
  62. -- This function, like 'pushCallStack', has no effect on a frozen 'CallStack'.
  63. --
  64. -- @since 4.9.0.0
  65. popCallStack :: CallStack -> CallStack
  66. popCallStack stk = case stk of
  67. EmptyCallStack -> errorWithoutStackTrace "popCallStack: empty stack"
  68. PushCallStack _ _ stk' -> stk'
  69. FreezeCallStack _ -> stk
  70. {-# INLINE popCallStack #-}
  71. -- | Return the current 'CallStack'.
  72. --
  73. -- Does *not* include the call-site of 'callStack'.
  74. --
  75. -- @since 4.9.0.0
  76. callStack :: HasCallStack => CallStack
  77. callStack =
  78. case ?callStack of
  79. EmptyCallStack -> EmptyCallStack
  80. _ -> popCallStack ?callStack
  81. {-# INLINE callStack #-}
  82. -- | Perform some computation without adding new entries to the 'CallStack'.
  83. --
  84. -- @since 4.9.0.0
  85. withFrozenCallStack :: HasCallStack
  86. => ( HasCallStack => a )
  87. -> a
  88. withFrozenCallStack do_this =
  89. -- we pop the stack before freezing it to remove
  90. -- withFrozenCallStack's call-site
  91. let ?callStack = freezeCallStack (popCallStack callStack)
  92. in do_this