//== APSIntType.h - Simple record of the type of APSInts --------*- C++ -*--==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSINTTYPE_H
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_APSINTTYPE_H

#include "llvm/ADT/APSInt.h"
#include <tuple>

namespace clang {
namespace ento {

/// A record of the "type" of an APSInt, used for conversions.
class APSIntType {
  uint32_t BitWidth;
  bool IsUnsigned;

public:
  APSIntType(uint32_t Width, bool Unsigned)
    : BitWidth(Width), IsUnsigned(Unsigned) {}

  /* implicit */ APSIntType(const llvm::APSInt &Value)
    : BitWidth(Value.getBitWidth()), IsUnsigned(Value.isUnsigned()) {}

  uint32_t getBitWidth() const { return BitWidth; }
  bool isUnsigned() const { return IsUnsigned; }

  /// Convert a given APSInt, in place, to match this type.
  ///
  /// This behaves like a C cast: converting 255u8 (0xFF) to s16 gives
  /// 255 (0x00FF), and converting -1s8 (0xFF) to u16 gives 65535 (0xFFFF).
  void apply(llvm::APSInt &Value) const {
    // Note the order here. We extend first to preserve the sign, if this value
    // is signed, /then/ match the signedness of the result type.
    Value = Value.extOrTrunc(BitWidth);
    Value.setIsUnsigned(IsUnsigned);
  }

  /// Convert and return a new APSInt with the given value, but this
  /// type's bit width and signedness.
  ///
  /// \see apply
  llvm::APSInt convert(const llvm::APSInt &Value) const LLVM_READONLY {
    llvm::APSInt Result(Value, Value.isUnsigned());
    apply(Result);
    return Result;
  }

  /// Returns an all-zero value for this type.
  llvm::APSInt getZeroValue() const LLVM_READONLY {
    return llvm::APSInt(BitWidth, IsUnsigned);
  }

  /// Returns the minimum value for this type.
  llvm::APSInt getMinValue() const LLVM_READONLY {
    return llvm::APSInt::getMinValue(BitWidth, IsUnsigned);
  }

  /// Returns the maximum value for this type.
  llvm::APSInt getMaxValue() const LLVM_READONLY {
    return llvm::APSInt::getMaxValue(BitWidth, IsUnsigned);
  }

  llvm::APSInt getValue(uint64_t RawValue) const LLVM_READONLY {
    return (llvm::APSInt(BitWidth, IsUnsigned) = RawValue);
  }

  /// Used to classify whether a value is representable using this type.
  ///
  /// \see testInRange
  enum RangeTestResultKind {
    RTR_Below = -1, ///< Value is less than the minimum representable value.
    RTR_Within = 0, ///< Value is representable using this type.
    RTR_Above = 1   ///< Value is greater than the maximum representable value.
  };

  /// Tests whether a given value is losslessly representable using this type.
  ///
  /// \param Val The value to test.
  /// \param AllowMixedSign Whether or not to allow signedness conversions.
  ///                       This determines whether -1s8 is considered in range
  ///                       for 'unsigned char' (u8).
  RangeTestResultKind testInRange(const llvm::APSInt &Val,
                                  bool AllowMixedSign) const LLVM_READONLY;

  bool operator==(const APSIntType &Other) const {
    return BitWidth == Other.BitWidth && IsUnsigned == Other.IsUnsigned;
  }

  /// Provide an ordering for finding a common conversion type.
  ///
  /// Unsigned integers are considered to be better conversion types than
  /// signed integers of the same width.
  bool operator<(const APSIntType &Other) const {
    return std::tie(BitWidth, IsUnsigned) <
           std::tie(Other.BitWidth, Other.IsUnsigned);
  }
};

} // end ento namespace
} // end clang namespace

#endif
