aboutsummaryrefslogtreecommitdiff
path: root/lib/AST
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-10-07 20:43:36 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-10-07 20:43:36 +0000
commit0351a1e2e17c1edf27f90c23fbf65d8fcad995c4 (patch)
treec8ac743f00e74c097b13baf564c0692d73c25f3b /lib/AST
parent0a4074768a6ecd81513f0db02bfb0e96ab3e56a0 (diff)
Fixes problem in finding visible convertion functions of a class
where matching conversion types in base classes were still visible. Plus refactoring and cleanup. Added a test case. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83485 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/DeclCXX.cpp92
1 files changed, 63 insertions, 29 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index d1aef6a5b3..7408f2fc60 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -285,39 +285,45 @@ void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
PlainOldData = false;
}
+void
+CXXRecordDecl::collectConversionFunctions(
+ llvm::SmallPtrSet<QualType, 8>& ConversionsTypeSet) {
+ OverloadedFunctionDecl *TopConversions = getConversionFunctions();
+ for (OverloadedFunctionDecl::function_iterator
+ TFunc = TopConversions->function_begin(),
+ TFuncEnd = TopConversions->function_end();
+ TFunc != TFuncEnd; ++TFunc) {
+ NamedDecl *TopConv = TFunc->get();
+ QualType TConvType;
+ if (FunctionTemplateDecl *TConversionTemplate =
+ dyn_cast<FunctionTemplateDecl>(TopConv))
+ TConvType =
+ getASTContext().getCanonicalType(
+ TConversionTemplate->getTemplatedDecl()->getResultType());
+ else
+ TConvType =
+ getASTContext().getCanonicalType(
+ cast<CXXConversionDecl>(TopConv)->getConversionType());
+ ConversionsTypeSet.insert(TConvType);
+ }
+}
+
/// 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) {
+CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
+ const llvm::SmallPtrSet<QualType, 8> &TopConversionsTypeSet,
+ const llvm::SmallPtrSet<QualType, 8> &HiddenConversionTypes) {
+ bool inTopClass = (RD == this);
QualType ClassType = getASTContext().getTypeDeclType(this);
if (const RecordType *Record = ClassType->getAs<RecordType>()) {
OverloadedFunctionDecl *Conversions
= cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
- llvm::SmallPtrSet<QualType, 8> TopConversionsTypeSet;
- bool inTopClass = (RD == this);
- if (!inTopClass &&
- (Conversions->function_begin() != Conversions->function_end())) {
- // populate the TypeSet with the type of current class's conversions.
- OverloadedFunctionDecl *TopConversions = RD->getConversionFunctions();
- for (OverloadedFunctionDecl::function_iterator
- TFunc = TopConversions->function_begin(),
- TFuncEnd = TopConversions->function_end();
- TFunc != TFuncEnd; ++TFunc) {
- NamedDecl *TopConv = TFunc->get();
- QualType TConvType;
- if (FunctionTemplateDecl *TConversionTemplate =
- dyn_cast<FunctionTemplateDecl>(TopConv))
- TConvType =
- getASTContext().getCanonicalType(
- TConversionTemplate->getTemplatedDecl()->getResultType());
- else
- TConvType =
- getASTContext().getCanonicalType(
- cast<CXXConversionDecl>(TopConv)->getConversionType());
- TopConversionsTypeSet.insert(TConvType);
- }
- }
for (OverloadedFunctionDecl::function_iterator
Func = Conversions->function_begin(),
@@ -336,7 +342,12 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD) {
ConvType =
getASTContext().getCanonicalType(
cast<CXXConversionDecl>(Conv)->getConversionType());
- if (inTopClass || !TopConversionsTypeSet.count(ConvType)) {
+ // 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);
@@ -350,7 +361,17 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD) {
E = vbases_end(); VBase != E; ++VBase) {
CXXRecordDecl *VBaseClassDecl
= cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
- VBaseClassDecl->getNestedVisibleConversionFunctions(RD);
+ if (inTopClass)
+ VBaseClassDecl->getNestedVisibleConversionFunctions(RD,
+ TopConversionsTypeSet,
+ TopConversionsTypeSet);
+ else {
+ llvm::SmallPtrSet<QualType, 8> HiddenConversionTypes;
+ collectConversionFunctions(HiddenConversionTypes);
+ VBaseClassDecl->getNestedVisibleConversionFunctions(RD,
+ TopConversionsTypeSet,
+ HiddenConversionTypes);
+ }
}
for (CXXRecordDecl::base_class_iterator Base = bases_begin(),
E = bases_end(); Base != E; ++Base) {
@@ -358,7 +379,17 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD) {
continue;
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
- BaseClassDecl->getNestedVisibleConversionFunctions(RD);
+ if (inTopClass)
+ BaseClassDecl->getNestedVisibleConversionFunctions(RD,
+ TopConversionsTypeSet,
+ TopConversionsTypeSet);
+ else {
+ llvm::SmallPtrSet<QualType, 8> HiddenConversionTypes;
+ collectConversionFunctions(HiddenConversionTypes);
+ BaseClassDecl->getNestedVisibleConversionFunctions(RD,
+ TopConversionsTypeSet,
+ HiddenConversionTypes);
+ }
}
}
@@ -372,7 +403,10 @@ CXXRecordDecl::getVisibleConversionFunctions() {
// If visible conversion list is already evaluated, return it.
if (ComputedVisibleConversions)
return &VisibleConversions;
- getNestedVisibleConversionFunctions(this);
+ llvm::SmallPtrSet<QualType, 8> TopConversionsTypeSet;
+ collectConversionFunctions(TopConversionsTypeSet);
+ getNestedVisibleConversionFunctions(this, TopConversionsTypeSet,
+ TopConversionsTypeSet);
ComputedVisibleConversions = true;
return &VisibleConversions;
}