/// 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); else RD->addVisibleConversionFunction(cast<CXXConversionDecl>(Conv)); } } } if (getNumBases() == 0 && getNumVBases() == 0) return; llvm::SmallPtrSet<CanQualType, 8> ConversionFunctions; if (!inTopClass) collectConversionFunctions(ConversionFunctions); 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)); } } 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)); } } }