+\begin{code}
+--------------------------------
+tyClDeclName :: TyClDecl name pat -> name
+tyClDeclName tycl_decl = tcdName tycl_decl
+
+--------------------------------
+tyClDeclNames :: Eq name => TyClDecl name pat -> [(name, SrcLoc)]
+-- 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, the first one counts as the SrcLoc
+-- We use the equality to filter out duplicate field names
+
+tyClDeclNames (TySynonym {tcdName = name, tcdLoc = loc}) = [(name,loc)]
+tyClDeclNames (IfaceSig {tcdName = name, tcdLoc = loc}) = [(name,loc)]
+tyClDeclNames (ForeignType {tcdName = name, tcdLoc = loc}) = [(name,loc)]
+
+tyClDeclNames (ClassDecl {tcdName = cls_name, tcdSigs = sigs, tcdLoc = loc})
+ = (cls_name,loc) : [(n,loc) | ClassOpSig n _ _ loc <- sigs]
+
+tyClDeclNames (TyData {tcdName = tc_name, tcdCons = cons, tcdLoc = loc})
+ = (tc_name,loc) : conDeclsNames cons
+
+
+tyClDeclTyVars (TySynonym {tcdTyVars = tvs}) = tvs
+tyClDeclTyVars (TyData {tcdTyVars = tvs}) = tvs
+tyClDeclTyVars (ClassDecl {tcdTyVars = tvs}) = tvs
+tyClDeclTyVars (ForeignType {}) = []
+tyClDeclTyVars (IfaceSig {}) = []
+
+
+--------------------------------
+-- The "system names" are extra implicit names *bound* by the decl.
+-- They are kept in a list rather than a tuple
+-- to make the renamer easier.
+
+type ClassSysNames name = [name]
+-- For class decls they are:
+-- [tycon, datacon wrapper, datacon worker,
+-- superclass selector 1, ..., superclass selector n]
+
+type DataSysNames name = [name]
+-- For data decls they are
+-- [from, to]
+-- where from :: T -> Tring
+-- to :: Tring -> T
+
+tyClDeclSysNames :: TyClDecl name pat -> [(name, SrcLoc)]
+-- Similar to tyClDeclNames, but returns the "implicit"
+-- or "system" names of the declaration
+
+tyClDeclSysNames (ClassDecl {tcdSysNames = names, tcdLoc = loc})
+ = [(n,loc) | n <- names]
+tyClDeclSysNames (TyData {tcdCons = cons, tcdSysNames = names, tcdLoc = loc})
+ = [(n,loc) | n <- names] ++
+ [(wkr_name,loc) | ConDecl _ wkr_name _ _ _ loc <- cons]
+tyClDeclSysNames decl = []
+
+
+mkClassDeclSysNames :: (name, name, name, [name]) -> [name]
+getClassDeclSysNames :: [name] -> (name, name, name, [name])
+mkClassDeclSysNames (a,b,c,ds) = a:b:c:ds
+getClassDeclSysNames (a:b:c:ds) = (a,b,c,ds)
+\end{code}
+
+\begin{code}
+instance (NamedThing name, Ord name) => Eq (TyClDecl name pat) where
+ -- Used only when building interface files
+ (==) d1@(IfaceSig {}) d2@(IfaceSig {})
+ = tcdName d1 == tcdName d2 &&
+ tcdType d1 == tcdType d2 &&
+ tcdIdInfo d1 == tcdIdInfo d2
+
+ (==) d1@(ForeignType {}) d2@(ForeignType {})
+ = tcdName d1 == tcdName d2 &&
+ tcdFoType d1 == tcdFoType d2
+
+ (==) d1@(TyData {}) d2@(TyData {})
+ = tcdName d1 == tcdName d2 &&
+ tcdND d1 == tcdND d2 &&
+ eqWithHsTyVars (tcdTyVars d1) (tcdTyVars d2) (\ env ->
+ eq_hsContext env (tcdCtxt d1) (tcdCtxt d2) &&
+ eqListBy (eq_ConDecl env) (tcdCons d1) (tcdCons d2)
+ )
+
+ (==) d1@(TySynonym {}) d2@(TySynonym {})
+ = tcdName d1 == tcdName d2 &&
+ eqWithHsTyVars (tcdTyVars d1) (tcdTyVars d2) (\ env ->
+ eq_hsType env (tcdSynRhs d1) (tcdSynRhs d2)
+ )
+
+ (==) d1@(ClassDecl {}) d2@(ClassDecl {})
+ = tcdName d1 == tcdName d2 &&
+ eqWithHsTyVars (tcdTyVars d1) (tcdTyVars d2) (\ env ->
+ eq_hsContext env (tcdCtxt d1) (tcdCtxt d2) &&
+ eqListBy (eq_hsFD env) (tcdFDs d1) (tcdFDs d2) &&
+ eqListBy (eq_cls_sig env) (tcdSigs d1) (tcdSigs d2)
+ )
+
+ (==) _ _ = False -- default case
+
+eq_hsFD env (ns1,ms1) (ns2,ms2)
+ = eqListBy (eq_hsVar env) ns1 ns2 && eqListBy (eq_hsVar env) ms1 ms2
+
+eq_cls_sig env (ClassOpSig n1 dm1 ty1 _) (ClassOpSig n2 dm2 ty2 _)
+ = n1==n2 && dm1 `eq_dm` dm2 && eq_hsType env ty1 ty2
+ where
+ -- Ignore the name of the default method for (DefMeth id)
+ -- This is used for comparing declarations before putting
+ -- them into interface files, and the name of the default
+ -- method isn't relevant
+ NoDefMeth `eq_dm` NoDefMeth = True
+ GenDefMeth `eq_dm` GenDefMeth = True
+ DefMeth _ `eq_dm` DefMeth _ = True
+ dm1 `eq_dm` dm2 = False
+
+