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