-- ** Class or type declarations
TyClDecl(..), LTyClDecl,
isClassDecl, isSynDecl, isDataDecl, isTypeDecl, isFamilyDecl,
- isFamInstDecl, tcdName, tyClDeclNames, tyClDeclTyVars,
+ isFamInstDecl, tcdName, tyClDeclTyVars,
countTyClDecls,
-- ** Instance declarations
InstDecl(..), LInstDecl, NewOrData(..), FamilyFlavour(..),
-- ** @RULE@ declarations
RuleDecl(..), LRuleDecl, RuleBndr(..),
collectRuleBndrSigTys,
+ -- ** @VECTORISE@ declarations
+ VectDecl(..), LVectDecl,
-- ** @default@ declarations
DefaultDecl(..), LDefaultDecl,
-- ** Top-level template haskell splice
CImportSpec(..),
-- ** Data-constructor declarations
ConDecl(..), LConDecl, ResType(..),
- HsConDeclDetails, hsConDeclArgTys, hsConDeclsNames,
+ HsConDeclDetails, hsConDeclArgTys,
-- ** Document comments
DocDecl(..), LDocDecl, docDeclDoc,
-- ** Deprecations
) where
-- friends:
-import {-# SOURCE #-} HsExpr( HsExpr, pprExpr )
+import {-# SOURCE #-} HsExpr( LHsExpr, HsExpr, pprExpr )
-- Because Expr imports Decls via HsBracket
import HsBinds
| WarningD (WarnDecl id)
| AnnD (AnnDecl id)
| RuleD (RuleDecl id)
+ | VectD (VectDecl id)
| SpliceD (SpliceDecl id)
| DocD (DocDecl)
| QuasiQuoteD (HsQuasiQuote id)
data HsGroup id
= HsGroup {
hs_valds :: HsValBinds id,
- hs_tyclds :: [LTyClDecl id],
+
+ hs_tyclds :: [[LTyClDecl id]],
+ -- A list of mutually-recursive groups
+ -- Parser generates a singleton list;
+ -- renamer does dependency analysis
+
hs_instds :: [LInstDecl id],
hs_derivds :: [LDerivDecl id],
-- Snaffled out of both top-level fixity signatures,
-- and those in class declarations
- hs_defds :: [LDefaultDecl id],
- hs_fords :: [LForeignDecl id],
- hs_warnds :: [LWarnDecl id],
- hs_annds :: [LAnnDecl id],
- hs_ruleds :: [LRuleDecl id],
+ hs_defds :: [LDefaultDecl id],
+ hs_fords :: [LForeignDecl id],
+ hs_warnds :: [LWarnDecl id],
+ hs_annds :: [LAnnDecl id],
+ hs_ruleds :: [LRuleDecl id],
+ hs_vects :: [LVectDecl id],
- hs_docs :: [LDocDecl]
+ hs_docs :: [LDocDecl]
} deriving (Data, Typeable)
emptyGroup, emptyRdrGroup, emptyRnGroup :: HsGroup a
emptyGroup = HsGroup { hs_tyclds = [], hs_instds = [], hs_derivds = [],
hs_fixds = [], hs_defds = [], hs_annds = [],
- hs_fords = [], hs_warnds = [], hs_ruleds = [],
+ hs_fords = [], hs_warnds = [], hs_ruleds = [], hs_vects = [],
hs_valds = error "emptyGroup hs_valds: Can't happen",
hs_docs = [] }
appendGroups :: HsGroup a -> HsGroup a -> HsGroup a
appendGroups
HsGroup {
- hs_valds = val_groups1,
- hs_tyclds = tyclds1,
- hs_instds = instds1,
+ hs_valds = val_groups1,
+ hs_tyclds = tyclds1,
+ hs_instds = instds1,
hs_derivds = derivds1,
- hs_fixds = fixds1,
- hs_defds = defds1,
- hs_annds = annds1,
- hs_fords = fords1,
- hs_warnds = warnds1,
- hs_ruleds = rulds1,
+ hs_fixds = fixds1,
+ hs_defds = defds1,
+ hs_annds = annds1,
+ hs_fords = fords1,
+ hs_warnds = warnds1,
+ hs_ruleds = rulds1,
+ hs_vects = vects1,
hs_docs = docs1 }
HsGroup {
- hs_valds = val_groups2,
- hs_tyclds = tyclds2,
- hs_instds = instds2,
+ hs_valds = val_groups2,
+ hs_tyclds = tyclds2,
+ hs_instds = instds2,
hs_derivds = derivds2,
- hs_fixds = fixds2,
- hs_defds = defds2,
- hs_annds = annds2,
- hs_fords = fords2,
- hs_warnds = warnds2,
- hs_ruleds = rulds2,
- hs_docs = docs2 }
+ hs_fixds = fixds2,
+ hs_defds = defds2,
+ hs_annds = annds2,
+ hs_fords = fords2,
+ hs_warnds = warnds2,
+ hs_ruleds = rulds2,
+ hs_vects = vects2,
+ hs_docs = docs2 }
=
HsGroup {
- hs_valds = val_groups1 `plusHsValBinds` val_groups2,
- hs_tyclds = tyclds1 ++ tyclds2,
- hs_instds = instds1 ++ instds2,
+ hs_valds = val_groups1 `plusHsValBinds` val_groups2,
+ hs_tyclds = tyclds1 ++ tyclds2,
+ hs_instds = instds1 ++ instds2,
hs_derivds = derivds1 ++ derivds2,
- hs_fixds = fixds1 ++ fixds2,
- hs_annds = annds1 ++ annds2,
- hs_defds = defds1 ++ defds2,
- hs_fords = fords1 ++ fords2,
- hs_warnds = warnds1 ++ warnds2,
- hs_ruleds = rulds1 ++ rulds2,
- hs_docs = docs1 ++ docs2 }
+ hs_fixds = fixds1 ++ fixds2,
+ hs_annds = annds1 ++ annds2,
+ hs_defds = defds1 ++ defds2,
+ hs_fords = fords1 ++ fords2,
+ hs_warnds = warnds1 ++ warnds2,
+ hs_ruleds = rulds1 ++ rulds2,
+ hs_vects = vects1 ++ vects2,
+ hs_docs = docs1 ++ docs2 }
\end{code}
\begin{code}
ppr (ForD fd) = ppr fd
ppr (SigD sd) = ppr sd
ppr (RuleD rd) = ppr rd
+ ppr (VectD vect) = ppr vect
ppr (WarningD wd) = ppr wd
ppr (AnnD ad) = ppr ad
ppr (SpliceD dd) = ppr dd
hs_annds = ann_decls,
hs_fords = foreign_decls,
hs_defds = default_decls,
- hs_ruleds = rule_decls })
- = vcat [ppr_ds fix_decls, ppr_ds default_decls,
- ppr_ds deprec_decls, ppr_ds ann_decls,
- ppr_ds rule_decls,
- ppr val_decls,
- ppr_ds tycl_decls, ppr_ds inst_decls,
- ppr_ds deriv_decls,
- ppr_ds foreign_decls]
+ hs_ruleds = rule_decls,
+ hs_vects = vect_decls })
+ = vcat_mb empty
+ [ppr_ds fix_decls, ppr_ds default_decls,
+ ppr_ds deprec_decls, ppr_ds ann_decls,
+ ppr_ds rule_decls,
+ ppr_ds vect_decls,
+ if isEmptyValBinds val_decls
+ then Nothing
+ else Just (ppr val_decls),
+ ppr_ds (concat tycl_decls),
+ ppr_ds inst_decls,
+ ppr_ds deriv_decls,
+ ppr_ds foreign_decls]
where
- ppr_ds [] = empty
- ppr_ds ds = blankLine $$ vcat (map ppr ds)
+ ppr_ds :: Outputable a => [a] -> Maybe SDoc
+ ppr_ds [] = Nothing
+ ppr_ds ds = Just (vcat (map ppr ds))
+
+ vcat_mb :: SDoc -> [Maybe SDoc] -> SDoc
+ -- Concatenate vertically with white-space between non-blanks
+ vcat_mb _ [] = empty
+ vcat_mb gap (Nothing : ds) = vcat_mb gap ds
+ vcat_mb gap (Just d : ds) = gap $$ d $$ vcat_mb blankLine ds
data SpliceDecl id
= SpliceDecl -- Top level splice
tcdName :: TyClDecl name -> name
tcdName decl = unLoc (tcdLName decl)
-tyClDeclNames :: Eq name => TyClDecl name -> [Located name]
--- ^ Returns all the /binding/ names of the decl, along with their SrcLocs.
--- The first one is guaranteed to be the name of the decl. For record fields
--- mentioned in multiple constructors, the SrcLoc will be from the first
--- occurence. We use the equality to filter out duplicate field names
-
-tyClDeclNames (TyFamily {tcdLName = name}) = [name]
-tyClDeclNames (TySynonym {tcdLName = name}) = [name]
-tyClDeclNames (ForeignType {tcdLName = name}) = [name]
-
-tyClDeclNames (ClassDecl {tcdLName = cls_name, tcdSigs = sigs, tcdATs = ats})
- = cls_name :
- concatMap (tyClDeclNames . unLoc) ats ++ [n | L _ (TypeSig n _) <- sigs]
-
-tyClDeclNames (TyData {tcdLName = tc_name, tcdCons = cons})
- = tc_name : hsConDeclsNames cons
-
tyClDeclTyVars :: TyClDecl name -> [LHsTyVarBndr name]
tyClDeclTyVars (TyFamily {tcdTyVars = tvs}) = tvs
tyClDeclTyVars (TySynonym {tcdTyVars = tvs}) = tvs
top_matter = ptext (sLit "class")
<+> pp_decl_head (unLoc context) lclas tyvars Nothing
<+> pprFundeps (map unLoc fds)
+ ppr_semi :: Outputable a => a -> SDoc
ppr_semi decl = ppr decl <> semi
pp_decl_head :: OutputableBndr name
ppr (ResTyGADT ty) = ptext (sLit "ResTyGADT") <+> pprParendHsType (unLoc ty)
\end{code}
-\begin{code}
-hsConDeclsNames :: (Eq name) => [LConDecl name] -> [Located name]
- -- See tyClDeclNames for what this does
- -- The function is boringly complicated because of the records
- -- And since we only have equality, we have to be a little careful
-hsConDeclsNames cons
- = snd (foldl do_one ([], []) cons)
- where
- do_one (flds_seen, acc) (L _ (ConDecl { con_name = lname, con_details = RecCon flds }))
- = (map unLoc new_flds ++ flds_seen, lname : new_flds ++ acc)
- where
- new_flds = filterOut (\f -> unLoc f `elem` flds_seen)
- (map cd_fld_name flds)
-
- do_one (flds_seen, acc) (L _ (ConDecl { con_name = lname }))
- = (flds_seen, lname:acc)
-\end{code}
-
\begin{code}
instance (OutputableBndr name) => Outputable (ConDecl name) where
-- Extract the declarations of associated types from an instance
--
-instDeclATs :: InstDecl name -> [LTyClDecl name]
-instDeclATs (InstDecl _ _ _ ats) = ats
+instDeclATs :: [LInstDecl name] -> [LTyClDecl name]
+instDeclATs inst_decls = [at | L _ (InstDecl _ _ _ ats) <- inst_decls, at <- ats]
\end{code}
%************************************************************************
-- * `Safety' is irrelevant for `CLabel' and `CWrapper'
--
CImport CCallConv -- ccall or stdcall
- Safety -- safe or unsafe
+ Safety -- interruptible, safe or unsafe
FastString -- name of C header
CImportSpec -- details of the C entity
deriving (Data, Typeable)
ppr (RuleBndrSig name ty) = ppr name <> dcolon <> ppr ty
\end{code}
+
+%************************************************************************
+%* *
+\subsection{Vectorisation declarations}
+%* *
+%************************************************************************
+
+A vectorisation pragma
+
+ {-# VECTORISE f = closure1 g (scalar_map g) #-} OR
+ {-# VECTORISE SCALAR f #-}
+
+Note [Typechecked vectorisation pragmas]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In case of the first variant of vectorisation pragmas (with an explicit expression),
+we need to infer the type of that expression during type checking and then keep that type
+around until vectorisation, so that it can be checked against the *vectorised* type of 'f'.
+(We cannot determine vectorised types during type checking due to internal information of
+the vectoriser being needed.)
+
+To this end, we annotate the 'Id' of 'f' (the variable mentioned in the PRAGMA) with the
+inferred type of the expression. This is slightly dodgy, as this is really the type of
+'$v_f' (the name of the vectorised function).
+
+\begin{code}
+type LVectDecl name = Located (VectDecl name)
+
+data VectDecl name
+ = HsVect
+ (Located name)
+ (Maybe (LHsExpr name)) -- 'Nothing' => SCALAR declaration
+ deriving (Data, Typeable)
+
+instance OutputableBndr name => Outputable (VectDecl name) where
+ ppr (HsVect v rhs)
+ = sep [text "{-# VECTORISE" <+> ppr v,
+ nest 4 (case rhs of
+ Nothing -> text "SCALAR #-}"
+ Just rhs -> pprExpr (unLoc rhs) <+> text "#-}") ]
+\end{code}
+
%************************************************************************
%* *
\subsection[DocDecl]{Document comments}