Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:30

0001 //===- CXXInheritance.h - C++ Inheritance -----------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file provides routines that help analyzing C++ inheritance hierarchies.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_CLANG_AST_CXXINHERITANCE_H
0014 #define LLVM_CLANG_AST_CXXINHERITANCE_H
0015 
0016 #include "clang/AST/DeclBase.h"
0017 #include "clang/AST/DeclCXX.h"
0018 #include "clang/AST/DeclarationName.h"
0019 #include "clang/AST/Type.h"
0020 #include "clang/AST/TypeOrdering.h"
0021 #include "clang/Basic/Specifiers.h"
0022 #include "llvm/ADT/DenseMap.h"
0023 #include "llvm/ADT/MapVector.h"
0024 #include "llvm/ADT/SmallSet.h"
0025 #include "llvm/ADT/SmallVector.h"
0026 #include "llvm/ADT/iterator_range.h"
0027 #include <list>
0028 #include <memory>
0029 #include <utility>
0030 
0031 namespace clang {
0032 
0033 class ASTContext;
0034 class NamedDecl;
0035 
0036 /// Represents an element in a path from a derived class to a
0037 /// base class.
0038 ///
0039 /// Each step in the path references the link from a
0040 /// derived class to one of its direct base classes, along with a
0041 /// base "number" that identifies which base subobject of the
0042 /// original derived class we are referencing.
0043 struct CXXBasePathElement {
0044   /// The base specifier that states the link from a derived
0045   /// class to a base class, which will be followed by this base
0046   /// path element.
0047   const CXXBaseSpecifier *Base;
0048 
0049   /// The record decl of the class that the base is a base of.
0050   const CXXRecordDecl *Class;
0051 
0052   /// Identifies which base class subobject (of type
0053   /// \c Base->getType()) this base path element refers to.
0054   ///
0055   /// This value is only valid if \c !Base->isVirtual(), because there
0056   /// is no base numbering for the zero or one virtual bases of a
0057   /// given type.
0058   int SubobjectNumber;
0059 };
0060 
0061 /// Represents a path from a specific derived class
0062 /// (which is not represented as part of the path) to a particular
0063 /// (direct or indirect) base class subobject.
0064 ///
0065 /// Individual elements in the path are described by the \c CXXBasePathElement
0066 /// structure, which captures both the link from a derived class to one of its
0067 /// direct bases and identification describing which base class
0068 /// subobject is being used.
0069 class CXXBasePath : public SmallVector<CXXBasePathElement, 4> {
0070 public:
0071   /// The access along this inheritance path.  This is only
0072   /// calculated when recording paths.  AS_none is a special value
0073   /// used to indicate a path which permits no legal access.
0074   AccessSpecifier Access = AS_public;
0075 
0076   CXXBasePath() = default;
0077 
0078   /// The declarations found inside this base class subobject.
0079   DeclContext::lookup_iterator Decls;
0080 
0081   void clear() {
0082     SmallVectorImpl<CXXBasePathElement>::clear();
0083     Access = AS_public;
0084   }
0085 };
0086 
0087 /// BasePaths - Represents the set of paths from a derived class to
0088 /// one of its (direct or indirect) bases. For example, given the
0089 /// following class hierarchy:
0090 ///
0091 /// @code
0092 /// class A { };
0093 /// class B : public A { };
0094 /// class C : public A { };
0095 /// class D : public B, public C{ };
0096 /// @endcode
0097 ///
0098 /// There are two potential BasePaths to represent paths from D to a
0099 /// base subobject of type A. One path is (D,0) -> (B,0) -> (A,0)
0100 /// and another is (D,0)->(C,0)->(A,1). These two paths actually
0101 /// refer to two different base class subobjects of the same type,
0102 /// so the BasePaths object refers to an ambiguous path. On the
0103 /// other hand, consider the following class hierarchy:
0104 ///
0105 /// @code
0106 /// class A { };
0107 /// class B : public virtual A { };
0108 /// class C : public virtual A { };
0109 /// class D : public B, public C{ };
0110 /// @endcode
0111 ///
0112 /// Here, there are two potential BasePaths again, (D, 0) -> (B, 0)
0113 /// -> (A,v) and (D, 0) -> (C, 0) -> (A, v), but since both of them
0114 /// refer to the same base class subobject of type A (the virtual
0115 /// one), there is no ambiguity.
0116 class CXXBasePaths {
0117   friend class CXXRecordDecl;
0118 
0119   /// The type from which this search originated.
0120   const CXXRecordDecl *Origin = nullptr;
0121 
0122   /// Paths - The actual set of paths that can be taken from the
0123   /// derived class to the same base class.
0124   std::list<CXXBasePath> Paths;
0125 
0126   /// ClassSubobjects - Records the class subobjects for each class
0127   /// type that we've seen. The first element IsVirtBase says
0128   /// whether we found a path to a virtual base for that class type,
0129   /// while NumberOfNonVirtBases contains the number of non-virtual base
0130   /// class subobjects for that class type. The key of the map is
0131   /// the cv-unqualified canonical type of the base class subobject.
0132   struct IsVirtBaseAndNumberNonVirtBases {
0133     LLVM_PREFERRED_TYPE(bool)
0134     unsigned IsVirtBase : 1;
0135     unsigned NumberOfNonVirtBases : 31;
0136   };
0137   llvm::SmallDenseMap<QualType, IsVirtBaseAndNumberNonVirtBases, 8>
0138       ClassSubobjects;
0139 
0140   /// VisitedDependentRecords - Records the dependent records that have been
0141   /// already visited.
0142   llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedDependentRecords;
0143 
0144   /// DetectedVirtual - The base class that is virtual.
0145   const RecordType *DetectedVirtual = nullptr;
0146 
0147   /// ScratchPath - A BasePath that is used by Sema::lookupInBases
0148   /// to help build the set of paths.
0149   CXXBasePath ScratchPath;
0150 
0151   /// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
0152   /// ambiguous paths while it is looking for a path from a derived
0153   /// type to a base type.
0154   bool FindAmbiguities;
0155 
0156   /// RecordPaths - Whether Sema::IsDerivedFrom should record paths
0157   /// while it is determining whether there are paths from a derived
0158   /// type to a base type.
0159   bool RecordPaths;
0160 
0161   /// DetectVirtual - Whether Sema::IsDerivedFrom should abort the search
0162   /// if it finds a path that goes across a virtual base. The virtual class
0163   /// is also recorded.
0164   bool DetectVirtual;
0165 
0166   bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record,
0167                      CXXRecordDecl::BaseMatchesCallback BaseMatches,
0168                      bool LookupInDependent = false);
0169 
0170 public:
0171   using paths_iterator = std::list<CXXBasePath>::iterator;
0172   using const_paths_iterator = std::list<CXXBasePath>::const_iterator;
0173   using decl_iterator = NamedDecl **;
0174 
0175   /// BasePaths - Construct a new BasePaths structure to record the
0176   /// paths for a derived-to-base search.
0177   explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true,
0178                         bool DetectVirtual = true)
0179       : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
0180         DetectVirtual(DetectVirtual) {}
0181 
0182   paths_iterator begin() { return Paths.begin(); }
0183   paths_iterator end()   { return Paths.end(); }
0184   const_paths_iterator begin() const { return Paths.begin(); }
0185   const_paths_iterator end()   const { return Paths.end(); }
0186 
0187   CXXBasePath&       front()       { return Paths.front(); }
0188   const CXXBasePath& front() const { return Paths.front(); }
0189 
0190   using decl_range = llvm::iterator_range<decl_iterator>;
0191 
0192   /// Determine whether the path from the most-derived type to the
0193   /// given base type is ambiguous (i.e., it refers to multiple subobjects of
0194   /// the same base type).
0195   bool isAmbiguous(CanQualType BaseType);
0196 
0197   /// Whether we are finding multiple paths to detect ambiguities.
0198   bool isFindingAmbiguities() const { return FindAmbiguities; }
0199 
0200   /// Whether we are recording paths.
0201   bool isRecordingPaths() const { return RecordPaths; }
0202 
0203   /// Specify whether we should be recording paths or not.
0204   void setRecordingPaths(bool RP) { RecordPaths = RP; }
0205 
0206   /// Whether we are detecting virtual bases.
0207   bool isDetectingVirtual() const { return DetectVirtual; }
0208 
0209   /// The virtual base discovered on the path (if we are merely
0210   /// detecting virtuals).
0211   const RecordType* getDetectedVirtual() const {
0212     return DetectedVirtual;
0213   }
0214 
0215   /// Retrieve the type from which this base-paths search
0216   /// began
0217   const CXXRecordDecl *getOrigin() const { return Origin; }
0218   void setOrigin(const CXXRecordDecl *Rec) { Origin = Rec; }
0219 
0220   /// Clear the base-paths results.
0221   void clear();
0222 
0223   /// Swap this data structure's contents with another CXXBasePaths
0224   /// object.
0225   void swap(CXXBasePaths &Other);
0226 };
0227 
0228 /// Uniquely identifies a virtual method within a class
0229 /// hierarchy by the method itself and a class subobject number.
0230 struct UniqueVirtualMethod {
0231   /// The overriding virtual method.
0232   CXXMethodDecl *Method = nullptr;
0233 
0234   /// The subobject in which the overriding virtual method
0235   /// resides.
0236   unsigned Subobject = 0;
0237 
0238   /// The virtual base class subobject of which this overridden
0239   /// virtual method is a part. Note that this records the closest
0240   /// derived virtual base class subobject.
0241   const CXXRecordDecl *InVirtualSubobject = nullptr;
0242 
0243   UniqueVirtualMethod() = default;
0244 
0245   UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
0246                       const CXXRecordDecl *InVirtualSubobject)
0247       : Method(Method), Subobject(Subobject),
0248         InVirtualSubobject(InVirtualSubobject) {}
0249 
0250   friend bool operator==(const UniqueVirtualMethod &X,
0251                          const UniqueVirtualMethod &Y) {
0252     return X.Method == Y.Method && X.Subobject == Y.Subobject &&
0253       X.InVirtualSubobject == Y.InVirtualSubobject;
0254   }
0255 
0256   friend bool operator!=(const UniqueVirtualMethod &X,
0257                          const UniqueVirtualMethod &Y) {
0258     return !(X == Y);
0259   }
0260 };
0261 
0262 /// The set of methods that override a given virtual method in
0263 /// each subobject where it occurs.
0264 ///
0265 /// The first part of the pair is the subobject in which the
0266 /// overridden virtual function occurs, while the second part of the
0267 /// pair is the virtual method that overrides it (including the
0268 /// subobject in which that virtual function occurs).
0269 class OverridingMethods {
0270   using ValuesT = SmallVector<UniqueVirtualMethod, 4>;
0271   using MapType = llvm::MapVector<unsigned, ValuesT>;
0272 
0273   MapType Overrides;
0274 
0275 public:
0276   // Iterate over the set of subobjects that have overriding methods.
0277   using iterator = MapType::iterator;
0278   using const_iterator = MapType::const_iterator;
0279 
0280   iterator begin() { return Overrides.begin(); }
0281   const_iterator begin() const { return Overrides.begin(); }
0282   iterator end() { return Overrides.end(); }
0283   const_iterator end() const { return Overrides.end(); }
0284   unsigned size() const { return Overrides.size(); }
0285 
0286   // Iterate over the set of overriding virtual methods in a given
0287   // subobject.
0288   using overriding_iterator =
0289       SmallVectorImpl<UniqueVirtualMethod>::iterator;
0290   using overriding_const_iterator =
0291       SmallVectorImpl<UniqueVirtualMethod>::const_iterator;
0292 
0293   // Add a new overriding method for a particular subobject.
0294   void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding);
0295 
0296   // Add all of the overriding methods from "other" into overrides for
0297   // this method. Used when merging the overrides from multiple base
0298   // class subobjects.
0299   void add(const OverridingMethods &Other);
0300 
0301   // Replace all overriding virtual methods in all subobjects with the
0302   // given virtual method.
0303   void replaceAll(UniqueVirtualMethod Overriding);
0304 };
0305 
0306 /// A mapping from each virtual member function to its set of
0307 /// final overriders.
0308 ///
0309 /// Within a class hierarchy for a given derived class, each virtual
0310 /// member function in that hierarchy has one or more "final
0311 /// overriders" (C++ [class.virtual]p2). A final overrider for a
0312 /// virtual function "f" is the virtual function that will actually be
0313 /// invoked when dispatching a call to "f" through the
0314 /// vtable. Well-formed classes have a single final overrider for each
0315 /// virtual function; in abstract classes, the final overrider for at
0316 /// least one virtual function is a pure virtual function. Due to
0317 /// multiple, virtual inheritance, it is possible for a class to have
0318 /// more than one final overrider. Although this is an error (per C++
0319 /// [class.virtual]p2), it is not considered an error here: the final
0320 /// overrider map can represent multiple final overriders for a
0321 /// method, and it is up to the client to determine whether they are
0322 /// problem. For example, the following class \c D has two final
0323 /// overriders for the virtual function \c A::f(), one in \c C and one
0324 /// in \c D:
0325 ///
0326 /// \code
0327 ///   struct A { virtual void f(); };
0328 ///   struct B : virtual A { virtual void f(); };
0329 ///   struct C : virtual A { virtual void f(); };
0330 ///   struct D : B, C { };
0331 /// \endcode
0332 ///
0333 /// This data structure contains a mapping from every virtual
0334 /// function *that does not override an existing virtual function* and
0335 /// in every subobject where that virtual function occurs to the set
0336 /// of virtual functions that override it. Thus, the same virtual
0337 /// function \c A::f can actually occur in multiple subobjects of type
0338 /// \c A due to multiple inheritance, and may be overridden by
0339 /// different virtual functions in each, as in the following example:
0340 ///
0341 /// \code
0342 ///   struct A { virtual void f(); };
0343 ///   struct B : A { virtual void f(); };
0344 ///   struct C : A { virtual void f(); };
0345 ///   struct D : B, C { };
0346 /// \endcode
0347 ///
0348 /// Unlike in the previous example, where the virtual functions \c
0349 /// B::f and \c C::f both overrode \c A::f in the same subobject of
0350 /// type \c A, in this example the two virtual functions both override
0351 /// \c A::f but in *different* subobjects of type A. This is
0352 /// represented by numbering the subobjects in which the overridden
0353 /// and the overriding virtual member functions are located. Subobject
0354 /// 0 represents the virtual base class subobject of that type, while
0355 /// subobject numbers greater than 0 refer to non-virtual base class
0356 /// subobjects of that type.
0357 class CXXFinalOverriderMap
0358   : public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> {};
0359 
0360 /// A set of all the primary bases for a class.
0361 class CXXIndirectPrimaryBaseSet
0362   : public llvm::SmallSet<const CXXRecordDecl*, 32> {};
0363 
0364 inline bool
0365 inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance) {
0366   return Inheritance == MSInheritanceModel::Unspecified;
0367 }
0368 
0369 // Only member pointers to functions need a this adjustment, since it can be
0370 // combined with the field offset for data pointers.
0371 inline bool inheritanceModelHasNVOffsetField(bool IsMemberFunction,
0372                                              MSInheritanceModel Inheritance) {
0373   return IsMemberFunction && Inheritance >= MSInheritanceModel::Multiple;
0374 }
0375 
0376 inline bool
0377 inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance) {
0378   return Inheritance >= MSInheritanceModel::Virtual;
0379 }
0380 
0381 inline bool inheritanceModelHasOnlyOneField(bool IsMemberFunction,
0382                                             MSInheritanceModel Inheritance) {
0383   if (IsMemberFunction)
0384     return Inheritance <= MSInheritanceModel::Single;
0385   return Inheritance <= MSInheritanceModel::Multiple;
0386 }
0387 
0388 } // namespace clang
0389 
0390 #endif // LLVM_CLANG_AST_CXXINHERITANCE_H