//===- AttributeImpl.h - Attribute Internals --------------------*- 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
/// This file defines various helper methods and classes used by
/// LLVMContextImpl for creating and managing attributes.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_IR_ATTRIBUTEIMPL_H
#define LLVM_LIB_IR_ATTRIBUTEIMPL_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Attributes.h"
#include "llvm/Support/TrailingObjects.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <string>
#include <utility>

namespace llvm {

class LLVMContext;
class Type;

//===----------------------------------------------------------------------===//
/// \class
/// This class represents a single, uniqued attribute. That attribute
/// could be a single enum, a tuple, or a string.
class AttributeImpl : public FoldingSetNode {
  unsigned char KindID; ///< Holds the AttrEntryKind of the attribute

protected:
  enum AttrEntryKind {
    EnumAttrEntry,
    IntAttrEntry,
    StringAttrEntry,
    TypeAttrEntry,
  };

  AttributeImpl(AttrEntryKind KindID) : KindID(KindID) {}

public:
  // AttributesImpl is uniqued, these should not be available.
  AttributeImpl(const AttributeImpl &) = delete;
  AttributeImpl &operator=(const AttributeImpl &) = delete;

  bool isEnumAttribute() const { return KindID == EnumAttrEntry; }
  bool isIntAttribute() const { return KindID == IntAttrEntry; }
  bool isStringAttribute() const { return KindID == StringAttrEntry; }
  bool isTypeAttribute() const { return KindID == TypeAttrEntry; }

  bool hasAttribute(Attribute::AttrKind A) const;
  bool hasAttribute(StringRef Kind) const;

  Attribute::AttrKind getKindAsEnum() const;
  uint64_t getValueAsInt() const;

  StringRef getKindAsString() const;
  StringRef getValueAsString() const;

  Type *getValueAsType() const;

  /// Used when sorting the attributes.
  bool operator<(const AttributeImpl &AI) const;

  void Profile(FoldingSetNodeID &ID) const {
    if (isEnumAttribute())
      Profile(ID, getKindAsEnum(), static_cast<uint64_t>(0));
    else if (isIntAttribute())
      Profile(ID, getKindAsEnum(), getValueAsInt());
    else if (isStringAttribute())
      Profile(ID, getKindAsString(), getValueAsString());
    else
      Profile(ID, getKindAsEnum(), getValueAsType());
  }

  static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,
                      uint64_t Val) {
    ID.AddInteger(Kind);
    if (Val) ID.AddInteger(Val);
  }

  static void Profile(FoldingSetNodeID &ID, StringRef Kind, StringRef Values) {
    ID.AddString(Kind);
    if (!Values.empty()) ID.AddString(Values);
  }

  static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,
                      Type *Ty) {
    ID.AddInteger(Kind);
    ID.AddPointer(Ty);
  }
};

static_assert(std::is_trivially_destructible<AttributeImpl>::value,
              "AttributeImpl should be trivially destructible");

//===----------------------------------------------------------------------===//
/// \class
/// A set of classes that contain the value of the
/// attribute object. There are three main categories: enum attribute entries,
/// represented by Attribute::AttrKind; alignment attribute entries; and string
/// attribute enties, which are for target-dependent attributes.

class EnumAttributeImpl : public AttributeImpl {
  Attribute::AttrKind Kind;

protected:
  EnumAttributeImpl(AttrEntryKind ID, Attribute::AttrKind Kind)
      : AttributeImpl(ID), Kind(Kind) {}

public:
  EnumAttributeImpl(Attribute::AttrKind Kind)
      : AttributeImpl(EnumAttrEntry), Kind(Kind) {}

  Attribute::AttrKind getEnumKind() const { return Kind; }
};

class IntAttributeImpl : public EnumAttributeImpl {
  uint64_t Val;

public:
  IntAttributeImpl(Attribute::AttrKind Kind, uint64_t Val)
      : EnumAttributeImpl(IntAttrEntry, Kind), Val(Val) {
    assert(Attribute::doesAttrKindHaveArgument(Kind) &&
           "Wrong kind for int attribute!");
  }

  uint64_t getValue() const { return Val; }
};

class StringAttributeImpl final
    : public AttributeImpl,
      private TrailingObjects<StringAttributeImpl, char> {
  friend TrailingObjects;

  unsigned KindSize;
  unsigned ValSize;
  size_t numTrailingObjects(OverloadToken<char>) const {
    return KindSize + 1 + ValSize + 1;
  }

public:
  StringAttributeImpl(StringRef Kind, StringRef Val = StringRef())
      : AttributeImpl(StringAttrEntry), KindSize(Kind.size()),
        ValSize(Val.size()) {
    char *TrailingString = getTrailingObjects<char>();
    // Some users rely on zero-termination.
    llvm::copy(Kind, TrailingString);
    TrailingString[KindSize] = '\0';
    llvm::copy(Val, &TrailingString[KindSize + 1]);
    TrailingString[KindSize + 1 + ValSize] = '\0';
  }

  StringRef getStringKind() const {
    return StringRef(getTrailingObjects<char>(), KindSize);
  }
  StringRef getStringValue() const {
    return StringRef(getTrailingObjects<char>() + KindSize + 1, ValSize);
  }

  static size_t totalSizeToAlloc(StringRef Kind, StringRef Val) {
    return TrailingObjects::totalSizeToAlloc<char>(Kind.size() + 1 +
                                                   Val.size() + 1);
  }
};

class TypeAttributeImpl : public EnumAttributeImpl {
  Type *Ty;

public:
  TypeAttributeImpl(Attribute::AttrKind Kind, Type *Ty)
      : EnumAttributeImpl(TypeAttrEntry, Kind), Ty(Ty) {}

  Type *getTypeValue() const { return Ty; }
};

class AttributeBitSet {
  /// Bitset with a bit for each available attribute Attribute::AttrKind.
  uint8_t AvailableAttrs[12] = {};
  static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT,
                "Too many attributes");

public:
  bool hasAttribute(Attribute::AttrKind Kind) const {
    return AvailableAttrs[Kind / 8] & (1 << (Kind % 8));
  }

  void addAttribute(Attribute::AttrKind Kind) {
    AvailableAttrs[Kind / 8] |= 1 << (Kind % 8);
  }
};

//===----------------------------------------------------------------------===//
/// \class
/// This class represents a group of attributes that apply to one
/// element: function, return type, or parameter.
class AttributeSetNode final
    : public FoldingSetNode,
      private TrailingObjects<AttributeSetNode, Attribute> {
  friend TrailingObjects;

  unsigned NumAttrs; ///< Number of attributes in this node.
  AttributeBitSet AvailableAttrs; ///< Available enum attributes.

  DenseMap<StringRef, Attribute> StringAttrs;

  AttributeSetNode(ArrayRef<Attribute> Attrs);

  static AttributeSetNode *getSorted(LLVMContext &C,
                                     ArrayRef<Attribute> SortedAttrs);
  Optional<Attribute> findEnumAttribute(Attribute::AttrKind Kind) const;

public:
  // AttributesSetNode is uniqued, these should not be available.
  AttributeSetNode(const AttributeSetNode &) = delete;
  AttributeSetNode &operator=(const AttributeSetNode &) = delete;

  void operator delete(void *p) { ::operator delete(p); }

  static AttributeSetNode *get(LLVMContext &C, const AttrBuilder &B);

  static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);

  /// Return the number of attributes this AttributeList contains.
  unsigned getNumAttributes() const { return NumAttrs; }

  bool hasAttribute(Attribute::AttrKind Kind) const {
    return AvailableAttrs.hasAttribute(Kind);
  }
  bool hasAttribute(StringRef Kind) const;
  bool hasAttributes() const { return NumAttrs != 0; }

  Attribute getAttribute(Attribute::AttrKind Kind) const;
  Attribute getAttribute(StringRef Kind) const;

  MaybeAlign getAlignment() const;
  MaybeAlign getStackAlignment() const;
  uint64_t getDereferenceableBytes() const;
  uint64_t getDereferenceableOrNullBytes() const;
  std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
  std::string getAsString(bool InAttrGrp) const;
  Type *getByValType() const;
  Type *getPreallocatedType() const;

  using iterator = const Attribute *;

  iterator begin() const { return getTrailingObjects<Attribute>(); }
  iterator end() const { return begin() + NumAttrs; }

  void Profile(FoldingSetNodeID &ID) const {
    Profile(ID, makeArrayRef(begin(), end()));
  }

  static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) {
    for (const auto &Attr : AttrList)
      Attr.Profile(ID);
  }
};

//===----------------------------------------------------------------------===//
/// \class
/// This class represents a set of attributes that apply to the function,
/// return type, and parameters.
class AttributeListImpl final
    : public FoldingSetNode,
      private TrailingObjects<AttributeListImpl, AttributeSet> {
  friend class AttributeList;
  friend TrailingObjects;

private:
  unsigned NumAttrSets; ///< Number of entries in this set.
  /// Available enum function attributes.
  AttributeBitSet AvailableFunctionAttrs;
  /// Union of enum attributes available at any index.
  AttributeBitSet AvailableSomewhereAttrs;

  // Helper fn for TrailingObjects class.
  size_t numTrailingObjects(OverloadToken<AttributeSet>) { return NumAttrSets; }

public:
  AttributeListImpl(ArrayRef<AttributeSet> Sets);

  // AttributesSetImpt is uniqued, these should not be available.
  AttributeListImpl(const AttributeListImpl &) = delete;
  AttributeListImpl &operator=(const AttributeListImpl &) = delete;

  /// Return true if the AttributeSet or the FunctionIndex has an
  /// enum attribute of the given kind.
  bool hasFnAttribute(Attribute::AttrKind Kind) const {
    return AvailableFunctionAttrs.hasAttribute(Kind);
  }

  /// Return true if the specified attribute is set for at least one
  /// parameter or for the return value. If Index is not nullptr, the index
  /// of a parameter with the specified attribute is provided.
  bool hasAttrSomewhere(Attribute::AttrKind Kind,
                        unsigned *Index = nullptr) const;

  using iterator = const AttributeSet *;

  iterator begin() const { return getTrailingObjects<AttributeSet>(); }
  iterator end() const { return begin() + NumAttrSets; }

  void Profile(FoldingSetNodeID &ID) const;
  static void Profile(FoldingSetNodeID &ID, ArrayRef<AttributeSet> Nodes);

  void dump() const;
};

static_assert(std::is_trivially_destructible<AttributeListImpl>::value,
              "AttributeListImpl should be trivially destructible");

} // end namespace llvm

#endif // LLVM_LIB_IR_ATTRIBUTEIMPL_H
