xref: /freebsd-src/contrib/llvm-project/clang/lib/AST/DeclCXX.cpp (revision 52418fc2be8efa5172b90a3a9e617017173612c4)
10b57cec5SDimitry Andric //===- DeclCXX.cpp - C++ Declaration AST Node Implementation --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the C++ related Decl classes.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTLambda.h"
160b57cec5SDimitry Andric #include "clang/AST/ASTMutationListener.h"
170b57cec5SDimitry Andric #include "clang/AST/ASTUnresolvedSet.h"
18480093f4SDimitry Andric #include "clang/AST/Attr.h"
190b57cec5SDimitry Andric #include "clang/AST/CXXInheritance.h"
200b57cec5SDimitry Andric #include "clang/AST/DeclBase.h"
210b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
220b57cec5SDimitry Andric #include "clang/AST/DeclarationName.h"
230b57cec5SDimitry Andric #include "clang/AST/Expr.h"
240b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h"
250b57cec5SDimitry Andric #include "clang/AST/LambdaCapture.h"
260b57cec5SDimitry Andric #include "clang/AST/NestedNameSpecifier.h"
270b57cec5SDimitry Andric #include "clang/AST/ODRHash.h"
280b57cec5SDimitry Andric #include "clang/AST/Type.h"
290b57cec5SDimitry Andric #include "clang/AST/TypeLoc.h"
300b57cec5SDimitry Andric #include "clang/AST/UnresolvedSet.h"
310b57cec5SDimitry Andric #include "clang/Basic/Diagnostic.h"
320b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h"
330b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
340b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h"
350b57cec5SDimitry Andric #include "clang/Basic/OperatorKinds.h"
360b57cec5SDimitry Andric #include "clang/Basic/PartialDiagnostic.h"
370b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
380b57cec5SDimitry Andric #include "clang/Basic/Specifiers.h"
39bdd1243dSDimitry Andric #include "clang/Basic/TargetInfo.h"
400b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
410b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
420b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
430b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
440b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
455ffd83dbSDimitry Andric #include "llvm/Support/Format.h"
460b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
470b57cec5SDimitry Andric #include <algorithm>
480b57cec5SDimitry Andric #include <cassert>
490b57cec5SDimitry Andric #include <cstddef>
500b57cec5SDimitry Andric #include <cstdint>
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric using namespace clang;
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
550b57cec5SDimitry Andric // Decl Allocation/Deallocation Method Implementations
560b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric void AccessSpecDecl::anchor() {}
590b57cec5SDimitry Andric 
600fca6ea1SDimitry Andric AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C,
610fca6ea1SDimitry Andric                                                    GlobalDeclID ID) {
620b57cec5SDimitry Andric   return new (C, ID) AccessSpecDecl(EmptyShell());
630b57cec5SDimitry Andric }
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const {
660b57cec5SDimitry Andric   ExternalASTSource *Source = C.getExternalSource();
670b57cec5SDimitry Andric   assert(Impl.Decls.isLazy() && "getFromExternalSource for non-lazy set");
680b57cec5SDimitry Andric   assert(Source && "getFromExternalSource with no external source");
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   for (ASTUnresolvedSet::iterator I = Impl.begin(); I != Impl.end(); ++I)
710fca6ea1SDimitry Andric     I.setDecl(
720fca6ea1SDimitry Andric         cast<NamedDecl>(Source->GetExternalDecl(GlobalDeclID(I.getDeclID()))));
730b57cec5SDimitry Andric   Impl.Decls.setLazy(false);
740b57cec5SDimitry Andric }
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
770b57cec5SDimitry Andric     : UserDeclaredConstructor(false), UserDeclaredSpecialMembers(0),
780b57cec5SDimitry Andric       Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
790b57cec5SDimitry Andric       Abstract(false), IsStandardLayout(true), IsCXX11StandardLayout(true),
800b57cec5SDimitry Andric       HasBasesWithFields(false), HasBasesWithNonStaticDataMembers(false),
810b57cec5SDimitry Andric       HasPrivateFields(false), HasProtectedFields(false),
820b57cec5SDimitry Andric       HasPublicFields(false), HasMutableFields(false), HasVariantMembers(false),
8304eeddc0SDimitry Andric       HasOnlyCMembers(true), HasInitMethod(false), HasInClassInitializer(false),
840b57cec5SDimitry Andric       HasUninitializedReferenceMember(false), HasUninitializedFields(false),
8504eeddc0SDimitry Andric       HasInheritedConstructor(false), HasInheritedDefaultConstructor(false),
86e8d8bef9SDimitry Andric       HasInheritedAssignment(false),
870b57cec5SDimitry Andric       NeedOverloadResolutionForCopyConstructor(false),
880b57cec5SDimitry Andric       NeedOverloadResolutionForMoveConstructor(false),
895ffd83dbSDimitry Andric       NeedOverloadResolutionForCopyAssignment(false),
900b57cec5SDimitry Andric       NeedOverloadResolutionForMoveAssignment(false),
910b57cec5SDimitry Andric       NeedOverloadResolutionForDestructor(false),
920b57cec5SDimitry Andric       DefaultedCopyConstructorIsDeleted(false),
930b57cec5SDimitry Andric       DefaultedMoveConstructorIsDeleted(false),
945ffd83dbSDimitry Andric       DefaultedCopyAssignmentIsDeleted(false),
950b57cec5SDimitry Andric       DefaultedMoveAssignmentIsDeleted(false),
960b57cec5SDimitry Andric       DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All),
970b57cec5SDimitry Andric       HasTrivialSpecialMembersForCall(SMF_All),
980b57cec5SDimitry Andric       DeclaredNonTrivialSpecialMembers(0),
990b57cec5SDimitry Andric       DeclaredNonTrivialSpecialMembersForCall(0), HasIrrelevantDestructor(true),
1000b57cec5SDimitry Andric       HasConstexprNonCopyMoveConstructor(false),
1010b57cec5SDimitry Andric       HasDefaultedDefaultConstructor(false),
1020b57cec5SDimitry Andric       DefaultedDefaultConstructorIsConstexpr(true),
1030b57cec5SDimitry Andric       HasConstexprDefaultConstructor(false),
104a7dea167SDimitry Andric       DefaultedDestructorIsConstexpr(true),
105e8d8bef9SDimitry Andric       HasNonLiteralTypeFieldsOrBases(false), StructuralIfLiteral(true),
1060b57cec5SDimitry Andric       UserProvidedDefaultConstructor(false), DeclaredSpecialMembers(0),
1070b57cec5SDimitry Andric       ImplicitCopyConstructorCanHaveConstParamForVBase(true),
1080b57cec5SDimitry Andric       ImplicitCopyConstructorCanHaveConstParamForNonVBase(true),
1090b57cec5SDimitry Andric       ImplicitCopyAssignmentHasConstParam(true),
1100b57cec5SDimitry Andric       HasDeclaredCopyConstructorWithConstParam(false),
111fe6060f1SDimitry Andric       HasDeclaredCopyAssignmentWithConstParam(false),
112fe6060f1SDimitry Andric       IsAnyDestructorNoReturn(false), IsLambda(false),
113a7dea167SDimitry Andric       IsParsingBaseSpecifiers(false), ComputedVisibleConversions(false),
114a7dea167SDimitry Andric       HasODRHash(false), Definition(D) {}
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const {
1170b57cec5SDimitry Andric   return Bases.get(Definition->getASTContext().getExternalSource());
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getVBasesSlowCase() const {
1210b57cec5SDimitry Andric   return VBases.get(Definition->getASTContext().getExternalSource());
1220b57cec5SDimitry Andric }
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C,
1250b57cec5SDimitry Andric                              DeclContext *DC, SourceLocation StartLoc,
1260b57cec5SDimitry Andric                              SourceLocation IdLoc, IdentifierInfo *Id,
1270b57cec5SDimitry Andric                              CXXRecordDecl *PrevDecl)
1280b57cec5SDimitry Andric     : RecordDecl(K, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl),
1290b57cec5SDimitry Andric       DefinitionData(PrevDecl ? PrevDecl->DefinitionData
1300b57cec5SDimitry Andric                               : nullptr) {}
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
1330b57cec5SDimitry Andric                                      DeclContext *DC, SourceLocation StartLoc,
1340b57cec5SDimitry Andric                                      SourceLocation IdLoc, IdentifierInfo *Id,
1350b57cec5SDimitry Andric                                      CXXRecordDecl *PrevDecl,
1360b57cec5SDimitry Andric                                      bool DelayTypeCreation) {
1370b57cec5SDimitry Andric   auto *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc, IdLoc, Id,
1380b57cec5SDimitry Andric                                       PrevDecl);
1390b57cec5SDimitry Andric   R->setMayHaveOutOfDateDef(C.getLangOpts().Modules);
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric   // FIXME: DelayTypeCreation seems like such a hack
1420b57cec5SDimitry Andric   if (!DelayTypeCreation)
1430b57cec5SDimitry Andric     C.getTypeDeclType(R, PrevDecl);
1440b57cec5SDimitry Andric   return R;
1450b57cec5SDimitry Andric }
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric CXXRecordDecl *
1480b57cec5SDimitry Andric CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
1490b57cec5SDimitry Andric                             TypeSourceInfo *Info, SourceLocation Loc,
15081ad6265SDimitry Andric                             unsigned DependencyKind, bool IsGeneric,
1510b57cec5SDimitry Andric                             LambdaCaptureDefault CaptureDefault) {
1525f757f3fSDimitry Andric   auto *R = new (C, DC) CXXRecordDecl(CXXRecord, TagTypeKind::Class, C, DC, Loc,
1535f757f3fSDimitry Andric                                       Loc, nullptr, nullptr);
1540b57cec5SDimitry Andric   R->setBeingDefined(true);
15581ad6265SDimitry Andric   R->DefinitionData = new (C) struct LambdaDefinitionData(
15681ad6265SDimitry Andric       R, Info, DependencyKind, IsGeneric, CaptureDefault);
1570b57cec5SDimitry Andric   R->setMayHaveOutOfDateDef(false);
1580b57cec5SDimitry Andric   R->setImplicit(true);
15981ad6265SDimitry Andric 
1600b57cec5SDimitry Andric   C.getTypeDeclType(R, /*PrevDecl=*/nullptr);
1610b57cec5SDimitry Andric   return R;
1620b57cec5SDimitry Andric }
1630b57cec5SDimitry Andric 
1640fca6ea1SDimitry Andric CXXRecordDecl *CXXRecordDecl::CreateDeserialized(const ASTContext &C,
1650fca6ea1SDimitry Andric                                                  GlobalDeclID ID) {
1665f757f3fSDimitry Andric   auto *R = new (C, ID)
1675f757f3fSDimitry Andric       CXXRecordDecl(CXXRecord, TagTypeKind::Struct, C, nullptr,
1685f757f3fSDimitry Andric                     SourceLocation(), SourceLocation(), nullptr, nullptr);
1690b57cec5SDimitry Andric   R->setMayHaveOutOfDateDef(false);
1700b57cec5SDimitry Andric   return R;
1710b57cec5SDimitry Andric }
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric /// Determine whether a class has a repeated base class. This is intended for
1740b57cec5SDimitry Andric /// use when determining if a class is standard-layout, so makes no attempt to
1750b57cec5SDimitry Andric /// handle virtual bases.
1760b57cec5SDimitry Andric static bool hasRepeatedBaseClass(const CXXRecordDecl *StartRD) {
1770b57cec5SDimitry Andric   llvm::SmallPtrSet<const CXXRecordDecl*, 8> SeenBaseTypes;
1780b57cec5SDimitry Andric   SmallVector<const CXXRecordDecl*, 8> WorkList = {StartRD};
1790b57cec5SDimitry Andric   while (!WorkList.empty()) {
1800b57cec5SDimitry Andric     const CXXRecordDecl *RD = WorkList.pop_back_val();
181349cc55cSDimitry Andric     if (RD->getTypeForDecl()->isDependentType())
182349cc55cSDimitry Andric       continue;
1830b57cec5SDimitry Andric     for (const CXXBaseSpecifier &BaseSpec : RD->bases()) {
1840b57cec5SDimitry Andric       if (const CXXRecordDecl *B = BaseSpec.getType()->getAsCXXRecordDecl()) {
1850b57cec5SDimitry Andric         if (!SeenBaseTypes.insert(B).second)
1860b57cec5SDimitry Andric           return true;
1870b57cec5SDimitry Andric         WorkList.push_back(B);
1880b57cec5SDimitry Andric       }
1890b57cec5SDimitry Andric     }
1900b57cec5SDimitry Andric   }
1910b57cec5SDimitry Andric   return false;
1920b57cec5SDimitry Andric }
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric void
1950b57cec5SDimitry Andric CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
1960b57cec5SDimitry Andric                         unsigned NumBases) {
1970b57cec5SDimitry Andric   ASTContext &C = getASTContext();
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric   if (!data().Bases.isOffset() && data().NumBases > 0)
2000b57cec5SDimitry Andric     C.Deallocate(data().getBases());
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric   if (NumBases) {
2030b57cec5SDimitry Andric     if (!C.getLangOpts().CPlusPlus17) {
2040b57cec5SDimitry Andric       // C++ [dcl.init.aggr]p1:
2050b57cec5SDimitry Andric       //   An aggregate is [...] a class with [...] no base classes [...].
2060b57cec5SDimitry Andric       data().Aggregate = false;
2070b57cec5SDimitry Andric     }
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric     // C++ [class]p4:
2100b57cec5SDimitry Andric     //   A POD-struct is an aggregate class...
2110b57cec5SDimitry Andric     data().PlainOldData = false;
2120b57cec5SDimitry Andric   }
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   // The set of seen virtual base types.
2150b57cec5SDimitry Andric   llvm::SmallPtrSet<CanQualType, 8> SeenVBaseTypes;
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric   // The virtual bases of this class.
2180b57cec5SDimitry Andric   SmallVector<const CXXBaseSpecifier *, 8> VBases;
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric   data().Bases = new(C) CXXBaseSpecifier [NumBases];
2210b57cec5SDimitry Andric   data().NumBases = NumBases;
2220b57cec5SDimitry Andric   for (unsigned i = 0; i < NumBases; ++i) {
2230b57cec5SDimitry Andric     data().getBases()[i] = *Bases[i];
2240b57cec5SDimitry Andric     // Keep track of inherited vbases for this base class.
2250b57cec5SDimitry Andric     const CXXBaseSpecifier *Base = Bases[i];
2260b57cec5SDimitry Andric     QualType BaseType = Base->getType();
2270b57cec5SDimitry Andric     // Skip dependent types; we can't do any checking on them now.
2280b57cec5SDimitry Andric     if (BaseType->isDependentType())
2290b57cec5SDimitry Andric       continue;
2300b57cec5SDimitry Andric     auto *BaseClassDecl =
231a7dea167SDimitry Andric         cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getDecl());
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric     // C++2a [class]p7:
2340b57cec5SDimitry Andric     //   A standard-layout class is a class that:
2350b57cec5SDimitry Andric     //    [...]
2360b57cec5SDimitry Andric     //    -- has all non-static data members and bit-fields in the class and
2370b57cec5SDimitry Andric     //       its base classes first declared in the same class
2380b57cec5SDimitry Andric     if (BaseClassDecl->data().HasBasesWithFields ||
2390b57cec5SDimitry Andric         !BaseClassDecl->field_empty()) {
2400b57cec5SDimitry Andric       if (data().HasBasesWithFields)
2410b57cec5SDimitry Andric         // Two bases have members or bit-fields: not standard-layout.
2420b57cec5SDimitry Andric         data().IsStandardLayout = false;
2430b57cec5SDimitry Andric       data().HasBasesWithFields = true;
2440b57cec5SDimitry Andric     }
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric     // C++11 [class]p7:
2470b57cec5SDimitry Andric     //   A standard-layout class is a class that:
2480b57cec5SDimitry Andric     //     -- [...] has [...] at most one base class with non-static data
2490b57cec5SDimitry Andric     //        members
2500b57cec5SDimitry Andric     if (BaseClassDecl->data().HasBasesWithNonStaticDataMembers ||
2510b57cec5SDimitry Andric         BaseClassDecl->hasDirectFields()) {
2520b57cec5SDimitry Andric       if (data().HasBasesWithNonStaticDataMembers)
2530b57cec5SDimitry Andric         data().IsCXX11StandardLayout = false;
2540b57cec5SDimitry Andric       data().HasBasesWithNonStaticDataMembers = true;
2550b57cec5SDimitry Andric     }
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric     if (!BaseClassDecl->isEmpty()) {
2580b57cec5SDimitry Andric       // C++14 [meta.unary.prop]p4:
2590b57cec5SDimitry Andric       //   T is a class type [...] with [...] no base class B for which
2600b57cec5SDimitry Andric       //   is_empty<B>::value is false.
2610b57cec5SDimitry Andric       data().Empty = false;
2620b57cec5SDimitry Andric     }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric     // C++1z [dcl.init.agg]p1:
2650b57cec5SDimitry Andric     //   An aggregate is a class with [...] no private or protected base classes
266e8d8bef9SDimitry Andric     if (Base->getAccessSpecifier() != AS_public) {
2670b57cec5SDimitry Andric       data().Aggregate = false;
2680b57cec5SDimitry Andric 
269e8d8bef9SDimitry Andric       // C++20 [temp.param]p7:
270e8d8bef9SDimitry Andric       //   A structural type is [...] a literal class type with [...] all base
271e8d8bef9SDimitry Andric       //   classes [...] public
272e8d8bef9SDimitry Andric       data().StructuralIfLiteral = false;
273e8d8bef9SDimitry Andric     }
274e8d8bef9SDimitry Andric 
2750b57cec5SDimitry Andric     // C++ [class.virtual]p1:
2760b57cec5SDimitry Andric     //   A class that declares or inherits a virtual function is called a
2770b57cec5SDimitry Andric     //   polymorphic class.
2780b57cec5SDimitry Andric     if (BaseClassDecl->isPolymorphic()) {
2790b57cec5SDimitry Andric       data().Polymorphic = true;
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric       //   An aggregate is a class with [...] no virtual functions.
2820b57cec5SDimitry Andric       data().Aggregate = false;
2830b57cec5SDimitry Andric     }
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric     // C++0x [class]p7:
2860b57cec5SDimitry Andric     //   A standard-layout class is a class that: [...]
2870b57cec5SDimitry Andric     //    -- has no non-standard-layout base classes
2880b57cec5SDimitry Andric     if (!BaseClassDecl->isStandardLayout())
2890b57cec5SDimitry Andric       data().IsStandardLayout = false;
2900b57cec5SDimitry Andric     if (!BaseClassDecl->isCXX11StandardLayout())
2910b57cec5SDimitry Andric       data().IsCXX11StandardLayout = false;
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric     // Record if this base is the first non-literal field or base.
2940b57cec5SDimitry Andric     if (!hasNonLiteralTypeFieldsOrBases() && !BaseType->isLiteralType(C))
2950b57cec5SDimitry Andric       data().HasNonLiteralTypeFieldsOrBases = true;
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric     // Now go through all virtual bases of this base and add them.
2980b57cec5SDimitry Andric     for (const auto &VBase : BaseClassDecl->vbases()) {
2990b57cec5SDimitry Andric       // Add this base if it's not already in the list.
3000b57cec5SDimitry Andric       if (SeenVBaseTypes.insert(C.getCanonicalType(VBase.getType())).second) {
3010b57cec5SDimitry Andric         VBases.push_back(&VBase);
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric         // C++11 [class.copy]p8:
3040b57cec5SDimitry Andric         //   The implicitly-declared copy constructor for a class X will have
3050b57cec5SDimitry Andric         //   the form 'X::X(const X&)' if each [...] virtual base class B of X
3060b57cec5SDimitry Andric         //   has a copy constructor whose first parameter is of type
3070b57cec5SDimitry Andric         //   'const B&' or 'const volatile B&' [...]
3080b57cec5SDimitry Andric         if (CXXRecordDecl *VBaseDecl = VBase.getType()->getAsCXXRecordDecl())
3090b57cec5SDimitry Andric           if (!VBaseDecl->hasCopyConstructorWithConstParam())
3100b57cec5SDimitry Andric             data().ImplicitCopyConstructorCanHaveConstParamForVBase = false;
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric         // C++1z [dcl.init.agg]p1:
3130b57cec5SDimitry Andric         //   An aggregate is a class with [...] no virtual base classes
3140b57cec5SDimitry Andric         data().Aggregate = false;
3150b57cec5SDimitry Andric       }
3160b57cec5SDimitry Andric     }
3170b57cec5SDimitry Andric 
3180b57cec5SDimitry Andric     if (Base->isVirtual()) {
3190b57cec5SDimitry Andric       // Add this base if it's not already in the list.
3200b57cec5SDimitry Andric       if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType)).second)
3210b57cec5SDimitry Andric         VBases.push_back(Base);
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric       // C++14 [meta.unary.prop] is_empty:
3240b57cec5SDimitry Andric       //   T is a class type, but not a union type, with ... no virtual base
3250b57cec5SDimitry Andric       //   classes
3260b57cec5SDimitry Andric       data().Empty = false;
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric       // C++1z [dcl.init.agg]p1:
3290b57cec5SDimitry Andric       //   An aggregate is a class with [...] no virtual base classes
3300b57cec5SDimitry Andric       data().Aggregate = false;
3310b57cec5SDimitry Andric 
3320b57cec5SDimitry Andric       // C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25:
3330b57cec5SDimitry Andric       //   A [default constructor, copy/move constructor, or copy/move assignment
3340b57cec5SDimitry Andric       //   operator for a class X] is trivial [...] if:
3350b57cec5SDimitry Andric       //    -- class X has [...] no virtual base classes
3360b57cec5SDimitry Andric       data().HasTrivialSpecialMembers &= SMF_Destructor;
3370b57cec5SDimitry Andric       data().HasTrivialSpecialMembersForCall &= SMF_Destructor;
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric       // C++0x [class]p7:
3400b57cec5SDimitry Andric       //   A standard-layout class is a class that: [...]
3410b57cec5SDimitry Andric       //    -- has [...] no virtual base classes
3420b57cec5SDimitry Andric       data().IsStandardLayout = false;
3430b57cec5SDimitry Andric       data().IsCXX11StandardLayout = false;
3440b57cec5SDimitry Andric 
345a7dea167SDimitry Andric       // C++20 [dcl.constexpr]p3:
346a7dea167SDimitry Andric       //   In the definition of a constexpr function [...]
347a7dea167SDimitry Andric       //    -- if the function is a constructor or destructor,
348a7dea167SDimitry Andric       //       its class shall not have any virtual base classes
3490b57cec5SDimitry Andric       data().DefaultedDefaultConstructorIsConstexpr = false;
350a7dea167SDimitry Andric       data().DefaultedDestructorIsConstexpr = false;
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric       // C++1z [class.copy]p8:
3530b57cec5SDimitry Andric       //   The implicitly-declared copy constructor for a class X will have
3540b57cec5SDimitry Andric       //   the form 'X::X(const X&)' if each potentially constructed subobject
3550b57cec5SDimitry Andric       //   has a copy constructor whose first parameter is of type
3560b57cec5SDimitry Andric       //   'const B&' or 'const volatile B&' [...]
3570b57cec5SDimitry Andric       if (!BaseClassDecl->hasCopyConstructorWithConstParam())
3580b57cec5SDimitry Andric         data().ImplicitCopyConstructorCanHaveConstParamForVBase = false;
3590b57cec5SDimitry Andric     } else {
3600b57cec5SDimitry Andric       // C++ [class.ctor]p5:
3610b57cec5SDimitry Andric       //   A default constructor is trivial [...] if:
3620b57cec5SDimitry Andric       //    -- all the direct base classes of its class have trivial default
3630b57cec5SDimitry Andric       //       constructors.
3640b57cec5SDimitry Andric       if (!BaseClassDecl->hasTrivialDefaultConstructor())
3650b57cec5SDimitry Andric         data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor;
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric       // C++0x [class.copy]p13:
3680b57cec5SDimitry Andric       //   A copy/move constructor for class X is trivial if [...]
3690b57cec5SDimitry Andric       //    [...]
3700b57cec5SDimitry Andric       //    -- the constructor selected to copy/move each direct base class
3710b57cec5SDimitry Andric       //       subobject is trivial, and
3720b57cec5SDimitry Andric       if (!BaseClassDecl->hasTrivialCopyConstructor())
3730b57cec5SDimitry Andric         data().HasTrivialSpecialMembers &= ~SMF_CopyConstructor;
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric       if (!BaseClassDecl->hasTrivialCopyConstructorForCall())
3760b57cec5SDimitry Andric         data().HasTrivialSpecialMembersForCall &= ~SMF_CopyConstructor;
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric       // If the base class doesn't have a simple move constructor, we'll eagerly
3790b57cec5SDimitry Andric       // declare it and perform overload resolution to determine which function
3800b57cec5SDimitry Andric       // it actually calls. If it does have a simple move constructor, this
3810b57cec5SDimitry Andric       // check is correct.
3820b57cec5SDimitry Andric       if (!BaseClassDecl->hasTrivialMoveConstructor())
3830b57cec5SDimitry Andric         data().HasTrivialSpecialMembers &= ~SMF_MoveConstructor;
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric       if (!BaseClassDecl->hasTrivialMoveConstructorForCall())
3860b57cec5SDimitry Andric         data().HasTrivialSpecialMembersForCall &= ~SMF_MoveConstructor;
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric       // C++0x [class.copy]p27:
3890b57cec5SDimitry Andric       //   A copy/move assignment operator for class X is trivial if [...]
3900b57cec5SDimitry Andric       //    [...]
3910b57cec5SDimitry Andric       //    -- the assignment operator selected to copy/move each direct base
3920b57cec5SDimitry Andric       //       class subobject is trivial, and
3930b57cec5SDimitry Andric       if (!BaseClassDecl->hasTrivialCopyAssignment())
3940b57cec5SDimitry Andric         data().HasTrivialSpecialMembers &= ~SMF_CopyAssignment;
3950b57cec5SDimitry Andric       // If the base class doesn't have a simple move assignment, we'll eagerly
3960b57cec5SDimitry Andric       // declare it and perform overload resolution to determine which function
3970b57cec5SDimitry Andric       // it actually calls. If it does have a simple move assignment, this
3980b57cec5SDimitry Andric       // check is correct.
3990b57cec5SDimitry Andric       if (!BaseClassDecl->hasTrivialMoveAssignment())
4000b57cec5SDimitry Andric         data().HasTrivialSpecialMembers &= ~SMF_MoveAssignment;
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric       // C++11 [class.ctor]p6:
4030b57cec5SDimitry Andric       //   If that user-written default constructor would satisfy the
4040fca6ea1SDimitry Andric       //   requirements of a constexpr constructor/function(C++23), the
4050fca6ea1SDimitry Andric       //   implicitly-defined default constructor is constexpr.
4060b57cec5SDimitry Andric       if (!BaseClassDecl->hasConstexprDefaultConstructor())
4070fca6ea1SDimitry Andric         data().DefaultedDefaultConstructorIsConstexpr =
4080fca6ea1SDimitry Andric             C.getLangOpts().CPlusPlus23;
4090b57cec5SDimitry Andric 
4100b57cec5SDimitry Andric       // C++1z [class.copy]p8:
4110b57cec5SDimitry Andric       //   The implicitly-declared copy constructor for a class X will have
4120b57cec5SDimitry Andric       //   the form 'X::X(const X&)' if each potentially constructed subobject
4130b57cec5SDimitry Andric       //   has a copy constructor whose first parameter is of type
4140b57cec5SDimitry Andric       //   'const B&' or 'const volatile B&' [...]
4150b57cec5SDimitry Andric       if (!BaseClassDecl->hasCopyConstructorWithConstParam())
4160b57cec5SDimitry Andric         data().ImplicitCopyConstructorCanHaveConstParamForNonVBase = false;
4170b57cec5SDimitry Andric     }
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric     // C++ [class.ctor]p3:
4200b57cec5SDimitry Andric     //   A destructor is trivial if all the direct base classes of its class
4210b57cec5SDimitry Andric     //   have trivial destructors.
4220b57cec5SDimitry Andric     if (!BaseClassDecl->hasTrivialDestructor())
4230b57cec5SDimitry Andric       data().HasTrivialSpecialMembers &= ~SMF_Destructor;
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric     if (!BaseClassDecl->hasTrivialDestructorForCall())
4260b57cec5SDimitry Andric       data().HasTrivialSpecialMembersForCall &= ~SMF_Destructor;
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric     if (!BaseClassDecl->hasIrrelevantDestructor())
4290b57cec5SDimitry Andric       data().HasIrrelevantDestructor = false;
4300b57cec5SDimitry Andric 
431fe6060f1SDimitry Andric     if (BaseClassDecl->isAnyDestructorNoReturn())
432fe6060f1SDimitry Andric       data().IsAnyDestructorNoReturn = true;
433fe6060f1SDimitry Andric 
4340b57cec5SDimitry Andric     // C++11 [class.copy]p18:
435480093f4SDimitry Andric     //   The implicitly-declared copy assignment operator for a class X will
4360b57cec5SDimitry Andric     //   have the form 'X& X::operator=(const X&)' if each direct base class B
4370b57cec5SDimitry Andric     //   of X has a copy assignment operator whose parameter is of type 'const
4380b57cec5SDimitry Andric     //   B&', 'const volatile B&', or 'B' [...]
4390b57cec5SDimitry Andric     if (!BaseClassDecl->hasCopyAssignmentWithConstParam())
4400b57cec5SDimitry Andric       data().ImplicitCopyAssignmentHasConstParam = false;
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric     // A class has an Objective-C object member if... or any of its bases
4430b57cec5SDimitry Andric     // has an Objective-C object member.
4440b57cec5SDimitry Andric     if (BaseClassDecl->hasObjectMember())
4450b57cec5SDimitry Andric       setHasObjectMember(true);
4460b57cec5SDimitry Andric 
4470b57cec5SDimitry Andric     if (BaseClassDecl->hasVolatileMember())
4480b57cec5SDimitry Andric       setHasVolatileMember(true);
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric     if (BaseClassDecl->getArgPassingRestrictions() ==
4515f757f3fSDimitry Andric         RecordArgPassingKind::CanNeverPassInRegs)
4525f757f3fSDimitry Andric       setArgPassingRestrictions(RecordArgPassingKind::CanNeverPassInRegs);
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric     // Keep track of the presence of mutable fields.
4555ffd83dbSDimitry Andric     if (BaseClassDecl->hasMutableFields())
4560b57cec5SDimitry Andric       data().HasMutableFields = true;
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric     if (BaseClassDecl->hasUninitializedReferenceMember())
4590b57cec5SDimitry Andric       data().HasUninitializedReferenceMember = true;
4600b57cec5SDimitry Andric 
4610b57cec5SDimitry Andric     if (!BaseClassDecl->allowConstDefaultInit())
4620b57cec5SDimitry Andric       data().HasUninitializedFields = true;
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric     addedClassSubobject(BaseClassDecl);
4650b57cec5SDimitry Andric   }
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric   // C++2a [class]p7:
4680b57cec5SDimitry Andric   //   A class S is a standard-layout class if it:
4690b57cec5SDimitry Andric   //     -- has at most one base class subobject of any given type
4700b57cec5SDimitry Andric   //
4710b57cec5SDimitry Andric   // Note that we only need to check this for classes with more than one base
4720b57cec5SDimitry Andric   // class. If there's only one base class, and it's standard layout, then
4730b57cec5SDimitry Andric   // we know there are no repeated base classes.
4740b57cec5SDimitry Andric   if (data().IsStandardLayout && NumBases > 1 && hasRepeatedBaseClass(this))
4750b57cec5SDimitry Andric     data().IsStandardLayout = false;
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   if (VBases.empty()) {
4780b57cec5SDimitry Andric     data().IsParsingBaseSpecifiers = false;
4790b57cec5SDimitry Andric     return;
4800b57cec5SDimitry Andric   }
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric   // Create base specifier for any direct or indirect virtual bases.
4830b57cec5SDimitry Andric   data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
4840b57cec5SDimitry Andric   data().NumVBases = VBases.size();
4850b57cec5SDimitry Andric   for (int I = 0, E = VBases.size(); I != E; ++I) {
4860b57cec5SDimitry Andric     QualType Type = VBases[I]->getType();
4870b57cec5SDimitry Andric     if (!Type->isDependentType())
4880b57cec5SDimitry Andric       addedClassSubobject(Type->getAsCXXRecordDecl());
4890b57cec5SDimitry Andric     data().getVBases()[I] = *VBases[I];
4900b57cec5SDimitry Andric   }
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric   data().IsParsingBaseSpecifiers = false;
4930b57cec5SDimitry Andric }
4940b57cec5SDimitry Andric 
4950b57cec5SDimitry Andric unsigned CXXRecordDecl::getODRHash() const {
4960b57cec5SDimitry Andric   assert(hasDefinition() && "ODRHash only for records with definitions");
4970b57cec5SDimitry Andric 
4980b57cec5SDimitry Andric   // Previously calculated hash is stored in DefinitionData.
4990b57cec5SDimitry Andric   if (DefinitionData->HasODRHash)
5000b57cec5SDimitry Andric     return DefinitionData->ODRHash;
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric   // Only calculate hash on first call of getODRHash per record.
5030b57cec5SDimitry Andric   ODRHash Hash;
5040b57cec5SDimitry Andric   Hash.AddCXXRecordDecl(getDefinition());
5050b57cec5SDimitry Andric   DefinitionData->HasODRHash = true;
5060b57cec5SDimitry Andric   DefinitionData->ODRHash = Hash.CalculateHash();
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   return DefinitionData->ODRHash;
5090b57cec5SDimitry Andric }
5100b57cec5SDimitry Andric 
5110b57cec5SDimitry Andric void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
5120b57cec5SDimitry Andric   // C++11 [class.copy]p11:
5130b57cec5SDimitry Andric   //   A defaulted copy/move constructor for a class X is defined as
5140b57cec5SDimitry Andric   //   deleted if X has:
5150b57cec5SDimitry Andric   //    -- a direct or virtual base class B that cannot be copied/moved [...]
5160b57cec5SDimitry Andric   //    -- a non-static data member of class type M (or array thereof)
5170b57cec5SDimitry Andric   //       that cannot be copied or moved [...]
5180b57cec5SDimitry Andric   if (!Subobj->hasSimpleCopyConstructor())
5190b57cec5SDimitry Andric     data().NeedOverloadResolutionForCopyConstructor = true;
5200b57cec5SDimitry Andric   if (!Subobj->hasSimpleMoveConstructor())
5210b57cec5SDimitry Andric     data().NeedOverloadResolutionForMoveConstructor = true;
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric   // C++11 [class.copy]p23:
5240b57cec5SDimitry Andric   //   A defaulted copy/move assignment operator for a class X is defined as
5250b57cec5SDimitry Andric   //   deleted if X has:
5260b57cec5SDimitry Andric   //    -- a direct or virtual base class B that cannot be copied/moved [...]
5270b57cec5SDimitry Andric   //    -- a non-static data member of class type M (or array thereof)
5280b57cec5SDimitry Andric   //        that cannot be copied or moved [...]
5295ffd83dbSDimitry Andric   if (!Subobj->hasSimpleCopyAssignment())
5305ffd83dbSDimitry Andric     data().NeedOverloadResolutionForCopyAssignment = true;
5310b57cec5SDimitry Andric   if (!Subobj->hasSimpleMoveAssignment())
5320b57cec5SDimitry Andric     data().NeedOverloadResolutionForMoveAssignment = true;
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric   // C++11 [class.ctor]p5, C++11 [class.copy]p11, C++11 [class.dtor]p5:
5350b57cec5SDimitry Andric   //   A defaulted [ctor or dtor] for a class X is defined as
5360b57cec5SDimitry Andric   //   deleted if X has:
5370b57cec5SDimitry Andric   //    -- any direct or virtual base class [...] has a type with a destructor
5380b57cec5SDimitry Andric   //       that is deleted or inaccessible from the defaulted [ctor or dtor].
5390b57cec5SDimitry Andric   //    -- any non-static data member has a type with a destructor
5400b57cec5SDimitry Andric   //       that is deleted or inaccessible from the defaulted [ctor or dtor].
5410b57cec5SDimitry Andric   if (!Subobj->hasSimpleDestructor()) {
5420b57cec5SDimitry Andric     data().NeedOverloadResolutionForCopyConstructor = true;
5430b57cec5SDimitry Andric     data().NeedOverloadResolutionForMoveConstructor = true;
5440b57cec5SDimitry Andric     data().NeedOverloadResolutionForDestructor = true;
5450b57cec5SDimitry Andric   }
546a7dea167SDimitry Andric 
547a7dea167SDimitry Andric   // C++2a [dcl.constexpr]p4:
548a7dea167SDimitry Andric   //   The definition of a constexpr destructor [shall] satisfy the
549a7dea167SDimitry Andric   //   following requirement:
550a7dea167SDimitry Andric   //   -- for every subobject of class type or (possibly multi-dimensional)
551a7dea167SDimitry Andric   //      array thereof, that class type shall have a constexpr destructor
552a7dea167SDimitry Andric   if (!Subobj->hasConstexprDestructor())
5530fca6ea1SDimitry Andric     data().DefaultedDestructorIsConstexpr =
5540fca6ea1SDimitry Andric         getASTContext().getLangOpts().CPlusPlus23;
555e8d8bef9SDimitry Andric 
556e8d8bef9SDimitry Andric   // C++20 [temp.param]p7:
557e8d8bef9SDimitry Andric   //   A structural type is [...] a literal class type [for which] the types
558e8d8bef9SDimitry Andric   //   of all base classes and non-static data members are structural types or
559e8d8bef9SDimitry Andric   //   (possibly multi-dimensional) array thereof
560e8d8bef9SDimitry Andric   if (!Subobj->data().StructuralIfLiteral)
561e8d8bef9SDimitry Andric     data().StructuralIfLiteral = false;
562a7dea167SDimitry Andric }
563a7dea167SDimitry Andric 
564*52418fc2SDimitry Andric const CXXRecordDecl *CXXRecordDecl::getStandardLayoutBaseWithFields() const {
565*52418fc2SDimitry Andric   assert(
566*52418fc2SDimitry Andric       isStandardLayout() &&
567*52418fc2SDimitry Andric       "getStandardLayoutBaseWithFields called on a non-standard-layout type");
568*52418fc2SDimitry Andric #ifdef EXPENSIVE_CHECKS
569*52418fc2SDimitry Andric   {
570*52418fc2SDimitry Andric     unsigned NumberOfBasesWithFields = 0;
571*52418fc2SDimitry Andric     if (!field_empty())
572*52418fc2SDimitry Andric       ++NumberOfBasesWithFields;
573*52418fc2SDimitry Andric     llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
574*52418fc2SDimitry Andric     forallBases([&](const CXXRecordDecl *Base) -> bool {
575*52418fc2SDimitry Andric       if (!Base->field_empty())
576*52418fc2SDimitry Andric         ++NumberOfBasesWithFields;
577*52418fc2SDimitry Andric       assert(
578*52418fc2SDimitry Andric           UniqueBases.insert(Base->getCanonicalDecl()).second &&
579*52418fc2SDimitry Andric           "Standard layout struct has multiple base classes of the same type");
580*52418fc2SDimitry Andric       return true;
581*52418fc2SDimitry Andric     });
582*52418fc2SDimitry Andric     assert(NumberOfBasesWithFields <= 1 &&
583*52418fc2SDimitry Andric            "Standard layout struct has fields declared in more than one class");
584*52418fc2SDimitry Andric   }
585*52418fc2SDimitry Andric #endif
586*52418fc2SDimitry Andric   if (!field_empty())
587*52418fc2SDimitry Andric     return this;
588*52418fc2SDimitry Andric   const CXXRecordDecl *Result = this;
589*52418fc2SDimitry Andric   forallBases([&](const CXXRecordDecl *Base) -> bool {
590*52418fc2SDimitry Andric     if (!Base->field_empty()) {
591*52418fc2SDimitry Andric       // This is the base where the fields are declared; return early
592*52418fc2SDimitry Andric       Result = Base;
593*52418fc2SDimitry Andric       return false;
594*52418fc2SDimitry Andric     }
595*52418fc2SDimitry Andric     return true;
596*52418fc2SDimitry Andric   });
597*52418fc2SDimitry Andric   return Result;
598*52418fc2SDimitry Andric }
599*52418fc2SDimitry Andric 
600a7dea167SDimitry Andric bool CXXRecordDecl::hasConstexprDestructor() const {
601a7dea167SDimitry Andric   auto *Dtor = getDestructor();
602a7dea167SDimitry Andric   return Dtor ? Dtor->isConstexpr() : defaultedDestructorIsConstexpr();
6030b57cec5SDimitry Andric }
6040b57cec5SDimitry Andric 
6050b57cec5SDimitry Andric bool CXXRecordDecl::hasAnyDependentBases() const {
6060b57cec5SDimitry Andric   if (!isDependentContext())
6070b57cec5SDimitry Andric     return false;
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric   return !forallBases([](const CXXRecordDecl *) { return true; });
6100b57cec5SDimitry Andric }
6110b57cec5SDimitry Andric 
6120b57cec5SDimitry Andric bool CXXRecordDecl::isTriviallyCopyable() const {
6130b57cec5SDimitry Andric   // C++0x [class]p5:
6140b57cec5SDimitry Andric   //   A trivially copyable class is a class that:
6150b57cec5SDimitry Andric   //   -- has no non-trivial copy constructors,
6160b57cec5SDimitry Andric   if (hasNonTrivialCopyConstructor()) return false;
6170b57cec5SDimitry Andric   //   -- has no non-trivial move constructors,
6180b57cec5SDimitry Andric   if (hasNonTrivialMoveConstructor()) return false;
6190b57cec5SDimitry Andric   //   -- has no non-trivial copy assignment operators,
6200b57cec5SDimitry Andric   if (hasNonTrivialCopyAssignment()) return false;
6210b57cec5SDimitry Andric   //   -- has no non-trivial move assignment operators, and
6220b57cec5SDimitry Andric   if (hasNonTrivialMoveAssignment()) return false;
6230b57cec5SDimitry Andric   //   -- has a trivial destructor.
6240b57cec5SDimitry Andric   if (!hasTrivialDestructor()) return false;
6250b57cec5SDimitry Andric 
6260b57cec5SDimitry Andric   return true;
6270b57cec5SDimitry Andric }
6280b57cec5SDimitry Andric 
629297eecfbSDimitry Andric bool CXXRecordDecl::isTriviallyCopyConstructible() const {
630297eecfbSDimitry Andric 
631297eecfbSDimitry Andric   //   A trivially copy constructible class is a class that:
632297eecfbSDimitry Andric   //   -- has no non-trivial copy constructors,
633297eecfbSDimitry Andric   if (hasNonTrivialCopyConstructor())
634297eecfbSDimitry Andric     return false;
635297eecfbSDimitry Andric   //   -- has a trivial destructor.
636297eecfbSDimitry Andric   if (!hasTrivialDestructor())
637297eecfbSDimitry Andric     return false;
638297eecfbSDimitry Andric 
639297eecfbSDimitry Andric   return true;
640297eecfbSDimitry Andric }
641297eecfbSDimitry Andric 
6420b57cec5SDimitry Andric void CXXRecordDecl::markedVirtualFunctionPure() {
6430b57cec5SDimitry Andric   // C++ [class.abstract]p2:
6440b57cec5SDimitry Andric   //   A class is abstract if it has at least one pure virtual function.
6450b57cec5SDimitry Andric   data().Abstract = true;
6460b57cec5SDimitry Andric }
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric bool CXXRecordDecl::hasSubobjectAtOffsetZeroOfEmptyBaseType(
6490b57cec5SDimitry Andric     ASTContext &Ctx, const CXXRecordDecl *XFirst) {
6500b57cec5SDimitry Andric   if (!getNumBases())
6510b57cec5SDimitry Andric     return false;
6520b57cec5SDimitry Andric 
6530b57cec5SDimitry Andric   llvm::SmallPtrSet<const CXXRecordDecl*, 8> Bases;
6540b57cec5SDimitry Andric   llvm::SmallPtrSet<const CXXRecordDecl*, 8> M;
6550b57cec5SDimitry Andric   SmallVector<const CXXRecordDecl*, 8> WorkList;
6560b57cec5SDimitry Andric 
6570b57cec5SDimitry Andric   // Visit a type that we have determined is an element of M(S).
6580b57cec5SDimitry Andric   auto Visit = [&](const CXXRecordDecl *RD) -> bool {
6590b57cec5SDimitry Andric     RD = RD->getCanonicalDecl();
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric     // C++2a [class]p8:
6620b57cec5SDimitry Andric     //   A class S is a standard-layout class if it [...] has no element of the
6630b57cec5SDimitry Andric     //   set M(S) of types as a base class.
6640b57cec5SDimitry Andric     //
6650b57cec5SDimitry Andric     // If we find a subobject of an empty type, it might also be a base class,
6660b57cec5SDimitry Andric     // so we'll need to walk the base classes to check.
6670b57cec5SDimitry Andric     if (!RD->data().HasBasesWithFields) {
6680b57cec5SDimitry Andric       // Walk the bases the first time, stopping if we find the type. Build a
6690b57cec5SDimitry Andric       // set of them so we don't need to walk them again.
6700b57cec5SDimitry Andric       if (Bases.empty()) {
6710b57cec5SDimitry Andric         bool RDIsBase = !forallBases([&](const CXXRecordDecl *Base) -> bool {
6720b57cec5SDimitry Andric           Base = Base->getCanonicalDecl();
6730b57cec5SDimitry Andric           if (RD == Base)
6740b57cec5SDimitry Andric             return false;
6750b57cec5SDimitry Andric           Bases.insert(Base);
6760b57cec5SDimitry Andric           return true;
6770b57cec5SDimitry Andric         });
6780b57cec5SDimitry Andric         if (RDIsBase)
6790b57cec5SDimitry Andric           return true;
6800b57cec5SDimitry Andric       } else {
6810b57cec5SDimitry Andric         if (Bases.count(RD))
6820b57cec5SDimitry Andric           return true;
6830b57cec5SDimitry Andric       }
6840b57cec5SDimitry Andric     }
6850b57cec5SDimitry Andric 
6860b57cec5SDimitry Andric     if (M.insert(RD).second)
6870b57cec5SDimitry Andric       WorkList.push_back(RD);
6880b57cec5SDimitry Andric     return false;
6890b57cec5SDimitry Andric   };
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric   if (Visit(XFirst))
6920b57cec5SDimitry Andric     return true;
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric   while (!WorkList.empty()) {
6950b57cec5SDimitry Andric     const CXXRecordDecl *X = WorkList.pop_back_val();
6960b57cec5SDimitry Andric 
6970b57cec5SDimitry Andric     // FIXME: We don't check the bases of X. That matches the standard, but
6980b57cec5SDimitry Andric     // that sure looks like a wording bug.
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric     //   -- If X is a non-union class type with a non-static data member
7010b57cec5SDimitry Andric     //      [recurse to each field] that is either of zero size or is the
7020b57cec5SDimitry Andric     //      first non-static data member of X
7030b57cec5SDimitry Andric     //   -- If X is a union type, [recurse to union members]
7040b57cec5SDimitry Andric     bool IsFirstField = true;
7050b57cec5SDimitry Andric     for (auto *FD : X->fields()) {
7060b57cec5SDimitry Andric       // FIXME: Should we really care about the type of the first non-static
7070b57cec5SDimitry Andric       // data member of a non-union if there are preceding unnamed bit-fields?
7080fca6ea1SDimitry Andric       if (FD->isUnnamedBitField())
7090b57cec5SDimitry Andric         continue;
7100b57cec5SDimitry Andric 
7110b57cec5SDimitry Andric       if (!IsFirstField && !FD->isZeroSize(Ctx))
7120b57cec5SDimitry Andric         continue;
7130b57cec5SDimitry Andric 
7140fca6ea1SDimitry Andric       if (FD->isInvalidDecl())
7150fca6ea1SDimitry Andric         continue;
7160fca6ea1SDimitry Andric 
7170b57cec5SDimitry Andric       //   -- If X is n array type, [visit the element type]
7180b57cec5SDimitry Andric       QualType T = Ctx.getBaseElementType(FD->getType());
7190b57cec5SDimitry Andric       if (auto *RD = T->getAsCXXRecordDecl())
7200b57cec5SDimitry Andric         if (Visit(RD))
7210b57cec5SDimitry Andric           return true;
7220b57cec5SDimitry Andric 
7230b57cec5SDimitry Andric       if (!X->isUnion())
7240b57cec5SDimitry Andric         IsFirstField = false;
7250b57cec5SDimitry Andric     }
7260b57cec5SDimitry Andric   }
7270b57cec5SDimitry Andric 
7280b57cec5SDimitry Andric   return false;
7290b57cec5SDimitry Andric }
7300b57cec5SDimitry Andric 
7310b57cec5SDimitry Andric bool CXXRecordDecl::lambdaIsDefaultConstructibleAndAssignable() const {
7320b57cec5SDimitry Andric   assert(isLambda() && "not a lambda");
7330b57cec5SDimitry Andric 
7340b57cec5SDimitry Andric   // C++2a [expr.prim.lambda.capture]p11:
7350b57cec5SDimitry Andric   //   The closure type associated with a lambda-expression has no default
7360b57cec5SDimitry Andric   //   constructor if the lambda-expression has a lambda-capture and a
7370b57cec5SDimitry Andric   //   defaulted default constructor otherwise. It has a deleted copy
7380b57cec5SDimitry Andric   //   assignment operator if the lambda-expression has a lambda-capture and
7390b57cec5SDimitry Andric   //   defaulted copy and move assignment operators otherwise.
7400b57cec5SDimitry Andric   //
7410b57cec5SDimitry Andric   // C++17 [expr.prim.lambda]p21:
7420b57cec5SDimitry Andric   //   The closure type associated with a lambda-expression has no default
7430b57cec5SDimitry Andric   //   constructor and a deleted copy assignment operator.
7445f757f3fSDimitry Andric   if (!isCapturelessLambda())
7450b57cec5SDimitry Andric     return false;
7465ffd83dbSDimitry Andric   return getASTContext().getLangOpts().CPlusPlus20;
7470b57cec5SDimitry Andric }
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric void CXXRecordDecl::addedMember(Decl *D) {
7505f757f3fSDimitry Andric   if (!D->isImplicit() && !isa<FieldDecl>(D) && !isa<IndirectFieldDecl>(D) &&
7515f757f3fSDimitry Andric       (!isa<TagDecl>(D) ||
7525f757f3fSDimitry Andric        cast<TagDecl>(D)->getTagKind() == TagTypeKind::Class ||
7535f757f3fSDimitry Andric        cast<TagDecl>(D)->getTagKind() == TagTypeKind::Interface))
7540b57cec5SDimitry Andric     data().HasOnlyCMembers = false;
7550b57cec5SDimitry Andric 
7560b57cec5SDimitry Andric   // Ignore friends and invalid declarations.
7570b57cec5SDimitry Andric   if (D->getFriendObjectKind() || D->isInvalidDecl())
7580b57cec5SDimitry Andric     return;
7590b57cec5SDimitry Andric 
7600b57cec5SDimitry Andric   auto *FunTmpl = dyn_cast<FunctionTemplateDecl>(D);
7610b57cec5SDimitry Andric   if (FunTmpl)
7620b57cec5SDimitry Andric     D = FunTmpl->getTemplatedDecl();
7630b57cec5SDimitry Andric 
7640b57cec5SDimitry Andric   // FIXME: Pass NamedDecl* to addedMember?
7650b57cec5SDimitry Andric   Decl *DUnderlying = D;
7660b57cec5SDimitry Andric   if (auto *ND = dyn_cast<NamedDecl>(DUnderlying)) {
7670b57cec5SDimitry Andric     DUnderlying = ND->getUnderlyingDecl();
7680b57cec5SDimitry Andric     if (auto *UnderlyingFunTmpl = dyn_cast<FunctionTemplateDecl>(DUnderlying))
7690b57cec5SDimitry Andric       DUnderlying = UnderlyingFunTmpl->getTemplatedDecl();
7700b57cec5SDimitry Andric   }
7710b57cec5SDimitry Andric 
7720b57cec5SDimitry Andric   if (const auto *Method = dyn_cast<CXXMethodDecl>(D)) {
7730b57cec5SDimitry Andric     if (Method->isVirtual()) {
7740b57cec5SDimitry Andric       // C++ [dcl.init.aggr]p1:
7750b57cec5SDimitry Andric       //   An aggregate is an array or a class with [...] no virtual functions.
7760b57cec5SDimitry Andric       data().Aggregate = false;
7770b57cec5SDimitry Andric 
7780b57cec5SDimitry Andric       // C++ [class]p4:
7790b57cec5SDimitry Andric       //   A POD-struct is an aggregate class...
7800b57cec5SDimitry Andric       data().PlainOldData = false;
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric       // C++14 [meta.unary.prop]p4:
7830b57cec5SDimitry Andric       //   T is a class type [...] with [...] no virtual member functions...
7840b57cec5SDimitry Andric       data().Empty = false;
7850b57cec5SDimitry Andric 
7860b57cec5SDimitry Andric       // C++ [class.virtual]p1:
7870b57cec5SDimitry Andric       //   A class that declares or inherits a virtual function is called a
7880b57cec5SDimitry Andric       //   polymorphic class.
7890b57cec5SDimitry Andric       data().Polymorphic = true;
7900b57cec5SDimitry Andric 
7910b57cec5SDimitry Andric       // C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25:
7920b57cec5SDimitry Andric       //   A [default constructor, copy/move constructor, or copy/move
7930b57cec5SDimitry Andric       //   assignment operator for a class X] is trivial [...] if:
7940b57cec5SDimitry Andric       //    -- class X has no virtual functions [...]
7950b57cec5SDimitry Andric       data().HasTrivialSpecialMembers &= SMF_Destructor;
7960b57cec5SDimitry Andric       data().HasTrivialSpecialMembersForCall &= SMF_Destructor;
7970b57cec5SDimitry Andric 
7980b57cec5SDimitry Andric       // C++0x [class]p7:
7990b57cec5SDimitry Andric       //   A standard-layout class is a class that: [...]
8000b57cec5SDimitry Andric       //    -- has no virtual functions
8010b57cec5SDimitry Andric       data().IsStandardLayout = false;
8020b57cec5SDimitry Andric       data().IsCXX11StandardLayout = false;
8030b57cec5SDimitry Andric     }
8040b57cec5SDimitry Andric   }
8050b57cec5SDimitry Andric 
8060b57cec5SDimitry Andric   // Notify the listener if an implicit member was added after the definition
8070b57cec5SDimitry Andric   // was completed.
8080b57cec5SDimitry Andric   if (!isBeingDefined() && D->isImplicit())
8090b57cec5SDimitry Andric     if (ASTMutationListener *L = getASTMutationListener())
8100b57cec5SDimitry Andric       L->AddedCXXImplicitMember(data().Definition, D);
8110b57cec5SDimitry Andric 
8120b57cec5SDimitry Andric   // The kind of special member this declaration is, if any.
8130b57cec5SDimitry Andric   unsigned SMKind = 0;
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric   // Handle constructors.
8160b57cec5SDimitry Andric   if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
817480093f4SDimitry Andric     if (Constructor->isInheritingConstructor()) {
818480093f4SDimitry Andric       // Ignore constructor shadow declarations. They are lazily created and
819480093f4SDimitry Andric       // so shouldn't affect any properties of the class.
820480093f4SDimitry Andric     } else {
8210b57cec5SDimitry Andric       if (!Constructor->isImplicit()) {
8220b57cec5SDimitry Andric         // Note that we have a user-declared constructor.
8230b57cec5SDimitry Andric         data().UserDeclaredConstructor = true;
8240b57cec5SDimitry Andric 
825bdd1243dSDimitry Andric         const TargetInfo &TI = getASTContext().getTargetInfo();
826bdd1243dSDimitry Andric         if ((!Constructor->isDeleted() && !Constructor->isDefaulted()) ||
827bdd1243dSDimitry Andric             !TI.areDefaultedSMFStillPOD(getLangOpts())) {
8280b57cec5SDimitry Andric           // C++ [class]p4:
8290b57cec5SDimitry Andric           //   A POD-struct is an aggregate class [...]
830480093f4SDimitry Andric           // Since the POD bit is meant to be C++03 POD-ness, clear it even if
831480093f4SDimitry Andric           // the type is technically an aggregate in C++0x since it wouldn't be
832480093f4SDimitry Andric           // in 03.
8330b57cec5SDimitry Andric           data().PlainOldData = false;
8340b57cec5SDimitry Andric         }
835bdd1243dSDimitry Andric       }
8360b57cec5SDimitry Andric 
8370b57cec5SDimitry Andric       if (Constructor->isDefaultConstructor()) {
8380b57cec5SDimitry Andric         SMKind |= SMF_DefaultConstructor;
8390b57cec5SDimitry Andric 
8400b57cec5SDimitry Andric         if (Constructor->isUserProvided())
8410b57cec5SDimitry Andric           data().UserProvidedDefaultConstructor = true;
8420b57cec5SDimitry Andric         if (Constructor->isConstexpr())
8430b57cec5SDimitry Andric           data().HasConstexprDefaultConstructor = true;
8440b57cec5SDimitry Andric         if (Constructor->isDefaulted())
8450b57cec5SDimitry Andric           data().HasDefaultedDefaultConstructor = true;
8460b57cec5SDimitry Andric       }
8470b57cec5SDimitry Andric 
8480b57cec5SDimitry Andric       if (!FunTmpl) {
8490b57cec5SDimitry Andric         unsigned Quals;
8500b57cec5SDimitry Andric         if (Constructor->isCopyConstructor(Quals)) {
8510b57cec5SDimitry Andric           SMKind |= SMF_CopyConstructor;
8520b57cec5SDimitry Andric 
8530b57cec5SDimitry Andric           if (Quals & Qualifiers::Const)
8540b57cec5SDimitry Andric             data().HasDeclaredCopyConstructorWithConstParam = true;
8550b57cec5SDimitry Andric         } else if (Constructor->isMoveConstructor())
8560b57cec5SDimitry Andric           SMKind |= SMF_MoveConstructor;
8570b57cec5SDimitry Andric       }
8580b57cec5SDimitry Andric 
8590b57cec5SDimitry Andric       // C++11 [dcl.init.aggr]p1: DR1518
8600b57cec5SDimitry Andric       //   An aggregate is an array or a class with no user-provided [or]
8610b57cec5SDimitry Andric       //   explicit [...] constructors
8620b57cec5SDimitry Andric       // C++20 [dcl.init.aggr]p1:
8630b57cec5SDimitry Andric       //   An aggregate is an array or a class with no user-declared [...]
8640b57cec5SDimitry Andric       //   constructors
8655ffd83dbSDimitry Andric       if (getASTContext().getLangOpts().CPlusPlus20
8660b57cec5SDimitry Andric               ? !Constructor->isImplicit()
8670b57cec5SDimitry Andric               : (Constructor->isUserProvided() || Constructor->isExplicit()))
8680b57cec5SDimitry Andric         data().Aggregate = false;
8690b57cec5SDimitry Andric     }
870480093f4SDimitry Andric   }
8710b57cec5SDimitry Andric 
8720b57cec5SDimitry Andric   // Handle constructors, including those inherited from base classes.
8730b57cec5SDimitry Andric   if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(DUnderlying)) {
8740b57cec5SDimitry Andric     // Record if we see any constexpr constructors which are neither copy
8750b57cec5SDimitry Andric     // nor move constructors.
8760b57cec5SDimitry Andric     // C++1z [basic.types]p10:
8770b57cec5SDimitry Andric     //   [...] has at least one constexpr constructor or constructor template
8780b57cec5SDimitry Andric     //   (possibly inherited from a base class) that is not a copy or move
8790b57cec5SDimitry Andric     //   constructor [...]
8800b57cec5SDimitry Andric     if (Constructor->isConstexpr() && !Constructor->isCopyOrMoveConstructor())
8810b57cec5SDimitry Andric       data().HasConstexprNonCopyMoveConstructor = true;
882e8d8bef9SDimitry Andric     if (!isa<CXXConstructorDecl>(D) && Constructor->isDefaultConstructor())
883e8d8bef9SDimitry Andric       data().HasInheritedDefaultConstructor = true;
8840b57cec5SDimitry Andric   }
8850b57cec5SDimitry Andric 
8860b57cec5SDimitry Andric   // Handle member functions.
8870b57cec5SDimitry Andric   if (const auto *Method = dyn_cast<CXXMethodDecl>(D)) {
88881ad6265SDimitry Andric     if (isa<CXXDestructorDecl>(D))
88981ad6265SDimitry Andric       SMKind |= SMF_Destructor;
89081ad6265SDimitry Andric 
8910b57cec5SDimitry Andric     if (Method->isCopyAssignmentOperator()) {
8920b57cec5SDimitry Andric       SMKind |= SMF_CopyAssignment;
8930b57cec5SDimitry Andric 
8940b57cec5SDimitry Andric       const auto *ParamTy =
8955f757f3fSDimitry Andric           Method->getNonObjectParameter(0)->getType()->getAs<ReferenceType>();
8960b57cec5SDimitry Andric       if (!ParamTy || ParamTy->getPointeeType().isConstQualified())
8970b57cec5SDimitry Andric         data().HasDeclaredCopyAssignmentWithConstParam = true;
8980b57cec5SDimitry Andric     }
8990b57cec5SDimitry Andric 
9000b57cec5SDimitry Andric     if (Method->isMoveAssignmentOperator())
9010b57cec5SDimitry Andric       SMKind |= SMF_MoveAssignment;
9020b57cec5SDimitry Andric 
9030b57cec5SDimitry Andric     // Keep the list of conversion functions up-to-date.
9040b57cec5SDimitry Andric     if (auto *Conversion = dyn_cast<CXXConversionDecl>(D)) {
9050b57cec5SDimitry Andric       // FIXME: We use the 'unsafe' accessor for the access specifier here,
9060b57cec5SDimitry Andric       // because Sema may not have set it yet. That's really just a misdesign
9070b57cec5SDimitry Andric       // in Sema. However, LLDB *will* have set the access specifier correctly,
9080b57cec5SDimitry Andric       // and adds declarations after the class is technically completed,
9090b57cec5SDimitry Andric       // so completeDefinition()'s overriding of the access specifiers doesn't
9100b57cec5SDimitry Andric       // work.
9110b57cec5SDimitry Andric       AccessSpecifier AS = Conversion->getAccessUnsafe();
9120b57cec5SDimitry Andric 
9130b57cec5SDimitry Andric       if (Conversion->getPrimaryTemplate()) {
9140b57cec5SDimitry Andric         // We don't record specializations.
9150b57cec5SDimitry Andric       } else {
9160b57cec5SDimitry Andric         ASTContext &Ctx = getASTContext();
9170b57cec5SDimitry Andric         ASTUnresolvedSet &Conversions = data().Conversions.get(Ctx);
9180b57cec5SDimitry Andric         NamedDecl *Primary =
9190b57cec5SDimitry Andric             FunTmpl ? cast<NamedDecl>(FunTmpl) : cast<NamedDecl>(Conversion);
9200b57cec5SDimitry Andric         if (Primary->getPreviousDecl())
9210b57cec5SDimitry Andric           Conversions.replace(cast<NamedDecl>(Primary->getPreviousDecl()),
9220b57cec5SDimitry Andric                               Primary, AS);
9230b57cec5SDimitry Andric         else
9240b57cec5SDimitry Andric           Conversions.addDecl(Ctx, Primary, AS);
9250b57cec5SDimitry Andric       }
9260b57cec5SDimitry Andric     }
9270b57cec5SDimitry Andric 
9280b57cec5SDimitry Andric     if (SMKind) {
9290b57cec5SDimitry Andric       // If this is the first declaration of a special member, we no longer have
9300b57cec5SDimitry Andric       // an implicit trivial special member.
9310b57cec5SDimitry Andric       data().HasTrivialSpecialMembers &=
9320b57cec5SDimitry Andric           data().DeclaredSpecialMembers | ~SMKind;
9330b57cec5SDimitry Andric       data().HasTrivialSpecialMembersForCall &=
9340b57cec5SDimitry Andric           data().DeclaredSpecialMembers | ~SMKind;
9350b57cec5SDimitry Andric 
9360b57cec5SDimitry Andric       // Note when we have declared a declared special member, and suppress the
9370b57cec5SDimitry Andric       // implicit declaration of this special member.
9380b57cec5SDimitry Andric       data().DeclaredSpecialMembers |= SMKind;
9390b57cec5SDimitry Andric       if (!Method->isImplicit()) {
9400b57cec5SDimitry Andric         data().UserDeclaredSpecialMembers |= SMKind;
9410b57cec5SDimitry Andric 
942bdd1243dSDimitry Andric         const TargetInfo &TI = getASTContext().getTargetInfo();
943bdd1243dSDimitry Andric         if ((!Method->isDeleted() && !Method->isDefaulted() &&
944bdd1243dSDimitry Andric              SMKind != SMF_MoveAssignment) ||
945bdd1243dSDimitry Andric             !TI.areDefaultedSMFStillPOD(getLangOpts())) {
9460b57cec5SDimitry Andric           // C++03 [class]p4:
9470b57cec5SDimitry Andric           //   A POD-struct is an aggregate class that has [...] no user-defined
9480b57cec5SDimitry Andric           //   copy assignment operator and no user-defined destructor.
9490b57cec5SDimitry Andric           //
9500b57cec5SDimitry Andric           // Since the POD bit is meant to be C++03 POD-ness, and in C++03,
9510b57cec5SDimitry Andric           // aggregates could not have any constructors, clear it even for an
9520b57cec5SDimitry Andric           // explicitly defaulted or deleted constructor.
953bdd1243dSDimitry Andric           // type is technically an aggregate in C++0x since it wouldn't be in
954bdd1243dSDimitry Andric           // 03.
9550b57cec5SDimitry Andric           //
956bdd1243dSDimitry Andric           // Also, a user-declared move assignment operator makes a class
957bdd1243dSDimitry Andric           // non-POD. This is an extension in C++03.
9580b57cec5SDimitry Andric           data().PlainOldData = false;
9590b57cec5SDimitry Andric         }
960bdd1243dSDimitry Andric       }
961bdd1243dSDimitry Andric       // When instantiating a class, we delay updating the destructor and
962bdd1243dSDimitry Andric       // triviality properties of the class until selecting a destructor and
963bdd1243dSDimitry Andric       // computing the eligibility of its special member functions. This is
964bdd1243dSDimitry Andric       // because there might be function constraints that we need to evaluate
965bdd1243dSDimitry Andric       // and compare later in the instantiation.
96681ad6265SDimitry Andric       if (!Method->isIneligibleOrNotSelected()) {
96781ad6265SDimitry Andric         addedEligibleSpecialMemberFunction(Method, SMKind);
96881ad6265SDimitry Andric       }
9690b57cec5SDimitry Andric     }
9700b57cec5SDimitry Andric 
9710b57cec5SDimitry Andric     return;
9720b57cec5SDimitry Andric   }
9730b57cec5SDimitry Andric 
9740b57cec5SDimitry Andric   // Handle non-static data members.
9750b57cec5SDimitry Andric   if (const auto *Field = dyn_cast<FieldDecl>(D)) {
9760b57cec5SDimitry Andric     ASTContext &Context = getASTContext();
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric     // C++2a [class]p7:
9790b57cec5SDimitry Andric     //   A standard-layout class is a class that:
9800b57cec5SDimitry Andric     //    [...]
9810b57cec5SDimitry Andric     //    -- has all non-static data members and bit-fields in the class and
9820b57cec5SDimitry Andric     //       its base classes first declared in the same class
9830b57cec5SDimitry Andric     if (data().HasBasesWithFields)
9840b57cec5SDimitry Andric       data().IsStandardLayout = false;
9850b57cec5SDimitry Andric 
9860b57cec5SDimitry Andric     // C++ [class.bit]p2:
9870b57cec5SDimitry Andric     //   A declaration for a bit-field that omits the identifier declares an
9880b57cec5SDimitry Andric     //   unnamed bit-field. Unnamed bit-fields are not members and cannot be
9890b57cec5SDimitry Andric     //   initialized.
9900fca6ea1SDimitry Andric     if (Field->isUnnamedBitField()) {
9910b57cec5SDimitry Andric       // C++ [meta.unary.prop]p4: [LWG2358]
9920b57cec5SDimitry Andric       //   T is a class type [...] with [...] no unnamed bit-fields of non-zero
9930b57cec5SDimitry Andric       //   length
9940b57cec5SDimitry Andric       if (data().Empty && !Field->isZeroLengthBitField(Context) &&
9950b57cec5SDimitry Andric           Context.getLangOpts().getClangABICompat() >
9960b57cec5SDimitry Andric               LangOptions::ClangABI::Ver6)
9970b57cec5SDimitry Andric         data().Empty = false;
9980b57cec5SDimitry Andric       return;
9990b57cec5SDimitry Andric     }
10000b57cec5SDimitry Andric 
10010b57cec5SDimitry Andric     // C++11 [class]p7:
10020b57cec5SDimitry Andric     //   A standard-layout class is a class that:
10030b57cec5SDimitry Andric     //    -- either has no non-static data members in the most derived class
10040b57cec5SDimitry Andric     //       [...] or has no base classes with non-static data members
10050b57cec5SDimitry Andric     if (data().HasBasesWithNonStaticDataMembers)
10060b57cec5SDimitry Andric       data().IsCXX11StandardLayout = false;
10070b57cec5SDimitry Andric 
10080b57cec5SDimitry Andric     // C++ [dcl.init.aggr]p1:
10090b57cec5SDimitry Andric     //   An aggregate is an array or a class (clause 9) with [...] no
10100b57cec5SDimitry Andric     //   private or protected non-static data members (clause 11).
10110b57cec5SDimitry Andric     //
10120b57cec5SDimitry Andric     // A POD must be an aggregate.
10130b57cec5SDimitry Andric     if (D->getAccess() == AS_private || D->getAccess() == AS_protected) {
10140b57cec5SDimitry Andric       data().Aggregate = false;
10150b57cec5SDimitry Andric       data().PlainOldData = false;
1016e8d8bef9SDimitry Andric 
1017e8d8bef9SDimitry Andric       // C++20 [temp.param]p7:
1018e8d8bef9SDimitry Andric       //   A structural type is [...] a literal class type [for which] all
1019e8d8bef9SDimitry Andric       //   non-static data members are public
1020e8d8bef9SDimitry Andric       data().StructuralIfLiteral = false;
10210b57cec5SDimitry Andric     }
10220b57cec5SDimitry Andric 
10230b57cec5SDimitry Andric     // Track whether this is the first field. We use this when checking
10240b57cec5SDimitry Andric     // whether the class is standard-layout below.
10250b57cec5SDimitry Andric     bool IsFirstField = !data().HasPrivateFields &&
10260b57cec5SDimitry Andric                         !data().HasProtectedFields && !data().HasPublicFields;
10270b57cec5SDimitry Andric 
10280b57cec5SDimitry Andric     // C++0x [class]p7:
10290b57cec5SDimitry Andric     //   A standard-layout class is a class that:
10300b57cec5SDimitry Andric     //    [...]
10310b57cec5SDimitry Andric     //    -- has the same access control for all non-static data members,
10320b57cec5SDimitry Andric     switch (D->getAccess()) {
10330b57cec5SDimitry Andric     case AS_private:    data().HasPrivateFields = true;   break;
10340b57cec5SDimitry Andric     case AS_protected:  data().HasProtectedFields = true; break;
10350b57cec5SDimitry Andric     case AS_public:     data().HasPublicFields = true;    break;
10360b57cec5SDimitry Andric     case AS_none:       llvm_unreachable("Invalid access specifier");
10370b57cec5SDimitry Andric     };
10380b57cec5SDimitry Andric     if ((data().HasPrivateFields + data().HasProtectedFields +
10390b57cec5SDimitry Andric          data().HasPublicFields) > 1) {
10400b57cec5SDimitry Andric       data().IsStandardLayout = false;
10410b57cec5SDimitry Andric       data().IsCXX11StandardLayout = false;
10420b57cec5SDimitry Andric     }
10430b57cec5SDimitry Andric 
10440b57cec5SDimitry Andric     // Keep track of the presence of mutable fields.
1045e8d8bef9SDimitry Andric     if (Field->isMutable()) {
10460b57cec5SDimitry Andric       data().HasMutableFields = true;
10470b57cec5SDimitry Andric 
1048e8d8bef9SDimitry Andric       // C++20 [temp.param]p7:
1049e8d8bef9SDimitry Andric       //   A structural type is [...] a literal class type [for which] all
1050e8d8bef9SDimitry Andric       //   non-static data members are public
1051e8d8bef9SDimitry Andric       data().StructuralIfLiteral = false;
1052e8d8bef9SDimitry Andric     }
1053e8d8bef9SDimitry Andric 
10540b57cec5SDimitry Andric     // C++11 [class.union]p8, DR1460:
10550b57cec5SDimitry Andric     //   If X is a union, a non-static data member of X that is not an anonymous
10560b57cec5SDimitry Andric     //   union is a variant member of X.
10570b57cec5SDimitry Andric     if (isUnion() && !Field->isAnonymousStructOrUnion())
10580b57cec5SDimitry Andric       data().HasVariantMembers = true;
10590b57cec5SDimitry Andric 
10600b57cec5SDimitry Andric     // C++0x [class]p9:
10610b57cec5SDimitry Andric     //   A POD struct is a class that is both a trivial class and a
10620b57cec5SDimitry Andric     //   standard-layout class, and has no non-static data members of type
10630b57cec5SDimitry Andric     //   non-POD struct, non-POD union (or array of such types).
10640b57cec5SDimitry Andric     //
10650b57cec5SDimitry Andric     // Automatic Reference Counting: the presence of a member of Objective-C pointer type
10660b57cec5SDimitry Andric     // that does not explicitly have no lifetime makes the class a non-POD.
10670b57cec5SDimitry Andric     QualType T = Context.getBaseElementType(Field->getType());
10680b57cec5SDimitry Andric     if (T->isObjCRetainableType() || T.isObjCGCStrong()) {
10690b57cec5SDimitry Andric       if (T.hasNonTrivialObjCLifetime()) {
10700b57cec5SDimitry Andric         // Objective-C Automatic Reference Counting:
10710b57cec5SDimitry Andric         //   If a class has a non-static data member of Objective-C pointer
10720b57cec5SDimitry Andric         //   type (or array thereof), it is a non-POD type and its
10730b57cec5SDimitry Andric         //   default constructor (if any), copy constructor, move constructor,
10740b57cec5SDimitry Andric         //   copy assignment operator, move assignment operator, and destructor are
10750b57cec5SDimitry Andric         //   non-trivial.
10760b57cec5SDimitry Andric         setHasObjectMember(true);
10770b57cec5SDimitry Andric         struct DefinitionData &Data = data();
10780b57cec5SDimitry Andric         Data.PlainOldData = false;
10790b57cec5SDimitry Andric         Data.HasTrivialSpecialMembers = 0;
10800b57cec5SDimitry Andric 
10810b57cec5SDimitry Andric         // __strong or __weak fields do not make special functions non-trivial
10820b57cec5SDimitry Andric         // for the purpose of calls.
10830b57cec5SDimitry Andric         Qualifiers::ObjCLifetime LT = T.getQualifiers().getObjCLifetime();
10840b57cec5SDimitry Andric         if (LT != Qualifiers::OCL_Strong && LT != Qualifiers::OCL_Weak)
10850b57cec5SDimitry Andric           data().HasTrivialSpecialMembersForCall = 0;
10860b57cec5SDimitry Andric 
10870b57cec5SDimitry Andric         // Structs with __weak fields should never be passed directly.
10880b57cec5SDimitry Andric         if (LT == Qualifiers::OCL_Weak)
10895f757f3fSDimitry Andric           setArgPassingRestrictions(RecordArgPassingKind::CanNeverPassInRegs);
10900b57cec5SDimitry Andric 
10910b57cec5SDimitry Andric         Data.HasIrrelevantDestructor = false;
10920b57cec5SDimitry Andric 
10930b57cec5SDimitry Andric         if (isUnion()) {
10940b57cec5SDimitry Andric           data().DefaultedCopyConstructorIsDeleted = true;
10950b57cec5SDimitry Andric           data().DefaultedMoveConstructorIsDeleted = true;
10965ffd83dbSDimitry Andric           data().DefaultedCopyAssignmentIsDeleted = true;
10970b57cec5SDimitry Andric           data().DefaultedMoveAssignmentIsDeleted = true;
10980b57cec5SDimitry Andric           data().DefaultedDestructorIsDeleted = true;
10990b57cec5SDimitry Andric           data().NeedOverloadResolutionForCopyConstructor = true;
11000b57cec5SDimitry Andric           data().NeedOverloadResolutionForMoveConstructor = true;
11015ffd83dbSDimitry Andric           data().NeedOverloadResolutionForCopyAssignment = true;
11020b57cec5SDimitry Andric           data().NeedOverloadResolutionForMoveAssignment = true;
11030b57cec5SDimitry Andric           data().NeedOverloadResolutionForDestructor = true;
11040b57cec5SDimitry Andric         }
11050b57cec5SDimitry Andric       } else if (!Context.getLangOpts().ObjCAutoRefCount) {
11060b57cec5SDimitry Andric         setHasObjectMember(true);
11070b57cec5SDimitry Andric       }
11080b57cec5SDimitry Andric     } else if (!T.isCXX98PODType(Context))
11090b57cec5SDimitry Andric       data().PlainOldData = false;
11100b57cec5SDimitry Andric 
11110b57cec5SDimitry Andric     if (T->isReferenceType()) {
11120b57cec5SDimitry Andric       if (!Field->hasInClassInitializer())
11130b57cec5SDimitry Andric         data().HasUninitializedReferenceMember = true;
11140b57cec5SDimitry Andric 
11150b57cec5SDimitry Andric       // C++0x [class]p7:
11160b57cec5SDimitry Andric       //   A standard-layout class is a class that:
11170b57cec5SDimitry Andric       //    -- has no non-static data members of type [...] reference,
11180b57cec5SDimitry Andric       data().IsStandardLayout = false;
11190b57cec5SDimitry Andric       data().IsCXX11StandardLayout = false;
11200b57cec5SDimitry Andric 
11210b57cec5SDimitry Andric       // C++1z [class.copy.ctor]p10:
11220b57cec5SDimitry Andric       //   A defaulted copy constructor for a class X is defined as deleted if X has:
11230b57cec5SDimitry Andric       //    -- a non-static data member of rvalue reference type
11240b57cec5SDimitry Andric       if (T->isRValueReferenceType())
11250b57cec5SDimitry Andric         data().DefaultedCopyConstructorIsDeleted = true;
11260b57cec5SDimitry Andric     }
11270b57cec5SDimitry Andric 
11280b57cec5SDimitry Andric     if (!Field->hasInClassInitializer() && !Field->isMutable()) {
11290b57cec5SDimitry Andric       if (CXXRecordDecl *FieldType = T->getAsCXXRecordDecl()) {
11300b57cec5SDimitry Andric         if (FieldType->hasDefinition() && !FieldType->allowConstDefaultInit())
11310b57cec5SDimitry Andric           data().HasUninitializedFields = true;
11320b57cec5SDimitry Andric       } else {
11330b57cec5SDimitry Andric         data().HasUninitializedFields = true;
11340b57cec5SDimitry Andric       }
11350b57cec5SDimitry Andric     }
11360b57cec5SDimitry Andric 
11370b57cec5SDimitry Andric     // Record if this field is the first non-literal or volatile field or base.
11380b57cec5SDimitry Andric     if (!T->isLiteralType(Context) || T.isVolatileQualified())
11390b57cec5SDimitry Andric       data().HasNonLiteralTypeFieldsOrBases = true;
11400b57cec5SDimitry Andric 
11410b57cec5SDimitry Andric     if (Field->hasInClassInitializer() ||
11420b57cec5SDimitry Andric         (Field->isAnonymousStructOrUnion() &&
11430b57cec5SDimitry Andric          Field->getType()->getAsCXXRecordDecl()->hasInClassInitializer())) {
11440b57cec5SDimitry Andric       data().HasInClassInitializer = true;
11450b57cec5SDimitry Andric 
11460b57cec5SDimitry Andric       // C++11 [class]p5:
11470b57cec5SDimitry Andric       //   A default constructor is trivial if [...] no non-static data member
11480b57cec5SDimitry Andric       //   of its class has a brace-or-equal-initializer.
11490b57cec5SDimitry Andric       data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor;
11500b57cec5SDimitry Andric 
11510b57cec5SDimitry Andric       // C++11 [dcl.init.aggr]p1:
11520b57cec5SDimitry Andric       //   An aggregate is a [...] class with [...] no
11530b57cec5SDimitry Andric       //   brace-or-equal-initializers for non-static data members.
11540b57cec5SDimitry Andric       //
11550b57cec5SDimitry Andric       // This rule was removed in C++14.
11560b57cec5SDimitry Andric       if (!getASTContext().getLangOpts().CPlusPlus14)
11570b57cec5SDimitry Andric         data().Aggregate = false;
11580b57cec5SDimitry Andric 
11590b57cec5SDimitry Andric       // C++11 [class]p10:
11600b57cec5SDimitry Andric       //   A POD struct is [...] a trivial class.
11610b57cec5SDimitry Andric       data().PlainOldData = false;
11620b57cec5SDimitry Andric     }
11630b57cec5SDimitry Andric 
11640b57cec5SDimitry Andric     // C++11 [class.copy]p23:
11650b57cec5SDimitry Andric     //   A defaulted copy/move assignment operator for a class X is defined
11660b57cec5SDimitry Andric     //   as deleted if X has:
11670b57cec5SDimitry Andric     //    -- a non-static data member of reference type
11685ffd83dbSDimitry Andric     if (T->isReferenceType()) {
11695ffd83dbSDimitry Andric       data().DefaultedCopyAssignmentIsDeleted = true;
11700b57cec5SDimitry Andric       data().DefaultedMoveAssignmentIsDeleted = true;
11715ffd83dbSDimitry Andric     }
11720b57cec5SDimitry Andric 
11730b57cec5SDimitry Andric     // Bitfields of length 0 are also zero-sized, but we already bailed out for
11740b57cec5SDimitry Andric     // those because they are always unnamed.
11750b57cec5SDimitry Andric     bool IsZeroSize = Field->isZeroSize(Context);
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric     if (const auto *RecordTy = T->getAs<RecordType>()) {
11780b57cec5SDimitry Andric       auto *FieldRec = cast<CXXRecordDecl>(RecordTy->getDecl());
11790b57cec5SDimitry Andric       if (FieldRec->getDefinition()) {
11800b57cec5SDimitry Andric         addedClassSubobject(FieldRec);
11810b57cec5SDimitry Andric 
11820b57cec5SDimitry Andric         // We may need to perform overload resolution to determine whether a
11830b57cec5SDimitry Andric         // field can be moved if it's const or volatile qualified.
11840b57cec5SDimitry Andric         if (T.getCVRQualifiers() & (Qualifiers::Const | Qualifiers::Volatile)) {
11850b57cec5SDimitry Andric           // We need to care about 'const' for the copy constructor because an
11860b57cec5SDimitry Andric           // implicit copy constructor might be declared with a non-const
11870b57cec5SDimitry Andric           // parameter.
11880b57cec5SDimitry Andric           data().NeedOverloadResolutionForCopyConstructor = true;
11890b57cec5SDimitry Andric           data().NeedOverloadResolutionForMoveConstructor = true;
11905ffd83dbSDimitry Andric           data().NeedOverloadResolutionForCopyAssignment = true;
11910b57cec5SDimitry Andric           data().NeedOverloadResolutionForMoveAssignment = true;
11920b57cec5SDimitry Andric         }
11930b57cec5SDimitry Andric 
11940b57cec5SDimitry Andric         // C++11 [class.ctor]p5, C++11 [class.copy]p11:
11950b57cec5SDimitry Andric         //   A defaulted [special member] for a class X is defined as
11960b57cec5SDimitry Andric         //   deleted if:
11970b57cec5SDimitry Andric         //    -- X is a union-like class that has a variant member with a
11980b57cec5SDimitry Andric         //       non-trivial [corresponding special member]
11990b57cec5SDimitry Andric         if (isUnion()) {
12000b57cec5SDimitry Andric           if (FieldRec->hasNonTrivialCopyConstructor())
12010b57cec5SDimitry Andric             data().DefaultedCopyConstructorIsDeleted = true;
12020b57cec5SDimitry Andric           if (FieldRec->hasNonTrivialMoveConstructor())
12030b57cec5SDimitry Andric             data().DefaultedMoveConstructorIsDeleted = true;
12045ffd83dbSDimitry Andric           if (FieldRec->hasNonTrivialCopyAssignment())
12055ffd83dbSDimitry Andric             data().DefaultedCopyAssignmentIsDeleted = true;
12060b57cec5SDimitry Andric           if (FieldRec->hasNonTrivialMoveAssignment())
12070b57cec5SDimitry Andric             data().DefaultedMoveAssignmentIsDeleted = true;
12080b57cec5SDimitry Andric           if (FieldRec->hasNonTrivialDestructor())
12090b57cec5SDimitry Andric             data().DefaultedDestructorIsDeleted = true;
12100b57cec5SDimitry Andric         }
12110b57cec5SDimitry Andric 
12120b57cec5SDimitry Andric         // For an anonymous union member, our overload resolution will perform
12130b57cec5SDimitry Andric         // overload resolution for its members.
12140b57cec5SDimitry Andric         if (Field->isAnonymousStructOrUnion()) {
12150b57cec5SDimitry Andric           data().NeedOverloadResolutionForCopyConstructor |=
12160b57cec5SDimitry Andric               FieldRec->data().NeedOverloadResolutionForCopyConstructor;
12170b57cec5SDimitry Andric           data().NeedOverloadResolutionForMoveConstructor |=
12180b57cec5SDimitry Andric               FieldRec->data().NeedOverloadResolutionForMoveConstructor;
12195ffd83dbSDimitry Andric           data().NeedOverloadResolutionForCopyAssignment |=
12205ffd83dbSDimitry Andric               FieldRec->data().NeedOverloadResolutionForCopyAssignment;
12210b57cec5SDimitry Andric           data().NeedOverloadResolutionForMoveAssignment |=
12220b57cec5SDimitry Andric               FieldRec->data().NeedOverloadResolutionForMoveAssignment;
12230b57cec5SDimitry Andric           data().NeedOverloadResolutionForDestructor |=
12240b57cec5SDimitry Andric               FieldRec->data().NeedOverloadResolutionForDestructor;
12250b57cec5SDimitry Andric         }
12260b57cec5SDimitry Andric 
12270b57cec5SDimitry Andric         // C++0x [class.ctor]p5:
12280b57cec5SDimitry Andric         //   A default constructor is trivial [...] if:
12290b57cec5SDimitry Andric         //    -- for all the non-static data members of its class that are of
12300b57cec5SDimitry Andric         //       class type (or array thereof), each such class has a trivial
12310b57cec5SDimitry Andric         //       default constructor.
12320b57cec5SDimitry Andric         if (!FieldRec->hasTrivialDefaultConstructor())
12330b57cec5SDimitry Andric           data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor;
12340b57cec5SDimitry Andric 
12350b57cec5SDimitry Andric         // C++0x [class.copy]p13:
12360b57cec5SDimitry Andric         //   A copy/move constructor for class X is trivial if [...]
12370b57cec5SDimitry Andric         //    [...]
12380b57cec5SDimitry Andric         //    -- for each non-static data member of X that is of class type (or
12390b57cec5SDimitry Andric         //       an array thereof), the constructor selected to copy/move that
12400b57cec5SDimitry Andric         //       member is trivial;
12410b57cec5SDimitry Andric         if (!FieldRec->hasTrivialCopyConstructor())
12420b57cec5SDimitry Andric           data().HasTrivialSpecialMembers &= ~SMF_CopyConstructor;
12430b57cec5SDimitry Andric 
12440b57cec5SDimitry Andric         if (!FieldRec->hasTrivialCopyConstructorForCall())
12450b57cec5SDimitry Andric           data().HasTrivialSpecialMembersForCall &= ~SMF_CopyConstructor;
12460b57cec5SDimitry Andric 
12470b57cec5SDimitry Andric         // If the field doesn't have a simple move constructor, we'll eagerly
12480b57cec5SDimitry Andric         // declare the move constructor for this class and we'll decide whether
12490b57cec5SDimitry Andric         // it's trivial then.
12500b57cec5SDimitry Andric         if (!FieldRec->hasTrivialMoveConstructor())
12510b57cec5SDimitry Andric           data().HasTrivialSpecialMembers &= ~SMF_MoveConstructor;
12520b57cec5SDimitry Andric 
12530b57cec5SDimitry Andric         if (!FieldRec->hasTrivialMoveConstructorForCall())
12540b57cec5SDimitry Andric           data().HasTrivialSpecialMembersForCall &= ~SMF_MoveConstructor;
12550b57cec5SDimitry Andric 
12560b57cec5SDimitry Andric         // C++0x [class.copy]p27:
12570b57cec5SDimitry Andric         //   A copy/move assignment operator for class X is trivial if [...]
12580b57cec5SDimitry Andric         //    [...]
12590b57cec5SDimitry Andric         //    -- for each non-static data member of X that is of class type (or
12600b57cec5SDimitry Andric         //       an array thereof), the assignment operator selected to
12610b57cec5SDimitry Andric         //       copy/move that member is trivial;
12620b57cec5SDimitry Andric         if (!FieldRec->hasTrivialCopyAssignment())
12630b57cec5SDimitry Andric           data().HasTrivialSpecialMembers &= ~SMF_CopyAssignment;
12640b57cec5SDimitry Andric         // If the field doesn't have a simple move assignment, we'll eagerly
12650b57cec5SDimitry Andric         // declare the move assignment for this class and we'll decide whether
12660b57cec5SDimitry Andric         // it's trivial then.
12670b57cec5SDimitry Andric         if (!FieldRec->hasTrivialMoveAssignment())
12680b57cec5SDimitry Andric           data().HasTrivialSpecialMembers &= ~SMF_MoveAssignment;
12690b57cec5SDimitry Andric 
12700b57cec5SDimitry Andric         if (!FieldRec->hasTrivialDestructor())
12710b57cec5SDimitry Andric           data().HasTrivialSpecialMembers &= ~SMF_Destructor;
12720b57cec5SDimitry Andric         if (!FieldRec->hasTrivialDestructorForCall())
12730b57cec5SDimitry Andric           data().HasTrivialSpecialMembersForCall &= ~SMF_Destructor;
12740b57cec5SDimitry Andric         if (!FieldRec->hasIrrelevantDestructor())
12750b57cec5SDimitry Andric           data().HasIrrelevantDestructor = false;
1276fe6060f1SDimitry Andric         if (FieldRec->isAnyDestructorNoReturn())
1277fe6060f1SDimitry Andric           data().IsAnyDestructorNoReturn = true;
12780b57cec5SDimitry Andric         if (FieldRec->hasObjectMember())
12790b57cec5SDimitry Andric           setHasObjectMember(true);
12800b57cec5SDimitry Andric         if (FieldRec->hasVolatileMember())
12810b57cec5SDimitry Andric           setHasVolatileMember(true);
12820b57cec5SDimitry Andric         if (FieldRec->getArgPassingRestrictions() ==
12835f757f3fSDimitry Andric             RecordArgPassingKind::CanNeverPassInRegs)
12845f757f3fSDimitry Andric           setArgPassingRestrictions(RecordArgPassingKind::CanNeverPassInRegs);
12850b57cec5SDimitry Andric 
12860b57cec5SDimitry Andric         // C++0x [class]p7:
12870b57cec5SDimitry Andric         //   A standard-layout class is a class that:
12880b57cec5SDimitry Andric         //    -- has no non-static data members of type non-standard-layout
12890b57cec5SDimitry Andric         //       class (or array of such types) [...]
12900b57cec5SDimitry Andric         if (!FieldRec->isStandardLayout())
12910b57cec5SDimitry Andric           data().IsStandardLayout = false;
12920b57cec5SDimitry Andric         if (!FieldRec->isCXX11StandardLayout())
12930b57cec5SDimitry Andric           data().IsCXX11StandardLayout = false;
12940b57cec5SDimitry Andric 
12950b57cec5SDimitry Andric         // C++2a [class]p7:
12960b57cec5SDimitry Andric         //   A standard-layout class is a class that:
12970b57cec5SDimitry Andric         //    [...]
12980b57cec5SDimitry Andric         //    -- has no element of the set M(S) of types as a base class.
12990b57cec5SDimitry Andric         if (data().IsStandardLayout &&
13000b57cec5SDimitry Andric             (isUnion() || IsFirstField || IsZeroSize) &&
13010b57cec5SDimitry Andric             hasSubobjectAtOffsetZeroOfEmptyBaseType(Context, FieldRec))
13020b57cec5SDimitry Andric           data().IsStandardLayout = false;
13030b57cec5SDimitry Andric 
13040b57cec5SDimitry Andric         // C++11 [class]p7:
13050b57cec5SDimitry Andric         //   A standard-layout class is a class that:
13060b57cec5SDimitry Andric         //    -- has no base classes of the same type as the first non-static
13070b57cec5SDimitry Andric         //       data member
13080b57cec5SDimitry Andric         if (data().IsCXX11StandardLayout && IsFirstField) {
13090b57cec5SDimitry Andric           // FIXME: We should check all base classes here, not just direct
13100b57cec5SDimitry Andric           // base classes.
13110b57cec5SDimitry Andric           for (const auto &BI : bases()) {
13120b57cec5SDimitry Andric             if (Context.hasSameUnqualifiedType(BI.getType(), T)) {
13130b57cec5SDimitry Andric               data().IsCXX11StandardLayout = false;
13140b57cec5SDimitry Andric               break;
13150b57cec5SDimitry Andric             }
13160b57cec5SDimitry Andric           }
13170b57cec5SDimitry Andric         }
13180b57cec5SDimitry Andric 
13190b57cec5SDimitry Andric         // Keep track of the presence of mutable fields.
13205ffd83dbSDimitry Andric         if (FieldRec->hasMutableFields())
13210b57cec5SDimitry Andric           data().HasMutableFields = true;
13225ffd83dbSDimitry Andric 
13235ffd83dbSDimitry Andric         if (Field->isMutable()) {
13245ffd83dbSDimitry Andric           // Our copy constructor/assignment might call something other than
13255ffd83dbSDimitry Andric           // the subobject's copy constructor/assignment if it's mutable and of
13265ffd83dbSDimitry Andric           // class type.
13270b57cec5SDimitry Andric           data().NeedOverloadResolutionForCopyConstructor = true;
13285ffd83dbSDimitry Andric           data().NeedOverloadResolutionForCopyAssignment = true;
13290b57cec5SDimitry Andric         }
13300b57cec5SDimitry Andric 
13310b57cec5SDimitry Andric         // C++11 [class.copy]p13:
13320b57cec5SDimitry Andric         //   If the implicitly-defined constructor would satisfy the
13330b57cec5SDimitry Andric         //   requirements of a constexpr constructor, the implicitly-defined
13340b57cec5SDimitry Andric         //   constructor is constexpr.
13350b57cec5SDimitry Andric         // C++11 [dcl.constexpr]p4:
13360b57cec5SDimitry Andric         //    -- every constructor involved in initializing non-static data
13370b57cec5SDimitry Andric         //       members [...] shall be a constexpr constructor
13380b57cec5SDimitry Andric         if (!Field->hasInClassInitializer() &&
13390b57cec5SDimitry Andric             !FieldRec->hasConstexprDefaultConstructor() && !isUnion())
13400b57cec5SDimitry Andric           // The standard requires any in-class initializer to be a constant
13410b57cec5SDimitry Andric           // expression. We consider this to be a defect.
13420fca6ea1SDimitry Andric           data().DefaultedDefaultConstructorIsConstexpr =
13430fca6ea1SDimitry Andric               Context.getLangOpts().CPlusPlus23;
13440b57cec5SDimitry Andric 
13450b57cec5SDimitry Andric         // C++11 [class.copy]p8:
13460b57cec5SDimitry Andric         //   The implicitly-declared copy constructor for a class X will have
13470b57cec5SDimitry Andric         //   the form 'X::X(const X&)' if each potentially constructed subobject
13480b57cec5SDimitry Andric         //   of a class type M (or array thereof) has a copy constructor whose
13490b57cec5SDimitry Andric         //   first parameter is of type 'const M&' or 'const volatile M&'.
13500b57cec5SDimitry Andric         if (!FieldRec->hasCopyConstructorWithConstParam())
13510b57cec5SDimitry Andric           data().ImplicitCopyConstructorCanHaveConstParamForNonVBase = false;
13520b57cec5SDimitry Andric 
13530b57cec5SDimitry Andric         // C++11 [class.copy]p18:
13540b57cec5SDimitry Andric         //   The implicitly-declared copy assignment oeprator for a class X will
13550b57cec5SDimitry Andric         //   have the form 'X& X::operator=(const X&)' if [...] for all the
13560b57cec5SDimitry Andric         //   non-static data members of X that are of a class type M (or array
13570b57cec5SDimitry Andric         //   thereof), each such class type has a copy assignment operator whose
13580b57cec5SDimitry Andric         //   parameter is of type 'const M&', 'const volatile M&' or 'M'.
13590b57cec5SDimitry Andric         if (!FieldRec->hasCopyAssignmentWithConstParam())
13600b57cec5SDimitry Andric           data().ImplicitCopyAssignmentHasConstParam = false;
13610b57cec5SDimitry Andric 
13620b57cec5SDimitry Andric         if (FieldRec->hasUninitializedReferenceMember() &&
13630b57cec5SDimitry Andric             !Field->hasInClassInitializer())
13640b57cec5SDimitry Andric           data().HasUninitializedReferenceMember = true;
13650b57cec5SDimitry Andric 
13660b57cec5SDimitry Andric         // C++11 [class.union]p8, DR1460:
13670b57cec5SDimitry Andric         //   a non-static data member of an anonymous union that is a member of
13680b57cec5SDimitry Andric         //   X is also a variant member of X.
13690b57cec5SDimitry Andric         if (FieldRec->hasVariantMembers() &&
13700b57cec5SDimitry Andric             Field->isAnonymousStructOrUnion())
13710b57cec5SDimitry Andric           data().HasVariantMembers = true;
13720b57cec5SDimitry Andric       }
13730b57cec5SDimitry Andric     } else {
13740b57cec5SDimitry Andric       // Base element type of field is a non-class type.
13750b57cec5SDimitry Andric       if (!T->isLiteralType(Context) ||
1376a7dea167SDimitry Andric           (!Field->hasInClassInitializer() && !isUnion() &&
13775ffd83dbSDimitry Andric            !Context.getLangOpts().CPlusPlus20))
13780b57cec5SDimitry Andric         data().DefaultedDefaultConstructorIsConstexpr = false;
13790b57cec5SDimitry Andric 
13800b57cec5SDimitry Andric       // C++11 [class.copy]p23:
13810b57cec5SDimitry Andric       //   A defaulted copy/move assignment operator for a class X is defined
13820b57cec5SDimitry Andric       //   as deleted if X has:
13830b57cec5SDimitry Andric       //    -- a non-static data member of const non-class type (or array
13840b57cec5SDimitry Andric       //       thereof)
13855ffd83dbSDimitry Andric       if (T.isConstQualified()) {
13865ffd83dbSDimitry Andric         data().DefaultedCopyAssignmentIsDeleted = true;
13870b57cec5SDimitry Andric         data().DefaultedMoveAssignmentIsDeleted = true;
13880b57cec5SDimitry Andric       }
1389e8d8bef9SDimitry Andric 
1390e8d8bef9SDimitry Andric       // C++20 [temp.param]p7:
1391e8d8bef9SDimitry Andric       //   A structural type is [...] a literal class type [for which] the
1392e8d8bef9SDimitry Andric       //   types of all non-static data members are structural types or
1393e8d8bef9SDimitry Andric       //   (possibly multidimensional) array thereof
1394e8d8bef9SDimitry Andric       // We deal with class types elsewhere.
1395e8d8bef9SDimitry Andric       if (!T->isStructuralType())
1396e8d8bef9SDimitry Andric         data().StructuralIfLiteral = false;
13975ffd83dbSDimitry Andric     }
13980b57cec5SDimitry Andric 
13990b57cec5SDimitry Andric     // C++14 [meta.unary.prop]p4:
14000b57cec5SDimitry Andric     //   T is a class type [...] with [...] no non-static data members other
14010b57cec5SDimitry Andric     //   than subobjects of zero size
14020b57cec5SDimitry Andric     if (data().Empty && !IsZeroSize)
14030b57cec5SDimitry Andric       data().Empty = false;
14040b57cec5SDimitry Andric   }
14050b57cec5SDimitry Andric 
14060b57cec5SDimitry Andric   // Handle using declarations of conversion functions.
14070b57cec5SDimitry Andric   if (auto *Shadow = dyn_cast<UsingShadowDecl>(D)) {
14080b57cec5SDimitry Andric     if (Shadow->getDeclName().getNameKind()
14090b57cec5SDimitry Andric           == DeclarationName::CXXConversionFunctionName) {
14100b57cec5SDimitry Andric       ASTContext &Ctx = getASTContext();
14110b57cec5SDimitry Andric       data().Conversions.get(Ctx).addDecl(Ctx, Shadow, Shadow->getAccess());
14120b57cec5SDimitry Andric     }
14130b57cec5SDimitry Andric   }
14140b57cec5SDimitry Andric 
14150b57cec5SDimitry Andric   if (const auto *Using = dyn_cast<UsingDecl>(D)) {
14160b57cec5SDimitry Andric     if (Using->getDeclName().getNameKind() ==
14170b57cec5SDimitry Andric         DeclarationName::CXXConstructorName) {
14180b57cec5SDimitry Andric       data().HasInheritedConstructor = true;
14190b57cec5SDimitry Andric       // C++1z [dcl.init.aggr]p1:
14200b57cec5SDimitry Andric       //  An aggregate is [...] a class [...] with no inherited constructors
14210b57cec5SDimitry Andric       data().Aggregate = false;
14220b57cec5SDimitry Andric     }
14230b57cec5SDimitry Andric 
14240b57cec5SDimitry Andric     if (Using->getDeclName().getCXXOverloadedOperator() == OO_Equal)
14250b57cec5SDimitry Andric       data().HasInheritedAssignment = true;
14260b57cec5SDimitry Andric   }
14270b57cec5SDimitry Andric }
14280b57cec5SDimitry Andric 
14297a6dacacSDimitry Andric bool CXXRecordDecl::isLiteral() const {
14307a6dacacSDimitry Andric   const LangOptions &LangOpts = getLangOpts();
14317a6dacacSDimitry Andric   if (!(LangOpts.CPlusPlus20 ? hasConstexprDestructor()
14327a6dacacSDimitry Andric                              : hasTrivialDestructor()))
14337a6dacacSDimitry Andric     return false;
14347a6dacacSDimitry Andric 
14357a6dacacSDimitry Andric   if (hasNonLiteralTypeFieldsOrBases()) {
14367a6dacacSDimitry Andric     // CWG2598
14377a6dacacSDimitry Andric     // is an aggregate union type that has either no variant
14387a6dacacSDimitry Andric     // members or at least one variant member of non-volatile literal type,
14397a6dacacSDimitry Andric     if (!isUnion())
14407a6dacacSDimitry Andric       return false;
14417a6dacacSDimitry Andric     bool HasAtLeastOneLiteralMember =
14427a6dacacSDimitry Andric         fields().empty() || any_of(fields(), [this](const FieldDecl *D) {
14437a6dacacSDimitry Andric           return !D->getType().isVolatileQualified() &&
14447a6dacacSDimitry Andric                  D->getType()->isLiteralType(getASTContext());
14457a6dacacSDimitry Andric         });
14467a6dacacSDimitry Andric     if (!HasAtLeastOneLiteralMember)
14477a6dacacSDimitry Andric       return false;
14487a6dacacSDimitry Andric   }
14497a6dacacSDimitry Andric 
14507a6dacacSDimitry Andric   return isAggregate() || (isLambda() && LangOpts.CPlusPlus17) ||
14517a6dacacSDimitry Andric          hasConstexprNonCopyMoveConstructor() || hasTrivialDefaultConstructor();
14527a6dacacSDimitry Andric }
14537a6dacacSDimitry Andric 
145481ad6265SDimitry Andric void CXXRecordDecl::addedSelectedDestructor(CXXDestructorDecl *DD) {
145581ad6265SDimitry Andric   DD->setIneligibleOrNotSelected(false);
145681ad6265SDimitry Andric   addedEligibleSpecialMemberFunction(DD, SMF_Destructor);
145781ad6265SDimitry Andric }
145881ad6265SDimitry Andric 
145981ad6265SDimitry Andric void CXXRecordDecl::addedEligibleSpecialMemberFunction(const CXXMethodDecl *MD,
146081ad6265SDimitry Andric                                                        unsigned SMKind) {
1461bdd1243dSDimitry Andric   // FIXME: We shouldn't change DeclaredNonTrivialSpecialMembers if `MD` is
1462bdd1243dSDimitry Andric   // a function template, but this needs CWG attention before we break ABI.
1463bdd1243dSDimitry Andric   // See https://github.com/llvm/llvm-project/issues/59206
1464bdd1243dSDimitry Andric 
146581ad6265SDimitry Andric   if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
146681ad6265SDimitry Andric     if (DD->isUserProvided())
146781ad6265SDimitry Andric       data().HasIrrelevantDestructor = false;
146881ad6265SDimitry Andric     // If the destructor is explicitly defaulted and not trivial or not public
146981ad6265SDimitry Andric     // or if the destructor is deleted, we clear HasIrrelevantDestructor in
147081ad6265SDimitry Andric     // finishedDefaultedOrDeletedMember.
147181ad6265SDimitry Andric 
147281ad6265SDimitry Andric     // C++11 [class.dtor]p5:
147381ad6265SDimitry Andric     //   A destructor is trivial if [...] the destructor is not virtual.
147481ad6265SDimitry Andric     if (DD->isVirtual()) {
147581ad6265SDimitry Andric       data().HasTrivialSpecialMembers &= ~SMF_Destructor;
147681ad6265SDimitry Andric       data().HasTrivialSpecialMembersForCall &= ~SMF_Destructor;
147781ad6265SDimitry Andric     }
147881ad6265SDimitry Andric 
147981ad6265SDimitry Andric     if (DD->isNoReturn())
148081ad6265SDimitry Andric       data().IsAnyDestructorNoReturn = true;
148181ad6265SDimitry Andric   }
148281ad6265SDimitry Andric 
148381ad6265SDimitry Andric   if (!MD->isImplicit() && !MD->isUserProvided()) {
148481ad6265SDimitry Andric     // This method is user-declared but not user-provided. We can't work
148581ad6265SDimitry Andric     // out whether it's trivial yet (not until we get to the end of the
148681ad6265SDimitry Andric     // class). We'll handle this method in
148781ad6265SDimitry Andric     // finishedDefaultedOrDeletedMember.
148881ad6265SDimitry Andric   } else if (MD->isTrivial()) {
148981ad6265SDimitry Andric     data().HasTrivialSpecialMembers |= SMKind;
149081ad6265SDimitry Andric     data().HasTrivialSpecialMembersForCall |= SMKind;
149181ad6265SDimitry Andric   } else if (MD->isTrivialForCall()) {
149281ad6265SDimitry Andric     data().HasTrivialSpecialMembersForCall |= SMKind;
149381ad6265SDimitry Andric     data().DeclaredNonTrivialSpecialMembers |= SMKind;
149481ad6265SDimitry Andric   } else {
149581ad6265SDimitry Andric     data().DeclaredNonTrivialSpecialMembers |= SMKind;
149681ad6265SDimitry Andric     // If this is a user-provided function, do not set
149781ad6265SDimitry Andric     // DeclaredNonTrivialSpecialMembersForCall here since we don't know
149881ad6265SDimitry Andric     // yet whether the method would be considered non-trivial for the
149981ad6265SDimitry Andric     // purpose of calls (attribute "trivial_abi" can be dropped from the
150081ad6265SDimitry Andric     // class later, which can change the special method's triviality).
150181ad6265SDimitry Andric     if (!MD->isUserProvided())
150281ad6265SDimitry Andric       data().DeclaredNonTrivialSpecialMembersForCall |= SMKind;
150381ad6265SDimitry Andric   }
150481ad6265SDimitry Andric }
150581ad6265SDimitry Andric 
15060b57cec5SDimitry Andric void CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) {
15070b57cec5SDimitry Andric   assert(!D->isImplicit() && !D->isUserProvided());
15080b57cec5SDimitry Andric 
15090b57cec5SDimitry Andric   // The kind of special member this declaration is, if any.
15100b57cec5SDimitry Andric   unsigned SMKind = 0;
15110b57cec5SDimitry Andric 
15120b57cec5SDimitry Andric   if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
15130b57cec5SDimitry Andric     if (Constructor->isDefaultConstructor()) {
15140b57cec5SDimitry Andric       SMKind |= SMF_DefaultConstructor;
15150b57cec5SDimitry Andric       if (Constructor->isConstexpr())
15160b57cec5SDimitry Andric         data().HasConstexprDefaultConstructor = true;
15170b57cec5SDimitry Andric     }
15180b57cec5SDimitry Andric     if (Constructor->isCopyConstructor())
15190b57cec5SDimitry Andric       SMKind |= SMF_CopyConstructor;
15200b57cec5SDimitry Andric     else if (Constructor->isMoveConstructor())
15210b57cec5SDimitry Andric       SMKind |= SMF_MoveConstructor;
15220b57cec5SDimitry Andric     else if (Constructor->isConstexpr())
15230b57cec5SDimitry Andric       // We may now know that the constructor is constexpr.
15240b57cec5SDimitry Andric       data().HasConstexprNonCopyMoveConstructor = true;
15250b57cec5SDimitry Andric   } else if (isa<CXXDestructorDecl>(D)) {
15260b57cec5SDimitry Andric     SMKind |= SMF_Destructor;
15270b57cec5SDimitry Andric     if (!D->isTrivial() || D->getAccess() != AS_public || D->isDeleted())
15280b57cec5SDimitry Andric       data().HasIrrelevantDestructor = false;
15290b57cec5SDimitry Andric   } else if (D->isCopyAssignmentOperator())
15300b57cec5SDimitry Andric     SMKind |= SMF_CopyAssignment;
15310b57cec5SDimitry Andric   else if (D->isMoveAssignmentOperator())
15320b57cec5SDimitry Andric     SMKind |= SMF_MoveAssignment;
15330b57cec5SDimitry Andric 
15340b57cec5SDimitry Andric   // Update which trivial / non-trivial special members we have.
15350b57cec5SDimitry Andric   // addedMember will have skipped this step for this member.
1536bdd1243dSDimitry Andric   if (!D->isIneligibleOrNotSelected()) {
15370b57cec5SDimitry Andric     if (D->isTrivial())
15380b57cec5SDimitry Andric       data().HasTrivialSpecialMembers |= SMKind;
15390b57cec5SDimitry Andric     else
15400b57cec5SDimitry Andric       data().DeclaredNonTrivialSpecialMembers |= SMKind;
15410b57cec5SDimitry Andric   }
1542bdd1243dSDimitry Andric }
1543bdd1243dSDimitry Andric 
1544bdd1243dSDimitry Andric void CXXRecordDecl::LambdaDefinitionData::AddCaptureList(ASTContext &Ctx,
1545bdd1243dSDimitry Andric                                                          Capture *CaptureList) {
1546bdd1243dSDimitry Andric   Captures.push_back(CaptureList);
1547bdd1243dSDimitry Andric   if (Captures.size() == 2) {
1548bdd1243dSDimitry Andric     // The TinyPtrVector member now needs destruction.
1549bdd1243dSDimitry Andric     Ctx.addDestruction(&Captures);
1550bdd1243dSDimitry Andric   }
1551bdd1243dSDimitry Andric }
15520b57cec5SDimitry Andric 
1553e8d8bef9SDimitry Andric void CXXRecordDecl::setCaptures(ASTContext &Context,
1554e8d8bef9SDimitry Andric                                 ArrayRef<LambdaCapture> Captures) {
15555ffd83dbSDimitry Andric   CXXRecordDecl::LambdaDefinitionData &Data = getLambdaData();
15565ffd83dbSDimitry Andric 
15575ffd83dbSDimitry Andric   // Copy captures.
15585ffd83dbSDimitry Andric   Data.NumCaptures = Captures.size();
15595ffd83dbSDimitry Andric   Data.NumExplicitCaptures = 0;
1560bdd1243dSDimitry Andric   auto *ToCapture = (LambdaCapture *)Context.Allocate(sizeof(LambdaCapture) *
15615ffd83dbSDimitry Andric                                                       Captures.size());
1562bdd1243dSDimitry Andric   Data.AddCaptureList(Context, ToCapture);
15630fca6ea1SDimitry Andric   for (const LambdaCapture &C : Captures) {
15640fca6ea1SDimitry Andric     if (C.isExplicit())
15655ffd83dbSDimitry Andric       ++Data.NumExplicitCaptures;
15665ffd83dbSDimitry Andric 
15670fca6ea1SDimitry Andric     new (ToCapture) LambdaCapture(C);
15685f757f3fSDimitry Andric     ToCapture++;
15695ffd83dbSDimitry Andric   }
15705ffd83dbSDimitry Andric 
15715ffd83dbSDimitry Andric   if (!lambdaIsDefaultConstructibleAndAssignable())
15725ffd83dbSDimitry Andric     Data.DefaultedCopyAssignmentIsDeleted = true;
15735ffd83dbSDimitry Andric }
15745ffd83dbSDimitry Andric 
15750b57cec5SDimitry Andric void CXXRecordDecl::setTrivialForCallFlags(CXXMethodDecl *D) {
15760b57cec5SDimitry Andric   unsigned SMKind = 0;
15770b57cec5SDimitry Andric 
15780b57cec5SDimitry Andric   if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
15790b57cec5SDimitry Andric     if (Constructor->isCopyConstructor())
15800b57cec5SDimitry Andric       SMKind = SMF_CopyConstructor;
15810b57cec5SDimitry Andric     else if (Constructor->isMoveConstructor())
15820b57cec5SDimitry Andric       SMKind = SMF_MoveConstructor;
15830b57cec5SDimitry Andric   } else if (isa<CXXDestructorDecl>(D))
15840b57cec5SDimitry Andric     SMKind = SMF_Destructor;
15850b57cec5SDimitry Andric 
15860b57cec5SDimitry Andric   if (D->isTrivialForCall())
15870b57cec5SDimitry Andric     data().HasTrivialSpecialMembersForCall |= SMKind;
15880b57cec5SDimitry Andric   else
15890b57cec5SDimitry Andric     data().DeclaredNonTrivialSpecialMembersForCall |= SMKind;
15900b57cec5SDimitry Andric }
15910b57cec5SDimitry Andric 
15920b57cec5SDimitry Andric bool CXXRecordDecl::isCLike() const {
15935f757f3fSDimitry Andric   if (getTagKind() == TagTypeKind::Class ||
15945f757f3fSDimitry Andric       getTagKind() == TagTypeKind::Interface ||
15950b57cec5SDimitry Andric       !TemplateOrInstantiation.isNull())
15960b57cec5SDimitry Andric     return false;
15970b57cec5SDimitry Andric   if (!hasDefinition())
15980b57cec5SDimitry Andric     return true;
15990b57cec5SDimitry Andric 
16000b57cec5SDimitry Andric   return isPOD() && data().HasOnlyCMembers;
16010b57cec5SDimitry Andric }
16020b57cec5SDimitry Andric 
16030b57cec5SDimitry Andric bool CXXRecordDecl::isGenericLambda() const {
16040b57cec5SDimitry Andric   if (!isLambda()) return false;
16050b57cec5SDimitry Andric   return getLambdaData().IsGenericLambda;
16060b57cec5SDimitry Andric }
16070b57cec5SDimitry Andric 
16080b57cec5SDimitry Andric #ifndef NDEBUG
16090b57cec5SDimitry Andric static bool allLookupResultsAreTheSame(const DeclContext::lookup_result &R) {
16100fca6ea1SDimitry Andric   return llvm::all_of(R, [&](NamedDecl *D) {
16110fca6ea1SDimitry Andric     return D->isInvalidDecl() || declaresSameEntity(D, R.front());
16120fca6ea1SDimitry Andric   });
16130b57cec5SDimitry Andric }
16140b57cec5SDimitry Andric #endif
16150b57cec5SDimitry Andric 
1616a7dea167SDimitry Andric static NamedDecl* getLambdaCallOperatorHelper(const CXXRecordDecl &RD) {
1617a7dea167SDimitry Andric   if (!RD.isLambda()) return nullptr;
16180b57cec5SDimitry Andric   DeclarationName Name =
1619a7dea167SDimitry Andric     RD.getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
1620a7dea167SDimitry Andric   DeclContext::lookup_result Calls = RD.lookup(Name);
16210b57cec5SDimitry Andric 
16220b57cec5SDimitry Andric   assert(!Calls.empty() && "Missing lambda call operator!");
16230b57cec5SDimitry Andric   assert(allLookupResultsAreTheSame(Calls) &&
16240b57cec5SDimitry Andric          "More than one lambda call operator!");
1625a7dea167SDimitry Andric   return Calls.front();
1626a7dea167SDimitry Andric }
16270b57cec5SDimitry Andric 
1628a7dea167SDimitry Andric FunctionTemplateDecl* CXXRecordDecl::getDependentLambdaCallOperator() const {
1629a7dea167SDimitry Andric   NamedDecl *CallOp = getLambdaCallOperatorHelper(*this);
1630a7dea167SDimitry Andric   return  dyn_cast_or_null<FunctionTemplateDecl>(CallOp);
1631a7dea167SDimitry Andric }
1632a7dea167SDimitry Andric 
1633a7dea167SDimitry Andric CXXMethodDecl *CXXRecordDecl::getLambdaCallOperator() const {
1634a7dea167SDimitry Andric   NamedDecl *CallOp = getLambdaCallOperatorHelper(*this);
1635a7dea167SDimitry Andric 
1636a7dea167SDimitry Andric   if (CallOp == nullptr)
1637a7dea167SDimitry Andric     return nullptr;
1638a7dea167SDimitry Andric 
16390b57cec5SDimitry Andric   if (const auto *CallOpTmpl = dyn_cast<FunctionTemplateDecl>(CallOp))
16400b57cec5SDimitry Andric     return cast<CXXMethodDecl>(CallOpTmpl->getTemplatedDecl());
16410b57cec5SDimitry Andric 
16420b57cec5SDimitry Andric   return cast<CXXMethodDecl>(CallOp);
16430b57cec5SDimitry Andric }
16440b57cec5SDimitry Andric 
16450b57cec5SDimitry Andric CXXMethodDecl* CXXRecordDecl::getLambdaStaticInvoker() const {
1646e8d8bef9SDimitry Andric   CXXMethodDecl *CallOp = getLambdaCallOperator();
1647e8d8bef9SDimitry Andric   CallingConv CC = CallOp->getType()->castAs<FunctionType>()->getCallConv();
1648e8d8bef9SDimitry Andric   return getLambdaStaticInvoker(CC);
1649e8d8bef9SDimitry Andric }
16500b57cec5SDimitry Andric 
1651e8d8bef9SDimitry Andric static DeclContext::lookup_result
1652e8d8bef9SDimitry Andric getLambdaStaticInvokers(const CXXRecordDecl &RD) {
1653e8d8bef9SDimitry Andric   assert(RD.isLambda() && "Must be a lambda");
1654e8d8bef9SDimitry Andric   DeclarationName Name =
1655e8d8bef9SDimitry Andric       &RD.getASTContext().Idents.get(getLambdaStaticInvokerName());
1656e8d8bef9SDimitry Andric   return RD.lookup(Name);
1657e8d8bef9SDimitry Andric }
1658e8d8bef9SDimitry Andric 
1659e8d8bef9SDimitry Andric static CXXMethodDecl *getInvokerAsMethod(NamedDecl *ND) {
1660e8d8bef9SDimitry Andric   if (const auto *InvokerTemplate = dyn_cast<FunctionTemplateDecl>(ND))
1661e8d8bef9SDimitry Andric     return cast<CXXMethodDecl>(InvokerTemplate->getTemplatedDecl());
1662e8d8bef9SDimitry Andric   return cast<CXXMethodDecl>(ND);
1663e8d8bef9SDimitry Andric }
1664e8d8bef9SDimitry Andric 
1665e8d8bef9SDimitry Andric CXXMethodDecl *CXXRecordDecl::getLambdaStaticInvoker(CallingConv CC) const {
1666e8d8bef9SDimitry Andric   if (!isLambda())
1667e8d8bef9SDimitry Andric     return nullptr;
1668e8d8bef9SDimitry Andric   DeclContext::lookup_result Invoker = getLambdaStaticInvokers(*this);
1669e8d8bef9SDimitry Andric 
1670e8d8bef9SDimitry Andric   for (NamedDecl *ND : Invoker) {
1671e8d8bef9SDimitry Andric     const auto *FTy =
1672e8d8bef9SDimitry Andric         cast<ValueDecl>(ND->getAsFunction())->getType()->castAs<FunctionType>();
1673e8d8bef9SDimitry Andric     if (FTy->getCallConv() == CC)
1674e8d8bef9SDimitry Andric       return getInvokerAsMethod(ND);
1675e8d8bef9SDimitry Andric   }
1676e8d8bef9SDimitry Andric 
1677e8d8bef9SDimitry Andric   return nullptr;
16780b57cec5SDimitry Andric }
16790b57cec5SDimitry Andric 
16800b57cec5SDimitry Andric void CXXRecordDecl::getCaptureFields(
1681bdd1243dSDimitry Andric     llvm::DenseMap<const ValueDecl *, FieldDecl *> &Captures,
16820b57cec5SDimitry Andric     FieldDecl *&ThisCapture) const {
16830b57cec5SDimitry Andric   Captures.clear();
16840b57cec5SDimitry Andric   ThisCapture = nullptr;
16850b57cec5SDimitry Andric 
16860b57cec5SDimitry Andric   LambdaDefinitionData &Lambda = getLambdaData();
1687bdd1243dSDimitry Andric   for (const LambdaCapture *List : Lambda.Captures) {
16880b57cec5SDimitry Andric     RecordDecl::field_iterator Field = field_begin();
1689bdd1243dSDimitry Andric     for (const LambdaCapture *C = List, *CEnd = C + Lambda.NumCaptures;
16900b57cec5SDimitry Andric          C != CEnd; ++C, ++Field) {
16910b57cec5SDimitry Andric       if (C->capturesThis())
16920b57cec5SDimitry Andric         ThisCapture = *Field;
16930b57cec5SDimitry Andric       else if (C->capturesVariable())
16940b57cec5SDimitry Andric         Captures[C->getCapturedVar()] = *Field;
16950b57cec5SDimitry Andric     }
16960b57cec5SDimitry Andric     assert(Field == field_end());
16970b57cec5SDimitry Andric   }
1698bdd1243dSDimitry Andric }
16990b57cec5SDimitry Andric 
17000b57cec5SDimitry Andric TemplateParameterList *
17010b57cec5SDimitry Andric CXXRecordDecl::getGenericLambdaTemplateParameterList() const {
17020b57cec5SDimitry Andric   if (!isGenericLambda()) return nullptr;
17030b57cec5SDimitry Andric   CXXMethodDecl *CallOp = getLambdaCallOperator();
17040b57cec5SDimitry Andric   if (FunctionTemplateDecl *Tmpl = CallOp->getDescribedFunctionTemplate())
17050b57cec5SDimitry Andric     return Tmpl->getTemplateParameters();
17060b57cec5SDimitry Andric   return nullptr;
17070b57cec5SDimitry Andric }
17080b57cec5SDimitry Andric 
17090b57cec5SDimitry Andric ArrayRef<NamedDecl *>
17100b57cec5SDimitry Andric CXXRecordDecl::getLambdaExplicitTemplateParameters() const {
17110b57cec5SDimitry Andric   TemplateParameterList *List = getGenericLambdaTemplateParameterList();
17120b57cec5SDimitry Andric   if (!List)
17130b57cec5SDimitry Andric     return {};
17140b57cec5SDimitry Andric 
17150b57cec5SDimitry Andric   assert(std::is_partitioned(List->begin(), List->end(),
17160b57cec5SDimitry Andric                              [](const NamedDecl *D) { return !D->isImplicit(); })
17170b57cec5SDimitry Andric          && "Explicit template params should be ordered before implicit ones");
17180b57cec5SDimitry Andric 
17190b57cec5SDimitry Andric   const auto ExplicitEnd = llvm::partition_point(
17200b57cec5SDimitry Andric       *List, [](const NamedDecl *D) { return !D->isImplicit(); });
1721bdd1243dSDimitry Andric   return llvm::ArrayRef(List->begin(), ExplicitEnd);
17220b57cec5SDimitry Andric }
17230b57cec5SDimitry Andric 
17240b57cec5SDimitry Andric Decl *CXXRecordDecl::getLambdaContextDecl() const {
17250b57cec5SDimitry Andric   assert(isLambda() && "Not a lambda closure type!");
17260b57cec5SDimitry Andric   ExternalASTSource *Source = getParentASTContext().getExternalSource();
17270b57cec5SDimitry Andric   return getLambdaData().ContextDecl.get(Source);
17280b57cec5SDimitry Andric }
17290b57cec5SDimitry Andric 
173006c3fb27SDimitry Andric void CXXRecordDecl::setLambdaNumbering(LambdaNumbering Numbering) {
1731d409305fSDimitry Andric   assert(isLambda() && "Not a lambda closure type!");
173206c3fb27SDimitry Andric   getLambdaData().ManglingNumber = Numbering.ManglingNumber;
173306c3fb27SDimitry Andric   if (Numbering.DeviceManglingNumber)
173406c3fb27SDimitry Andric     getASTContext().DeviceLambdaManglingNumbers[this] =
173506c3fb27SDimitry Andric         Numbering.DeviceManglingNumber;
173606c3fb27SDimitry Andric   getLambdaData().IndexInContext = Numbering.IndexInContext;
173706c3fb27SDimitry Andric   getLambdaData().ContextDecl = Numbering.ContextDecl;
173806c3fb27SDimitry Andric   getLambdaData().HasKnownInternalLinkage = Numbering.HasKnownInternalLinkage;
1739d409305fSDimitry Andric }
1740d409305fSDimitry Andric 
1741d409305fSDimitry Andric unsigned CXXRecordDecl::getDeviceLambdaManglingNumber() const {
1742d409305fSDimitry Andric   assert(isLambda() && "Not a lambda closure type!");
174306c3fb27SDimitry Andric   return getASTContext().DeviceLambdaManglingNumbers.lookup(this);
1744d409305fSDimitry Andric }
1745d409305fSDimitry Andric 
17460b57cec5SDimitry Andric static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
17470b57cec5SDimitry Andric   QualType T =
17480b57cec5SDimitry Andric       cast<CXXConversionDecl>(Conv->getUnderlyingDecl()->getAsFunction())
17490b57cec5SDimitry Andric           ->getConversionType();
17500b57cec5SDimitry Andric   return Context.getCanonicalType(T);
17510b57cec5SDimitry Andric }
17520b57cec5SDimitry Andric 
17530b57cec5SDimitry Andric /// Collect the visible conversions of a base class.
17540b57cec5SDimitry Andric ///
17550b57cec5SDimitry Andric /// \param Record a base class of the class we're considering
17560b57cec5SDimitry Andric /// \param InVirtual whether this base class is a virtual base (or a base
17570b57cec5SDimitry Andric ///   of a virtual base)
17580b57cec5SDimitry Andric /// \param Access the access along the inheritance path to this base
17590b57cec5SDimitry Andric /// \param ParentHiddenTypes the conversions provided by the inheritors
17600b57cec5SDimitry Andric ///   of this base
17610b57cec5SDimitry Andric /// \param Output the set to which to add conversions from non-virtual bases
17620b57cec5SDimitry Andric /// \param VOutput the set to which to add conversions from virtual bases
17630b57cec5SDimitry Andric /// \param HiddenVBaseCs the set of conversions which were hidden in a
17640b57cec5SDimitry Andric ///   virtual base along some inheritance path
1765480093f4SDimitry Andric static void CollectVisibleConversions(
1766480093f4SDimitry Andric     ASTContext &Context, const CXXRecordDecl *Record, bool InVirtual,
17670b57cec5SDimitry Andric     AccessSpecifier Access,
17680b57cec5SDimitry Andric     const llvm::SmallPtrSet<CanQualType, 8> &ParentHiddenTypes,
1769480093f4SDimitry Andric     ASTUnresolvedSet &Output, UnresolvedSetImpl &VOutput,
17700b57cec5SDimitry Andric     llvm::SmallPtrSet<NamedDecl *, 8> &HiddenVBaseCs) {
17710b57cec5SDimitry Andric   // The set of types which have conversions in this class or its
17720b57cec5SDimitry Andric   // subclasses.  As an optimization, we don't copy the derived set
17730b57cec5SDimitry Andric   // unless it might change.
17740b57cec5SDimitry Andric   const llvm::SmallPtrSet<CanQualType, 8> *HiddenTypes = &ParentHiddenTypes;
17750b57cec5SDimitry Andric   llvm::SmallPtrSet<CanQualType, 8> HiddenTypesBuffer;
17760b57cec5SDimitry Andric 
17770b57cec5SDimitry Andric   // Collect the direct conversions and figure out which conversions
17780b57cec5SDimitry Andric   // will be hidden in the subclasses.
17790b57cec5SDimitry Andric   CXXRecordDecl::conversion_iterator ConvI = Record->conversion_begin();
17800b57cec5SDimitry Andric   CXXRecordDecl::conversion_iterator ConvE = Record->conversion_end();
17810b57cec5SDimitry Andric   if (ConvI != ConvE) {
17820b57cec5SDimitry Andric     HiddenTypesBuffer = ParentHiddenTypes;
17830b57cec5SDimitry Andric     HiddenTypes = &HiddenTypesBuffer;
17840b57cec5SDimitry Andric 
17850b57cec5SDimitry Andric     for (CXXRecordDecl::conversion_iterator I = ConvI; I != ConvE; ++I) {
17860b57cec5SDimitry Andric       CanQualType ConvType(GetConversionType(Context, I.getDecl()));
17870b57cec5SDimitry Andric       bool Hidden = ParentHiddenTypes.count(ConvType);
17880b57cec5SDimitry Andric       if (!Hidden)
17890b57cec5SDimitry Andric         HiddenTypesBuffer.insert(ConvType);
17900b57cec5SDimitry Andric 
17910b57cec5SDimitry Andric       // If this conversion is hidden and we're in a virtual base,
17920b57cec5SDimitry Andric       // remember that it's hidden along some inheritance path.
17930b57cec5SDimitry Andric       if (Hidden && InVirtual)
17940b57cec5SDimitry Andric         HiddenVBaseCs.insert(cast<NamedDecl>(I.getDecl()->getCanonicalDecl()));
17950b57cec5SDimitry Andric 
17960b57cec5SDimitry Andric       // If this conversion isn't hidden, add it to the appropriate output.
17970b57cec5SDimitry Andric       else if (!Hidden) {
17980b57cec5SDimitry Andric         AccessSpecifier IAccess
17990b57cec5SDimitry Andric           = CXXRecordDecl::MergeAccess(Access, I.getAccess());
18000b57cec5SDimitry Andric 
18010b57cec5SDimitry Andric         if (InVirtual)
18020b57cec5SDimitry Andric           VOutput.addDecl(I.getDecl(), IAccess);
18030b57cec5SDimitry Andric         else
18040b57cec5SDimitry Andric           Output.addDecl(Context, I.getDecl(), IAccess);
18050b57cec5SDimitry Andric       }
18060b57cec5SDimitry Andric     }
18070b57cec5SDimitry Andric   }
18080b57cec5SDimitry Andric 
18090b57cec5SDimitry Andric   // Collect information recursively from any base classes.
18100b57cec5SDimitry Andric   for (const auto &I : Record->bases()) {
1811480093f4SDimitry Andric     const auto *RT = I.getType()->getAs<RecordType>();
18120b57cec5SDimitry Andric     if (!RT) continue;
18130b57cec5SDimitry Andric 
18140b57cec5SDimitry Andric     AccessSpecifier BaseAccess
18150b57cec5SDimitry Andric       = CXXRecordDecl::MergeAccess(Access, I.getAccessSpecifier());
18160b57cec5SDimitry Andric     bool BaseInVirtual = InVirtual || I.isVirtual();
18170b57cec5SDimitry Andric 
18180b57cec5SDimitry Andric     auto *Base = cast<CXXRecordDecl>(RT->getDecl());
18190b57cec5SDimitry Andric     CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess,
18200b57cec5SDimitry Andric                               *HiddenTypes, Output, VOutput, HiddenVBaseCs);
18210b57cec5SDimitry Andric   }
18220b57cec5SDimitry Andric }
18230b57cec5SDimitry Andric 
18240b57cec5SDimitry Andric /// Collect the visible conversions of a class.
18250b57cec5SDimitry Andric ///
18260b57cec5SDimitry Andric /// This would be extremely straightforward if it weren't for virtual
18270b57cec5SDimitry Andric /// bases.  It might be worth special-casing that, really.
18280b57cec5SDimitry Andric static void CollectVisibleConversions(ASTContext &Context,
1829480093f4SDimitry Andric                                       const CXXRecordDecl *Record,
18300b57cec5SDimitry Andric                                       ASTUnresolvedSet &Output) {
18310b57cec5SDimitry Andric   // The collection of all conversions in virtual bases that we've
18320b57cec5SDimitry Andric   // found.  These will be added to the output as long as they don't
18330b57cec5SDimitry Andric   // appear in the hidden-conversions set.
18340b57cec5SDimitry Andric   UnresolvedSet<8> VBaseCs;
18350b57cec5SDimitry Andric 
18360b57cec5SDimitry Andric   // The set of conversions in virtual bases that we've determined to
18370b57cec5SDimitry Andric   // be hidden.
18380b57cec5SDimitry Andric   llvm::SmallPtrSet<NamedDecl*, 8> HiddenVBaseCs;
18390b57cec5SDimitry Andric 
18400b57cec5SDimitry Andric   // The set of types hidden by classes derived from this one.
18410b57cec5SDimitry Andric   llvm::SmallPtrSet<CanQualType, 8> HiddenTypes;
18420b57cec5SDimitry Andric 
18430b57cec5SDimitry Andric   // Go ahead and collect the direct conversions and add them to the
18440b57cec5SDimitry Andric   // hidden-types set.
18450b57cec5SDimitry Andric   CXXRecordDecl::conversion_iterator ConvI = Record->conversion_begin();
18460b57cec5SDimitry Andric   CXXRecordDecl::conversion_iterator ConvE = Record->conversion_end();
18470b57cec5SDimitry Andric   Output.append(Context, ConvI, ConvE);
18480b57cec5SDimitry Andric   for (; ConvI != ConvE; ++ConvI)
18490b57cec5SDimitry Andric     HiddenTypes.insert(GetConversionType(Context, ConvI.getDecl()));
18500b57cec5SDimitry Andric 
18510b57cec5SDimitry Andric   // Recursively collect conversions from base classes.
18520b57cec5SDimitry Andric   for (const auto &I : Record->bases()) {
1853480093f4SDimitry Andric     const auto *RT = I.getType()->getAs<RecordType>();
18540b57cec5SDimitry Andric     if (!RT) continue;
18550b57cec5SDimitry Andric 
18560b57cec5SDimitry Andric     CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()),
18570b57cec5SDimitry Andric                               I.isVirtual(), I.getAccessSpecifier(),
18580b57cec5SDimitry Andric                               HiddenTypes, Output, VBaseCs, HiddenVBaseCs);
18590b57cec5SDimitry Andric   }
18600b57cec5SDimitry Andric 
18610b57cec5SDimitry Andric   // Add any unhidden conversions provided by virtual bases.
18620b57cec5SDimitry Andric   for (UnresolvedSetIterator I = VBaseCs.begin(), E = VBaseCs.end();
18630b57cec5SDimitry Andric          I != E; ++I) {
18640b57cec5SDimitry Andric     if (!HiddenVBaseCs.count(cast<NamedDecl>(I.getDecl()->getCanonicalDecl())))
18650b57cec5SDimitry Andric       Output.addDecl(Context, I.getDecl(), I.getAccess());
18660b57cec5SDimitry Andric   }
18670b57cec5SDimitry Andric }
18680b57cec5SDimitry Andric 
18690b57cec5SDimitry Andric /// getVisibleConversionFunctions - get all conversion functions visible
18700b57cec5SDimitry Andric /// in current class; including conversion function templates.
18710b57cec5SDimitry Andric llvm::iterator_range<CXXRecordDecl::conversion_iterator>
1872480093f4SDimitry Andric CXXRecordDecl::getVisibleConversionFunctions() const {
18730b57cec5SDimitry Andric   ASTContext &Ctx = getASTContext();
18740b57cec5SDimitry Andric 
18750b57cec5SDimitry Andric   ASTUnresolvedSet *Set;
18760b57cec5SDimitry Andric   if (bases_begin() == bases_end()) {
18770b57cec5SDimitry Andric     // If root class, all conversions are visible.
18780b57cec5SDimitry Andric     Set = &data().Conversions.get(Ctx);
18790b57cec5SDimitry Andric   } else {
18800b57cec5SDimitry Andric     Set = &data().VisibleConversions.get(Ctx);
18810b57cec5SDimitry Andric     // If visible conversion list is not evaluated, evaluate it.
18820b57cec5SDimitry Andric     if (!data().ComputedVisibleConversions) {
18830b57cec5SDimitry Andric       CollectVisibleConversions(Ctx, this, *Set);
18840b57cec5SDimitry Andric       data().ComputedVisibleConversions = true;
18850b57cec5SDimitry Andric     }
18860b57cec5SDimitry Andric   }
18870b57cec5SDimitry Andric   return llvm::make_range(Set->begin(), Set->end());
18880b57cec5SDimitry Andric }
18890b57cec5SDimitry Andric 
18900b57cec5SDimitry Andric void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) {
18910b57cec5SDimitry Andric   // This operation is O(N) but extremely rare.  Sema only uses it to
18920b57cec5SDimitry Andric   // remove UsingShadowDecls in a class that were followed by a direct
18930b57cec5SDimitry Andric   // declaration, e.g.:
18940b57cec5SDimitry Andric   //   class A : B {
18950b57cec5SDimitry Andric   //     using B::operator int;
18960b57cec5SDimitry Andric   //     operator int();
18970b57cec5SDimitry Andric   //   };
18980b57cec5SDimitry Andric   // This is uncommon by itself and even more uncommon in conjunction
18990b57cec5SDimitry Andric   // with sufficiently large numbers of directly-declared conversions
19000b57cec5SDimitry Andric   // that asymptotic behavior matters.
19010b57cec5SDimitry Andric 
19020b57cec5SDimitry Andric   ASTUnresolvedSet &Convs = data().Conversions.get(getASTContext());
19030b57cec5SDimitry Andric   for (unsigned I = 0, E = Convs.size(); I != E; ++I) {
19040b57cec5SDimitry Andric     if (Convs[I].getDecl() == ConvDecl) {
19050b57cec5SDimitry Andric       Convs.erase(I);
1906349cc55cSDimitry Andric       assert(!llvm::is_contained(Convs, ConvDecl) &&
19070b57cec5SDimitry Andric              "conversion was found multiple times in unresolved set");
19080b57cec5SDimitry Andric       return;
19090b57cec5SDimitry Andric     }
19100b57cec5SDimitry Andric   }
19110b57cec5SDimitry Andric 
19120b57cec5SDimitry Andric   llvm_unreachable("conversion not found in set!");
19130b57cec5SDimitry Andric }
19140b57cec5SDimitry Andric 
19150b57cec5SDimitry Andric CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
19160b57cec5SDimitry Andric   if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
19170b57cec5SDimitry Andric     return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom());
19180b57cec5SDimitry Andric 
19190b57cec5SDimitry Andric   return nullptr;
19200b57cec5SDimitry Andric }
19210b57cec5SDimitry Andric 
19220b57cec5SDimitry Andric MemberSpecializationInfo *CXXRecordDecl::getMemberSpecializationInfo() const {
19230b57cec5SDimitry Andric   return TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>();
19240b57cec5SDimitry Andric }
19250b57cec5SDimitry Andric 
19260b57cec5SDimitry Andric void
19270b57cec5SDimitry Andric CXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD,
19280b57cec5SDimitry Andric                                              TemplateSpecializationKind TSK) {
19290b57cec5SDimitry Andric   assert(TemplateOrInstantiation.isNull() &&
19300b57cec5SDimitry Andric          "Previous template or instantiation?");
19310b57cec5SDimitry Andric   assert(!isa<ClassTemplatePartialSpecializationDecl>(this));
19320b57cec5SDimitry Andric   TemplateOrInstantiation
19330b57cec5SDimitry Andric     = new (getASTContext()) MemberSpecializationInfo(RD, TSK);
19340b57cec5SDimitry Andric }
19350b57cec5SDimitry Andric 
19360b57cec5SDimitry Andric ClassTemplateDecl *CXXRecordDecl::getDescribedClassTemplate() const {
19370b57cec5SDimitry Andric   return TemplateOrInstantiation.dyn_cast<ClassTemplateDecl *>();
19380b57cec5SDimitry Andric }
19390b57cec5SDimitry Andric 
19400b57cec5SDimitry Andric void CXXRecordDecl::setDescribedClassTemplate(ClassTemplateDecl *Template) {
19410b57cec5SDimitry Andric   TemplateOrInstantiation = Template;
19420b57cec5SDimitry Andric }
19430b57cec5SDimitry Andric 
19440b57cec5SDimitry Andric TemplateSpecializationKind CXXRecordDecl::getTemplateSpecializationKind() const{
19450b57cec5SDimitry Andric   if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(this))
19460b57cec5SDimitry Andric     return Spec->getSpecializationKind();
19470b57cec5SDimitry Andric 
19480b57cec5SDimitry Andric   if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
19490b57cec5SDimitry Andric     return MSInfo->getTemplateSpecializationKind();
19500b57cec5SDimitry Andric 
19510b57cec5SDimitry Andric   return TSK_Undeclared;
19520b57cec5SDimitry Andric }
19530b57cec5SDimitry Andric 
19540b57cec5SDimitry Andric void
19550b57cec5SDimitry Andric CXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
19560b57cec5SDimitry Andric   if (auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
19570b57cec5SDimitry Andric     Spec->setSpecializationKind(TSK);
19580b57cec5SDimitry Andric     return;
19590b57cec5SDimitry Andric   }
19600b57cec5SDimitry Andric 
19610b57cec5SDimitry Andric   if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
19620b57cec5SDimitry Andric     MSInfo->setTemplateSpecializationKind(TSK);
19630b57cec5SDimitry Andric     return;
19640b57cec5SDimitry Andric   }
19650b57cec5SDimitry Andric 
19660b57cec5SDimitry Andric   llvm_unreachable("Not a class template or member class specialization");
19670b57cec5SDimitry Andric }
19680b57cec5SDimitry Andric 
19690b57cec5SDimitry Andric const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const {
19700b57cec5SDimitry Andric   auto GetDefinitionOrSelf =
19710b57cec5SDimitry Andric       [](const CXXRecordDecl *D) -> const CXXRecordDecl * {
19720b57cec5SDimitry Andric     if (auto *Def = D->getDefinition())
19730b57cec5SDimitry Andric       return Def;
19740b57cec5SDimitry Andric     return D;
19750b57cec5SDimitry Andric   };
19760b57cec5SDimitry Andric 
19770b57cec5SDimitry Andric   // If it's a class template specialization, find the template or partial
19780b57cec5SDimitry Andric   // specialization from which it was instantiated.
19790b57cec5SDimitry Andric   if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
19800b57cec5SDimitry Andric     auto From = TD->getInstantiatedFrom();
19810b57cec5SDimitry Andric     if (auto *CTD = From.dyn_cast<ClassTemplateDecl *>()) {
19820b57cec5SDimitry Andric       while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) {
19830b57cec5SDimitry Andric         if (NewCTD->isMemberSpecialization())
19840b57cec5SDimitry Andric           break;
19850b57cec5SDimitry Andric         CTD = NewCTD;
19860b57cec5SDimitry Andric       }
19870b57cec5SDimitry Andric       return GetDefinitionOrSelf(CTD->getTemplatedDecl());
19880b57cec5SDimitry Andric     }
19890b57cec5SDimitry Andric     if (auto *CTPSD =
19900b57cec5SDimitry Andric             From.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
19910b57cec5SDimitry Andric       while (auto *NewCTPSD = CTPSD->getInstantiatedFromMember()) {
19920b57cec5SDimitry Andric         if (NewCTPSD->isMemberSpecialization())
19930b57cec5SDimitry Andric           break;
19940b57cec5SDimitry Andric         CTPSD = NewCTPSD;
19950b57cec5SDimitry Andric       }
19960b57cec5SDimitry Andric       return GetDefinitionOrSelf(CTPSD);
19970b57cec5SDimitry Andric     }
19980b57cec5SDimitry Andric   }
19990b57cec5SDimitry Andric 
20000b57cec5SDimitry Andric   if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
20010b57cec5SDimitry Andric     if (isTemplateInstantiation(MSInfo->getTemplateSpecializationKind())) {
20020b57cec5SDimitry Andric       const CXXRecordDecl *RD = this;
20030b57cec5SDimitry Andric       while (auto *NewRD = RD->getInstantiatedFromMemberClass())
20040b57cec5SDimitry Andric         RD = NewRD;
20050b57cec5SDimitry Andric       return GetDefinitionOrSelf(RD);
20060b57cec5SDimitry Andric     }
20070b57cec5SDimitry Andric   }
20080b57cec5SDimitry Andric 
20090b57cec5SDimitry Andric   assert(!isTemplateInstantiation(this->getTemplateSpecializationKind()) &&
20100b57cec5SDimitry Andric          "couldn't find pattern for class template instantiation");
20110b57cec5SDimitry Andric   return nullptr;
20120b57cec5SDimitry Andric }
20130b57cec5SDimitry Andric 
20140b57cec5SDimitry Andric CXXDestructorDecl *CXXRecordDecl::getDestructor() const {
20150b57cec5SDimitry Andric   ASTContext &Context = getASTContext();
20160b57cec5SDimitry Andric   QualType ClassType = Context.getTypeDeclType(this);
20170b57cec5SDimitry Andric 
20180b57cec5SDimitry Andric   DeclarationName Name
20190b57cec5SDimitry Andric     = Context.DeclarationNames.getCXXDestructorName(
20200b57cec5SDimitry Andric                                           Context.getCanonicalType(ClassType));
20210b57cec5SDimitry Andric 
20220b57cec5SDimitry Andric   DeclContext::lookup_result R = lookup(Name);
20230b57cec5SDimitry Andric 
202481ad6265SDimitry Andric   // If a destructor was marked as not selected, we skip it. We don't always
202581ad6265SDimitry Andric   // have a selected destructor: dependent types, unnamed structs.
202681ad6265SDimitry Andric   for (auto *Decl : R) {
202781ad6265SDimitry Andric     auto* DD = dyn_cast<CXXDestructorDecl>(Decl);
202881ad6265SDimitry Andric     if (DD && !DD->isIneligibleOrNotSelected())
202981ad6265SDimitry Andric       return DD;
203081ad6265SDimitry Andric   }
203181ad6265SDimitry Andric   return nullptr;
20320b57cec5SDimitry Andric }
20330b57cec5SDimitry Andric 
20340b57cec5SDimitry Andric static bool isDeclContextInNamespace(const DeclContext *DC) {
20350b57cec5SDimitry Andric   while (!DC->isTranslationUnit()) {
20360b57cec5SDimitry Andric     if (DC->isNamespace())
20370b57cec5SDimitry Andric       return true;
20380b57cec5SDimitry Andric     DC = DC->getParent();
20390b57cec5SDimitry Andric   }
20400b57cec5SDimitry Andric   return false;
20410b57cec5SDimitry Andric }
20420b57cec5SDimitry Andric 
20430b57cec5SDimitry Andric bool CXXRecordDecl::isInterfaceLike() const {
20440b57cec5SDimitry Andric   assert(hasDefinition() && "checking for interface-like without a definition");
20450b57cec5SDimitry Andric   // All __interfaces are inheritently interface-like.
20460b57cec5SDimitry Andric   if (isInterface())
20470b57cec5SDimitry Andric     return true;
20480b57cec5SDimitry Andric 
20490b57cec5SDimitry Andric   // Interface-like types cannot have a user declared constructor, destructor,
20500b57cec5SDimitry Andric   // friends, VBases, conversion functions, or fields.  Additionally, lambdas
20510b57cec5SDimitry Andric   // cannot be interface types.
20520b57cec5SDimitry Andric   if (isLambda() || hasUserDeclaredConstructor() ||
20530b57cec5SDimitry Andric       hasUserDeclaredDestructor() || !field_empty() || hasFriends() ||
20540b57cec5SDimitry Andric       getNumVBases() > 0 || conversion_end() - conversion_begin() > 0)
20550b57cec5SDimitry Andric     return false;
20560b57cec5SDimitry Andric 
20570b57cec5SDimitry Andric   // No interface-like type can have a method with a definition.
20580b57cec5SDimitry Andric   for (const auto *const Method : methods())
20590b57cec5SDimitry Andric     if (Method->isDefined() && !Method->isImplicit())
20600b57cec5SDimitry Andric       return false;
20610b57cec5SDimitry Andric 
20620b57cec5SDimitry Andric   // Check "Special" types.
20630b57cec5SDimitry Andric   const auto *Uuid = getAttr<UuidAttr>();
20640b57cec5SDimitry Andric   // MS SDK declares IUnknown/IDispatch both in the root of a TU, or in an
20650b57cec5SDimitry Andric   // extern C++ block directly in the TU.  These are only valid if in one
20660b57cec5SDimitry Andric   // of these two situations.
20670b57cec5SDimitry Andric   if (Uuid && isStruct() && !getDeclContext()->isExternCContext() &&
20680b57cec5SDimitry Andric       !isDeclContextInNamespace(getDeclContext()) &&
20690b57cec5SDimitry Andric       ((getName() == "IUnknown" &&
20700b57cec5SDimitry Andric         Uuid->getGuid() == "00000000-0000-0000-C000-000000000046") ||
20710b57cec5SDimitry Andric        (getName() == "IDispatch" &&
20720b57cec5SDimitry Andric         Uuid->getGuid() == "00020400-0000-0000-C000-000000000046"))) {
20730b57cec5SDimitry Andric     if (getNumBases() > 0)
20740b57cec5SDimitry Andric       return false;
20750b57cec5SDimitry Andric     return true;
20760b57cec5SDimitry Andric   }
20770b57cec5SDimitry Andric 
20780b57cec5SDimitry Andric   // FIXME: Any access specifiers is supposed to make this no longer interface
20790b57cec5SDimitry Andric   // like.
20800b57cec5SDimitry Andric 
20810b57cec5SDimitry Andric   // If this isn't a 'special' type, it must have a single interface-like base.
20820b57cec5SDimitry Andric   if (getNumBases() != 1)
20830b57cec5SDimitry Andric     return false;
20840b57cec5SDimitry Andric 
20850b57cec5SDimitry Andric   const auto BaseSpec = *bases_begin();
20860b57cec5SDimitry Andric   if (BaseSpec.isVirtual() || BaseSpec.getAccessSpecifier() != AS_public)
20870b57cec5SDimitry Andric     return false;
20880b57cec5SDimitry Andric   const auto *Base = BaseSpec.getType()->getAsCXXRecordDecl();
20890b57cec5SDimitry Andric   if (Base->isInterface() || !Base->isInterfaceLike())
20900b57cec5SDimitry Andric     return false;
20910b57cec5SDimitry Andric   return true;
20920b57cec5SDimitry Andric }
20930b57cec5SDimitry Andric 
20940b57cec5SDimitry Andric void CXXRecordDecl::completeDefinition() {
20950b57cec5SDimitry Andric   completeDefinition(nullptr);
20960b57cec5SDimitry Andric }
20970b57cec5SDimitry Andric 
20980fca6ea1SDimitry Andric static bool hasPureVirtualFinalOverrider(
20990fca6ea1SDimitry Andric     const CXXRecordDecl &RD, const CXXFinalOverriderMap *FinalOverriders) {
21000fca6ea1SDimitry Andric   if (!FinalOverriders) {
21010fca6ea1SDimitry Andric     CXXFinalOverriderMap MyFinalOverriders;
21020fca6ea1SDimitry Andric     RD.getFinalOverriders(MyFinalOverriders);
21030fca6ea1SDimitry Andric     return hasPureVirtualFinalOverrider(RD, &MyFinalOverriders);
21040fca6ea1SDimitry Andric   }
21050fca6ea1SDimitry Andric 
21060fca6ea1SDimitry Andric   for (const CXXFinalOverriderMap::value_type &
21070fca6ea1SDimitry Andric         OverridingMethodsEntry : *FinalOverriders) {
21080fca6ea1SDimitry Andric     for (const auto &[_, SubobjOverrides] : OverridingMethodsEntry.second) {
21090fca6ea1SDimitry Andric       assert(SubobjOverrides.size() > 0 &&
21100fca6ea1SDimitry Andric             "All virtual functions have overriding virtual functions");
21110fca6ea1SDimitry Andric 
21120fca6ea1SDimitry Andric       if (SubobjOverrides.front().Method->isPureVirtual())
21130fca6ea1SDimitry Andric         return true;
21140fca6ea1SDimitry Andric     }
21150fca6ea1SDimitry Andric   }
21160fca6ea1SDimitry Andric   return false;
21170fca6ea1SDimitry Andric }
21180fca6ea1SDimitry Andric 
21190b57cec5SDimitry Andric void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
21200b57cec5SDimitry Andric   RecordDecl::completeDefinition();
21210b57cec5SDimitry Andric 
21220b57cec5SDimitry Andric   // If the class may be abstract (but hasn't been marked as such), check for
21230b57cec5SDimitry Andric   // any pure final overriders.
21240fca6ea1SDimitry Andric   //
21250b57cec5SDimitry Andric   // C++ [class.abstract]p4:
21260b57cec5SDimitry Andric   //   A class is abstract if it contains or inherits at least one
21270b57cec5SDimitry Andric   //   pure virtual function for which the final overrider is pure
21280b57cec5SDimitry Andric   //   virtual.
21290fca6ea1SDimitry Andric   if (mayBeAbstract() && hasPureVirtualFinalOverrider(*this, FinalOverriders))
21300fca6ea1SDimitry Andric     markAbstract();
21310b57cec5SDimitry Andric 
21320b57cec5SDimitry Andric   // Set access bits correctly on the directly-declared conversions.
21330b57cec5SDimitry Andric   for (conversion_iterator I = conversion_begin(), E = conversion_end();
21340b57cec5SDimitry Andric        I != E; ++I)
21350b57cec5SDimitry Andric     I.setAccess((*I)->getAccess());
21360b57cec5SDimitry Andric }
21370b57cec5SDimitry Andric 
21380b57cec5SDimitry Andric bool CXXRecordDecl::mayBeAbstract() const {
21390b57cec5SDimitry Andric   if (data().Abstract || isInvalidDecl() || !data().Polymorphic ||
21400b57cec5SDimitry Andric       isDependentContext())
21410b57cec5SDimitry Andric     return false;
21420b57cec5SDimitry Andric 
21430b57cec5SDimitry Andric   for (const auto &B : bases()) {
21440b57cec5SDimitry Andric     const auto *BaseDecl =
2145a7dea167SDimitry Andric         cast<CXXRecordDecl>(B.getType()->castAs<RecordType>()->getDecl());
21460b57cec5SDimitry Andric     if (BaseDecl->isAbstract())
21470b57cec5SDimitry Andric       return true;
21480b57cec5SDimitry Andric   }
21490b57cec5SDimitry Andric 
21500b57cec5SDimitry Andric   return false;
21510b57cec5SDimitry Andric }
21520b57cec5SDimitry Andric 
21535ffd83dbSDimitry Andric bool CXXRecordDecl::isEffectivelyFinal() const {
21545ffd83dbSDimitry Andric   auto *Def = getDefinition();
21555ffd83dbSDimitry Andric   if (!Def)
21565ffd83dbSDimitry Andric     return false;
21575ffd83dbSDimitry Andric   if (Def->hasAttr<FinalAttr>())
21585ffd83dbSDimitry Andric     return true;
21595ffd83dbSDimitry Andric   if (const auto *Dtor = Def->getDestructor())
21605ffd83dbSDimitry Andric     if (Dtor->hasAttr<FinalAttr>())
21615ffd83dbSDimitry Andric       return true;
21625ffd83dbSDimitry Andric   return false;
21635ffd83dbSDimitry Andric }
21645ffd83dbSDimitry Andric 
21650b57cec5SDimitry Andric void CXXDeductionGuideDecl::anchor() {}
21660b57cec5SDimitry Andric 
21670b57cec5SDimitry Andric bool ExplicitSpecifier::isEquivalent(const ExplicitSpecifier Other) const {
21680b57cec5SDimitry Andric   if ((getKind() != Other.getKind() ||
21690b57cec5SDimitry Andric        getKind() == ExplicitSpecKind::Unresolved)) {
21700b57cec5SDimitry Andric     if (getKind() == ExplicitSpecKind::Unresolved &&
21710b57cec5SDimitry Andric         Other.getKind() == ExplicitSpecKind::Unresolved) {
21720b57cec5SDimitry Andric       ODRHash SelfHash, OtherHash;
21730b57cec5SDimitry Andric       SelfHash.AddStmt(getExpr());
21740b57cec5SDimitry Andric       OtherHash.AddStmt(Other.getExpr());
21750b57cec5SDimitry Andric       return SelfHash.CalculateHash() == OtherHash.CalculateHash();
21760b57cec5SDimitry Andric     } else
21770b57cec5SDimitry Andric       return false;
21780b57cec5SDimitry Andric   }
21790b57cec5SDimitry Andric   return true;
21800b57cec5SDimitry Andric }
21810b57cec5SDimitry Andric 
21820b57cec5SDimitry Andric ExplicitSpecifier ExplicitSpecifier::getFromDecl(FunctionDecl *Function) {
21830b57cec5SDimitry Andric   switch (Function->getDeclKind()) {
21840b57cec5SDimitry Andric   case Decl::Kind::CXXConstructor:
21850b57cec5SDimitry Andric     return cast<CXXConstructorDecl>(Function)->getExplicitSpecifier();
21860b57cec5SDimitry Andric   case Decl::Kind::CXXConversion:
21870b57cec5SDimitry Andric     return cast<CXXConversionDecl>(Function)->getExplicitSpecifier();
21880b57cec5SDimitry Andric   case Decl::Kind::CXXDeductionGuide:
21890b57cec5SDimitry Andric     return cast<CXXDeductionGuideDecl>(Function)->getExplicitSpecifier();
21900b57cec5SDimitry Andric   default:
21910b57cec5SDimitry Andric     return {};
21920b57cec5SDimitry Andric   }
21930b57cec5SDimitry Andric }
21940b57cec5SDimitry Andric 
219506c3fb27SDimitry Andric CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create(
219606c3fb27SDimitry Andric     ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
219706c3fb27SDimitry Andric     ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T,
219806c3fb27SDimitry Andric     TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor,
219906c3fb27SDimitry Andric     DeductionCandidate Kind) {
22000b57cec5SDimitry Andric   return new (C, DC) CXXDeductionGuideDecl(C, DC, StartLoc, ES, NameInfo, T,
220106c3fb27SDimitry Andric                                            TInfo, EndLocation, Ctor, Kind);
22020b57cec5SDimitry Andric }
22030b57cec5SDimitry Andric 
22040fca6ea1SDimitry Andric CXXDeductionGuideDecl *
22050fca6ea1SDimitry Andric CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
22060b57cec5SDimitry Andric   return new (C, ID) CXXDeductionGuideDecl(
22070b57cec5SDimitry Andric       C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(),
220806c3fb27SDimitry Andric       QualType(), nullptr, SourceLocation(), nullptr,
220906c3fb27SDimitry Andric       DeductionCandidate::Normal);
22100b57cec5SDimitry Andric }
22110b57cec5SDimitry Andric 
221255e4f9d5SDimitry Andric RequiresExprBodyDecl *RequiresExprBodyDecl::Create(
221355e4f9d5SDimitry Andric     ASTContext &C, DeclContext *DC, SourceLocation StartLoc) {
221455e4f9d5SDimitry Andric   return new (C, DC) RequiresExprBodyDecl(C, DC, StartLoc);
221555e4f9d5SDimitry Andric }
221655e4f9d5SDimitry Andric 
22170fca6ea1SDimitry Andric RequiresExprBodyDecl *
22180fca6ea1SDimitry Andric RequiresExprBodyDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
221955e4f9d5SDimitry Andric   return new (C, ID) RequiresExprBodyDecl(C, nullptr, SourceLocation());
222055e4f9d5SDimitry Andric }
222155e4f9d5SDimitry Andric 
22220b57cec5SDimitry Andric void CXXMethodDecl::anchor() {}
22230b57cec5SDimitry Andric 
22240b57cec5SDimitry Andric bool CXXMethodDecl::isStatic() const {
22250b57cec5SDimitry Andric   const CXXMethodDecl *MD = getCanonicalDecl();
22260b57cec5SDimitry Andric 
22270b57cec5SDimitry Andric   if (MD->getStorageClass() == SC_Static)
22280b57cec5SDimitry Andric     return true;
22290b57cec5SDimitry Andric 
22300b57cec5SDimitry Andric   OverloadedOperatorKind OOK = getDeclName().getCXXOverloadedOperator();
22310b57cec5SDimitry Andric   return isStaticOverloadedOperator(OOK);
22320b57cec5SDimitry Andric }
22330b57cec5SDimitry Andric 
22340b57cec5SDimitry Andric static bool recursivelyOverrides(const CXXMethodDecl *DerivedMD,
22350b57cec5SDimitry Andric                                  const CXXMethodDecl *BaseMD) {
22360b57cec5SDimitry Andric   for (const CXXMethodDecl *MD : DerivedMD->overridden_methods()) {
22370b57cec5SDimitry Andric     if (MD->getCanonicalDecl() == BaseMD->getCanonicalDecl())
22380b57cec5SDimitry Andric       return true;
22390b57cec5SDimitry Andric     if (recursivelyOverrides(MD, BaseMD))
22400b57cec5SDimitry Andric       return true;
22410b57cec5SDimitry Andric   }
22420b57cec5SDimitry Andric   return false;
22430b57cec5SDimitry Andric }
22440b57cec5SDimitry Andric 
22450b57cec5SDimitry Andric CXXMethodDecl *
22460b57cec5SDimitry Andric CXXMethodDecl::getCorrespondingMethodDeclaredInClass(const CXXRecordDecl *RD,
22470b57cec5SDimitry Andric                                                      bool MayBeBase) {
22480b57cec5SDimitry Andric   if (this->getParent()->getCanonicalDecl() == RD->getCanonicalDecl())
22490b57cec5SDimitry Andric     return this;
22500b57cec5SDimitry Andric 
22510b57cec5SDimitry Andric   // Lookup doesn't work for destructors, so handle them separately.
22520b57cec5SDimitry Andric   if (isa<CXXDestructorDecl>(this)) {
22530b57cec5SDimitry Andric     CXXMethodDecl *MD = RD->getDestructor();
22540b57cec5SDimitry Andric     if (MD) {
22550b57cec5SDimitry Andric       if (recursivelyOverrides(MD, this))
22560b57cec5SDimitry Andric         return MD;
22570b57cec5SDimitry Andric       if (MayBeBase && recursivelyOverrides(this, MD))
22580b57cec5SDimitry Andric         return MD;
22590b57cec5SDimitry Andric     }
22600b57cec5SDimitry Andric     return nullptr;
22610b57cec5SDimitry Andric   }
22620b57cec5SDimitry Andric 
22630b57cec5SDimitry Andric   for (auto *ND : RD->lookup(getDeclName())) {
22640b57cec5SDimitry Andric     auto *MD = dyn_cast<CXXMethodDecl>(ND);
22650b57cec5SDimitry Andric     if (!MD)
22660b57cec5SDimitry Andric       continue;
22670b57cec5SDimitry Andric     if (recursivelyOverrides(MD, this))
22680b57cec5SDimitry Andric       return MD;
22690b57cec5SDimitry Andric     if (MayBeBase && recursivelyOverrides(this, MD))
22700b57cec5SDimitry Andric       return MD;
22710b57cec5SDimitry Andric   }
22720b57cec5SDimitry Andric 
22730b57cec5SDimitry Andric   return nullptr;
22740b57cec5SDimitry Andric }
22750b57cec5SDimitry Andric 
22760b57cec5SDimitry Andric CXXMethodDecl *
22770b57cec5SDimitry Andric CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD,
22780b57cec5SDimitry Andric                                              bool MayBeBase) {
22790b57cec5SDimitry Andric   if (auto *MD = getCorrespondingMethodDeclaredInClass(RD, MayBeBase))
22800b57cec5SDimitry Andric     return MD;
22810b57cec5SDimitry Andric 
228213138422SDimitry Andric   llvm::SmallVector<CXXMethodDecl*, 4> FinalOverriders;
228313138422SDimitry Andric   auto AddFinalOverrider = [&](CXXMethodDecl *D) {
228413138422SDimitry Andric     // If this function is overridden by a candidate final overrider, it is not
228513138422SDimitry Andric     // a final overrider.
228613138422SDimitry Andric     for (CXXMethodDecl *OtherD : FinalOverriders) {
228713138422SDimitry Andric       if (declaresSameEntity(D, OtherD) || recursivelyOverrides(OtherD, D))
228813138422SDimitry Andric         return;
228913138422SDimitry Andric     }
229013138422SDimitry Andric 
229113138422SDimitry Andric     // Other candidate final overriders might be overridden by this function.
2292349cc55cSDimitry Andric     llvm::erase_if(FinalOverriders, [&](CXXMethodDecl *OtherD) {
229313138422SDimitry Andric       return recursivelyOverrides(D, OtherD);
2294349cc55cSDimitry Andric     });
229513138422SDimitry Andric 
229613138422SDimitry Andric     FinalOverriders.push_back(D);
229713138422SDimitry Andric   };
229813138422SDimitry Andric 
22990b57cec5SDimitry Andric   for (const auto &I : RD->bases()) {
23000b57cec5SDimitry Andric     const RecordType *RT = I.getType()->getAs<RecordType>();
23010b57cec5SDimitry Andric     if (!RT)
23020b57cec5SDimitry Andric       continue;
23030b57cec5SDimitry Andric     const auto *Base = cast<CXXRecordDecl>(RT->getDecl());
230413138422SDimitry Andric     if (CXXMethodDecl *D = this->getCorrespondingMethodInClass(Base))
230513138422SDimitry Andric       AddFinalOverrider(D);
23060b57cec5SDimitry Andric   }
23070b57cec5SDimitry Andric 
230813138422SDimitry Andric   return FinalOverriders.size() == 1 ? FinalOverriders.front() : nullptr;
23090b57cec5SDimitry Andric }
23100b57cec5SDimitry Andric 
2311349cc55cSDimitry Andric CXXMethodDecl *
2312349cc55cSDimitry Andric CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
2313349cc55cSDimitry Andric                       const DeclarationNameInfo &NameInfo, QualType T,
2314349cc55cSDimitry Andric                       TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin,
2315349cc55cSDimitry Andric                       bool isInline, ConstexprSpecKind ConstexprKind,
2316480093f4SDimitry Andric                       SourceLocation EndLocation,
2317480093f4SDimitry Andric                       Expr *TrailingRequiresClause) {
2318349cc55cSDimitry Andric   return new (C, RD) CXXMethodDecl(
2319349cc55cSDimitry Andric       CXXMethod, C, RD, StartLoc, NameInfo, T, TInfo, SC, UsesFPIntrin,
2320349cc55cSDimitry Andric       isInline, ConstexprKind, EndLocation, TrailingRequiresClause);
23210b57cec5SDimitry Andric }
23220b57cec5SDimitry Andric 
23230fca6ea1SDimitry Andric CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C,
23240fca6ea1SDimitry Andric                                                  GlobalDeclID ID) {
2325349cc55cSDimitry Andric   return new (C, ID) CXXMethodDecl(
2326349cc55cSDimitry Andric       CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(),
2327349cc55cSDimitry Andric       QualType(), nullptr, SC_None, false, false,
2328e8d8bef9SDimitry Andric       ConstexprSpecKind::Unspecified, SourceLocation(), nullptr);
23290b57cec5SDimitry Andric }
23300b57cec5SDimitry Andric 
23310b57cec5SDimitry Andric CXXMethodDecl *CXXMethodDecl::getDevirtualizedMethod(const Expr *Base,
23320b57cec5SDimitry Andric                                                      bool IsAppleKext) {
23330b57cec5SDimitry Andric   assert(isVirtual() && "this method is expected to be virtual");
23340b57cec5SDimitry Andric 
23350b57cec5SDimitry Andric   // When building with -fapple-kext, all calls must go through the vtable since
23360b57cec5SDimitry Andric   // the kernel linker can do runtime patching of vtables.
23370b57cec5SDimitry Andric   if (IsAppleKext)
23380b57cec5SDimitry Andric     return nullptr;
23390b57cec5SDimitry Andric 
23400b57cec5SDimitry Andric   // If the member function is marked 'final', we know that it can't be
23410b57cec5SDimitry Andric   // overridden and can therefore devirtualize it unless it's pure virtual.
23420b57cec5SDimitry Andric   if (hasAttr<FinalAttr>())
23437a6dacacSDimitry Andric     return isPureVirtual() ? nullptr : this;
23440b57cec5SDimitry Andric 
23450b57cec5SDimitry Andric   // If Base is unknown, we cannot devirtualize.
23460b57cec5SDimitry Andric   if (!Base)
23470b57cec5SDimitry Andric     return nullptr;
23480b57cec5SDimitry Andric 
23490b57cec5SDimitry Andric   // If the base expression (after skipping derived-to-base conversions) is a
23500b57cec5SDimitry Andric   // class prvalue, then we can devirtualize.
23510b57cec5SDimitry Andric   Base = Base->getBestDynamicClassTypeExpr();
2352fe6060f1SDimitry Andric   if (Base->isPRValue() && Base->getType()->isRecordType())
23530b57cec5SDimitry Andric     return this;
23540b57cec5SDimitry Andric 
23550b57cec5SDimitry Andric   // If we don't even know what we would call, we can't devirtualize.
23560b57cec5SDimitry Andric   const CXXRecordDecl *BestDynamicDecl = Base->getBestDynamicClassType();
23570b57cec5SDimitry Andric   if (!BestDynamicDecl)
23580b57cec5SDimitry Andric     return nullptr;
23590b57cec5SDimitry Andric 
23600b57cec5SDimitry Andric   // There may be a method corresponding to MD in a derived class.
23610b57cec5SDimitry Andric   CXXMethodDecl *DevirtualizedMethod =
23620b57cec5SDimitry Andric       getCorrespondingMethodInClass(BestDynamicDecl);
23630b57cec5SDimitry Andric 
236413138422SDimitry Andric   // If there final overrider in the dynamic type is ambiguous, we can't
236513138422SDimitry Andric   // devirtualize this call.
236613138422SDimitry Andric   if (!DevirtualizedMethod)
236713138422SDimitry Andric     return nullptr;
236813138422SDimitry Andric 
23690b57cec5SDimitry Andric   // If that method is pure virtual, we can't devirtualize. If this code is
23700b57cec5SDimitry Andric   // reached, the result would be UB, not a direct call to the derived class
23710b57cec5SDimitry Andric   // function, and we can't assume the derived class function is defined.
23727a6dacacSDimitry Andric   if (DevirtualizedMethod->isPureVirtual())
23730b57cec5SDimitry Andric     return nullptr;
23740b57cec5SDimitry Andric 
23750b57cec5SDimitry Andric   // If that method is marked final, we can devirtualize it.
23760b57cec5SDimitry Andric   if (DevirtualizedMethod->hasAttr<FinalAttr>())
23770b57cec5SDimitry Andric     return DevirtualizedMethod;
23780b57cec5SDimitry Andric 
2379a7dea167SDimitry Andric   // Similarly, if the class itself or its destructor is marked 'final',
2380a7dea167SDimitry Andric   // the class can't be derived from and we can therefore devirtualize the
2381a7dea167SDimitry Andric   // member function call.
23825ffd83dbSDimitry Andric   if (BestDynamicDecl->isEffectivelyFinal())
23830b57cec5SDimitry Andric     return DevirtualizedMethod;
23840b57cec5SDimitry Andric 
23850b57cec5SDimitry Andric   if (const auto *DRE = dyn_cast<DeclRefExpr>(Base)) {
23860b57cec5SDimitry Andric     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
23870b57cec5SDimitry Andric       if (VD->getType()->isRecordType())
23880b57cec5SDimitry Andric         // This is a record decl. We know the type and can devirtualize it.
23890b57cec5SDimitry Andric         return DevirtualizedMethod;
23900b57cec5SDimitry Andric 
23910b57cec5SDimitry Andric     return nullptr;
23920b57cec5SDimitry Andric   }
23930b57cec5SDimitry Andric 
23940b57cec5SDimitry Andric   // We can devirtualize calls on an object accessed by a class member access
23950b57cec5SDimitry Andric   // expression, since by C++11 [basic.life]p6 we know that it can't refer to
23960b57cec5SDimitry Andric   // a derived class object constructed in the same location.
23970b57cec5SDimitry Andric   if (const auto *ME = dyn_cast<MemberExpr>(Base)) {
23980b57cec5SDimitry Andric     const ValueDecl *VD = ME->getMemberDecl();
23990b57cec5SDimitry Andric     return VD->getType()->isRecordType() ? DevirtualizedMethod : nullptr;
24000b57cec5SDimitry Andric   }
24010b57cec5SDimitry Andric 
24020b57cec5SDimitry Andric   // Likewise for calls on an object accessed by a (non-reference) pointer to
24030b57cec5SDimitry Andric   // member access.
24040b57cec5SDimitry Andric   if (auto *BO = dyn_cast<BinaryOperator>(Base)) {
24050b57cec5SDimitry Andric     if (BO->isPtrMemOp()) {
24060b57cec5SDimitry Andric       auto *MPT = BO->getRHS()->getType()->castAs<MemberPointerType>();
24070b57cec5SDimitry Andric       if (MPT->getPointeeType()->isRecordType())
24080b57cec5SDimitry Andric         return DevirtualizedMethod;
24090b57cec5SDimitry Andric     }
24100b57cec5SDimitry Andric   }
24110b57cec5SDimitry Andric 
24120b57cec5SDimitry Andric   // We can't devirtualize the call.
24130b57cec5SDimitry Andric   return nullptr;
24140b57cec5SDimitry Andric }
24150b57cec5SDimitry Andric 
24160b57cec5SDimitry Andric bool CXXMethodDecl::isUsualDeallocationFunction(
24170b57cec5SDimitry Andric     SmallVectorImpl<const FunctionDecl *> &PreventedBy) const {
24180b57cec5SDimitry Andric   assert(PreventedBy.empty() && "PreventedBy is expected to be empty");
24190b57cec5SDimitry Andric   if (getOverloadedOperator() != OO_Delete &&
24200b57cec5SDimitry Andric       getOverloadedOperator() != OO_Array_Delete)
24210b57cec5SDimitry Andric     return false;
24220b57cec5SDimitry Andric 
24230b57cec5SDimitry Andric   // C++ [basic.stc.dynamic.deallocation]p2:
24240b57cec5SDimitry Andric   //   A template instance is never a usual deallocation function,
24250b57cec5SDimitry Andric   //   regardless of its signature.
24260b57cec5SDimitry Andric   if (getPrimaryTemplate())
24270b57cec5SDimitry Andric     return false;
24280b57cec5SDimitry Andric 
24290b57cec5SDimitry Andric   // C++ [basic.stc.dynamic.deallocation]p2:
24300b57cec5SDimitry Andric   //   If a class T has a member deallocation function named operator delete
24310b57cec5SDimitry Andric   //   with exactly one parameter, then that function is a usual (non-placement)
24320b57cec5SDimitry Andric   //   deallocation function. [...]
24330b57cec5SDimitry Andric   if (getNumParams() == 1)
24340b57cec5SDimitry Andric     return true;
24350b57cec5SDimitry Andric   unsigned UsualParams = 1;
24360b57cec5SDimitry Andric 
24370b57cec5SDimitry Andric   // C++ P0722:
24380b57cec5SDimitry Andric   //   A destroying operator delete is a usual deallocation function if
24390b57cec5SDimitry Andric   //   removing the std::destroying_delete_t parameter and changing the
24400b57cec5SDimitry Andric   //   first parameter type from T* to void* results in the signature of
24410b57cec5SDimitry Andric   //   a usual deallocation function.
24420b57cec5SDimitry Andric   if (isDestroyingOperatorDelete())
24430b57cec5SDimitry Andric     ++UsualParams;
24440b57cec5SDimitry Andric 
24450b57cec5SDimitry Andric   // C++ <=14 [basic.stc.dynamic.deallocation]p2:
24460b57cec5SDimitry Andric   //   [...] If class T does not declare such an operator delete but does
24470b57cec5SDimitry Andric   //   declare a member deallocation function named operator delete with
24480b57cec5SDimitry Andric   //   exactly two parameters, the second of which has type std::size_t (18.1),
24490b57cec5SDimitry Andric   //   then this function is a usual deallocation function.
24500b57cec5SDimitry Andric   //
24510b57cec5SDimitry Andric   // C++17 says a usual deallocation function is one with the signature
24520b57cec5SDimitry Andric   //   (void* [, size_t] [, std::align_val_t] [, ...])
24530b57cec5SDimitry Andric   // and all such functions are usual deallocation functions. It's not clear
24540b57cec5SDimitry Andric   // that allowing varargs functions was intentional.
24550b57cec5SDimitry Andric   ASTContext &Context = getASTContext();
24560b57cec5SDimitry Andric   if (UsualParams < getNumParams() &&
24570b57cec5SDimitry Andric       Context.hasSameUnqualifiedType(getParamDecl(UsualParams)->getType(),
24580b57cec5SDimitry Andric                                      Context.getSizeType()))
24590b57cec5SDimitry Andric     ++UsualParams;
24600b57cec5SDimitry Andric 
24610b57cec5SDimitry Andric   if (UsualParams < getNumParams() &&
24620b57cec5SDimitry Andric       getParamDecl(UsualParams)->getType()->isAlignValT())
24630b57cec5SDimitry Andric     ++UsualParams;
24640b57cec5SDimitry Andric 
24650b57cec5SDimitry Andric   if (UsualParams != getNumParams())
24660b57cec5SDimitry Andric     return false;
24670b57cec5SDimitry Andric 
24680b57cec5SDimitry Andric   // In C++17 onwards, all potential usual deallocation functions are actual
24690b57cec5SDimitry Andric   // usual deallocation functions. Honor this behavior when post-C++14
24700b57cec5SDimitry Andric   // deallocation functions are offered as extensions too.
2471349cc55cSDimitry Andric   // FIXME(EricWF): Destroying Delete should be a language option. How do we
24720b57cec5SDimitry Andric   // handle when destroying delete is used prior to C++17?
24730b57cec5SDimitry Andric   if (Context.getLangOpts().CPlusPlus17 ||
24740b57cec5SDimitry Andric       Context.getLangOpts().AlignedAllocation ||
24750b57cec5SDimitry Andric       isDestroyingOperatorDelete())
24760b57cec5SDimitry Andric     return true;
24770b57cec5SDimitry Andric 
24780b57cec5SDimitry Andric   // This function is a usual deallocation function if there are no
24790b57cec5SDimitry Andric   // single-parameter deallocation functions of the same kind.
24800b57cec5SDimitry Andric   DeclContext::lookup_result R = getDeclContext()->lookup(getDeclName());
24810b57cec5SDimitry Andric   bool Result = true;
24820b57cec5SDimitry Andric   for (const auto *D : R) {
24830b57cec5SDimitry Andric     if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
24840b57cec5SDimitry Andric       if (FD->getNumParams() == 1) {
24850b57cec5SDimitry Andric         PreventedBy.push_back(FD);
24860b57cec5SDimitry Andric         Result = false;
24870b57cec5SDimitry Andric       }
24880b57cec5SDimitry Andric     }
24890b57cec5SDimitry Andric   }
24900b57cec5SDimitry Andric   return Result;
24910b57cec5SDimitry Andric }
24920b57cec5SDimitry Andric 
24935f757f3fSDimitry Andric bool CXXMethodDecl::isExplicitObjectMemberFunction() const {
24945f757f3fSDimitry Andric   // C++2b [dcl.fct]p6:
24955f757f3fSDimitry Andric   // An explicit object member function is a non-static member
24965f757f3fSDimitry Andric   // function with an explicit object parameter
24975f757f3fSDimitry Andric   return !isStatic() && hasCXXExplicitFunctionObjectParameter();
24985f757f3fSDimitry Andric }
24995f757f3fSDimitry Andric 
25005f757f3fSDimitry Andric bool CXXMethodDecl::isImplicitObjectMemberFunction() const {
25015f757f3fSDimitry Andric   return !isStatic() && !hasCXXExplicitFunctionObjectParameter();
25025f757f3fSDimitry Andric }
25035f757f3fSDimitry Andric 
25040b57cec5SDimitry Andric bool CXXMethodDecl::isCopyAssignmentOperator() const {
25050b57cec5SDimitry Andric   // C++0x [class.copy]p17:
25060b57cec5SDimitry Andric   //  A user-declared copy assignment operator X::operator= is a non-static
25070b57cec5SDimitry Andric   //  non-template member function of class X with exactly one parameter of
25080b57cec5SDimitry Andric   //  type X, X&, const X&, volatile X& or const volatile X&.
25090b57cec5SDimitry Andric   if (/*operator=*/getOverloadedOperator() != OO_Equal ||
25100b57cec5SDimitry Andric       /*non-static*/ isStatic() ||
25115f757f3fSDimitry Andric 
25120b57cec5SDimitry Andric       /*non-template*/ getPrimaryTemplate() || getDescribedFunctionTemplate() ||
25135f757f3fSDimitry Andric       getNumExplicitParams() != 1)
25140b57cec5SDimitry Andric     return false;
25150b57cec5SDimitry Andric 
25165f757f3fSDimitry Andric   QualType ParamType = getNonObjectParameter(0)->getType();
25170b57cec5SDimitry Andric   if (const auto *Ref = ParamType->getAs<LValueReferenceType>())
25180b57cec5SDimitry Andric     ParamType = Ref->getPointeeType();
25190b57cec5SDimitry Andric 
25200b57cec5SDimitry Andric   ASTContext &Context = getASTContext();
25210b57cec5SDimitry Andric   QualType ClassType
25220b57cec5SDimitry Andric     = Context.getCanonicalType(Context.getTypeDeclType(getParent()));
25230b57cec5SDimitry Andric   return Context.hasSameUnqualifiedType(ClassType, ParamType);
25240b57cec5SDimitry Andric }
25250b57cec5SDimitry Andric 
25260b57cec5SDimitry Andric bool CXXMethodDecl::isMoveAssignmentOperator() const {
25270b57cec5SDimitry Andric   // C++0x [class.copy]p19:
25280b57cec5SDimitry Andric   //  A user-declared move assignment operator X::operator= is a non-static
25290b57cec5SDimitry Andric   //  non-template member function of class X with exactly one parameter of type
25300b57cec5SDimitry Andric   //  X&&, const X&&, volatile X&&, or const volatile X&&.
25310b57cec5SDimitry Andric   if (getOverloadedOperator() != OO_Equal || isStatic() ||
25320b57cec5SDimitry Andric       getPrimaryTemplate() || getDescribedFunctionTemplate() ||
25335f757f3fSDimitry Andric       getNumExplicitParams() != 1)
25340b57cec5SDimitry Andric     return false;
25350b57cec5SDimitry Andric 
25365f757f3fSDimitry Andric   QualType ParamType = getNonObjectParameter(0)->getType();
2537fcaf7f86SDimitry Andric   if (!ParamType->isRValueReferenceType())
25380b57cec5SDimitry Andric     return false;
25390b57cec5SDimitry Andric   ParamType = ParamType->getPointeeType();
25400b57cec5SDimitry Andric 
25410b57cec5SDimitry Andric   ASTContext &Context = getASTContext();
25420b57cec5SDimitry Andric   QualType ClassType
25430b57cec5SDimitry Andric     = Context.getCanonicalType(Context.getTypeDeclType(getParent()));
25440b57cec5SDimitry Andric   return Context.hasSameUnqualifiedType(ClassType, ParamType);
25450b57cec5SDimitry Andric }
25460b57cec5SDimitry Andric 
25470b57cec5SDimitry Andric void CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) {
25480b57cec5SDimitry Andric   assert(MD->isCanonicalDecl() && "Method is not canonical!");
25490b57cec5SDimitry Andric   assert(!MD->getParent()->isDependentContext() &&
25500b57cec5SDimitry Andric          "Can't add an overridden method to a class template!");
25510b57cec5SDimitry Andric   assert(MD->isVirtual() && "Method is not virtual!");
25520b57cec5SDimitry Andric 
25530b57cec5SDimitry Andric   getASTContext().addOverriddenMethod(this, MD);
25540b57cec5SDimitry Andric }
25550b57cec5SDimitry Andric 
25560b57cec5SDimitry Andric CXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const {
25570b57cec5SDimitry Andric   if (isa<CXXConstructorDecl>(this)) return nullptr;
25580b57cec5SDimitry Andric   return getASTContext().overridden_methods_begin(this);
25590b57cec5SDimitry Andric }
25600b57cec5SDimitry Andric 
25610b57cec5SDimitry Andric CXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const {
25620b57cec5SDimitry Andric   if (isa<CXXConstructorDecl>(this)) return nullptr;
25630b57cec5SDimitry Andric   return getASTContext().overridden_methods_end(this);
25640b57cec5SDimitry Andric }
25650b57cec5SDimitry Andric 
25660b57cec5SDimitry Andric unsigned CXXMethodDecl::size_overridden_methods() const {
25670b57cec5SDimitry Andric   if (isa<CXXConstructorDecl>(this)) return 0;
25680b57cec5SDimitry Andric   return getASTContext().overridden_methods_size(this);
25690b57cec5SDimitry Andric }
25700b57cec5SDimitry Andric 
25710b57cec5SDimitry Andric CXXMethodDecl::overridden_method_range
25720b57cec5SDimitry Andric CXXMethodDecl::overridden_methods() const {
25730b57cec5SDimitry Andric   if (isa<CXXConstructorDecl>(this))
25740b57cec5SDimitry Andric     return overridden_method_range(nullptr, nullptr);
25750b57cec5SDimitry Andric   return getASTContext().overridden_methods(this);
25760b57cec5SDimitry Andric }
25770b57cec5SDimitry Andric 
25780b57cec5SDimitry Andric static QualType getThisObjectType(ASTContext &C, const FunctionProtoType *FPT,
25790b57cec5SDimitry Andric                                   const CXXRecordDecl *Decl) {
25800b57cec5SDimitry Andric   QualType ClassTy = C.getTypeDeclType(Decl);
25810b57cec5SDimitry Andric   return C.getQualifiedType(ClassTy, FPT->getMethodQuals());
25820b57cec5SDimitry Andric }
25830b57cec5SDimitry Andric 
25840b57cec5SDimitry Andric QualType CXXMethodDecl::getThisType(const FunctionProtoType *FPT,
25850b57cec5SDimitry Andric                                     const CXXRecordDecl *Decl) {
25860b57cec5SDimitry Andric   ASTContext &C = Decl->getASTContext();
25870b57cec5SDimitry Andric   QualType ObjectTy = ::getThisObjectType(C, FPT, Decl);
25880fca6ea1SDimitry Andric 
25890fca6ea1SDimitry Andric   // Unlike 'const' and 'volatile', a '__restrict' qualifier must be
25900fca6ea1SDimitry Andric   // attached to the pointer type, not the pointee.
25910fca6ea1SDimitry Andric   bool Restrict = FPT->getMethodQuals().hasRestrict();
25920fca6ea1SDimitry Andric   if (Restrict)
25930fca6ea1SDimitry Andric     ObjectTy.removeLocalRestrict();
25940fca6ea1SDimitry Andric 
25950fca6ea1SDimitry Andric   ObjectTy = C.getLangOpts().HLSL ? C.getLValueReferenceType(ObjectTy)
25965f757f3fSDimitry Andric                                   : C.getPointerType(ObjectTy);
25970fca6ea1SDimitry Andric 
25980fca6ea1SDimitry Andric   if (Restrict)
25990fca6ea1SDimitry Andric     ObjectTy.addRestrict();
26000fca6ea1SDimitry Andric   return ObjectTy;
26010b57cec5SDimitry Andric }
26020b57cec5SDimitry Andric 
26030b57cec5SDimitry Andric QualType CXXMethodDecl::getThisType() const {
26040b57cec5SDimitry Andric   // C++ 9.3.2p1: The type of this in a member function of a class X is X*.
26050b57cec5SDimitry Andric   // If the member function is declared const, the type of this is const X*,
26060b57cec5SDimitry Andric   // if the member function is declared volatile, the type of this is
26070b57cec5SDimitry Andric   // volatile X*, and if the member function is declared const volatile,
26080b57cec5SDimitry Andric   // the type of this is const volatile X*.
26090b57cec5SDimitry Andric   assert(isInstance() && "No 'this' for static methods!");
26105ffd83dbSDimitry Andric   return CXXMethodDecl::getThisType(getType()->castAs<FunctionProtoType>(),
26110b57cec5SDimitry Andric                                     getParent());
26120b57cec5SDimitry Andric }
26130b57cec5SDimitry Andric 
26145f757f3fSDimitry Andric QualType CXXMethodDecl::getFunctionObjectParameterReferenceType() const {
26155f757f3fSDimitry Andric   if (isExplicitObjectMemberFunction())
26165f757f3fSDimitry Andric     return parameters()[0]->getType();
26175f757f3fSDimitry Andric 
26185f757f3fSDimitry Andric   ASTContext &C = getParentASTContext();
26195f757f3fSDimitry Andric   const FunctionProtoType *FPT = getType()->castAs<FunctionProtoType>();
26205f757f3fSDimitry Andric   QualType Type = ::getThisObjectType(C, FPT, getParent());
26215f757f3fSDimitry Andric   RefQualifierKind RK = FPT->getRefQualifier();
26225f757f3fSDimitry Andric   if (RK == RefQualifierKind::RQ_RValue)
26235f757f3fSDimitry Andric     return C.getRValueReferenceType(Type);
26245f757f3fSDimitry Andric   return C.getLValueReferenceType(Type);
26250b57cec5SDimitry Andric }
26260b57cec5SDimitry Andric 
26270b57cec5SDimitry Andric bool CXXMethodDecl::hasInlineBody() const {
26280b57cec5SDimitry Andric   // If this function is a template instantiation, look at the template from
26290b57cec5SDimitry Andric   // which it was instantiated.
26300b57cec5SDimitry Andric   const FunctionDecl *CheckFn = getTemplateInstantiationPattern();
26310b57cec5SDimitry Andric   if (!CheckFn)
26320b57cec5SDimitry Andric     CheckFn = this;
26330b57cec5SDimitry Andric 
26340b57cec5SDimitry Andric   const FunctionDecl *fn;
26350b57cec5SDimitry Andric   return CheckFn->isDefined(fn) && !fn->isOutOfLine() &&
26360b57cec5SDimitry Andric          (fn->doesThisDeclarationHaveABody() || fn->willHaveBody());
26370b57cec5SDimitry Andric }
26380b57cec5SDimitry Andric 
26390b57cec5SDimitry Andric bool CXXMethodDecl::isLambdaStaticInvoker() const {
26400b57cec5SDimitry Andric   const CXXRecordDecl *P = getParent();
2641e8d8bef9SDimitry Andric   return P->isLambda() && getDeclName().isIdentifier() &&
2642e8d8bef9SDimitry Andric          getName() == getLambdaStaticInvokerName();
26430b57cec5SDimitry Andric }
26440b57cec5SDimitry Andric 
26450b57cec5SDimitry Andric CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
26460b57cec5SDimitry Andric                                        TypeSourceInfo *TInfo, bool IsVirtual,
26470b57cec5SDimitry Andric                                        SourceLocation L, Expr *Init,
26480b57cec5SDimitry Andric                                        SourceLocation R,
26490b57cec5SDimitry Andric                                        SourceLocation EllipsisLoc)
2650fe6060f1SDimitry Andric     : Initializee(TInfo), Init(Init), MemberOrEllipsisLocation(EllipsisLoc),
26510b57cec5SDimitry Andric       LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(IsVirtual),
26520b57cec5SDimitry Andric       IsWritten(false), SourceOrder(0) {}
26530b57cec5SDimitry Andric 
2654fe6060f1SDimitry Andric CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
26550b57cec5SDimitry Andric                                        SourceLocation MemberLoc,
26560b57cec5SDimitry Andric                                        SourceLocation L, Expr *Init,
26570b57cec5SDimitry Andric                                        SourceLocation R)
2658fe6060f1SDimitry Andric     : Initializee(Member), Init(Init), MemberOrEllipsisLocation(MemberLoc),
26590b57cec5SDimitry Andric       LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
26600b57cec5SDimitry Andric       IsWritten(false), SourceOrder(0) {}
26610b57cec5SDimitry Andric 
26620b57cec5SDimitry Andric CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
26630b57cec5SDimitry Andric                                        IndirectFieldDecl *Member,
26640b57cec5SDimitry Andric                                        SourceLocation MemberLoc,
26650b57cec5SDimitry Andric                                        SourceLocation L, Expr *Init,
26660b57cec5SDimitry Andric                                        SourceLocation R)
2667fe6060f1SDimitry Andric     : Initializee(Member), Init(Init), MemberOrEllipsisLocation(MemberLoc),
26680b57cec5SDimitry Andric       LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
26690b57cec5SDimitry Andric       IsWritten(false), SourceOrder(0) {}
26700b57cec5SDimitry Andric 
26710b57cec5SDimitry Andric CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
26720b57cec5SDimitry Andric                                        TypeSourceInfo *TInfo,
26730b57cec5SDimitry Andric                                        SourceLocation L, Expr *Init,
26740b57cec5SDimitry Andric                                        SourceLocation R)
26750b57cec5SDimitry Andric     : Initializee(TInfo), Init(Init), LParenLoc(L), RParenLoc(R),
26760b57cec5SDimitry Andric       IsDelegating(true), IsVirtual(false), IsWritten(false), SourceOrder(0) {}
26770b57cec5SDimitry Andric 
26780b57cec5SDimitry Andric int64_t CXXCtorInitializer::getID(const ASTContext &Context) const {
26790b57cec5SDimitry Andric   return Context.getAllocator()
26800b57cec5SDimitry Andric                 .identifyKnownAlignedObject<CXXCtorInitializer>(this);
26810b57cec5SDimitry Andric }
26820b57cec5SDimitry Andric 
26830b57cec5SDimitry Andric TypeLoc CXXCtorInitializer::getBaseClassLoc() const {
26840b57cec5SDimitry Andric   if (isBaseInitializer())
26850b57cec5SDimitry Andric     return Initializee.get<TypeSourceInfo*>()->getTypeLoc();
26860b57cec5SDimitry Andric   else
26870b57cec5SDimitry Andric     return {};
26880b57cec5SDimitry Andric }
26890b57cec5SDimitry Andric 
26900b57cec5SDimitry Andric const Type *CXXCtorInitializer::getBaseClass() const {
26910b57cec5SDimitry Andric   if (isBaseInitializer())
26920b57cec5SDimitry Andric     return Initializee.get<TypeSourceInfo*>()->getType().getTypePtr();
26930b57cec5SDimitry Andric   else
26940b57cec5SDimitry Andric     return nullptr;
26950b57cec5SDimitry Andric }
26960b57cec5SDimitry Andric 
26970b57cec5SDimitry Andric SourceLocation CXXCtorInitializer::getSourceLocation() const {
26980b57cec5SDimitry Andric   if (isInClassMemberInitializer())
26990b57cec5SDimitry Andric     return getAnyMember()->getLocation();
27000b57cec5SDimitry Andric 
27010b57cec5SDimitry Andric   if (isAnyMemberInitializer())
27020b57cec5SDimitry Andric     return getMemberLocation();
27030b57cec5SDimitry Andric 
27040b57cec5SDimitry Andric   if (const auto *TSInfo = Initializee.get<TypeSourceInfo *>())
2705bdd1243dSDimitry Andric     return TSInfo->getTypeLoc().getBeginLoc();
27060b57cec5SDimitry Andric 
27070b57cec5SDimitry Andric   return {};
27080b57cec5SDimitry Andric }
27090b57cec5SDimitry Andric 
27100b57cec5SDimitry Andric SourceRange CXXCtorInitializer::getSourceRange() const {
27110b57cec5SDimitry Andric   if (isInClassMemberInitializer()) {
27120b57cec5SDimitry Andric     FieldDecl *D = getAnyMember();
27130b57cec5SDimitry Andric     if (Expr *I = D->getInClassInitializer())
27140b57cec5SDimitry Andric       return I->getSourceRange();
27150b57cec5SDimitry Andric     return {};
27160b57cec5SDimitry Andric   }
27170b57cec5SDimitry Andric 
27180b57cec5SDimitry Andric   return SourceRange(getSourceLocation(), getRParenLoc());
27190b57cec5SDimitry Andric }
27200b57cec5SDimitry Andric 
27210b57cec5SDimitry Andric CXXConstructorDecl::CXXConstructorDecl(
27220b57cec5SDimitry Andric     ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
27230b57cec5SDimitry Andric     const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
2724349cc55cSDimitry Andric     ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
2725349cc55cSDimitry Andric     bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
2726349cc55cSDimitry Andric     InheritedConstructor Inherited, Expr *TrailingRequiresClause)
27270b57cec5SDimitry Andric     : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
2728349cc55cSDimitry Andric                     SC_None, UsesFPIntrin, isInline, ConstexprKind,
2729349cc55cSDimitry Andric                     SourceLocation(), TrailingRequiresClause) {
27300b57cec5SDimitry Andric   setNumCtorInitializers(0);
27310b57cec5SDimitry Andric   setInheritingConstructor(static_cast<bool>(Inherited));
27320b57cec5SDimitry Andric   setImplicit(isImplicitlyDeclared);
27330b57cec5SDimitry Andric   CXXConstructorDeclBits.HasTrailingExplicitSpecifier = ES.getExpr() ? 1 : 0;
27340b57cec5SDimitry Andric   if (Inherited)
27350b57cec5SDimitry Andric     *getTrailingObjects<InheritedConstructor>() = Inherited;
27360b57cec5SDimitry Andric   setExplicitSpecifier(ES);
27370b57cec5SDimitry Andric }
27380b57cec5SDimitry Andric 
27390b57cec5SDimitry Andric void CXXConstructorDecl::anchor() {}
27400b57cec5SDimitry Andric 
27410b57cec5SDimitry Andric CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C,
27420fca6ea1SDimitry Andric                                                            GlobalDeclID ID,
27430b57cec5SDimitry Andric                                                            uint64_t AllocKind) {
2744fe6060f1SDimitry Andric   bool hasTrailingExplicit = static_cast<bool>(AllocKind & TAKHasTailExplicit);
27450b57cec5SDimitry Andric   bool isInheritingConstructor =
27460b57cec5SDimitry Andric       static_cast<bool>(AllocKind & TAKInheritsConstructor);
27470b57cec5SDimitry Andric   unsigned Extra =
27480b57cec5SDimitry Andric       additionalSizeToAlloc<InheritedConstructor, ExplicitSpecifier>(
2749fe6060f1SDimitry Andric           isInheritingConstructor, hasTrailingExplicit);
2750e8d8bef9SDimitry Andric   auto *Result = new (C, ID, Extra) CXXConstructorDecl(
2751e8d8bef9SDimitry Andric       C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
2752349cc55cSDimitry Andric       ExplicitSpecifier(), false, false, false, ConstexprSpecKind::Unspecified,
2753e8d8bef9SDimitry Andric       InheritedConstructor(), nullptr);
27540b57cec5SDimitry Andric   Result->setInheritingConstructor(isInheritingConstructor);
27550b57cec5SDimitry Andric   Result->CXXConstructorDeclBits.HasTrailingExplicitSpecifier =
2756fe6060f1SDimitry Andric       hasTrailingExplicit;
27570b57cec5SDimitry Andric   Result->setExplicitSpecifier(ExplicitSpecifier());
27580b57cec5SDimitry Andric   return Result;
27590b57cec5SDimitry Andric }
27600b57cec5SDimitry Andric 
27610b57cec5SDimitry Andric CXXConstructorDecl *CXXConstructorDecl::Create(
27620b57cec5SDimitry Andric     ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
27630b57cec5SDimitry Andric     const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
2764349cc55cSDimitry Andric     ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline,
2765349cc55cSDimitry Andric     bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind,
2766349cc55cSDimitry Andric     InheritedConstructor Inherited, Expr *TrailingRequiresClause) {
27670b57cec5SDimitry Andric   assert(NameInfo.getName().getNameKind()
27680b57cec5SDimitry Andric          == DeclarationName::CXXConstructorName &&
27690b57cec5SDimitry Andric          "Name must refer to a constructor");
27700b57cec5SDimitry Andric   unsigned Extra =
27710b57cec5SDimitry Andric       additionalSizeToAlloc<InheritedConstructor, ExplicitSpecifier>(
27720b57cec5SDimitry Andric           Inherited ? 1 : 0, ES.getExpr() ? 1 : 0);
2773349cc55cSDimitry Andric   return new (C, RD, Extra) CXXConstructorDecl(
2774349cc55cSDimitry Andric       C, RD, StartLoc, NameInfo, T, TInfo, ES, UsesFPIntrin, isInline,
2775349cc55cSDimitry Andric       isImplicitlyDeclared, ConstexprKind, Inherited, TrailingRequiresClause);
27760b57cec5SDimitry Andric }
27770b57cec5SDimitry Andric 
27780b57cec5SDimitry Andric CXXConstructorDecl::init_const_iterator CXXConstructorDecl::init_begin() const {
27790b57cec5SDimitry Andric   return CtorInitializers.get(getASTContext().getExternalSource());
27800b57cec5SDimitry Andric }
27810b57cec5SDimitry Andric 
27820b57cec5SDimitry Andric CXXConstructorDecl *CXXConstructorDecl::getTargetConstructor() const {
27830b57cec5SDimitry Andric   assert(isDelegatingConstructor() && "Not a delegating constructor!");
27840b57cec5SDimitry Andric   Expr *E = (*init_begin())->getInit()->IgnoreImplicit();
27850b57cec5SDimitry Andric   if (const auto *Construct = dyn_cast<CXXConstructExpr>(E))
27860b57cec5SDimitry Andric     return Construct->getConstructor();
27870b57cec5SDimitry Andric 
27880b57cec5SDimitry Andric   return nullptr;
27890b57cec5SDimitry Andric }
27900b57cec5SDimitry Andric 
27910b57cec5SDimitry Andric bool CXXConstructorDecl::isDefaultConstructor() const {
27925ffd83dbSDimitry Andric   // C++ [class.default.ctor]p1:
27935ffd83dbSDimitry Andric   //   A default constructor for a class X is a constructor of class X for
27945ffd83dbSDimitry Andric   //   which each parameter that is not a function parameter pack has a default
27955ffd83dbSDimitry Andric   //   argument (including the case of a constructor with no parameters)
27965ffd83dbSDimitry Andric   return getMinRequiredArguments() == 0;
27970b57cec5SDimitry Andric }
27980b57cec5SDimitry Andric 
27990b57cec5SDimitry Andric bool
28000b57cec5SDimitry Andric CXXConstructorDecl::isCopyConstructor(unsigned &TypeQuals) const {
28010b57cec5SDimitry Andric   return isCopyOrMoveConstructor(TypeQuals) &&
28020b57cec5SDimitry Andric          getParamDecl(0)->getType()->isLValueReferenceType();
28030b57cec5SDimitry Andric }
28040b57cec5SDimitry Andric 
28050b57cec5SDimitry Andric bool CXXConstructorDecl::isMoveConstructor(unsigned &TypeQuals) const {
28060b57cec5SDimitry Andric   return isCopyOrMoveConstructor(TypeQuals) &&
28070b57cec5SDimitry Andric          getParamDecl(0)->getType()->isRValueReferenceType();
28080b57cec5SDimitry Andric }
28090b57cec5SDimitry Andric 
28100b57cec5SDimitry Andric /// Determine whether this is a copy or move constructor.
28110b57cec5SDimitry Andric bool CXXConstructorDecl::isCopyOrMoveConstructor(unsigned &TypeQuals) const {
28120b57cec5SDimitry Andric   // C++ [class.copy]p2:
28130b57cec5SDimitry Andric   //   A non-template constructor for class X is a copy constructor
28140b57cec5SDimitry Andric   //   if its first parameter is of type X&, const X&, volatile X& or
28150b57cec5SDimitry Andric   //   const volatile X&, and either there are no other parameters
28160b57cec5SDimitry Andric   //   or else all other parameters have default arguments (8.3.6).
28170b57cec5SDimitry Andric   // C++0x [class.copy]p3:
28180b57cec5SDimitry Andric   //   A non-template constructor for class X is a move constructor if its
28190b57cec5SDimitry Andric   //   first parameter is of type X&&, const X&&, volatile X&&, or
28200b57cec5SDimitry Andric   //   const volatile X&&, and either there are no other parameters or else
28210b57cec5SDimitry Andric   //   all other parameters have default arguments.
28225ffd83dbSDimitry Andric   if (!hasOneParamOrDefaultArgs() || getPrimaryTemplate() != nullptr ||
28235ffd83dbSDimitry Andric       getDescribedFunctionTemplate() != nullptr)
28240b57cec5SDimitry Andric     return false;
28250b57cec5SDimitry Andric 
28260b57cec5SDimitry Andric   const ParmVarDecl *Param = getParamDecl(0);
28270b57cec5SDimitry Andric 
28280b57cec5SDimitry Andric   // Do we have a reference type?
28290b57cec5SDimitry Andric   const auto *ParamRefType = Param->getType()->getAs<ReferenceType>();
28300b57cec5SDimitry Andric   if (!ParamRefType)
28310b57cec5SDimitry Andric     return false;
28320b57cec5SDimitry Andric 
28330b57cec5SDimitry Andric   // Is it a reference to our class type?
28340b57cec5SDimitry Andric   ASTContext &Context = getASTContext();
28350b57cec5SDimitry Andric 
28360b57cec5SDimitry Andric   CanQualType PointeeType
28370b57cec5SDimitry Andric     = Context.getCanonicalType(ParamRefType->getPointeeType());
28380b57cec5SDimitry Andric   CanQualType ClassTy
28390b57cec5SDimitry Andric     = Context.getCanonicalType(Context.getTagDeclType(getParent()));
28400b57cec5SDimitry Andric   if (PointeeType.getUnqualifiedType() != ClassTy)
28410b57cec5SDimitry Andric     return false;
28420b57cec5SDimitry Andric 
28430b57cec5SDimitry Andric   // FIXME: other qualifiers?
28440b57cec5SDimitry Andric 
28450b57cec5SDimitry Andric   // We have a copy or move constructor.
28460b57cec5SDimitry Andric   TypeQuals = PointeeType.getCVRQualifiers();
28470b57cec5SDimitry Andric   return true;
28480b57cec5SDimitry Andric }
28490b57cec5SDimitry Andric 
28500b57cec5SDimitry Andric bool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const {
28510b57cec5SDimitry Andric   // C++ [class.conv.ctor]p1:
28520b57cec5SDimitry Andric   //   A constructor declared without the function-specifier explicit
28530b57cec5SDimitry Andric   //   that can be called with a single parameter specifies a
28540b57cec5SDimitry Andric   //   conversion from the type of its first parameter to the type of
28550b57cec5SDimitry Andric   //   its class. Such a constructor is called a converting
28560b57cec5SDimitry Andric   //   constructor.
28570b57cec5SDimitry Andric   if (isExplicit() && !AllowExplicit)
28580b57cec5SDimitry Andric     return false;
28590b57cec5SDimitry Andric 
28605ffd83dbSDimitry Andric   // FIXME: This has nothing to do with the definition of converting
28615ffd83dbSDimitry Andric   // constructor, but is convenient for how we use this function in overload
28625ffd83dbSDimitry Andric   // resolution.
28635ffd83dbSDimitry Andric   return getNumParams() == 0
28645ffd83dbSDimitry Andric              ? getType()->castAs<FunctionProtoType>()->isVariadic()
28655ffd83dbSDimitry Andric              : getMinRequiredArguments() <= 1;
28660b57cec5SDimitry Andric }
28670b57cec5SDimitry Andric 
28680b57cec5SDimitry Andric bool CXXConstructorDecl::isSpecializationCopyingObject() const {
28695ffd83dbSDimitry Andric   if (!hasOneParamOrDefaultArgs() || getDescribedFunctionTemplate() != nullptr)
28700b57cec5SDimitry Andric     return false;
28710b57cec5SDimitry Andric 
28720b57cec5SDimitry Andric   const ParmVarDecl *Param = getParamDecl(0);
28730b57cec5SDimitry Andric 
28740b57cec5SDimitry Andric   ASTContext &Context = getASTContext();
28750b57cec5SDimitry Andric   CanQualType ParamType = Context.getCanonicalType(Param->getType());
28760b57cec5SDimitry Andric 
28770b57cec5SDimitry Andric   // Is it the same as our class type?
28780b57cec5SDimitry Andric   CanQualType ClassTy
28790b57cec5SDimitry Andric     = Context.getCanonicalType(Context.getTagDeclType(getParent()));
28800b57cec5SDimitry Andric   if (ParamType.getUnqualifiedType() != ClassTy)
28810b57cec5SDimitry Andric     return false;
28820b57cec5SDimitry Andric 
28830b57cec5SDimitry Andric   return true;
28840b57cec5SDimitry Andric }
28850b57cec5SDimitry Andric 
28860b57cec5SDimitry Andric void CXXDestructorDecl::anchor() {}
28870b57cec5SDimitry Andric 
28880fca6ea1SDimitry Andric CXXDestructorDecl *CXXDestructorDecl::CreateDeserialized(ASTContext &C,
28890fca6ea1SDimitry Andric                                                          GlobalDeclID ID) {
2890e8d8bef9SDimitry Andric   return new (C, ID) CXXDestructorDecl(
2891e8d8bef9SDimitry Andric       C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
2892349cc55cSDimitry Andric       false, false, false, ConstexprSpecKind::Unspecified, nullptr);
28930b57cec5SDimitry Andric }
28940b57cec5SDimitry Andric 
2895a7dea167SDimitry Andric CXXDestructorDecl *CXXDestructorDecl::Create(
2896a7dea167SDimitry Andric     ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
2897a7dea167SDimitry Andric     const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
2898349cc55cSDimitry Andric     bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared,
2899349cc55cSDimitry Andric     ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause) {
29000b57cec5SDimitry Andric   assert(NameInfo.getName().getNameKind()
29010b57cec5SDimitry Andric          == DeclarationName::CXXDestructorName &&
29020b57cec5SDimitry Andric          "Name must refer to a destructor");
2903349cc55cSDimitry Andric   return new (C, RD) CXXDestructorDecl(
2904349cc55cSDimitry Andric       C, RD, StartLoc, NameInfo, T, TInfo, UsesFPIntrin, isInline,
2905349cc55cSDimitry Andric       isImplicitlyDeclared, ConstexprKind, TrailingRequiresClause);
29060b57cec5SDimitry Andric }
29070b57cec5SDimitry Andric 
29080b57cec5SDimitry Andric void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) {
29090b57cec5SDimitry Andric   auto *First = cast<CXXDestructorDecl>(getFirstDecl());
29100b57cec5SDimitry Andric   if (OD && !First->OperatorDelete) {
29110b57cec5SDimitry Andric     First->OperatorDelete = OD;
29120b57cec5SDimitry Andric     First->OperatorDeleteThisArg = ThisArg;
29130b57cec5SDimitry Andric     if (auto *L = getASTMutationListener())
29140b57cec5SDimitry Andric       L->ResolvedOperatorDelete(First, OD, ThisArg);
29150b57cec5SDimitry Andric   }
29160b57cec5SDimitry Andric }
29170b57cec5SDimitry Andric 
29180b57cec5SDimitry Andric void CXXConversionDecl::anchor() {}
29190b57cec5SDimitry Andric 
29200fca6ea1SDimitry Andric CXXConversionDecl *CXXConversionDecl::CreateDeserialized(ASTContext &C,
29210fca6ea1SDimitry Andric                                                          GlobalDeclID ID) {
29220b57cec5SDimitry Andric   return new (C, ID) CXXConversionDecl(
29230b57cec5SDimitry Andric       C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
2924349cc55cSDimitry Andric       false, false, ExplicitSpecifier(), ConstexprSpecKind::Unspecified,
2925e8d8bef9SDimitry Andric       SourceLocation(), nullptr);
29260b57cec5SDimitry Andric }
29270b57cec5SDimitry Andric 
29280b57cec5SDimitry Andric CXXConversionDecl *CXXConversionDecl::Create(
29290b57cec5SDimitry Andric     ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
29300b57cec5SDimitry Andric     const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
2931349cc55cSDimitry Andric     bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES,
2932349cc55cSDimitry Andric     ConstexprSpecKind ConstexprKind, SourceLocation EndLocation,
2933349cc55cSDimitry Andric     Expr *TrailingRequiresClause) {
29340b57cec5SDimitry Andric   assert(NameInfo.getName().getNameKind()
29350b57cec5SDimitry Andric          == DeclarationName::CXXConversionFunctionName &&
29360b57cec5SDimitry Andric          "Name must refer to a conversion function");
2937349cc55cSDimitry Andric   return new (C, RD) CXXConversionDecl(
2938349cc55cSDimitry Andric       C, RD, StartLoc, NameInfo, T, TInfo, UsesFPIntrin, isInline, ES,
2939480093f4SDimitry Andric       ConstexprKind, EndLocation, TrailingRequiresClause);
29400b57cec5SDimitry Andric }
29410b57cec5SDimitry Andric 
29420b57cec5SDimitry Andric bool CXXConversionDecl::isLambdaToBlockPointerConversion() const {
29430b57cec5SDimitry Andric   return isImplicit() && getParent()->isLambda() &&
29440b57cec5SDimitry Andric          getConversionType()->isBlockPointerType();
29450b57cec5SDimitry Andric }
29460b57cec5SDimitry Andric 
29470b57cec5SDimitry Andric LinkageSpecDecl::LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
29485f757f3fSDimitry Andric                                  SourceLocation LangLoc,
29495f757f3fSDimitry Andric                                  LinkageSpecLanguageIDs lang, bool HasBraces)
29500b57cec5SDimitry Andric     : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
29510b57cec5SDimitry Andric       ExternLoc(ExternLoc), RBraceLoc(SourceLocation()) {
29520b57cec5SDimitry Andric   setLanguage(lang);
29530b57cec5SDimitry Andric   LinkageSpecDeclBits.HasBraces = HasBraces;
29540b57cec5SDimitry Andric }
29550b57cec5SDimitry Andric 
29560b57cec5SDimitry Andric void LinkageSpecDecl::anchor() {}
29570b57cec5SDimitry Andric 
29585f757f3fSDimitry Andric LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, DeclContext *DC,
29590b57cec5SDimitry Andric                                          SourceLocation ExternLoc,
29600b57cec5SDimitry Andric                                          SourceLocation LangLoc,
29615f757f3fSDimitry Andric                                          LinkageSpecLanguageIDs Lang,
29620b57cec5SDimitry Andric                                          bool HasBraces) {
29630b57cec5SDimitry Andric   return new (C, DC) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces);
29640b57cec5SDimitry Andric }
29650b57cec5SDimitry Andric 
29660b57cec5SDimitry Andric LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C,
29670fca6ea1SDimitry Andric                                                      GlobalDeclID ID) {
29685f757f3fSDimitry Andric   return new (C, ID)
29695f757f3fSDimitry Andric       LinkageSpecDecl(nullptr, SourceLocation(), SourceLocation(),
29705f757f3fSDimitry Andric                       LinkageSpecLanguageIDs::C, false);
29710b57cec5SDimitry Andric }
29720b57cec5SDimitry Andric 
29730b57cec5SDimitry Andric void UsingDirectiveDecl::anchor() {}
29740b57cec5SDimitry Andric 
29750b57cec5SDimitry Andric UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
29760b57cec5SDimitry Andric                                                SourceLocation L,
29770b57cec5SDimitry Andric                                                SourceLocation NamespaceLoc,
29780b57cec5SDimitry Andric                                            NestedNameSpecifierLoc QualifierLoc,
29790b57cec5SDimitry Andric                                                SourceLocation IdentLoc,
29800b57cec5SDimitry Andric                                                NamedDecl *Used,
29810b57cec5SDimitry Andric                                                DeclContext *CommonAncestor) {
29820b57cec5SDimitry Andric   if (auto *NS = dyn_cast_or_null<NamespaceDecl>(Used))
29830fca6ea1SDimitry Andric     Used = NS->getFirstDecl();
29840b57cec5SDimitry Andric   return new (C, DC) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierLoc,
29850b57cec5SDimitry Andric                                         IdentLoc, Used, CommonAncestor);
29860b57cec5SDimitry Andric }
29870b57cec5SDimitry Andric 
29880b57cec5SDimitry Andric UsingDirectiveDecl *UsingDirectiveDecl::CreateDeserialized(ASTContext &C,
29890fca6ea1SDimitry Andric                                                            GlobalDeclID ID) {
29900b57cec5SDimitry Andric   return new (C, ID) UsingDirectiveDecl(nullptr, SourceLocation(),
29910b57cec5SDimitry Andric                                         SourceLocation(),
29920b57cec5SDimitry Andric                                         NestedNameSpecifierLoc(),
29930b57cec5SDimitry Andric                                         SourceLocation(), nullptr, nullptr);
29940b57cec5SDimitry Andric }
29950b57cec5SDimitry Andric 
29960b57cec5SDimitry Andric NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
29970b57cec5SDimitry Andric   if (auto *NA = dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace))
29980b57cec5SDimitry Andric     return NA->getNamespace();
29990b57cec5SDimitry Andric   return cast_or_null<NamespaceDecl>(NominatedNamespace);
30000b57cec5SDimitry Andric }
30010b57cec5SDimitry Andric 
30020b57cec5SDimitry Andric NamespaceDecl::NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
30030b57cec5SDimitry Andric                              SourceLocation StartLoc, SourceLocation IdLoc,
3004bdd1243dSDimitry Andric                              IdentifierInfo *Id, NamespaceDecl *PrevDecl,
3005bdd1243dSDimitry Andric                              bool Nested)
30060b57cec5SDimitry Andric     : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
3007bdd1243dSDimitry Andric       redeclarable_base(C), LocStart(StartLoc) {
30080fca6ea1SDimitry Andric   setInline(Inline);
30090fca6ea1SDimitry Andric   setNested(Nested);
30100b57cec5SDimitry Andric   setPreviousDecl(PrevDecl);
30110b57cec5SDimitry Andric }
30120b57cec5SDimitry Andric 
30130b57cec5SDimitry Andric NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
30140b57cec5SDimitry Andric                                      bool Inline, SourceLocation StartLoc,
30150b57cec5SDimitry Andric                                      SourceLocation IdLoc, IdentifierInfo *Id,
3016bdd1243dSDimitry Andric                                      NamespaceDecl *PrevDecl, bool Nested) {
3017bdd1243dSDimitry Andric   return new (C, DC)
3018bdd1243dSDimitry Andric       NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id, PrevDecl, Nested);
30190b57cec5SDimitry Andric }
30200b57cec5SDimitry Andric 
30210fca6ea1SDimitry Andric NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C,
30220fca6ea1SDimitry Andric                                                  GlobalDeclID ID) {
30230b57cec5SDimitry Andric   return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(),
3024bdd1243dSDimitry Andric                                    SourceLocation(), nullptr, nullptr, false);
30250b57cec5SDimitry Andric }
30260b57cec5SDimitry Andric 
30270b57cec5SDimitry Andric NamespaceDecl *NamespaceDecl::getNextRedeclarationImpl() {
30280b57cec5SDimitry Andric   return getNextRedeclaration();
30290b57cec5SDimitry Andric }
30300b57cec5SDimitry Andric 
30310b57cec5SDimitry Andric NamespaceDecl *NamespaceDecl::getPreviousDeclImpl() {
30320b57cec5SDimitry Andric   return getPreviousDecl();
30330b57cec5SDimitry Andric }
30340b57cec5SDimitry Andric 
30350b57cec5SDimitry Andric NamespaceDecl *NamespaceDecl::getMostRecentDeclImpl() {
30360b57cec5SDimitry Andric   return getMostRecentDecl();
30370b57cec5SDimitry Andric }
30380b57cec5SDimitry Andric 
30390b57cec5SDimitry Andric void NamespaceAliasDecl::anchor() {}
30400b57cec5SDimitry Andric 
30410b57cec5SDimitry Andric NamespaceAliasDecl *NamespaceAliasDecl::getNextRedeclarationImpl() {
30420b57cec5SDimitry Andric   return getNextRedeclaration();
30430b57cec5SDimitry Andric }
30440b57cec5SDimitry Andric 
30450b57cec5SDimitry Andric NamespaceAliasDecl *NamespaceAliasDecl::getPreviousDeclImpl() {
30460b57cec5SDimitry Andric   return getPreviousDecl();
30470b57cec5SDimitry Andric }
30480b57cec5SDimitry Andric 
30490b57cec5SDimitry Andric NamespaceAliasDecl *NamespaceAliasDecl::getMostRecentDeclImpl() {
30500b57cec5SDimitry Andric   return getMostRecentDecl();
30510b57cec5SDimitry Andric }
30520b57cec5SDimitry Andric 
30530b57cec5SDimitry Andric NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
30540b57cec5SDimitry Andric                                                SourceLocation UsingLoc,
30550b57cec5SDimitry Andric                                                SourceLocation AliasLoc,
30560b57cec5SDimitry Andric                                                IdentifierInfo *Alias,
30570b57cec5SDimitry Andric                                            NestedNameSpecifierLoc QualifierLoc,
30580b57cec5SDimitry Andric                                                SourceLocation IdentLoc,
30590b57cec5SDimitry Andric                                                NamedDecl *Namespace) {
30600b57cec5SDimitry Andric   // FIXME: Preserve the aliased namespace as written.
30610b57cec5SDimitry Andric   if (auto *NS = dyn_cast_or_null<NamespaceDecl>(Namespace))
30620fca6ea1SDimitry Andric     Namespace = NS->getFirstDecl();
30630b57cec5SDimitry Andric   return new (C, DC) NamespaceAliasDecl(C, DC, UsingLoc, AliasLoc, Alias,
30640b57cec5SDimitry Andric                                         QualifierLoc, IdentLoc, Namespace);
30650b57cec5SDimitry Andric }
30660b57cec5SDimitry Andric 
30670fca6ea1SDimitry Andric NamespaceAliasDecl *NamespaceAliasDecl::CreateDeserialized(ASTContext &C,
30680fca6ea1SDimitry Andric                                                            GlobalDeclID ID) {
30690b57cec5SDimitry Andric   return new (C, ID) NamespaceAliasDecl(C, nullptr, SourceLocation(),
30700b57cec5SDimitry Andric                                         SourceLocation(), nullptr,
30710b57cec5SDimitry Andric                                         NestedNameSpecifierLoc(),
30720b57cec5SDimitry Andric                                         SourceLocation(), nullptr);
30730b57cec5SDimitry Andric }
30740b57cec5SDimitry Andric 
3075480093f4SDimitry Andric void LifetimeExtendedTemporaryDecl::anchor() {}
3076480093f4SDimitry Andric 
3077480093f4SDimitry Andric /// Retrieve the storage duration for the materialized temporary.
3078480093f4SDimitry Andric StorageDuration LifetimeExtendedTemporaryDecl::getStorageDuration() const {
3079480093f4SDimitry Andric   const ValueDecl *ExtendingDecl = getExtendingDecl();
3080480093f4SDimitry Andric   if (!ExtendingDecl)
3081480093f4SDimitry Andric     return SD_FullExpression;
3082480093f4SDimitry Andric   // FIXME: This is not necessarily correct for a temporary materialized
3083480093f4SDimitry Andric   // within a default initializer.
3084480093f4SDimitry Andric   if (isa<FieldDecl>(ExtendingDecl))
3085480093f4SDimitry Andric     return SD_Automatic;
3086480093f4SDimitry Andric   // FIXME: This only works because storage class specifiers are not allowed
3087480093f4SDimitry Andric   // on decomposition declarations.
3088480093f4SDimitry Andric   if (isa<BindingDecl>(ExtendingDecl))
3089480093f4SDimitry Andric     return ExtendingDecl->getDeclContext()->isFunctionOrMethod() ? SD_Automatic
3090480093f4SDimitry Andric                                                                  : SD_Static;
3091480093f4SDimitry Andric   return cast<VarDecl>(ExtendingDecl)->getStorageDuration();
3092480093f4SDimitry Andric }
3093480093f4SDimitry Andric 
3094480093f4SDimitry Andric APValue *LifetimeExtendedTemporaryDecl::getOrCreateValue(bool MayCreate) const {
3095480093f4SDimitry Andric   assert(getStorageDuration() == SD_Static &&
3096480093f4SDimitry Andric          "don't need to cache the computed value for this temporary");
3097480093f4SDimitry Andric   if (MayCreate && !Value) {
3098480093f4SDimitry Andric     Value = (new (getASTContext()) APValue);
3099480093f4SDimitry Andric     getASTContext().addDestruction(Value);
3100480093f4SDimitry Andric   }
3101480093f4SDimitry Andric   assert(Value && "may not be null");
3102480093f4SDimitry Andric   return Value;
3103480093f4SDimitry Andric }
3104480093f4SDimitry Andric 
31050b57cec5SDimitry Andric void UsingShadowDecl::anchor() {}
31060b57cec5SDimitry Andric 
31070b57cec5SDimitry Andric UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC,
3108fe6060f1SDimitry Andric                                  SourceLocation Loc, DeclarationName Name,
3109fe6060f1SDimitry Andric                                  BaseUsingDecl *Introducer, NamedDecl *Target)
3110fe6060f1SDimitry Andric     : NamedDecl(K, DC, Loc, Name), redeclarable_base(C),
3111fe6060f1SDimitry Andric       UsingOrNextShadow(Introducer) {
311281ad6265SDimitry Andric   if (Target) {
311381ad6265SDimitry Andric     assert(!isa<UsingShadowDecl>(Target));
31140b57cec5SDimitry Andric     setTargetDecl(Target);
311581ad6265SDimitry Andric   }
31160b57cec5SDimitry Andric   setImplicit();
31170b57cec5SDimitry Andric }
31180b57cec5SDimitry Andric 
31190b57cec5SDimitry Andric UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, EmptyShell Empty)
31200b57cec5SDimitry Andric     : NamedDecl(K, nullptr, SourceLocation(), DeclarationName()),
31210b57cec5SDimitry Andric       redeclarable_base(C) {}
31220b57cec5SDimitry Andric 
31230fca6ea1SDimitry Andric UsingShadowDecl *UsingShadowDecl::CreateDeserialized(ASTContext &C,
31240fca6ea1SDimitry Andric                                                      GlobalDeclID ID) {
31250b57cec5SDimitry Andric   return new (C, ID) UsingShadowDecl(UsingShadow, C, EmptyShell());
31260b57cec5SDimitry Andric }
31270b57cec5SDimitry Andric 
3128fe6060f1SDimitry Andric BaseUsingDecl *UsingShadowDecl::getIntroducer() const {
31290b57cec5SDimitry Andric   const UsingShadowDecl *Shadow = this;
31300b57cec5SDimitry Andric   while (const auto *NextShadow =
31310b57cec5SDimitry Andric              dyn_cast<UsingShadowDecl>(Shadow->UsingOrNextShadow))
31320b57cec5SDimitry Andric     Shadow = NextShadow;
3133fe6060f1SDimitry Andric   return cast<BaseUsingDecl>(Shadow->UsingOrNextShadow);
31340b57cec5SDimitry Andric }
31350b57cec5SDimitry Andric 
31360b57cec5SDimitry Andric void ConstructorUsingShadowDecl::anchor() {}
31370b57cec5SDimitry Andric 
31380b57cec5SDimitry Andric ConstructorUsingShadowDecl *
31390b57cec5SDimitry Andric ConstructorUsingShadowDecl::Create(ASTContext &C, DeclContext *DC,
31400b57cec5SDimitry Andric                                    SourceLocation Loc, UsingDecl *Using,
31410b57cec5SDimitry Andric                                    NamedDecl *Target, bool IsVirtual) {
31420b57cec5SDimitry Andric   return new (C, DC) ConstructorUsingShadowDecl(C, DC, Loc, Using, Target,
31430b57cec5SDimitry Andric                                                 IsVirtual);
31440b57cec5SDimitry Andric }
31450b57cec5SDimitry Andric 
31460b57cec5SDimitry Andric ConstructorUsingShadowDecl *
31470fca6ea1SDimitry Andric ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
31480b57cec5SDimitry Andric   return new (C, ID) ConstructorUsingShadowDecl(C, EmptyShell());
31490b57cec5SDimitry Andric }
31500b57cec5SDimitry Andric 
31510b57cec5SDimitry Andric CXXRecordDecl *ConstructorUsingShadowDecl::getNominatedBaseClass() const {
3152fe6060f1SDimitry Andric   return getIntroducer()->getQualifier()->getAsRecordDecl();
31530b57cec5SDimitry Andric }
31540b57cec5SDimitry Andric 
3155fe6060f1SDimitry Andric void BaseUsingDecl::anchor() {}
31560b57cec5SDimitry Andric 
3157fe6060f1SDimitry Andric void BaseUsingDecl::addShadowDecl(UsingShadowDecl *S) {
3158349cc55cSDimitry Andric   assert(!llvm::is_contained(shadows(), S) && "declaration already in set");
3159fe6060f1SDimitry Andric   assert(S->getIntroducer() == this);
31600b57cec5SDimitry Andric 
31610b57cec5SDimitry Andric   if (FirstUsingShadow.getPointer())
31620b57cec5SDimitry Andric     S->UsingOrNextShadow = FirstUsingShadow.getPointer();
31630b57cec5SDimitry Andric   FirstUsingShadow.setPointer(S);
31640b57cec5SDimitry Andric }
31650b57cec5SDimitry Andric 
3166fe6060f1SDimitry Andric void BaseUsingDecl::removeShadowDecl(UsingShadowDecl *S) {
3167349cc55cSDimitry Andric   assert(llvm::is_contained(shadows(), S) && "declaration not in set");
3168fe6060f1SDimitry Andric   assert(S->getIntroducer() == this);
31690b57cec5SDimitry Andric 
31700b57cec5SDimitry Andric   // Remove S from the shadow decl chain. This is O(n) but hopefully rare.
31710b57cec5SDimitry Andric 
31720b57cec5SDimitry Andric   if (FirstUsingShadow.getPointer() == S) {
31730b57cec5SDimitry Andric     FirstUsingShadow.setPointer(
31740b57cec5SDimitry Andric       dyn_cast<UsingShadowDecl>(S->UsingOrNextShadow));
31750b57cec5SDimitry Andric     S->UsingOrNextShadow = this;
31760b57cec5SDimitry Andric     return;
31770b57cec5SDimitry Andric   }
31780b57cec5SDimitry Andric 
31790b57cec5SDimitry Andric   UsingShadowDecl *Prev = FirstUsingShadow.getPointer();
31800b57cec5SDimitry Andric   while (Prev->UsingOrNextShadow != S)
31810b57cec5SDimitry Andric     Prev = cast<UsingShadowDecl>(Prev->UsingOrNextShadow);
31820b57cec5SDimitry Andric   Prev->UsingOrNextShadow = S->UsingOrNextShadow;
31830b57cec5SDimitry Andric   S->UsingOrNextShadow = this;
31840b57cec5SDimitry Andric }
31850b57cec5SDimitry Andric 
3186fe6060f1SDimitry Andric void UsingDecl::anchor() {}
3187fe6060f1SDimitry Andric 
31880b57cec5SDimitry Andric UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL,
31890b57cec5SDimitry Andric                              NestedNameSpecifierLoc QualifierLoc,
31900b57cec5SDimitry Andric                              const DeclarationNameInfo &NameInfo,
31910b57cec5SDimitry Andric                              bool HasTypename) {
31920b57cec5SDimitry Andric   return new (C, DC) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename);
31930b57cec5SDimitry Andric }
31940b57cec5SDimitry Andric 
31950fca6ea1SDimitry Andric UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
31960b57cec5SDimitry Andric   return new (C, ID) UsingDecl(nullptr, SourceLocation(),
31970b57cec5SDimitry Andric                                NestedNameSpecifierLoc(), DeclarationNameInfo(),
31980b57cec5SDimitry Andric                                false);
31990b57cec5SDimitry Andric }
32000b57cec5SDimitry Andric 
32010b57cec5SDimitry Andric SourceRange UsingDecl::getSourceRange() const {
32020b57cec5SDimitry Andric   SourceLocation Begin = isAccessDeclaration()
32030b57cec5SDimitry Andric     ? getQualifierLoc().getBeginLoc() : UsingLocation;
32040b57cec5SDimitry Andric   return SourceRange(Begin, getNameInfo().getEndLoc());
32050b57cec5SDimitry Andric }
32060b57cec5SDimitry Andric 
3207fe6060f1SDimitry Andric void UsingEnumDecl::anchor() {}
3208fe6060f1SDimitry Andric 
3209fe6060f1SDimitry Andric UsingEnumDecl *UsingEnumDecl::Create(ASTContext &C, DeclContext *DC,
3210bdd1243dSDimitry Andric                                      SourceLocation UL,
3211bdd1243dSDimitry Andric                                      SourceLocation EL,
3212bdd1243dSDimitry Andric                                      SourceLocation NL,
3213bdd1243dSDimitry Andric                                      TypeSourceInfo *EnumType) {
3214bdd1243dSDimitry Andric   assert(isa<EnumDecl>(EnumType->getType()->getAsTagDecl()));
3215bdd1243dSDimitry Andric   return new (C, DC)
3216bdd1243dSDimitry Andric       UsingEnumDecl(DC, EnumType->getType()->getAsTagDecl()->getDeclName(), UL, EL, NL, EnumType);
3217fe6060f1SDimitry Andric }
3218fe6060f1SDimitry Andric 
32190fca6ea1SDimitry Andric UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C,
32200fca6ea1SDimitry Andric                                                  GlobalDeclID ID) {
3221bdd1243dSDimitry Andric   return new (C, ID)
3222bdd1243dSDimitry Andric       UsingEnumDecl(nullptr, DeclarationName(), SourceLocation(),
3223fe6060f1SDimitry Andric                     SourceLocation(), SourceLocation(), nullptr);
3224fe6060f1SDimitry Andric }
3225fe6060f1SDimitry Andric 
3226fe6060f1SDimitry Andric SourceRange UsingEnumDecl::getSourceRange() const {
3227bdd1243dSDimitry Andric   return SourceRange(UsingLocation, EnumType->getTypeLoc().getEndLoc());
3228fe6060f1SDimitry Andric }
3229fe6060f1SDimitry Andric 
32300b57cec5SDimitry Andric void UsingPackDecl::anchor() {}
32310b57cec5SDimitry Andric 
32320b57cec5SDimitry Andric UsingPackDecl *UsingPackDecl::Create(ASTContext &C, DeclContext *DC,
32330b57cec5SDimitry Andric                                      NamedDecl *InstantiatedFrom,
32340b57cec5SDimitry Andric                                      ArrayRef<NamedDecl *> UsingDecls) {
32350b57cec5SDimitry Andric   size_t Extra = additionalSizeToAlloc<NamedDecl *>(UsingDecls.size());
32360b57cec5SDimitry Andric   return new (C, DC, Extra) UsingPackDecl(DC, InstantiatedFrom, UsingDecls);
32370b57cec5SDimitry Andric }
32380b57cec5SDimitry Andric 
32390fca6ea1SDimitry Andric UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
32400b57cec5SDimitry Andric                                                  unsigned NumExpansions) {
32410b57cec5SDimitry Andric   size_t Extra = additionalSizeToAlloc<NamedDecl *>(NumExpansions);
3242bdd1243dSDimitry Andric   auto *Result =
3243bdd1243dSDimitry Andric       new (C, ID, Extra) UsingPackDecl(nullptr, nullptr, std::nullopt);
32440b57cec5SDimitry Andric   Result->NumExpansions = NumExpansions;
32450b57cec5SDimitry Andric   auto *Trail = Result->getTrailingObjects<NamedDecl *>();
32460b57cec5SDimitry Andric   for (unsigned I = 0; I != NumExpansions; ++I)
32470b57cec5SDimitry Andric     new (Trail + I) NamedDecl*(nullptr);
32480b57cec5SDimitry Andric   return Result;
32490b57cec5SDimitry Andric }
32500b57cec5SDimitry Andric 
32510b57cec5SDimitry Andric void UnresolvedUsingValueDecl::anchor() {}
32520b57cec5SDimitry Andric 
32530b57cec5SDimitry Andric UnresolvedUsingValueDecl *
32540b57cec5SDimitry Andric UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
32550b57cec5SDimitry Andric                                  SourceLocation UsingLoc,
32560b57cec5SDimitry Andric                                  NestedNameSpecifierLoc QualifierLoc,
32570b57cec5SDimitry Andric                                  const DeclarationNameInfo &NameInfo,
32580b57cec5SDimitry Andric                                  SourceLocation EllipsisLoc) {
32590b57cec5SDimitry Andric   return new (C, DC) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
32600b57cec5SDimitry Andric                                               QualifierLoc, NameInfo,
32610b57cec5SDimitry Andric                                               EllipsisLoc);
32620b57cec5SDimitry Andric }
32630b57cec5SDimitry Andric 
32640b57cec5SDimitry Andric UnresolvedUsingValueDecl *
32650fca6ea1SDimitry Andric UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
32660b57cec5SDimitry Andric   return new (C, ID) UnresolvedUsingValueDecl(nullptr, QualType(),
32670b57cec5SDimitry Andric                                               SourceLocation(),
32680b57cec5SDimitry Andric                                               NestedNameSpecifierLoc(),
32690b57cec5SDimitry Andric                                               DeclarationNameInfo(),
32700b57cec5SDimitry Andric                                               SourceLocation());
32710b57cec5SDimitry Andric }
32720b57cec5SDimitry Andric 
32730b57cec5SDimitry Andric SourceRange UnresolvedUsingValueDecl::getSourceRange() const {
32740b57cec5SDimitry Andric   SourceLocation Begin = isAccessDeclaration()
32750b57cec5SDimitry Andric     ? getQualifierLoc().getBeginLoc() : UsingLocation;
32760b57cec5SDimitry Andric   return SourceRange(Begin, getNameInfo().getEndLoc());
32770b57cec5SDimitry Andric }
32780b57cec5SDimitry Andric 
32790b57cec5SDimitry Andric void UnresolvedUsingTypenameDecl::anchor() {}
32800b57cec5SDimitry Andric 
32810b57cec5SDimitry Andric UnresolvedUsingTypenameDecl *
32820b57cec5SDimitry Andric UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC,
32830b57cec5SDimitry Andric                                     SourceLocation UsingLoc,
32840b57cec5SDimitry Andric                                     SourceLocation TypenameLoc,
32850b57cec5SDimitry Andric                                     NestedNameSpecifierLoc QualifierLoc,
32860b57cec5SDimitry Andric                                     SourceLocation TargetNameLoc,
32870b57cec5SDimitry Andric                                     DeclarationName TargetName,
32880b57cec5SDimitry Andric                                     SourceLocation EllipsisLoc) {
32890b57cec5SDimitry Andric   return new (C, DC) UnresolvedUsingTypenameDecl(
32900b57cec5SDimitry Andric       DC, UsingLoc, TypenameLoc, QualifierLoc, TargetNameLoc,
32910b57cec5SDimitry Andric       TargetName.getAsIdentifierInfo(), EllipsisLoc);
32920b57cec5SDimitry Andric }
32930b57cec5SDimitry Andric 
32940b57cec5SDimitry Andric UnresolvedUsingTypenameDecl *
32950fca6ea1SDimitry Andric UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C,
32960fca6ea1SDimitry Andric                                                 GlobalDeclID ID) {
32970b57cec5SDimitry Andric   return new (C, ID) UnresolvedUsingTypenameDecl(
32980b57cec5SDimitry Andric       nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(),
32990b57cec5SDimitry Andric       SourceLocation(), nullptr, SourceLocation());
33000b57cec5SDimitry Andric }
33010b57cec5SDimitry Andric 
3302fe6060f1SDimitry Andric UnresolvedUsingIfExistsDecl *
3303fe6060f1SDimitry Andric UnresolvedUsingIfExistsDecl::Create(ASTContext &Ctx, DeclContext *DC,
3304fe6060f1SDimitry Andric                                     SourceLocation Loc, DeclarationName Name) {
3305fe6060f1SDimitry Andric   return new (Ctx, DC) UnresolvedUsingIfExistsDecl(DC, Loc, Name);
3306fe6060f1SDimitry Andric }
3307fe6060f1SDimitry Andric 
3308fe6060f1SDimitry Andric UnresolvedUsingIfExistsDecl *
33090fca6ea1SDimitry Andric UnresolvedUsingIfExistsDecl::CreateDeserialized(ASTContext &Ctx,
33100fca6ea1SDimitry Andric                                                 GlobalDeclID ID) {
3311fe6060f1SDimitry Andric   return new (Ctx, ID)
3312fe6060f1SDimitry Andric       UnresolvedUsingIfExistsDecl(nullptr, SourceLocation(), DeclarationName());
3313fe6060f1SDimitry Andric }
3314fe6060f1SDimitry Andric 
3315fe6060f1SDimitry Andric UnresolvedUsingIfExistsDecl::UnresolvedUsingIfExistsDecl(DeclContext *DC,
3316fe6060f1SDimitry Andric                                                          SourceLocation Loc,
3317fe6060f1SDimitry Andric                                                          DeclarationName Name)
3318fe6060f1SDimitry Andric     : NamedDecl(Decl::UnresolvedUsingIfExists, DC, Loc, Name) {}
3319fe6060f1SDimitry Andric 
3320fe6060f1SDimitry Andric void UnresolvedUsingIfExistsDecl::anchor() {}
3321fe6060f1SDimitry Andric 
33220b57cec5SDimitry Andric void StaticAssertDecl::anchor() {}
33230b57cec5SDimitry Andric 
33240b57cec5SDimitry Andric StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
33250b57cec5SDimitry Andric                                            SourceLocation StaticAssertLoc,
332606c3fb27SDimitry Andric                                            Expr *AssertExpr, Expr *Message,
33270b57cec5SDimitry Andric                                            SourceLocation RParenLoc,
33280b57cec5SDimitry Andric                                            bool Failed) {
33290b57cec5SDimitry Andric   return new (C, DC) StaticAssertDecl(DC, StaticAssertLoc, AssertExpr, Message,
33300b57cec5SDimitry Andric                                       RParenLoc, Failed);
33310b57cec5SDimitry Andric }
33320b57cec5SDimitry Andric 
33330b57cec5SDimitry Andric StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C,
33340fca6ea1SDimitry Andric                                                        GlobalDeclID ID) {
33350b57cec5SDimitry Andric   return new (C, ID) StaticAssertDecl(nullptr, SourceLocation(), nullptr,
33360b57cec5SDimitry Andric                                       nullptr, SourceLocation(), false);
33370b57cec5SDimitry Andric }
33380b57cec5SDimitry Andric 
3339bdd1243dSDimitry Andric VarDecl *ValueDecl::getPotentiallyDecomposedVarDecl() {
3340bdd1243dSDimitry Andric   assert((isa<VarDecl, BindingDecl>(this)) &&
3341bdd1243dSDimitry Andric          "expected a VarDecl or a BindingDecl");
3342bdd1243dSDimitry Andric   if (auto *Var = llvm::dyn_cast<VarDecl>(this))
3343bdd1243dSDimitry Andric     return Var;
3344bdd1243dSDimitry Andric   if (auto *BD = llvm::dyn_cast<BindingDecl>(this))
3345bdd1243dSDimitry Andric     return llvm::dyn_cast<VarDecl>(BD->getDecomposedDecl());
3346bdd1243dSDimitry Andric   return nullptr;
3347bdd1243dSDimitry Andric }
3348bdd1243dSDimitry Andric 
33490b57cec5SDimitry Andric void BindingDecl::anchor() {}
33500b57cec5SDimitry Andric 
33510b57cec5SDimitry Andric BindingDecl *BindingDecl::Create(ASTContext &C, DeclContext *DC,
33520b57cec5SDimitry Andric                                  SourceLocation IdLoc, IdentifierInfo *Id) {
33530b57cec5SDimitry Andric   return new (C, DC) BindingDecl(DC, IdLoc, Id);
33540b57cec5SDimitry Andric }
33550b57cec5SDimitry Andric 
33560fca6ea1SDimitry Andric BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
33570b57cec5SDimitry Andric   return new (C, ID) BindingDecl(nullptr, SourceLocation(), nullptr);
33580b57cec5SDimitry Andric }
33590b57cec5SDimitry Andric 
33600b57cec5SDimitry Andric VarDecl *BindingDecl::getHoldingVar() const {
33610b57cec5SDimitry Andric   Expr *B = getBinding();
33620b57cec5SDimitry Andric   if (!B)
33630b57cec5SDimitry Andric     return nullptr;
33640b57cec5SDimitry Andric   auto *DRE = dyn_cast<DeclRefExpr>(B->IgnoreImplicit());
33650b57cec5SDimitry Andric   if (!DRE)
33660b57cec5SDimitry Andric     return nullptr;
33670b57cec5SDimitry Andric 
33685ffd83dbSDimitry Andric   auto *VD = cast<VarDecl>(DRE->getDecl());
33690b57cec5SDimitry Andric   assert(VD->isImplicit() && "holding var for binding decl not implicit");
33700b57cec5SDimitry Andric   return VD;
33710b57cec5SDimitry Andric }
33720b57cec5SDimitry Andric 
33730b57cec5SDimitry Andric void DecompositionDecl::anchor() {}
33740b57cec5SDimitry Andric 
33750b57cec5SDimitry Andric DecompositionDecl *DecompositionDecl::Create(ASTContext &C, DeclContext *DC,
33760b57cec5SDimitry Andric                                              SourceLocation StartLoc,
33770b57cec5SDimitry Andric                                              SourceLocation LSquareLoc,
33780b57cec5SDimitry Andric                                              QualType T, TypeSourceInfo *TInfo,
33790b57cec5SDimitry Andric                                              StorageClass SC,
33800b57cec5SDimitry Andric                                              ArrayRef<BindingDecl *> Bindings) {
33810b57cec5SDimitry Andric   size_t Extra = additionalSizeToAlloc<BindingDecl *>(Bindings.size());
33820b57cec5SDimitry Andric   return new (C, DC, Extra)
33830b57cec5SDimitry Andric       DecompositionDecl(C, DC, StartLoc, LSquareLoc, T, TInfo, SC, Bindings);
33840b57cec5SDimitry Andric }
33850b57cec5SDimitry Andric 
33860b57cec5SDimitry Andric DecompositionDecl *DecompositionDecl::CreateDeserialized(ASTContext &C,
33870fca6ea1SDimitry Andric                                                          GlobalDeclID ID,
33880b57cec5SDimitry Andric                                                          unsigned NumBindings) {
33890b57cec5SDimitry Andric   size_t Extra = additionalSizeToAlloc<BindingDecl *>(NumBindings);
33900b57cec5SDimitry Andric   auto *Result = new (C, ID, Extra)
33910b57cec5SDimitry Andric       DecompositionDecl(C, nullptr, SourceLocation(), SourceLocation(),
3392bdd1243dSDimitry Andric                         QualType(), nullptr, StorageClass(), std::nullopt);
33930b57cec5SDimitry Andric   // Set up and clean out the bindings array.
33940b57cec5SDimitry Andric   Result->NumBindings = NumBindings;
33950b57cec5SDimitry Andric   auto *Trail = Result->getTrailingObjects<BindingDecl *>();
33960b57cec5SDimitry Andric   for (unsigned I = 0; I != NumBindings; ++I)
33970b57cec5SDimitry Andric     new (Trail + I) BindingDecl*(nullptr);
33980b57cec5SDimitry Andric   return Result;
33990b57cec5SDimitry Andric }
34000b57cec5SDimitry Andric 
3401bdd1243dSDimitry Andric void DecompositionDecl::printName(llvm::raw_ostream &OS,
3402bdd1243dSDimitry Andric                                   const PrintingPolicy &Policy) const {
3403bdd1243dSDimitry Andric   OS << '[';
34040b57cec5SDimitry Andric   bool Comma = false;
34050b57cec5SDimitry Andric   for (const auto *B : bindings()) {
34060b57cec5SDimitry Andric     if (Comma)
3407bdd1243dSDimitry Andric       OS << ", ";
3408bdd1243dSDimitry Andric     B->printName(OS, Policy);
34090b57cec5SDimitry Andric     Comma = true;
34100b57cec5SDimitry Andric   }
3411bdd1243dSDimitry Andric   OS << ']';
34120b57cec5SDimitry Andric }
34130b57cec5SDimitry Andric 
34140b57cec5SDimitry Andric void MSPropertyDecl::anchor() {}
34150b57cec5SDimitry Andric 
34160b57cec5SDimitry Andric MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC,
34170b57cec5SDimitry Andric                                        SourceLocation L, DeclarationName N,
34180b57cec5SDimitry Andric                                        QualType T, TypeSourceInfo *TInfo,
34190b57cec5SDimitry Andric                                        SourceLocation StartL,
34200b57cec5SDimitry Andric                                        IdentifierInfo *Getter,
34210b57cec5SDimitry Andric                                        IdentifierInfo *Setter) {
34220b57cec5SDimitry Andric   return new (C, DC) MSPropertyDecl(DC, L, N, T, TInfo, StartL, Getter, Setter);
34230b57cec5SDimitry Andric }
34240b57cec5SDimitry Andric 
34250b57cec5SDimitry Andric MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C,
34260fca6ea1SDimitry Andric                                                    GlobalDeclID ID) {
34270b57cec5SDimitry Andric   return new (C, ID) MSPropertyDecl(nullptr, SourceLocation(),
34280b57cec5SDimitry Andric                                     DeclarationName(), QualType(), nullptr,
34290b57cec5SDimitry Andric                                     SourceLocation(), nullptr, nullptr);
34300b57cec5SDimitry Andric }
34310b57cec5SDimitry Andric 
34325ffd83dbSDimitry Andric void MSGuidDecl::anchor() {}
34335ffd83dbSDimitry Andric 
34345ffd83dbSDimitry Andric MSGuidDecl::MSGuidDecl(DeclContext *DC, QualType T, Parts P)
34355ffd83dbSDimitry Andric     : ValueDecl(Decl::MSGuid, DC, SourceLocation(), DeclarationName(), T),
343604eeddc0SDimitry Andric       PartVal(P) {}
34375ffd83dbSDimitry Andric 
34385ffd83dbSDimitry Andric MSGuidDecl *MSGuidDecl::Create(const ASTContext &C, QualType T, Parts P) {
34395ffd83dbSDimitry Andric   DeclContext *DC = C.getTranslationUnitDecl();
34405ffd83dbSDimitry Andric   return new (C, DC) MSGuidDecl(DC, T, P);
34415ffd83dbSDimitry Andric }
34425ffd83dbSDimitry Andric 
34430fca6ea1SDimitry Andric MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
34445ffd83dbSDimitry Andric   return new (C, ID) MSGuidDecl(nullptr, QualType(), Parts());
34455ffd83dbSDimitry Andric }
34465ffd83dbSDimitry Andric 
3447bdd1243dSDimitry Andric void MSGuidDecl::printName(llvm::raw_ostream &OS,
3448bdd1243dSDimitry Andric                            const PrintingPolicy &) const {
34495ffd83dbSDimitry Andric   OS << llvm::format("GUID{%08" PRIx32 "-%04" PRIx16 "-%04" PRIx16 "-",
34505ffd83dbSDimitry Andric                      PartVal.Part1, PartVal.Part2, PartVal.Part3);
34515ffd83dbSDimitry Andric   unsigned I = 0;
34525ffd83dbSDimitry Andric   for (uint8_t Byte : PartVal.Part4And5) {
34535ffd83dbSDimitry Andric     OS << llvm::format("%02" PRIx8, Byte);
34545ffd83dbSDimitry Andric     if (++I == 2)
34555ffd83dbSDimitry Andric       OS << '-';
34565ffd83dbSDimitry Andric   }
34575ffd83dbSDimitry Andric   OS << '}';
34585ffd83dbSDimitry Andric }
34595ffd83dbSDimitry Andric 
34605ffd83dbSDimitry Andric /// Determine if T is a valid 'struct _GUID' of the shape that we expect.
34615ffd83dbSDimitry Andric static bool isValidStructGUID(ASTContext &Ctx, QualType T) {
34625ffd83dbSDimitry Andric   // FIXME: We only need to check this once, not once each time we compute a
34635ffd83dbSDimitry Andric   // GUID APValue.
34645ffd83dbSDimitry Andric   using MatcherRef = llvm::function_ref<bool(QualType)>;
34655ffd83dbSDimitry Andric 
34665ffd83dbSDimitry Andric   auto IsInt = [&Ctx](unsigned N) {
34675ffd83dbSDimitry Andric     return [&Ctx, N](QualType T) {
34685ffd83dbSDimitry Andric       return T->isUnsignedIntegerOrEnumerationType() &&
34695ffd83dbSDimitry Andric              Ctx.getIntWidth(T) == N;
34705ffd83dbSDimitry Andric     };
34715ffd83dbSDimitry Andric   };
34725ffd83dbSDimitry Andric 
34735ffd83dbSDimitry Andric   auto IsArray = [&Ctx](MatcherRef Elem, unsigned N) {
34745ffd83dbSDimitry Andric     return [&Ctx, Elem, N](QualType T) {
34755ffd83dbSDimitry Andric       const ConstantArrayType *CAT = Ctx.getAsConstantArrayType(T);
34765ffd83dbSDimitry Andric       return CAT && CAT->getSize() == N && Elem(CAT->getElementType());
34775ffd83dbSDimitry Andric     };
34785ffd83dbSDimitry Andric   };
34795ffd83dbSDimitry Andric 
34805ffd83dbSDimitry Andric   auto IsStruct = [](std::initializer_list<MatcherRef> Fields) {
34815ffd83dbSDimitry Andric     return [Fields](QualType T) {
34825ffd83dbSDimitry Andric       const RecordDecl *RD = T->getAsRecordDecl();
34835ffd83dbSDimitry Andric       if (!RD || RD->isUnion())
34845ffd83dbSDimitry Andric         return false;
34855ffd83dbSDimitry Andric       RD = RD->getDefinition();
34865ffd83dbSDimitry Andric       if (!RD)
34875ffd83dbSDimitry Andric         return false;
34885ffd83dbSDimitry Andric       if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
34895ffd83dbSDimitry Andric         if (CXXRD->getNumBases())
34905ffd83dbSDimitry Andric           return false;
34915ffd83dbSDimitry Andric       auto MatcherIt = Fields.begin();
34925ffd83dbSDimitry Andric       for (const FieldDecl *FD : RD->fields()) {
34930fca6ea1SDimitry Andric         if (FD->isUnnamedBitField())
34940fca6ea1SDimitry Andric           continue;
34955ffd83dbSDimitry Andric         if (FD->isBitField() || MatcherIt == Fields.end() ||
34965ffd83dbSDimitry Andric             !(*MatcherIt)(FD->getType()))
34975ffd83dbSDimitry Andric           return false;
34985ffd83dbSDimitry Andric         ++MatcherIt;
34995ffd83dbSDimitry Andric       }
35005ffd83dbSDimitry Andric       return MatcherIt == Fields.end();
35015ffd83dbSDimitry Andric     };
35025ffd83dbSDimitry Andric   };
35035ffd83dbSDimitry Andric 
35045ffd83dbSDimitry Andric   // We expect an {i32, i16, i16, [8 x i8]}.
35055ffd83dbSDimitry Andric   return IsStruct({IsInt(32), IsInt(16), IsInt(16), IsArray(IsInt(8), 8)})(T);
35065ffd83dbSDimitry Andric }
35075ffd83dbSDimitry Andric 
35085ffd83dbSDimitry Andric APValue &MSGuidDecl::getAsAPValue() const {
35095ffd83dbSDimitry Andric   if (APVal.isAbsent() && isValidStructGUID(getASTContext(), getType())) {
35105ffd83dbSDimitry Andric     using llvm::APInt;
35115ffd83dbSDimitry Andric     using llvm::APSInt;
35125ffd83dbSDimitry Andric     APVal = APValue(APValue::UninitStruct(), 0, 4);
35135ffd83dbSDimitry Andric     APVal.getStructField(0) = APValue(APSInt(APInt(32, PartVal.Part1), true));
35145ffd83dbSDimitry Andric     APVal.getStructField(1) = APValue(APSInt(APInt(16, PartVal.Part2), true));
35155ffd83dbSDimitry Andric     APVal.getStructField(2) = APValue(APSInt(APInt(16, PartVal.Part3), true));
35165ffd83dbSDimitry Andric     APValue &Arr = APVal.getStructField(3) =
35175ffd83dbSDimitry Andric         APValue(APValue::UninitArray(), 8, 8);
35185ffd83dbSDimitry Andric     for (unsigned I = 0; I != 8; ++I) {
35195ffd83dbSDimitry Andric       Arr.getArrayInitializedElt(I) =
35205ffd83dbSDimitry Andric           APValue(APSInt(APInt(8, PartVal.Part4And5[I]), true));
35215ffd83dbSDimitry Andric     }
35225ffd83dbSDimitry Andric     // Register this APValue to be destroyed if necessary. (Note that the
35235ffd83dbSDimitry Andric     // MSGuidDecl destructor is never run.)
35245ffd83dbSDimitry Andric     getASTContext().addDestruction(&APVal);
35255ffd83dbSDimitry Andric   }
35265ffd83dbSDimitry Andric 
35275ffd83dbSDimitry Andric   return APVal;
35285ffd83dbSDimitry Andric }
35295ffd83dbSDimitry Andric 
353081ad6265SDimitry Andric void UnnamedGlobalConstantDecl::anchor() {}
353181ad6265SDimitry Andric 
353281ad6265SDimitry Andric UnnamedGlobalConstantDecl::UnnamedGlobalConstantDecl(const ASTContext &C,
353381ad6265SDimitry Andric                                                      DeclContext *DC,
353481ad6265SDimitry Andric                                                      QualType Ty,
353581ad6265SDimitry Andric                                                      const APValue &Val)
353681ad6265SDimitry Andric     : ValueDecl(Decl::UnnamedGlobalConstant, DC, SourceLocation(),
353781ad6265SDimitry Andric                 DeclarationName(), Ty),
353881ad6265SDimitry Andric       Value(Val) {
353981ad6265SDimitry Andric   // Cleanup the embedded APValue if required (note that our destructor is never
354081ad6265SDimitry Andric   // run)
354181ad6265SDimitry Andric   if (Value.needsCleanup())
354281ad6265SDimitry Andric     C.addDestruction(&Value);
354381ad6265SDimitry Andric }
354481ad6265SDimitry Andric 
354581ad6265SDimitry Andric UnnamedGlobalConstantDecl *
354681ad6265SDimitry Andric UnnamedGlobalConstantDecl::Create(const ASTContext &C, QualType T,
354781ad6265SDimitry Andric                                   const APValue &Value) {
354881ad6265SDimitry Andric   DeclContext *DC = C.getTranslationUnitDecl();
354981ad6265SDimitry Andric   return new (C, DC) UnnamedGlobalConstantDecl(C, DC, T, Value);
355081ad6265SDimitry Andric }
355181ad6265SDimitry Andric 
355281ad6265SDimitry Andric UnnamedGlobalConstantDecl *
35530fca6ea1SDimitry Andric UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
355481ad6265SDimitry Andric   return new (C, ID)
355581ad6265SDimitry Andric       UnnamedGlobalConstantDecl(C, nullptr, QualType(), APValue());
355681ad6265SDimitry Andric }
355781ad6265SDimitry Andric 
3558bdd1243dSDimitry Andric void UnnamedGlobalConstantDecl::printName(llvm::raw_ostream &OS,
3559bdd1243dSDimitry Andric                                           const PrintingPolicy &) const {
356081ad6265SDimitry Andric   OS << "unnamed-global-constant";
356181ad6265SDimitry Andric }
356281ad6265SDimitry Andric 
35630b57cec5SDimitry Andric static const char *getAccessName(AccessSpecifier AS) {
35640b57cec5SDimitry Andric   switch (AS) {
35650b57cec5SDimitry Andric     case AS_none:
35660b57cec5SDimitry Andric       llvm_unreachable("Invalid access specifier!");
35670b57cec5SDimitry Andric     case AS_public:
35680b57cec5SDimitry Andric       return "public";
35690b57cec5SDimitry Andric     case AS_private:
35700b57cec5SDimitry Andric       return "private";
35710b57cec5SDimitry Andric     case AS_protected:
35720b57cec5SDimitry Andric       return "protected";
35730b57cec5SDimitry Andric   }
35740b57cec5SDimitry Andric   llvm_unreachable("Invalid access specifier!");
35750b57cec5SDimitry Andric }
35760b57cec5SDimitry Andric 
3577e8d8bef9SDimitry Andric const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
35780b57cec5SDimitry Andric                                              AccessSpecifier AS) {
35790b57cec5SDimitry Andric   return DB << getAccessName(AS);
35800b57cec5SDimitry Andric }
3581