/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
Line | Count | Source |
1 | | //== APSIntType.h - Simple record of the type of APSInts --------*- C++ -*--==// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSINTTYPE_H |
10 | | #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSINTTYPE_H |
11 | | |
12 | | #include "llvm/ADT/APSInt.h" |
13 | | #include <tuple> |
14 | | |
15 | | namespace clang { |
16 | | namespace ento { |
17 | | |
18 | | /// A record of the "type" of an APSInt, used for conversions. |
19 | | class APSIntType { |
20 | | uint32_t BitWidth; |
21 | | bool IsUnsigned; |
22 | | |
23 | | public: |
24 | | constexpr APSIntType(uint32_t Width, bool Unsigned) |
25 | 2.39M | : BitWidth(Width), IsUnsigned(Unsigned) {} |
26 | | |
27 | | /* implicit */ APSIntType(const llvm::APSInt &Value) |
28 | 1.41M | : BitWidth(Value.getBitWidth()), IsUnsigned(Value.isUnsigned()) {} |
29 | | |
30 | 464k | uint32_t getBitWidth() const { return BitWidth; } |
31 | 357k | bool isUnsigned() const { return IsUnsigned; } |
32 | | |
33 | | /// Convert a given APSInt, in place, to match this type. |
34 | | /// |
35 | | /// This behaves like a C cast: converting 255u8 (0xFF) to s16 gives |
36 | | /// 255 (0x00FF), and converting -1s8 (0xFF) to u16 gives 65535 (0xFFFF). |
37 | 1.49M | void apply(llvm::APSInt &Value) const { |
38 | | // Note the order here. We extend first to preserve the sign, if this value |
39 | | // is signed, /then/ match the signedness of the result type. |
40 | 1.49M | Value = Value.extOrTrunc(BitWidth); |
41 | 1.49M | Value.setIsUnsigned(IsUnsigned); |
42 | 1.49M | } |
43 | | |
44 | | /// Convert and return a new APSInt with the given value, but this |
45 | | /// type's bit width and signedness. |
46 | | /// |
47 | | /// \see apply |
48 | 607k | llvm::APSInt convert(const llvm::APSInt &Value) const LLVM_READONLY { |
49 | 607k | llvm::APSInt Result(Value, Value.isUnsigned()); |
50 | 607k | apply(Result); |
51 | 607k | return Result; |
52 | 607k | } |
53 | | |
54 | | /// Returns an all-zero value for this type. |
55 | 303k | llvm::APSInt getZeroValue() const LLVM_READONLY { |
56 | 303k | return llvm::APSInt(BitWidth, IsUnsigned); |
57 | 303k | } |
58 | | |
59 | | /// Returns the minimum value for this type. |
60 | 793k | llvm::APSInt getMinValue() const LLVM_READONLY { |
61 | 793k | return llvm::APSInt::getMinValue(BitWidth, IsUnsigned); |
62 | 793k | } |
63 | | |
64 | | /// Returns the maximum value for this type. |
65 | 808k | llvm::APSInt getMaxValue() const LLVM_READONLY { |
66 | 808k | return llvm::APSInt::getMaxValue(BitWidth, IsUnsigned); |
67 | 808k | } |
68 | | |
69 | 407k | llvm::APSInt getValue(uint64_t RawValue) const LLVM_READONLY { |
70 | 407k | return (llvm::APSInt(BitWidth, IsUnsigned) = RawValue); |
71 | 407k | } |
72 | | |
73 | | /// Used to classify whether a value is representable using this type. |
74 | | /// |
75 | | /// \see testInRange |
76 | | enum RangeTestResultKind { |
77 | | RTR_Below = -1, ///< Value is less than the minimum representable value. |
78 | | RTR_Within = 0, ///< Value is representable using this type. |
79 | | RTR_Above = 1 ///< Value is greater than the maximum representable value. |
80 | | }; |
81 | | |
82 | | /// Tests whether a given value is losslessly representable using this type. |
83 | | /// |
84 | | /// \param Val The value to test. |
85 | | /// \param AllowMixedSign Whether or not to allow signedness conversions. |
86 | | /// This determines whether -1s8 is considered in range |
87 | | /// for 'unsigned char' (u8). |
88 | | RangeTestResultKind testInRange(const llvm::APSInt &Val, |
89 | | bool AllowMixedSign) const LLVM_READONLY; |
90 | | |
91 | 231k | bool operator==(const APSIntType &Other) const { |
92 | 231k | return BitWidth == Other.BitWidth && IsUnsigned == Other.IsUnsigned157k ; |
93 | 231k | } |
94 | | |
95 | | /// Provide an ordering for finding a common conversion type. |
96 | | /// |
97 | | /// Unsigned integers are considered to be better conversion types than |
98 | | /// signed integers of the same width. |
99 | 308k | bool operator<(const APSIntType &Other) const { |
100 | 308k | return std::tie(BitWidth, IsUnsigned) < |
101 | 308k | std::tie(Other.BitWidth, Other.IsUnsigned); |
102 | 308k | } |
103 | | }; |
104 | | |
105 | | } // end ento namespace |
106 | | } // end clang namespace |
107 | | |
108 | | #endif |