Regularize support for naming conversion functions in using decls.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99979 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index dfaa855..3c3786d 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -3327,6 +3327,11 @@
CurContext->addDecl(Shadow);
Shadow->setAccess(UD->getAccess());
+ // Register it as a conversion if appropriate.
+ if (Shadow->getDeclName().getNameKind()
+ == DeclarationName::CXXConversionFunctionName)
+ cast<CXXRecordDecl>(CurContext)->addConversionFunction(Shadow);
+
if (Orig->isInvalidDecl() || UD->isInvalidDecl())
Shadow->setInvalidDecl();
@@ -3361,6 +3366,10 @@
/// decl structures are (very reasonably) not designed for removal.
/// (2) avoids this but is very fiddly and phase-dependent.
void Sema::HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow) {
+ if (Shadow->getDeclName().getNameKind() ==
+ DeclarationName::CXXConversionFunctionName)
+ cast<CXXRecordDecl>(Shadow->getDeclContext())->removeConversion(Shadow);
+
// Remove it from the DeclContext...
Shadow->getDeclContext()->removeDecl(Shadow);
@@ -3374,7 +3383,7 @@
Shadow->getUsingDecl()->removeShadowDecl(Shadow);
// TODO: complain somehow if Shadow was used. It shouldn't
- // be possible for this to happen, because
+ // be possible for this to happen, because...?
}
/// Builds a using declaration.
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 9baa6ac..3befb7e 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1302,17 +1302,21 @@
QualType Type = Ex->getType();
if (const RecordType *Record = Type->getAs<RecordType>()) {
- llvm::SmallVector<CXXConversionDecl *, 4> ObjectPtrConversions;
+ llvm::SmallVector<CXXConversionDecl*, 4> ObjectPtrConversions;
+
CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
- const UnresolvedSetImpl *Conversions = RD->getVisibleConversionFunctions();
-
+ const UnresolvedSetImpl *Conversions = RD->getVisibleConversionFunctions();
for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
+ NamedDecl *D = I.getDecl();
+ if (isa<UsingShadowDecl>(D))
+ D = cast<UsingShadowDecl>(D)->getTargetDecl();
+
// Skip over templated conversion functions; they aren't considered.
- if (isa<FunctionTemplateDecl>(*I))
+ if (isa<FunctionTemplateDecl>(D))
continue;
- CXXConversionDecl *Conv = cast<CXXConversionDecl>(*I);
+ CXXConversionDecl *Conv = cast<CXXConversionDecl>(D);
QualType ConvType = Conv->getConversionType().getNonReferenceType();
if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
@@ -1322,9 +1326,10 @@
if (ObjectPtrConversions.size() == 1) {
// We have a single conversion to a pointer-to-object type. Perform
// that conversion.
+ // TODO: don't redo the conversion calculation.
Operand.release();
- if (!PerformImplicitConversion(Ex,
- ObjectPtrConversions.front()->getConversionType(),
+ if (!PerformImplicitConversion(Ex,
+ ObjectPtrConversions.front()->getConversionType(),
AA_Converting)) {
Operand = Owned(Ex);
Type = Ex->getType();
@@ -1333,10 +1338,8 @@
else if (ObjectPtrConversions.size() > 1) {
Diag(StartLoc, diag::err_ambiguous_delete_operand)
<< Type << Ex->getSourceRange();
- for (unsigned i= 0; i < ObjectPtrConversions.size(); i++) {
- CXXConversionDecl *Conv = ObjectPtrConversions[i];
- NoteOverloadCandidate(Conv);
- }
+ for (unsigned i= 0; i < ObjectPtrConversions.size(); i++)
+ NoteOverloadCandidate(ObjectPtrConversions[i]);
return ExprError();
}
}
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 4612bda..00e2fba 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -2838,7 +2838,7 @@
if (ConvTemplate)
Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
else
- Conv = cast<CXXConversionDecl>(*I);
+ Conv = cast<CXXConversionDecl>(D);
if (AllowExplicit || !Conv->isExplicit()) {
if (ConvTemplate)
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 8d33139..be367c3 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1582,10 +1582,10 @@
CXXConversionDecl *Conv;
FunctionTemplateDecl *ConvTemplate;
- if ((ConvTemplate = dyn_cast<FunctionTemplateDecl>(*I)))
- Conv = dyn_cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
+ if ((ConvTemplate = dyn_cast<FunctionTemplateDecl>(D)))
+ Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
else
- Conv = dyn_cast<CXXConversionDecl>(*I);
+ Conv = cast<CXXConversionDecl>(D);
if (AllowExplicit || !Conv->isExplicit()) {
if (ConvTemplate)
@@ -3310,13 +3310,16 @@
= ClassDecl->getVisibleConversionFunctions();
for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
+ NamedDecl *D = I.getDecl();
+ if (isa<UsingShadowDecl>(D))
+ D = cast<UsingShadowDecl>(D)->getTargetDecl();
// Skip conversion function templates; they don't tell us anything
// about which builtin types we can convert to.
- if (isa<FunctionTemplateDecl>(*I))
+ if (isa<FunctionTemplateDecl>(D))
continue;
- CXXConversionDecl *Conv = cast<CXXConversionDecl>(*I);
+ CXXConversionDecl *Conv = cast<CXXConversionDecl>(D);
if (AllowExplicitConversions || !Conv->isExplicit()) {
AddTypesConvertedFrom(Conv->getConversionType(), Loc, false, false,
VisibleQuals);
@@ -3378,7 +3381,10 @@
for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
- if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(*I)) {
+ NamedDecl *D = I.getDecl();
+ if (isa<UsingShadowDecl>(D))
+ D = cast<UsingShadowDecl>(D)->getTargetDecl();
+ if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(D)) {
QualType CanTy = Context.getCanonicalType(Conv->getConversionType());
if (const ReferenceType *ResTypeRef = CanTy->getAs<ReferenceType>())
CanTy = ResTypeRef->getPointeeType();