/* Language-independent APIs to enable/disable per-location warnings.

   Copyright (C) 2021-2025 Free Software Foundation, Inc.
   Contributed by Martin Sebor <msebor@redhat.com>

   This file is part of GCC.

   GCC is free software; you can redistribute it and/or modify it under
   the terms of the GNU General Public License as published by the Free
   Software Foundation; either version 3, or (at your option) any later
   version.

   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   for more details.

   You should have received a copy of the GNU General Public License
   along with GCC; see the file COPYING3.  If not see
   <http://www.gnu.org/licenses/>.  */

#ifndef GCC_DIAGNOSTIC_SPEC_H_INCLUDED
#define GCC_DIAGNOSTIC_SPEC_H_INCLUDED

#include "hash-map.h"

/* A "bitset" of warning groups.  */

class nowarn_spec_t
{
public:
  enum
    {
     /* Middle end warnings about invalid accesses.  */
     NW_ACCESS = 1 << 0,
     /* Front end/lexical warnings.  */
     NW_LEXICAL = 1 << 1,
     /* Warnings about null pointers.  */
     NW_NONNULL = 1 << 2,
     /* Warnings about uninitialized reads.  */
     NW_UNINIT = 1 << 3,
     /* Warnings about arithmetic overflow.  */
     NW_VFLOW = 1 << 4,
     /* Warnings about dangling pointers.  */
     NW_DANGLING = 1 << 5,
     /* All other unclassified warnings.  */
     NW_OTHER = 1 << 6,
     /* Warnings about redundant calls.  */
     NW_REDUNDANT = 1 << 7,
     /* All groups of warnings.  */
     NW_ALL = (NW_ACCESS | NW_LEXICAL | NW_NONNULL
	       | NW_UNINIT | NW_VFLOW | NW_DANGLING | NW_REDUNDANT | NW_OTHER)
   };

  nowarn_spec_t (): m_bits () { }

  nowarn_spec_t (opt_code);

  static nowarn_spec_t from_bits (unsigned bits)
  {
    nowarn_spec_t spec;
    spec.m_bits = bits;
    return spec;
  }

  /* Return the raw bitset.  */
  operator unsigned() const
  {
    return m_bits;
  }

  /* Return true if the bitset is clear.  */
  bool operator!() const
  {
    return !m_bits;
  }

  /* Return the inverse of the bitset.  */
  nowarn_spec_t operator~() const
  {
    nowarn_spec_t res (*this);
    res.m_bits &= ~NW_ALL;
    return res;
  }

  /* Set *THIS to the bitwise OR of *THIS and RHS.  */
  nowarn_spec_t& operator|= (const nowarn_spec_t &rhs)
  {
    m_bits |= rhs.m_bits;
    return *this;
  }

  /* Set *THIS to the bitwise AND of *THIS and RHS.  */
  nowarn_spec_t& operator&= (const nowarn_spec_t &rhs)
  {
    m_bits &= rhs.m_bits;
    return *this;
  }

  /* Set *THIS to the bitwise exclusive OR of *THIS and RHS.  */
  nowarn_spec_t& operator^= (const nowarn_spec_t &rhs)
  {
    m_bits ^= rhs.m_bits;
    return *this;
  }

private:
  /* Bitset of warning groups.  */
  unsigned m_bits;
};

/* Return the bitwise OR of LHS and RHS.  */

inline nowarn_spec_t
operator| (const nowarn_spec_t &lhs, const nowarn_spec_t &rhs)
{
  return nowarn_spec_t (lhs) |= rhs;
}

/* Return the bitwise AND of LHS and RHS.  */

inline nowarn_spec_t
operator& (const nowarn_spec_t &lhs, const nowarn_spec_t &rhs)
{
  return nowarn_spec_t (lhs) &= rhs;
}

/* Return true if LHS is equal RHS.  */

inline bool
operator== (const nowarn_spec_t &lhs, const nowarn_spec_t &rhs)
{
  return static_cast<unsigned>(lhs) == static_cast<unsigned>(rhs);
}

/* Return true if LHS is not equal RHS.  */

inline bool
operator!= (const nowarn_spec_t &lhs, const nowarn_spec_t &rhs)
{
  return !(lhs == rhs);
}

typedef hash_map<location_hash, nowarn_spec_t> nowarn_map_t;

/* A mapping from a 'location_t' to the warning spec set for it.  */
extern GTY(()) nowarn_map_t *nowarn_map;

#endif // GCC_DIAGNOSTIC_SPEC_H_INCLUDED
