[project @ 2002-09-13 15:02:25 by simonpj]
[ghc-hetmet.git] / ghc / compiler / utils / Panic.lhs
1 %
2 % (c) The GRASP Project, Glasgow University, 1992-2000
3 %
4 \section{Panic error messages}
5
6 Defines basic funtions for printing error messages.
7
8 It's hard to put these functions anywhere else without causing
9 some unnecessary loops in the module dependency graph.
10
11 \begin{code}
12 module Panic  
13    ( 
14      GhcException(..), ghcError, progName, 
15      panic, panic#, assertPanic, trace,
16      showException, showGhcException, throwDyn
17    ) where
18
19 #include "HsVersions.h"
20
21 import Config
22 import FastTypes
23
24 import DYNAMIC
25 import EXCEPTION
26 import TRACE            ( trace )
27 import UNSAFE_IO        ( unsafePerformIO )
28
29 import System
30 \end{code}
31
32 GHC's own exception type.
33
34 \begin{code}
35 ghcError :: GhcException -> a
36 ghcError e = throwDyn e
37
38 -- error messages all take the form
39 --
40 --      <location>: <error>
41 --
42 -- If the location is on the command line, or in GHC itself, then 
43 -- <location>="ghc".  All of the error types below correspond to 
44 -- a <location> of "ghc", except for ProgramError (where the string is
45 -- assumed to contain a location already, so we don't print one).
46
47 data GhcException
48   = PhaseFailed String          -- name of phase 
49                 ExitCode        -- an external phase (eg. cpp) failed
50   | Interrupted                 -- someone pressed ^C
51   | UsageError String           -- prints the short usage msg after the error
52   | CmdLineError String         -- cmdline prob, but doesn't print usage
53   | Panic String                -- the `impossible' happened
54   | InstallationError String    -- an installation problem
55   | ProgramError String         -- error in the user's code, probably
56   deriving Eq
57
58 progName = unsafePerformIO (getProgName)
59 {-# NOINLINE progName #-}
60
61 short_usage = "Usage: For basic information, try the `--help' option."
62    
63 showException :: Exception -> String
64 -- Show expected dynamic exceptions specially
65 showException (DynException d) | Just e <- fromDynamic d 
66                                = show (e::GhcException)
67 showException other_exn        = show other_exn
68
69 instance Show GhcException where
70   showsPrec _ e@(ProgramError _) = showGhcException e
71   showsPrec _ e = showString progName . showString ": " . showGhcException e
72
73 showGhcException (UsageError str)
74    = showString str . showChar '\n' . showString short_usage
75 showGhcException (PhaseFailed phase code)
76    = showString "phase `" . showString phase . 
77      showString "' failed (exitcode = " . shows int_code . 
78      showString ")"
79   where
80     int_code = 
81       case code of
82         ExitSuccess   -> (0::Int)
83         ExitFailure x -> x
84 showGhcException (CmdLineError str)
85    = showString str
86 showGhcException (ProgramError str)
87    = showString str
88 showGhcException (InstallationError str)
89    = showString str
90 showGhcException (Interrupted)
91    = showString "interrupted"
92 showGhcException (Panic s)
93    = showString ("panic! (the `impossible' happened, GHC version "
94                  ++ cProjectVersion ++ "):\n\t"
95                  ++ s ++ "\n\n"
96                  ++ "Please report it as a compiler bug "
97                  ++ "to glasgow-haskell-bugs@haskell.org,\n"
98                  ++ "or http://sourceforge.net/projects/ghc/.\n\n")
99
100 ghcExceptionTc = mkTyCon "GhcException"
101 {-# NOINLINE ghcExceptionTc #-}
102 instance Typeable GhcException where
103   typeOf _ = mkAppTy ghcExceptionTc []
104 \end{code}
105
106 Panics and asserts.
107
108 \begin{code}
109 panic :: String -> a
110 panic x = throwDyn (Panic x)
111
112 -- #-versions because panic can't return an unboxed int, and that's
113 -- what TAG_ is with GHC at the moment.  Ugh. (Simon)
114 -- No, man -- Too Beautiful! (Will)
115
116 panic# :: String -> FastInt
117 panic# s = case (panic s) of () -> _ILIT 0
118
119 assertPanic :: String -> Int -> a
120 assertPanic file line = 
121   throw (AssertionFailed 
122            ("ASSERT failed! file " ++ file ++ ", line " ++ show line))
123 \end{code}