//===- MCSectionELF.h - ELF Machine Code Sections ---------------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file declares the MCSectionELF class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_MC_MCSECTIONELF_H
#define LLVM_MC_MCSECTIONELF_H

#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/SectionKind.h"

namespace llvm {

class MCSymbol;

/// This represents a section on linux, lots of unix variants and some bare
/// metal systems.
class MCSectionELF final : public MCSection {
  /// This is the sh_type field of a section, drawn from the enums below.
  unsigned Type;

  /// This is the sh_flags field of a section, drawn from the enums below.
  unsigned Flags;

  unsigned UniqueID;

  /// The size of each entry in this section. This size only makes sense for
  /// sections that contain fixed-sized entries. If a section does not contain
  /// fixed-sized entries 'EntrySize' will be 0.
  unsigned EntrySize;

  /// The section group signature symbol (if not null) and a bool indicating
  /// whether this is a GRP_COMDAT group.
  const PointerIntPair<const MCSymbolELF *, 1, bool> Group;

  /// Used by SHF_LINK_ORDER. If non-null, the sh_link field will be set to the
  /// section header index of the section where LinkedToSym is defined.
  const MCSymbol *LinkedToSym;

private:
  friend class MCContext;

  // The storage of Name is owned by MCContext's ELFUniquingMap.
  MCSectionELF(StringRef Name, unsigned type, unsigned flags, SectionKind K,
               unsigned entrySize, const MCSymbolELF *group, bool IsComdat,
               unsigned UniqueID, MCSymbol *Begin,
               const MCSymbolELF *LinkedToSym)
      : MCSection(SV_ELF, Name, K, Begin), Type(type), Flags(flags),
        UniqueID(UniqueID), EntrySize(entrySize), Group(group, IsComdat),
        LinkedToSym(LinkedToSym) {
    if (Group.getPointer())
      Group.getPointer()->setIsSignature();
  }

  // TODO Delete after we stop supporting generation of GNU-style .zdebug_*
  // sections.
  void setSectionName(StringRef Name) { this->Name = Name; }

public:
  /// Decides whether a '.section' directive should be printed before the
  /// section name
  bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;

  unsigned getType() const { return Type; }
  unsigned getFlags() const { return Flags; }
  unsigned getEntrySize() const { return EntrySize; }
  void setFlags(unsigned F) { Flags = F; }
  const MCSymbolELF *getGroup() const { return Group.getPointer(); }
  bool isComdat() const { return Group.getInt(); }

  void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
                            raw_ostream &OS,
                            const MCExpr *Subsection) const override;
  bool UseCodeAlign() const override;
  bool isVirtualSection() const override;
  StringRef getVirtualSectionKind() const override;

  bool isUnique() const { return UniqueID != NonUniqueID; }
  unsigned getUniqueID() const { return UniqueID; }

  const MCSection *getLinkedToSection() const {
    return &LinkedToSym->getSection();
  }
  const MCSymbol *getLinkedToSymbol() const { return LinkedToSym; }

  static bool classof(const MCSection *S) {
    return S->getVariant() == SV_ELF;
  }
};

} // end namespace llvm

#endif // LLVM_MC_MCSECTIONELF_H
