//===- 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, std::max(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.insert({Name, nullptr});
  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.insert({Name, nullptr});
  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.insert({std::make_pair(ClassToExtend, Category), nullptr});
  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.insert({IVar, nullptr});
  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;
}
