From c571f790fc7b36531e3b7a7baa58d8d41fb1c3e3 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 10 Sep 2009 22:26:16 +0000 Subject: Patch to collect conversion methods in base(s) and derived class into a candidate set. llvm-svn: 81467 --- clang/lib/Sema/SemaOverload.cpp | 74 +++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 25 deletions(-) (limited to 'clang/lib/Sema/SemaOverload.cpp') diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index c5bbd34af8a..7e179793d70 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1331,6 +1331,51 @@ static void GetFunctionAndTemplate(AnyFunctionDecl Orig, T *&Function, Function = cast(Orig); } +void +Sema::AddAllConversionCandidate(CXXRecordDecl *ClassDecl, Expr *From, + QualType ToType, bool AllowExplicit, + OverloadCandidateSet &CandidateSet) { + for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(), + E = ClassDecl->vbases_end(); VBase != E; ++VBase) { + CXXRecordDecl *BaseClassDecl + = cast(VBase->getType()->getAs()->getDecl()); + AddAllConversionCandidate(BaseClassDecl, From, ToType, AllowExplicit, + CandidateSet); + } + for (CXXRecordDecl::base_class_iterator Base = + ClassDecl->bases_begin(), + E = ClassDecl->bases_end(); Base != E; ++Base) { + if (Base->isVirtual()) + continue; + CXXRecordDecl *BaseClassDecl + = cast(Base->getType()->getAs()->getDecl()); + AddAllConversionCandidate(BaseClassDecl, From, ToType, AllowExplicit, + CandidateSet); + } + + OverloadedFunctionDecl *Conversions + = ClassDecl->getConversionFunctions(); + + for (OverloadedFunctionDecl::function_iterator Func + = Conversions->function_begin(); + Func != Conversions->function_end(); ++Func) { + CXXConversionDecl *Conv; + FunctionTemplateDecl *ConvTemplate; + GetFunctionAndTemplate(*Func, Conv, ConvTemplate); + if (ConvTemplate) + Conv = dyn_cast(ConvTemplate->getTemplatedDecl()); + else + Conv = dyn_cast(*Func); + + if (AllowExplicit || !Conv->isExplicit()) { + if (ConvTemplate) + AddTemplateConversionCandidate(ConvTemplate, From, ToType, + CandidateSet); + else + AddConversionCandidate(Conv, From, ToType, CandidateSet); + } + } +} /// Determines whether there is a user-defined conversion sequence /// (C++ [over.ics.user]) that converts expression From to the type @@ -1406,31 +1451,10 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType, } else if (const RecordType *FromRecordType = From->getType()->getAs()) { if (CXXRecordDecl *FromRecordDecl - = dyn_cast(FromRecordType->getDecl())) { - // Add all of the conversion functions as candidates. - // FIXME: Look for conversions in base classes! - OverloadedFunctionDecl *Conversions - = FromRecordDecl->getConversionFunctions(); - for (OverloadedFunctionDecl::function_iterator Func - = Conversions->function_begin(); - Func != Conversions->function_end(); ++Func) { - CXXConversionDecl *Conv; - FunctionTemplateDecl *ConvTemplate; - GetFunctionAndTemplate(*Func, Conv, ConvTemplate); - if (ConvTemplate) - Conv = dyn_cast(ConvTemplate->getTemplatedDecl()); - else - Conv = dyn_cast(*Func); - - if (AllowExplicit || !Conv->isExplicit()) { - if (ConvTemplate) - AddTemplateConversionCandidate(ConvTemplate, From, ToType, - CandidateSet); - else - AddConversionCandidate(Conv, From, ToType, CandidateSet); - } - } - } + = dyn_cast(FromRecordType->getDecl())) + // Add all of the conversion functions as candidates. + AddAllConversionCandidate(FromRecordDecl, From, ToType, AllowExplicit, + CandidateSet); } OverloadCandidateSet::iterator Best; -- cgit v1.2.3