diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-09-12 19:52:10 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-09-12 19:52:10 +0000 |
commit | faebcbbc7ca36e57a710f4690ee4f7fdf1d062ee (patch) | |
tree | 386995ccf596490029e1c0ed980b6ac860a86d26 | |
parent | 8a1d229ac0c1d0860afcc5342c654b61ed0eed2d (diff) |
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
-rw-r--r-- | lib/AST/DeclCXX.cpp | 70 |
1 files changed, 36 insertions, 34 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index abb5505731..591f856c2c 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 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD) { 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); |