//===- ExtractAPI/API.h -----------------------------------------*- 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 the APIRecord-based structs and the APISet class.
///
/// Clang ExtractAPI is a tool to collect API information from a given set of
/// header files. The structures in this file describe data representations of
/// the API information collected for various kinds of symbols.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_EXTRACTAPI_API_H
#define LLVM_CLANG_EXTRACTAPI_API_H

#include "clang/AST/Availability.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/RawCommentList.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/ExtractAPI/DeclarationFragments.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
#include <cstddef>
#include <iterator>
#include <memory>
#include <optional>
#include <type_traits>

namespace clang {
namespace extractapi {

class Template {
  struct TemplateParameter {
    // "class", "typename", or concept name
    std::string Type;
    std::string Name;
    unsigned int Index;
    unsigned int Depth;
    bool IsParameterPack;

    TemplateParameter(std::string Type, std::string Name, unsigned int Index,
                      unsigned int Depth, bool IsParameterPack)
        : Type(Type), Name(Name), Index(Index), Depth(Depth),
          IsParameterPack(IsParameterPack) {}
  };

  struct TemplateConstraint {
    // type name of the constraint, if it has one
    std::string Type;
    std::string Kind;
    std::string LHS, RHS;
  };
  llvm::SmallVector<TemplateParameter> Parameters;
  llvm::SmallVector<TemplateConstraint> Constraints;

public:
  Template() = default;

  Template(const TemplateDecl *Decl) {
    for (auto *const Parameter : *Decl->getTemplateParameters()) {
      const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
      if (!Param) // some params are null
        continue;
      std::string Type;
      if (Param->hasTypeConstraint())
        Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
      else if (Param->wasDeclaredWithTypename())
        Type = "typename";
      else
        Type = "class";

      addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
                           Param->getDepth(), Param->isParameterPack());
    }
  }

  Template(const ClassTemplatePartialSpecializationDecl *Decl) {
    for (auto *const Parameter : *Decl->getTemplateParameters()) {
      const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
      if (!Param) // some params are null
        continue;
      std::string Type;
      if (Param->hasTypeConstraint())
        Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
      else if (Param->wasDeclaredWithTypename())
        Type = "typename";
      else
        Type = "class";

      addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
                           Param->getDepth(), Param->isParameterPack());
    }
  }

  Template(const VarTemplatePartialSpecializationDecl *Decl) {
    for (auto *const Parameter : *Decl->getTemplateParameters()) {
      const auto *Param = dyn_cast<TemplateTypeParmDecl>(Parameter);
      if (!Param) // some params are null
        continue;
      std::string Type;
      if (Param->hasTypeConstraint())
        Type = Param->getTypeConstraint()->getNamedConcept()->getName().str();
      else if (Param->wasDeclaredWithTypename())
        Type = "typename";
      else
        Type = "class";

      addTemplateParameter(Type, Param->getName().str(), Param->getIndex(),
                           Param->getDepth(), Param->isParameterPack());
    }
  }

  const llvm::SmallVector<TemplateParameter> &getParameters() const {
    return Parameters;
  }

  const llvm::SmallVector<TemplateConstraint> &getConstraints() const {
    return Constraints;
  }

  void addTemplateParameter(std::string Type, std::string Name,
                            unsigned int Index, unsigned int Depth,
                            bool IsParameterPack) {
    Parameters.emplace_back(Type, Name, Index, Depth, IsParameterPack);
  }

  bool empty() const { return Parameters.empty() && Constraints.empty(); }
};

/// DocComment is a vector of RawComment::CommentLine.
///
/// Each line represents one line of striped documentation comment,
/// with source range information. This simplifies calculating the source
/// location of a character in the doc comment for pointing back to the source
/// file.
/// e.g.
/// \code
///   /// This is a documentation comment
///       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'  First line.
///   ///     with multiple lines.
///       ^~~~~~~~~~~~~~~~~~~~~~~'         Second line.
/// \endcode
using DocComment = std::vector<RawComment::CommentLine>;

struct APIRecord;

// This represents a reference to another symbol that might come from external
/// sources.
struct SymbolReference {
  StringRef Name;
  StringRef USR;

  /// The source project/module/product of the referred symbol.
  StringRef Source;

  // A Pointer to the APIRecord for this reference if known
  const APIRecord *Record = nullptr;

  SymbolReference() = default;
  SymbolReference(StringRef Name, StringRef USR, StringRef Source = "")
      : Name(Name), USR(USR), Source(Source) {}
  SymbolReference(const APIRecord *R);

  /// Determine if this SymbolReference is empty.
  ///
  /// \returns true if and only if all \c Name, \c USR, and \c Source is empty.
  bool empty() const { return Name.empty() && USR.empty() && Source.empty(); }
};

class RecordContext;

// Concrete classes deriving from APIRecord need to have a construct with first
// arguments USR, and Name, in that order. This is so that they
// are compatible with `APISet::createRecord`.
// When adding a new kind of record don't forget to update APIRecords.inc!
/// The base representation of an API record. Holds common symbol information.
struct APIRecord {
  /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
  enum RecordKind {
    RK_Unknown,
    // If adding a record context record kind here make sure to update
    // RecordContext::classof if needed and add a RECORD_CONTEXT entry to
    // APIRecords.inc
    RK_FirstRecordContext,
    RK_Namespace,
    RK_Enum,
    RK_Struct,
    RK_Union,
    RK_ObjCInterface,
    RK_ObjCCategory,
    RK_ObjCProtocol,
    RK_CXXClass,
    RK_ClassTemplate,
    RK_ClassTemplateSpecialization,
    RK_ClassTemplatePartialSpecialization,
    RK_StructField,
    RK_UnionField,
    RK_CXXField,
    RK_StaticField,
    RK_CXXFieldTemplate,
    RK_GlobalVariable,
    RK_GlobalVariableTemplate,
    RK_GlobalVariableTemplateSpecialization,
    RK_GlobalVariableTemplatePartialSpecialization,
    RK_LastRecordContext,
    RK_GlobalFunction,
    RK_GlobalFunctionTemplate,
    RK_GlobalFunctionTemplateSpecialization,
    RK_EnumConstant,
    RK_Concept,
    RK_CXXStaticMethod,
    RK_CXXInstanceMethod,
    RK_CXXConstructorMethod,
    RK_CXXDestructorMethod,
    RK_CXXMethodTemplate,
    RK_CXXMethodTemplateSpecialization,
    RK_ObjCInstanceProperty,
    RK_ObjCClassProperty,
    RK_ObjCIvar,
    RK_ObjCClassMethod,
    RK_ObjCInstanceMethod,
    RK_MacroDefinition,
    RK_Typedef,
  };

  StringRef USR;
  StringRef Name;

  SymbolReference Parent;

  PresumedLoc Location;
  AvailabilityInfo Availability;
  LinkageInfo Linkage;

  /// Documentation comment lines attached to this symbol declaration.
  DocComment Comment;

  /// Declaration fragments of this symbol declaration.
  DeclarationFragments Declaration;

  /// SubHeading provides a more detailed representation than the plain
  /// declaration name.
  ///
  /// SubHeading is an array of declaration fragments of tagged declaration
  /// name, with potentially more tokens (for example the \c +/- symbol for
  /// Objective-C class/instance methods).
  DeclarationFragments SubHeading;

  /// Whether the symbol was defined in a system header.
  bool IsFromSystemHeader;

  AccessControl Access;

private:
  const RecordKind Kind;
  friend class RecordContext;
  // Used to store the next child record in RecordContext. This works because
  // APIRecords semantically only have one parent.
  mutable APIRecord *NextInContext = nullptr;

public:
  APIRecord *getNextInContext() const { return NextInContext; }

  RecordKind getKind() const { return Kind; }

  static APIRecord *castFromRecordContext(const RecordContext *Ctx);
  static RecordContext *castToRecordContext(const APIRecord *Record);

  APIRecord() = delete;

  APIRecord(RecordKind Kind, StringRef USR, StringRef Name,
            SymbolReference Parent, PresumedLoc Location,
            AvailabilityInfo Availability, LinkageInfo Linkage,
            const DocComment &Comment, DeclarationFragments Declaration,
            DeclarationFragments SubHeading, bool IsFromSystemHeader,
            AccessControl Access = AccessControl())
      : USR(USR), Name(Name), Parent(std::move(Parent)), Location(Location),
        Availability(std::move(Availability)), Linkage(Linkage),
        Comment(Comment), Declaration(Declaration), SubHeading(SubHeading),
        IsFromSystemHeader(IsFromSystemHeader), Access(std::move(Access)),
        Kind(Kind) {}

  APIRecord(RecordKind Kind, StringRef USR, StringRef Name)
      : USR(USR), Name(Name), Kind(Kind) {}

  // Pure virtual destructor to make APIRecord abstract
  virtual ~APIRecord() = 0;
  static bool classof(const APIRecord *Record) { return true; }
  static bool classofKind(RecordKind K) { return true; }
  static bool classof(const RecordContext *Ctx) { return true; }
};

/// Base class used for specific record types that have children records this is
/// analogous to the DeclContext for the AST
class RecordContext {
public:
  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(APIRecord::RecordKind K) {
    return K > APIRecord::RK_FirstRecordContext &&
           K < APIRecord::RK_LastRecordContext;
  }

  static bool classof(const RecordContext *Context) { return true; }

  RecordContext(APIRecord::RecordKind Kind) : Kind(Kind) {}

  /// Append \p Other children chain into ours and empty out Other's record
  /// chain.
  void stealRecordChain(RecordContext &Other);

  APIRecord::RecordKind getKind() const { return Kind; }

  struct record_iterator {
  private:
    APIRecord *Current = nullptr;

  public:
    using value_type = APIRecord *;
    using reference = const value_type &;
    using pointer = const value_type *;
    using iterator_category = std::forward_iterator_tag;
    using difference_type = std::ptrdiff_t;

    record_iterator() = default;
    explicit record_iterator(value_type R) : Current(R) {}
    reference operator*() const { return Current; }
    // This doesn't strictly meet the iterator requirements, but it's the
    // behavior we want here.
    value_type operator->() const { return Current; }
    record_iterator &operator++() {
      Current = Current->getNextInContext();
      return *this;
    }
    record_iterator operator++(int) {
      record_iterator tmp(*this);
      ++(*this);
      return tmp;
    }

    friend bool operator==(record_iterator x, record_iterator y) {
      return x.Current == y.Current;
    }
    friend bool operator!=(record_iterator x, record_iterator y) {
      return x.Current != y.Current;
    }
  };

  using record_range = llvm::iterator_range<record_iterator>;
  record_range records() const {
    return record_range(records_begin(), records_end());
  }
  record_iterator records_begin() const { return record_iterator(First); };
  record_iterator records_end() const { return record_iterator(); }
  bool records_empty() const { return First == nullptr; };

private:
  APIRecord::RecordKind Kind;
  mutable APIRecord *First = nullptr;
  mutable APIRecord *Last = nullptr;
  bool IsWellFormed() const;

protected:
  friend class APISet;
  void addToRecordChain(APIRecord *) const;
};

struct NamespaceRecord : APIRecord, RecordContext {
  NamespaceRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                  PresumedLoc Loc, AvailabilityInfo Availability,
                  LinkageInfo Linkage, const DocComment &Comment,
                  DeclarationFragments Declaration,
                  DeclarationFragments SubHeading, bool IsFromSystemHeader)
      : APIRecord(RK_Namespace, USR, Name, Parent, Loc, std::move(Availability),
                  Linkage, Comment, Declaration, SubHeading,
                  IsFromSystemHeader),
        RecordContext(RK_Namespace) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_Namespace; }
};

/// This holds information associated with global functions.
struct GlobalFunctionRecord : APIRecord {
  FunctionSignature Signature;

  GlobalFunctionRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                       PresumedLoc Loc, AvailabilityInfo Availability,
                       LinkageInfo Linkage, const DocComment &Comment,
                       DeclarationFragments Declaration,
                       DeclarationFragments SubHeading,
                       FunctionSignature Signature, bool IsFromSystemHeader)
      : APIRecord(RK_GlobalFunction, USR, Name, Parent, Loc,
                  std::move(Availability), Linkage, Comment, Declaration,
                  SubHeading, IsFromSystemHeader),
        Signature(Signature) {}

  GlobalFunctionRecord(RecordKind Kind, StringRef USR, StringRef Name,
                       SymbolReference Parent, PresumedLoc Loc,
                       AvailabilityInfo Availability, LinkageInfo Linkage,
                       const DocComment &Comment,
                       DeclarationFragments Declaration,
                       DeclarationFragments SubHeading,
                       FunctionSignature Signature, bool IsFromSystemHeader)
      : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
                  Linkage, Comment, Declaration, SubHeading,
                  IsFromSystemHeader),
        Signature(Signature) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_GlobalFunction; }

private:
  virtual void anchor();
};

struct GlobalFunctionTemplateRecord : GlobalFunctionRecord {
  Template Templ;

  GlobalFunctionTemplateRecord(StringRef USR, StringRef Name,
                               SymbolReference Parent, PresumedLoc Loc,
                               AvailabilityInfo Availability,
                               LinkageInfo Linkage, const DocComment &Comment,
                               DeclarationFragments Declaration,
                               DeclarationFragments SubHeading,
                               FunctionSignature Signature, Template Template,
                               bool IsFromSystemHeader)
      : GlobalFunctionRecord(RK_GlobalFunctionTemplate, USR, Name, Parent, Loc,
                             std::move(Availability), Linkage, Comment,
                             Declaration, SubHeading, Signature,
                             IsFromSystemHeader),
        Templ(Template) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_GlobalFunctionTemplate;
  }
};

struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord {
  GlobalFunctionTemplateSpecializationRecord(
      StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
      AvailabilityInfo Availability, LinkageInfo Linkage,
      const DocComment &Comment, DeclarationFragments Declaration,
      DeclarationFragments SubHeading, FunctionSignature Signature,
      bool IsFromSystemHeader)
      : GlobalFunctionRecord(RK_GlobalFunctionTemplateSpecialization, USR, Name,
                             Parent, Loc, std::move(Availability), Linkage,
                             Comment, Declaration, SubHeading, Signature,
                             IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_GlobalFunctionTemplateSpecialization;
  }
};

/// This holds information associated with global functions.
struct GlobalVariableRecord : APIRecord, RecordContext {
  GlobalVariableRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                       PresumedLoc Loc, AvailabilityInfo Availability,
                       LinkageInfo Linkage, const DocComment &Comment,
                       DeclarationFragments Declaration,
                       DeclarationFragments SubHeading, bool IsFromSystemHeader)
      : APIRecord(RK_GlobalVariable, USR, Name, Parent, Loc,
                  std::move(Availability), Linkage, Comment, Declaration,
                  SubHeading, IsFromSystemHeader),
        RecordContext(RK_GlobalVariable) {}

  GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name,
                       SymbolReference Parent, PresumedLoc Loc,
                       AvailabilityInfo Availability, LinkageInfo Linkage,
                       const DocComment &Comment,
                       DeclarationFragments Declaration,
                       DeclarationFragments SubHeading, bool IsFromSystemHeader)
      : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
                  Linkage, Comment, Declaration, SubHeading,
                  IsFromSystemHeader),
        RecordContext(Kind) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_GlobalVariable || K == RK_GlobalVariableTemplate ||
           K == RK_GlobalVariableTemplateSpecialization ||
           K == RK_GlobalVariableTemplatePartialSpecialization;
  }

private:
  virtual void anchor();
};

struct GlobalVariableTemplateRecord : GlobalVariableRecord {
  Template Templ;

  GlobalVariableTemplateRecord(StringRef USR, StringRef Name,
                               SymbolReference Parent, PresumedLoc Loc,
                               AvailabilityInfo Availability,
                               LinkageInfo Linkage, const DocComment &Comment,
                               DeclarationFragments Declaration,
                               DeclarationFragments SubHeading,
                               class Template Template, bool IsFromSystemHeader)
      : GlobalVariableRecord(RK_GlobalVariableTemplate, USR, Name, Parent, Loc,
                             std::move(Availability), Linkage, Comment,
                             Declaration, SubHeading, IsFromSystemHeader),
        Templ(Template) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_GlobalVariableTemplate;
  }
};

struct GlobalVariableTemplateSpecializationRecord : GlobalVariableRecord {
  GlobalVariableTemplateSpecializationRecord(
      StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
      AvailabilityInfo Availability, LinkageInfo Linkage,
      const DocComment &Comment, DeclarationFragments Declaration,
      DeclarationFragments SubHeading, bool IsFromSystemHeader)
      : GlobalVariableRecord(RK_GlobalVariableTemplateSpecialization, USR, Name,
                             Parent, Loc, std::move(Availability), Linkage,
                             Comment, Declaration, SubHeading,
                             IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_GlobalVariableTemplateSpecialization;
  }
};

struct GlobalVariableTemplatePartialSpecializationRecord
    : GlobalVariableRecord {
  Template Templ;

  GlobalVariableTemplatePartialSpecializationRecord(
      StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
      AvailabilityInfo Availability, LinkageInfo Linkage,
      const DocComment &Comment, DeclarationFragments Declaration,
      DeclarationFragments SubHeading, class Template Template,
      bool IsFromSystemHeader)
      : GlobalVariableRecord(RK_GlobalVariableTemplatePartialSpecialization,
                             USR, Name, Parent, Loc, std::move(Availability),
                             Linkage, Comment, Declaration, SubHeading,
                             IsFromSystemHeader),
        Templ(Template) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_GlobalVariableTemplatePartialSpecialization;
  }
};

/// This holds information associated with enum constants.
struct EnumConstantRecord : APIRecord {
  EnumConstantRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                     PresumedLoc Loc, AvailabilityInfo Availability,
                     const DocComment &Comment,
                     DeclarationFragments Declaration,
                     DeclarationFragments SubHeading, bool IsFromSystemHeader)
      : APIRecord(RK_EnumConstant, USR, Name, Parent, Loc,
                  std::move(Availability), LinkageInfo::none(), Comment,
                  Declaration, SubHeading, IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_EnumConstant; }

private:
  virtual void anchor();
};

struct TagRecord : APIRecord, RecordContext {
  TagRecord(RecordKind Kind, StringRef USR, StringRef Name,
            SymbolReference Parent, PresumedLoc Loc,
            AvailabilityInfo Availability, const DocComment &Comment,
            DeclarationFragments Declaration, DeclarationFragments SubHeading,
            bool IsFromSystemHeader, bool IsEmbeddedInVarDeclarator,
            AccessControl Access = AccessControl())
      : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
                  LinkageInfo::none(), Comment, Declaration, SubHeading,
                  IsFromSystemHeader, std::move(Access)),
        RecordContext(Kind),
        IsEmbeddedInVarDeclarator(IsEmbeddedInVarDeclarator){};

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_Struct || K == RK_Union || K == RK_Enum;
  }

  bool IsEmbeddedInVarDeclarator;

  virtual ~TagRecord() = 0;
};

/// This holds information associated with enums.
struct EnumRecord : TagRecord {
  EnumRecord(StringRef USR, StringRef Name, SymbolReference Parent,
             PresumedLoc Loc, AvailabilityInfo Availability,
             const DocComment &Comment, DeclarationFragments Declaration,
             DeclarationFragments SubHeading, bool IsFromSystemHeader,
             bool IsEmbeddedInVarDeclarator,
             AccessControl Access = AccessControl())
      : TagRecord(RK_Enum, USR, Name, Parent, Loc, std::move(Availability),
                  Comment, Declaration, SubHeading, IsFromSystemHeader,
                  IsEmbeddedInVarDeclarator, std::move(Access)) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }

  static bool classofKind(RecordKind K) { return K == RK_Enum; }

private:
  virtual void anchor();
};

/// This holds information associated with struct or union fields fields.
struct RecordFieldRecord : APIRecord, RecordContext {
  RecordFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
                    SymbolReference Parent, PresumedLoc Loc,
                    AvailabilityInfo Availability, const DocComment &Comment,
                    DeclarationFragments Declaration,
                    DeclarationFragments SubHeading, bool IsFromSystemHeader)
      : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
                  LinkageInfo::none(), Comment, Declaration, SubHeading,
                  IsFromSystemHeader),
        RecordContext(Kind) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_StructField || K == RK_UnionField;
  }

  virtual ~RecordFieldRecord() = 0;
};

/// This holds information associated with structs and unions.
struct RecordRecord : TagRecord {
  RecordRecord(RecordKind Kind, StringRef USR, StringRef Name,
               SymbolReference Parent, PresumedLoc Loc,
               AvailabilityInfo Availability, const DocComment &Comment,
               DeclarationFragments Declaration,
               DeclarationFragments SubHeading, bool IsFromSystemHeader,
               bool IsEmbeddedInVarDeclarator,
               AccessControl Access = AccessControl())
      : TagRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
                  Comment, Declaration, SubHeading, IsFromSystemHeader,
                  IsEmbeddedInVarDeclarator, std::move(Access)) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_Struct || K == RK_Union;
  }

  bool isAnonymousWithNoTypedef() { return Name.empty(); }

  virtual ~RecordRecord() = 0;
};

struct StructFieldRecord : RecordFieldRecord {
  StructFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                    PresumedLoc Loc, AvailabilityInfo Availability,
                    const DocComment &Comment, DeclarationFragments Declaration,
                    DeclarationFragments SubHeading, bool IsFromSystemHeader)
      : RecordFieldRecord(RK_StructField, USR, Name, Parent, Loc,
                          std::move(Availability), Comment, Declaration,
                          SubHeading, IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_StructField; }

private:
  virtual void anchor();
};

struct StructRecord : RecordRecord {
  StructRecord(StringRef USR, StringRef Name, SymbolReference Parent,
               PresumedLoc Loc, AvailabilityInfo Availability,
               const DocComment &Comment, DeclarationFragments Declaration,
               DeclarationFragments SubHeading, bool IsFromSystemHeader,
               bool IsEmbeddedInVarDeclarator)
      : RecordRecord(RK_Struct, USR, Name, Parent, Loc, std::move(Availability),
                     Comment, Declaration, SubHeading, IsFromSystemHeader,
                     IsEmbeddedInVarDeclarator) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_Struct; }

private:
  virtual void anchor();
};

struct UnionFieldRecord : RecordFieldRecord {
  UnionFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                   PresumedLoc Loc, AvailabilityInfo Availability,
                   const DocComment &Comment, DeclarationFragments Declaration,
                   DeclarationFragments SubHeading, bool IsFromSystemHeader)
      : RecordFieldRecord(RK_UnionField, USR, Name, Parent, Loc,
                          std::move(Availability), Comment, Declaration,
                          SubHeading, IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_UnionField; }

private:
  virtual void anchor();
};

struct UnionRecord : RecordRecord {
  UnionRecord(StringRef USR, StringRef Name, SymbolReference Parent,
              PresumedLoc Loc, AvailabilityInfo Availability,
              const DocComment &Comment, DeclarationFragments Declaration,
              DeclarationFragments SubHeading, bool IsFromSystemHeader,
              bool IsEmbeddedInVarDeclarator)
      : RecordRecord(RK_Union, USR, Name, Parent, Loc, std::move(Availability),
                     Comment, Declaration, SubHeading, IsFromSystemHeader,
                     IsEmbeddedInVarDeclarator) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_Union; }

private:
  virtual void anchor();
};

struct CXXFieldRecord : APIRecord, RecordContext {
  CXXFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                 PresumedLoc Loc, AvailabilityInfo Availability,
                 const DocComment &Comment, DeclarationFragments Declaration,
                 DeclarationFragments SubHeading, AccessControl Access,
                 bool IsFromSystemHeader)
      : APIRecord(RK_CXXField, USR, Name, Parent, Loc, std::move(Availability),
                  LinkageInfo::none(), Comment, Declaration, SubHeading,
                  IsFromSystemHeader, std::move(Access)),
        RecordContext(RK_CXXField) {}

  CXXFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
                 SymbolReference Parent, PresumedLoc Loc,
                 AvailabilityInfo Availability, const DocComment &Comment,
                 DeclarationFragments Declaration,
                 DeclarationFragments SubHeading, AccessControl Access,
                 bool IsFromSystemHeader)
      : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
                  LinkageInfo::none(), Comment, Declaration, SubHeading,
                  IsFromSystemHeader, std::move(Access)),
        RecordContext(Kind) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_CXXField || K == RK_CXXFieldTemplate || K == RK_StaticField;
  }

private:
  virtual void anchor();
};

struct CXXFieldTemplateRecord : CXXFieldRecord {
  Template Templ;

  CXXFieldTemplateRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                         PresumedLoc Loc, AvailabilityInfo Availability,
                         const DocComment &Comment,
                         DeclarationFragments Declaration,
                         DeclarationFragments SubHeading, AccessControl Access,
                         Template Template, bool IsFromSystemHeader)
      : CXXFieldRecord(RK_CXXFieldTemplate, USR, Name, Parent, Loc,
                       std::move(Availability), Comment, Declaration,
                       SubHeading, std::move(Access), IsFromSystemHeader),
        Templ(Template) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_CXXFieldTemplate; }
};

struct CXXMethodRecord : APIRecord {
  FunctionSignature Signature;

  CXXMethodRecord() = delete;

  CXXMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
                  SymbolReference Parent, PresumedLoc Loc,
                  AvailabilityInfo Availability, const DocComment &Comment,
                  DeclarationFragments Declaration,
                  DeclarationFragments SubHeading, FunctionSignature Signature,
                  AccessControl Access, bool IsFromSystemHeader)
      : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
                  LinkageInfo::none(), Comment, Declaration, SubHeading,
                  IsFromSystemHeader, std::move(Access)),
        Signature(Signature) {}

  virtual ~CXXMethodRecord() = 0;
};

struct CXXConstructorRecord : CXXMethodRecord {
  CXXConstructorRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                       PresumedLoc Loc, AvailabilityInfo Availability,
                       const DocComment &Comment,
                       DeclarationFragments Declaration,
                       DeclarationFragments SubHeading,
                       FunctionSignature Signature, AccessControl Access,
                       bool IsFromSystemHeader)
      : CXXMethodRecord(RK_CXXConstructorMethod, USR, Name, Parent, Loc,
                        std::move(Availability), Comment, Declaration,
                        SubHeading, Signature, std::move(Access),
                        IsFromSystemHeader) {}
  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_CXXConstructorMethod; }

private:
  virtual void anchor();
};

struct CXXDestructorRecord : CXXMethodRecord {
  CXXDestructorRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                      PresumedLoc Loc, AvailabilityInfo Availability,
                      const DocComment &Comment,
                      DeclarationFragments Declaration,
                      DeclarationFragments SubHeading,
                      FunctionSignature Signature, AccessControl Access,
                      bool IsFromSystemHeader)
      : CXXMethodRecord(RK_CXXDestructorMethod, USR, Name, Parent, Loc,
                        std::move(Availability), Comment, Declaration,
                        SubHeading, Signature, std::move(Access),
                        IsFromSystemHeader) {}
  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_CXXDestructorMethod; }

private:
  virtual void anchor();
};

struct CXXStaticMethodRecord : CXXMethodRecord {
  CXXStaticMethodRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                        PresumedLoc Loc, AvailabilityInfo Availability,
                        const DocComment &Comment,
                        DeclarationFragments Declaration,
                        DeclarationFragments SubHeading,
                        FunctionSignature Signature, AccessControl Access,
                        bool IsFromSystemHeader)
      : CXXMethodRecord(RK_CXXStaticMethod, USR, Name, Parent, Loc,
                        std::move(Availability), Comment, Declaration,
                        SubHeading, Signature, std::move(Access),
                        IsFromSystemHeader) {}
  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_CXXStaticMethod; }

private:
  virtual void anchor();
};

struct CXXInstanceMethodRecord : CXXMethodRecord {
  CXXInstanceMethodRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                          PresumedLoc Loc, AvailabilityInfo Availability,
                          const DocComment &Comment,
                          DeclarationFragments Declaration,
                          DeclarationFragments SubHeading,
                          FunctionSignature Signature, AccessControl Access,
                          bool IsFromSystemHeader)
      : CXXMethodRecord(RK_CXXInstanceMethod, USR, Name, Parent, Loc,
                        std::move(Availability), Comment, Declaration,
                        SubHeading, Signature, std::move(Access),
                        IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_CXXInstanceMethod; }

private:
  virtual void anchor();
};

struct CXXMethodTemplateRecord : CXXMethodRecord {
  Template Templ;

  CXXMethodTemplateRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                          PresumedLoc Loc, AvailabilityInfo Availability,
                          const DocComment &Comment,
                          DeclarationFragments Declaration,
                          DeclarationFragments SubHeading,
                          FunctionSignature Signature, AccessControl Access,
                          Template Template, bool IsFromSystemHeader)
      : CXXMethodRecord(RK_CXXMethodTemplate, USR, Name, Parent, Loc,
                        std::move(Availability), Comment, Declaration,
                        SubHeading, Signature, std::move(Access),
                        IsFromSystemHeader),
        Templ(Template) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_CXXMethodTemplate; }
};

struct CXXMethodTemplateSpecializationRecord : CXXMethodRecord {
  CXXMethodTemplateSpecializationRecord(
      StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
      AvailabilityInfo Availability, const DocComment &Comment,
      DeclarationFragments Declaration, DeclarationFragments SubHeading,
      FunctionSignature Signature, AccessControl Access,
      bool IsFromSystemHeader)
      : CXXMethodRecord(RK_CXXMethodTemplateSpecialization, USR, Name, Parent,
                        Loc, std::move(Availability), Comment, Declaration,
                        SubHeading, Signature, std::move(Access),
                        IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_CXXMethodTemplateSpecialization;
  }
};

/// This holds information associated with Objective-C properties.
struct ObjCPropertyRecord : APIRecord {
  /// The attributes associated with an Objective-C property.
  enum AttributeKind : unsigned {
    NoAttr = 0,
    ReadOnly = 1,
    Dynamic = 1 << 2,
  };

  AttributeKind Attributes;
  StringRef GetterName;
  StringRef SetterName;
  bool IsOptional;

  ObjCPropertyRecord(RecordKind Kind, StringRef USR, StringRef Name,
                     SymbolReference Parent, PresumedLoc Loc,
                     AvailabilityInfo Availability, const DocComment &Comment,
                     DeclarationFragments Declaration,
                     DeclarationFragments SubHeading, AttributeKind Attributes,
                     StringRef GetterName, StringRef SetterName,
                     bool IsOptional, bool IsFromSystemHeader)
      : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
                  LinkageInfo::none(), Comment, Declaration, SubHeading,
                  IsFromSystemHeader),
        Attributes(Attributes), GetterName(GetterName), SetterName(SetterName),
        IsOptional(IsOptional) {}

  bool isReadOnly() const { return Attributes & ReadOnly; }
  bool isDynamic() const { return Attributes & Dynamic; }

  virtual ~ObjCPropertyRecord() = 0;
};

struct ObjCInstancePropertyRecord : ObjCPropertyRecord {
  ObjCInstancePropertyRecord(
      StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
      AvailabilityInfo Availability, const DocComment &Comment,
      DeclarationFragments Declaration, DeclarationFragments SubHeading,
      AttributeKind Attributes, StringRef GetterName, StringRef SetterName,
      bool IsOptional, bool IsFromSystemHeader)
      : ObjCPropertyRecord(RK_ObjCInstanceProperty, USR, Name, Parent, Loc,
                           std::move(Availability), Comment, Declaration,
                           SubHeading, Attributes, GetterName, SetterName,
                           IsOptional, IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_ObjCInstanceProperty; }

private:
  virtual void anchor();
};

struct ObjCClassPropertyRecord : ObjCPropertyRecord {
  ObjCClassPropertyRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                          PresumedLoc Loc, AvailabilityInfo Availability,
                          const DocComment &Comment,
                          DeclarationFragments Declaration,
                          DeclarationFragments SubHeading,
                          AttributeKind Attributes, StringRef GetterName,
                          StringRef SetterName, bool IsOptional,
                          bool IsFromSystemHeader)
      : ObjCPropertyRecord(RK_ObjCClassProperty, USR, Name, Parent, Loc,
                           std::move(Availability), Comment, Declaration,
                           SubHeading, Attributes, GetterName, SetterName,
                           IsOptional, IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_ObjCClassProperty; }

private:
  virtual void anchor();
};

/// This holds information associated with Objective-C instance variables.
struct ObjCInstanceVariableRecord : APIRecord {
  ObjCInstanceVariableRecord(StringRef USR, StringRef Name,
                             SymbolReference Parent, PresumedLoc Loc,
                             AvailabilityInfo Availability,
                             const DocComment &Comment,
                             DeclarationFragments Declaration,
                             DeclarationFragments SubHeading,
                             bool IsFromSystemHeader)
      : APIRecord(RK_ObjCIvar, USR, Name, Parent, Loc, std::move(Availability),
                  LinkageInfo::none(), Comment, Declaration, SubHeading,
                  IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_ObjCIvar; }

private:
  virtual void anchor();
};

/// This holds information associated with Objective-C methods.
struct ObjCMethodRecord : APIRecord {
  FunctionSignature Signature;

  ObjCMethodRecord() = delete;

  ObjCMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
                   SymbolReference Parent, PresumedLoc Loc,
                   AvailabilityInfo Availability, const DocComment &Comment,
                   DeclarationFragments Declaration,
                   DeclarationFragments SubHeading, FunctionSignature Signature,
                   bool IsFromSystemHeader)
      : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
                  LinkageInfo::none(), Comment, Declaration, SubHeading,
                  IsFromSystemHeader),
        Signature(Signature) {}

  virtual ~ObjCMethodRecord() = 0;
};

struct ObjCInstanceMethodRecord : ObjCMethodRecord {
  ObjCInstanceMethodRecord(StringRef USR, StringRef Name,
                           SymbolReference Parent, PresumedLoc Loc,
                           AvailabilityInfo Availability,
                           const DocComment &Comment,
                           DeclarationFragments Declaration,
                           DeclarationFragments SubHeading,
                           FunctionSignature Signature, bool IsFromSystemHeader)
      : ObjCMethodRecord(RK_ObjCInstanceMethod, USR, Name, Parent, Loc,
                         std::move(Availability), Comment, Declaration,
                         SubHeading, Signature, IsFromSystemHeader) {}
  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_ObjCInstanceMethod; }

private:
  virtual void anchor();
};

struct ObjCClassMethodRecord : ObjCMethodRecord {
  ObjCClassMethodRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                        PresumedLoc Loc, AvailabilityInfo Availability,
                        const DocComment &Comment,
                        DeclarationFragments Declaration,
                        DeclarationFragments SubHeading,
                        FunctionSignature Signature, bool IsFromSystemHeader)
      : ObjCMethodRecord(RK_ObjCClassMethod, USR, Name, Parent, Loc,
                         std::move(Availability), Comment, Declaration,
                         SubHeading, Signature, IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_ObjCClassMethod; }

private:
  virtual void anchor();
};

struct StaticFieldRecord : CXXFieldRecord {
  StaticFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                    PresumedLoc Loc, AvailabilityInfo Availability,
                    LinkageInfo Linkage, const DocComment &Comment,
                    DeclarationFragments Declaration,
                    DeclarationFragments SubHeading, AccessControl Access,
                    bool IsFromSystemHeader)
      : CXXFieldRecord(RK_StaticField, USR, Name, Parent, Loc,
                       std::move(Availability), Comment, Declaration,
                       SubHeading, std::move(Access), IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_StaticField; }
};

/// The base representation of an Objective-C container record. Holds common
/// information associated with Objective-C containers.
struct ObjCContainerRecord : APIRecord, RecordContext {
  SmallVector<SymbolReference> Protocols;

  ObjCContainerRecord() = delete;

  ObjCContainerRecord(RecordKind Kind, StringRef USR, StringRef Name,
                      SymbolReference Parent, PresumedLoc Loc,
                      AvailabilityInfo Availability, LinkageInfo Linkage,
                      const DocComment &Comment,
                      DeclarationFragments Declaration,
                      DeclarationFragments SubHeading, bool IsFromSystemHeader)
      : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
                  Linkage, Comment, Declaration, SubHeading,
                  IsFromSystemHeader),
        RecordContext(Kind) {}

  virtual ~ObjCContainerRecord() = 0;
};

struct CXXClassRecord : RecordRecord {
  SmallVector<SymbolReference> Bases;

  CXXClassRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                 PresumedLoc Loc, AvailabilityInfo Availability,
                 const DocComment &Comment, DeclarationFragments Declaration,
                 DeclarationFragments SubHeading, RecordKind Kind,
                 AccessControl Access, bool IsFromSystemHeader,
                 bool IsEmbeddedInVarDeclarator = false)
      : RecordRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
                     Comment, Declaration, SubHeading, IsFromSystemHeader,
                     IsEmbeddedInVarDeclarator, std::move(Access)) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_CXXClass || K == RK_ClassTemplate ||
           K == RK_ClassTemplateSpecialization ||
           K == RK_ClassTemplatePartialSpecialization;
  }

private:
  virtual void anchor();
};

struct ClassTemplateRecord : CXXClassRecord {
  Template Templ;

  ClassTemplateRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                      PresumedLoc Loc, AvailabilityInfo Availability,
                      const DocComment &Comment,
                      DeclarationFragments Declaration,
                      DeclarationFragments SubHeading, Template Template,
                      AccessControl Access, bool IsFromSystemHeader)
      : CXXClassRecord(USR, Name, Parent, Loc, std::move(Availability), Comment,
                       Declaration, SubHeading, RK_ClassTemplate,
                       std::move(Access), IsFromSystemHeader),
        Templ(Template) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_ClassTemplate; }
};

struct ClassTemplateSpecializationRecord : CXXClassRecord {
  ClassTemplateSpecializationRecord(
      StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
      AvailabilityInfo Availability, const DocComment &Comment,
      DeclarationFragments Declaration, DeclarationFragments SubHeading,
      AccessControl Access, bool IsFromSystemHeader)
      : CXXClassRecord(USR, Name, Parent, Loc, std::move(Availability), Comment,
                       Declaration, SubHeading, RK_ClassTemplateSpecialization,
                       Access, IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_ClassTemplateSpecialization;
  }
};

struct ClassTemplatePartialSpecializationRecord : CXXClassRecord {
  Template Templ;
  ClassTemplatePartialSpecializationRecord(
      StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc,
      AvailabilityInfo Availability, const DocComment &Comment,
      DeclarationFragments Declaration, DeclarationFragments SubHeading,
      Template Template, AccessControl Access, bool IsFromSystemHeader)
      : CXXClassRecord(USR, Name, Parent, Loc, std::move(Availability), Comment,
                       Declaration, SubHeading,
                       RK_ClassTemplatePartialSpecialization, Access,
                       IsFromSystemHeader),
        Templ(Template) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) {
    return K == RK_ClassTemplatePartialSpecialization;
  }
};

struct ConceptRecord : APIRecord {
  Template Templ;

  ConceptRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                PresumedLoc Loc, AvailabilityInfo Availability,
                const DocComment &Comment, DeclarationFragments Declaration,
                DeclarationFragments SubHeading, Template Template,
                bool IsFromSystemHeader)
      : APIRecord(RK_Concept, USR, Name, Parent, Loc, std::move(Availability),
                  LinkageInfo::none(), Comment, Declaration, SubHeading,
                  IsFromSystemHeader),
        Templ(Template) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_Concept; }
};

/// This holds information associated with Objective-C categories.
struct ObjCCategoryRecord : ObjCContainerRecord {
  SymbolReference Interface;

  ObjCCategoryRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                     PresumedLoc Loc, AvailabilityInfo Availability,
                     const DocComment &Comment,
                     DeclarationFragments Declaration,
                     DeclarationFragments SubHeading, SymbolReference Interface,
                     bool IsFromSystemHeader)
      : ObjCContainerRecord(RK_ObjCCategory, USR, Name, Parent, Loc,
                            std::move(Availability), LinkageInfo::none(),
                            Comment, Declaration, SubHeading,
                            IsFromSystemHeader),
        Interface(Interface) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_ObjCCategory; }

  bool isExtendingExternalModule() const { return !Interface.Source.empty(); }

  std::optional<StringRef> getExtendedExternalModule() const {
    if (!isExtendingExternalModule())
      return {};
    return Interface.Source;
  }

private:
  virtual void anchor();
};

/// This holds information associated with Objective-C interfaces/classes.
struct ObjCInterfaceRecord : ObjCContainerRecord {
  SymbolReference SuperClass;

  ObjCInterfaceRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                      PresumedLoc Loc, AvailabilityInfo Availability,
                      LinkageInfo Linkage, const DocComment &Comment,
                      DeclarationFragments Declaration,
                      DeclarationFragments SubHeading,
                      SymbolReference SuperClass, bool IsFromSystemHeader)
      : ObjCContainerRecord(RK_ObjCInterface, USR, Name, Parent, Loc,
                            std::move(Availability), Linkage, Comment,
                            Declaration, SubHeading, IsFromSystemHeader),
        SuperClass(SuperClass) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_ObjCInterface; }

private:
  virtual void anchor();
};

/// This holds information associated with Objective-C protocols.
struct ObjCProtocolRecord : ObjCContainerRecord {
  ObjCProtocolRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                     PresumedLoc Loc, AvailabilityInfo Availability,
                     const DocComment &Comment,
                     DeclarationFragments Declaration,
                     DeclarationFragments SubHeading, bool IsFromSystemHeader)
      : ObjCContainerRecord(RK_ObjCProtocol, USR, Name, Parent, Loc,
                            std::move(Availability), LinkageInfo::none(),
                            Comment, Declaration, SubHeading,
                            IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_ObjCProtocol; }

private:
  virtual void anchor();
};

/// This holds information associated with macro definitions.
struct MacroDefinitionRecord : APIRecord {
  MacroDefinitionRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                        PresumedLoc Loc, DeclarationFragments Declaration,
                        DeclarationFragments SubHeading,
                        bool IsFromSystemHeader)
      : APIRecord(RK_MacroDefinition, USR, Name, Parent, Loc,
                  AvailabilityInfo(), LinkageInfo(), {}, Declaration,
                  SubHeading, IsFromSystemHeader) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_MacroDefinition; }

private:
  virtual void anchor();
};

/// This holds information associated with typedefs.
///
/// Note: Typedefs for anonymous enums and structs typically don't get emitted
/// by the serializers but still get a TypedefRecord. Instead we use the
/// typedef name as a name for the underlying anonymous struct or enum.
struct TypedefRecord : APIRecord {
  SymbolReference UnderlyingType;

  TypedefRecord(StringRef USR, StringRef Name, SymbolReference Parent,
                PresumedLoc Loc, AvailabilityInfo Availability,
                const DocComment &Comment, DeclarationFragments Declaration,
                DeclarationFragments SubHeading, SymbolReference UnderlyingType,
                bool IsFromSystemHeader)
      : APIRecord(RK_Typedef, USR, Name, Parent, Loc, std::move(Availability),
                  LinkageInfo(), Comment, Declaration, SubHeading,
                  IsFromSystemHeader),
        UnderlyingType(UnderlyingType) {}

  static bool classof(const APIRecord *Record) {
    return classofKind(Record->getKind());
  }
  static bool classofKind(RecordKind K) { return K == RK_Typedef; }

private:
  virtual void anchor();
};

/// APISet holds the set of API records collected from given inputs.
class APISet {
public:
  /// Get the target triple for the ExtractAPI invocation.
  const llvm::Triple &getTarget() const { return Target; }

  /// Get the language used by the APIs.
  Language getLanguage() const { return Lang; }

  /// Finds the APIRecord for a given USR.
  ///
  /// \returns a pointer to the APIRecord associated with that USR or nullptr.
  APIRecord *findRecordForUSR(StringRef USR) const;

  /// Copy \p String into the Allocator in this APISet.
  ///
  /// \returns a StringRef of the copied string in APISet::Allocator.
  StringRef copyString(StringRef String);

  SymbolReference createSymbolReference(StringRef Name, StringRef USR,
                                        StringRef Source = "");

  /// Create a subclass of \p APIRecord and store it in the APISet.
  ///
  /// \returns A pointer to the created record or the already existing record
  /// matching this USR.
  template <typename RecordTy, typename... CtorArgsContTy>
  typename std::enable_if_t<std::is_base_of_v<APIRecord, RecordTy>, RecordTy> *
  createRecord(StringRef USR, StringRef Name, CtorArgsContTy &&...CtorArgs);

  ArrayRef<const APIRecord *> getTopLevelRecords() const {
    return TopLevelRecords;
  }

  APISet(const llvm::Triple &Target, Language Lang,
         const std::string &ProductName)
      : Target(Target), Lang(Lang), ProductName(ProductName) {}

  // Prevent moves and copies
  APISet(const APISet &Other) = delete;
  APISet &operator=(const APISet &Other) = delete;
  APISet(APISet &&Other) = delete;
  APISet &operator=(APISet &&Other) = delete;

private:
  /// BumpPtrAllocator that serves as the memory arena for the allocated objects
  llvm::BumpPtrAllocator Allocator;

  const llvm::Triple Target;
  const Language Lang;

  struct APIRecordDeleter {
    void operator()(APIRecord *Record) { Record->~APIRecord(); }
  };

  // Ensure that the destructor of each record is called when the LookupTable is
  // destroyed without calling delete operator as the memory for the record
  // lives in the BumpPtrAllocator.
  using APIRecordStoredPtr = std::unique_ptr<APIRecord, APIRecordDeleter>;
  llvm::DenseMap<StringRef, APIRecordStoredPtr> USRBasedLookupTable;
  std::vector<const APIRecord *> TopLevelRecords;

public:
  const std::string ProductName;
};

template <typename RecordTy, typename... CtorArgsContTy>
typename std::enable_if_t<std::is_base_of_v<APIRecord, RecordTy>, RecordTy> *
APISet::createRecord(StringRef USR, StringRef Name,
                     CtorArgsContTy &&...CtorArgs) {
  // Ensure USR refers to a String stored in the allocator.
  auto USRString = copyString(USR);
  auto Result = USRBasedLookupTable.insert({USRString, nullptr});
  RecordTy *Record;

  // Create the record if it does not already exist
  if (Result.second) {
    Record = new (Allocator) RecordTy(
        USRString, copyString(Name), std::forward<CtorArgsContTy>(CtorArgs)...);
    // Store the record in the record lookup map
    Result.first->second = APIRecordStoredPtr(Record);

    if (auto *ParentContext =
            dyn_cast_if_present<RecordContext>(Record->Parent.Record))
      ParentContext->addToRecordChain(Record);
    else
      TopLevelRecords.push_back(Record);
  } else {
    Record = dyn_cast<RecordTy>(Result.first->second.get());
  }

  return Record;
}

// Helper type for implementing casting to RecordContext pointers.
// Selected when FromTy not a known subclass of RecordContext.
template <typename FromTy,
          bool IsKnownSubType = std::is_base_of_v<RecordContext, FromTy>>
struct ToRecordContextCastInfoWrapper {
  static_assert(std::is_base_of_v<APIRecord, FromTy>,
                "Can only cast APIRecord and derived classes to RecordContext");

  static bool isPossible(FromTy *From) { return RecordContext::classof(From); }

  static RecordContext *doCast(FromTy *From) {
    return APIRecord::castToRecordContext(From);
  }
};

// Selected when FromTy is a known subclass of RecordContext.
template <typename FromTy> struct ToRecordContextCastInfoWrapper<FromTy, true> {
  static_assert(std::is_base_of_v<APIRecord, FromTy>,
                "Can only cast APIRecord and derived classes to RecordContext");
  static bool isPossible(const FromTy *From) { return true; }
  static RecordContext *doCast(FromTy *From) {
    return static_cast<RecordContext *>(From);
  }
};

// Helper type for implementing casting to RecordContext pointers.
// Selected when ToTy isn't a known subclass of RecordContext
template <typename ToTy,
          bool IsKnownSubType = std::is_base_of_v<RecordContext, ToTy>>
struct FromRecordContextCastInfoWrapper {
  static_assert(
      std::is_base_of_v<APIRecord, ToTy>,
      "Can only class RecordContext to APIRecord and derived classes");

  static bool isPossible(RecordContext *Ctx) {
    return ToTy::classofKind(Ctx->getKind());
  }

  static ToTy *doCast(RecordContext *Ctx) {
    return APIRecord::castFromRecordContext(Ctx);
  }
};

// Selected when ToTy is a known subclass of RecordContext.
template <typename ToTy> struct FromRecordContextCastInfoWrapper<ToTy, true> {
  static_assert(
      std::is_base_of_v<APIRecord, ToTy>,
      "Can only class RecordContext to APIRecord and derived classes");
  static bool isPossible(RecordContext *Ctx) {
    return ToTy::classof(Ctx->getKind());
  }
  static RecordContext *doCast(RecordContext *Ctx) {
    return static_cast<ToTy *>(Ctx);
  }
};

} // namespace extractapi
} // namespace clang

// Implement APIRecord (and derived classes) to and from RecordContext
// conversions
namespace llvm {

template <typename FromTy>
struct CastInfo<::clang::extractapi::RecordContext, FromTy *>
    : public NullableValueCastFailed<::clang::extractapi::RecordContext *>,
      public DefaultDoCastIfPossible<
          ::clang::extractapi::RecordContext *, FromTy *,
          CastInfo<::clang::extractapi::RecordContext, FromTy *>> {
  static inline bool isPossible(FromTy *From) {
    return ::clang::extractapi::ToRecordContextCastInfoWrapper<
        FromTy>::isPossible(From);
  }

  static inline ::clang::extractapi::RecordContext *doCast(FromTy *From) {
    return ::clang::extractapi::ToRecordContextCastInfoWrapper<FromTy>::doCast(
        From);
  }
};

template <typename FromTy>
struct CastInfo<::clang::extractapi::RecordContext, const FromTy *>
    : public ConstStrippingForwardingCast<
          ::clang::extractapi::RecordContext, const FromTy *,
          CastInfo<::clang::extractapi::RecordContext, FromTy *>> {};

template <typename ToTy>
struct CastInfo<ToTy, ::clang::extractapi::RecordContext *>
    : public NullableValueCastFailed<ToTy *>,
      public DefaultDoCastIfPossible<
          ToTy *, ::clang::extractapi::RecordContext *,
          CastInfo<ToTy, ::clang::extractapi::RecordContext *>> {
  static inline bool isPossible(::clang::extractapi::RecordContext *Ctx) {
    return ::clang::extractapi::FromRecordContextCastInfoWrapper<
        ToTy>::isPossible(Ctx);
  }

  static inline ToTy *doCast(::clang::extractapi::RecordContext *Ctx) {
    return ::clang::extractapi::FromRecordContextCastInfoWrapper<ToTy>::doCast(
        Ctx);
  }
};

template <typename ToTy>
struct CastInfo<ToTy, const ::clang::extractapi::RecordContext *>
    : public ConstStrippingForwardingCast<
          ToTy, const ::clang::extractapi::RecordContext *,
          CastInfo<ToTy, ::clang::extractapi::RecordContext *>> {};

} // namespace llvm

#endif // LLVM_CLANG_EXTRACTAPI_API_H
