Home | History | Annotate | Download | only in PathSensitive
      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 
     15 namespace clang {
     16 namespace ento {
     17 
     18 /// \brief 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   APSIntType(uint32_t Width, bool Unsigned)
     25     : BitWidth(Width), IsUnsigned(Unsigned) {}
     26 
     27   /* implicit */ APSIntType(const llvm::APSInt &Value)
     28     : BitWidth(Value.getBitWidth()), IsUnsigned(Value.isUnsigned()) {}
     29 
     30   uint32_t getBitWidth() const { return BitWidth; }
     31   bool isUnsigned() const { return IsUnsigned; }
     32 
     33   /// \brief 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   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     Value = Value.extOrTrunc(BitWidth);
     41     Value.setIsUnsigned(IsUnsigned);
     42   }
     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   llvm::APSInt convert(const llvm::APSInt &Value) const LLVM_READONLY {
     49     llvm::APSInt Result(Value, Value.isUnsigned());
     50     apply(Result);
     51     return Result;
     52   }
     53 
     54   /// Returns an all-zero value for this type.
     55   llvm::APSInt getZeroValue() const LLVM_READONLY {
     56     return llvm::APSInt(BitWidth, IsUnsigned);
     57   }
     58 
     59   /// Returns the minimum value for this type.
     60   llvm::APSInt getMinValue() const LLVM_READONLY {
     61     return llvm::APSInt::getMinValue(BitWidth, IsUnsigned);
     62   }
     63 
     64   /// Returns the maximum value for this type.
     65   llvm::APSInt getMaxValue() const LLVM_READONLY {
     66     return llvm::APSInt::getMaxValue(BitWidth, IsUnsigned);
     67   }
     68 
     69   llvm::APSInt getValue(uint64_t RawValue) const LLVM_READONLY {
     70     return (llvm::APSInt(BitWidth, IsUnsigned) = RawValue);
     71   }
     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   bool operator==(const APSIntType &Other) const {
     92     return BitWidth == Other.BitWidth && IsUnsigned == Other.IsUnsigned;
     93   }
     94 
     95   /// \brief 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   bool operator<(const APSIntType &Other) const {
    100     if (BitWidth < Other.BitWidth)
    101       return true;
    102     if (BitWidth > Other.BitWidth)
    103       return false;
    104     if (!IsUnsigned && Other.IsUnsigned)
    105       return true;
    106     return false;
    107   }
    108 };
    109 
    110 } // end ento namespace
    111 } // end clang namespace
    112 
    113 #endif
    114