module Language.C.Analysis.SemError (
InvalidASTError(..), invalidAST,
BadSpecifierError(..), badSpecifierError,
TypeMismatch(..), typeMismatch,
RedefError(..), RedefInfo(..), RedefKind(..), redefinition,
)
where
import Data.Typeable
import Language.C.Analysis.SemRep
import Language.C.Data.Error
import Language.C.Data.Node
newtype InvalidASTError = InvalidAST ErrorInfo deriving (Typeable)
instance Error InvalidASTError where
errorInfo (InvalidAST ei) = ei
changeErrorLevel (InvalidAST ei) lvl' = InvalidAST (changeErrorLevel ei lvl')
newtype BadSpecifierError = BadSpecifierError ErrorInfo deriving (Typeable)
instance Error BadSpecifierError where
errorInfo (BadSpecifierError ei) = ei
changeErrorLevel (BadSpecifierError ei) lvl' = BadSpecifierError (changeErrorLevel ei lvl')
data RedefError = RedefError ErrorLevel RedefInfo deriving Typeable
data RedefInfo = RedefInfo String RedefKind NodeInfo NodeInfo
data RedefKind = DuplicateDef | DiffKindRedecl | ShadowedDef | DisagreeLinkage |
NoLinkageOld
data TypeMismatch = TypeMismatch String (NodeInfo,Type) (NodeInfo,Type) deriving Typeable
instance Show InvalidASTError where show = showError "AST invariant violated"
invalidAST :: NodeInfo -> String -> InvalidASTError
invalidAST node_info msg = InvalidAST (mkErrorInfo LevelError msg node_info)
instance Show BadSpecifierError where show = showError "Bad specifier"
badSpecifierError :: NodeInfo -> String -> BadSpecifierError
badSpecifierError node_info msg = BadSpecifierError (mkErrorInfo LevelError msg node_info)
typeMismatch :: String -> (NodeInfo, Type) -> (NodeInfo,Type) -> TypeMismatch
typeMismatch = TypeMismatch
instance Show TypeMismatch where
show tm = showError "Type mismatch" (typeMismatchInfo tm)
instance Error TypeMismatch where
errorInfo = typeMismatchInfo
typeMismatchInfo :: TypeMismatch -> ErrorInfo
typeMismatchInfo (TypeMismatch reason (node1,_ty2) _t2) =
ErrorInfo LevelError (posOfNode node1) [reason]
instance Show RedefError where
show (RedefError lvl info) = showErrorInfo (redefErrLabel info) (redefErrorInfo lvl info)
instance Error RedefError where
errorInfo (RedefError lvl info) = redefErrorInfo lvl info
changeErrorLevel (RedefError _lvl info) lvl' = RedefError lvl' info
redefErrLabel :: RedefInfo -> String
redefErrLabel (RedefInfo ident _ _ _) = ident ++ " redefined"
redefErrorInfo :: ErrorLevel -> RedefInfo -> ErrorInfo
redefErrorInfo lvl info@(RedefInfo _ _ node old_node) =
ErrorInfo lvl (posOfNode node) ([redefErrReason info] ++ prevDeclMsg old_node)
redefErrReason :: RedefInfo -> String
redefErrReason (RedefInfo ident DuplicateDef _ _) = "duplicate definition of " ++ ident
redefErrReason (RedefInfo ident ShadowedDef _ _) = "this declaration of " ++ ident ++ " shadows a previous one"
redefErrReason (RedefInfo ident DiffKindRedecl _ _) = ident ++ " previously declared as a different kind of symbol"
redefErrReason (RedefInfo ident DisagreeLinkage _ _) = ident ++ " previously declared with different linkage"
redefErrReason (RedefInfo ident NoLinkageOld _ _) = ident ++ " previously declared without linkage"
prevDeclMsg :: NodeInfo -> [String]
prevDeclMsg old_node = ["The previous declaration was here: ", show (posOfNode old_node)]
redefinition :: ErrorLevel -> String -> RedefKind -> NodeInfo -> NodeInfo -> RedefError
redefinition lvl ctx kind new old = RedefError lvl (RedefInfo ctx kind new old)