//===-- Declaration.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
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_SYMBOL_DECLARATION_H
#define LLDB_SYMBOL_DECLARATION_H

#include "lldb/Utility/FileSpec.h"
#include "lldb/lldb-private.h"

namespace lldb_private {

/// \class Declaration Declaration.h "lldb/Core/Declaration.h"
/// A class that describes the declaration location of a
///        lldb object.
///
/// The declarations include the file specification, line number, and the
/// column info and can help track where functions, blocks, inlined functions,
/// types, variables, any many other debug core objects were declared.
class Declaration {
public:
  /// Default constructor.
  Declaration() : m_file() {}

  /// Construct with file specification, and optional line and column.
  ///
  /// \param[in] file_spec
  ///     The file specification that describes where this was
  ///     declared.
  ///
  /// \param[in] line
  ///     The line number that describes where this was declared. Set
  ///     to zero if there is no line number information.
  ///
  /// \param[in] column
  ///     The column number that describes where this was declared.
  ///     Set to zero if there is no column number information.
  Declaration(const FileSpec &file_spec, uint32_t line = 0,
              uint16_t column = LLDB_INVALID_COLUMN_NUMBER)
      : m_file(file_spec), m_line(line), m_column(column) {}

  /// Construct with a pointer to another Declaration object.
  Declaration(const Declaration *decl_ptr)
      : m_file(), m_line(0), m_column(LLDB_INVALID_COLUMN_NUMBER) {
    if (decl_ptr)
      *this = *decl_ptr;
  }

  /// Clear the object's state.
  ///
  /// Sets the file specification to be empty, and the line and column to
  /// zero.
  void Clear() {
    m_file.Clear();
    m_line = 0;
    m_column = 0;
  }

  /// Compare two declaration objects.
  ///
  /// Compares the two file specifications from \a lhs and \a rhs. If the file
  /// specifications are equal, then continue to compare the line number and
  /// column numbers respectively.
  ///
  /// \param[in] lhs
  ///     The Left Hand Side const Declaration object reference.
  ///
  /// \param[in] rhs
  ///     The Right Hand Side const Declaration object reference.
  ///
  /// \return
  ///     -1 if lhs < rhs
  ///     0 if lhs == rhs
  ///     1 if lhs > rhs
  static int Compare(const Declaration &lhs, const Declaration &rhs);

  /// Checks if this object has the same file and line as another declaration
  /// object.
  ///
  /// \param[in] declaration
  ///     The const Declaration object to compare with.
  ///
  /// \return
  ///     Returns \b true if \b declaration is at the same file and
  ///     line, \b false otherwise.
  bool FileAndLineEqual(const Declaration &declaration) const;

  /// Dump a description of this object to a Stream.
  ///
  /// Dump a description of the contents of this object to the supplied stream
  /// \a s.
  ///
  /// \param[in] s
  ///     The stream to which to dump the object description.
  void Dump(Stream *s, bool show_fullpaths) const;

  bool DumpStopContext(Stream *s, bool show_fullpaths) const;

  /// Get accessor for file specification.
  ///
  /// \return
  ///     A reference to the file specification object.
  FileSpec &GetFile() { return m_file; }

  /// Get const accessor for file specification.
  ///
  /// \return
  ///     A const reference to the file specification object.
  const FileSpec &GetFile() const { return m_file; }

  /// Get accessor for the declaration line number.
  ///
  /// \return
  ///     Non-zero indicates a valid line number, zero indicates no
  ///     line information is available.
  uint32_t GetLine() const { return m_line; }

  /// Get accessor for the declaration column number.
  ///
  /// \return
  ///     Non-zero indicates a valid column number, zero indicates no
  ///     column information is available.
  uint16_t GetColumn() const { return m_column; }

  /// Convert to boolean operator.
  ///
  /// This allows code to check a Declaration object to see if it
  /// contains anything valid using code such as:
  ///
  /// \code
  /// Declaration decl(...);
  /// if (decl)
  /// { ...
  /// \endcode
  ///
  /// \return
  ///     A \b true if both the file_spec and the line are valid,
  ///     \b false otherwise.
  explicit operator bool() const { return IsValid(); }

  bool IsValid() const {
    return m_file && m_line != 0 && m_line != LLDB_INVALID_LINE_NUMBER;
  }

  /// Get the memory cost of this object.
  ///
  /// \return
  ///     The number of bytes that this object occupies in memory.
  ///     The returned value does not include the bytes for any
  ///     shared string values.
  ///
  /// \see ConstString::StaticMemorySize ()
  size_t MemorySize() const;

  /// Set accessor for the declaration file specification.
  ///
  /// \param[in] file_spec
  ///     The new declaration file specification.
  void SetFile(const FileSpec &file_spec) { m_file = file_spec; }

  /// Set accessor for the declaration line number.
  ///
  /// \param[in] line
  ///     Non-zero indicates a valid line number, zero indicates no
  ///     line information is available.
  void SetLine(uint32_t line) { m_line = line; }

  /// Set accessor for the declaration column number.
  ///
  /// \param[in] column
  ///     Non-zero indicates a valid column number, zero indicates no
  ///     column information is available.
  void SetColumn(uint16_t column) { m_column = column; }

protected:
  /// The file specification that points to the source file where the
  /// declaration occurred.
  FileSpec m_file;
  /// Non-zero values indicates a valid line number, zero indicates no line
  /// number information is available.
  uint32_t m_line = 0;
  /// Non-zero values indicates a valid column number, zero indicates no column
  /// information is available.
  uint16_t m_column = LLDB_INVALID_COLUMN_NUMBER;
};

bool operator==(const Declaration &lhs, const Declaration &rhs);

} // namespace lldb_private

#endif // LLDB_SYMBOL_DECLARATION_H
