diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-03-16 16:52:15 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-03-16 16:52:15 +0000 |
commit | 1033b7c1e32962948b01a25145829f17bc70a8de (patch) | |
tree | 52aebaff3a47b97dbac434530524c30967468412 /lib/AST/DeclCXX.cpp | |
parent | 27c39af73c0d7d0b97e57b3a905040d4cefc9708 (diff) | |
download | FreeBSD-src-1033b7c1e32962948b01a25145829f17bc70a8de.zip FreeBSD-src-1033b7c1e32962948b01a25145829f17bc70a8de.tar.gz |
Update clang to r98631.
Diffstat (limited to 'lib/AST/DeclCXX.cpp')
-rw-r--r-- | lib/AST/DeclCXX.cpp | 256 |
1 files changed, 123 insertions, 133 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 7f4ad34..37f7479 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -33,7 +33,7 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) HasTrivialCopyConstructor(true), HasTrivialCopyAssignment(true), HasTrivialDestructor(true), ComputedVisibleConversions(false), Bases(0), NumBases(0), VBases(0), NumVBases(0), - Definition(D) { + Definition(D), FirstFriend(0) { } CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, @@ -318,105 +318,128 @@ void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context, data().PlainOldData = false; } -void -CXXRecordDecl::collectConversionFunctions( - llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const -{ - const UnresolvedSetImpl *Cs = getConversionFunctions(); - for (UnresolvedSetImpl::iterator I = Cs->begin(), E = Cs->end(); - I != E; ++I) { - NamedDecl *TopConv = *I; - CanQualType TConvType; - if (FunctionTemplateDecl *TConversionTemplate = - dyn_cast<FunctionTemplateDecl>(TopConv)) - TConvType = - getASTContext().getCanonicalType( - TConversionTemplate->getTemplatedDecl()->getResultType()); - else - TConvType = - getASTContext().getCanonicalType( - cast<CXXConversionDecl>(TopConv)->getConversionType()); - ConversionsTypeSet.insert(TConvType); - } -} - -/// getNestedVisibleConversionFunctions - imports unique conversion -/// functions from base classes into the visible conversion function -/// list of the class 'RD'. This is a private helper method. -/// TopConversionsTypeSet is the set of conversion functions of the class -/// we are interested in. HiddenConversionTypes is set of conversion functions -/// of the immediate derived class which hides the conversion functions found -/// in current class. -void -CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD, - const llvm::SmallPtrSet<CanQualType, 8> &TopConversionsTypeSet, - const llvm::SmallPtrSet<CanQualType, 8> &HiddenConversionTypes) -{ - bool inTopClass = (RD == this); - QualType ClassType = getASTContext().getTypeDeclType(this); - if (const RecordType *Record = ClassType->getAs<RecordType>()) { - const UnresolvedSetImpl *Cs - = cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions(); - - for (UnresolvedSetImpl::iterator I = Cs->begin(), E = Cs->end(); - I != E; ++I) { - NamedDecl *Conv = *I; - // Only those conversions not exact match of conversions in current - // class are candidateconversion routines. - CanQualType ConvType; - if (FunctionTemplateDecl *ConversionTemplate = - dyn_cast<FunctionTemplateDecl>(Conv)) - ConvType = - getASTContext().getCanonicalType( - ConversionTemplate->getTemplatedDecl()->getResultType()); - else - ConvType = - getASTContext().getCanonicalType( - cast<CXXConversionDecl>(Conv)->getConversionType()); - // We only add conversion functions found in the base class if they - // are not hidden by those found in HiddenConversionTypes which are - // the conversion functions in its derived class. - if (inTopClass || - (!TopConversionsTypeSet.count(ConvType) && - !HiddenConversionTypes.count(ConvType)) ) { - if (FunctionTemplateDecl *ConversionTemplate = - dyn_cast<FunctionTemplateDecl>(Conv)) - RD->addVisibleConversionFunction(ConversionTemplate); +static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) { + QualType T; + if (FunctionTemplateDecl *ConvTemp = dyn_cast<FunctionTemplateDecl>(Conv)) + T = ConvTemp->getTemplatedDecl()->getResultType(); + else + T = cast<CXXConversionDecl>(Conv)->getConversionType(); + return Context.getCanonicalType(T); +} + +/// Collect the visible conversions of a base class. +/// +/// \param Base a base class of the class we're considering +/// \param InVirtual whether this base class is a virtual base (or a base +/// of a virtual base) +/// \param Access the access along the inheritance path to this base +/// \param ParentHiddenTypes the conversions provided by the inheritors +/// of this base +/// \param Output the set to which to add conversions from non-virtual bases +/// \param VOutput the set to which to add conversions from virtual bases +/// \param HiddenVBaseCs the set of conversions which were hidden in a +/// virtual base along some inheritance path +static void CollectVisibleConversions(ASTContext &Context, + CXXRecordDecl *Record, + bool InVirtual, + AccessSpecifier Access, + const llvm::SmallPtrSet<CanQualType, 8> &ParentHiddenTypes, + UnresolvedSetImpl &Output, + UnresolvedSetImpl &VOutput, + llvm::SmallPtrSet<NamedDecl*, 8> &HiddenVBaseCs) { + // The set of types which have conversions in this class or its + // subclasses. As an optimization, we don't copy the derived set + // unless it might change. + const llvm::SmallPtrSet<CanQualType, 8> *HiddenTypes = &ParentHiddenTypes; + llvm::SmallPtrSet<CanQualType, 8> HiddenTypesBuffer; + + // Collect the direct conversions and figure out which conversions + // will be hidden in the subclasses. + UnresolvedSetImpl &Cs = *Record->getConversionFunctions(); + if (!Cs.empty()) { + HiddenTypesBuffer = ParentHiddenTypes; + HiddenTypes = &HiddenTypesBuffer; + + for (UnresolvedSetIterator I = Cs.begin(), E = Cs.end(); I != E; ++I) { + bool Hidden = + !HiddenTypesBuffer.insert(GetConversionType(Context, I.getDecl())); + + // If this conversion is hidden and we're in a virtual base, + // remember that it's hidden along some inheritance path. + if (Hidden && InVirtual) + HiddenVBaseCs.insert(cast<NamedDecl>(I.getDecl()->getCanonicalDecl())); + + // If this conversion isn't hidden, add it to the appropriate output. + else if (!Hidden) { + AccessSpecifier IAccess + = CXXRecordDecl::MergeAccess(Access, I.getAccess()); + + if (InVirtual) + VOutput.addDecl(I.getDecl(), IAccess); else - RD->addVisibleConversionFunction(cast<CXXConversionDecl>(Conv)); + Output.addDecl(I.getDecl(), IAccess); } } } - if (getNumBases() == 0 && getNumVBases() == 0) - return; + // Collect information recursively from any base classes. + for (CXXRecordDecl::base_class_iterator + I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) { + const RecordType *RT = I->getType()->getAs<RecordType>(); + if (!RT) continue; - llvm::SmallPtrSet<CanQualType, 8> ConversionFunctions; - if (!inTopClass) - collectConversionFunctions(ConversionFunctions); + AccessSpecifier BaseAccess + = CXXRecordDecl::MergeAccess(Access, I->getAccessSpecifier()); + bool BaseInVirtual = InVirtual || I->isVirtual(); - for (CXXRecordDecl::base_class_iterator VBase = vbases_begin(), - E = vbases_end(); VBase != E; ++VBase) { - if (const RecordType *RT = VBase->getType()->getAs<RecordType>()) { - CXXRecordDecl *VBaseClassDecl - = cast<CXXRecordDecl>(RT->getDecl()); - VBaseClassDecl->getNestedVisibleConversionFunctions(RD, - TopConversionsTypeSet, - (inTopClass ? TopConversionsTypeSet : ConversionFunctions)); - } + CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl()); + CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess, + *HiddenTypes, Output, VOutput, HiddenVBaseCs); } - for (CXXRecordDecl::base_class_iterator Base = bases_begin(), - E = bases_end(); Base != E; ++Base) { - if (Base->isVirtual()) - continue; - if (const RecordType *RT = Base->getType()->getAs<RecordType>()) { - CXXRecordDecl *BaseClassDecl - = cast<CXXRecordDecl>(RT->getDecl()); +} - BaseClassDecl->getNestedVisibleConversionFunctions(RD, - TopConversionsTypeSet, - (inTopClass ? TopConversionsTypeSet : ConversionFunctions)); - } +/// Collect the visible conversions of a class. +/// +/// This would be extremely straightforward if it weren't for virtual +/// bases. It might be worth special-casing that, really. +static void CollectVisibleConversions(ASTContext &Context, + CXXRecordDecl *Record, + UnresolvedSetImpl &Output) { + // The collection of all conversions in virtual bases that we've + // found. These will be added to the output as long as they don't + // appear in the hidden-conversions set. + UnresolvedSet<8> VBaseCs; + + // The set of conversions in virtual bases that we've determined to + // be hidden. + llvm::SmallPtrSet<NamedDecl*, 8> HiddenVBaseCs; + + // The set of types hidden by classes derived from this one. + llvm::SmallPtrSet<CanQualType, 8> HiddenTypes; + + // Go ahead and collect the direct conversions and add them to the + // hidden-types set. + UnresolvedSetImpl &Cs = *Record->getConversionFunctions(); + Output.append(Cs.begin(), Cs.end()); + for (UnresolvedSetIterator I = Cs.begin(), E = Cs.end(); I != E; ++I) + HiddenTypes.insert(GetConversionType(Context, I.getDecl())); + + // Recursively collect conversions from base classes. + for (CXXRecordDecl::base_class_iterator + I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) { + const RecordType *RT = I->getType()->getAs<RecordType>(); + if (!RT) continue; + + CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()), + I->isVirtual(), I->getAccessSpecifier(), + HiddenTypes, Output, VBaseCs, HiddenVBaseCs); + } + + // Add any unhidden conversions provided by virtual bases. + for (UnresolvedSetIterator I = VBaseCs.begin(), E = VBaseCs.end(); + I != E; ++I) { + if (!HiddenVBaseCs.count(cast<NamedDecl>(I.getDecl()->getCanonicalDecl()))) + Output.addDecl(I.getDecl(), I.getAccess()); } } @@ -429,37 +452,27 @@ const UnresolvedSetImpl *CXXRecordDecl::getVisibleConversionFunctions() { // If visible conversion list is already evaluated, return it. if (data().ComputedVisibleConversions) return &data().VisibleConversions; - llvm::SmallPtrSet<CanQualType, 8> TopConversionsTypeSet; - collectConversionFunctions(TopConversionsTypeSet); - getNestedVisibleConversionFunctions(this, TopConversionsTypeSet, - TopConversionsTypeSet); + CollectVisibleConversions(getASTContext(), this, data().VisibleConversions); data().ComputedVisibleConversions = true; return &data().VisibleConversions; } -void CXXRecordDecl::addVisibleConversionFunction( - CXXConversionDecl *ConvDecl) { - assert(!ConvDecl->getDescribedFunctionTemplate() && - "Conversion function templates should cast to FunctionTemplateDecl."); - data().VisibleConversions.addDecl(ConvDecl); -} - -void CXXRecordDecl::addVisibleConversionFunction( - FunctionTemplateDecl *ConvDecl) { - assert(isa<CXXConversionDecl>(ConvDecl->getTemplatedDecl()) && - "Function template is not a conversion function template"); - data().VisibleConversions.addDecl(ConvDecl); -} - void CXXRecordDecl::addConversionFunction(CXXConversionDecl *ConvDecl) { assert(!ConvDecl->getDescribedFunctionTemplate() && "Conversion function templates should cast to FunctionTemplateDecl."); + assert(ConvDecl->getDeclContext() == this && + "conversion function does not belong to this record"); + + // We intentionally don't use the decl's access here because it + // hasn't been set yet. That's really just a misdesign in Sema. data().Conversions.addDecl(ConvDecl); } void CXXRecordDecl::addConversionFunction(FunctionTemplateDecl *ConvDecl) { assert(isa<CXXConversionDecl>(ConvDecl->getTemplatedDecl()) && "Function template is not a conversion function template"); + assert(ConvDecl->getDeclContext() == this && + "conversion function does not belong to this record"); data().Conversions.addDecl(ConvDecl); } @@ -846,28 +859,6 @@ CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD, return new (C) CXXConversionDecl(RD, L, N, T, TInfo, isInline, isExplicit); } -FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - FriendUnion Friend, - SourceLocation FriendL) { -#ifndef NDEBUG - if (Friend.is<NamedDecl*>()) { - NamedDecl *D = Friend.get<NamedDecl*>(); - assert(isa<FunctionDecl>(D) || - isa<CXXRecordDecl>(D) || - isa<FunctionTemplateDecl>(D) || - isa<ClassTemplateDecl>(D)); - - // As a temporary hack, we permit template instantiation to point - // to the original declaration when instantiating members. - assert(D->getFriendObjectKind() || - (cast<CXXRecordDecl>(DC)->getTemplateSpecializationKind())); - } -#endif - - return new (C) FriendDecl(DC, L, Friend, FriendL); -} - LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, @@ -952,8 +943,7 @@ StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC, void StaticAssertDecl::Destroy(ASTContext& C) { AssertExpr->Destroy(C); Message->Destroy(C); - this->~StaticAssertDecl(); - C.Deallocate((void *)this); + Decl::Destroy(C); } StaticAssertDecl::~StaticAssertDecl() { |