import HscTypes
import StaticFlags
import UniqFM
+import Type
+import TyCon
+import FiniteMap
import Data.Array
import System.Time (ClockTime(..))
:: DynFlags
-> Module
-> ModLocation -- of the current module
+ -> [TyCon] -- type constructor in this module
-> LHsBinds Id
-> IO (LHsBinds Id, HpcInfo, ModBreaks)
-addCoverageTicksToBinds dflags mod mod_loc binds = do
+addCoverageTicksToBinds dflags mod mod_loc tyCons binds = do
let orig_file =
case ml_hs_file mod_loc of
Just file -> file
{ modName = mod_name
, declPath = []
, inScope = emptyVarSet
+ , blackList = listToFM [ (getSrcSpan (tyConName tyCon),())
+ | tyCon <- tyCons ]
})
(TT
{ tickBoxCount = 0
addTickLHsBinds binds = mapBagM addTickLHsBind binds
addTickLHsBind :: LHsBind Id -> TM (LHsBind Id)
-addTickLHsBind (L pos (AbsBinds abs_tvs abs_dicts abs_exports abs_binds)) = do
+addTickLHsBind (L pos t@(AbsBinds abs_tvs abs_dicts abs_exports abs_binds)) = do
abs_binds' <- addTickLHsBinds abs_binds
return $ L pos $ AbsBinds abs_tvs abs_dicts abs_exports abs_binds'
-
addTickLHsBind (L pos (funBind@(FunBind { fun_id = (L _ id) }))) = do
let name = getOccString id
decl_path <- getPathEntry
addPathEntry name $
addTickMatchGroup (fun_matches funBind)
+ blackListed <- isBlackListed pos
+
-- Todo: we don't want redundant ticks on simple pattern bindings
- if not opt_Hpc && isSimplePatBind funBind
+ -- We don't want to generate code for blacklisted positions
+ if blackListed || (not opt_Hpc && isSimplePatBind funBind)
then
return $ L pos $ funBind { fun_matches = MatchGroup matches' ty
, fun_tick = Nothing
-}
addTickLHsBind other = return other
--- add a tick to the expression no matter what it is
+-- Add a tick to the expression no matter what it is. There is one exception:
+-- for the debugger, if the expression is a 'let', then we don't want to add
+-- a tick here because there will definititely be a tick on the body anyway.
addTickLHsExprAlways :: LHsExpr Id -> TM (LHsExpr Id)
-addTickLHsExprAlways (L pos e0) = do
- allocTickBox (ExpBox False) pos $ addTickHsExpr e0
+addTickLHsExprAlways (L pos e0)
+ | not opt_Hpc, HsLet _ _ <- e0 = addTickLHsExprNever (L pos e0)
+ | otherwise = allocTickBox (ExpBox False) pos $ addTickHsExpr e0
addTickLHsExprNeverOrAlways :: LHsExpr Id -> TM (LHsExpr Id)
addTickLHsExprNeverOrAlways e
(addTickLHsExprOptAlt True e2)
(addTickLHsExprOptAlt True e3)
addTickHsExpr (HsLet binds e) =
+ bindLocals (map unLoc $ collectLocalBinders binds) $
liftM2 HsLet
- (addTickHsLocalBinds binds) -- to think about: !patterns.
- (bindLocals (map unLoc $ collectLocalBinders binds) $
- addTickLHsExprNeverOrAlways e)
+ (addTickHsLocalBinds binds) -- to think about: !patterns.
+ (addTickLHsExprNeverOrAlways e)
addTickHsExpr (HsDo cxt stmts last_exp srcloc) = do
(stmts', last_exp') <- addTickLStmts' forQual stmts
(addTickLHsExpr last_exp)
data TickTransEnv = TTE { modName :: String
, declPath :: [String]
, inScope :: VarSet
+ , blackList :: FiniteMap SrcSpan ()
}
-- deriving Show
(r, fv, st') -> (r, fv `delListFromUFM` occs, st')
where occs = [ nameOccName (idName id) | id <- new_ids ]
+isBlackListed :: SrcSpan -> TM Bool
+isBlackListed pos = TM $ \ env st ->
+ case lookupFM (blackList env) pos of
+ Nothing -> (False,noFVs,st)
+ Just () -> (True,noFVs,st)
+
-- the tick application inherits the source position of its
-- expression argument to support nested box allocations
allocTickBox :: BoxLabel -> SrcSpan -> TM (HsExpr Id) -> TM (LHsExpr Id)