1239313Sdim//== APSIntType.h - Simple record of the type of APSInts --------*- C++ -*--==// 2239313Sdim// 3239313Sdim// The LLVM Compiler Infrastructure 4239313Sdim// 5239313Sdim// This file is distributed under the University of Illinois Open Source 6239313Sdim// License. See LICENSE.TXT for details. 7239313Sdim// 8239313Sdim//===----------------------------------------------------------------------===// 9239313Sdim 10239313Sdim#ifndef LLVM_CLANG_SA_CORE_APSINTTYPE_H 11239313Sdim#define LLVM_CLANG_SA_CORE_APSINTTYPE_H 12239313Sdim 13239313Sdim#include "llvm/ADT/APSInt.h" 14239313Sdim 15239313Sdimnamespace clang { 16239313Sdimnamespace ento { 17239313Sdim 18239313Sdim/// \brief A record of the "type" of an APSInt, used for conversions. 19239313Sdimclass APSIntType { 20239313Sdim uint32_t BitWidth; 21239313Sdim bool IsUnsigned; 22239313Sdim 23239313Sdimpublic: 24239313Sdim APSIntType(uint32_t Width, bool Unsigned) 25239313Sdim : BitWidth(Width), IsUnsigned(Unsigned) {} 26239313Sdim 27239313Sdim /* implicit */ APSIntType(const llvm::APSInt &Value) 28239313Sdim : BitWidth(Value.getBitWidth()), IsUnsigned(Value.isUnsigned()) {} 29239313Sdim 30239313Sdim uint32_t getBitWidth() const { return BitWidth; } 31239313Sdim bool isUnsigned() const { return IsUnsigned; } 32239313Sdim 33239313Sdim /// \brief Convert a given APSInt, in place, to match this type. 34239313Sdim /// 35239313Sdim /// This behaves like a C cast: converting 255u8 (0xFF) to s16 gives 36239313Sdim /// 255 (0x00FF), and converting -1s8 (0xFF) to u16 gives 65535 (0xFFFF). 37239313Sdim void apply(llvm::APSInt &Value) const { 38239313Sdim // Note the order here. We extend first to preserve the sign, if this value 39239313Sdim // is signed, /then/ match the signedness of the result type. 40239313Sdim Value = Value.extOrTrunc(BitWidth); 41239313Sdim Value.setIsUnsigned(IsUnsigned); 42239313Sdim } 43239313Sdim 44239313Sdim /// Convert and return a new APSInt with the given value, but this 45239313Sdim /// type's bit width and signedness. 46239313Sdim /// 47239313Sdim /// \see apply 48239313Sdim llvm::APSInt convert(const llvm::APSInt &Value) const LLVM_READONLY { 49239313Sdim llvm::APSInt Result(Value, Value.isUnsigned()); 50239313Sdim apply(Result); 51239313Sdim return Result; 52239313Sdim } 53239313Sdim 54239313Sdim /// Returns an all-zero value for this type. 55239313Sdim llvm::APSInt getZeroValue() const LLVM_READONLY { 56239313Sdim return llvm::APSInt(BitWidth, IsUnsigned); 57239313Sdim } 58239313Sdim 59239313Sdim /// Returns the minimum value for this type. 60239313Sdim llvm::APSInt getMinValue() const LLVM_READONLY { 61239313Sdim return llvm::APSInt::getMinValue(BitWidth, IsUnsigned); 62239313Sdim } 63239313Sdim 64239313Sdim /// Returns the maximum value for this type. 65239313Sdim llvm::APSInt getMaxValue() const LLVM_READONLY { 66239313Sdim return llvm::APSInt::getMaxValue(BitWidth, IsUnsigned); 67239313Sdim } 68239313Sdim 69245431Sdim llvm::APSInt getValue(uint64_t RawValue) const LLVM_READONLY { 70245431Sdim return (llvm::APSInt(BitWidth, IsUnsigned) = RawValue); 71245431Sdim } 72245431Sdim 73239313Sdim /// Used to classify whether a value is representable using this type. 74239313Sdim /// 75239313Sdim /// \see testInRange 76239313Sdim enum RangeTestResultKind { 77239313Sdim RTR_Below = -1, ///< Value is less than the minimum representable value. 78239313Sdim RTR_Within = 0, ///< Value is representable using this type. 79239313Sdim RTR_Above = 1 ///< Value is greater than the maximum representable value. 80239313Sdim }; 81239313Sdim 82239313Sdim /// Tests whether a given value is losslessly representable using this type. 83239313Sdim /// 84252723Sdim /// \param Val The value to test. 85252723Sdim /// \param AllowMixedSign Whether or not to allow signedness conversions. 86252723Sdim /// This determines whether -1s8 is considered in range 87252723Sdim /// for 'unsigned char' (u8). 88252723Sdim RangeTestResultKind testInRange(const llvm::APSInt &Val, 89252723Sdim bool AllowMixedSign) const LLVM_READONLY; 90239313Sdim 91239313Sdim bool operator==(const APSIntType &Other) const { 92239313Sdim return BitWidth == Other.BitWidth && IsUnsigned == Other.IsUnsigned; 93239313Sdim } 94239313Sdim 95239313Sdim /// \brief Provide an ordering for finding a common conversion type. 96239313Sdim /// 97239313Sdim /// Unsigned integers are considered to be better conversion types than 98239313Sdim /// signed integers of the same width. 99239313Sdim bool operator<(const APSIntType &Other) const { 100239313Sdim if (BitWidth < Other.BitWidth) 101239313Sdim return true; 102239313Sdim if (BitWidth > Other.BitWidth) 103239313Sdim return false; 104239313Sdim if (!IsUnsigned && Other.IsUnsigned) 105239313Sdim return true; 106239313Sdim return false; 107239313Sdim } 108239313Sdim}; 109239313Sdim 110239313Sdim} // end ento namespace 111239313Sdim} // end clang namespace 112239313Sdim 113239313Sdim#endif 114