]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
Merge clang 3.5.0 release from ^/vendor/clang/dist, resolve conflicts,
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / StaticAnalyzer / Core / PathSensitive / APSIntType.h
1 //== APSIntType.h - Simple record of the type of APSInts --------*- C++ -*--==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLVM_CLANG_SA_CORE_APSINTTYPE_H
11 #define LLVM_CLANG_SA_CORE_APSINTTYPE_H
12
13 #include "llvm/ADT/APSInt.h"
14 #include <tuple>
15
16 namespace clang {
17 namespace ento {
18
19 /// \brief A record of the "type" of an APSInt, used for conversions.
20 class APSIntType {
21   uint32_t BitWidth;
22   bool IsUnsigned;
23
24 public:
25   APSIntType(uint32_t Width, bool Unsigned)
26     : BitWidth(Width), IsUnsigned(Unsigned) {}
27
28   /* implicit */ APSIntType(const llvm::APSInt &Value)
29     : BitWidth(Value.getBitWidth()), IsUnsigned(Value.isUnsigned()) {}
30
31   uint32_t getBitWidth() const { return BitWidth; }
32   bool isUnsigned() const { return IsUnsigned; }
33
34   /// \brief Convert a given APSInt, in place, to match this type.
35   ///
36   /// This behaves like a C cast: converting 255u8 (0xFF) to s16 gives
37   /// 255 (0x00FF), and converting -1s8 (0xFF) to u16 gives 65535 (0xFFFF).
38   void apply(llvm::APSInt &Value) const {
39     // Note the order here. We extend first to preserve the sign, if this value
40     // is signed, /then/ match the signedness of the result type.
41     Value = Value.extOrTrunc(BitWidth);
42     Value.setIsUnsigned(IsUnsigned);
43   }
44
45   /// Convert and return a new APSInt with the given value, but this
46   /// type's bit width and signedness.
47   ///
48   /// \see apply
49   llvm::APSInt convert(const llvm::APSInt &Value) const LLVM_READONLY {
50     llvm::APSInt Result(Value, Value.isUnsigned());
51     apply(Result);
52     return Result;
53   }
54
55   /// Returns an all-zero value for this type.
56   llvm::APSInt getZeroValue() const LLVM_READONLY {
57     return llvm::APSInt(BitWidth, IsUnsigned);
58   }
59
60   /// Returns the minimum value for this type.
61   llvm::APSInt getMinValue() const LLVM_READONLY {
62     return llvm::APSInt::getMinValue(BitWidth, IsUnsigned);
63   }
64
65   /// Returns the maximum value for this type.
66   llvm::APSInt getMaxValue() const LLVM_READONLY {
67     return llvm::APSInt::getMaxValue(BitWidth, IsUnsigned);
68   }
69
70   llvm::APSInt getValue(uint64_t RawValue) const LLVM_READONLY {
71     return (llvm::APSInt(BitWidth, IsUnsigned) = RawValue);
72   }
73
74   /// Used to classify whether a value is representable using this type.
75   ///
76   /// \see testInRange
77   enum RangeTestResultKind {
78     RTR_Below = -1, ///< Value is less than the minimum representable value.
79     RTR_Within = 0, ///< Value is representable using this type.
80     RTR_Above = 1   ///< Value is greater than the maximum representable value.
81   };
82
83   /// Tests whether a given value is losslessly representable using this type.
84   ///
85   /// \param Val The value to test.
86   /// \param AllowMixedSign Whether or not to allow signedness conversions.
87   ///                       This determines whether -1s8 is considered in range
88   ///                       for 'unsigned char' (u8).
89   RangeTestResultKind testInRange(const llvm::APSInt &Val,
90                                   bool AllowMixedSign) const LLVM_READONLY;
91   
92   bool operator==(const APSIntType &Other) const {
93     return BitWidth == Other.BitWidth && IsUnsigned == Other.IsUnsigned;
94   }
95
96   /// \brief Provide an ordering for finding a common conversion type.
97   ///
98   /// Unsigned integers are considered to be better conversion types than
99   /// signed integers of the same width.
100   bool operator<(const APSIntType &Other) const {
101     return std::tie(BitWidth, IsUnsigned) <
102            std::tie(Other.BitWidth, Other.IsUnsigned);
103   }
104 };
105     
106 } // end ento namespace
107 } // end clang namespace
108
109 #endif