DeclCXX.cpp revision 212904
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 14193326Sed#include "clang/AST/DeclCXX.h" 15193326Sed#include "clang/AST/DeclTemplate.h" 16193326Sed#include "clang/AST/ASTContext.h" 17193326Sed#include "clang/AST/Expr.h" 18200583Srdivacky#include "clang/AST/TypeLoc.h" 19193326Sed#include "clang/Basic/IdentifierTable.h" 20193326Sed#include "llvm/ADT/STLExtras.h" 21198092Srdivacky#include "llvm/ADT/SmallPtrSet.h" 22193326Sedusing namespace clang; 23193326Sed 24193326Sed//===----------------------------------------------------------------------===// 25193326Sed// Decl Allocation/Deallocation Method Implementations 26193326Sed//===----------------------------------------------------------------------===// 27193326Sed 28203955SrdivackyCXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) 29203955Srdivacky : UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false), 30193326Sed UserDeclaredCopyAssignment(false), UserDeclaredDestructor(false), 31198092Srdivacky Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false), 32198092Srdivacky Abstract(false), HasTrivialConstructor(true), 33198092Srdivacky HasTrivialCopyConstructor(true), HasTrivialCopyAssignment(true), 34198092Srdivacky HasTrivialDestructor(true), ComputedVisibleConversions(false), 35210299Sed DeclaredDefaultConstructor(false), DeclaredCopyConstructor(false), 36210299Sed DeclaredCopyAssignment(false), DeclaredDestructor(false), 37198092Srdivacky Bases(0), NumBases(0), VBases(0), NumVBases(0), 38205219Srdivacky Definition(D), FirstFriend(0) { 39203955Srdivacky} 40203955Srdivacky 41203955SrdivackyCXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, 42203955Srdivacky SourceLocation L, IdentifierInfo *Id, 43203955Srdivacky CXXRecordDecl *PrevDecl, 44203955Srdivacky SourceLocation TKL) 45203955Srdivacky : RecordDecl(K, TK, DC, L, Id, PrevDecl, TKL), 46203955Srdivacky DefinitionData(PrevDecl ? PrevDecl->DefinitionData : 0), 47193326Sed TemplateOrInstantiation() { } 48193326Sed 49193326SedCXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, 50193326Sed SourceLocation L, IdentifierInfo *Id, 51198092Srdivacky SourceLocation TKL, 52193326Sed CXXRecordDecl* PrevDecl, 53193326Sed bool DelayTypeCreation) { 54198092Srdivacky CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, L, Id, 55198092Srdivacky PrevDecl, TKL); 56198092Srdivacky 57198092Srdivacky // FIXME: DelayTypeCreation seems like such a hack 58193326Sed if (!DelayTypeCreation) 59198092Srdivacky C.getTypeDeclType(R, PrevDecl); 60193326Sed return R; 61193326Sed} 62193326Sed 63210299SedCXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, EmptyShell Empty) { 64210299Sed return new (C) CXXRecordDecl(CXXRecord, TTK_Struct, 0, SourceLocation(), 0, 0, 65210299Sed SourceLocation()); 66210299Sed} 67210299Sed 68198092Srdivackyvoid 69203955SrdivackyCXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, 70193326Sed unsigned NumBases) { 71203955Srdivacky ASTContext &C = getASTContext(); 72203955Srdivacky 73198092Srdivacky // C++ [dcl.init.aggr]p1: 74193326Sed // An aggregate is an array or a class (clause 9) with [...] 75193326Sed // no base classes [...]. 76203955Srdivacky data().Aggregate = false; 77193326Sed 78203955Srdivacky if (data().Bases) 79203955Srdivacky C.Deallocate(data().Bases); 80193326Sed 81206084Srdivacky // The set of seen virtual base types. 82206084Srdivacky llvm::SmallPtrSet<CanQualType, 8> SeenVBaseTypes; 83206084Srdivacky 84206084Srdivacky // The virtual bases of this class. 85206084Srdivacky llvm::SmallVector<const CXXBaseSpecifier *, 8> VBases; 86198092Srdivacky 87203955Srdivacky data().Bases = new(C) CXXBaseSpecifier [NumBases]; 88203955Srdivacky data().NumBases = NumBases; 89198092Srdivacky for (unsigned i = 0; i < NumBases; ++i) { 90203955Srdivacky data().Bases[i] = *Bases[i]; 91198092Srdivacky // Keep track of inherited vbases for this base class. 92198092Srdivacky const CXXBaseSpecifier *Base = Bases[i]; 93198092Srdivacky QualType BaseType = Base->getType(); 94204643Srdivacky // Skip dependent types; we can't do any checking on them now. 95198092Srdivacky if (BaseType->isDependentType()) 96198092Srdivacky continue; 97198092Srdivacky CXXRecordDecl *BaseClassDecl 98198092Srdivacky = cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); 99206084Srdivacky 100206084Srdivacky // Now go through all virtual bases of this base and add them. 101198092Srdivacky for (CXXRecordDecl::base_class_iterator VBase = 102198092Srdivacky BaseClassDecl->vbases_begin(), 103198092Srdivacky E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) { 104206084Srdivacky // Add this base if it's not already in the list. 105206084Srdivacky if (SeenVBaseTypes.insert(C.getCanonicalType(VBase->getType()))) 106206084Srdivacky VBases.push_back(VBase); 107198092Srdivacky } 108206084Srdivacky 109206084Srdivacky if (Base->isVirtual()) { 110206084Srdivacky // Add this base if it's not already in the list. 111206084Srdivacky if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType))) 112206084Srdivacky VBases.push_back(Base); 113198092Srdivacky } 114206084Srdivacky 115198092Srdivacky } 116206084Srdivacky 117206084Srdivacky if (VBases.empty()) 118206084Srdivacky return; 119206084Srdivacky 120206084Srdivacky // Create base specifier for any direct or indirect virtual bases. 121206084Srdivacky data().VBases = new (C) CXXBaseSpecifier[VBases.size()]; 122206084Srdivacky data().NumVBases = VBases.size(); 123206084Srdivacky for (int I = 0, E = VBases.size(); I != E; ++I) { 124212904Sdim TypeSourceInfo *VBaseTypeInfo = VBases[I]->getTypeSourceInfo(); 125212904Sdim 126206084Srdivacky // Skip dependent types; we can't do any checking on them now. 127212904Sdim if (VBaseTypeInfo->getType()->isDependentType()) 128206084Srdivacky continue; 129206084Srdivacky 130212904Sdim CXXRecordDecl *VBaseClassDecl = cast<CXXRecordDecl>( 131212904Sdim VBaseTypeInfo->getType()->getAs<RecordType>()->getDecl()); 132206084Srdivacky 133206084Srdivacky data().VBases[I] = 134206084Srdivacky CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true, 135208600Srdivacky VBaseClassDecl->getTagKind() == TTK_Class, 136212904Sdim VBases[I]->getAccessSpecifier(), VBaseTypeInfo); 137198092Srdivacky } 138193326Sed} 139193326Sed 140202379Srdivacky/// Callback function for CXXRecordDecl::forallBases that acknowledges 141202379Srdivacky/// that it saw a base class. 142202379Srdivackystatic bool SawBase(const CXXRecordDecl *, void *) { 143202379Srdivacky return true; 144202379Srdivacky} 145202379Srdivacky 146202379Srdivackybool CXXRecordDecl::hasAnyDependentBases() const { 147202379Srdivacky if (!isDependentContext()) 148202379Srdivacky return false; 149202379Srdivacky 150202379Srdivacky return !forallBases(SawBase, 0); 151202379Srdivacky} 152202379Srdivacky 153193326Sedbool CXXRecordDecl::hasConstCopyConstructor(ASTContext &Context) const { 154198092Srdivacky return getCopyConstructor(Context, Qualifiers::Const) != 0; 155194711Sed} 156194711Sed 157210299Sed/// \brief Perform a simplistic form of overload resolution that only considers 158210299Sed/// cv-qualifiers on a single parameter, and return the best overload candidate 159210299Sed/// (if there is one). 160210299Sedstatic CXXMethodDecl * 161210299SedGetBestOverloadCandidateSimple( 162210299Sed const llvm::SmallVectorImpl<std::pair<CXXMethodDecl *, Qualifiers> > &Cands) { 163210299Sed if (Cands.empty()) 164210299Sed return 0; 165210299Sed if (Cands.size() == 1) 166210299Sed return Cands[0].first; 167210299Sed 168210299Sed unsigned Best = 0, N = Cands.size(); 169210299Sed for (unsigned I = 1; I != N; ++I) 170210299Sed if (Cands[Best].second.isSupersetOf(Cands[I].second)) 171210299Sed Best = I; 172210299Sed 173210299Sed for (unsigned I = 1; I != N; ++I) 174210299Sed if (Cands[Best].second.isSupersetOf(Cands[I].second)) 175210299Sed return 0; 176210299Sed 177210299Sed return Cands[Best].first; 178210299Sed} 179210299Sed 180198092SrdivackyCXXConstructorDecl *CXXRecordDecl::getCopyConstructor(ASTContext &Context, 181194711Sed unsigned TypeQuals) const{ 182193326Sed QualType ClassType 183193326Sed = Context.getTypeDeclType(const_cast<CXXRecordDecl*>(this)); 184198092Srdivacky DeclarationName ConstructorName 185193326Sed = Context.DeclarationNames.getCXXConstructorName( 186194711Sed Context.getCanonicalType(ClassType)); 187194711Sed unsigned FoundTQs; 188210299Sed llvm::SmallVector<std::pair<CXXMethodDecl *, Qualifiers>, 4> Found; 189193326Sed DeclContext::lookup_const_iterator Con, ConEnd; 190195341Sed for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName); 191193326Sed Con != ConEnd; ++Con) { 192198092Srdivacky // C++ [class.copy]p2: 193198092Srdivacky // A non-template constructor for class X is a copy constructor if [...] 194198092Srdivacky if (isa<FunctionTemplateDecl>(*Con)) 195198092Srdivacky continue; 196198092Srdivacky 197210299Sed CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); 198210299Sed if (Constructor->isCopyConstructor(FoundTQs)) { 199198092Srdivacky if (((TypeQuals & Qualifiers::Const) == (FoundTQs & Qualifiers::Const)) || 200198092Srdivacky (!(TypeQuals & Qualifiers::Const) && (FoundTQs & Qualifiers::Const))) 201210299Sed Found.push_back(std::make_pair( 202210299Sed const_cast<CXXConstructorDecl *>(Constructor), 203210299Sed Qualifiers::fromCVRMask(FoundTQs))); 204194711Sed } 205193326Sed } 206210299Sed 207210299Sed return cast_or_null<CXXConstructorDecl>( 208210299Sed GetBestOverloadCandidateSimple(Found)); 209193326Sed} 210193326Sed 211210299SedCXXMethodDecl *CXXRecordDecl::getCopyAssignmentOperator(bool ArgIsConst) const { 212210299Sed ASTContext &Context = getASTContext(); 213210299Sed QualType Class = Context.getTypeDeclType(const_cast<CXXRecordDecl *>(this)); 214210299Sed DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal); 215210299Sed 216210299Sed llvm::SmallVector<std::pair<CXXMethodDecl *, Qualifiers>, 4> Found; 217193326Sed DeclContext::lookup_const_iterator Op, OpEnd; 218210299Sed for (llvm::tie(Op, OpEnd) = this->lookup(Name); Op != OpEnd; ++Op) { 219193326Sed // C++ [class.copy]p9: 220193326Sed // A user-declared copy assignment operator is a non-static non-template 221193326Sed // member function of class X with exactly one parameter of type X, X&, 222193326Sed // const X&, volatile X& or const volatile X&. 223198893Srdivacky const CXXMethodDecl* Method = dyn_cast<CXXMethodDecl>(*Op); 224210299Sed if (!Method || Method->isStatic() || Method->getPrimaryTemplate()) 225198893Srdivacky continue; 226210299Sed 227210299Sed const FunctionProtoType *FnType 228210299Sed = Method->getType()->getAs<FunctionProtoType>(); 229193326Sed assert(FnType && "Overloaded operator has no prototype."); 230193326Sed // Don't assert on this; an invalid decl might have been left in the AST. 231193326Sed if (FnType->getNumArgs() != 1 || FnType->isVariadic()) 232193326Sed continue; 233210299Sed 234193326Sed QualType ArgType = FnType->getArgType(0); 235210299Sed Qualifiers Quals; 236198092Srdivacky if (const LValueReferenceType *Ref = ArgType->getAs<LValueReferenceType>()) { 237193326Sed ArgType = Ref->getPointeeType(); 238210299Sed // If we have a const argument and we have a reference to a non-const, 239210299Sed // this function does not match. 240210299Sed if (ArgIsConst && !ArgType.isConstQualified()) 241210299Sed continue; 242210299Sed 243210299Sed Quals = ArgType.getQualifiers(); 244210299Sed } else { 245210299Sed // By-value copy-assignment operators are treated like const X& 246210299Sed // copy-assignment operators. 247210299Sed Quals = Qualifiers::fromCVRMask(Qualifiers::Const); 248193326Sed } 249210299Sed 250210299Sed if (!Context.hasSameUnqualifiedType(ArgType, Class)) 251193326Sed continue; 252210299Sed 253210299Sed // Save this copy-assignment operator. It might be "the one". 254210299Sed Found.push_back(std::make_pair(const_cast<CXXMethodDecl *>(Method), Quals)); 255193326Sed } 256210299Sed 257210299Sed // Use a simplistic form of overload resolution to find the candidate. 258210299Sed return GetBestOverloadCandidateSimple(Found); 259193326Sed} 260193326Sed 261193326Sedvoid 262198092SrdivackyCXXRecordDecl::addedConstructor(ASTContext &Context, 263193326Sed CXXConstructorDecl *ConDecl) { 264194613Sed assert(!ConDecl->isImplicit() && "addedConstructor - not for implicit decl"); 265194613Sed // Note that we have a user-declared constructor. 266203955Srdivacky data().UserDeclaredConstructor = true; 267193326Sed 268210299Sed // Note that we have no need of an implicitly-declared default constructor. 269210299Sed data().DeclaredDefaultConstructor = true; 270210299Sed 271198092Srdivacky // C++ [dcl.init.aggr]p1: 272194613Sed // An aggregate is an array or a class (clause 9) with no 273194613Sed // user-declared constructors (12.1) [...]. 274203955Srdivacky data().Aggregate = false; 275193326Sed 276194613Sed // C++ [class]p4: 277194613Sed // A POD-struct is an aggregate class [...] 278203955Srdivacky data().PlainOldData = false; 279193326Sed 280194613Sed // C++ [class.ctor]p5: 281194613Sed // A constructor is trivial if it is an implicitly-declared default 282194613Sed // constructor. 283198092Srdivacky // FIXME: C++0x: don't do this for "= default" default constructors. 284203955Srdivacky data().HasTrivialConstructor = false; 285198092Srdivacky 286194613Sed // Note when we have a user-declared copy constructor, which will 287194613Sed // suppress the implicit declaration of a copy constructor. 288201361Srdivacky if (ConDecl->isCopyConstructor()) { 289203955Srdivacky data().UserDeclaredCopyConstructor = true; 290210299Sed data().DeclaredCopyConstructor = true; 291210299Sed 292198092Srdivacky // C++ [class.copy]p6: 293198092Srdivacky // A copy constructor is trivial if it is implicitly declared. 294198092Srdivacky // FIXME: C++0x: don't do this for "= default" copy constructors. 295203955Srdivacky data().HasTrivialCopyConstructor = false; 296210299Sed 297198092Srdivacky } 298193326Sed} 299193326Sed 300193326Sedvoid CXXRecordDecl::addedAssignmentOperator(ASTContext &Context, 301193326Sed CXXMethodDecl *OpDecl) { 302193326Sed // We're interested specifically in copy assignment operators. 303198092Srdivacky const FunctionProtoType *FnType = OpDecl->getType()->getAs<FunctionProtoType>(); 304193326Sed assert(FnType && "Overloaded operator has no proto function type."); 305193326Sed assert(FnType->getNumArgs() == 1 && !FnType->isVariadic()); 306198092Srdivacky 307198092Srdivacky // Copy assignment operators must be non-templates. 308198092Srdivacky if (OpDecl->getPrimaryTemplate() || OpDecl->getDescribedFunctionTemplate()) 309198092Srdivacky return; 310198092Srdivacky 311193326Sed QualType ArgType = FnType->getArgType(0); 312198092Srdivacky if (const LValueReferenceType *Ref = ArgType->getAs<LValueReferenceType>()) 313193326Sed ArgType = Ref->getPointeeType(); 314193326Sed 315193326Sed ArgType = ArgType.getUnqualifiedType(); 316193326Sed QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType( 317193326Sed const_cast<CXXRecordDecl*>(this))); 318193326Sed 319199482Srdivacky if (!Context.hasSameUnqualifiedType(ClassType, ArgType)) 320193326Sed return; 321193326Sed 322193326Sed // This is a copy assignment operator. 323199482Srdivacky // Note on the decl that it is a copy assignment operator. 324199482Srdivacky OpDecl->setCopyAssignment(true); 325199482Srdivacky 326193326Sed // Suppress the implicit declaration of a copy constructor. 327203955Srdivacky data().UserDeclaredCopyAssignment = true; 328210299Sed data().DeclaredCopyAssignment = true; 329210299Sed 330198092Srdivacky // C++ [class.copy]p11: 331198092Srdivacky // A copy assignment operator is trivial if it is implicitly declared. 332198092Srdivacky // FIXME: C++0x: don't do this for "= default" copy operators. 333203955Srdivacky data().HasTrivialCopyAssignment = false; 334198092Srdivacky 335193326Sed // C++ [class]p4: 336193326Sed // A POD-struct is an aggregate class that [...] has no user-defined copy 337193326Sed // assignment operator [...]. 338203955Srdivacky data().PlainOldData = false; 339193326Sed} 340193326Sed 341205219Srdivackystatic CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) { 342205219Srdivacky QualType T; 343206084Srdivacky if (isa<UsingShadowDecl>(Conv)) 344206084Srdivacky Conv = cast<UsingShadowDecl>(Conv)->getTargetDecl(); 345205219Srdivacky if (FunctionTemplateDecl *ConvTemp = dyn_cast<FunctionTemplateDecl>(Conv)) 346205219Srdivacky T = ConvTemp->getTemplatedDecl()->getResultType(); 347205219Srdivacky else 348205219Srdivacky T = cast<CXXConversionDecl>(Conv)->getConversionType(); 349205219Srdivacky return Context.getCanonicalType(T); 350198092Srdivacky} 351198092Srdivacky 352205219Srdivacky/// Collect the visible conversions of a base class. 353205219Srdivacky/// 354205219Srdivacky/// \param Base a base class of the class we're considering 355205219Srdivacky/// \param InVirtual whether this base class is a virtual base (or a base 356205219Srdivacky/// of a virtual base) 357205219Srdivacky/// \param Access the access along the inheritance path to this base 358205219Srdivacky/// \param ParentHiddenTypes the conversions provided by the inheritors 359205219Srdivacky/// of this base 360205219Srdivacky/// \param Output the set to which to add conversions from non-virtual bases 361205219Srdivacky/// \param VOutput the set to which to add conversions from virtual bases 362205219Srdivacky/// \param HiddenVBaseCs the set of conversions which were hidden in a 363205219Srdivacky/// virtual base along some inheritance path 364205219Srdivackystatic void CollectVisibleConversions(ASTContext &Context, 365205219Srdivacky CXXRecordDecl *Record, 366205219Srdivacky bool InVirtual, 367205219Srdivacky AccessSpecifier Access, 368205219Srdivacky const llvm::SmallPtrSet<CanQualType, 8> &ParentHiddenTypes, 369205219Srdivacky UnresolvedSetImpl &Output, 370205219Srdivacky UnresolvedSetImpl &VOutput, 371205219Srdivacky llvm::SmallPtrSet<NamedDecl*, 8> &HiddenVBaseCs) { 372205219Srdivacky // The set of types which have conversions in this class or its 373205219Srdivacky // subclasses. As an optimization, we don't copy the derived set 374205219Srdivacky // unless it might change. 375205219Srdivacky const llvm::SmallPtrSet<CanQualType, 8> *HiddenTypes = &ParentHiddenTypes; 376205219Srdivacky llvm::SmallPtrSet<CanQualType, 8> HiddenTypesBuffer; 377205219Srdivacky 378205219Srdivacky // Collect the direct conversions and figure out which conversions 379205219Srdivacky // will be hidden in the subclasses. 380205219Srdivacky UnresolvedSetImpl &Cs = *Record->getConversionFunctions(); 381205219Srdivacky if (!Cs.empty()) { 382205219Srdivacky HiddenTypesBuffer = ParentHiddenTypes; 383205219Srdivacky HiddenTypes = &HiddenTypesBuffer; 384205219Srdivacky 385205219Srdivacky for (UnresolvedSetIterator I = Cs.begin(), E = Cs.end(); I != E; ++I) { 386205219Srdivacky bool Hidden = 387205219Srdivacky !HiddenTypesBuffer.insert(GetConversionType(Context, I.getDecl())); 388205219Srdivacky 389205219Srdivacky // If this conversion is hidden and we're in a virtual base, 390205219Srdivacky // remember that it's hidden along some inheritance path. 391205219Srdivacky if (Hidden && InVirtual) 392205219Srdivacky HiddenVBaseCs.insert(cast<NamedDecl>(I.getDecl()->getCanonicalDecl())); 393205219Srdivacky 394205219Srdivacky // If this conversion isn't hidden, add it to the appropriate output. 395205219Srdivacky else if (!Hidden) { 396205219Srdivacky AccessSpecifier IAccess 397205219Srdivacky = CXXRecordDecl::MergeAccess(Access, I.getAccess()); 398205219Srdivacky 399205219Srdivacky if (InVirtual) 400205219Srdivacky VOutput.addDecl(I.getDecl(), IAccess); 401198092Srdivacky else 402205219Srdivacky Output.addDecl(I.getDecl(), IAccess); 403198092Srdivacky } 404198092Srdivacky } 405198092Srdivacky } 406198893Srdivacky 407205219Srdivacky // Collect information recursively from any base classes. 408205219Srdivacky for (CXXRecordDecl::base_class_iterator 409205219Srdivacky I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) { 410205219Srdivacky const RecordType *RT = I->getType()->getAs<RecordType>(); 411205219Srdivacky if (!RT) continue; 412198893Srdivacky 413205219Srdivacky AccessSpecifier BaseAccess 414205219Srdivacky = CXXRecordDecl::MergeAccess(Access, I->getAccessSpecifier()); 415205219Srdivacky bool BaseInVirtual = InVirtual || I->isVirtual(); 416198893Srdivacky 417205219Srdivacky CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl()); 418205219Srdivacky CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess, 419205219Srdivacky *HiddenTypes, Output, VOutput, HiddenVBaseCs); 420198092Srdivacky } 421205219Srdivacky} 422198893Srdivacky 423205219Srdivacky/// Collect the visible conversions of a class. 424205219Srdivacky/// 425205219Srdivacky/// This would be extremely straightforward if it weren't for virtual 426205219Srdivacky/// bases. It might be worth special-casing that, really. 427205219Srdivackystatic void CollectVisibleConversions(ASTContext &Context, 428205219Srdivacky CXXRecordDecl *Record, 429205219Srdivacky UnresolvedSetImpl &Output) { 430205219Srdivacky // The collection of all conversions in virtual bases that we've 431205219Srdivacky // found. These will be added to the output as long as they don't 432205219Srdivacky // appear in the hidden-conversions set. 433205219Srdivacky UnresolvedSet<8> VBaseCs; 434205219Srdivacky 435205219Srdivacky // The set of conversions in virtual bases that we've determined to 436205219Srdivacky // be hidden. 437205219Srdivacky llvm::SmallPtrSet<NamedDecl*, 8> HiddenVBaseCs; 438205219Srdivacky 439205219Srdivacky // The set of types hidden by classes derived from this one. 440205219Srdivacky llvm::SmallPtrSet<CanQualType, 8> HiddenTypes; 441205219Srdivacky 442205219Srdivacky // Go ahead and collect the direct conversions and add them to the 443205219Srdivacky // hidden-types set. 444205219Srdivacky UnresolvedSetImpl &Cs = *Record->getConversionFunctions(); 445205219Srdivacky Output.append(Cs.begin(), Cs.end()); 446205219Srdivacky for (UnresolvedSetIterator I = Cs.begin(), E = Cs.end(); I != E; ++I) 447205219Srdivacky HiddenTypes.insert(GetConversionType(Context, I.getDecl())); 448205219Srdivacky 449205219Srdivacky // Recursively collect conversions from base classes. 450205219Srdivacky for (CXXRecordDecl::base_class_iterator 451205219Srdivacky I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) { 452205219Srdivacky const RecordType *RT = I->getType()->getAs<RecordType>(); 453205219Srdivacky if (!RT) continue; 454205219Srdivacky 455205219Srdivacky CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()), 456205219Srdivacky I->isVirtual(), I->getAccessSpecifier(), 457205219Srdivacky HiddenTypes, Output, VBaseCs, HiddenVBaseCs); 458198092Srdivacky } 459205219Srdivacky 460205219Srdivacky // Add any unhidden conversions provided by virtual bases. 461205219Srdivacky for (UnresolvedSetIterator I = VBaseCs.begin(), E = VBaseCs.end(); 462205219Srdivacky I != E; ++I) { 463205219Srdivacky if (!HiddenVBaseCs.count(cast<NamedDecl>(I.getDecl()->getCanonicalDecl()))) 464205219Srdivacky Output.addDecl(I.getDecl(), I.getAccess()); 465205219Srdivacky } 466198092Srdivacky} 467198092Srdivacky 468198092Srdivacky/// getVisibleConversionFunctions - get all conversion functions visible 469198092Srdivacky/// in current class; including conversion function templates. 470202879Srdivackyconst UnresolvedSetImpl *CXXRecordDecl::getVisibleConversionFunctions() { 471198092Srdivacky // If root class, all conversions are visible. 472198092Srdivacky if (bases_begin() == bases_end()) 473203955Srdivacky return &data().Conversions; 474198092Srdivacky // If visible conversion list is already evaluated, return it. 475203955Srdivacky if (data().ComputedVisibleConversions) 476203955Srdivacky return &data().VisibleConversions; 477205219Srdivacky CollectVisibleConversions(getASTContext(), this, data().VisibleConversions); 478203955Srdivacky data().ComputedVisibleConversions = true; 479203955Srdivacky return &data().VisibleConversions; 480198092Srdivacky} 481198092Srdivacky 482206084Srdivacky#ifndef NDEBUG 483206084Srdivackyvoid CXXRecordDecl::CheckConversionFunction(NamedDecl *ConvDecl) { 484205219Srdivacky assert(ConvDecl->getDeclContext() == this && 485205219Srdivacky "conversion function does not belong to this record"); 486198092Srdivacky 487206084Srdivacky ConvDecl = ConvDecl->getUnderlyingDecl(); 488206084Srdivacky if (FunctionTemplateDecl *Temp = dyn_cast<FunctionTemplateDecl>(ConvDecl)) { 489206084Srdivacky assert(isa<CXXConversionDecl>(Temp->getTemplatedDecl())); 490206084Srdivacky } else { 491206084Srdivacky assert(isa<CXXConversionDecl>(ConvDecl)); 492206084Srdivacky } 493193326Sed} 494206084Srdivacky#endif 495193326Sed 496206084Srdivackyvoid CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) { 497206084Srdivacky // This operation is O(N) but extremely rare. Sema only uses it to 498206084Srdivacky // remove UsingShadowDecls in a class that were followed by a direct 499206084Srdivacky // declaration, e.g.: 500206084Srdivacky // class A : B { 501206084Srdivacky // using B::operator int; 502206084Srdivacky // operator int(); 503206084Srdivacky // }; 504206084Srdivacky // This is uncommon by itself and even more uncommon in conjunction 505206084Srdivacky // with sufficiently large numbers of directly-declared conversions 506206084Srdivacky // that asymptotic behavior matters. 507206084Srdivacky 508206084Srdivacky UnresolvedSetImpl &Convs = *getConversionFunctions(); 509206084Srdivacky for (unsigned I = 0, E = Convs.size(); I != E; ++I) { 510206084Srdivacky if (Convs[I].getDecl() == ConvDecl) { 511206084Srdivacky Convs.erase(I); 512206084Srdivacky assert(std::find(Convs.begin(), Convs.end(), ConvDecl) == Convs.end() 513206084Srdivacky && "conversion was found multiple times in unresolved set"); 514206084Srdivacky return; 515206084Srdivacky } 516206084Srdivacky } 517206084Srdivacky 518206084Srdivacky llvm_unreachable("conversion not found in set!"); 519198092Srdivacky} 520194613Sed 521200583Srdivackyvoid CXXRecordDecl::setMethodAsVirtual(FunctionDecl *Method) { 522200583Srdivacky Method->setVirtualAsWritten(true); 523200583Srdivacky setAggregate(false); 524200583Srdivacky setPOD(false); 525200583Srdivacky setEmpty(false); 526200583Srdivacky setPolymorphic(true); 527200583Srdivacky setHasTrivialConstructor(false); 528200583Srdivacky setHasTrivialCopyConstructor(false); 529200583Srdivacky setHasTrivialCopyAssignment(false); 530200583Srdivacky} 531200583Srdivacky 532198092SrdivackyCXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const { 533198092Srdivacky if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) 534198092Srdivacky return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom()); 535198092Srdivacky 536198092Srdivacky return 0; 537198092Srdivacky} 538198092Srdivacky 539198092SrdivackyMemberSpecializationInfo *CXXRecordDecl::getMemberSpecializationInfo() const { 540198092Srdivacky return TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>(); 541198092Srdivacky} 542198092Srdivacky 543198092Srdivackyvoid 544198092SrdivackyCXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD, 545198092Srdivacky TemplateSpecializationKind TSK) { 546198092Srdivacky assert(TemplateOrInstantiation.isNull() && 547198092Srdivacky "Previous template or instantiation?"); 548198092Srdivacky assert(!isa<ClassTemplateSpecializationDecl>(this)); 549198092Srdivacky TemplateOrInstantiation 550198092Srdivacky = new (getASTContext()) MemberSpecializationInfo(RD, TSK); 551198092Srdivacky} 552198092Srdivacky 553200583SrdivackyTemplateSpecializationKind CXXRecordDecl::getTemplateSpecializationKind() const{ 554200583Srdivacky if (const ClassTemplateSpecializationDecl *Spec 555198092Srdivacky = dyn_cast<ClassTemplateSpecializationDecl>(this)) 556198092Srdivacky return Spec->getSpecializationKind(); 557198092Srdivacky 558198092Srdivacky if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) 559198092Srdivacky return MSInfo->getTemplateSpecializationKind(); 560198092Srdivacky 561198092Srdivacky return TSK_Undeclared; 562198092Srdivacky} 563198092Srdivacky 564198092Srdivackyvoid 565198092SrdivackyCXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) { 566198092Srdivacky if (ClassTemplateSpecializationDecl *Spec 567198092Srdivacky = dyn_cast<ClassTemplateSpecializationDecl>(this)) { 568198092Srdivacky Spec->setSpecializationKind(TSK); 569198092Srdivacky return; 570198092Srdivacky } 571198092Srdivacky 572198092Srdivacky if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) { 573198092Srdivacky MSInfo->setTemplateSpecializationKind(TSK); 574198092Srdivacky return; 575198092Srdivacky } 576198092Srdivacky 577198092Srdivacky assert(false && "Not a class template or member class specialization"); 578198092Srdivacky} 579198092Srdivacky 580194613SedCXXConstructorDecl * 581210299SedCXXRecordDecl::getDefaultConstructor() { 582210299Sed ASTContext &Context = getASTContext(); 583194613Sed QualType ClassType = Context.getTypeDeclType(this); 584194613Sed DeclarationName ConstructorName 585194613Sed = Context.DeclarationNames.getCXXConstructorName( 586194613Sed Context.getCanonicalType(ClassType.getUnqualifiedType())); 587198092Srdivacky 588194613Sed DeclContext::lookup_const_iterator Con, ConEnd; 589195341Sed for (llvm::tie(Con, ConEnd) = lookup(ConstructorName); 590194613Sed Con != ConEnd; ++Con) { 591198092Srdivacky // FIXME: In C++0x, a constructor template can be a default constructor. 592198092Srdivacky if (isa<FunctionTemplateDecl>(*Con)) 593198092Srdivacky continue; 594198092Srdivacky 595194613Sed CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con); 596194613Sed if (Constructor->isDefaultConstructor()) 597194613Sed return Constructor; 598194613Sed } 599194613Sed return 0; 600194613Sed} 601194613Sed 602210299SedCXXDestructorDecl *CXXRecordDecl::getDestructor() const { 603210299Sed ASTContext &Context = getASTContext(); 604193326Sed QualType ClassType = Context.getTypeDeclType(this); 605193326Sed 606198092Srdivacky DeclarationName Name 607198092Srdivacky = Context.DeclarationNames.getCXXDestructorName( 608198092Srdivacky Context.getCanonicalType(ClassType)); 609198092Srdivacky 610204643Srdivacky DeclContext::lookup_const_iterator I, E; 611198092Srdivacky llvm::tie(I, E) = lookup(Name); 612212904Sdim if (I == E) 613212904Sdim return 0; 614198092Srdivacky 615200583Srdivacky CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I); 616193326Sed assert(++I == E && "Found more than one destructor!"); 617198092Srdivacky 618193326Sed return Dtor; 619193326Sed} 620193326Sed 621193326SedCXXMethodDecl * 622193326SedCXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, 623212904Sdim const DeclarationNameInfo &NameInfo, 624200583Srdivacky QualType T, TypeSourceInfo *TInfo, 625207619Srdivacky bool isStatic, StorageClass SCAsWritten, bool isInline) { 626212904Sdim return new (C) CXXMethodDecl(CXXMethod, RD, NameInfo, T, TInfo, 627207619Srdivacky isStatic, SCAsWritten, isInline); 628193326Sed} 629193326Sed 630198092Srdivackybool CXXMethodDecl::isUsualDeallocationFunction() const { 631198092Srdivacky if (getOverloadedOperator() != OO_Delete && 632198092Srdivacky getOverloadedOperator() != OO_Array_Delete) 633198092Srdivacky return false; 634204643Srdivacky 635198092Srdivacky // C++ [basic.stc.dynamic.deallocation]p2: 636204643Srdivacky // A template instance is never a usual deallocation function, 637204643Srdivacky // regardless of its signature. 638204643Srdivacky if (getPrimaryTemplate()) 639204643Srdivacky return false; 640204643Srdivacky 641204643Srdivacky // C++ [basic.stc.dynamic.deallocation]p2: 642198092Srdivacky // If a class T has a member deallocation function named operator delete 643198092Srdivacky // with exactly one parameter, then that function is a usual (non-placement) 644198092Srdivacky // deallocation function. [...] 645198092Srdivacky if (getNumParams() == 1) 646198092Srdivacky return true; 647198092Srdivacky 648198092Srdivacky // C++ [basic.stc.dynamic.deallocation]p2: 649198092Srdivacky // [...] If class T does not declare such an operator delete but does 650198092Srdivacky // declare a member deallocation function named operator delete with 651198092Srdivacky // exactly two parameters, the second of which has type std::size_t (18.1), 652198092Srdivacky // then this function is a usual deallocation function. 653198092Srdivacky ASTContext &Context = getASTContext(); 654198092Srdivacky if (getNumParams() != 2 || 655203955Srdivacky !Context.hasSameUnqualifiedType(getParamDecl(1)->getType(), 656203955Srdivacky Context.getSizeType())) 657198092Srdivacky return false; 658198092Srdivacky 659198092Srdivacky // This function is a usual deallocation function if there are no 660198092Srdivacky // single-parameter deallocation functions of the same kind. 661198092Srdivacky for (DeclContext::lookup_const_result R = getDeclContext()->lookup(getDeclName()); 662198092Srdivacky R.first != R.second; ++R.first) { 663198092Srdivacky if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*R.first)) 664198092Srdivacky if (FD->getNumParams() == 1) 665198092Srdivacky return false; 666198092Srdivacky } 667198092Srdivacky 668198092Srdivacky return true; 669198092Srdivacky} 670193326Sed 671207619Srdivackybool CXXMethodDecl::isCopyAssignmentOperator() const { 672207619Srdivacky // C++0x [class.copy]p19: 673207619Srdivacky // A user-declared copy assignment operator X::operator= is a non-static 674207619Srdivacky // non-template member function of class X with exactly one parameter of 675207619Srdivacky // type X, X&, const X&, volatile X& or const volatile X&. 676207619Srdivacky if (/*operator=*/getOverloadedOperator() != OO_Equal || 677207619Srdivacky /*non-static*/ isStatic() || 678207619Srdivacky /*non-template*/getPrimaryTemplate() || getDescribedFunctionTemplate() || 679207619Srdivacky /*exactly one parameter*/getNumParams() != 1) 680207619Srdivacky return false; 681207619Srdivacky 682207619Srdivacky QualType ParamType = getParamDecl(0)->getType(); 683207619Srdivacky if (const LValueReferenceType *Ref = ParamType->getAs<LValueReferenceType>()) 684207619Srdivacky ParamType = Ref->getPointeeType(); 685207619Srdivacky 686207619Srdivacky ASTContext &Context = getASTContext(); 687207619Srdivacky QualType ClassType 688207619Srdivacky = Context.getCanonicalType(Context.getTypeDeclType(getParent())); 689207619Srdivacky return Context.hasSameUnqualifiedType(ClassType, ParamType); 690207619Srdivacky} 691207619Srdivacky 692193326Sedvoid CXXMethodDecl::addOverriddenMethod(const CXXMethodDecl *MD) { 693200583Srdivacky assert(MD->isCanonicalDecl() && "Method is not canonical!"); 694203955Srdivacky assert(!MD->getParent()->isDependentContext() && 695203955Srdivacky "Can't add an overridden method to a class template!"); 696203955Srdivacky 697204643Srdivacky getASTContext().addOverriddenMethod(this, MD); 698193326Sed} 699193326Sed 700193326SedCXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const { 701204643Srdivacky return getASTContext().overridden_methods_begin(this); 702193326Sed} 703193326Sed 704193326SedCXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const { 705204643Srdivacky return getASTContext().overridden_methods_end(this); 706193326Sed} 707193326Sed 708210299Sedunsigned CXXMethodDecl::size_overridden_methods() const { 709210299Sed return getASTContext().overridden_methods_size(this); 710210299Sed} 711210299Sed 712193326SedQualType CXXMethodDecl::getThisType(ASTContext &C) const { 713193326Sed // C++ 9.3.2p1: The type of this in a member function of a class X is X*. 714193326Sed // If the member function is declared const, the type of this is const X*, 715193326Sed // if the member function is declared volatile, the type of this is 716193326Sed // volatile X*, and if the member function is declared const volatile, 717193326Sed // the type of this is const volatile X*. 718193326Sed 719193326Sed assert(isInstance() && "No 'this' for static methods!"); 720194179Sed 721204962Srdivacky QualType ClassTy = C.getTypeDeclType(getParent()); 722198092Srdivacky ClassTy = C.getQualifiedType(ClassTy, 723198092Srdivacky Qualifiers::fromCVRMask(getTypeQualifiers())); 724198092Srdivacky return C.getPointerType(ClassTy); 725193326Sed} 726193326Sed 727200583Srdivackybool CXXMethodDecl::hasInlineBody() const { 728202379Srdivacky // If this function is a template instantiation, look at the template from 729202379Srdivacky // which it was instantiated. 730202379Srdivacky const FunctionDecl *CheckFn = getTemplateInstantiationPattern(); 731202379Srdivacky if (!CheckFn) 732202379Srdivacky CheckFn = this; 733202379Srdivacky 734200583Srdivacky const FunctionDecl *fn; 735210299Sed return CheckFn->hasBody(fn) && !fn->isOutOfLine(); 736200583Srdivacky} 737200583Srdivacky 738193326SedCXXBaseOrMemberInitializer:: 739200583SrdivackyCXXBaseOrMemberInitializer(ASTContext &Context, 740207619Srdivacky TypeSourceInfo *TInfo, bool IsVirtual, 741203955Srdivacky SourceLocation L, Expr *Init, SourceLocation R) 742208600Srdivacky : BaseOrMember(TInfo), Init(Init), AnonUnionMember(0), 743208600Srdivacky LParenLoc(L), RParenLoc(R), IsVirtual(IsVirtual), IsWritten(false), 744208600Srdivacky SourceOrderOrNumArrayIndices(0) 745200583Srdivacky{ 746193326Sed} 747193326Sed 748193326SedCXXBaseOrMemberInitializer:: 749200583SrdivackyCXXBaseOrMemberInitializer(ASTContext &Context, 750200583Srdivacky FieldDecl *Member, SourceLocation MemberLoc, 751203955Srdivacky SourceLocation L, Expr *Init, SourceLocation R) 752208600Srdivacky : BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init), 753208600Srdivacky AnonUnionMember(0), LParenLoc(L), RParenLoc(R), IsVirtual(false), 754208600Srdivacky IsWritten(false), SourceOrderOrNumArrayIndices(0) 755208600Srdivacky{ 756208600Srdivacky} 757208600Srdivacky 758208600SrdivackyCXXBaseOrMemberInitializer:: 759208600SrdivackyCXXBaseOrMemberInitializer(ASTContext &Context, 760208600Srdivacky FieldDecl *Member, SourceLocation MemberLoc, 761208600Srdivacky SourceLocation L, Expr *Init, SourceLocation R, 762208600Srdivacky VarDecl **Indices, 763208600Srdivacky unsigned NumIndices) 764203955Srdivacky : BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init), 765208600Srdivacky AnonUnionMember(0), LParenLoc(L), RParenLoc(R), IsVirtual(false), 766208600Srdivacky IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices) 767200583Srdivacky{ 768208600Srdivacky VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1); 769208600Srdivacky memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *)); 770193326Sed} 771193326Sed 772208600SrdivackyCXXBaseOrMemberInitializer * 773208600SrdivackyCXXBaseOrMemberInitializer::Create(ASTContext &Context, 774208600Srdivacky FieldDecl *Member, 775208600Srdivacky SourceLocation MemberLoc, 776208600Srdivacky SourceLocation L, 777208600Srdivacky Expr *Init, 778208600Srdivacky SourceLocation R, 779208600Srdivacky VarDecl **Indices, 780208600Srdivacky unsigned NumIndices) { 781208600Srdivacky void *Mem = Context.Allocate(sizeof(CXXBaseOrMemberInitializer) + 782208600Srdivacky sizeof(VarDecl *) * NumIndices, 783208600Srdivacky llvm::alignof<CXXBaseOrMemberInitializer>()); 784208600Srdivacky return new (Mem) CXXBaseOrMemberInitializer(Context, Member, MemberLoc, 785208600Srdivacky L, Init, R, Indices, NumIndices); 786208600Srdivacky} 787208600Srdivacky 788200583SrdivackyTypeLoc CXXBaseOrMemberInitializer::getBaseClassLoc() const { 789200583Srdivacky if (isBaseInitializer()) 790200583Srdivacky return BaseOrMember.get<TypeSourceInfo*>()->getTypeLoc(); 791200583Srdivacky else 792200583Srdivacky return TypeLoc(); 793200583Srdivacky} 794200583Srdivacky 795200583SrdivackyType *CXXBaseOrMemberInitializer::getBaseClass() { 796200583Srdivacky if (isBaseInitializer()) 797200583Srdivacky return BaseOrMember.get<TypeSourceInfo*>()->getType().getTypePtr(); 798200583Srdivacky else 799200583Srdivacky return 0; 800200583Srdivacky} 801200583Srdivacky 802200583Srdivackyconst Type *CXXBaseOrMemberInitializer::getBaseClass() const { 803200583Srdivacky if (isBaseInitializer()) 804200583Srdivacky return BaseOrMember.get<TypeSourceInfo*>()->getType().getTypePtr(); 805200583Srdivacky else 806200583Srdivacky return 0; 807200583Srdivacky} 808200583Srdivacky 809200583SrdivackySourceLocation CXXBaseOrMemberInitializer::getSourceLocation() const { 810200583Srdivacky if (isMemberInitializer()) 811200583Srdivacky return getMemberLocation(); 812200583Srdivacky 813208600Srdivacky return getBaseClassLoc().getLocalSourceRange().getBegin(); 814200583Srdivacky} 815200583Srdivacky 816200583SrdivackySourceRange CXXBaseOrMemberInitializer::getSourceRange() const { 817200583Srdivacky return SourceRange(getSourceLocation(), getRParenLoc()); 818200583Srdivacky} 819200583Srdivacky 820193326SedCXXConstructorDecl * 821208600SrdivackyCXXConstructorDecl::Create(ASTContext &C, EmptyShell Empty) { 822212904Sdim return new (C) CXXConstructorDecl(0, DeclarationNameInfo(), 823208600Srdivacky QualType(), 0, false, false, false); 824208600Srdivacky} 825208600Srdivacky 826208600SrdivackyCXXConstructorDecl * 827193326SedCXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, 828212904Sdim const DeclarationNameInfo &NameInfo, 829200583Srdivacky QualType T, TypeSourceInfo *TInfo, 830198092Srdivacky bool isExplicit, 831207619Srdivacky bool isInline, 832207619Srdivacky bool isImplicitlyDeclared) { 833212904Sdim assert(NameInfo.getName().getNameKind() 834212904Sdim == DeclarationName::CXXConstructorName && 835193326Sed "Name must refer to a constructor"); 836212904Sdim return new (C) CXXConstructorDecl(RD, NameInfo, T, TInfo, isExplicit, 837207619Srdivacky isInline, isImplicitlyDeclared); 838193326Sed} 839193326Sed 840193326Sedbool CXXConstructorDecl::isDefaultConstructor() const { 841193326Sed // C++ [class.ctor]p5: 842193326Sed // A default constructor for a class X is a constructor of class 843193326Sed // X that can be called without an argument. 844193326Sed return (getNumParams() == 0) || 845198092Srdivacky (getNumParams() > 0 && getParamDecl(0)->hasDefaultArg()); 846193326Sed} 847193326Sed 848198092Srdivackybool 849201361SrdivackyCXXConstructorDecl::isCopyConstructor(unsigned &TypeQuals) const { 850193326Sed // C++ [class.copy]p2: 851193326Sed // A non-template constructor for class X is a copy constructor 852193326Sed // if its first parameter is of type X&, const X&, volatile X& or 853193326Sed // const volatile X&, and either there are no other parameters 854193326Sed // or else all other parameters have default arguments (8.3.6). 855193326Sed if ((getNumParams() < 1) || 856198092Srdivacky (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) || 857198092Srdivacky (getPrimaryTemplate() != 0) || 858198092Srdivacky (getDescribedFunctionTemplate() != 0)) 859193326Sed return false; 860193326Sed 861193326Sed const ParmVarDecl *Param = getParamDecl(0); 862193326Sed 863193326Sed // Do we have a reference type? Rvalue references don't count. 864193326Sed const LValueReferenceType *ParamRefType = 865198092Srdivacky Param->getType()->getAs<LValueReferenceType>(); 866193326Sed if (!ParamRefType) 867193326Sed return false; 868193326Sed 869193326Sed // Is it a reference to our class type? 870201361Srdivacky ASTContext &Context = getASTContext(); 871201361Srdivacky 872198092Srdivacky CanQualType PointeeType 873193326Sed = Context.getCanonicalType(ParamRefType->getPointeeType()); 874198092Srdivacky CanQualType ClassTy 875198092Srdivacky = Context.getCanonicalType(Context.getTagDeclType(getParent())); 876193326Sed if (PointeeType.getUnqualifiedType() != ClassTy) 877193326Sed return false; 878193326Sed 879198092Srdivacky // FIXME: other qualifiers? 880198092Srdivacky 881193326Sed // We have a copy constructor. 882193326Sed TypeQuals = PointeeType.getCVRQualifiers(); 883193326Sed return true; 884193326Sed} 885193326Sed 886198092Srdivackybool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const { 887193326Sed // C++ [class.conv.ctor]p1: 888193326Sed // A constructor declared without the function-specifier explicit 889193326Sed // that can be called with a single parameter specifies a 890193326Sed // conversion from the type of its first parameter to the type of 891193326Sed // its class. Such a constructor is called a converting 892193326Sed // constructor. 893198092Srdivacky if (isExplicit() && !AllowExplicit) 894193326Sed return false; 895193326Sed 896198092Srdivacky return (getNumParams() == 0 && 897198092Srdivacky getType()->getAs<FunctionProtoType>()->isVariadic()) || 898193326Sed (getNumParams() == 1) || 899193576Sed (getNumParams() > 1 && getParamDecl(1)->hasDefaultArg()); 900193326Sed} 901193326Sed 902199482Srdivackybool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const { 903199482Srdivacky if ((getNumParams() < 1) || 904199482Srdivacky (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) || 905199482Srdivacky (getPrimaryTemplate() == 0) || 906199482Srdivacky (getDescribedFunctionTemplate() != 0)) 907199482Srdivacky return false; 908199482Srdivacky 909199482Srdivacky const ParmVarDecl *Param = getParamDecl(0); 910199482Srdivacky 911199482Srdivacky ASTContext &Context = getASTContext(); 912199482Srdivacky CanQualType ParamType = Context.getCanonicalType(Param->getType()); 913199482Srdivacky 914199482Srdivacky // Strip off the lvalue reference, if any. 915199482Srdivacky if (CanQual<LValueReferenceType> ParamRefType 916199482Srdivacky = ParamType->getAs<LValueReferenceType>()) 917199482Srdivacky ParamType = ParamRefType->getPointeeType(); 918199482Srdivacky 919199482Srdivacky 920199482Srdivacky // Is it the same as our our class type? 921199482Srdivacky CanQualType ClassTy 922199482Srdivacky = Context.getCanonicalType(Context.getTagDeclType(getParent())); 923199482Srdivacky if (ParamType.getUnqualifiedType() != ClassTy) 924199482Srdivacky return false; 925199482Srdivacky 926199482Srdivacky return true; 927199482Srdivacky} 928199482Srdivacky 929193326SedCXXDestructorDecl * 930208600SrdivackyCXXDestructorDecl::Create(ASTContext &C, EmptyShell Empty) { 931212904Sdim return new (C) CXXDestructorDecl(0, DeclarationNameInfo(), 932208600Srdivacky QualType(), false, false); 933208600Srdivacky} 934208600Srdivacky 935208600SrdivackyCXXDestructorDecl * 936193326SedCXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, 937212904Sdim const DeclarationNameInfo &NameInfo, 938198092Srdivacky QualType T, bool isInline, 939193326Sed bool isImplicitlyDeclared) { 940212904Sdim assert(NameInfo.getName().getNameKind() 941212904Sdim == DeclarationName::CXXDestructorName && 942193326Sed "Name must refer to a destructor"); 943212904Sdim return new (C) CXXDestructorDecl(RD, NameInfo, T, isInline, 944212904Sdim isImplicitlyDeclared); 945193326Sed} 946193326Sed 947193326SedCXXConversionDecl * 948208600SrdivackyCXXConversionDecl::Create(ASTContext &C, EmptyShell Empty) { 949212904Sdim return new (C) CXXConversionDecl(0, DeclarationNameInfo(), 950208600Srdivacky QualType(), 0, false, false); 951208600Srdivacky} 952208600Srdivacky 953208600SrdivackyCXXConversionDecl * 954193326SedCXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD, 955212904Sdim const DeclarationNameInfo &NameInfo, 956200583Srdivacky QualType T, TypeSourceInfo *TInfo, 957198092Srdivacky bool isInline, bool isExplicit) { 958212904Sdim assert(NameInfo.getName().getNameKind() 959212904Sdim == DeclarationName::CXXConversionFunctionName && 960193326Sed "Name must refer to a conversion function"); 961212904Sdim return new (C) CXXConversionDecl(RD, NameInfo, T, TInfo, 962212904Sdim isInline, isExplicit); 963193326Sed} 964193326Sed 965193326SedLinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, 966198092Srdivacky DeclContext *DC, 967193326Sed SourceLocation L, 968193326Sed LanguageIDs Lang, bool Braces) { 969193326Sed return new (C) LinkageSpecDecl(DC, L, Lang, Braces); 970193326Sed} 971193326Sed 972193326SedUsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, 973193326Sed SourceLocation L, 974193326Sed SourceLocation NamespaceLoc, 975193326Sed SourceRange QualifierRange, 976193326Sed NestedNameSpecifier *Qualifier, 977193326Sed SourceLocation IdentLoc, 978199990Srdivacky NamedDecl *Used, 979193326Sed DeclContext *CommonAncestor) { 980199990Srdivacky if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used)) 981199990Srdivacky Used = NS->getOriginalNamespace(); 982198092Srdivacky return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierRange, 983193326Sed Qualifier, IdentLoc, Used, CommonAncestor); 984193326Sed} 985193326Sed 986199990SrdivackyNamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() { 987199990Srdivacky if (NamespaceAliasDecl *NA = 988199990Srdivacky dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace)) 989199990Srdivacky return NA->getNamespace(); 990199990Srdivacky return cast_or_null<NamespaceDecl>(NominatedNamespace); 991199990Srdivacky} 992199990Srdivacky 993198092SrdivackyNamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, 994212904Sdim SourceLocation UsingLoc, 995198092Srdivacky SourceLocation AliasLoc, 996198092Srdivacky IdentifierInfo *Alias, 997193326Sed SourceRange QualifierRange, 998193326Sed NestedNameSpecifier *Qualifier, 999198092Srdivacky SourceLocation IdentLoc, 1000193326Sed NamedDecl *Namespace) { 1001199990Srdivacky if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace)) 1002199990Srdivacky Namespace = NS->getOriginalNamespace(); 1003212904Sdim return new (C) NamespaceAliasDecl(DC, UsingLoc, AliasLoc, Alias, QualifierRange, 1004193326Sed Qualifier, IdentLoc, Namespace); 1005193326Sed} 1006193326Sed 1007194613SedUsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, 1008212904Sdim SourceRange NNR, SourceLocation UL, 1009212904Sdim NestedNameSpecifier* TargetNNS, 1010212904Sdim const DeclarationNameInfo &NameInfo, 1011212904Sdim bool IsTypeNameArg) { 1012212904Sdim return new (C) UsingDecl(DC, NNR, UL, TargetNNS, NameInfo, IsTypeNameArg); 1013194613Sed} 1014194613Sed 1015199482SrdivackyUnresolvedUsingValueDecl * 1016199482SrdivackyUnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC, 1017199482Srdivacky SourceLocation UsingLoc, 1018199482Srdivacky SourceRange TargetNNR, 1019199482Srdivacky NestedNameSpecifier *TargetNNS, 1020212904Sdim const DeclarationNameInfo &NameInfo) { 1021199482Srdivacky return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc, 1022212904Sdim TargetNNR, TargetNNS, NameInfo); 1023198092Srdivacky} 1024198092Srdivacky 1025199482SrdivackyUnresolvedUsingTypenameDecl * 1026199482SrdivackyUnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC, 1027199482Srdivacky SourceLocation UsingLoc, 1028199482Srdivacky SourceLocation TypenameLoc, 1029199482Srdivacky SourceRange TargetNNR, 1030199482Srdivacky NestedNameSpecifier *TargetNNS, 1031199482Srdivacky SourceLocation TargetNameLoc, 1032199482Srdivacky DeclarationName TargetName) { 1033199482Srdivacky return new (C) UnresolvedUsingTypenameDecl(DC, UsingLoc, TypenameLoc, 1034199482Srdivacky TargetNNR, TargetNNS, 1035199482Srdivacky TargetNameLoc, 1036199482Srdivacky TargetName.getAsIdentifierInfo()); 1037199482Srdivacky} 1038199482Srdivacky 1039193326SedStaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC, 1040193326Sed SourceLocation L, Expr *AssertExpr, 1041193326Sed StringLiteral *Message) { 1042193326Sed return new (C) StaticAssertDecl(DC, L, AssertExpr, Message); 1043193326Sed} 1044193326Sed 1045193326Sedstatic const char *getAccessName(AccessSpecifier AS) { 1046193326Sed switch (AS) { 1047193326Sed default: 1048193326Sed case AS_none: 1049193326Sed assert("Invalid access specifier!"); 1050193326Sed return 0; 1051193326Sed case AS_public: 1052193326Sed return "public"; 1053193326Sed case AS_private: 1054193326Sed return "private"; 1055193326Sed case AS_protected: 1056193326Sed return "protected"; 1057193326Sed } 1058193326Sed} 1059193326Sed 1060193326Sedconst DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, 1061193326Sed AccessSpecifier AS) { 1062193326Sed return DB << getAccessName(AS); 1063193326Sed} 1064