diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 38 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 2 |
3 files changed, 32 insertions, 16 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 17f2dfda648..bcb47baa24f 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -1176,7 +1176,7 @@ bool CXXConstructorDecl::isConvertingConstructor(bool AllowExplicit) const { (getNumParams() > 1 && getParamDecl(1)->hasDefaultArg()); } -bool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const { +bool CXXConstructorDecl::isSpecializationCopyingObject() const { if ((getNumParams() < 1) || (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) || (getPrimaryTemplate() == 0) || @@ -1188,12 +1188,6 @@ bool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const { ASTContext &Context = getASTContext(); CanQualType ParamType = Context.getCanonicalType(Param->getType()); - // Strip off the lvalue reference, if any. - if (CanQual<LValueReferenceType> ParamRefType - = ParamType->getAs<LValueReferenceType>()) - ParamType = ParamRefType->getPointeeType(); - - // Is it the same as our our class type? CanQualType ClassTy = Context.getCanonicalType(Context.getTagDeclType(getParent())); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index f45893df86d..e601a7d328c 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -3391,17 +3391,39 @@ static ExprResult CopyObject(Sema &S, OverloadCandidateSet CandidateSet(Loc); for (llvm::tie(Con, ConEnd) = S.LookupConstructors(Class); Con != ConEnd; ++Con) { - // Only consider copy constructors. - CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(*Con); - if (!Constructor || Constructor->isInvalidDecl() || - !Constructor->isCopyConstructor() || - !Constructor->isConvertingConstructor(/*AllowExplicit=*/false)) + // Only consider copy constructors and constructor templates. + CXXConstructorDecl *Constructor = 0; + + if ((Constructor = dyn_cast<CXXConstructorDecl>(*Con))) { + // Handle copy constructors, only. + if (!Constructor || Constructor->isInvalidDecl() || + !Constructor->isCopyConstructor() || + !Constructor->isConvertingConstructor(/*AllowExplicit=*/false)) + continue; + + DeclAccessPair FoundDecl + = DeclAccessPair::make(Constructor, Constructor->getAccess()); + S.AddOverloadCandidate(Constructor, FoundDecl, + &CurInitExpr, 1, CandidateSet); + continue; + } + + // Handle constructor templates. + FunctionTemplateDecl *ConstructorTmpl = cast<FunctionTemplateDecl>(*Con); + if (ConstructorTmpl->isInvalidDecl()) + continue; + + Constructor = cast<CXXConstructorDecl>( + ConstructorTmpl->getTemplatedDecl()); + if (!Constructor->isConvertingConstructor(/*AllowExplicit=*/false)) continue; + // FIXME: Do we need to limit this to copy-constructor-like + // candidates? DeclAccessPair FoundDecl - = DeclAccessPair::make(Constructor, Constructor->getAccess()); - S.AddOverloadCandidate(Constructor, FoundDecl, - &CurInitExpr, 1, CandidateSet); + = DeclAccessPair::make(ConstructorTmpl, ConstructorTmpl->getAccess()); + S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, 0, + &CurInitExpr, 1, CandidateSet, true); } OverloadCandidateSet::iterator Best; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 3ed79fd4613..440f5acdbc2 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -3457,7 +3457,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, // of a class object to an object of its class type. QualType ClassType = Context.getTypeDeclType(Constructor->getParent()); if (NumArgs == 1 && - Constructor->isCopyConstructorLikeSpecialization() && + Constructor->isSpecializationCopyingObject() && (Context.hasSameUnqualifiedType(ClassType, Args[0]->getType()) || IsDerivedFrom(Args[0]->getType(), ClassType))) return; |

