//===-- Globals.cpp - Implement the GlobalValue & GlobalVariable class ----===//
//
// 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 implements the GlobalValue & GlobalVariable classes for the IR
// library.
//
//===----------------------------------------------------------------------===//

#include "LLVMContextImpl.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MD5.h"
#include "llvm/TargetParser/Triple.h"
using namespace llvm;

//===----------------------------------------------------------------------===//
//                            GlobalValue Class
//===----------------------------------------------------------------------===//

// GlobalValue should be a Constant, plus a type, a module, some flags, and an
// intrinsic ID. Add an assert to prevent people from accidentally growing
// GlobalValue while adding flags.
static_assert(sizeof(GlobalValue) ==
                  sizeof(Constant) + 2 * sizeof(void *) + 2 * sizeof(unsigned),
              "unexpected GlobalValue size growth");

// GlobalObject adds a comdat.
static_assert(sizeof(GlobalObject) == sizeof(GlobalValue) + sizeof(void *),
              "unexpected GlobalObject size growth");

bool GlobalValue::isMaterializable() const {
  if (const Function *F = dyn_cast<Function>(this))
    return F->isMaterializable();
  return false;
}
Error GlobalValue::materialize() { return getParent()->materialize(this); }

/// Override destroyConstantImpl to make sure it doesn't get called on
/// GlobalValue's because they shouldn't be treated like other constants.
void GlobalValue::destroyConstantImpl() {
  llvm_unreachable("You can't GV->destroyConstantImpl()!");
}

Value *GlobalValue::handleOperandChangeImpl(Value *From, Value *To) {
  llvm_unreachable("Unsupported class for handleOperandChange()!");
}

/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a GlobalValue) from the GlobalValue Src to this one.
void GlobalValue::copyAttributesFrom(const GlobalValue *Src) {
  setVisibility(Src->getVisibility());
  setUnnamedAddr(Src->getUnnamedAddr());
  setThreadLocalMode(Src->getThreadLocalMode());
  setDLLStorageClass(Src->getDLLStorageClass());
  setDSOLocal(Src->isDSOLocal());
  setPartition(Src->getPartition());
  if (Src->hasSanitizerMetadata())
    setSanitizerMetadata(Src->getSanitizerMetadata());
  else
    removeSanitizerMetadata();
}

GlobalValue::GUID
GlobalValue::getGUIDAssumingExternalLinkage(StringRef GlobalIdentifier) {
  return MD5Hash(GlobalIdentifier);
}

void GlobalValue::removeFromParent() {
  switch (getValueID()) {
#define HANDLE_GLOBAL_VALUE(NAME)                                              \
  case Value::NAME##Val:                                                       \
    return static_cast<NAME *>(this)->removeFromParent();
#include "llvm/IR/Value.def"
  default:
    break;
  }
  llvm_unreachable("not a global");
}

void GlobalValue::eraseFromParent() {
  switch (getValueID()) {
#define HANDLE_GLOBAL_VALUE(NAME)                                              \
  case Value::NAME##Val:                                                       \
    return static_cast<NAME *>(this)->eraseFromParent();
#include "llvm/IR/Value.def"
  default:
    break;
  }
  llvm_unreachable("not a global");
}

GlobalObject::~GlobalObject() { setComdat(nullptr); }

bool GlobalValue::isInterposable() const {
  if (isInterposableLinkage(getLinkage()))
    return true;
  return getParent() && getParent()->getSemanticInterposition() &&
         !isDSOLocal();
}

bool GlobalValue::canBenefitFromLocalAlias() const {
  if (isTagged()) {
    // Cannot create local aliases to MTE tagged globals. The address of a
    // tagged global includes a tag that is assigned by the loader in the
    // GOT.
    return false;
  }
  // See AsmPrinter::getSymbolPreferLocal(). For a deduplicate comdat kind,
  // references to a discarded local symbol from outside the group are not
  // allowed, so avoid the local alias.
  auto isDeduplicateComdat = [](const Comdat *C) {
    return C && C->getSelectionKind() != Comdat::NoDeduplicate;
  };
  return hasDefaultVisibility() &&
         GlobalObject::isExternalLinkage(getLinkage()) && !isDeclaration() &&
         !isa<GlobalIFunc>(this) && !isDeduplicateComdat(getComdat());
}

const DataLayout &GlobalValue::getDataLayout() const {
  return getParent()->getDataLayout();
}

void GlobalObject::setAlignment(MaybeAlign Align) {
  assert((!Align || *Align <= MaximumAlignment) &&
         "Alignment is greater than MaximumAlignment!");
  unsigned AlignmentData = encode(Align);
  unsigned OldData = getGlobalValueSubClassData();
  setGlobalValueSubClassData((OldData & ~AlignmentMask) | AlignmentData);
  assert(getAlign() == Align && "Alignment representation error!");
}

void GlobalObject::setAlignment(Align Align) {
  assert(Align <= MaximumAlignment &&
         "Alignment is greater than MaximumAlignment!");
  unsigned AlignmentData = encode(Align);
  unsigned OldData = getGlobalValueSubClassData();
  setGlobalValueSubClassData((OldData & ~AlignmentMask) | AlignmentData);
  assert(getAlign() && *getAlign() == Align &&
         "Alignment representation error!");
}

void GlobalObject::copyAttributesFrom(const GlobalObject *Src) {
  GlobalValue::copyAttributesFrom(Src);
  setAlignment(Src->getAlign());
  setSection(Src->getSection());
}

std::string GlobalValue::getGlobalIdentifier(StringRef Name,
                                             GlobalValue::LinkageTypes Linkage,
                                             StringRef FileName) {
  // Value names may be prefixed with a binary '1' to indicate
  // that the backend should not modify the symbols due to any platform
  // naming convention. Do not include that '1' in the PGO profile name.
  Name.consume_front("\1");

  std::string GlobalName;
  if (llvm::GlobalValue::isLocalLinkage(Linkage)) {
    // For local symbols, prepend the main file name to distinguish them.
    // Do not include the full path in the file name since there's no guarantee
    // that it will stay the same, e.g., if the files are checked out from
    // version control in different locations.
    if (FileName.empty())
      GlobalName += "<unknown>";
    else
      GlobalName += FileName;

    GlobalName += GlobalIdentifierDelimiter;
  }
  GlobalName += Name;
  return GlobalName;
}

std::string GlobalValue::getGlobalIdentifier() const {
  return getGlobalIdentifier(getName(), getLinkage(),
                             getParent()->getSourceFileName());
}

StringRef GlobalValue::getSection() const {
  if (auto *GA = dyn_cast<GlobalAlias>(this)) {
    // In general we cannot compute this at the IR level, but we try.
    if (const GlobalObject *GO = GA->getAliaseeObject())
      return GO->getSection();
    return "";
  }
  return cast<GlobalObject>(this)->getSection();
}

const Comdat *GlobalValue::getComdat() const {
  if (auto *GA = dyn_cast<GlobalAlias>(this)) {
    // In general we cannot compute this at the IR level, but we try.
    if (const GlobalObject *GO = GA->getAliaseeObject())
      return const_cast<GlobalObject *>(GO)->getComdat();
    return nullptr;
  }
  // ifunc and its resolver are separate things so don't use resolver comdat.
  if (isa<GlobalIFunc>(this))
    return nullptr;
  return cast<GlobalObject>(this)->getComdat();
}

void GlobalObject::setComdat(Comdat *C) {
  if (ObjComdat)
    ObjComdat->removeUser(this);
  ObjComdat = C;
  if (C)
    C->addUser(this);
}

StringRef GlobalValue::getPartition() const {
  if (!hasPartition())
    return "";
  return getContext().pImpl->GlobalValuePartitions[this];
}

void GlobalValue::setPartition(StringRef S) {
  // Do nothing if we're clearing the partition and it is already empty.
  if (!hasPartition() && S.empty())
    return;

  // Get or create a stable partition name string and put it in the table in the
  // context.
  if (!S.empty())
    S = getContext().pImpl->Saver.save(S);
  getContext().pImpl->GlobalValuePartitions[this] = S;

  // Update the HasPartition field. Setting the partition to the empty string
  // means this global no longer has a partition.
  HasPartition = !S.empty();
}

using SanitizerMetadata = GlobalValue::SanitizerMetadata;
const SanitizerMetadata &GlobalValue::getSanitizerMetadata() const {
  assert(hasSanitizerMetadata());
  assert(getContext().pImpl->GlobalValueSanitizerMetadata.count(this));
  return getContext().pImpl->GlobalValueSanitizerMetadata[this];
}

void GlobalValue::setSanitizerMetadata(SanitizerMetadata Meta) {
  getContext().pImpl->GlobalValueSanitizerMetadata[this] = Meta;
  HasSanitizerMetadata = true;
}

void GlobalValue::removeSanitizerMetadata() {
  DenseMap<const GlobalValue *, SanitizerMetadata> &MetadataMap =
      getContext().pImpl->GlobalValueSanitizerMetadata;
  MetadataMap.erase(this);
  HasSanitizerMetadata = false;
}

void GlobalValue::setNoSanitizeMetadata() {
  SanitizerMetadata Meta;
  Meta.NoAddress = true;
  Meta.NoHWAddress = true;
  setSanitizerMetadata(Meta);
}

StringRef GlobalObject::getSectionImpl() const {
  assert(hasSection());
  return getContext().pImpl->GlobalObjectSections[this];
}

void GlobalObject::setSection(StringRef S) {
  // Do nothing if we're clearing the section and it is already empty.
  if (!hasSection() && S.empty())
    return;

  // Get or create a stable section name string and put it in the table in the
  // context.
  if (!S.empty())
    S = getContext().pImpl->Saver.save(S);
  getContext().pImpl->GlobalObjectSections[this] = S;

  // Update the HasSectionHashEntryBit. Setting the section to the empty string
  // means this global no longer has a section.
  setGlobalObjectFlag(HasSectionHashEntryBit, !S.empty());
}

bool GlobalObject::setSectionPrefix(StringRef Prefix) {
  StringRef ExistingPrefix;
  if (std::optional<StringRef> MaybePrefix = getSectionPrefix())
    ExistingPrefix = *MaybePrefix;

  if (ExistingPrefix == Prefix)
    return false;

  if (Prefix.empty()) {
    setMetadata(LLVMContext::MD_section_prefix, nullptr);
    return true;
  }
  MDBuilder MDB(getContext());
  setMetadata(LLVMContext::MD_section_prefix,
              MDB.createGlobalObjectSectionPrefix(Prefix));
  return true;
}

std::optional<StringRef> GlobalObject::getSectionPrefix() const {
  if (MDNode *MD = getMetadata(LLVMContext::MD_section_prefix)) {
    [[maybe_unused]] StringRef MDName =
        cast<MDString>(MD->getOperand(0))->getString();
    assert((MDName == "section_prefix" ||
            (isa<Function>(this) && MDName == "function_section_prefix")) &&
           "Metadata not match");
    return cast<MDString>(MD->getOperand(1))->getString();
  }
  return std::nullopt;
}

bool GlobalValue::isNobuiltinFnDef() const {
  const Function *F = dyn_cast<Function>(this);
  if (!F || F->empty())
    return false;
  return F->hasFnAttribute(Attribute::NoBuiltin);
}

bool GlobalValue::isDeclaration() const {
  // Globals are definitions if they have an initializer.
  if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(this))
    return GV->getNumOperands() == 0;

  // Functions are definitions if they have a body.
  if (const Function *F = dyn_cast<Function>(this))
    return F->empty() && !F->isMaterializable();

  // Aliases and ifuncs are always definitions.
  assert(isa<GlobalAlias>(this) || isa<GlobalIFunc>(this));
  return false;
}

bool GlobalObject::canIncreaseAlignment() const {
  // Firstly, can only increase the alignment of a global if it
  // is a strong definition.
  if (!isStrongDefinitionForLinker())
    return false;

  // It also has to either not have a section defined, or, not have
  // alignment specified. (If it is assigned a section, the global
  // could be densely packed with other objects in the section, and
  // increasing the alignment could cause padding issues.)
  if (hasSection() && getAlign())
    return false;

  // On ELF platforms, we're further restricted in that we can't
  // increase the alignment of any variable which might be emitted
  // into a shared library, and which is exported. If the main
  // executable accesses a variable found in a shared-lib, the main
  // exe actually allocates memory for and exports the symbol ITSELF,
  // overriding the symbol found in the library. That is, at link
  // time, the observed alignment of the variable is copied into the
  // executable binary. (A COPY relocation is also generated, to copy
  // the initial data from the shadowed variable in the shared-lib
  // into the location in the main binary, before running code.)
  //
  // And thus, even though you might think you are defining the
  // global, and allocating the memory for the global in your object
  // file, and thus should be able to set the alignment arbitrarily,
  // that's not actually true. Doing so can cause an ABI breakage; an
  // executable might have already been built with the previous
  // alignment of the variable, and then assuming an increased
  // alignment will be incorrect.

  // Conservatively assume ELF if there's no parent pointer.
  bool isELF = (!Parent || Parent->getTargetTriple().isOSBinFormatELF());
  if (isELF && !isDSOLocal())
    return false;

  // GV with toc-data attribute is defined in a TOC entry. To mitigate TOC
  // overflow, the alignment of such symbol should not be increased. Otherwise,
  // padding is needed thus more TOC entries are wasted.
  bool isXCOFF = (!Parent || Parent->getTargetTriple().isOSBinFormatXCOFF());
  if (isXCOFF)
    if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(this))
      if (GV->hasAttribute("toc-data"))
        return false;

  return true;
}

template <typename Operation>
static const GlobalObject *
findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases,
               const Operation &Op) {
  if (auto *GO = dyn_cast<GlobalObject>(C)) {
    Op(*GO);
    return GO;
  }
  if (auto *GA = dyn_cast<GlobalAlias>(C)) {
    Op(*GA);
    if (Aliases.insert(GA).second)
      return findBaseObject(GA->getOperand(0), Aliases, Op);
  }
  if (auto *CE = dyn_cast<ConstantExpr>(C)) {
    switch (CE->getOpcode()) {
    case Instruction::Add: {
      auto *LHS = findBaseObject(CE->getOperand(0), Aliases, Op);
      auto *RHS = findBaseObject(CE->getOperand(1), Aliases, Op);
      if (LHS && RHS)
        return nullptr;
      return LHS ? LHS : RHS;
    }
    case Instruction::Sub: {
      if (findBaseObject(CE->getOperand(1), Aliases, Op))
        return nullptr;
      return findBaseObject(CE->getOperand(0), Aliases, Op);
    }
    case Instruction::IntToPtr:
    case Instruction::PtrToAddr:
    case Instruction::PtrToInt:
    case Instruction::BitCast:
    case Instruction::AddrSpaceCast:
    case Instruction::GetElementPtr:
      return findBaseObject(CE->getOperand(0), Aliases, Op);
    default:
      break;
    }
  }
  return nullptr;
}

const GlobalObject *GlobalValue::getAliaseeObject() const {
  DenseSet<const GlobalAlias *> Aliases;
  return findBaseObject(this, Aliases, [](const GlobalValue &) {});
}

bool GlobalValue::isAbsoluteSymbolRef() const {
  auto *GO = dyn_cast<GlobalObject>(this);
  if (!GO)
    return false;

  return GO->getMetadata(LLVMContext::MD_absolute_symbol);
}

std::optional<ConstantRange> GlobalValue::getAbsoluteSymbolRange() const {
  auto *GO = dyn_cast<GlobalObject>(this);
  if (!GO)
    return std::nullopt;

  MDNode *MD = GO->getMetadata(LLVMContext::MD_absolute_symbol);
  if (!MD)
    return std::nullopt;

  return getConstantRangeFromMetadata(*MD);
}

bool GlobalValue::canBeOmittedFromSymbolTable() const {
  if (!hasLinkOnceODRLinkage())
    return false;

  // We assume that anyone who sets global unnamed_addr on a non-constant
  // knows what they're doing.
  if (hasGlobalUnnamedAddr())
    return true;

  // If it is a non constant variable, it needs to be uniqued across shared
  // objects.
  if (auto *Var = dyn_cast<GlobalVariable>(this))
    if (!Var->isConstant())
      return false;

  return hasAtLeastLocalUnnamedAddr();
}

//===----------------------------------------------------------------------===//
// GlobalVariable Implementation
//===----------------------------------------------------------------------===//

GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
                               Constant *InitVal, const Twine &Name,
                               ThreadLocalMode TLMode, unsigned AddressSpace,
                               bool isExternallyInitialized)
    : GlobalObject(Ty, Value::GlobalVariableVal, AllocMarker, Link, Name,
                   AddressSpace),
      isConstantGlobal(constant),
      isExternallyInitializedConstant(isExternallyInitialized) {
  assert(!Ty->isFunctionTy() && PointerType::isValidElementType(Ty) &&
         "invalid type for global variable");
  setThreadLocalMode(TLMode);
  if (InitVal) {
    assert(InitVal->getType() == Ty &&
           "Initializer should be the same type as the GlobalVariable!");
    Op<0>() = InitVal;
  } else {
    setGlobalVariableNumOperands(0);
  }
}

GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
                               LinkageTypes Link, Constant *InitVal,
                               const Twine &Name, GlobalVariable *Before,
                               ThreadLocalMode TLMode,
                               std::optional<unsigned> AddressSpace,
                               bool isExternallyInitialized)
    : GlobalVariable(Ty, constant, Link, InitVal, Name, TLMode,
                     AddressSpace
                         ? *AddressSpace
                         : M.getDataLayout().getDefaultGlobalsAddressSpace(),
                     isExternallyInitialized) {
  if (Before)
    Before->getParent()->insertGlobalVariable(Before->getIterator(), this);
  else
    M.insertGlobalVariable(this);
}

void GlobalVariable::removeFromParent() {
  getParent()->removeGlobalVariable(this);
}

void GlobalVariable::eraseFromParent() {
  getParent()->eraseGlobalVariable(this);
}

void GlobalVariable::setInitializer(Constant *InitVal) {
  if (!InitVal) {
    if (hasInitializer()) {
      // Note, the num operands is used to compute the offset of the operand, so
      // the order here matters.  Clearing the operand then clearing the num
      // operands ensures we have the correct offset to the operand.
      Op<0>().set(nullptr);
      setGlobalVariableNumOperands(0);
    }
  } else {
    assert(InitVal->getType() == getValueType() &&
           "Initializer type must match GlobalVariable type");
    // Note, the num operands is used to compute the offset of the operand, so
    // the order here matters.  We need to set num operands to 1 first so that
    // we get the correct offset to the first operand when we set it.
    if (!hasInitializer())
      setGlobalVariableNumOperands(1);
    Op<0>().set(InitVal);
  }
}

void GlobalVariable::replaceInitializer(Constant *InitVal) {
  assert(InitVal && "Can't compute type of null initializer");
  ValueType = InitVal->getType();
  setInitializer(InitVal);
}

/// Copy all additional attributes (those not needed to create a GlobalVariable)
/// from the GlobalVariable Src to this one.
void GlobalVariable::copyAttributesFrom(const GlobalVariable *Src) {
  GlobalObject::copyAttributesFrom(Src);
  setExternallyInitialized(Src->isExternallyInitialized());
  setAttributes(Src->getAttributes());
  if (auto CM = Src->getCodeModel())
    setCodeModel(*CM);
}

void GlobalVariable::dropAllReferences() {
  User::dropAllReferences();
  clearMetadata();
}

void GlobalVariable::setCodeModel(CodeModel::Model CM) {
  unsigned CodeModelData = static_cast<unsigned>(CM) + 1;
  unsigned OldData = getGlobalValueSubClassData();
  unsigned NewData = (OldData & ~(CodeModelMask << CodeModelShift)) |
                     (CodeModelData << CodeModelShift);
  setGlobalValueSubClassData(NewData);
  assert(getCodeModel() == CM && "Code model representation error!");
}

void GlobalVariable::clearCodeModel() {
  unsigned CodeModelData = 0;
  unsigned OldData = getGlobalValueSubClassData();
  unsigned NewData = (OldData & ~(CodeModelMask << CodeModelShift)) |
                     (CodeModelData << CodeModelShift);
  setGlobalValueSubClassData(NewData);
  assert(getCodeModel() == std::nullopt && "Code model representation error!");
}

//===----------------------------------------------------------------------===//
// GlobalAlias Implementation
//===----------------------------------------------------------------------===//

GlobalAlias::GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Link,
                         const Twine &Name, Constant *Aliasee,
                         Module *ParentModule)
    : GlobalValue(Ty, Value::GlobalAliasVal, AllocMarker, Link, Name,
                  AddressSpace) {
  setAliasee(Aliasee);
  if (ParentModule)
    ParentModule->insertAlias(this);
}

GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace,
                                 LinkageTypes Link, const Twine &Name,
                                 Constant *Aliasee, Module *ParentModule) {
  return new GlobalAlias(Ty, AddressSpace, Link, Name, Aliasee, ParentModule);
}

GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace,
                                 LinkageTypes Linkage, const Twine &Name,
                                 Module *Parent) {
  return create(Ty, AddressSpace, Linkage, Name, nullptr, Parent);
}

GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace,
                                 LinkageTypes Linkage, const Twine &Name,
                                 GlobalValue *Aliasee) {
  return create(Ty, AddressSpace, Linkage, Name, Aliasee, Aliasee->getParent());
}

GlobalAlias *GlobalAlias::create(LinkageTypes Link, const Twine &Name,
                                 GlobalValue *Aliasee) {
  return create(Aliasee->getValueType(), Aliasee->getAddressSpace(), Link, Name,
                Aliasee);
}

GlobalAlias *GlobalAlias::create(const Twine &Name, GlobalValue *Aliasee) {
  return create(Aliasee->getLinkage(), Name, Aliasee);
}

void GlobalAlias::removeFromParent() { getParent()->removeAlias(this); }

void GlobalAlias::eraseFromParent() { getParent()->eraseAlias(this); }

void GlobalAlias::setAliasee(Constant *Aliasee) {
  assert((!Aliasee || Aliasee->getType() == getType()) &&
         "Alias and aliasee types should match!");
  Op<0>().set(Aliasee);
}

const GlobalObject *GlobalAlias::getAliaseeObject() const {
  DenseSet<const GlobalAlias *> Aliases;
  return findBaseObject(getOperand(0), Aliases, [](const GlobalValue &) {});
}

//===----------------------------------------------------------------------===//
// GlobalIFunc Implementation
//===----------------------------------------------------------------------===//

GlobalIFunc::GlobalIFunc(Type *Ty, unsigned AddressSpace, LinkageTypes Link,
                         const Twine &Name, Constant *Resolver,
                         Module *ParentModule)
    : GlobalObject(Ty, Value::GlobalIFuncVal, AllocMarker, Link, Name,
                   AddressSpace) {
  setResolver(Resolver);
  if (ParentModule)
    ParentModule->insertIFunc(this);
}

GlobalIFunc *GlobalIFunc::create(Type *Ty, unsigned AddressSpace,
                                 LinkageTypes Link, const Twine &Name,
                                 Constant *Resolver, Module *ParentModule) {
  return new GlobalIFunc(Ty, AddressSpace, Link, Name, Resolver, ParentModule);
}

void GlobalIFunc::removeFromParent() { getParent()->removeIFunc(this); }

void GlobalIFunc::eraseFromParent() { getParent()->eraseIFunc(this); }

const Function *GlobalIFunc::getResolverFunction() const {
  return dyn_cast<Function>(getResolver()->stripPointerCastsAndAliases());
}

void GlobalIFunc::applyAlongResolverPath(
    function_ref<void(const GlobalValue &)> Op) const {
  DenseSet<const GlobalAlias *> Aliases;
  findBaseObject(getResolver(), Aliases, Op);
}
