//===-- ubsan_value.h -------------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
// Representation of data which is passed from the compiler-generated calls into
// the ubsan runtime.
//
//===----------------------------------------------------------------------===//
#ifndef UBSAN_VALUE_H
#define UBSAN_VALUE_H

#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"

// FIXME: Move this out to a config header.
#if __SIZEOF_INT128__
__extension__ typedef __int128 s128;
__extension__ typedef unsigned __int128 u128;
#define HAVE_INT128_T 1
#else
#define HAVE_INT128_T 0
#endif

namespace __ubsan {

/// \brief Largest integer types we support.
#if HAVE_INT128_T
typedef s128 SIntMax;
typedef u128 UIntMax;
#else
typedef s64 SIntMax;
typedef u64 UIntMax;
#endif

/// \brief Largest floating-point type we support.
typedef long double FloatMax;

/// \brief A description of a source location. This corresponds to Clang's
/// \c PresumedLoc type.
class SourceLocation {
  const char *Filename;
  u32 Line;
  u32 Column;

public:
  SourceLocation() : Filename(), Line(), Column() {}
  SourceLocation(const char *Filename, unsigned Line, unsigned Column)
    : Filename(Filename), Line(Line), Column(Column) {}

  /// \brief Determine whether the source location is known.
  bool isInvalid() const { return !Filename; }

  /// \brief Atomically acquire a copy, disabling original in-place.
  /// Exactly one call to acquire() returns a copy that isn't disabled.
  SourceLocation acquire() {
    u32 OldColumn = __sanitizer::atomic_exchange(
                        (__sanitizer::atomic_uint32_t *)&Column, ~u32(0),
                        __sanitizer::memory_order_relaxed);
    return SourceLocation(Filename, Line, OldColumn);
  }

  /// \brief Determine if this Location has been disabled.
  /// Disabled SourceLocations are invalid to use.
  bool isDisabled() {
    return Column == ~u32(0);
  }

  /// \brief Get the presumed filename for the source location.
  const char *getFilename() const { return Filename; }
  /// \brief Get the presumed line number.
  unsigned getLine() const { return Line; }
  /// \brief Get the column within the presumed line.
  unsigned getColumn() const { return Column; }
};


/// \brief A description of a type.
class TypeDescriptor {
  /// A value from the \c Kind enumeration, specifying what flavor of type we
  /// have.
  u16 TypeKind;

  /// A \c Type-specific value providing information which allows us to
  /// interpret the meaning of a ValueHandle of this type.
  u16 TypeInfo;

  /// The name of the type follows, in a format suitable for including in
  /// diagnostics.
  char TypeName[1];

public:
  enum Kind {
    /// An integer type. Lowest bit is 1 for a signed value, 0 for an unsigned
    /// value. Remaining bits are log_2(bit width). The value representation is
    /// the integer itself if it fits into a ValueHandle, and a pointer to the
    /// integer otherwise.
    TK_Integer = 0x0000,
    /// A floating-point type. Low 16 bits are bit width. The value
    /// representation is that of bitcasting the floating-point value to an
    /// integer type.
    TK_Float = 0x0001,
    /// Any other type. The value representation is unspecified.
    TK_Unknown = 0xffff
  };

  const char *getTypeName() const { return TypeName; }

  Kind getKind() const {
    return static_cast<Kind>(TypeKind);
  }

  bool isIntegerTy() const { return getKind() == TK_Integer; }
  bool isSignedIntegerTy() const {
    return isIntegerTy() && (TypeInfo & 1);
  }
  bool isUnsignedIntegerTy() const {
    return isIntegerTy() && !(TypeInfo & 1);
  }
  unsigned getIntegerBitWidth() const {
    CHECK(isIntegerTy());
    return 1 << (TypeInfo >> 1);
  }

  bool isFloatTy() const { return getKind() == TK_Float; }
  unsigned getFloatBitWidth() const {
    CHECK(isFloatTy());
    return TypeInfo;
  }
};

/// \brief An opaque handle to a value.
typedef uptr ValueHandle;

/// Returns the class name of the given ObjC object, or null if the name
/// cannot be found.
const char *getObjCClassName(ValueHandle Pointer);

/// \brief Representation of an operand value provided by the instrumented code.
///
/// This is a combination of a TypeDescriptor (which is emitted as constant data
/// as an operand to a handler function) and a ValueHandle (which is passed at
/// runtime when a check failure occurs).
class Value {
  /// The type of the value.
  const TypeDescriptor &Type;
  /// The encoded value itself.
  ValueHandle Val;

  /// Is \c Val a (zero-extended) integer?
  bool isInlineInt() const {
    CHECK(getType().isIntegerTy());
    const unsigned InlineBits = sizeof(ValueHandle) * 8;
    const unsigned Bits = getType().getIntegerBitWidth();
    return Bits <= InlineBits;
  }

  /// Is \c Val a (zero-extended) integer representation of a float?
  bool isInlineFloat() const {
    CHECK(getType().isFloatTy());
    const unsigned InlineBits = sizeof(ValueHandle) * 8;
    const unsigned Bits = getType().getFloatBitWidth();
    return Bits <= InlineBits;
  }

public:
  Value(const TypeDescriptor &Type, ValueHandle Val) : Type(Type), Val(Val) {}

  const TypeDescriptor &getType() const { return Type; }

  /// \brief Get this value as a signed integer.
  SIntMax getSIntValue() const;

  /// \brief Get this value as an unsigned integer.
  UIntMax getUIntValue() const;

  /// \brief Decode this value, which must be a positive or unsigned integer.
  UIntMax getPositiveIntValue() const;

  /// Is this an integer with value -1?
  bool isMinusOne() const {
    return getType().isSignedIntegerTy() && getSIntValue() == -1;
  }

  /// Is this a negative integer?
  bool isNegative() const {
    return getType().isSignedIntegerTy() && getSIntValue() < 0;
  }

  /// \brief Get this value as a floating-point quantity.
  FloatMax getFloatValue() const;
};

} // namespace __ubsan

#endif // UBSAN_VALUE_H
