clang API Documentation
00001 //== APSIntType.h - Simple record of the type of APSInts --------*- C++ -*--==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSINTTYPE_H 00011 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSINTTYPE_H 00012 00013 #include "llvm/ADT/APSInt.h" 00014 #include <tuple> 00015 00016 namespace clang { 00017 namespace ento { 00018 00019 /// \brief A record of the "type" of an APSInt, used for conversions. 00020 class APSIntType { 00021 uint32_t BitWidth; 00022 bool IsUnsigned; 00023 00024 public: 00025 APSIntType(uint32_t Width, bool Unsigned) 00026 : BitWidth(Width), IsUnsigned(Unsigned) {} 00027 00028 /* implicit */ APSIntType(const llvm::APSInt &Value) 00029 : BitWidth(Value.getBitWidth()), IsUnsigned(Value.isUnsigned()) {} 00030 00031 uint32_t getBitWidth() const { return BitWidth; } 00032 bool isUnsigned() const { return IsUnsigned; } 00033 00034 /// \brief Convert a given APSInt, in place, to match this type. 00035 /// 00036 /// This behaves like a C cast: converting 255u8 (0xFF) to s16 gives 00037 /// 255 (0x00FF), and converting -1s8 (0xFF) to u16 gives 65535 (0xFFFF). 00038 void apply(llvm::APSInt &Value) const { 00039 // Note the order here. We extend first to preserve the sign, if this value 00040 // is signed, /then/ match the signedness of the result type. 00041 Value = Value.extOrTrunc(BitWidth); 00042 Value.setIsUnsigned(IsUnsigned); 00043 } 00044 00045 /// Convert and return a new APSInt with the given value, but this 00046 /// type's bit width and signedness. 00047 /// 00048 /// \see apply 00049 llvm::APSInt convert(const llvm::APSInt &Value) const LLVM_READONLY { 00050 llvm::APSInt Result(Value, Value.isUnsigned()); 00051 apply(Result); 00052 return Result; 00053 } 00054 00055 /// Returns an all-zero value for this type. 00056 llvm::APSInt getZeroValue() const LLVM_READONLY { 00057 return llvm::APSInt(BitWidth, IsUnsigned); 00058 } 00059 00060 /// Returns the minimum value for this type. 00061 llvm::APSInt getMinValue() const LLVM_READONLY { 00062 return llvm::APSInt::getMinValue(BitWidth, IsUnsigned); 00063 } 00064 00065 /// Returns the maximum value for this type. 00066 llvm::APSInt getMaxValue() const LLVM_READONLY { 00067 return llvm::APSInt::getMaxValue(BitWidth, IsUnsigned); 00068 } 00069 00070 llvm::APSInt getValue(uint64_t RawValue) const LLVM_READONLY { 00071 return (llvm::APSInt(BitWidth, IsUnsigned) = RawValue); 00072 } 00073 00074 /// Used to classify whether a value is representable using this type. 00075 /// 00076 /// \see testInRange 00077 enum RangeTestResultKind { 00078 RTR_Below = -1, ///< Value is less than the minimum representable value. 00079 RTR_Within = 0, ///< Value is representable using this type. 00080 RTR_Above = 1 ///< Value is greater than the maximum representable value. 00081 }; 00082 00083 /// Tests whether a given value is losslessly representable using this type. 00084 /// 00085 /// \param Val The value to test. 00086 /// \param AllowMixedSign Whether or not to allow signedness conversions. 00087 /// This determines whether -1s8 is considered in range 00088 /// for 'unsigned char' (u8). 00089 RangeTestResultKind testInRange(const llvm::APSInt &Val, 00090 bool AllowMixedSign) const LLVM_READONLY; 00091 00092 bool operator==(const APSIntType &Other) const { 00093 return BitWidth == Other.BitWidth && IsUnsigned == Other.IsUnsigned; 00094 } 00095 00096 /// \brief Provide an ordering for finding a common conversion type. 00097 /// 00098 /// Unsigned integers are considered to be better conversion types than 00099 /// signed integers of the same width. 00100 bool operator<(const APSIntType &Other) const { 00101 return std::tie(BitWidth, IsUnsigned) < 00102 std::tie(Other.BitWidth, Other.IsUnsigned); 00103 } 00104 }; 00105 00106 } // end ento namespace 00107 } // end clang namespace 00108 00109 #endif