ghc-8.10.0.20191210: The GHC API
Safe HaskellNone
LanguageHaskell2010

Literal

Synopsis

Main data type

data Literal Source #

So-called Literals are one of:

  • An unboxed numeric literal or floating-point literal which is presumed to be surrounded by appropriate constructors (Int#, etc.), so that the overall thing makes sense.

We maintain the invariant that the Integer in the LitNumber constructor is actually in the (possibly target-dependent) range. The mkLit{Int,Word}*Wrap smart constructors ensure this by applying the target machine's wrapping semantics. Use these in situations where you know the wrapping semantics are correct.

  • The literal derived from the label mentioned in a "foreign label" declaration (LitLabel)
  • A LitRubbish to be used in place of values of UnliftedRep (i.e. 'MutVar#') when the the value is never used.
  • A character
  • A string
  • The NULL pointer

Constructors

LitChar Char

Char# - at least 31 bits. Create with mkLitChar

LitNumber !LitNumType !Integer Type

Any numeric literal that can be internally represented with an Integer. See Note [Types of LitNumbers] below for the Type field.

LitString ByteString

A string-literal: stored and emitted UTF-8 encoded, we'll arrange to decode it at runtime. Also emitted with a '\0' terminator. Create with mkLitString

LitNullAddr

The NULL pointer, the only pointer value that can be represented as a Literal. Create with nullAddrLit

LitRubbish

A nonsense value, used when an unlifted binding is absent and has type forall (a :: TYPE UnliftedRep). a. May be lowered by code-gen to any possible value. Also see Note [Rubbish literals]

LitFloat Rational

Float#. Create with mkLitFloat

LitDouble Rational

Double#. Create with mkLitDouble

LitLabel FastString (Maybe Int) FunctionOrData

A label literal. Parameters:

1) The name of the symbol mentioned in the declaration

2) The size (in bytes) of the arguments the label expects. Only applicable with stdcall labels. Just x => <x> will be appended to label name when emitting assembly.

3) Flag indicating whether the symbol references a function or a data

Instances

Instances details
Eq Literal # 
Instance details

Defined in Literal

Methods

(==) :: Literal -> Literal -> Bool #

(/=) :: Literal -> Literal -> Bool #

Data Literal # 
Instance details

Defined in Literal

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Literal -> c Literal Source #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c Literal Source #

toConstr :: Literal -> Constr Source #

dataTypeOf :: Literal -> DataType Source #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c Literal) Source #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Literal) Source #

gmapT :: (forall b. Data b => b -> b) -> Literal -> Literal Source #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Literal -> r Source #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Literal -> r Source #

gmapQ :: (forall d. Data d => d -> u) -> Literal -> [u] Source #

gmapQi :: Int -> (forall d. Data d => d -> u) -> Literal -> u Source #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> Literal -> m Literal Source #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Literal -> m Literal Source #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Literal -> m Literal Source #

Ord Literal #

Needed for the Ord instance of AltCon, which in turn is needed in CoreMap.

Instance details

Defined in Literal

Outputable Literal # 
Instance details

Defined in Literal

Binary Literal # 
Instance details

Defined in Literal

data LitNumType Source #

Numeric literal type

Constructors

LitNumInteger

Integer (see Note [Integer literals])

LitNumNatural

Natural (see Note [Natural literals])

LitNumInt

Int# - according to target machine

LitNumInt64

Int64# - exactly 64 bits

LitNumWord

Word# - according to target machine

LitNumWord64

Word64# - exactly 64 bits

Instances

Instances details
Enum LitNumType # 
Instance details

Defined in Literal

Eq LitNumType # 
Instance details

Defined in Literal

Data LitNumType # 
Instance details

Defined in Literal

Methods

gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> LitNumType -> c LitNumType Source #

gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c LitNumType Source #

toConstr :: LitNumType -> Constr Source #

dataTypeOf :: LitNumType -> DataType Source #

dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c LitNumType) Source #

dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c LitNumType) Source #

gmapT :: (forall b. Data b => b -> b) -> LitNumType -> LitNumType Source #

gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> LitNumType -> r Source #

gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> LitNumType -> r Source #

gmapQ :: (forall d. Data d => d -> u) -> LitNumType -> [u] Source #

gmapQi :: Int -> (forall d. Data d => d -> u) -> LitNumType -> u Source #

gmapM :: Monad m => (forall d. Data d => d -> m d) -> LitNumType -> m LitNumType Source #

gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> LitNumType -> m LitNumType Source #

gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> LitNumType -> m LitNumType Source #

Ord LitNumType # 
Instance details

Defined in Literal

Binary LitNumType # 
Instance details

Defined in Literal

Creating Literals

mkLitInt :: DynFlags -> Integer -> Literal Source #

Creates a Literal of type Int#

mkLitIntWrap :: DynFlags -> Integer -> Literal Source #

Creates a Literal of type Int#. If the argument is out of the (target-dependent) range, it is wrapped. See Note [WordInt underflowoverflow]

mkLitIntWrapC :: DynFlags -> Integer -> (Literal, Bool) Source #

Creates a Literal of type Int#, as well as a Boolean flag indicating overflow. That is, if the argument is out of the (target-dependent) range the argument is wrapped and the overflow flag will be set. See Note [WordInt underflowoverflow]

mkLitWord :: DynFlags -> Integer -> Literal Source #

Creates a Literal of type Word#

mkLitWordWrap :: DynFlags -> Integer -> Literal Source #

Creates a Literal of type Word#. If the argument is out of the (target-dependent) range, it is wrapped. See Note [WordInt underflowoverflow]

mkLitWordWrapC :: DynFlags -> Integer -> (Literal, Bool) Source #

Creates a Literal of type Word#, as well as a Boolean flag indicating carry. That is, if the argument is out of the (target-dependent) range the argument is wrapped and the carry flag will be set. See Note [WordInt underflowoverflow]

mkLitInt64 :: Integer -> Literal Source #

Creates a Literal of type Int64#

mkLitInt64Wrap :: DynFlags -> Integer -> Literal Source #

Creates a Literal of type Int64#. If the argument is out of the range, it is wrapped.

mkLitWord64 :: Integer -> Literal Source #

Creates a Literal of type Word64#

mkLitWord64Wrap :: DynFlags -> Integer -> Literal Source #

Creates a Literal of type Word64#. If the argument is out of the range, it is wrapped.

mkLitFloat :: Rational -> Literal Source #

Creates a Literal of type Float#

mkLitDouble :: Rational -> Literal Source #

Creates a Literal of type Double#

mkLitChar :: Char -> Literal Source #

Creates a Literal of type Char#

mkLitString :: String -> Literal Source #

Creates a Literal of type Addr#, which is appropriate for passing to e.g. some of the "error" functions in GHC.Err such as GHC.Err.runtimeError

mkLitNumber :: DynFlags -> LitNumType -> Integer -> Type -> Literal Source #

Create a numeric Literal of the given type

mkLitNumberWrap :: DynFlags -> LitNumType -> Integer -> Type -> Literal Source #

Create a numeric Literal of the given type

Operations on Literals

literalType :: Literal -> Type Source #

Find the Haskell Type the literal occupies

litNumIsSigned :: LitNumType -> Bool Source #

Indicate if a numeric literal type supports negative numbers

litNumCheckRange :: DynFlags -> LitNumType -> Integer -> Bool Source #

Check that a given number is in the range of a numeric literal

Predicates on Literals and their contents

litIsDupable :: DynFlags -> Literal -> Bool Source #

True if code space does not go bad if we duplicate this literal

litIsTrivial :: Literal -> Bool Source #

True if there is absolutely no penalty to duplicating the literal. False principally of strings.

"Why?", you say? I'm glad you asked. Well, for one duplicating strings would blow up code sizes. Not only this, it's also unsafe.

Consider a program that wants to traverse a string. One way it might do this is to first compute the Addr# pointing to the end of the string, and then, starting from the beginning, bump a pointer using eqAddr# to determine the end. For instance,

-- Given pointers to the start and end of a string, count how many zeros
-- the string contains.
countZeros :: Addr -> -> Int
countZeros start end = go start 0
  where
    go off n
      | off `addrEq#` end = n
      | otherwise         = go (off `plusAddr#` 1) n'
      where n' | isTrue off 0 0#) = n + 1
               | otherwise                                 = n

Consider what happens if we considered strings to be trivial (and therefore duplicable) and emitted a call like countZeros "hello" plusAddr# 5). The beginning and end pointers do not belong to the same string, meaning that an iteration like the above would blow up terribly. This is what happened in #12757.

Ultimately the solution here is to make primitive strings a bit more structured, ensuring that the compiler can't inline in ways that will break user code. One approach to this is described in #8472.

isZeroLit :: Literal -> Bool Source #

Tests whether the literal represents a zero of whatever type it is

litValue :: Literal -> Integer Source #

Returns the Integer contained in the Literal, for when that makes sense, i.e. for Char, Int, Word, LitInteger and LitNatural.

isLitValue :: Literal -> Bool Source #

Indicate if the Literal contains an Integer value, e.g. Char, Int, Word, LitInteger and LitNatural.

isLitValue_maybe :: Literal -> Maybe Integer Source #

Returns the Integer contained in the Literal, for when that makes sense, i.e. for Char and numbers.

mapLitValue :: DynFlags -> (Integer -> Integer) -> Literal -> Literal Source #

Apply a function to the Integer contained in the Literal, for when that makes sense, e.g. for Char and numbers. For fixed-size integral literals, the result will be wrapped in accordance with the semantics of the target type. See Note [WordInt underflowoverflow]

Coercions

narrowLit :: forall a. Integral a => Proxy a -> Literal -> Literal Source #

Narrow a literal number (unchecked result range)

rubbishLit :: Literal Source #

A nonsense literal of type forall (a :: TYPE UnliftedRep). a.