More work toward having an access method for visible
conversion functions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81618 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 2149005..a9eca9b 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -33,7 +33,8 @@
Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
Abstract(false), HasTrivialConstructor(true),
HasTrivialCopyConstructor(true), HasTrivialCopyAssignment(true),
- HasTrivialDestructor(true), Bases(0), NumBases(0), VBases(0), NumVBases(0),
+ HasTrivialDestructor(true), ComputedVisibleConversions(false),
+ Bases(0), NumBases(0), VBases(0), NumVBases(0),
Conversions(DC, DeclarationName()),
VisibleConversions(DC, DeclarationName()),
TemplateOrInstantiation() { }
@@ -283,22 +284,12 @@
PlainOldData = false;
}
-/// getVisibleConversionFunctions - get all conversion functions visible
-/// in current class; including conversion function templates.
-OverloadedFunctionDecl *
-CXXRecordDecl::getVisibleConversionFunctions(ASTContext &Context,
- CXXRecordDecl *RD) {
- if (RD == this) {
- // If root class, all conversions are visible.
- if (RD->bases_begin() == RD->bases_end())
- return &Conversions;
- // If visible conversion list is already evaluated, return it.
- if (VisibleConversions.function_begin()
- != VisibleConversions.function_end())
- return &VisibleConversions;
- }
-
- QualType ClassType = Context.getTypeDeclType(this);
+/// getNestedVisibleConversionFunctions - imports unique conversion
+/// functions from base classes into the visible conversion function
+/// list of the class 'RD'. This is a private helper method.
+void
+CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD) {
+ QualType ClassType = getASTContext().getTypeDeclType(this);
if (const RecordType *Record = ClassType->getAs<RecordType>()) {
OverloadedFunctionDecl *Conversions
= cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
@@ -306,24 +297,36 @@
Func = Conversions->function_begin(),
FuncEnd = Conversions->function_end();
Func != FuncEnd; ++Func) {
- if (FunctionTemplateDecl *ConversionTemplate =
- dyn_cast<FunctionTemplateDecl>(*Func)) {
- RD->addVisibleConversionFunction(Context, ConversionTemplate);
- continue;
- }
- CXXConversionDecl *Conv = cast<CXXConversionDecl>(*Func);
+ NamedDecl *Conv = Func->get();
bool Candidate = true;
// Only those conversions not exact match of conversions in current
// class are candidateconversion routines.
+ // FIXME. This is a O(n^2) algorithm.
if (RD != this) {
OverloadedFunctionDecl *TopConversions = RD->getConversionFunctions();
- QualType ConvType = Context.getCanonicalType(Conv->getType());
+ QualType ConvType;
+ FunctionDecl *FD;
+ if (FunctionTemplateDecl *ConversionTemplate =
+ dyn_cast<FunctionTemplateDecl>(Conv))
+ FD = ConversionTemplate->getTemplatedDecl();
+ else
+ FD = cast<FunctionDecl>(Conv);
+ ConvType = getASTContext().getCanonicalType(FD->getType());
+
for (OverloadedFunctionDecl::function_iterator
TFunc = TopConversions->function_begin(),
TFuncEnd = TopConversions->function_end();
TFunc != TFuncEnd; ++TFunc) {
- CXXConversionDecl *TopConv = cast<CXXConversionDecl>(*TFunc);
- QualType TConvType = Context.getCanonicalType(TopConv->getType());
+
+ NamedDecl *TopConv = TFunc->get();
+ FunctionDecl *TFD;
+ QualType TConvType;
+ if (FunctionTemplateDecl *TConversionTemplate =
+ dyn_cast<FunctionTemplateDecl>(TopConv))
+ TFD = TConversionTemplate->getTemplatedDecl();
+ else
+ TFD = cast<FunctionDecl>(TopConv);
+ TConvType = getASTContext().getCanonicalType(TFD->getType());
if (ConvType == TConvType) {
Candidate = false;
break;
@@ -331,11 +334,11 @@
}
}
if (Candidate) {
- if (FunctionTemplateDecl *ConversionTemplate
- = Conv->getDescribedFunctionTemplate())
- RD->addVisibleConversionFunction(Context, ConversionTemplate);
- else if (!Conv->getPrimaryTemplate()) // ignore specializations
- RD->addVisibleConversionFunction(Context, Conv);
+ if (FunctionTemplateDecl *ConversionTemplate =
+ dyn_cast<FunctionTemplateDecl>(Conv))
+ RD->addVisibleConversionFunction(ConversionTemplate);
+ else
+ RD->addVisibleConversionFunction(cast<CXXConversionDecl>(Conv));
}
}
}
@@ -344,7 +347,7 @@
E = vbases_end(); VBase != E; ++VBase) {
CXXRecordDecl *VBaseClassDecl
= cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
- VBaseClassDecl->getVisibleConversionFunctions(Context, RD);
+ VBaseClassDecl->getNestedVisibleConversionFunctions(RD);
}
for (CXXRecordDecl::base_class_iterator Base = bases_begin(),
E = bases_end(); Base != E; ++Base) {
@@ -352,19 +355,33 @@
continue;
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
- BaseClassDecl->getVisibleConversionFunctions(Context, RD);
+ BaseClassDecl->getNestedVisibleConversionFunctions(RD);
}
+}
+
+/// getVisibleConversionFunctions - get all conversion functions visible
+/// in current class; including conversion function templates.
+OverloadedFunctionDecl *
+CXXRecordDecl::getVisibleConversionFunctions() {
+ // If root class, all conversions are visible.
+ if (bases_begin() == bases_end())
+ return &Conversions;
+ // If visible conversion list is already evaluated, return it.
+ if (ComputedVisibleConversions)
+ return &VisibleConversions;
+ getNestedVisibleConversionFunctions(this);
+ ComputedVisibleConversions = true;
return &VisibleConversions;
}
-void CXXRecordDecl::addVisibleConversionFunction(ASTContext &Context,
+void CXXRecordDecl::addVisibleConversionFunction(
CXXConversionDecl *ConvDecl) {
assert(!ConvDecl->getDescribedFunctionTemplate() &&
"Conversion function templates should cast to FunctionTemplateDecl.");
VisibleConversions.addOverload(ConvDecl);
}
-void CXXRecordDecl::addVisibleConversionFunction(ASTContext &Context,
+void CXXRecordDecl::addVisibleConversionFunction(
FunctionTemplateDecl *ConvDecl) {
assert(isa<CXXConversionDecl>(ConvDecl->getTemplatedDecl()) &&
"Function template is not a conversion function template");