From cc68d53bf08473f6952178b0b44102af04d061b1 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Sat, 20 Jan 2024 02:57:09 -0500 Subject: [PATCH] Add support for __builtin_bit_cast (#96) * Add support for __builtin_bit_cast * Bump deepseq upper bound --- language-c.cabal | 2 +- scripts/tokenlist.txt | 1 + src/Language/C/Analysis/AstAnalysis.hs | 1 + src/Language/C/Parser/Lexer.x | 4 +++- src/Language/C/Parser/Parser.y | 6 +++++- src/Language/C/Parser/Tokens.hs | 2 ++ src/Language/C/Pretty.hs | 3 +++ src/Language/C/Syntax/AST.hs | 7 +++++++ 8 files changed, 23 insertions(+), 3 deletions(-) diff --git a/language-c.cabal b/language-c.cabal index 0a312f92..5bf0c231 100644 --- a/language-c.cabal +++ b/language-c.cabal @@ -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, diff --git a/scripts/tokenlist.txt b/scripts/tokenlist.txt index 6c8d9a87..a56e7a09 100644 --- a/scripts/tokenlist.txt +++ b/scripts/tokenlist.txt @@ -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 diff --git a/src/Language/C/Analysis/AstAnalysis.hs b/src/Language/C/Analysis/AstAnalysis.hs index e12c26b3..8f0c49c9 100644 --- a/src/Language/C/Analysis/AstAnalysis.hs +++ b/src/Language/C/Analysis/AstAnalysis.hs @@ -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] diff --git a/src/Language/C/Parser/Lexer.x b/src/Language/C/Parser/Lexer.x index 5b733687..d3756c15 100644 --- a/src/Language/C/Parser/Lexer.x +++ b/src/Language/C/Parser/Lexer.x @@ -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 @@ -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) diff --git a/src/Language/C/Parser/Parser.y b/src/Language/C/Parser/Parser.y index a4b50527..bc042b51 100644 --- a/src/Language/C/Parser/Parser.y +++ b/src/Language/C/Parser/Parser.y @@ -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 @@ -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) -- diff --git a/src/Language/C/Parser/Tokens.hs b/src/Language/C/Parser/Tokens.hs index 2d667c3a..78e18f12 100644 --- a/src/Language/C/Parser/Tokens.hs +++ b/src/Language/C/Parser/Tokens.hs @@ -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 @@ -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" diff --git a/src/Language/C/Pretty.hs b/src/Language/C/Pretty.hs index 9fafb971..61fe18f8 100644 --- a/src/Language/C/Pretty.hs +++ b/src/Language/C/Pretty.hs @@ -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 diff --git a/src/Language/C/Syntax/AST.hs b/src/Language/C/Syntax/AST.hs index d26b0e83..eab48465 100644 --- a/src/Language/C/Syntax/AST.hs +++ b/src/Language/C/Syntax/AST.hs @@ -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) @@ -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) @@ -1409,12 +1411,15 @@ 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) @@ -1422,6 +1427,8 @@ instance Annotated CBuiltinThing where = 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