diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-04-02 08:55:10 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-04-02 08:55:10 +0000 |
commit | 07b2cfcdb817cc0790420f159a313d61e7241cb9 (patch) | |
tree | d374cdca417e76f1bf101f139dba2db1d10ee8f7 /lib/AST/DeclCXX.cpp | |
parent | 1e255aab650a7fa2047fd953cae65b12215280af (diff) | |
download | FreeBSD-src-07b2cfcdb817cc0790420f159a313d61e7241cb9.zip FreeBSD-src-07b2cfcdb817cc0790420f159a313d61e7241cb9.tar.gz |
Update clang to r100181.
Diffstat (limited to 'lib/AST/DeclCXX.cpp')
-rw-r--r-- | lib/AST/DeclCXX.cpp | 133 |
1 files changed, 71 insertions, 62 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 37f7479..94ed85c 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -83,9 +83,11 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, if (data().Bases) C.Deallocate(data().Bases); - int vbaseCount = 0; - llvm::SmallVector<const CXXBaseSpecifier*, 8> UniqueVbases; - bool hasDirectVirtualBase = false; + // The set of seen virtual base types. + llvm::SmallPtrSet<CanQualType, 8> SeenVBaseTypes; + + // The virtual bases of this class. + llvm::SmallVector<const CXXBaseSpecifier *, 8> VBases; data().Bases = new(C) CXXBaseSpecifier [NumBases]; data().NumBases = NumBases; @@ -99,58 +101,44 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, continue; CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); - if (Base->isVirtual()) - hasDirectVirtualBase = true; + + // Now go through all virtual bases of this base and add them. for (CXXRecordDecl::base_class_iterator VBase = BaseClassDecl->vbases_begin(), E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) { - // Add this vbase to the array of vbases for current class if it is - // not already in the list. - // FIXME. Note that we do a linear search as number of such classes are - // very few. - int i; - for (i = 0; i < vbaseCount; ++i) - if (UniqueVbases[i]->getType() == VBase->getType()) - break; - if (i == vbaseCount) { - UniqueVbases.push_back(VBase); - ++vbaseCount; - } + // Add this base if it's not already in the list. + if (SeenVBaseTypes.insert(C.getCanonicalType(VBase->getType()))) + VBases.push_back(VBase); } - } - if (hasDirectVirtualBase) { - // Iterate one more time through the direct bases and add the virtual - // base to the list of vritual bases for current class. - for (unsigned i = 0; i < NumBases; ++i) { - const CXXBaseSpecifier *VBase = Bases[i]; - if (!VBase->isVirtual()) - continue; - int j; - for (j = 0; j < vbaseCount; ++j) - if (UniqueVbases[j]->getType() == VBase->getType()) - break; - if (j == vbaseCount) { - UniqueVbases.push_back(VBase); - ++vbaseCount; - } + + if (Base->isVirtual()) { + // Add this base if it's not already in the list. + if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType))) + VBases.push_back(Base); } + } - if (vbaseCount > 0) { - // build AST for inhireted, direct or indirect, virtual bases. - data().VBases = new (C) CXXBaseSpecifier [vbaseCount]; - data().NumVBases = vbaseCount; - for (int i = 0; i < vbaseCount; i++) { - QualType QT = UniqueVbases[i]->getType(); - // Skip dependent types; we can't do any checking on them now. - if (QT->isDependentType()) - continue; - CXXRecordDecl *VBaseClassDecl - = cast<CXXRecordDecl>(QT->getAs<RecordType>()->getDecl()); - data().VBases[i] = - CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true, - VBaseClassDecl->getTagKind() == RecordDecl::TK_class, - UniqueVbases[i]->getAccessSpecifier(), QT); - } + + if (VBases.empty()) + return; + + // Create base specifier for any direct or indirect virtual bases. + data().VBases = new (C) CXXBaseSpecifier[VBases.size()]; + data().NumVBases = VBases.size(); + for (int I = 0, E = VBases.size(); I != E; ++I) { + QualType VBaseType = VBases[I]->getType(); + + // Skip dependent types; we can't do any checking on them now. + if (VBaseType->isDependentType()) + continue; + + CXXRecordDecl *VBaseClassDecl + = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl()); + + data().VBases[I] = + CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true, + VBaseClassDecl->getTagKind() == RecordDecl::TK_class, + VBases[I]->getAccessSpecifier(), VBaseType); } } @@ -320,6 +308,8 @@ void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context, static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) { QualType T; + if (isa<UsingShadowDecl>(Conv)) + Conv = cast<UsingShadowDecl>(Conv)->getTargetDecl(); if (FunctionTemplateDecl *ConvTemp = dyn_cast<FunctionTemplateDecl>(Conv)) T = ConvTemp->getTemplatedDecl()->getResultType(); else @@ -457,26 +447,45 @@ const UnresolvedSetImpl *CXXRecordDecl::getVisibleConversionFunctions() { return &data().VisibleConversions; } -void CXXRecordDecl::addConversionFunction(CXXConversionDecl *ConvDecl) { - assert(!ConvDecl->getDescribedFunctionTemplate() && - "Conversion function templates should cast to FunctionTemplateDecl."); +#ifndef NDEBUG +void CXXRecordDecl::CheckConversionFunction(NamedDecl *ConvDecl) { 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); + ConvDecl = ConvDecl->getUnderlyingDecl(); + if (FunctionTemplateDecl *Temp = dyn_cast<FunctionTemplateDecl>(ConvDecl)) { + assert(isa<CXXConversionDecl>(Temp->getTemplatedDecl())); + } else { + assert(isa<CXXConversionDecl>(ConvDecl)); + } } +#endif + +void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) { + // This operation is O(N) but extremely rare. Sema only uses it to + // remove UsingShadowDecls in a class that were followed by a direct + // declaration, e.g.: + // class A : B { + // using B::operator int; + // operator int(); + // }; + // This is uncommon by itself and even more uncommon in conjunction + // with sufficiently large numbers of directly-declared conversions + // that asymptotic behavior matters. + + UnresolvedSetImpl &Convs = *getConversionFunctions(); + for (unsigned I = 0, E = Convs.size(); I != E; ++I) { + if (Convs[I].getDecl() == ConvDecl) { + Convs.erase(I); + assert(std::find(Convs.begin(), Convs.end(), ConvDecl) == Convs.end() + && "conversion was found multiple times in unresolved set"); + return; + } + } -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); + llvm_unreachable("conversion not found in set!"); } - void CXXRecordDecl::setMethodAsVirtual(FunctionDecl *Method) { Method->setVirtualAsWritten(true); setAggregate(false); |