//===- RecordsSlice.cpp --------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Implements the Records Slice APIs.
//
//===----------------------------------------------------------------------===//

#include "llvm/TextAPI/RecordsSlice.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/TextAPI/InterfaceFile.h"
#include "llvm/TextAPI/Record.h"
#include "llvm/TextAPI/Symbol.h"
#include <utility>

using namespace llvm;
using namespace llvm::MachO;

Record *RecordsSlice::addRecord(StringRef Name, SymbolFlags Flags,
                                GlobalRecord::Kind GV, RecordLinkage Linkage) {
  // Find a specific Record type to capture.
  auto [APIName, SymKind, InterfaceType] = parseSymbol(Name);
  Name = APIName;
  switch (SymKind) {
  case EncodeKind::GlobalSymbol:
    return addGlobal(Name, Linkage, GV, Flags);
  case EncodeKind::ObjectiveCClass:
    return addObjCInterface(Name, Linkage, InterfaceType);
  case EncodeKind::ObjectiveCClassEHType: {
    ObjCInterfaceRecord *Rec = addObjCInterface(Name, Linkage, InterfaceType);
    // When classes without ehtype are used in try/catch blocks
    // a weak-defined symbol is exported.
    if ((Flags & SymbolFlags::WeakDefined) == SymbolFlags::WeakDefined)
      updateFlags(Rec, SymbolFlags::WeakDefined);
    return Rec;
  }
  case EncodeKind::ObjectiveCInstanceVariable: {
    auto [Super, IVar] = Name.split('.');
    // Attempt to find super class.
    ObjCContainerRecord *Container = findContainer(/*isIVar=*/false, Super);
    // If not found, create extension since there is no mapped class symbol.
    if (Container == nullptr)
      Container = addObjCCategory(Super, {});
    return addObjCIVar(Container, IVar, Linkage);
  }
  }

  llvm_unreachable("unexpected symbol kind when adding to Record Slice");
}

ObjCContainerRecord *RecordsSlice::findContainer(bool IsIVar,
                                                 StringRef Name) const {
  StringRef Super = IsIVar ? Name.split('.').first : Name;
  ObjCContainerRecord *Container = findObjCInterface(Super);
  // Ivars can only exist with extensions, if they did not come from
  // class.
  if (Container == nullptr)
    Container = findObjCCategory(Super, "");
  return Container;
}

template <typename R, typename C = RecordMap<R>, typename K = StringRef>
R *findRecord(K Key, const C &Container) {
  const auto *Record = Container.find(Key);
  if (Record == Container.end())
    return nullptr;
  return Record->second.get();
}

GlobalRecord *RecordsSlice::findGlobal(StringRef Name,
                                       GlobalRecord::Kind GV) const {
  auto *Record = findRecord<GlobalRecord>(Name, Globals);
  if (!Record)
    return nullptr;

  switch (GV) {
  case GlobalRecord::Kind::Variable: {
    if (!Record->isVariable())
      return nullptr;
    break;
  }
  case GlobalRecord::Kind::Function: {
    if (!Record->isFunction())
      return nullptr;
    break;
  }
  case GlobalRecord::Kind::Unknown:
    return Record;
  }

  return Record;
}

RecordLinkage
ObjCInterfaceRecord::getLinkageForSymbol(ObjCIFSymbolKind CurrType) const {
  assert(CurrType <= ObjCIFSymbolKind::EHType &&
         "expected single ObjCIFSymbolKind enum value");
  if (CurrType == ObjCIFSymbolKind::Class)
    return Linkages.Class;

  if (CurrType == ObjCIFSymbolKind::MetaClass)
    return Linkages.MetaClass;

  if (CurrType == ObjCIFSymbolKind::EHType)
    return Linkages.EHType;

  llvm_unreachable("unexpected ObjCIFSymbolKind");
}

void ObjCInterfaceRecord::updateLinkageForSymbols(ObjCIFSymbolKind SymType,
                                                  RecordLinkage Link) {
  if ((SymType & ObjCIFSymbolKind::Class) == ObjCIFSymbolKind::Class)
    Linkages.Class = std::max(Link, Linkages.Class);
  if ((SymType & ObjCIFSymbolKind::MetaClass) == ObjCIFSymbolKind::MetaClass)
    Linkages.MetaClass = std::max(Link, Linkages.MetaClass);
  if ((SymType & ObjCIFSymbolKind::EHType) == ObjCIFSymbolKind::EHType)
    Linkages.EHType = std::max(Link, Linkages.EHType);

  // Obj-C Classes represent multiple symbols that could have competing
  // linkages, in this case assign the largest one, when querying the linkage of
  // the record itself. This allows visitors pick whether they want to account
  // for complete symbol information.
  Linkage = std::max({Linkages.Class, Linkages.MetaClass, Linkages.EHType});
}

ObjCInterfaceRecord *RecordsSlice::findObjCInterface(StringRef Name) const {
  return findRecord<ObjCInterfaceRecord>(Name, Classes);
}

ObjCCategoryRecord *RecordsSlice::findObjCCategory(StringRef ClassToExtend,
                                                   StringRef Category) const {
  return findRecord<ObjCCategoryRecord>(std::make_pair(ClassToExtend, Category),
                                        Categories);
}

ObjCIVarRecord *ObjCContainerRecord::findObjCIVar(StringRef IVar) const {
  return findRecord<ObjCIVarRecord>(IVar, IVars);
}

ObjCIVarRecord *RecordsSlice::findObjCIVar(bool IsScopedName,
                                           StringRef Name) const {
  // If scoped name, the name of the container is known.
  if (IsScopedName) {
    // IVar does not exist if there is not a container assigned to it.
    auto *Container = findContainer(/*IsIVar=*/true, Name);
    if (!Container)
      return nullptr;

    StringRef IVar = Name.substr(Name.find_first_of('.') + 1);
    return Container->findObjCIVar(IVar);
  }

  // Otherwise traverse through containers and attempt to find IVar.
  auto getIVar = [Name](auto &Records) -> ObjCIVarRecord * {
    for (const auto &[_, Container] : Records) {
      if (auto *IVarR = Container->findObjCIVar(Name))
        return IVarR;
    }
    return nullptr;
  };

  if (auto *IVarRecord = getIVar(Classes))
    return IVarRecord;

  return getIVar(Categories);
}

GlobalRecord *RecordsSlice::addGlobal(StringRef Name, RecordLinkage Linkage,
                                      GlobalRecord::Kind GV, SymbolFlags Flags,
                                      bool Inlined) {
  if (GV == GlobalRecord::Kind::Function)
    Flags |= SymbolFlags::Text;
  else if (GV == GlobalRecord::Kind::Variable)
    Flags |= SymbolFlags::Data;

  Name = copyString(Name);
  auto Result = Globals.try_emplace(Name);
  if (Result.second)
    Result.first->second =
        std::make_unique<GlobalRecord>(Name, Linkage, Flags, GV, Inlined);
  else {
    updateLinkage(Result.first->second.get(), Linkage);
    updateFlags(Result.first->second.get(), Flags);
  }
  return Result.first->second.get();
}

ObjCInterfaceRecord *RecordsSlice::addObjCInterface(StringRef Name,
                                                    RecordLinkage Linkage,
                                                    ObjCIFSymbolKind SymType) {
  Name = copyString(Name);
  auto Result = Classes.try_emplace(Name);
  if (Result.second)
    Result.first->second =
        std::make_unique<ObjCInterfaceRecord>(Name, Linkage, SymType);
  else
    Result.first->second->updateLinkageForSymbols(SymType, Linkage);
  return Result.first->second.get();
}

SymbolFlags Record::mergeFlags(SymbolFlags Flags, RecordLinkage Linkage) {
  // Add Linkage properties into Flags.
  switch (Linkage) {
  case RecordLinkage::Rexported:
    Flags |= SymbolFlags::Rexported;
    return Flags;
  case RecordLinkage::Undefined:
    Flags |= SymbolFlags::Undefined;
    return Flags;
  default:
    return Flags;
  }
}

bool ObjCInterfaceRecord::addObjCCategory(ObjCCategoryRecord *Record) {
  auto Result = Categories.insert({Name, Record});
  return Result.second;
}

ObjCCategoryRecord *RecordsSlice::addObjCCategory(StringRef ClassToExtend,
                                                  StringRef Category) {
  Category = copyString(Category);
  ClassToExtend = copyString(ClassToExtend);

  // Add owning record first into record slice.
  auto Result = Categories.try_emplace(std::make_pair(ClassToExtend, Category));
  if (Result.second)
    Result.first->second =
        std::make_unique<ObjCCategoryRecord>(ClassToExtend, Category);

  // Then add reference to it in in the class.
  if (auto *ObjCClass = findObjCInterface(ClassToExtend))
    ObjCClass->addObjCCategory(Result.first->second.get());

  return Result.first->second.get();
}

std::vector<ObjCIVarRecord *> ObjCContainerRecord::getObjCIVars() const {
  std::vector<ObjCIVarRecord *> Records;
  Records.reserve(IVars.size());
  for (const auto &Record : IVars)
    Records.push_back(Record.second.get());
  return Records;
}

std::vector<ObjCCategoryRecord *>
ObjCInterfaceRecord::getObjCCategories() const {
  std::vector<ObjCCategoryRecord *> Records;
  Records.reserve(Categories.size());
  for (const auto &Record : Categories)
    Records.push_back(Record.second);
  return Records;
}

ObjCIVarRecord *ObjCContainerRecord::addObjCIVar(StringRef IVar,
                                                 RecordLinkage Linkage) {
  auto Result = IVars.try_emplace(IVar);
  if (Result.second)
    Result.first->second = std::make_unique<ObjCIVarRecord>(IVar, Linkage);
  return Result.first->second.get();
}

ObjCIVarRecord *RecordsSlice::addObjCIVar(ObjCContainerRecord *Container,
                                          StringRef Name,
                                          RecordLinkage Linkage) {
  Name = copyString(Name);
  ObjCIVarRecord *Record = Container->addObjCIVar(Name, Linkage);
  updateLinkage(Record, Linkage);
  return Record;
}

StringRef RecordsSlice::copyString(StringRef String) {
  if (String.empty())
    return {};

  if (StringAllocator.identifyObject(String.data()))
    return String;

  void *Ptr = StringAllocator.Allocate(String.size(), 1);
  memcpy(Ptr, String.data(), String.size());
  return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
}

RecordsSlice::BinaryAttrs &RecordsSlice::getBinaryAttrs() {
  if (!hasBinaryAttrs())
    BA = std::make_unique<BinaryAttrs>();
  return *BA;
}

void RecordsSlice::visit(RecordVisitor &V) const {
  for (auto &G : Globals)
    V.visitGlobal(*G.second);
  for (auto &C : Classes)
    V.visitObjCInterface(*C.second);
  for (auto &Cat : Categories)
    V.visitObjCCategory(*Cat.second);
}

static std::unique_ptr<InterfaceFile>
createInterfaceFile(const Records &Slices, StringRef InstallName) {
  // Pickup symbols first.
  auto Symbols = std::make_unique<SymbolSet>();
  for (auto &S : Slices) {
    if (S->empty())
      continue;
    auto &BA = S->getBinaryAttrs();
    if (BA.InstallName != InstallName)
      continue;

    SymbolConverter Converter(Symbols.get(), S->getTarget(),
                              !BA.TwoLevelNamespace);
    S->visit(Converter);
  }

  auto File = std::make_unique<InterfaceFile>(std::move(Symbols));
  File->setInstallName(InstallName);
  // Assign other attributes.
  for (auto &S : Slices) {
    if (S->empty())
      continue;
    auto &BA = S->getBinaryAttrs();
    if (BA.InstallName != InstallName)
      continue;
    const Target &Targ = S->getTarget();
    File->addTarget(Targ);
    File->setFromBinaryAttrs(BA, Targ);
  }

  return File;
}

std::unique_ptr<InterfaceFile>
llvm::MachO::convertToInterfaceFile(const Records &Slices) {
  std::unique_ptr<InterfaceFile> File;
  if (Slices.empty())
    return File;

  SetVector<StringRef> InstallNames;
  for (auto &S : Slices) {
    auto Name = S->getBinaryAttrs().InstallName;
    if (Name.empty())
      continue;
    InstallNames.insert(Name);
  }

  File = createInterfaceFile(Slices, *InstallNames.begin());
  for (StringRef IN : llvm::drop_begin(InstallNames))
    File->addDocument(createInterfaceFile(Slices, IN));

  return File;
}
