//===- Sanitizers.h - C Language Family Language Options --------*- 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
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Defines the clang::SanitizerKind enum.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_BASIC_SANITIZERS_H
#define LLVM_CLANG_BASIC_SANITIZERS_H

#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <cstdint>

namespace llvm {
class hash_code;
}

namespace clang {

class SanitizerMask {
  // NOTE: this class assumes kNumElem == 2 in most of the constexpr functions,
  // in order to work within the C++11 constexpr function constraints. If you
  // change kNumElem, you'll need to update those member functions as well.

  /// Number of array elements.
  static constexpr unsigned kNumElem = 2;
  /// Mask value initialized to 0.
  uint64_t maskLoToHigh[kNumElem]{};
  /// Number of bits in a mask.
  static constexpr unsigned kNumBits = sizeof(decltype(maskLoToHigh)) * 8;
  /// Number of bits in a mask element.
  static constexpr unsigned kNumBitElem = sizeof(decltype(maskLoToHigh[0])) * 8;

  constexpr SanitizerMask(uint64_t mask1, uint64_t mask2)
      : maskLoToHigh{mask1, mask2} {}

public:
  SanitizerMask() = default;

  static constexpr bool checkBitPos(const unsigned Pos) {
    return Pos < kNumBits;
  }

  /// Create a mask with a bit enabled at position Pos.
  static constexpr SanitizerMask bitPosToMask(const unsigned Pos) {
    return SanitizerMask((Pos < kNumBitElem) ? 1ULL << Pos % kNumBitElem : 0,
                         (Pos >= kNumBitElem && Pos < kNumBitElem * 2)
                             ? 1ULL << Pos % kNumBitElem
                             : 0);
  }

  unsigned countPopulation() const {
    unsigned total = 0;
    for (const auto &Val : maskLoToHigh)
      total += llvm::countPopulation(Val);
    return total;
  }

  void flipAllBits() {
    for (auto &Val : maskLoToHigh)
      Val = ~Val;
  }

  bool isPowerOf2() const {
    return countPopulation() == 1;
  }

  llvm::hash_code hash_value() const;

  constexpr explicit operator bool() const {
    return maskLoToHigh[0] || maskLoToHigh[1];
  }

  constexpr bool operator==(const SanitizerMask &V) const {
    return maskLoToHigh[0] == V.maskLoToHigh[0] &&
           maskLoToHigh[1] == V.maskLoToHigh[1];
  }

  SanitizerMask &operator&=(const SanitizerMask &RHS) {
    for (unsigned k = 0; k < kNumElem; k++)
      maskLoToHigh[k] &= RHS.maskLoToHigh[k];
    return *this;
  }

  SanitizerMask &operator|=(const SanitizerMask &RHS) {
    for (unsigned k = 0; k < kNumElem; k++)
      maskLoToHigh[k] |= RHS.maskLoToHigh[k];
    return *this;
  }

  constexpr bool operator!() const { return !bool(*this); }

  constexpr bool operator!=(const SanitizerMask &RHS) const {
    return !((*this) == RHS);
  }

  friend constexpr inline SanitizerMask operator~(SanitizerMask v) {
    return SanitizerMask(~v.maskLoToHigh[0], ~v.maskLoToHigh[1]);
  }

  friend constexpr inline SanitizerMask operator&(SanitizerMask a,
                                                  const SanitizerMask &b) {
    return SanitizerMask(a.maskLoToHigh[0] & b.maskLoToHigh[0],
                         a.maskLoToHigh[1] & b.maskLoToHigh[1]);
  }

  friend constexpr inline SanitizerMask operator|(SanitizerMask a,
                                                  const SanitizerMask &b) {
    return SanitizerMask(a.maskLoToHigh[0] | b.maskLoToHigh[0],
                         a.maskLoToHigh[1] | b.maskLoToHigh[1]);
  }
};

// Declaring in clang namespace so that it can be found by ADL.
llvm::hash_code hash_value(const clang::SanitizerMask &Arg);

// Define the set of sanitizer kinds, as well as the set of sanitizers each
// sanitizer group expands into.
struct SanitizerKind {
  // Assign ordinals to possible values of -fsanitize= flag, which we will use
  // as bit positions.
  enum SanitizerOrdinal : uint64_t {
#define SANITIZER(NAME, ID) SO_##ID,
#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
#include "clang/Basic/Sanitizers.def"
    SO_Count
  };

#define SANITIZER(NAME, ID)                                                    \
  static constexpr SanitizerMask ID = SanitizerMask::bitPosToMask(SO_##ID);    \
  static_assert(SanitizerMask::checkBitPos(SO_##ID), "Bit position too big.");
#define SANITIZER_GROUP(NAME, ID, ALIAS)                                       \
  static constexpr SanitizerMask ID = SanitizerMask(ALIAS);                    \
  static constexpr SanitizerMask ID##Group =                                   \
      SanitizerMask::bitPosToMask(SO_##ID##Group);                             \
  static_assert(SanitizerMask::checkBitPos(SO_##ID##Group),                    \
                "Bit position too big.");
#include "clang/Basic/Sanitizers.def"
}; // SanitizerKind

struct SanitizerSet {
  /// Check if a certain (single) sanitizer is enabled.
  bool has(SanitizerMask K) const {
    assert(K.isPowerOf2() && "Has to be a single sanitizer.");
    return static_cast<bool>(Mask & K);
  }

  /// Check if one or more sanitizers are enabled.
  bool hasOneOf(SanitizerMask K) const { return static_cast<bool>(Mask & K); }

  /// Enable or disable a certain (single) sanitizer.
  void set(SanitizerMask K, bool Value) {
    assert(K.isPowerOf2() && "Has to be a single sanitizer.");
    Mask = Value ? (Mask | K) : (Mask & ~K);
  }

  /// Disable the sanitizers specified in \p K.
  void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; }

  /// Returns true if no sanitizers are enabled.
  bool empty() const { return !Mask; }

  /// Bitmask of enabled sanitizers.
  SanitizerMask Mask;
};

/// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);

/// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
/// this group enables.
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds);

/// Return the sanitizers which do not affect preprocessing.
inline SanitizerMask getPPTransparentSanitizers() {
  return SanitizerKind::CFI | SanitizerKind::Integer |
         SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
         SanitizerKind::Undefined | SanitizerKind::FloatDivideByZero;
}

} // namespace clang

#endif // LLVM_CLANG_BASIC_SANITIZERS_H
