diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-09-11 21:44:33 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-09-11 21:44:33 +0000 |
commit | b54ccb2782bff6e6be75a5c27e4bb33586ce5ce0 (patch) | |
tree | afab1ab4e814a8eb246a314e00d966b3bad773fe /clang/lib/AST/DeclCXX.cpp | |
parent | 7241795049aa8386212bc2462e89fcf876371079 (diff) | |
download | bcm5719-llvm-b54ccb2782bff6e6be75a5c27e4bb33586ce5ce0.tar.gz bcm5719-llvm-b54ccb2782bff6e6be75a5c27e4bb33586ce5ce0.zip |
Patch to build visible conversion function list lazily and make its
first use in calling the conversion function on delete statements.
llvm-svn: 81576
Diffstat (limited to 'clang/lib/AST/DeclCXX.cpp')
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 073ef947bf8..e878a3df280 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -35,6 +35,7 @@ CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, HasTrivialCopyConstructor(true), HasTrivialCopyAssignment(true), HasTrivialDestructor(true), Bases(0), NumBases(0), VBases(0), NumVBases(0), Conversions(DC, DeclarationName()), + VisibleConversions(DC, DeclarationName()), TemplateOrInstantiation() { } CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, @@ -282,6 +283,89 @@ void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context, PlainOldData = false; } +/// getVisibleConversionFunctions - get all conversion functions visible +/// in current class; including conversion function templates. +OverloadedFunctionDecl * +CXXRecordDecl::getVisibleConversionFunctions(ASTContext &Context, + CXXRecordDecl *RD) { + // If visible conversion list is already evaluated, return it. + if (RD == this && + VisibleConversions.function_begin() != VisibleConversions.function_end()) + return &VisibleConversions; + + QualType ClassType = Context.getTypeDeclType(this); + if (const RecordType *Record = ClassType->getAs<RecordType>()) { + OverloadedFunctionDecl *Conversions + = cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions(); + for (OverloadedFunctionDecl::function_iterator + 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); + bool Candidate = true; + // Only those conversions not exact match of conversions in current + // class are candidateconversion routines. + if (RD != this) { + OverloadedFunctionDecl *TopConversions = RD->getConversionFunctions(); + QualType ConvType = Context.getCanonicalType(Conv->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()); + if (ConvType == TConvType) { + Candidate = false; + break; + } + } + } + if (Candidate) { + if (FunctionTemplateDecl *ConversionTemplate + = Conv->getDescribedFunctionTemplate()) + RD->addVisibleConversionFunction(Context, ConversionTemplate); + else if (!Conv->getPrimaryTemplate()) // ignore specializations + RD->addVisibleConversionFunction(Context, Conv); + } + } + } + + for (CXXRecordDecl::base_class_iterator VBase = vbases_begin(), + E = vbases_end(); VBase != E; ++VBase) { + CXXRecordDecl *VBaseClassDecl + = cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl()); + VBaseClassDecl->getVisibleConversionFunctions(Context, RD); + } + for (CXXRecordDecl::base_class_iterator Base = bases_begin(), + E = bases_end(); Base != E; ++Base) { + if (Base->isVirtual()) + continue; + CXXRecordDecl *BaseClassDecl + = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); + BaseClassDecl->getVisibleConversionFunctions(Context, RD); + } + return &VisibleConversions; +} + +void CXXRecordDecl::addVisibleConversionFunction(ASTContext &Context, + CXXConversionDecl *ConvDecl) { + assert(!ConvDecl->getDescribedFunctionTemplate() && + "Conversion function templates should cast to FunctionTemplateDecl."); + VisibleConversions.addOverload(ConvDecl); +} + +void CXXRecordDecl::addVisibleConversionFunction(ASTContext &Context, + FunctionTemplateDecl *ConvDecl) { + assert(isa<CXXConversionDecl>(ConvDecl->getTemplatedDecl()) && + "Function template is not a conversion function template"); + VisibleConversions.addOverload(ConvDecl); +} + void CXXRecordDecl::addConversionFunction(ASTContext &Context, CXXConversionDecl *ConvDecl) { assert(!ConvDecl->getDescribedFunctionTemplate() && |