Skip to content

Commit

Permalink
Add support for __builtin_bit_cast (#96)
Browse files Browse the repository at this point in the history
* Add support for __builtin_bit_cast

* Bump deepseq upper bound
  • Loading branch information
bgamari authored Jan 20, 2024
1 parent 61cbabc commit cc68d53
Show file tree
Hide file tree
Showing 8 changed files with 23 additions and 3 deletions.
2 changes: 1 addition & 1 deletion language-c.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Library
Build-Depends: base >= 4.8 && < 5,
array,
containers >= 0.3,
deepseq >= 1.4.0.0 && < 1.5,
deepseq >= 1.4.0.0 && < 1.6,
directory,
filepath,
mtl,
Expand Down
1 change: 1 addition & 0 deletions scripts/tokenlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ label __label__
(CTokGnuC GnuCVaArg) __builtin_va_arg
(CTokGnuC GnuCOffsetof) __builtin_offsetof
(CTokGnuC GnuCTyCompat) __builtin_types_compatible_p
(flip CTokClangC ClangCBitCast) __builtin_bit_cast
(flip CTokClangC ClangBuiltinConvertVector) __builtin_convertvector
1 change: 1 addition & 0 deletions src/Language/C/Analysis/AstAnalysis.hs
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,7 @@ builtinType (CBuiltinVaArg _ d _) = analyseTypeDecl d
builtinType (CBuiltinOffsetOf _ _ _) = return size_tType
builtinType (CBuiltinTypesCompatible _ _ _) = return boolType
builtinType (CBuiltinConvertVector _expr ty _) = analyseTypeDecl ty
builtinType (CBuiltinBitCast ty _expr _) = analyseTypeDecl ty

-- return @Just declspecs@ without @CTypedef@ if the declaration specifier contain @typedef@
hasTypeDef :: [CDeclSpec] -> Maybe [CDeclSpec]
Expand Down
4 changes: 3 additions & 1 deletion src/Language/C/Parser/Lexer.x
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,11 @@ label __label__
(CTokGnuC GnuCVaArg) __builtin_va_arg
(CTokGnuC GnuCOffsetof) __builtin_offsetof
(CTokGnuC GnuCTyCompat) __builtin_types_compatible_p
(CTokGnuC GnuBitCast) __builtin_bit_cast
(flip CTokClangC ClangBuiltinConvertVector) __builtin_convertvector
-}
-- Tokens: _Alignas _Alignof __alignof alignof __alignof__ __asm asm __asm__ _Atomic auto break _Bool case char __const const __const__ continue _Complex __complex__ default do double else enum extern float for _Generic goto if __inline inline __inline__ int __int128 __int128_t long _Noreturn _Nullable __nullable _Nonnull __nonnull register __restrict restrict __restrict__ return short __signed signed __signed__ sizeof static _Static_assert struct switch typedef __typeof typeof __typeof__ __thread _Thread_local __uint128 __uint128_t union unsigned void __volatile volatile __volatile__ while __label__ _Float32 _Float32x _Float64 _Float64x _Float128 __float128 _Float128x __attribute __attribute__ __extension__ __real __real__ __imag __imag__ __builtin_va_arg __builtin_offsetof __builtin_types_compatible_p __builtin_convertvector
-- Tokens: _Alignas _Alignof __alignof alignof __alignof__ __asm asm __asm__ _Atomic auto break _Bool case char __const const __const__ continue _Complex __complex__ default do double else enum extern float for _Generic goto if __inline inline __inline__ int __int128_t long _Noreturn _Nullable __nullable _Nonnull __nonnull register __restrict restrict __restrict__ return short __signed signed __signed__ sizeof static _Static_assert struct switch typedef __typeof typeof __typeof__ __thread _Thread_local __uint128 __uint128_t union unsigned void __volatile volatile __volatile__ while __label__ _Float32 _Float32x _Float64 _Float64x _Float128 __float128 _Float128x __attribute __attribute__ __extension__ __real __real__ __imag __imag__ __builtin_va_arg __builtin_offsetof __builtin_types_compatible_p __builtin_bit_cast __builtin_convertvector
idkwtok ('_' : 'A' : 'l' : 'i' : 'g' : 'n' : 'a' : 's' : []) = tok 8 CTokAlignas
idkwtok ('_' : 'A' : 'l' : 'i' : 'g' : 'n' : 'o' : 'f' : []) = tok 8 CTokAlignof
idkwtok ('_' : 'A' : 't' : 'o' : 'm' : 'i' : 'c' : []) = tok 7 CTokAtomic
Expand Down Expand Up @@ -356,6 +357,7 @@ idkwtok ('_' : '_' : 'a' : 't' : 't' : 'r' : 'i' : 'b' : 'u' : 't' : 'e' : []) =
idkwtok ('_' : '_' : 'a' : 't' : 't' : 'r' : 'i' : 'b' : 'u' : 't' : 'e' : '_' : '_' : []) = tok 13 (CTokGnuC GnuCAttrTok)
idkwtok ('a' : 'u' : 't' : 'o' : []) = tok 4 CTokAuto
idkwtok ('b' : 'r' : 'e' : 'a' : 'k' : []) = tok 5 CTokBreak
idkwtok ('_' : '_' : 'b' : 'u' : 'i' : 'l' : 't' : 'i' : 'n' : '_' : 'b' : 'i' : 't' : '_' : 'c' : 'a' : 's' : 't' : []) = tok 18 (flip CTokClangC ClangCBitCast)
idkwtok ('_' : '_' : 'b' : 'u' : 'i' : 'l' : 't' : 'i' : 'n' : '_' : 'c' : 'o' : 'n' : 'v' : 'e' : 'r' : 't' : 'v' : 'e' : 'c' : 't' : 'o' : 'r' : []) = tok 23 (flip CTokClangC ClangBuiltinConvertVector)
idkwtok ('_' : '_' : 'b' : 'u' : 'i' : 'l' : 't' : 'i' : 'n' : '_' : 'o' : 'f' : 'f' : 's' : 'e' : 't' : 'o' : 'f' : []) = tok 18 (CTokGnuC GnuCOffsetof)
idkwtok ('_' : '_' : 'b' : 'u' : 'i' : 'l' : 't' : 'i' : 'n' : '_' : 't' : 'y' : 'p' : 'e' : 's' : '_' : 'c' : 'o' : 'm' : 'p' : 'a' : 't' : 'i' : 'b' : 'l' : 'e' : '_' : 'p' : []) = tok 28 (CTokGnuC GnuCTyCompat)
Expand Down
6 changes: 5 additions & 1 deletion src/Language/C/Parser/Parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ tyident { CTokTyIdent _ $$ } -- `typedef-name' identifier
"__builtin_types_compatible_p" { CTokGnuC GnuCTyCompat _ }
"__builtin_convertvector" { CTokClangC _ ClangBuiltinConvertVector }
clangcversion { CTokClangC _ (ClangCVersionTok $$) } -- Clang version literal
"__builtin_bit_cast" { CTokClangC _ ClangCBitCast }
"__kernel" { CTokClKernel _ } -- OpenCL kernel function
"__read_only" { CTokClRdOnly _ } -- OpenCL read only qualifier
"__write_only" { CTokClWrOnly _ } -- OpenCL write only qualifier
Expand Down Expand Up @@ -1770,7 +1771,10 @@ primary_expression
{% withNodeInfo $1 $ CBuiltinExpr . CBuiltinTypesCompatible $3 $5 }
| "__builtin_convertvector" '(' assignment_expression ',' type_name ')'
{% withNodeInfo $1 $ CBuiltinExpr . CBuiltinConvertVector $3 $5 }
{% withNodeInfo $1 $ CBuiltinExpr . CBuiltinConvertVector $3 $5 }
| "__builtin_bit_cast" '(' type_name ',' assignment_expression ')'
{% withNodeInfo $1 $ CBuiltinExpr . CBuiltinBitCast $3 $5 }
-- Generic Selection association list (C11 6.5.1.1)
--
Expand Down
2 changes: 2 additions & 0 deletions src/Language/C/Parser/Tokens.hs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ data GnuCTok = GnuCAttrTok -- `__attribute__'

data ClangCTok = ClangCVersionTok !ClangCVersion -- version constant from 'availability' attribute
| ClangBuiltinConvertVector
| ClangCBitCast -- `__builtin_bit_cast`

instance Pos CToken where
posOf = fst . posLenOfTok
Expand Down Expand Up @@ -395,6 +396,7 @@ instance Show CToken where
showsPrec _ (CTokGnuC GnuCTyCompat _) = showString "__builtin_types_compatible_p"
showsPrec _ (CTokClangC _ (ClangCVersionTok v)) = shows v
showsPrec _ (CTokClangC _ ClangBuiltinConvertVector) = showString "__builtin_convertvector"
showsPrec _ (CTokClangC _ ClangCBitCast) = showString "__builtin_bit_cast"
showsPrec _ (CTokClKernel _ ) = showString "__kernel"
showsPrec _ (CTokClRdOnly _ ) = showString "__read_only"
showsPrec _ (CTokClWrOnly _ ) = showString "__write_only"
Expand Down
3 changes: 3 additions & 0 deletions src/Language/C/Pretty.hs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,9 @@ instance Pretty CBuiltin where
pretty (CBuiltinConvertVector expr ty _) =
text "__builtin_convertvector" <+>
parens (pretty expr <> comma <+> pretty ty)
pretty (CBuiltinBitCast ty expr _) =
text "__builtin_bit_cast" <+>
parens (pretty ty <> comma <+> pretty expr)

instance Pretty CAssignOp where
pretty op = text $ case op of
Expand Down
7 changes: 7 additions & 0 deletions src/Language/C/Syntax/AST.hs
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,7 @@ data CBuiltinThing a
| CBuiltinOffsetOf (CDeclaration a) [CPartDesignator a] a -- ^ @(type, designator-list)@
| CBuiltinTypesCompatible (CDeclaration a) (CDeclaration a) a -- ^ @(type,type)@
| CBuiltinConvertVector (CExpression a) (CDeclaration a) a -- ^ @(expr, type)@
| CBuiltinBitCast (CDeclaration a) (CExpression a) a -- ^ @(type, expr)@
deriving (Show, Data,Typeable, Generic {-! ,CNode ,Functor ,Annotated !-})

instance NFData a => NFData (CBuiltinThing a)
Expand Down Expand Up @@ -1397,6 +1398,7 @@ instance CNode t1 => CNode (CBuiltinThing t1) where
nodeInfo (CBuiltinOffsetOf _ _ n) = nodeInfo n
nodeInfo (CBuiltinTypesCompatible _ _ n) = nodeInfo n
nodeInfo (CBuiltinConvertVector _ _ n) = nodeInfo n
nodeInfo (CBuiltinBitCast _ _ n) = nodeInfo n
instance CNode t1 => Pos (CBuiltinThing t1) where
posOf x = posOf (nodeInfo x)

Expand All @@ -1409,19 +1411,24 @@ instance Functor CBuiltinThing where
= CBuiltinTypesCompatible (fmap _f a1) (fmap _f a2) (_f a3)
fmap _f (CBuiltinConvertVector a1 a2 a3)
= CBuiltinConvertVector (fmap _f a1) (fmap _f a2) (_f a3)
fmap _f (CBuiltinBitCast a1 a2 a3)
= CBuiltinBitCast (fmap _f a1) (fmap _f a2) (_f a3)

instance Annotated CBuiltinThing where
annotation (CBuiltinVaArg _ _ n) = n
annotation (CBuiltinOffsetOf _ _ n) = n
annotation (CBuiltinTypesCompatible _ _ n) = n
annotation (CBuiltinConvertVector _ _ n) = n
annotation (CBuiltinBitCast _ _ n) = n
amap f (CBuiltinVaArg a_1 a_2 a_3) = CBuiltinVaArg a_1 a_2 (f a_3)
amap f (CBuiltinOffsetOf a_1 a_2 a_3)
= CBuiltinOffsetOf a_1 a_2 (f a_3)
amap f (CBuiltinTypesCompatible a_1 a_2 a_3)
= CBuiltinTypesCompatible a_1 a_2 (f a_3)
amap f (CBuiltinConvertVector a_1 a_2 a_3) =
CBuiltinConvertVector a_1 a_2 (f a_3)
amap f (CBuiltinBitCast a_1 a_2 a_3) =
CBuiltinBitCast a_1 a_2 (f a_3)

instance CNode t1 => CNode (CConstant t1) where
nodeInfo (CIntConst _ n) = nodeInfo n
Expand Down

0 comments on commit cc68d53

Please sign in to comment.