clang API Documentation

APSIntType.h
Go to the documentation of this file.
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