//===- CXXInheritance.h - C++ Inheritance -----------------------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file provides routines that help analyzing C++ inheritance hierarchies.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_CXXINHERITANCE_H
#define LLVM_CLANG_AST_CXXINHERITANCE_H

#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeOrdering.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
#include <list>
#include <memory>
#include <utility>

namespace clang {

class ASTContext;
class NamedDecl;

/// Represents an element in a path from a derived class to a
/// base class.
///
/// Each step in the path references the link from a
/// derived class to one of its direct base classes, along with a
/// base "number" that identifies which base subobject of the
/// original derived class we are referencing.
struct CXXBasePathElement {
  /// The base specifier that states the link from a derived
  /// class to a base class, which will be followed by this base
  /// path element.
  const CXXBaseSpecifier *Base;

  /// The record decl of the class that the base is a base of.
  const CXXRecordDecl *Class;

  /// Identifies which base class subobject (of type
  /// \c Base->getType()) this base path element refers to.
  ///
  /// This value is only valid if \c !Base->isVirtual(), because there
  /// is no base numbering for the zero or one virtual bases of a
  /// given type.
  int SubobjectNumber;
};

/// Represents a path from a specific derived class
/// (which is not represented as part of the path) to a particular
/// (direct or indirect) base class subobject.
///
/// Individual elements in the path are described by the \c CXXBasePathElement
/// structure, which captures both the link from a derived class to one of its
/// direct bases and identification describing which base class
/// subobject is being used.
class CXXBasePath : public SmallVector<CXXBasePathElement, 4> {
public:
  /// The access along this inheritance path.  This is only
  /// calculated when recording paths.  AS_none is a special value
  /// used to indicate a path which permits no legal access.
  AccessSpecifier Access = AS_public;

  CXXBasePath() = default;

  /// The declarations found inside this base class subobject.
  DeclContext::lookup_iterator Decls;

  void clear() {
    SmallVectorImpl<CXXBasePathElement>::clear();
    Access = AS_public;
  }
};

/// BasePaths - Represents the set of paths from a derived class to
/// one of its (direct or indirect) bases. For example, given the
/// following class hierarchy:
///
/// @code
/// class A { };
/// class B : public A { };
/// class C : public A { };
/// class D : public B, public C{ };
/// @endcode
///
/// There are two potential BasePaths to represent paths from D to a
/// base subobject of type A. One path is (D,0) -> (B,0) -> (A,0)
/// and another is (D,0)->(C,0)->(A,1). These two paths actually
/// refer to two different base class subobjects of the same type,
/// so the BasePaths object refers to an ambiguous path. On the
/// other hand, consider the following class hierarchy:
///
/// @code
/// class A { };
/// class B : public virtual A { };
/// class C : public virtual A { };
/// class D : public B, public C{ };
/// @endcode
///
/// Here, there are two potential BasePaths again, (D, 0) -> (B, 0)
/// -> (A,v) and (D, 0) -> (C, 0) -> (A, v), but since both of them
/// refer to the same base class subobject of type A (the virtual
/// one), there is no ambiguity.
class CXXBasePaths {
  friend class CXXRecordDecl;

  /// The type from which this search originated.
  const CXXRecordDecl *Origin = nullptr;

  /// Paths - The actual set of paths that can be taken from the
  /// derived class to the same base class.
  std::list<CXXBasePath> Paths;

  /// ClassSubobjects - Records the class subobjects for each class
  /// type that we've seen. The first element IsVirtBase says
  /// whether we found a path to a virtual base for that class type,
  /// while NumberOfNonVirtBases contains the number of non-virtual base
  /// class subobjects for that class type. The key of the map is
  /// the cv-unqualified canonical type of the base class subobject.
  struct IsVirtBaseAndNumberNonVirtBases {
    unsigned IsVirtBase : 1;
    unsigned NumberOfNonVirtBases : 31;
  };
  llvm::SmallDenseMap<QualType, IsVirtBaseAndNumberNonVirtBases, 8>
      ClassSubobjects;

  /// VisitedDependentRecords - Records the dependent records that have been
  /// already visited.
  llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedDependentRecords;

  /// DetectedVirtual - The base class that is virtual.
  const RecordType *DetectedVirtual = nullptr;

  /// ScratchPath - A BasePath that is used by Sema::lookupInBases
  /// to help build the set of paths.
  CXXBasePath ScratchPath;

  /// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
  /// ambiguous paths while it is looking for a path from a derived
  /// type to a base type.
  bool FindAmbiguities;

  /// RecordPaths - Whether Sema::IsDerivedFrom should record paths
  /// while it is determining whether there are paths from a derived
  /// type to a base type.
  bool RecordPaths;

  /// DetectVirtual - Whether Sema::IsDerivedFrom should abort the search
  /// if it finds a path that goes across a virtual base. The virtual class
  /// is also recorded.
  bool DetectVirtual;

  bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record,
                     CXXRecordDecl::BaseMatchesCallback BaseMatches,
                     bool LookupInDependent = false);

public:
  using paths_iterator = std::list<CXXBasePath>::iterator;
  using const_paths_iterator = std::list<CXXBasePath>::const_iterator;
  using decl_iterator = NamedDecl **;

  /// BasePaths - Construct a new BasePaths structure to record the
  /// paths for a derived-to-base search.
  explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true,
                        bool DetectVirtual = true)
      : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
        DetectVirtual(DetectVirtual) {}

  paths_iterator begin() { return Paths.begin(); }
  paths_iterator end()   { return Paths.end(); }
  const_paths_iterator begin() const { return Paths.begin(); }
  const_paths_iterator end()   const { return Paths.end(); }

  CXXBasePath&       front()       { return Paths.front(); }
  const CXXBasePath& front() const { return Paths.front(); }

  using decl_range = llvm::iterator_range<decl_iterator>;

  /// Determine whether the path from the most-derived type to the
  /// given base type is ambiguous (i.e., it refers to multiple subobjects of
  /// the same base type).
  bool isAmbiguous(CanQualType BaseType);

  /// Whether we are finding multiple paths to detect ambiguities.
  bool isFindingAmbiguities() const { return FindAmbiguities; }

  /// Whether we are recording paths.
  bool isRecordingPaths() const { return RecordPaths; }

  /// Specify whether we should be recording paths or not.
  void setRecordingPaths(bool RP) { RecordPaths = RP; }

  /// Whether we are detecting virtual bases.
  bool isDetectingVirtual() const { return DetectVirtual; }

  /// The virtual base discovered on the path (if we are merely
  /// detecting virtuals).
  const RecordType* getDetectedVirtual() const {
    return DetectedVirtual;
  }

  /// Retrieve the type from which this base-paths search
  /// began
  const CXXRecordDecl *getOrigin() const { return Origin; }
  void setOrigin(const CXXRecordDecl *Rec) { Origin = Rec; }

  /// Clear the base-paths results.
  void clear();

  /// Swap this data structure's contents with another CXXBasePaths
  /// object.
  void swap(CXXBasePaths &Other);
};

/// Uniquely identifies a virtual method within a class
/// hierarchy by the method itself and a class subobject number.
struct UniqueVirtualMethod {
  /// The overriding virtual method.
  CXXMethodDecl *Method = nullptr;

  /// The subobject in which the overriding virtual method
  /// resides.
  unsigned Subobject = 0;

  /// The virtual base class subobject of which this overridden
  /// virtual method is a part. Note that this records the closest
  /// derived virtual base class subobject.
  const CXXRecordDecl *InVirtualSubobject = nullptr;

  UniqueVirtualMethod() = default;

  UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
                      const CXXRecordDecl *InVirtualSubobject)
      : Method(Method), Subobject(Subobject),
        InVirtualSubobject(InVirtualSubobject) {}

  friend bool operator==(const UniqueVirtualMethod &X,
                         const UniqueVirtualMethod &Y) {
    return X.Method == Y.Method && X.Subobject == Y.Subobject &&
      X.InVirtualSubobject == Y.InVirtualSubobject;
  }

  friend bool operator!=(const UniqueVirtualMethod &X,
                         const UniqueVirtualMethod &Y) {
    return !(X == Y);
  }
};

/// The set of methods that override a given virtual method in
/// each subobject where it occurs.
///
/// The first part of the pair is the subobject in which the
/// overridden virtual function occurs, while the second part of the
/// pair is the virtual method that overrides it (including the
/// subobject in which that virtual function occurs).
class OverridingMethods {
  using ValuesT = SmallVector<UniqueVirtualMethod, 4>;
  using MapType = llvm::MapVector<unsigned, ValuesT>;

  MapType Overrides;

public:
  // Iterate over the set of subobjects that have overriding methods.
  using iterator = MapType::iterator;
  using const_iterator = MapType::const_iterator;

  iterator begin() { return Overrides.begin(); }
  const_iterator begin() const { return Overrides.begin(); }
  iterator end() { return Overrides.end(); }
  const_iterator end() const { return Overrides.end(); }
  unsigned size() const { return Overrides.size(); }

  // Iterate over the set of overriding virtual methods in a given
  // subobject.
  using overriding_iterator =
      SmallVectorImpl<UniqueVirtualMethod>::iterator;
  using overriding_const_iterator =
      SmallVectorImpl<UniqueVirtualMethod>::const_iterator;

  // Add a new overriding method for a particular subobject.
  void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding);

  // Add all of the overriding methods from "other" into overrides for
  // this method. Used when merging the overrides from multiple base
  // class subobjects.
  void add(const OverridingMethods &Other);

  // Replace all overriding virtual methods in all subobjects with the
  // given virtual method.
  void replaceAll(UniqueVirtualMethod Overriding);
};

/// A mapping from each virtual member function to its set of
/// final overriders.
///
/// Within a class hierarchy for a given derived class, each virtual
/// member function in that hierarchy has one or more "final
/// overriders" (C++ [class.virtual]p2). A final overrider for a
/// virtual function "f" is the virtual function that will actually be
/// invoked when dispatching a call to "f" through the
/// vtable. Well-formed classes have a single final overrider for each
/// virtual function; in abstract classes, the final overrider for at
/// least one virtual function is a pure virtual function. Due to
/// multiple, virtual inheritance, it is possible for a class to have
/// more than one final overrider. Athough this is an error (per C++
/// [class.virtual]p2), it is not considered an error here: the final
/// overrider map can represent multiple final overriders for a
/// method, and it is up to the client to determine whether they are
/// problem. For example, the following class \c D has two final
/// overriders for the virtual function \c A::f(), one in \c C and one
/// in \c D:
///
/// \code
///   struct A { virtual void f(); };
///   struct B : virtual A { virtual void f(); };
///   struct C : virtual A { virtual void f(); };
///   struct D : B, C { };
/// \endcode
///
/// This data structure contains a mapping from every virtual
/// function *that does not override an existing virtual function* and
/// in every subobject where that virtual function occurs to the set
/// of virtual functions that override it. Thus, the same virtual
/// function \c A::f can actually occur in multiple subobjects of type
/// \c A due to multiple inheritance, and may be overridden by
/// different virtual functions in each, as in the following example:
///
/// \code
///   struct A { virtual void f(); };
///   struct B : A { virtual void f(); };
///   struct C : A { virtual void f(); };
///   struct D : B, C { };
/// \endcode
///
/// Unlike in the previous example, where the virtual functions \c
/// B::f and \c C::f both overrode \c A::f in the same subobject of
/// type \c A, in this example the two virtual functions both override
/// \c A::f but in *different* subobjects of type A. This is
/// represented by numbering the subobjects in which the overridden
/// and the overriding virtual member functions are located. Subobject
/// 0 represents the virtual base class subobject of that type, while
/// subobject numbers greater than 0 refer to non-virtual base class
/// subobjects of that type.
class CXXFinalOverriderMap
  : public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> {};

/// A set of all the primary bases for a class.
class CXXIndirectPrimaryBaseSet
  : public llvm::SmallSet<const CXXRecordDecl*, 32> {};

inline bool
inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance) {
  return Inheritance == MSInheritanceModel::Unspecified;
}

// Only member pointers to functions need a this adjustment, since it can be
// combined with the field offset for data pointers.
inline bool inheritanceModelHasNVOffsetField(bool IsMemberFunction,
                                             MSInheritanceModel Inheritance) {
  return IsMemberFunction && Inheritance >= MSInheritanceModel::Multiple;
}

inline bool
inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance) {
  return Inheritance >= MSInheritanceModel::Virtual;
}

inline bool inheritanceModelHasOnlyOneField(bool IsMemberFunction,
                                            MSInheritanceModel Inheritance) {
  if (IsMemberFunction)
    return Inheritance <= MSInheritanceModel::Single;
  return Inheritance <= MSInheritanceModel::Multiple;
}

} // namespace clang

#endif // LLVM_CLANG_AST_CXXINHERITANCE_H
