From b394f50ac90a38aee6e5daf6ff6cd80afed79726 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 12 Sep 2009 18:26:03 +0000 Subject: More work toward having an access method for visible conversion functions. llvm-svn: 81618 --- clang/lib/AST/DeclCXX.cpp | 87 ++++++++++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 35 deletions(-) (limited to 'clang/lib/AST/DeclCXX.cpp') diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 2149005cde5..a9eca9b23a2 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -33,7 +33,8 @@ CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC, 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 @@ 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 (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()) { OverloadedFunctionDecl *Conversions = cast(Record->getDecl())->getConversionFunctions(); @@ -306,24 +297,36 @@ CXXRecordDecl::getVisibleConversionFunctions(ASTContext &Context, Func = Conversions->function_begin(), FuncEnd = Conversions->function_end(); Func != FuncEnd; ++Func) { - if (FunctionTemplateDecl *ConversionTemplate = - dyn_cast(*Func)) { - RD->addVisibleConversionFunction(Context, ConversionTemplate); - continue; - } - CXXConversionDecl *Conv = cast(*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(Conv)) + FD = ConversionTemplate->getTemplatedDecl(); + else + FD = cast(Conv); + ConvType = getASTContext().getCanonicalType(FD->getType()); + for (OverloadedFunctionDecl::function_iterator TFunc = TopConversions->function_begin(), TFuncEnd = TopConversions->function_end(); TFunc != TFuncEnd; ++TFunc) { - CXXConversionDecl *TopConv = cast(*TFunc); - QualType TConvType = Context.getCanonicalType(TopConv->getType()); + + NamedDecl *TopConv = TFunc->get(); + FunctionDecl *TFD; + QualType TConvType; + if (FunctionTemplateDecl *TConversionTemplate = + dyn_cast(TopConv)) + TFD = TConversionTemplate->getTemplatedDecl(); + else + TFD = cast(TopConv); + TConvType = getASTContext().getCanonicalType(TFD->getType()); if (ConvType == TConvType) { Candidate = false; break; @@ -331,11 +334,11 @@ CXXRecordDecl::getVisibleConversionFunctions(ASTContext &Context, } } 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(Conv)) + RD->addVisibleConversionFunction(ConversionTemplate); + else + RD->addVisibleConversionFunction(cast(Conv)); } } } @@ -344,7 +347,7 @@ CXXRecordDecl::getVisibleConversionFunctions(ASTContext &Context, E = vbases_end(); VBase != E; ++VBase) { CXXRecordDecl *VBaseClassDecl = cast(VBase->getType()->getAs()->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 @@ CXXRecordDecl::getVisibleConversionFunctions(ASTContext &Context, continue; CXXRecordDecl *BaseClassDecl = cast(Base->getType()->getAs()->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(ConvDecl->getTemplatedDecl()) && "Function template is not a conversion function template"); -- cgit v1.2.3