1193326Sed//===--- DeclCXX.cpp - C++ Declaration AST Node Implementation ------------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements the C++ related Decl classes. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed#include "clang/AST/DeclCXX.h" 14193326Sed#include "clang/AST/ASTContext.h" 15263509Sdim#include "clang/AST/ASTLambda.h" 16218893Sdim#include "clang/AST/ASTMutationListener.h" 17218893Sdim#include "clang/AST/CXXInheritance.h" 18252723Sdim#include "clang/AST/DeclTemplate.h" 19193326Sed#include "clang/AST/Expr.h" 20235633Sdim#include "clang/AST/ExprCXX.h" 21200583Srdivacky#include "clang/AST/TypeLoc.h" 22193326Sed#include "clang/Basic/IdentifierTable.h" 23193326Sed#include "llvm/ADT/STLExtras.h" 24198092Srdivacky#include "llvm/ADT/SmallPtrSet.h" 25193326Sedusing namespace clang; 26193326Sed 27193326Sed//===----------------------------------------------------------------------===// 28193326Sed// Decl Allocation/Deallocation Method Implementations 29193326Sed//===----------------------------------------------------------------------===// 30193326Sed 31235633Sdimvoid AccessSpecDecl::anchor() { } 32235633Sdim 33235633SdimAccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 34235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(AccessSpecDecl)); 35235633Sdim return new (Mem) AccessSpecDecl(EmptyShell()); 36235633Sdim} 37235633Sdim 38263509Sdimvoid LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const { 39263509Sdim ExternalASTSource *Source = C.getExternalSource(); 40263509Sdim assert(Impl.Decls.isLazy() && "getFromExternalSource for non-lazy set"); 41263509Sdim assert(Source && "getFromExternalSource with no external source"); 42263509Sdim 43263509Sdim for (ASTUnresolvedSet::iterator I = Impl.begin(); I != Impl.end(); ++I) 44263509Sdim I.setDecl(cast<NamedDecl>(Source->GetExternalDecl( 45263509Sdim reinterpret_cast<uintptr_t>(I.getDecl()) >> 2))); 46263509Sdim Impl.Decls.setLazy(false); 47263509Sdim} 48263509Sdim 49203955SrdivackyCXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) 50252723Sdim : UserDeclaredConstructor(false), UserDeclaredSpecialMembers(0), 51198092Srdivacky Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false), 52221345Sdim Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true), 53221345Sdim HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false), 54235633Sdim HasMutableFields(false), HasOnlyCMembers(true), 55252723Sdim HasInClassInitializer(false), HasUninitializedReferenceMember(false), 56252723Sdim NeedOverloadResolutionForMoveConstructor(false), 57252723Sdim NeedOverloadResolutionForMoveAssignment(false), 58252723Sdim NeedOverloadResolutionForDestructor(false), 59252723Sdim DefaultedMoveConstructorIsDeleted(false), 60252723Sdim DefaultedMoveAssignmentIsDeleted(false), 61252723Sdim DefaultedDestructorIsDeleted(false), 62252723Sdim HasTrivialSpecialMembers(SMF_All), 63252723Sdim DeclaredNonTrivialSpecialMembers(0), 64252723Sdim HasIrrelevantDestructor(true), 65235633Sdim HasConstexprNonCopyMoveConstructor(false), 66235633Sdim DefaultedDefaultConstructorIsConstexpr(true), 67252723Sdim HasConstexprDefaultConstructor(false), 68223017Sdim HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false), 69252723Sdim UserProvidedDefaultConstructor(false), DeclaredSpecialMembers(0), 70252723Sdim ImplicitCopyConstructorHasConstParam(true), 71252723Sdim ImplicitCopyAssignmentHasConstParam(true), 72252723Sdim HasDeclaredCopyConstructorWithConstParam(false), 73252723Sdim HasDeclaredCopyAssignmentWithConstParam(false), 74252723Sdim IsLambda(false), NumBases(0), NumVBases(0), Bases(), VBases(), 75263509Sdim Definition(D), FirstFriend() { 76203955Srdivacky} 77203955Srdivacky 78245431SdimCXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const { 79245431Sdim return Bases.get(Definition->getASTContext().getExternalSource()); 80245431Sdim} 81245431Sdim 82245431SdimCXXBaseSpecifier *CXXRecordDecl::DefinitionData::getVBasesSlowCase() const { 83245431Sdim return VBases.get(Definition->getASTContext().getExternalSource()); 84245431Sdim} 85245431Sdim 86203955SrdivackyCXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, 87221345Sdim SourceLocation StartLoc, SourceLocation IdLoc, 88221345Sdim IdentifierInfo *Id, CXXRecordDecl *PrevDecl) 89221345Sdim : RecordDecl(K, TK, DC, StartLoc, IdLoc, Id, PrevDecl), 90203955Srdivacky DefinitionData(PrevDecl ? PrevDecl->DefinitionData : 0), 91193326Sed TemplateOrInstantiation() { } 92193326Sed 93218893SdimCXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK, 94221345Sdim DeclContext *DC, SourceLocation StartLoc, 95221345Sdim SourceLocation IdLoc, IdentifierInfo *Id, 96193326Sed CXXRecordDecl* PrevDecl, 97193326Sed bool DelayTypeCreation) { 98221345Sdim CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, StartLoc, IdLoc, 99221345Sdim Id, PrevDecl); 100252723Sdim R->MayHaveOutOfDateDef = C.getLangOpts().Modules; 101198092Srdivacky 102198092Srdivacky // FIXME: DelayTypeCreation seems like such a hack 103193326Sed if (!DelayTypeCreation) 104198092Srdivacky C.getTypeDeclType(R, PrevDecl); 105193326Sed return R; 106193326Sed} 107193326Sed 108235633SdimCXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, 109245431Sdim TypeSourceInfo *Info, SourceLocation Loc, 110263509Sdim bool Dependent, bool IsGeneric, 111263509Sdim LambdaCaptureDefault CaptureDefault) { 112235633Sdim CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TTK_Class, DC, Loc, Loc, 113235633Sdim 0, 0); 114235633Sdim R->IsBeingDefined = true; 115263509Sdim R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info, 116263509Sdim Dependent, 117263509Sdim IsGeneric, 118263509Sdim CaptureDefault); 119252723Sdim R->MayHaveOutOfDateDef = false; 120263509Sdim R->setImplicit(true); 121235633Sdim C.getTypeDeclType(R, /*PrevDecl=*/0); 122235633Sdim return R; 123210299Sed} 124210299Sed 125235633SdimCXXRecordDecl * 126235633SdimCXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { 127235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXRecordDecl)); 128252723Sdim CXXRecordDecl *R = new (Mem) CXXRecordDecl(CXXRecord, TTK_Struct, 0, 129252723Sdim SourceLocation(), SourceLocation(), 130252723Sdim 0, 0); 131252723Sdim R->MayHaveOutOfDateDef = false; 132252723Sdim return R; 133235633Sdim} 134235633Sdim 135198092Srdivackyvoid 136203955SrdivackyCXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, 137193326Sed unsigned NumBases) { 138203955Srdivacky ASTContext &C = getASTContext(); 139193326Sed 140218893Sdim if (!data().Bases.isOffset() && data().NumBases > 0) 141218893Sdim C.Deallocate(data().getBases()); 142193326Sed 143235633Sdim if (NumBases) { 144235633Sdim // C++ [dcl.init.aggr]p1: 145235633Sdim // An aggregate is [...] a class with [...] no base classes [...]. 146235633Sdim data().Aggregate = false; 147235633Sdim 148235633Sdim // C++ [class]p4: 149235633Sdim // A POD-struct is an aggregate class... 150235633Sdim data().PlainOldData = false; 151235633Sdim } 152235633Sdim 153206084Srdivacky // The set of seen virtual base types. 154206084Srdivacky llvm::SmallPtrSet<CanQualType, 8> SeenVBaseTypes; 155206084Srdivacky 156206084Srdivacky // The virtual bases of this class. 157226890Sdim SmallVector<const CXXBaseSpecifier *, 8> VBases; 158198092Srdivacky 159203955Srdivacky data().Bases = new(C) CXXBaseSpecifier [NumBases]; 160203955Srdivacky data().NumBases = NumBases; 161198092Srdivacky for (unsigned i = 0; i < NumBases; ++i) { 162218893Sdim data().getBases()[i] = *Bases[i]; 163198092Srdivacky // Keep track of inherited vbases for this base class. 164198092Srdivacky const CXXBaseSpecifier *Base = Bases[i]; 165198092Srdivacky QualType BaseType = Base->getType(); 166204643Srdivacky // Skip dependent types; we can't do any checking on them now. 167198092Srdivacky if (BaseType->isDependentType()) 168198092Srdivacky continue; 169198092Srdivacky CXXRecordDecl *BaseClassDecl 170198092Srdivacky = cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 171206084Srdivacky 172218893Sdim // A class with a non-empty base class is not empty. 173218893Sdim // FIXME: Standard ref? 174221345Sdim if (!BaseClassDecl->isEmpty()) { 175221345Sdim if (!data().Empty) { 176221345Sdim // C++0x [class]p7: 177221345Sdim // A standard-layout class is a class that: 178221345Sdim // [...] 179221345Sdim // -- either has no non-static data members in the most derived 180221345Sdim // class and at most one base class with non-static data members, 181221345Sdim // or has no base classes with non-static data members, and 182221345Sdim // If this is the second non-empty base, then neither of these two 183221345Sdim // clauses can be true. 184221345Sdim data().IsStandardLayout = false; 185221345Sdim } 186221345Sdim 187218893Sdim data().Empty = false; 188221345Sdim data().HasNoNonEmptyBases = false; 189221345Sdim } 190218893Sdim 191218893Sdim // C++ [class.virtual]p1: 192218893Sdim // A class that declares or inherits a virtual function is called a 193218893Sdim // polymorphic class. 194218893Sdim if (BaseClassDecl->isPolymorphic()) 195218893Sdim data().Polymorphic = true; 196221345Sdim 197221345Sdim // C++0x [class]p7: 198221345Sdim // A standard-layout class is a class that: [...] 199221345Sdim // -- has no non-standard-layout base classes 200221345Sdim if (!BaseClassDecl->isStandardLayout()) 201221345Sdim data().IsStandardLayout = false; 202221345Sdim 203221345Sdim // Record if this base is the first non-literal field or base. 204252723Sdim if (!hasNonLiteralTypeFieldsOrBases() && !BaseType->isLiteralType(C)) 205221345Sdim data().HasNonLiteralTypeFieldsOrBases = true; 206218893Sdim 207206084Srdivacky // Now go through all virtual bases of this base and add them. 208198092Srdivacky for (CXXRecordDecl::base_class_iterator VBase = 209198092Srdivacky BaseClassDecl->vbases_begin(), 210198092Srdivacky E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) { 211206084Srdivacky // Add this base if it's not already in the list. 212252723Sdim if (SeenVBaseTypes.insert(C.getCanonicalType(VBase->getType()))) { 213206084Srdivacky VBases.push_back(VBase); 214252723Sdim 215252723Sdim // C++11 [class.copy]p8: 216252723Sdim // The implicitly-declared copy constructor for a class X will have 217252723Sdim // the form 'X::X(const X&)' if each [...] virtual base class B of X 218252723Sdim // has a copy constructor whose first parameter is of type 219252723Sdim // 'const B&' or 'const volatile B&' [...] 220252723Sdim if (CXXRecordDecl *VBaseDecl = VBase->getType()->getAsCXXRecordDecl()) 221252723Sdim if (!VBaseDecl->hasCopyConstructorWithConstParam()) 222252723Sdim data().ImplicitCopyConstructorHasConstParam = false; 223252723Sdim } 224198092Srdivacky } 225206084Srdivacky 226206084Srdivacky if (Base->isVirtual()) { 227206084Srdivacky // Add this base if it's not already in the list. 228206084Srdivacky if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType))) 229252723Sdim VBases.push_back(Base); 230252723Sdim 231218893Sdim // C++0x [meta.unary.prop] is_empty: 232218893Sdim // T is a class type, but not a union type, with ... no virtual base 233218893Sdim // classes 234218893Sdim data().Empty = false; 235221345Sdim 236252723Sdim // C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25: 237252723Sdim // A [default constructor, copy/move constructor, or copy/move assignment 238252723Sdim // operator for a class X] is trivial [...] if: 239252723Sdim // -- class X has [...] no virtual base classes 240252723Sdim data().HasTrivialSpecialMembers &= SMF_Destructor; 241221345Sdim 242221345Sdim // C++0x [class]p7: 243221345Sdim // A standard-layout class is a class that: [...] 244221345Sdim // -- has [...] no virtual base classes 245221345Sdim data().IsStandardLayout = false; 246235633Sdim 247235633Sdim // C++11 [dcl.constexpr]p4: 248235633Sdim // In the definition of a constexpr constructor [...] 249235633Sdim // -- the class shall not have any virtual base classes 250235633Sdim data().DefaultedDefaultConstructorIsConstexpr = false; 251218893Sdim } else { 252218893Sdim // C++ [class.ctor]p5: 253223017Sdim // A default constructor is trivial [...] if: 254223017Sdim // -- all the direct base classes of its class have trivial default 255223017Sdim // constructors. 256223017Sdim if (!BaseClassDecl->hasTrivialDefaultConstructor()) 257252723Sdim data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor; 258252723Sdim 259221345Sdim // C++0x [class.copy]p13: 260221345Sdim // A copy/move constructor for class X is trivial if [...] 261221345Sdim // [...] 262221345Sdim // -- the constructor selected to copy/move each direct base class 263221345Sdim // subobject is trivial, and 264218893Sdim if (!BaseClassDecl->hasTrivialCopyConstructor()) 265252723Sdim data().HasTrivialSpecialMembers &= ~SMF_CopyConstructor; 266252723Sdim // If the base class doesn't have a simple move constructor, we'll eagerly 267252723Sdim // declare it and perform overload resolution to determine which function 268252723Sdim // it actually calls. If it does have a simple move constructor, this 269252723Sdim // check is correct. 270252723Sdim if (!BaseClassDecl->hasTrivialMoveConstructor()) 271252723Sdim data().HasTrivialSpecialMembers &= ~SMF_MoveConstructor; 272221345Sdim 273221345Sdim // C++0x [class.copy]p27: 274221345Sdim // A copy/move assignment operator for class X is trivial if [...] 275221345Sdim // [...] 276221345Sdim // -- the assignment operator selected to copy/move each direct base 277221345Sdim // class subobject is trivial, and 278218893Sdim if (!BaseClassDecl->hasTrivialCopyAssignment()) 279252723Sdim data().HasTrivialSpecialMembers &= ~SMF_CopyAssignment; 280252723Sdim // If the base class doesn't have a simple move assignment, we'll eagerly 281252723Sdim // declare it and perform overload resolution to determine which function 282252723Sdim // it actually calls. If it does have a simple move assignment, this 283252723Sdim // check is correct. 284252723Sdim if (!BaseClassDecl->hasTrivialMoveAssignment()) 285252723Sdim data().HasTrivialSpecialMembers &= ~SMF_MoveAssignment; 286235633Sdim 287235633Sdim // C++11 [class.ctor]p6: 288235633Sdim // If that user-written default constructor would satisfy the 289235633Sdim // requirements of a constexpr constructor, the implicitly-defined 290235633Sdim // default constructor is constexpr. 291235633Sdim if (!BaseClassDecl->hasConstexprDefaultConstructor()) 292235633Sdim data().DefaultedDefaultConstructorIsConstexpr = false; 293198092Srdivacky } 294252723Sdim 295218893Sdim // C++ [class.ctor]p3: 296218893Sdim // A destructor is trivial if all the direct base classes of its class 297218893Sdim // have trivial destructors. 298218893Sdim if (!BaseClassDecl->hasTrivialDestructor()) 299252723Sdim data().HasTrivialSpecialMembers &= ~SMF_Destructor; 300235633Sdim 301235633Sdim if (!BaseClassDecl->hasIrrelevantDestructor()) 302235633Sdim data().HasIrrelevantDestructor = false; 303235633Sdim 304252723Sdim // C++11 [class.copy]p18: 305252723Sdim // The implicitly-declared copy assignment oeprator for a class X will 306252723Sdim // have the form 'X& X::operator=(const X&)' if each direct base class B 307252723Sdim // of X has a copy assignment operator whose parameter is of type 'const 308252723Sdim // B&', 'const volatile B&', or 'B' [...] 309252723Sdim if (!BaseClassDecl->hasCopyAssignmentWithConstParam()) 310252723Sdim data().ImplicitCopyAssignmentHasConstParam = false; 311252723Sdim 312252723Sdim // C++11 [class.copy]p8: 313252723Sdim // The implicitly-declared copy constructor for a class X will have 314252723Sdim // the form 'X::X(const X&)' if each direct [...] base class B of X 315252723Sdim // has a copy constructor whose first parameter is of type 316252723Sdim // 'const B&' or 'const volatile B&' [...] 317252723Sdim if (!BaseClassDecl->hasCopyConstructorWithConstParam()) 318252723Sdim data().ImplicitCopyConstructorHasConstParam = false; 319252723Sdim 320224145Sdim // A class has an Objective-C object member if... or any of its bases 321224145Sdim // has an Objective-C object member. 322224145Sdim if (BaseClassDecl->hasObjectMember()) 323224145Sdim setHasObjectMember(true); 324252723Sdim 325252723Sdim if (BaseClassDecl->hasVolatileMember()) 326252723Sdim setHasVolatileMember(true); 327224145Sdim 328223017Sdim // Keep track of the presence of mutable fields. 329223017Sdim if (BaseClassDecl->hasMutableFields()) 330223017Sdim data().HasMutableFields = true; 331252723Sdim 332252723Sdim if (BaseClassDecl->hasUninitializedReferenceMember()) 333252723Sdim data().HasUninitializedReferenceMember = true; 334252723Sdim 335252723Sdim addedClassSubobject(BaseClassDecl); 336198092Srdivacky } 337206084Srdivacky 338206084Srdivacky if (VBases.empty()) 339206084Srdivacky return; 340206084Srdivacky 341206084Srdivacky // Create base specifier for any direct or indirect virtual bases. 342206084Srdivacky data().VBases = new (C) CXXBaseSpecifier[VBases.size()]; 343206084Srdivacky data().NumVBases = VBases.size(); 344252723Sdim for (int I = 0, E = VBases.size(); I != E; ++I) { 345252723Sdim QualType Type = VBases[I]->getType(); 346252723Sdim if (!Type->isDependentType()) 347252723Sdim addedClassSubobject(Type->getAsCXXRecordDecl()); 348224145Sdim data().getVBases()[I] = *VBases[I]; 349252723Sdim } 350193326Sed} 351193326Sed 352252723Sdimvoid CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) { 353252723Sdim // C++11 [class.copy]p11: 354252723Sdim // A defaulted copy/move constructor for a class X is defined as 355252723Sdim // deleted if X has: 356252723Sdim // -- a direct or virtual base class B that cannot be copied/moved [...] 357252723Sdim // -- a non-static data member of class type M (or array thereof) 358252723Sdim // that cannot be copied or moved [...] 359252723Sdim if (!Subobj->hasSimpleMoveConstructor()) 360252723Sdim data().NeedOverloadResolutionForMoveConstructor = true; 361252723Sdim 362252723Sdim // C++11 [class.copy]p23: 363252723Sdim // A defaulted copy/move assignment operator for a class X is defined as 364252723Sdim // deleted if X has: 365252723Sdim // -- a direct or virtual base class B that cannot be copied/moved [...] 366252723Sdim // -- a non-static data member of class type M (or array thereof) 367252723Sdim // that cannot be copied or moved [...] 368252723Sdim if (!Subobj->hasSimpleMoveAssignment()) 369252723Sdim data().NeedOverloadResolutionForMoveAssignment = true; 370252723Sdim 371252723Sdim // C++11 [class.ctor]p5, C++11 [class.copy]p11, C++11 [class.dtor]p5: 372252723Sdim // A defaulted [ctor or dtor] for a class X is defined as 373252723Sdim // deleted if X has: 374252723Sdim // -- any direct or virtual base class [...] has a type with a destructor 375252723Sdim // that is deleted or inaccessible from the defaulted [ctor or dtor]. 376252723Sdim // -- any non-static data member has a type with a destructor 377252723Sdim // that is deleted or inaccessible from the defaulted [ctor or dtor]. 378252723Sdim if (!Subobj->hasSimpleDestructor()) { 379252723Sdim data().NeedOverloadResolutionForMoveConstructor = true; 380252723Sdim data().NeedOverloadResolutionForDestructor = true; 381252723Sdim } 382252723Sdim} 383252723Sdim 384202379Srdivacky/// Callback function for CXXRecordDecl::forallBases that acknowledges 385202379Srdivacky/// that it saw a base class. 386202379Srdivackystatic bool SawBase(const CXXRecordDecl *, void *) { 387202379Srdivacky return true; 388202379Srdivacky} 389202379Srdivacky 390202379Srdivackybool CXXRecordDecl::hasAnyDependentBases() const { 391202379Srdivacky if (!isDependentContext()) 392202379Srdivacky return false; 393202379Srdivacky 394202379Srdivacky return !forallBases(SawBase, 0); 395202379Srdivacky} 396202379Srdivacky 397221345Sdimbool CXXRecordDecl::isTriviallyCopyable() const { 398221345Sdim // C++0x [class]p5: 399221345Sdim // A trivially copyable class is a class that: 400221345Sdim // -- has no non-trivial copy constructors, 401252723Sdim if (hasNonTrivialCopyConstructor()) return false; 402221345Sdim // -- has no non-trivial move constructors, 403252723Sdim if (hasNonTrivialMoveConstructor()) return false; 404221345Sdim // -- has no non-trivial copy assignment operators, 405252723Sdim if (hasNonTrivialCopyAssignment()) return false; 406221345Sdim // -- has no non-trivial move assignment operators, and 407252723Sdim if (hasNonTrivialMoveAssignment()) return false; 408221345Sdim // -- has a trivial destructor. 409221345Sdim if (!hasTrivialDestructor()) return false; 410221345Sdim 411221345Sdim return true; 412221345Sdim} 413221345Sdim 414218893Sdimvoid CXXRecordDecl::markedVirtualFunctionPure() { 415218893Sdim // C++ [class.abstract]p2: 416218893Sdim // A class is abstract if it has at least one pure virtual function. 417218893Sdim data().Abstract = true; 418218893Sdim} 419193326Sed 420218893Sdimvoid CXXRecordDecl::addedMember(Decl *D) { 421235633Sdim if (!D->isImplicit() && 422235633Sdim !isa<FieldDecl>(D) && 423235633Sdim !isa<IndirectFieldDecl>(D) && 424245431Sdim (!isa<TagDecl>(D) || cast<TagDecl>(D)->getTagKind() == TTK_Class || 425245431Sdim cast<TagDecl>(D)->getTagKind() == TTK_Interface)) 426235633Sdim data().HasOnlyCMembers = false; 427235633Sdim 428218893Sdim // Ignore friends and invalid declarations. 429218893Sdim if (D->getFriendObjectKind() || D->isInvalidDecl()) 430218893Sdim return; 431210299Sed 432218893Sdim FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D); 433218893Sdim if (FunTmpl) 434218893Sdim D = FunTmpl->getTemplatedDecl(); 435218893Sdim 436218893Sdim if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { 437218893Sdim if (Method->isVirtual()) { 438218893Sdim // C++ [dcl.init.aggr]p1: 439218893Sdim // An aggregate is an array or a class with [...] no virtual functions. 440218893Sdim data().Aggregate = false; 441218893Sdim 442218893Sdim // C++ [class]p4: 443218893Sdim // A POD-struct is an aggregate class... 444218893Sdim data().PlainOldData = false; 445218893Sdim 446218893Sdim // Virtual functions make the class non-empty. 447218893Sdim // FIXME: Standard ref? 448218893Sdim data().Empty = false; 449193326Sed 450218893Sdim // C++ [class.virtual]p1: 451218893Sdim // A class that declares or inherits a virtual function is called a 452218893Sdim // polymorphic class. 453218893Sdim data().Polymorphic = true; 454221345Sdim 455252723Sdim // C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25: 456252723Sdim // A [default constructor, copy/move constructor, or copy/move 457252723Sdim // assignment operator for a class X] is trivial [...] if: 458221345Sdim // -- class X has no virtual functions [...] 459252723Sdim data().HasTrivialSpecialMembers &= SMF_Destructor; 460221345Sdim 461221345Sdim // C++0x [class]p7: 462221345Sdim // A standard-layout class is a class that: [...] 463221345Sdim // -- has no virtual functions 464221345Sdim data().IsStandardLayout = false; 465218893Sdim } 466218893Sdim } 467193326Sed 468252723Sdim // Notify the listener if an implicit member was added after the definition 469252723Sdim // was completed. 470252723Sdim if (!isBeingDefined() && D->isImplicit()) 471252723Sdim if (ASTMutationListener *L = getASTMutationListener()) 472252723Sdim L->AddedCXXImplicitMember(data().Definition, D); 473218893Sdim 474252723Sdim // The kind of special member this declaration is, if any. 475252723Sdim unsigned SMKind = 0; 476252723Sdim 477252723Sdim // Handle constructors. 478218893Sdim if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) { 479252723Sdim if (!Constructor->isImplicit()) { 480252723Sdim // Note that we have a user-declared constructor. 481252723Sdim data().UserDeclaredConstructor = true; 482218893Sdim 483252723Sdim // C++ [class]p4: 484252723Sdim // A POD-struct is an aggregate class [...] 485252723Sdim // Since the POD bit is meant to be C++03 POD-ness, clear it even if the 486252723Sdim // type is technically an aggregate in C++0x since it wouldn't be in 03. 487252723Sdim data().PlainOldData = false; 488252723Sdim } 489252723Sdim 490226890Sdim // Technically, "user-provided" is only defined for special member 491226890Sdim // functions, but the intent of the standard is clearly that it should apply 492226890Sdim // to all functions. 493226890Sdim bool UserProvided = Constructor->isUserProvided(); 494218893Sdim 495223017Sdim if (Constructor->isDefaultConstructor()) { 496252723Sdim SMKind |= SMF_DefaultConstructor; 497252723Sdim 498252723Sdim if (UserProvided) 499223017Sdim data().UserProvidedDefaultConstructor = true; 500252723Sdim if (Constructor->isConstexpr()) 501235633Sdim data().HasConstexprDefaultConstructor = true; 502223017Sdim } 503218893Sdim 504221345Sdim if (!FunTmpl) { 505252723Sdim unsigned Quals; 506252723Sdim if (Constructor->isCopyConstructor(Quals)) { 507252723Sdim SMKind |= SMF_CopyConstructor; 508221345Sdim 509252723Sdim if (Quals & Qualifiers::Const) 510252723Sdim data().HasDeclaredCopyConstructorWithConstParam = true; 511252723Sdim } else if (Constructor->isMoveConstructor()) 512252723Sdim SMKind |= SMF_MoveConstructor; 513252723Sdim } 514223017Sdim 515252723Sdim // Record if we see any constexpr constructors which are neither copy 516252723Sdim // nor move constructors. 517252723Sdim if (Constructor->isConstexpr() && !Constructor->isCopyOrMoveConstructor()) 518226890Sdim data().HasConstexprNonCopyMoveConstructor = true; 519221345Sdim 520223017Sdim // C++ [dcl.init.aggr]p1: 521223017Sdim // An aggregate is an array or a class with no user-declared 522223017Sdim // constructors [...]. 523252723Sdim // C++11 [dcl.init.aggr]p1: 524223017Sdim // An aggregate is an array or a class with no user-provided 525223017Sdim // constructors [...]. 526252723Sdim if (getASTContext().getLangOpts().CPlusPlus11 527252723Sdim ? UserProvided : !Constructor->isImplicit()) 528223017Sdim data().Aggregate = false; 529198092Srdivacky } 530193326Sed 531252723Sdim // Handle destructors. 532223017Sdim if (CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D)) { 533252723Sdim SMKind |= SMF_Destructor; 534235633Sdim 535252723Sdim if (!DD->isImplicit()) 536252723Sdim data().HasIrrelevantDestructor = false; 537245431Sdim 538252723Sdim // C++11 [class.dtor]p5: 539252723Sdim // A destructor is trivial if [...] the destructor is not virtual. 540252723Sdim if (DD->isVirtual()) 541252723Sdim data().HasTrivialSpecialMembers &= ~SMF_Destructor; 542218893Sdim } 543252723Sdim 544252723Sdim // Handle member functions. 545218893Sdim if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { 546223017Sdim if (Method->isCopyAssignmentOperator()) { 547252723Sdim SMKind |= SMF_CopyAssignment; 548221345Sdim 549252723Sdim const ReferenceType *ParamTy = 550252723Sdim Method->getParamDecl(0)->getType()->getAs<ReferenceType>(); 551252723Sdim if (!ParamTy || ParamTy->getPointeeType().isConstQualified()) 552252723Sdim data().HasDeclaredCopyAssignmentWithConstParam = true; 553223017Sdim } 554223017Sdim 555252723Sdim if (Method->isMoveAssignmentOperator()) 556252723Sdim SMKind |= SMF_MoveAssignment; 557223017Sdim 558218893Sdim // Keep the list of conversion functions up-to-date. 559218893Sdim if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) { 560252723Sdim // FIXME: We use the 'unsafe' accessor for the access specifier here, 561252723Sdim // because Sema may not have set it yet. That's really just a misdesign 562252723Sdim // in Sema. However, LLDB *will* have set the access specifier correctly, 563252723Sdim // and adds declarations after the class is technically completed, 564252723Sdim // so completeDefinition()'s overriding of the access specifiers doesn't 565252723Sdim // work. 566252723Sdim AccessSpecifier AS = Conversion->getAccessUnsafe(); 567193326Sed 568252723Sdim if (Conversion->getPrimaryTemplate()) { 569252723Sdim // We don't record specializations. 570218893Sdim } else { 571263509Sdim ASTContext &Ctx = getASTContext(); 572263509Sdim ASTUnresolvedSet &Conversions = data().Conversions.get(Ctx); 573263509Sdim NamedDecl *Primary = 574263509Sdim FunTmpl ? cast<NamedDecl>(FunTmpl) : cast<NamedDecl>(Conversion); 575263509Sdim if (Primary->getPreviousDecl()) 576263509Sdim Conversions.replace(cast<NamedDecl>(Primary->getPreviousDecl()), 577263509Sdim Primary, AS); 578218893Sdim else 579263509Sdim Conversions.addDecl(Ctx, Primary, AS); 580218893Sdim } 581218893Sdim } 582252723Sdim 583252723Sdim if (SMKind) { 584252723Sdim // If this is the first declaration of a special member, we no longer have 585252723Sdim // an implicit trivial special member. 586252723Sdim data().HasTrivialSpecialMembers &= 587252723Sdim data().DeclaredSpecialMembers | ~SMKind; 588252723Sdim 589252723Sdim if (!Method->isImplicit() && !Method->isUserProvided()) { 590252723Sdim // This method is user-declared but not user-provided. We can't work out 591252723Sdim // whether it's trivial yet (not until we get to the end of the class). 592252723Sdim // We'll handle this method in finishedDefaultedOrDeletedMember. 593252723Sdim } else if (Method->isTrivial()) 594252723Sdim data().HasTrivialSpecialMembers |= SMKind; 595252723Sdim else 596252723Sdim data().DeclaredNonTrivialSpecialMembers |= SMKind; 597252723Sdim 598252723Sdim // Note when we have declared a declared special member, and suppress the 599252723Sdim // implicit declaration of this special member. 600252723Sdim data().DeclaredSpecialMembers |= SMKind; 601252723Sdim 602252723Sdim if (!Method->isImplicit()) { 603252723Sdim data().UserDeclaredSpecialMembers |= SMKind; 604252723Sdim 605252723Sdim // C++03 [class]p4: 606252723Sdim // A POD-struct is an aggregate class that has [...] no user-defined 607252723Sdim // copy assignment operator and no user-defined destructor. 608252723Sdim // 609252723Sdim // Since the POD bit is meant to be C++03 POD-ness, and in C++03, 610252723Sdim // aggregates could not have any constructors, clear it even for an 611252723Sdim // explicitly defaulted or deleted constructor. 612252723Sdim // type is technically an aggregate in C++0x since it wouldn't be in 03. 613252723Sdim // 614252723Sdim // Also, a user-declared move assignment operator makes a class non-POD. 615252723Sdim // This is an extension in C++03. 616252723Sdim data().PlainOldData = false; 617252723Sdim } 618252723Sdim } 619252723Sdim 620193326Sed return; 621218893Sdim } 622252723Sdim 623218893Sdim // Handle non-static data members. 624218893Sdim if (FieldDecl *Field = dyn_cast<FieldDecl>(D)) { 625226890Sdim // C++ [class.bit]p2: 626226890Sdim // A declaration for a bit-field that omits the identifier declares an 627226890Sdim // unnamed bit-field. Unnamed bit-fields are not members and cannot be 628226890Sdim // initialized. 629226890Sdim if (Field->isUnnamedBitfield()) 630226890Sdim return; 631226890Sdim 632218893Sdim // C++ [dcl.init.aggr]p1: 633218893Sdim // An aggregate is an array or a class (clause 9) with [...] no 634218893Sdim // private or protected non-static data members (clause 11). 635218893Sdim // 636218893Sdim // A POD must be an aggregate. 637218893Sdim if (D->getAccess() == AS_private || D->getAccess() == AS_protected) { 638218893Sdim data().Aggregate = false; 639218893Sdim data().PlainOldData = false; 640218893Sdim } 641221345Sdim 642221345Sdim // C++0x [class]p7: 643221345Sdim // A standard-layout class is a class that: 644221345Sdim // [...] 645221345Sdim // -- has the same access control for all non-static data members, 646221345Sdim switch (D->getAccess()) { 647221345Sdim case AS_private: data().HasPrivateFields = true; break; 648221345Sdim case AS_protected: data().HasProtectedFields = true; break; 649221345Sdim case AS_public: data().HasPublicFields = true; break; 650226890Sdim case AS_none: llvm_unreachable("Invalid access specifier"); 651221345Sdim }; 652221345Sdim if ((data().HasPrivateFields + data().HasProtectedFields + 653221345Sdim data().HasPublicFields) > 1) 654221345Sdim data().IsStandardLayout = false; 655221345Sdim 656223017Sdim // Keep track of the presence of mutable fields. 657223017Sdim if (Field->isMutable()) 658223017Sdim data().HasMutableFields = true; 659223017Sdim 660221345Sdim // C++0x [class]p9: 661218893Sdim // A POD struct is a class that is both a trivial class and a 662218893Sdim // standard-layout class, and has no non-static data members of type 663218893Sdim // non-POD struct, non-POD union (or array of such types). 664224145Sdim // 665224145Sdim // Automatic Reference Counting: the presence of a member of Objective-C pointer type 666224145Sdim // that does not explicitly have no lifetime makes the class a non-POD. 667224145Sdim // However, we delay setting PlainOldData to false in this case so that 668224145Sdim // Sema has a chance to diagnostic causes where the same class will be 669245431Sdim // non-POD with Automatic Reference Counting but a POD without ARC. 670224145Sdim // In this case, the class will become a non-POD class when we complete 671224145Sdim // the definition. 672218893Sdim ASTContext &Context = getASTContext(); 673218893Sdim QualType T = Context.getBaseElementType(Field->getType()); 674224145Sdim if (T->isObjCRetainableType() || T.isObjCGCStrong()) { 675235633Sdim if (!Context.getLangOpts().ObjCAutoRefCount || 676224145Sdim T.getObjCLifetime() != Qualifiers::OCL_ExplicitNone) 677224145Sdim setHasObjectMember(true); 678263509Sdim } else if (!T.isCXX98PODType(Context)) 679218893Sdim data().PlainOldData = false; 680224145Sdim 681221345Sdim if (T->isReferenceType()) { 682252723Sdim if (!Field->hasInClassInitializer()) 683252723Sdim data().HasUninitializedReferenceMember = true; 684221345Sdim 685221345Sdim // C++0x [class]p7: 686221345Sdim // A standard-layout class is a class that: 687221345Sdim // -- has no non-static data members of type [...] reference, 688221345Sdim data().IsStandardLayout = false; 689221345Sdim } 690221345Sdim 691235633Sdim // Record if this field is the first non-literal or volatile field or base. 692252723Sdim if (!T->isLiteralType(Context) || T.isVolatileQualified()) 693221345Sdim data().HasNonLiteralTypeFieldsOrBases = true; 694221345Sdim 695223017Sdim if (Field->hasInClassInitializer()) { 696245431Sdim data().HasInClassInitializer = true; 697245431Sdim 698245431Sdim // C++11 [class]p5: 699223017Sdim // A default constructor is trivial if [...] no non-static data member 700223017Sdim // of its class has a brace-or-equal-initializer. 701252723Sdim data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor; 702223017Sdim 703245431Sdim // C++11 [dcl.init.aggr]p1: 704223017Sdim // An aggregate is a [...] class with [...] no 705223017Sdim // brace-or-equal-initializers for non-static data members. 706252723Sdim // 707252723Sdim // This rule was removed in C++1y. 708252723Sdim if (!getASTContext().getLangOpts().CPlusPlus1y) 709252723Sdim data().Aggregate = false; 710223017Sdim 711245431Sdim // C++11 [class]p10: 712223017Sdim // A POD struct is [...] a trivial class. 713223017Sdim data().PlainOldData = false; 714223017Sdim } 715223017Sdim 716252723Sdim // C++11 [class.copy]p23: 717252723Sdim // A defaulted copy/move assignment operator for a class X is defined 718252723Sdim // as deleted if X has: 719252723Sdim // -- a non-static data member of reference type 720252723Sdim if (T->isReferenceType()) 721252723Sdim data().DefaultedMoveAssignmentIsDeleted = true; 722252723Sdim 723218893Sdim if (const RecordType *RecordTy = T->getAs<RecordType>()) { 724218893Sdim CXXRecordDecl* FieldRec = cast<CXXRecordDecl>(RecordTy->getDecl()); 725218893Sdim if (FieldRec->getDefinition()) { 726252723Sdim addedClassSubobject(FieldRec); 727252723Sdim 728263509Sdim // We may need to perform overload resolution to determine whether a 729263509Sdim // field can be moved if it's const or volatile qualified. 730263509Sdim if (T.getCVRQualifiers() & (Qualifiers::Const | Qualifiers::Volatile)) { 731263509Sdim data().NeedOverloadResolutionForMoveConstructor = true; 732263509Sdim data().NeedOverloadResolutionForMoveAssignment = true; 733263509Sdim } 734263509Sdim 735252723Sdim // C++11 [class.ctor]p5, C++11 [class.copy]p11: 736252723Sdim // A defaulted [special member] for a class X is defined as 737252723Sdim // deleted if: 738252723Sdim // -- X is a union-like class that has a variant member with a 739252723Sdim // non-trivial [corresponding special member] 740252723Sdim if (isUnion()) { 741252723Sdim if (FieldRec->hasNonTrivialMoveConstructor()) 742252723Sdim data().DefaultedMoveConstructorIsDeleted = true; 743252723Sdim if (FieldRec->hasNonTrivialMoveAssignment()) 744252723Sdim data().DefaultedMoveAssignmentIsDeleted = true; 745252723Sdim if (FieldRec->hasNonTrivialDestructor()) 746252723Sdim data().DefaultedDestructorIsDeleted = true; 747252723Sdim } 748252723Sdim 749223017Sdim // C++0x [class.ctor]p5: 750235633Sdim // A default constructor is trivial [...] if: 751223017Sdim // -- for all the non-static data members of its class that are of 752223017Sdim // class type (or array thereof), each such class has a trivial 753223017Sdim // default constructor. 754223017Sdim if (!FieldRec->hasTrivialDefaultConstructor()) 755252723Sdim data().HasTrivialSpecialMembers &= ~SMF_DefaultConstructor; 756221345Sdim 757221345Sdim // C++0x [class.copy]p13: 758221345Sdim // A copy/move constructor for class X is trivial if [...] 759221345Sdim // [...] 760221345Sdim // -- for each non-static data member of X that is of class type (or 761221345Sdim // an array thereof), the constructor selected to copy/move that 762221345Sdim // member is trivial; 763218893Sdim if (!FieldRec->hasTrivialCopyConstructor()) 764252723Sdim data().HasTrivialSpecialMembers &= ~SMF_CopyConstructor; 765252723Sdim // If the field doesn't have a simple move constructor, we'll eagerly 766252723Sdim // declare the move constructor for this class and we'll decide whether 767252723Sdim // it's trivial then. 768252723Sdim if (!FieldRec->hasTrivialMoveConstructor()) 769252723Sdim data().HasTrivialSpecialMembers &= ~SMF_MoveConstructor; 770221345Sdim 771221345Sdim // C++0x [class.copy]p27: 772221345Sdim // A copy/move assignment operator for class X is trivial if [...] 773221345Sdim // [...] 774221345Sdim // -- for each non-static data member of X that is of class type (or 775221345Sdim // an array thereof), the assignment operator selected to 776221345Sdim // copy/move that member is trivial; 777218893Sdim if (!FieldRec->hasTrivialCopyAssignment()) 778252723Sdim data().HasTrivialSpecialMembers &= ~SMF_CopyAssignment; 779252723Sdim // If the field doesn't have a simple move assignment, we'll eagerly 780252723Sdim // declare the move assignment for this class and we'll decide whether 781252723Sdim // it's trivial then. 782252723Sdim if (!FieldRec->hasTrivialMoveAssignment()) 783252723Sdim data().HasTrivialSpecialMembers &= ~SMF_MoveAssignment; 784221345Sdim 785218893Sdim if (!FieldRec->hasTrivialDestructor()) 786252723Sdim data().HasTrivialSpecialMembers &= ~SMF_Destructor; 787235633Sdim if (!FieldRec->hasIrrelevantDestructor()) 788235633Sdim data().HasIrrelevantDestructor = false; 789224145Sdim if (FieldRec->hasObjectMember()) 790224145Sdim setHasObjectMember(true); 791252723Sdim if (FieldRec->hasVolatileMember()) 792252723Sdim setHasVolatileMember(true); 793221345Sdim 794221345Sdim // C++0x [class]p7: 795221345Sdim // A standard-layout class is a class that: 796221345Sdim // -- has no non-static data members of type non-standard-layout 797221345Sdim // class (or array of such types) [...] 798221345Sdim if (!FieldRec->isStandardLayout()) 799221345Sdim data().IsStandardLayout = false; 800221345Sdim 801221345Sdim // C++0x [class]p7: 802221345Sdim // A standard-layout class is a class that: 803221345Sdim // [...] 804221345Sdim // -- has no base classes of the same type as the first non-static 805221345Sdim // data member. 806221345Sdim // We don't want to expend bits in the state of the record decl 807221345Sdim // tracking whether this is the first non-static data member so we 808221345Sdim // cheat a bit and use some of the existing state: the empty bit. 809221345Sdim // Virtual bases and virtual methods make a class non-empty, but they 810221345Sdim // also make it non-standard-layout so we needn't check here. 811221345Sdim // A non-empty base class may leave the class standard-layout, but not 812221345Sdim // if we have arrived here, and have at least on non-static data 813221345Sdim // member. If IsStandardLayout remains true, then the first non-static 814221345Sdim // data member must come through here with Empty still true, and Empty 815221345Sdim // will subsequently be set to false below. 816221345Sdim if (data().IsStandardLayout && data().Empty) { 817221345Sdim for (CXXRecordDecl::base_class_const_iterator BI = bases_begin(), 818221345Sdim BE = bases_end(); 819221345Sdim BI != BE; ++BI) { 820221345Sdim if (Context.hasSameUnqualifiedType(BI->getType(), T)) { 821221345Sdim data().IsStandardLayout = false; 822221345Sdim break; 823221345Sdim } 824221345Sdim } 825221345Sdim } 826223017Sdim 827223017Sdim // Keep track of the presence of mutable fields. 828223017Sdim if (FieldRec->hasMutableFields()) 829223017Sdim data().HasMutableFields = true; 830235633Sdim 831235633Sdim // C++11 [class.copy]p13: 832235633Sdim // If the implicitly-defined constructor would satisfy the 833235633Sdim // requirements of a constexpr constructor, the implicitly-defined 834235633Sdim // constructor is constexpr. 835235633Sdim // C++11 [dcl.constexpr]p4: 836235633Sdim // -- every constructor involved in initializing non-static data 837235633Sdim // members [...] shall be a constexpr constructor 838235633Sdim if (!Field->hasInClassInitializer() && 839245431Sdim !FieldRec->hasConstexprDefaultConstructor() && !isUnion()) 840235633Sdim // The standard requires any in-class initializer to be a constant 841235633Sdim // expression. We consider this to be a defect. 842235633Sdim data().DefaultedDefaultConstructorIsConstexpr = false; 843252723Sdim 844252723Sdim // C++11 [class.copy]p8: 845252723Sdim // The implicitly-declared copy constructor for a class X will have 846252723Sdim // the form 'X::X(const X&)' if [...] for all the non-static data 847252723Sdim // members of X that are of a class type M (or array thereof), each 848252723Sdim // such class type has a copy constructor whose first parameter is 849252723Sdim // of type 'const M&' or 'const volatile M&'. 850252723Sdim if (!FieldRec->hasCopyConstructorWithConstParam()) 851252723Sdim data().ImplicitCopyConstructorHasConstParam = false; 852252723Sdim 853252723Sdim // C++11 [class.copy]p18: 854252723Sdim // The implicitly-declared copy assignment oeprator for a class X will 855252723Sdim // have the form 'X& X::operator=(const X&)' if [...] for all the 856252723Sdim // non-static data members of X that are of a class type M (or array 857252723Sdim // thereof), each such class type has a copy assignment operator whose 858252723Sdim // parameter is of type 'const M&', 'const volatile M&' or 'M'. 859252723Sdim if (!FieldRec->hasCopyAssignmentWithConstParam()) 860252723Sdim data().ImplicitCopyAssignmentHasConstParam = false; 861252723Sdim 862252723Sdim if (FieldRec->hasUninitializedReferenceMember() && 863252723Sdim !Field->hasInClassInitializer()) 864252723Sdim data().HasUninitializedReferenceMember = true; 865218893Sdim } 866235633Sdim } else { 867235633Sdim // Base element type of field is a non-class type. 868252723Sdim if (!T->isLiteralType(Context) || 869245431Sdim (!Field->hasInClassInitializer() && !isUnion())) 870235633Sdim data().DefaultedDefaultConstructorIsConstexpr = false; 871252723Sdim 872252723Sdim // C++11 [class.copy]p23: 873252723Sdim // A defaulted copy/move assignment operator for a class X is defined 874252723Sdim // as deleted if X has: 875252723Sdim // -- a non-static data member of const non-class type (or array 876252723Sdim // thereof) 877252723Sdim if (T.isConstQualified()) 878252723Sdim data().DefaultedMoveAssignmentIsDeleted = true; 879218893Sdim } 880221345Sdim 881221345Sdim // C++0x [class]p7: 882221345Sdim // A standard-layout class is a class that: 883221345Sdim // [...] 884221345Sdim // -- either has no non-static data members in the most derived 885221345Sdim // class and at most one base class with non-static data members, 886221345Sdim // or has no base classes with non-static data members, and 887221345Sdim // At this point we know that we have a non-static data member, so the last 888221345Sdim // clause holds. 889221345Sdim if (!data().HasNoNonEmptyBases) 890221345Sdim data().IsStandardLayout = false; 891221345Sdim 892218893Sdim // If this is not a zero-length bit-field, then the class is not empty. 893218893Sdim if (data().Empty) { 894226890Sdim if (!Field->isBitField() || 895226890Sdim (!Field->getBitWidth()->isTypeDependent() && 896226890Sdim !Field->getBitWidth()->isValueDependent() && 897226890Sdim Field->getBitWidthValue(Context) != 0)) 898218893Sdim data().Empty = false; 899218893Sdim } 900218893Sdim } 901218893Sdim 902218893Sdim // Handle using declarations of conversion functions. 903263509Sdim if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(D)) { 904218893Sdim if (Shadow->getDeclName().getNameKind() 905263509Sdim == DeclarationName::CXXConversionFunctionName) { 906263509Sdim ASTContext &Ctx = getASTContext(); 907263509Sdim data().Conversions.get(Ctx).addDecl(Ctx, Shadow, Shadow->getAccess()); 908263509Sdim } 909263509Sdim } 910193326Sed} 911193326Sed 912252723Sdimvoid CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) { 913252723Sdim assert(!D->isImplicit() && !D->isUserProvided()); 914252723Sdim 915252723Sdim // The kind of special member this declaration is, if any. 916252723Sdim unsigned SMKind = 0; 917252723Sdim 918252723Sdim if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) { 919252723Sdim if (Constructor->isDefaultConstructor()) { 920252723Sdim SMKind |= SMF_DefaultConstructor; 921252723Sdim if (Constructor->isConstexpr()) 922252723Sdim data().HasConstexprDefaultConstructor = true; 923252723Sdim } 924252723Sdim if (Constructor->isCopyConstructor()) 925252723Sdim SMKind |= SMF_CopyConstructor; 926252723Sdim else if (Constructor->isMoveConstructor()) 927252723Sdim SMKind |= SMF_MoveConstructor; 928252723Sdim else if (Constructor->isConstexpr()) 929252723Sdim // We may now know that the constructor is constexpr. 930252723Sdim data().HasConstexprNonCopyMoveConstructor = true; 931252723Sdim } else if (isa<CXXDestructorDecl>(D)) 932252723Sdim SMKind |= SMF_Destructor; 933252723Sdim else if (D->isCopyAssignmentOperator()) 934252723Sdim SMKind |= SMF_CopyAssignment; 935252723Sdim else if (D->isMoveAssignmentOperator()) 936252723Sdim SMKind |= SMF_MoveAssignment; 937252723Sdim 938252723Sdim // Update which trivial / non-trivial special members we have. 939252723Sdim // addedMember will have skipped this step for this member. 940252723Sdim if (D->isTrivial()) 941252723Sdim data().HasTrivialSpecialMembers |= SMKind; 942252723Sdim else 943252723Sdim data().DeclaredNonTrivialSpecialMembers |= SMKind; 944252723Sdim} 945252723Sdim 946235633Sdimbool CXXRecordDecl::isCLike() const { 947245431Sdim if (getTagKind() == TTK_Class || getTagKind() == TTK_Interface || 948245431Sdim !TemplateOrInstantiation.isNull()) 949235633Sdim return false; 950235633Sdim if (!hasDefinition()) 951235633Sdim return true; 952235633Sdim 953235633Sdim return isPOD() && data().HasOnlyCMembers; 954235633Sdim} 955263509Sdim 956263509Sdimbool CXXRecordDecl::isGenericLambda() const { 957263509Sdim if (!isLambda()) return false; 958263509Sdim return getLambdaData().IsGenericLambda; 959263509Sdim} 960235633Sdim 961263509SdimCXXMethodDecl* CXXRecordDecl::getLambdaCallOperator() const { 962263509Sdim if (!isLambda()) return 0; 963263509Sdim DeclarationName Name = 964263509Sdim getASTContext().DeclarationNames.getCXXOperatorName(OO_Call); 965263509Sdim DeclContext::lookup_const_result Calls = lookup(Name); 966263509Sdim 967263509Sdim assert(!Calls.empty() && "Missing lambda call operator!"); 968263509Sdim assert(Calls.size() == 1 && "More than one lambda call operator!"); 969263509Sdim 970263509Sdim NamedDecl *CallOp = Calls.front(); 971263509Sdim if (FunctionTemplateDecl *CallOpTmpl = 972263509Sdim dyn_cast<FunctionTemplateDecl>(CallOp)) 973263509Sdim return cast<CXXMethodDecl>(CallOpTmpl->getTemplatedDecl()); 974263509Sdim 975263509Sdim return cast<CXXMethodDecl>(CallOp); 976263509Sdim} 977263509Sdim 978263509SdimCXXMethodDecl* CXXRecordDecl::getLambdaStaticInvoker() const { 979263509Sdim if (!isLambda()) return 0; 980263509Sdim DeclarationName Name = 981263509Sdim &getASTContext().Idents.get(getLambdaStaticInvokerName()); 982263509Sdim DeclContext::lookup_const_result Invoker = lookup(Name); 983263509Sdim if (Invoker.empty()) return 0; 984263509Sdim assert(Invoker.size() == 1 && "More than one static invoker operator!"); 985263509Sdim NamedDecl *InvokerFun = Invoker.front(); 986263509Sdim if (FunctionTemplateDecl *InvokerTemplate = 987263509Sdim dyn_cast<FunctionTemplateDecl>(InvokerFun)) 988263509Sdim return cast<CXXMethodDecl>(InvokerTemplate->getTemplatedDecl()); 989263509Sdim 990263509Sdim return cast<CXXMethodDecl>(InvokerFun); 991263509Sdim} 992263509Sdim 993235633Sdimvoid CXXRecordDecl::getCaptureFields( 994235633Sdim llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures, 995235633Sdim FieldDecl *&ThisCapture) const { 996235633Sdim Captures.clear(); 997235633Sdim ThisCapture = 0; 998235633Sdim 999235633Sdim LambdaDefinitionData &Lambda = getLambdaData(); 1000235633Sdim RecordDecl::field_iterator Field = field_begin(); 1001235633Sdim for (LambdaExpr::Capture *C = Lambda.Captures, *CEnd = C + Lambda.NumCaptures; 1002235633Sdim C != CEnd; ++C, ++Field) { 1003263509Sdim if (C->capturesThis()) 1004235633Sdim ThisCapture = *Field; 1005263509Sdim else if (C->capturesVariable()) 1006263509Sdim Captures[C->getCapturedVar()] = *Field; 1007235633Sdim } 1008263509Sdim assert(Field == field_end()); 1009235633Sdim} 1010235633Sdim 1011263509SdimTemplateParameterList * 1012263509SdimCXXRecordDecl::getGenericLambdaTemplateParameterList() const { 1013263509Sdim if (!isLambda()) return 0; 1014263509Sdim CXXMethodDecl *CallOp = getLambdaCallOperator(); 1015263509Sdim if (FunctionTemplateDecl *Tmpl = CallOp->getDescribedFunctionTemplate()) 1016263509Sdim return Tmpl->getTemplateParameters(); 1017263509Sdim return 0; 1018263509Sdim} 1019235633Sdim 1020205219Srdivackystatic CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) { 1021205219Srdivacky QualType T; 1022206084Srdivacky if (isa<UsingShadowDecl>(Conv)) 1023206084Srdivacky Conv = cast<UsingShadowDecl>(Conv)->getTargetDecl(); 1024205219Srdivacky if (FunctionTemplateDecl *ConvTemp = dyn_cast<FunctionTemplateDecl>(Conv)) 1025205219Srdivacky T = ConvTemp->getTemplatedDecl()->getResultType(); 1026205219Srdivacky else 1027205219Srdivacky T = cast<CXXConversionDecl>(Conv)->getConversionType(); 1028205219Srdivacky return Context.getCanonicalType(T); 1029198092Srdivacky} 1030198092Srdivacky 1031205219Srdivacky/// Collect the visible conversions of a base class. 1032205219Srdivacky/// 1033245431Sdim/// \param Record a base class of the class we're considering 1034205219Srdivacky/// \param InVirtual whether this base class is a virtual base (or a base 1035205219Srdivacky/// of a virtual base) 1036205219Srdivacky/// \param Access the access along the inheritance path to this base 1037205219Srdivacky/// \param ParentHiddenTypes the conversions provided by the inheritors 1038205219Srdivacky/// of this base 1039205219Srdivacky/// \param Output the set to which to add conversions from non-virtual bases 1040205219Srdivacky/// \param VOutput the set to which to add conversions from virtual bases 1041205219Srdivacky/// \param HiddenVBaseCs the set of conversions which were hidden in a 1042205219Srdivacky/// virtual base along some inheritance path 1043205219Srdivackystatic void CollectVisibleConversions(ASTContext &Context, 1044205219Srdivacky CXXRecordDecl *Record, 1045205219Srdivacky bool InVirtual, 1046205219Srdivacky AccessSpecifier Access, 1047205219Srdivacky const llvm::SmallPtrSet<CanQualType, 8> &ParentHiddenTypes, 1048252723Sdim ASTUnresolvedSet &Output, 1049205219Srdivacky UnresolvedSetImpl &VOutput, 1050205219Srdivacky llvm::SmallPtrSet<NamedDecl*, 8> &HiddenVBaseCs) { 1051205219Srdivacky // The set of types which have conversions in this class or its 1052205219Srdivacky // subclasses. As an optimization, we don't copy the derived set 1053205219Srdivacky // unless it might change. 1054205219Srdivacky const llvm::SmallPtrSet<CanQualType, 8> *HiddenTypes = &ParentHiddenTypes; 1055205219Srdivacky llvm::SmallPtrSet<CanQualType, 8> HiddenTypesBuffer; 1056205219Srdivacky 1057205219Srdivacky // Collect the direct conversions and figure out which conversions 1058205219Srdivacky // will be hidden in the subclasses. 1059252723Sdim CXXRecordDecl::conversion_iterator ConvI = Record->conversion_begin(); 1060252723Sdim CXXRecordDecl::conversion_iterator ConvE = Record->conversion_end(); 1061252723Sdim if (ConvI != ConvE) { 1062205219Srdivacky HiddenTypesBuffer = ParentHiddenTypes; 1063205219Srdivacky HiddenTypes = &HiddenTypesBuffer; 1064205219Srdivacky 1065252723Sdim for (CXXRecordDecl::conversion_iterator I = ConvI; I != ConvE; ++I) { 1066245431Sdim CanQualType ConvType(GetConversionType(Context, I.getDecl())); 1067245431Sdim bool Hidden = ParentHiddenTypes.count(ConvType); 1068245431Sdim if (!Hidden) 1069245431Sdim HiddenTypesBuffer.insert(ConvType); 1070205219Srdivacky 1071205219Srdivacky // If this conversion is hidden and we're in a virtual base, 1072205219Srdivacky // remember that it's hidden along some inheritance path. 1073205219Srdivacky if (Hidden && InVirtual) 1074205219Srdivacky HiddenVBaseCs.insert(cast<NamedDecl>(I.getDecl()->getCanonicalDecl())); 1075205219Srdivacky 1076205219Srdivacky // If this conversion isn't hidden, add it to the appropriate output. 1077205219Srdivacky else if (!Hidden) { 1078205219Srdivacky AccessSpecifier IAccess 1079205219Srdivacky = CXXRecordDecl::MergeAccess(Access, I.getAccess()); 1080205219Srdivacky 1081205219Srdivacky if (InVirtual) 1082205219Srdivacky VOutput.addDecl(I.getDecl(), IAccess); 1083198092Srdivacky else 1084252723Sdim Output.addDecl(Context, I.getDecl(), IAccess); 1085198092Srdivacky } 1086198092Srdivacky } 1087198092Srdivacky } 1088198893Srdivacky 1089205219Srdivacky // Collect information recursively from any base classes. 1090205219Srdivacky for (CXXRecordDecl::base_class_iterator 1091205219Srdivacky I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) { 1092205219Srdivacky const RecordType *RT = I->getType()->getAs<RecordType>(); 1093205219Srdivacky if (!RT) continue; 1094198893Srdivacky 1095205219Srdivacky AccessSpecifier BaseAccess 1096205219Srdivacky = CXXRecordDecl::MergeAccess(Access, I->getAccessSpecifier()); 1097205219Srdivacky bool BaseInVirtual = InVirtual || I->isVirtual(); 1098198893Srdivacky 1099205219Srdivacky CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl()); 1100205219Srdivacky CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess, 1101205219Srdivacky *HiddenTypes, Output, VOutput, HiddenVBaseCs); 1102198092Srdivacky } 1103205219Srdivacky} 1104198893Srdivacky 1105205219Srdivacky/// Collect the visible conversions of a class. 1106205219Srdivacky/// 1107205219Srdivacky/// This would be extremely straightforward if it weren't for virtual 1108205219Srdivacky/// bases. It might be worth special-casing that, really. 1109205219Srdivackystatic void CollectVisibleConversions(ASTContext &Context, 1110205219Srdivacky CXXRecordDecl *Record, 1111252723Sdim ASTUnresolvedSet &Output) { 1112205219Srdivacky // The collection of all conversions in virtual bases that we've 1113205219Srdivacky // found. These will be added to the output as long as they don't 1114205219Srdivacky // appear in the hidden-conversions set. 1115205219Srdivacky UnresolvedSet<8> VBaseCs; 1116205219Srdivacky 1117205219Srdivacky // The set of conversions in virtual bases that we've determined to 1118205219Srdivacky // be hidden. 1119205219Srdivacky llvm::SmallPtrSet<NamedDecl*, 8> HiddenVBaseCs; 1120205219Srdivacky 1121205219Srdivacky // The set of types hidden by classes derived from this one. 1122205219Srdivacky llvm::SmallPtrSet<CanQualType, 8> HiddenTypes; 1123205219Srdivacky 1124205219Srdivacky // Go ahead and collect the direct conversions and add them to the 1125205219Srdivacky // hidden-types set. 1126252723Sdim CXXRecordDecl::conversion_iterator ConvI = Record->conversion_begin(); 1127252723Sdim CXXRecordDecl::conversion_iterator ConvE = Record->conversion_end(); 1128252723Sdim Output.append(Context, ConvI, ConvE); 1129252723Sdim for (; ConvI != ConvE; ++ConvI) 1130252723Sdim HiddenTypes.insert(GetConversionType(Context, ConvI.getDecl())); 1131205219Srdivacky 1132205219Srdivacky // Recursively collect conversions from base classes. 1133205219Srdivacky for (CXXRecordDecl::base_class_iterator 1134205219Srdivacky I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) { 1135205219Srdivacky const RecordType *RT = I->getType()->getAs<RecordType>(); 1136205219Srdivacky if (!RT) continue; 1137205219Srdivacky 1138205219Srdivacky CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()), 1139205219Srdivacky I->isVirtual(), I->getAccessSpecifier(), 1140205219Srdivacky HiddenTypes, Output, VBaseCs, HiddenVBaseCs); 1141198092Srdivacky } 1142205219Srdivacky 1143205219Srdivacky // Add any unhidden conversions provided by virtual bases. 1144205219Srdivacky for (UnresolvedSetIterator I = VBaseCs.begin(), E = VBaseCs.end(); 1145205219Srdivacky I != E; ++I) { 1146205219Srdivacky if (!HiddenVBaseCs.count(cast<NamedDecl>(I.getDecl()->getCanonicalDecl()))) 1147252723Sdim Output.addDecl(Context, I.getDecl(), I.getAccess()); 1148205219Srdivacky } 1149198092Srdivacky} 1150198092Srdivacky 1151198092Srdivacky/// getVisibleConversionFunctions - get all conversion functions visible 1152198092Srdivacky/// in current class; including conversion function templates. 1153252723Sdimstd::pair<CXXRecordDecl::conversion_iterator,CXXRecordDecl::conversion_iterator> 1154252723SdimCXXRecordDecl::getVisibleConversionFunctions() { 1155263509Sdim ASTContext &Ctx = getASTContext(); 1156263509Sdim 1157263509Sdim ASTUnresolvedSet *Set; 1158263509Sdim if (bases_begin() == bases_end()) { 1159263509Sdim // If root class, all conversions are visible. 1160263509Sdim Set = &data().Conversions.get(Ctx); 1161263509Sdim } else { 1162263509Sdim Set = &data().VisibleConversions.get(Ctx); 1163263509Sdim // If visible conversion list is not evaluated, evaluate it. 1164263509Sdim if (!data().ComputedVisibleConversions) { 1165263509Sdim CollectVisibleConversions(Ctx, this, *Set); 1166263509Sdim data().ComputedVisibleConversions = true; 1167263509Sdim } 1168252723Sdim } 1169263509Sdim return std::make_pair(Set->begin(), Set->end()); 1170198092Srdivacky} 1171198092Srdivacky 1172206084Srdivackyvoid CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) { 1173206084Srdivacky // This operation is O(N) but extremely rare. Sema only uses it to 1174206084Srdivacky // remove UsingShadowDecls in a class that were followed by a direct 1175206084Srdivacky // declaration, e.g.: 1176206084Srdivacky // class A : B { 1177206084Srdivacky // using B::operator int; 1178206084Srdivacky // operator int(); 1179206084Srdivacky // }; 1180206084Srdivacky // This is uncommon by itself and even more uncommon in conjunction 1181206084Srdivacky // with sufficiently large numbers of directly-declared conversions 1182206084Srdivacky // that asymptotic behavior matters. 1183206084Srdivacky 1184263509Sdim ASTUnresolvedSet &Convs = data().Conversions.get(getASTContext()); 1185206084Srdivacky for (unsigned I = 0, E = Convs.size(); I != E; ++I) { 1186206084Srdivacky if (Convs[I].getDecl() == ConvDecl) { 1187206084Srdivacky Convs.erase(I); 1188206084Srdivacky assert(std::find(Convs.begin(), Convs.end(), ConvDecl) == Convs.end() 1189206084Srdivacky && "conversion was found multiple times in unresolved set"); 1190206084Srdivacky return; 1191206084Srdivacky } 1192206084Srdivacky } 1193206084Srdivacky 1194206084Srdivacky llvm_unreachable("conversion not found in set!"); 1195198092Srdivacky} 1196194613Sed 1197198092SrdivackyCXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const { 1198198092Srdivacky if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) 1199198092Srdivacky return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom()); 1200198092Srdivacky 1201198092Srdivacky return 0; 1202198092Srdivacky} 1203198092Srdivacky 1204198092Srdivackyvoid 1205198092SrdivackyCXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD, 1206198092Srdivacky TemplateSpecializationKind TSK) { 1207198092Srdivacky assert(TemplateOrInstantiation.isNull() && 1208198092Srdivacky "Previous template or instantiation?"); 1209263509Sdim assert(!isa<ClassTemplatePartialSpecializationDecl>(this)); 1210198092Srdivacky TemplateOrInstantiation 1211198092Srdivacky = new (getASTContext()) MemberSpecializationInfo(RD, TSK); 1212198092Srdivacky} 1213198092Srdivacky 1214200583SrdivackyTemplateSpecializationKind CXXRecordDecl::getTemplateSpecializationKind() const{ 1215200583Srdivacky if (const ClassTemplateSpecializationDecl *Spec 1216198092Srdivacky = dyn_cast<ClassTemplateSpecializationDecl>(this)) 1217198092Srdivacky return Spec->getSpecializationKind(); 1218198092Srdivacky 1219198092Srdivacky if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) 1220198092Srdivacky return MSInfo->getTemplateSpecializationKind(); 1221198092Srdivacky 1222198092Srdivacky return TSK_Undeclared; 1223198092Srdivacky} 1224198092Srdivacky 1225198092Srdivackyvoid 1226198092SrdivackyCXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) { 1227198092Srdivacky if (ClassTemplateSpecializationDecl *Spec 1228198092Srdivacky = dyn_cast<ClassTemplateSpecializationDecl>(this)) { 1229198092Srdivacky Spec->setSpecializationKind(TSK); 1230198092Srdivacky return; 1231198092Srdivacky } 1232198092Srdivacky 1233198092Srdivacky if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) { 1234198092Srdivacky MSInfo->setTemplateSpecializationKind(TSK); 1235198092Srdivacky return; 1236198092Srdivacky } 1237198092Srdivacky 1238226890Sdim llvm_unreachable("Not a class template or member class specialization"); 1239198092Srdivacky} 1240198092Srdivacky 1241210299SedCXXDestructorDecl *CXXRecordDecl::getDestructor() const { 1242210299Sed ASTContext &Context = getASTContext(); 1243193326Sed QualType ClassType = Context.getTypeDeclType(this); 1244193326Sed 1245198092Srdivacky DeclarationName Name 1246198092Srdivacky = Context.DeclarationNames.getCXXDestructorName( 1247198092Srdivacky Context.getCanonicalType(ClassType)); 1248198092Srdivacky 1249252723Sdim DeclContext::lookup_const_result R = lookup(Name); 1250252723Sdim if (R.empty()) 1251212904Sdim return 0; 1252198092Srdivacky 1253252723Sdim CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(R.front()); 1254193326Sed return Dtor; 1255193326Sed} 1256193326Sed 1257218893Sdimvoid CXXRecordDecl::completeDefinition() { 1258218893Sdim completeDefinition(0); 1259218893Sdim} 1260218893Sdim 1261218893Sdimvoid CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) { 1262218893Sdim RecordDecl::completeDefinition(); 1263218893Sdim 1264235633Sdim if (hasObjectMember() && getASTContext().getLangOpts().ObjCAutoRefCount) { 1265224145Sdim // Objective-C Automatic Reference Counting: 1266224145Sdim // If a class has a non-static data member of Objective-C pointer 1267224145Sdim // type (or array thereof), it is a non-POD type and its 1268245431Sdim // default constructor (if any), copy constructor, move constructor, 1269245431Sdim // copy assignment operator, move assignment operator, and destructor are 1270245431Sdim // non-trivial. 1271224145Sdim struct DefinitionData &Data = data(); 1272224145Sdim Data.PlainOldData = false; 1273252723Sdim Data.HasTrivialSpecialMembers = 0; 1274235633Sdim Data.HasIrrelevantDestructor = false; 1275224145Sdim } 1276224145Sdim 1277218893Sdim // If the class may be abstract (but hasn't been marked as such), check for 1278218893Sdim // any pure final overriders. 1279218893Sdim if (mayBeAbstract()) { 1280218893Sdim CXXFinalOverriderMap MyFinalOverriders; 1281218893Sdim if (!FinalOverriders) { 1282218893Sdim getFinalOverriders(MyFinalOverriders); 1283218893Sdim FinalOverriders = &MyFinalOverriders; 1284218893Sdim } 1285218893Sdim 1286218893Sdim bool Done = false; 1287218893Sdim for (CXXFinalOverriderMap::iterator M = FinalOverriders->begin(), 1288218893Sdim MEnd = FinalOverriders->end(); 1289218893Sdim M != MEnd && !Done; ++M) { 1290218893Sdim for (OverridingMethods::iterator SO = M->second.begin(), 1291218893Sdim SOEnd = M->second.end(); 1292218893Sdim SO != SOEnd && !Done; ++SO) { 1293218893Sdim assert(SO->second.size() > 0 && 1294218893Sdim "All virtual functions have overridding virtual functions"); 1295218893Sdim 1296218893Sdim // C++ [class.abstract]p4: 1297218893Sdim // A class is abstract if it contains or inherits at least one 1298218893Sdim // pure virtual function for which the final overrider is pure 1299218893Sdim // virtual. 1300218893Sdim if (SO->second.front().Method->isPure()) { 1301218893Sdim data().Abstract = true; 1302218893Sdim Done = true; 1303218893Sdim break; 1304218893Sdim } 1305218893Sdim } 1306218893Sdim } 1307218893Sdim } 1308218893Sdim 1309218893Sdim // Set access bits correctly on the directly-declared conversions. 1310263509Sdim for (conversion_iterator I = conversion_begin(), E = conversion_end(); 1311218893Sdim I != E; ++I) 1312252723Sdim I.setAccess((*I)->getAccess()); 1313218893Sdim} 1314218893Sdim 1315218893Sdimbool CXXRecordDecl::mayBeAbstract() const { 1316218893Sdim if (data().Abstract || isInvalidDecl() || !data().Polymorphic || 1317218893Sdim isDependentContext()) 1318218893Sdim return false; 1319218893Sdim 1320218893Sdim for (CXXRecordDecl::base_class_const_iterator B = bases_begin(), 1321218893Sdim BEnd = bases_end(); 1322218893Sdim B != BEnd; ++B) { 1323218893Sdim CXXRecordDecl *BaseDecl 1324218893Sdim = cast<CXXRecordDecl>(B->getType()->getAs<RecordType>()->getDecl()); 1325218893Sdim if (BaseDecl->isAbstract()) 1326218893Sdim return true; 1327218893Sdim } 1328218893Sdim 1329218893Sdim return false; 1330218893Sdim} 1331218893Sdim 1332235633Sdimvoid CXXMethodDecl::anchor() { } 1333235633Sdim 1334252723Sdimbool CXXMethodDecl::isStatic() const { 1335252723Sdim const CXXMethodDecl *MD = getCanonicalDecl(); 1336252723Sdim 1337252723Sdim if (MD->getStorageClass() == SC_Static) 1338252723Sdim return true; 1339252723Sdim 1340263509Sdim OverloadedOperatorKind OOK = getDeclName().getCXXOverloadedOperator(); 1341263509Sdim return isStaticOverloadedOperator(OOK); 1342252723Sdim} 1343252723Sdim 1344245431Sdimstatic bool recursivelyOverrides(const CXXMethodDecl *DerivedMD, 1345245431Sdim const CXXMethodDecl *BaseMD) { 1346245431Sdim for (CXXMethodDecl::method_iterator I = DerivedMD->begin_overridden_methods(), 1347245431Sdim E = DerivedMD->end_overridden_methods(); I != E; ++I) { 1348245431Sdim const CXXMethodDecl *MD = *I; 1349245431Sdim if (MD->getCanonicalDecl() == BaseMD->getCanonicalDecl()) 1350245431Sdim return true; 1351245431Sdim if (recursivelyOverrides(MD, BaseMD)) 1352245431Sdim return true; 1353245431Sdim } 1354245431Sdim return false; 1355245431Sdim} 1356245431Sdim 1357193326SedCXXMethodDecl * 1358245431SdimCXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD, 1359245431Sdim bool MayBeBase) { 1360245431Sdim if (this->getParent()->getCanonicalDecl() == RD->getCanonicalDecl()) 1361245431Sdim return this; 1362245431Sdim 1363245431Sdim // Lookup doesn't work for destructors, so handle them separately. 1364245431Sdim if (isa<CXXDestructorDecl>(this)) { 1365245431Sdim CXXMethodDecl *MD = RD->getDestructor(); 1366245431Sdim if (MD) { 1367245431Sdim if (recursivelyOverrides(MD, this)) 1368245431Sdim return MD; 1369245431Sdim if (MayBeBase && recursivelyOverrides(this, MD)) 1370245431Sdim return MD; 1371245431Sdim } 1372245431Sdim return NULL; 1373245431Sdim } 1374245431Sdim 1375245431Sdim lookup_const_result Candidates = RD->lookup(getDeclName()); 1376252723Sdim for (NamedDecl * const * I = Candidates.begin(); I != Candidates.end(); ++I) { 1377245431Sdim CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*I); 1378245431Sdim if (!MD) 1379245431Sdim continue; 1380245431Sdim if (recursivelyOverrides(MD, this)) 1381245431Sdim return MD; 1382245431Sdim if (MayBeBase && recursivelyOverrides(this, MD)) 1383245431Sdim return MD; 1384245431Sdim } 1385245431Sdim 1386245431Sdim for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1387245431Sdim E = RD->bases_end(); I != E; ++I) { 1388245431Sdim const RecordType *RT = I->getType()->getAs<RecordType>(); 1389245431Sdim if (!RT) 1390245431Sdim continue; 1391245431Sdim const CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl()); 1392245431Sdim CXXMethodDecl *T = this->getCorrespondingMethodInClass(Base); 1393245431Sdim if (T) 1394245431Sdim return T; 1395245431Sdim } 1396245431Sdim 1397245431Sdim return NULL; 1398245431Sdim} 1399245431Sdim 1400245431SdimCXXMethodDecl * 1401193326SedCXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, 1402221345Sdim SourceLocation StartLoc, 1403212904Sdim const DeclarationNameInfo &NameInfo, 1404200583Srdivacky QualType T, TypeSourceInfo *TInfo, 1405252723Sdim StorageClass SC, bool isInline, 1406226890Sdim bool isConstexpr, SourceLocation EndLocation) { 1407221345Sdim return new (C) CXXMethodDecl(CXXMethod, RD, StartLoc, NameInfo, T, TInfo, 1408252723Sdim SC, isInline, isConstexpr, 1409226890Sdim EndLocation); 1410193326Sed} 1411193326Sed 1412235633SdimCXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1413235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXMethodDecl)); 1414235633Sdim return new (Mem) CXXMethodDecl(CXXMethod, 0, SourceLocation(), 1415235633Sdim DeclarationNameInfo(), QualType(), 1416252723Sdim 0, SC_None, false, false, 1417235633Sdim SourceLocation()); 1418235633Sdim} 1419235633Sdim 1420198092Srdivackybool CXXMethodDecl::isUsualDeallocationFunction() const { 1421198092Srdivacky if (getOverloadedOperator() != OO_Delete && 1422198092Srdivacky getOverloadedOperator() != OO_Array_Delete) 1423198092Srdivacky return false; 1424204643Srdivacky 1425198092Srdivacky // C++ [basic.stc.dynamic.deallocation]p2: 1426204643Srdivacky // A template instance is never a usual deallocation function, 1427204643Srdivacky // regardless of its signature. 1428204643Srdivacky if (getPrimaryTemplate()) 1429204643Srdivacky return false; 1430204643Srdivacky 1431204643Srdivacky // C++ [basic.stc.dynamic.deallocation]p2: 1432198092Srdivacky // If a class T has a member deallocation function named operator delete 1433198092Srdivacky // with exactly one parameter, then that function is a usual (non-placement) 1434198092Srdivacky // deallocation function. [...] 1435198092Srdivacky if (getNumParams() == 1) 1436198092Srdivacky return true; 1437198092Srdivacky 1438198092Srdivacky // C++ [basic.stc.dynamic.deallocation]p2: 1439198092Srdivacky // [...] If class T does not declare such an operator delete but does 1440198092Srdivacky // declare a member deallocation function named operator delete with 1441198092Srdivacky // exactly two parameters, the second of which has type std::size_t (18.1), 1442198092Srdivacky // then this function is a usual deallocation function. 1443198092Srdivacky ASTContext &Context = getASTContext(); 1444198092Srdivacky if (getNumParams() != 2 || 1445203955Srdivacky !Context.hasSameUnqualifiedType(getParamDecl(1)->getType(), 1446203955Srdivacky Context.getSizeType())) 1447198092Srdivacky return false; 1448198092Srdivacky 1449198092Srdivacky // This function is a usual deallocation function if there are no 1450198092Srdivacky // single-parameter deallocation functions of the same kind. 1451252723Sdim DeclContext::lookup_const_result R = getDeclContext()->lookup(getDeclName()); 1452252723Sdim for (DeclContext::lookup_const_result::iterator I = R.begin(), E = R.end(); 1453252723Sdim I != E; ++I) { 1454252723Sdim if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) 1455198092Srdivacky if (FD->getNumParams() == 1) 1456198092Srdivacky return false; 1457198092Srdivacky } 1458198092Srdivacky 1459198092Srdivacky return true; 1460198092Srdivacky} 1461193326Sed 1462207619Srdivackybool CXXMethodDecl::isCopyAssignmentOperator() const { 1463223017Sdim // C++0x [class.copy]p17: 1464207619Srdivacky // A user-declared copy assignment operator X::operator= is a non-static 1465207619Srdivacky // non-template member function of class X with exactly one parameter of 1466207619Srdivacky // type X, X&, const X&, volatile X& or const volatile X&. 1467207619Srdivacky if (/*operator=*/getOverloadedOperator() != OO_Equal || 1468207619Srdivacky /*non-static*/ isStatic() || 1469263509Sdim /*non-template*/getPrimaryTemplate() || getDescribedFunctionTemplate() || 1470263509Sdim getNumParams() != 1) 1471207619Srdivacky return false; 1472207619Srdivacky 1473207619Srdivacky QualType ParamType = getParamDecl(0)->getType(); 1474207619Srdivacky if (const LValueReferenceType *Ref = ParamType->getAs<LValueReferenceType>()) 1475207619Srdivacky ParamType = Ref->getPointeeType(); 1476207619Srdivacky 1477207619Srdivacky ASTContext &Context = getASTContext(); 1478207619Srdivacky QualType ClassType 1479207619Srdivacky = Context.getCanonicalType(Context.getTypeDeclType(getParent())); 1480207619Srdivacky return Context.hasSameUnqualifiedType(ClassType, ParamType); 1481207619Srdivacky} 1482207619Srdivacky 1483223017Sdimbool CXXMethodDecl::isMoveAssignmentOperator() const { 1484223017Sdim // C++0x [class.copy]p19: 1485223017Sdim // A user-declared move assignment operator X::operator= is a non-static 1486223017Sdim // non-template member function of class X with exactly one parameter of type 1487223017Sdim // X&&, const X&&, volatile X&&, or const volatile X&&. 1488223017Sdim if (getOverloadedOperator() != OO_Equal || isStatic() || 1489263509Sdim getPrimaryTemplate() || getDescribedFunctionTemplate() || 1490263509Sdim getNumParams() != 1) 1491223017Sdim return false; 1492223017Sdim 1493223017Sdim QualType ParamType = getParamDecl(0)->getType(); 1494223017Sdim if (!isa<RValueReferenceType>(ParamType)) 1495223017Sdim return false; 1496223017Sdim ParamType = ParamType->getPointeeType(); 1497223017Sdim 1498223017Sdim ASTContext &Context = getASTContext(); 1499223017Sdim QualType ClassType 1500223017Sdim = Context.getCanonicalType(Context.getTypeDeclType(getParent())); 1501223017Sdim return Context.hasSameUnqualifiedType(ClassType, ParamType); 1502223017Sdim} 1503223017Sdim 1504193326Sedvoid CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) { 1505200583Srdivacky assert(MD->isCanonicalDecl() && "Method is not canonical!"); 1506203955Srdivacky assert(!MD->getParent()->isDependentContext() && 1507203955Srdivacky "Can't add an overridden method to a class template!"); 1508235633Sdim assert(MD->isVirtual() && "Method is not virtual!"); 1509203955Srdivacky 1510204643Srdivacky getASTContext().addOverriddenMethod(this, MD); 1511193326Sed} 1512193326Sed 1513193326SedCXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const { 1514235633Sdim if (isa<CXXConstructorDecl>(this)) return 0; 1515204643Srdivacky return getASTContext().overridden_methods_begin(this); 1516193326Sed} 1517193326Sed 1518193326SedCXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const { 1519235633Sdim if (isa<CXXConstructorDecl>(this)) return 0; 1520204643Srdivacky return getASTContext().overridden_methods_end(this); 1521193326Sed} 1522193326Sed 1523210299Sedunsigned CXXMethodDecl::size_overridden_methods() const { 1524235633Sdim if (isa<CXXConstructorDecl>(this)) return 0; 1525210299Sed return getASTContext().overridden_methods_size(this); 1526210299Sed} 1527210299Sed 1528193326SedQualType CXXMethodDecl::getThisType(ASTContext &C) const { 1529193326Sed // C++ 9.3.2p1: The type of this in a member function of a class X is X*. 1530193326Sed // If the member function is declared const, the type of this is const X*, 1531193326Sed // if the member function is declared volatile, the type of this is 1532193326Sed // volatile X*, and if the member function is declared const volatile, 1533193326Sed // the type of this is const volatile X*. 1534193326Sed 1535193326Sed assert(isInstance() && "No 'this' for static methods!"); 1536194179Sed 1537204962Srdivacky QualType ClassTy = C.getTypeDeclType(getParent()); 1538198092Srdivacky ClassTy = C.getQualifiedType(ClassTy, 1539198092Srdivacky Qualifiers::fromCVRMask(getTypeQualifiers())); 1540198092Srdivacky return C.getPointerType(ClassTy); 1541193326Sed} 1542193326Sed 1543200583Srdivackybool CXXMethodDecl::hasInlineBody() const { 1544202379Srdivacky // If this function is a template instantiation, look at the template from 1545202379Srdivacky // which it was instantiated. 1546202379Srdivacky const FunctionDecl *CheckFn = getTemplateInstantiationPattern(); 1547202379Srdivacky if (!CheckFn) 1548202379Srdivacky CheckFn = this; 1549202379Srdivacky 1550200583Srdivacky const FunctionDecl *fn; 1551210299Sed return CheckFn->hasBody(fn) && !fn->isOutOfLine(); 1552200583Srdivacky} 1553200583Srdivacky 1554235633Sdimbool CXXMethodDecl::isLambdaStaticInvoker() const { 1555263509Sdim const CXXRecordDecl *P = getParent(); 1556263509Sdim if (P->isLambda()) { 1557263509Sdim if (const CXXMethodDecl *StaticInvoker = P->getLambdaStaticInvoker()) { 1558263509Sdim if (StaticInvoker == this) return true; 1559263509Sdim if (P->isGenericLambda() && this->isFunctionTemplateSpecialization()) 1560263509Sdim return StaticInvoker == this->getPrimaryTemplate()->getTemplatedDecl(); 1561263509Sdim } 1562263509Sdim } 1563263509Sdim return false; 1564235633Sdim} 1565235633Sdim 1566218893SdimCXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, 1567218893Sdim TypeSourceInfo *TInfo, bool IsVirtual, 1568218893Sdim SourceLocation L, Expr *Init, 1569218893Sdim SourceLocation R, 1570218893Sdim SourceLocation EllipsisLoc) 1571218893Sdim : Initializee(TInfo), MemberOrEllipsisLocation(EllipsisLoc), Init(Init), 1572235633Sdim LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(IsVirtual), 1573235633Sdim IsWritten(false), SourceOrderOrNumArrayIndices(0) 1574200583Srdivacky{ 1575193326Sed} 1576193326Sed 1577218893SdimCXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, 1578218893Sdim FieldDecl *Member, 1579218893Sdim SourceLocation MemberLoc, 1580218893Sdim SourceLocation L, Expr *Init, 1581218893Sdim SourceLocation R) 1582218893Sdim : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init), 1583235633Sdim LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false), 1584208600Srdivacky IsWritten(false), SourceOrderOrNumArrayIndices(0) 1585208600Srdivacky{ 1586208600Srdivacky} 1587208600Srdivacky 1588218893SdimCXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, 1589218893Sdim IndirectFieldDecl *Member, 1590218893Sdim SourceLocation MemberLoc, 1591218893Sdim SourceLocation L, Expr *Init, 1592218893Sdim SourceLocation R) 1593218893Sdim : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init), 1594235633Sdim LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false), 1595218893Sdim IsWritten(false), SourceOrderOrNumArrayIndices(0) 1596218893Sdim{ 1597218893Sdim} 1598218893Sdim 1599218893SdimCXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, 1600235633Sdim TypeSourceInfo *TInfo, 1601235633Sdim SourceLocation L, Expr *Init, 1602221345Sdim SourceLocation R) 1603235633Sdim : Initializee(TInfo), MemberOrEllipsisLocation(), Init(Init), 1604235633Sdim LParenLoc(L), RParenLoc(R), IsDelegating(true), IsVirtual(false), 1605221345Sdim IsWritten(false), SourceOrderOrNumArrayIndices(0) 1606221345Sdim{ 1607221345Sdim} 1608221345Sdim 1609221345SdimCXXCtorInitializer::CXXCtorInitializer(ASTContext &Context, 1610218893Sdim FieldDecl *Member, 1611218893Sdim SourceLocation MemberLoc, 1612218893Sdim SourceLocation L, Expr *Init, 1613218893Sdim SourceLocation R, 1614218893Sdim VarDecl **Indices, 1615218893Sdim unsigned NumIndices) 1616218893Sdim : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init), 1617218893Sdim LParenLoc(L), RParenLoc(R), IsVirtual(false), 1618208600Srdivacky IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices) 1619200583Srdivacky{ 1620208600Srdivacky VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1); 1621208600Srdivacky memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *)); 1622193326Sed} 1623193326Sed 1624218893SdimCXXCtorInitializer *CXXCtorInitializer::Create(ASTContext &Context, 1625218893Sdim FieldDecl *Member, 1626218893Sdim SourceLocation MemberLoc, 1627218893Sdim SourceLocation L, Expr *Init, 1628218893Sdim SourceLocation R, 1629218893Sdim VarDecl **Indices, 1630218893Sdim unsigned NumIndices) { 1631218893Sdim void *Mem = Context.Allocate(sizeof(CXXCtorInitializer) + 1632208600Srdivacky sizeof(VarDecl *) * NumIndices, 1633218893Sdim llvm::alignOf<CXXCtorInitializer>()); 1634218893Sdim return new (Mem) CXXCtorInitializer(Context, Member, MemberLoc, L, Init, R, 1635218893Sdim Indices, NumIndices); 1636208600Srdivacky} 1637208600Srdivacky 1638218893SdimTypeLoc CXXCtorInitializer::getBaseClassLoc() const { 1639200583Srdivacky if (isBaseInitializer()) 1640218893Sdim return Initializee.get<TypeSourceInfo*>()->getTypeLoc(); 1641200583Srdivacky else 1642200583Srdivacky return TypeLoc(); 1643200583Srdivacky} 1644200583Srdivacky 1645218893Sdimconst Type *CXXCtorInitializer::getBaseClass() const { 1646200583Srdivacky if (isBaseInitializer()) 1647218893Sdim return Initializee.get<TypeSourceInfo*>()->getType().getTypePtr(); 1648200583Srdivacky else 1649200583Srdivacky return 0; 1650200583Srdivacky} 1651200583Srdivacky 1652218893SdimSourceLocation CXXCtorInitializer::getSourceLocation() const { 1653235633Sdim if (isAnyMemberInitializer()) 1654200583Srdivacky return getMemberLocation(); 1655223017Sdim 1656223017Sdim if (isInClassMemberInitializer()) 1657223017Sdim return getAnyMember()->getLocation(); 1658200583Srdivacky 1659235633Sdim if (TypeSourceInfo *TSInfo = Initializee.get<TypeSourceInfo*>()) 1660235633Sdim return TSInfo->getTypeLoc().getLocalSourceRange().getBegin(); 1661235633Sdim 1662235633Sdim return SourceLocation(); 1663200583Srdivacky} 1664200583Srdivacky 1665218893SdimSourceRange CXXCtorInitializer::getSourceRange() const { 1666223017Sdim if (isInClassMemberInitializer()) { 1667223017Sdim FieldDecl *D = getAnyMember(); 1668223017Sdim if (Expr *I = D->getInClassInitializer()) 1669223017Sdim return I->getSourceRange(); 1670223017Sdim return SourceRange(); 1671223017Sdim } 1672223017Sdim 1673200583Srdivacky return SourceRange(getSourceLocation(), getRParenLoc()); 1674200583Srdivacky} 1675200583Srdivacky 1676235633Sdimvoid CXXConstructorDecl::anchor() { } 1677235633Sdim 1678193326SedCXXConstructorDecl * 1679235633SdimCXXConstructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1680235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXConstructorDecl)); 1681235633Sdim return new (Mem) CXXConstructorDecl(0, SourceLocation(),DeclarationNameInfo(), 1682235633Sdim QualType(), 0, false, false, false,false); 1683208600Srdivacky} 1684208600Srdivacky 1685208600SrdivackyCXXConstructorDecl * 1686193326SedCXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, 1687221345Sdim SourceLocation StartLoc, 1688212904Sdim const DeclarationNameInfo &NameInfo, 1689200583Srdivacky QualType T, TypeSourceInfo *TInfo, 1690226890Sdim bool isExplicit, bool isInline, 1691226890Sdim bool isImplicitlyDeclared, bool isConstexpr) { 1692212904Sdim assert(NameInfo.getName().getNameKind() 1693212904Sdim == DeclarationName::CXXConstructorName && 1694193326Sed "Name must refer to a constructor"); 1695221345Sdim return new (C) CXXConstructorDecl(RD, StartLoc, NameInfo, T, TInfo, 1696226890Sdim isExplicit, isInline, isImplicitlyDeclared, 1697226890Sdim isConstexpr); 1698193326Sed} 1699193326Sed 1700235633SdimCXXConstructorDecl *CXXConstructorDecl::getTargetConstructor() const { 1701235633Sdim assert(isDelegatingConstructor() && "Not a delegating constructor!"); 1702235633Sdim Expr *E = (*init_begin())->getInit()->IgnoreImplicit(); 1703235633Sdim if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(E)) 1704235633Sdim return Construct->getConstructor(); 1705235633Sdim 1706235633Sdim return 0; 1707235633Sdim} 1708235633Sdim 1709193326Sedbool CXXConstructorDecl::isDefaultConstructor() const { 1710193326Sed // C++ [class.ctor]p5: 1711193326Sed // A default constructor for a class X is a constructor of class 1712193326Sed // X that can be called without an argument. 1713193326Sed return (getNumParams() == 0) || 1714198092Srdivacky (getNumParams() > 0 && getParamDecl(0)->hasDefaultArg()); 1715193326Sed} 1716193326Sed 1717198092Srdivackybool 1718201361SrdivackyCXXConstructorDecl::isCopyConstructor(unsigned &TypeQuals) const { 1719218893Sdim return isCopyOrMoveConstructor(TypeQuals) && 1720218893Sdim getParamDecl(0)->getType()->isLValueReferenceType(); 1721218893Sdim} 1722218893Sdim 1723218893Sdimbool CXXConstructorDecl::isMoveConstructor(unsigned &TypeQuals) const { 1724218893Sdim return isCopyOrMoveConstructor(TypeQuals) && 1725218893Sdim getParamDecl(0)->getType()->isRValueReferenceType(); 1726218893Sdim} 1727218893Sdim 1728218893Sdim/// \brief Determine whether this is a copy or move constructor. 1729218893Sdimbool CXXConstructorDecl::isCopyOrMoveConstructor(unsigned &TypeQuals) const { 1730193326Sed // C++ [class.copy]p2: 1731193326Sed // A non-template constructor for class X is a copy constructor 1732193326Sed // if its first parameter is of type X&, const X&, volatile X& or 1733193326Sed // const volatile X&, and either there are no other parameters 1734193326Sed // or else all other parameters have default arguments (8.3.6). 1735218893Sdim // C++0x [class.copy]p3: 1736218893Sdim // A non-template constructor for class X is a move constructor if its 1737218893Sdim // first parameter is of type X&&, const X&&, volatile X&&, or 1738218893Sdim // const volatile X&&, and either there are no other parameters or else 1739218893Sdim // all other parameters have default arguments. 1740193326Sed if ((getNumParams() < 1) || 1741198092Srdivacky (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) || 1742198092Srdivacky (getPrimaryTemplate() != 0) || 1743198092Srdivacky (getDescribedFunctionTemplate() != 0)) 1744193326Sed return false; 1745218893Sdim 1746193326Sed const ParmVarDecl *Param = getParamDecl(0); 1747218893Sdim 1748218893Sdim // Do we have a reference type? 1749218893Sdim const ReferenceType *ParamRefType = Param->getType()->getAs<ReferenceType>(); 1750193326Sed if (!ParamRefType) 1751193326Sed return false; 1752218893Sdim 1753193326Sed // Is it a reference to our class type? 1754201361Srdivacky ASTContext &Context = getASTContext(); 1755201361Srdivacky 1756198092Srdivacky CanQualType PointeeType 1757193326Sed = Context.getCanonicalType(ParamRefType->getPointeeType()); 1758198092Srdivacky CanQualType ClassTy 1759198092Srdivacky = Context.getCanonicalType(Context.getTagDeclType(getParent())); 1760193326Sed if (PointeeType.getUnqualifiedType() != ClassTy) 1761193326Sed return false; 1762218893Sdim 1763198092Srdivacky // FIXME: other qualifiers? 1764218893Sdim 1765218893Sdim // We have a copy or move constructor. 1766193326Sed TypeQuals = PointeeType.getCVRQualifiers(); 1767218893Sdim return true; 1768193326Sed} 1769193326Sed 1770198092Srdivackybool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const { 1771193326Sed // C++ [class.conv.ctor]p1: 1772193326Sed // A constructor declared without the function-specifier explicit 1773193326Sed // that can be called with a single parameter specifies a 1774193326Sed // conversion from the type of its first parameter to the type of 1775193326Sed // its class. Such a constructor is called a converting 1776193326Sed // constructor. 1777198092Srdivacky if (isExplicit() && !AllowExplicit) 1778193326Sed return false; 1779193326Sed 1780198092Srdivacky return (getNumParams() == 0 && 1781198092Srdivacky getType()->getAs<FunctionProtoType>()->isVariadic()) || 1782193326Sed (getNumParams() == 1) || 1783245431Sdim (getNumParams() > 1 && 1784245431Sdim (getParamDecl(1)->hasDefaultArg() || 1785245431Sdim getParamDecl(1)->isParameterPack())); 1786193326Sed} 1787193326Sed 1788218893Sdimbool CXXConstructorDecl::isSpecializationCopyingObject() const { 1789199482Srdivacky if ((getNumParams() < 1) || 1790199482Srdivacky (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) || 1791199482Srdivacky (getPrimaryTemplate() == 0) || 1792199482Srdivacky (getDescribedFunctionTemplate() != 0)) 1793199482Srdivacky return false; 1794199482Srdivacky 1795199482Srdivacky const ParmVarDecl *Param = getParamDecl(0); 1796199482Srdivacky 1797199482Srdivacky ASTContext &Context = getASTContext(); 1798199482Srdivacky CanQualType ParamType = Context.getCanonicalType(Param->getType()); 1799199482Srdivacky 1800199482Srdivacky // Is it the same as our our class type? 1801199482Srdivacky CanQualType ClassTy 1802199482Srdivacky = Context.getCanonicalType(Context.getTagDeclType(getParent())); 1803199482Srdivacky if (ParamType.getUnqualifiedType() != ClassTy) 1804199482Srdivacky return false; 1805199482Srdivacky 1806199482Srdivacky return true; 1807199482Srdivacky} 1808199482Srdivacky 1809218893Sdimconst CXXConstructorDecl *CXXConstructorDecl::getInheritedConstructor() const { 1810218893Sdim // Hack: we store the inherited constructor in the overridden method table 1811235633Sdim method_iterator It = getASTContext().overridden_methods_begin(this); 1812235633Sdim if (It == getASTContext().overridden_methods_end(this)) 1813218893Sdim return 0; 1814218893Sdim 1815218893Sdim return cast<CXXConstructorDecl>(*It); 1816218893Sdim} 1817218893Sdim 1818218893Sdimvoid 1819218893SdimCXXConstructorDecl::setInheritedConstructor(const CXXConstructorDecl *BaseCtor){ 1820218893Sdim // Hack: we store the inherited constructor in the overridden method table 1821235633Sdim assert(getASTContext().overridden_methods_size(this) == 0 && 1822235633Sdim "Base ctor already set."); 1823235633Sdim getASTContext().addOverriddenMethod(this, BaseCtor); 1824218893Sdim} 1825218893Sdim 1826235633Sdimvoid CXXDestructorDecl::anchor() { } 1827235633Sdim 1828193326SedCXXDestructorDecl * 1829235633SdimCXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1830235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXDestructorDecl)); 1831235633Sdim return new (Mem) CXXDestructorDecl(0, SourceLocation(), DeclarationNameInfo(), 1832218893Sdim QualType(), 0, false, false); 1833208600Srdivacky} 1834208600Srdivacky 1835208600SrdivackyCXXDestructorDecl * 1836193326SedCXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, 1837221345Sdim SourceLocation StartLoc, 1838212904Sdim const DeclarationNameInfo &NameInfo, 1839218893Sdim QualType T, TypeSourceInfo *TInfo, 1840226890Sdim bool isInline, bool isImplicitlyDeclared) { 1841212904Sdim assert(NameInfo.getName().getNameKind() 1842212904Sdim == DeclarationName::CXXDestructorName && 1843193326Sed "Name must refer to a destructor"); 1844221345Sdim return new (C) CXXDestructorDecl(RD, StartLoc, NameInfo, T, TInfo, isInline, 1845212904Sdim isImplicitlyDeclared); 1846193326Sed} 1847193326Sed 1848235633Sdimvoid CXXConversionDecl::anchor() { } 1849235633Sdim 1850193326SedCXXConversionDecl * 1851235633SdimCXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1852235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXConversionDecl)); 1853235633Sdim return new (Mem) CXXConversionDecl(0, SourceLocation(), DeclarationNameInfo(), 1854235633Sdim QualType(), 0, false, false, false, 1855235633Sdim SourceLocation()); 1856208600Srdivacky} 1857208600Srdivacky 1858208600SrdivackyCXXConversionDecl * 1859193326SedCXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD, 1860221345Sdim SourceLocation StartLoc, 1861212904Sdim const DeclarationNameInfo &NameInfo, 1862200583Srdivacky QualType T, TypeSourceInfo *TInfo, 1863221345Sdim bool isInline, bool isExplicit, 1864226890Sdim bool isConstexpr, SourceLocation EndLocation) { 1865212904Sdim assert(NameInfo.getName().getNameKind() 1866212904Sdim == DeclarationName::CXXConversionFunctionName && 1867193326Sed "Name must refer to a conversion function"); 1868221345Sdim return new (C) CXXConversionDecl(RD, StartLoc, NameInfo, T, TInfo, 1869226890Sdim isInline, isExplicit, isConstexpr, 1870226890Sdim EndLocation); 1871193326Sed} 1872193326Sed 1873235633Sdimbool CXXConversionDecl::isLambdaToBlockPointerConversion() const { 1874235633Sdim return isImplicit() && getParent()->isLambda() && 1875235633Sdim getConversionType()->isBlockPointerType(); 1876235633Sdim} 1877235633Sdim 1878235633Sdimvoid LinkageSpecDecl::anchor() { } 1879235633Sdim 1880193326SedLinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, 1881198092Srdivacky DeclContext *DC, 1882221345Sdim SourceLocation ExternLoc, 1883221345Sdim SourceLocation LangLoc, 1884221345Sdim LanguageIDs Lang, 1885252723Sdim bool HasBraces) { 1886252723Sdim return new (C) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces); 1887193326Sed} 1888193326Sed 1889235633SdimLinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1890235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(LinkageSpecDecl)); 1891235633Sdim return new (Mem) LinkageSpecDecl(0, SourceLocation(), SourceLocation(), 1892252723Sdim lang_c, false); 1893235633Sdim} 1894235633Sdim 1895235633Sdimvoid UsingDirectiveDecl::anchor() { } 1896235633Sdim 1897193326SedUsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, 1898193326Sed SourceLocation L, 1899193326Sed SourceLocation NamespaceLoc, 1900219077Sdim NestedNameSpecifierLoc QualifierLoc, 1901193326Sed SourceLocation IdentLoc, 1902199990Srdivacky NamedDecl *Used, 1903193326Sed DeclContext *CommonAncestor) { 1904199990Srdivacky if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used)) 1905199990Srdivacky Used = NS->getOriginalNamespace(); 1906219077Sdim return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierLoc, 1907219077Sdim IdentLoc, Used, CommonAncestor); 1908193326Sed} 1909193326Sed 1910235633SdimUsingDirectiveDecl * 1911235633SdimUsingDirectiveDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1912235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UsingDirectiveDecl)); 1913235633Sdim return new (Mem) UsingDirectiveDecl(0, SourceLocation(), SourceLocation(), 1914235633Sdim NestedNameSpecifierLoc(), 1915235633Sdim SourceLocation(), 0, 0); 1916235633Sdim} 1917235633Sdim 1918199990SrdivackyNamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() { 1919199990Srdivacky if (NamespaceAliasDecl *NA = 1920199990Srdivacky dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace)) 1921199990Srdivacky return NA->getNamespace(); 1922199990Srdivacky return cast_or_null<NamespaceDecl>(NominatedNamespace); 1923199990Srdivacky} 1924199990Srdivacky 1925235633Sdimvoid NamespaceDecl::anchor() { } 1926235633Sdim 1927235633SdimNamespaceDecl::NamespaceDecl(DeclContext *DC, bool Inline, 1928235633Sdim SourceLocation StartLoc, 1929235633Sdim SourceLocation IdLoc, IdentifierInfo *Id, 1930235633Sdim NamespaceDecl *PrevDecl) 1931235633Sdim : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace), 1932235633Sdim LocStart(StartLoc), RBraceLoc(), AnonOrFirstNamespaceAndInline(0, Inline) 1933235633Sdim{ 1934263509Sdim setPreviousDecl(PrevDecl); 1935235633Sdim 1936235633Sdim if (PrevDecl) 1937235633Sdim AnonOrFirstNamespaceAndInline.setPointer(PrevDecl->getOriginalNamespace()); 1938235633Sdim} 1939235633Sdim 1940235633SdimNamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, 1941235633Sdim bool Inline, SourceLocation StartLoc, 1942235633Sdim SourceLocation IdLoc, IdentifierInfo *Id, 1943235633Sdim NamespaceDecl *PrevDecl) { 1944235633Sdim return new (C) NamespaceDecl(DC, Inline, StartLoc, IdLoc, Id, PrevDecl); 1945235633Sdim} 1946235633Sdim 1947235633SdimNamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1948235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NamespaceDecl)); 1949235633Sdim return new (Mem) NamespaceDecl(0, false, SourceLocation(), SourceLocation(), 1950235633Sdim 0, 0); 1951235633Sdim} 1952235633Sdim 1953235633Sdimvoid NamespaceAliasDecl::anchor() { } 1954235633Sdim 1955198092SrdivackyNamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, 1956212904Sdim SourceLocation UsingLoc, 1957198092Srdivacky SourceLocation AliasLoc, 1958198092Srdivacky IdentifierInfo *Alias, 1959219077Sdim NestedNameSpecifierLoc QualifierLoc, 1960198092Srdivacky SourceLocation IdentLoc, 1961193326Sed NamedDecl *Namespace) { 1962199990Srdivacky if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace)) 1963199990Srdivacky Namespace = NS->getOriginalNamespace(); 1964219077Sdim return new (C) NamespaceAliasDecl(DC, UsingLoc, AliasLoc, Alias, 1965219077Sdim QualifierLoc, IdentLoc, Namespace); 1966193326Sed} 1967193326Sed 1968235633SdimNamespaceAliasDecl * 1969235633SdimNamespaceAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1970235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NamespaceAliasDecl)); 1971235633Sdim return new (Mem) NamespaceAliasDecl(0, SourceLocation(), SourceLocation(), 0, 1972235633Sdim NestedNameSpecifierLoc(), 1973235633Sdim SourceLocation(), 0); 1974235633Sdim} 1975235633Sdim 1976235633Sdimvoid UsingShadowDecl::anchor() { } 1977235633Sdim 1978235633SdimUsingShadowDecl * 1979235633SdimUsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1980235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UsingShadowDecl)); 1981235633Sdim return new (Mem) UsingShadowDecl(0, SourceLocation(), 0, 0); 1982235633Sdim} 1983235633Sdim 1984218893SdimUsingDecl *UsingShadowDecl::getUsingDecl() const { 1985218893Sdim const UsingShadowDecl *Shadow = this; 1986218893Sdim while (const UsingShadowDecl *NextShadow = 1987218893Sdim dyn_cast<UsingShadowDecl>(Shadow->UsingOrNextShadow)) 1988218893Sdim Shadow = NextShadow; 1989218893Sdim return cast<UsingDecl>(Shadow->UsingOrNextShadow); 1990218893Sdim} 1991218893Sdim 1992235633Sdimvoid UsingDecl::anchor() { } 1993235633Sdim 1994218893Sdimvoid UsingDecl::addShadowDecl(UsingShadowDecl *S) { 1995218893Sdim assert(std::find(shadow_begin(), shadow_end(), S) == shadow_end() && 1996218893Sdim "declaration already in set"); 1997218893Sdim assert(S->getUsingDecl() == this); 1998218893Sdim 1999235633Sdim if (FirstUsingShadow.getPointer()) 2000235633Sdim S->UsingOrNextShadow = FirstUsingShadow.getPointer(); 2001235633Sdim FirstUsingShadow.setPointer(S); 2002218893Sdim} 2003218893Sdim 2004218893Sdimvoid UsingDecl::removeShadowDecl(UsingShadowDecl *S) { 2005218893Sdim assert(std::find(shadow_begin(), shadow_end(), S) != shadow_end() && 2006218893Sdim "declaration not in set"); 2007218893Sdim assert(S->getUsingDecl() == this); 2008218893Sdim 2009218893Sdim // Remove S from the shadow decl chain. This is O(n) but hopefully rare. 2010218893Sdim 2011235633Sdim if (FirstUsingShadow.getPointer() == S) { 2012235633Sdim FirstUsingShadow.setPointer( 2013235633Sdim dyn_cast<UsingShadowDecl>(S->UsingOrNextShadow)); 2014218893Sdim S->UsingOrNextShadow = this; 2015218893Sdim return; 2016218893Sdim } 2017218893Sdim 2018235633Sdim UsingShadowDecl *Prev = FirstUsingShadow.getPointer(); 2019218893Sdim while (Prev->UsingOrNextShadow != S) 2020218893Sdim Prev = cast<UsingShadowDecl>(Prev->UsingOrNextShadow); 2021218893Sdim Prev->UsingOrNextShadow = S->UsingOrNextShadow; 2022218893Sdim S->UsingOrNextShadow = this; 2023218893Sdim} 2024218893Sdim 2025219077SdimUsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL, 2026219077Sdim NestedNameSpecifierLoc QualifierLoc, 2027212904Sdim const DeclarationNameInfo &NameInfo, 2028263509Sdim bool HasTypename) { 2029263509Sdim return new (C) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename); 2030194613Sed} 2031194613Sed 2032235633SdimUsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 2033235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UsingDecl)); 2034235633Sdim return new (Mem) UsingDecl(0, SourceLocation(), NestedNameSpecifierLoc(), 2035235633Sdim DeclarationNameInfo(), false); 2036235633Sdim} 2037235633Sdim 2038263509SdimSourceRange UsingDecl::getSourceRange() const { 2039263509Sdim SourceLocation Begin = isAccessDeclaration() 2040263509Sdim ? getQualifierLoc().getBeginLoc() : UsingLocation; 2041263509Sdim return SourceRange(Begin, getNameInfo().getEndLoc()); 2042263509Sdim} 2043263509Sdim 2044235633Sdimvoid UnresolvedUsingValueDecl::anchor() { } 2045235633Sdim 2046199482SrdivackyUnresolvedUsingValueDecl * 2047199482SrdivackyUnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC, 2048199482Srdivacky SourceLocation UsingLoc, 2049219077Sdim NestedNameSpecifierLoc QualifierLoc, 2050212904Sdim const DeclarationNameInfo &NameInfo) { 2051199482Srdivacky return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc, 2052219077Sdim QualifierLoc, NameInfo); 2053198092Srdivacky} 2054198092Srdivacky 2055235633SdimUnresolvedUsingValueDecl * 2056235633SdimUnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 2057235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UnresolvedUsingValueDecl)); 2058235633Sdim return new (Mem) UnresolvedUsingValueDecl(0, QualType(), SourceLocation(), 2059235633Sdim NestedNameSpecifierLoc(), 2060235633Sdim DeclarationNameInfo()); 2061235633Sdim} 2062235633Sdim 2063263509SdimSourceRange UnresolvedUsingValueDecl::getSourceRange() const { 2064263509Sdim SourceLocation Begin = isAccessDeclaration() 2065263509Sdim ? getQualifierLoc().getBeginLoc() : UsingLocation; 2066263509Sdim return SourceRange(Begin, getNameInfo().getEndLoc()); 2067263509Sdim} 2068263509Sdim 2069235633Sdimvoid UnresolvedUsingTypenameDecl::anchor() { } 2070235633Sdim 2071199482SrdivackyUnresolvedUsingTypenameDecl * 2072199482SrdivackyUnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC, 2073199482Srdivacky SourceLocation UsingLoc, 2074199482Srdivacky SourceLocation TypenameLoc, 2075219077Sdim NestedNameSpecifierLoc QualifierLoc, 2076199482Srdivacky SourceLocation TargetNameLoc, 2077199482Srdivacky DeclarationName TargetName) { 2078199482Srdivacky return new (C) UnresolvedUsingTypenameDecl(DC, UsingLoc, TypenameLoc, 2079219077Sdim QualifierLoc, TargetNameLoc, 2080199482Srdivacky TargetName.getAsIdentifierInfo()); 2081199482Srdivacky} 2082199482Srdivacky 2083235633SdimUnresolvedUsingTypenameDecl * 2084235633SdimUnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 2085235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, 2086235633Sdim sizeof(UnresolvedUsingTypenameDecl)); 2087235633Sdim return new (Mem) UnresolvedUsingTypenameDecl(0, SourceLocation(), 2088235633Sdim SourceLocation(), 2089235633Sdim NestedNameSpecifierLoc(), 2090235633Sdim SourceLocation(), 2091235633Sdim 0); 2092235633Sdim} 2093235633Sdim 2094235633Sdimvoid StaticAssertDecl::anchor() { } 2095235633Sdim 2096193326SedStaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC, 2097221345Sdim SourceLocation StaticAssertLoc, 2098221345Sdim Expr *AssertExpr, 2099221345Sdim StringLiteral *Message, 2100245431Sdim SourceLocation RParenLoc, 2101245431Sdim bool Failed) { 2102221345Sdim return new (C) StaticAssertDecl(DC, StaticAssertLoc, AssertExpr, Message, 2103245431Sdim RParenLoc, Failed); 2104193326Sed} 2105193326Sed 2106235633SdimStaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C, 2107235633Sdim unsigned ID) { 2108235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(StaticAssertDecl)); 2109245431Sdim return new (Mem) StaticAssertDecl(0, SourceLocation(), 0, 0, 2110245431Sdim SourceLocation(), false); 2111235633Sdim} 2112235633Sdim 2113193326Sedstatic const char *getAccessName(AccessSpecifier AS) { 2114193326Sed switch (AS) { 2115193326Sed case AS_none: 2116226890Sdim llvm_unreachable("Invalid access specifier!"); 2117193326Sed case AS_public: 2118193326Sed return "public"; 2119193326Sed case AS_private: 2120193326Sed return "private"; 2121193326Sed case AS_protected: 2122193326Sed return "protected"; 2123193326Sed } 2124235633Sdim llvm_unreachable("Invalid access specifier!"); 2125193326Sed} 2126193326Sed 2127193326Sedconst DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, 2128193326Sed AccessSpecifier AS) { 2129193326Sed return DB << getAccessName(AS); 2130193326Sed} 2131235633Sdim 2132235633Sdimconst PartialDiagnostic &clang::operator<<(const PartialDiagnostic &DB, 2133235633Sdim AccessSpecifier AS) { 2134235633Sdim return DB << getAccessName(AS); 2135235633Sdim} 2136