More improvement in building list of visible conversion
functions for a class when needed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81624 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index abb5505..591f856 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/Expr.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -293,47 +294,48 @@
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()->getType());
+ else
+ TConvType =
+ getASTContext().getCanonicalType(
+ cast<FunctionDecl>(TopConv)->getType());
+ TopConversionsTypeSet.insert(TConvType);
+ }
+ }
+
for (OverloadedFunctionDecl::function_iterator
Func = Conversions->function_begin(),
FuncEnd = Conversions->function_end();
Func != FuncEnd; ++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;
- 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) {
-
- 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;
- }
- }
- }
- if (Candidate) {
+ QualType ConvType;
+ if (FunctionTemplateDecl *ConversionTemplate =
+ dyn_cast<FunctionTemplateDecl>(Conv))
+ ConvType =
+ getASTContext().getCanonicalType(
+ ConversionTemplate->getTemplatedDecl()->getType());
+ else
+ ConvType =
+ getASTContext().getCanonicalType(cast<FunctionDecl>(Conv)->getType());
+ if (inTopClass || !TopConversionsTypeSet.count(ConvType)) {
if (FunctionTemplateDecl *ConversionTemplate =
dyn_cast<FunctionTemplateDecl>(Conv))
RD->addVisibleConversionFunction(ConversionTemplate);