From 7bb12da2b0749eeebb21854c77877736969e59f2 Mon Sep 17 00:00:00 2001 From: John McCall Date: Tue, 2 Feb 2010 06:20:04 +0000 Subject: [PATCH] Extract a common base class between UnresolvedLookupExpr and UnresolvedMemberExpr and employ it in a few places where it's useful. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95072 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ExprCXX.h | 308 +++++++++++++++-------------- lib/AST/ExprCXX.cpp | 25 ++- lib/Sema/SemaExpr.cpp | 2 +- lib/Sema/SemaOverload.cpp | 93 +++------ lib/Sema/SemaTemplateDeduction.cpp | 31 +-- 5 files changed, 205 insertions(+), 254 deletions(-) diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index a2b9f40012..3ff9f4a601 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1129,6 +1129,112 @@ public: virtual child_iterator child_end(); }; +/// \brief A reference to an overloaded function set, either an +/// \t UnresolvedLookupExpr or an \t UnresolvedMemberExpr. +class OverloadExpr : public Expr { + /// The results. These are undesugared, which is to say, they may + /// include UsingShadowDecls. Access is relative to the naming + /// class. + UnresolvedSet<4> Results; + + /// The common name of these declarations. + DeclarationName Name; + + /// The scope specifier, if any. + NestedNameSpecifier *Qualifier; + + /// The source range of the scope specifier. + SourceRange QualifierRange; + + /// The location of the name. + SourceLocation NameLoc; + + /// True if the name was a template-id. + bool HasExplicitTemplateArgs; + +protected: + OverloadExpr(StmtClass K, QualType T, bool Dependent, + NestedNameSpecifier *Qualifier, SourceRange QRange, + DeclarationName Name, SourceLocation NameLoc, + bool HasTemplateArgs) + : Expr(K, T, Dependent, Dependent), + Name(Name), Qualifier(Qualifier), QualifierRange(QRange), + NameLoc(NameLoc), HasExplicitTemplateArgs(HasTemplateArgs) + {} + +public: + /// Computes whether an unresolved lookup on the given declarations + /// and optional template arguments is type- and value-dependent. + static bool ComputeDependence(UnresolvedSetIterator Begin, + UnresolvedSetIterator End, + const TemplateArgumentListInfo *Args); + + /// Finds the overloaded expression in the given expression of + /// OverloadTy. + /// + /// \return the expression (which must be there) and true if it is + /// within an address-of operator. + static llvm::PointerIntPair find(Expr *E) { + assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload)); + + bool op = false; + E = E->IgnoreParens(); + if (isa(E)) + op = true, E = cast(E)->getSubExpr()->IgnoreParens(); + return llvm::PointerIntPair(cast(E), op); + } + + void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) { + Results.append(Begin, End); + } + + typedef UnresolvedSetImpl::iterator decls_iterator; + decls_iterator decls_begin() const { return Results.begin(); } + decls_iterator decls_end() const { return Results.end(); } + + /// Gets the decls as an unresolved set. + const UnresolvedSetImpl &getDecls() { return Results; } + + /// Gets the number of declarations in the unresolved set. + unsigned getNumDecls() const { return Results.size(); } + + /// Gets the name looked up. + DeclarationName getName() const { return Name; } + void setName(DeclarationName N) { Name = N; } + + /// Gets the location of the name. + SourceLocation getNameLoc() const { return NameLoc; } + void setNameLoc(SourceLocation Loc) { NameLoc = Loc; } + + /// Fetches the nested-name qualifier, if one was given. + NestedNameSpecifier *getQualifier() const { return Qualifier; } + + /// Fetches the range of the nested-name qualifier. + SourceRange getQualifierRange() const { return QualifierRange; } + + /// \brief Determines whether this expression had an explicit + /// template argument list, e.g. f. + bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } + + ExplicitTemplateArgumentList &getExplicitTemplateArgs(); // defined far below + + const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + return const_cast(this)->getExplicitTemplateArgs(); + } + + ExplicitTemplateArgumentList *getOptionalExplicitTemplateArgs() { + if (hasExplicitTemplateArgs()) + return &getExplicitTemplateArgs(); + return 0; + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == UnresolvedLookupExprClass || + T->getStmtClass() == UnresolvedMemberExprClass; + } + static bool classof(const OverloadExpr *) { return true; } +}; + /// \brief A reference to a name which we were able to look up during /// parsing but could not resolve to a specific declaration. This /// arises in several ways: @@ -1139,30 +1245,7 @@ public: /// These never include UnresolvedUsingValueDecls, which are always /// class members and therefore appear only in /// UnresolvedMemberLookupExprs. -class UnresolvedLookupExpr : public Expr { - /// The results. These are undesugared, which is to say, they may - /// include UsingShadowDecls. - UnresolvedSet<4> Results; - - /// The name declared. - DeclarationName Name; - - /// The naming class (C++ [class.access.base]p5) of the lookup, if - /// any. This can generally be recalculated from the context chain, - /// but that can be fairly expensive for unqualified lookups. If we - /// want to improve memory use here, this could go in a union - /// against the qualified-lookup bits. - CXXRecordDecl *NamingClass; - - /// The qualifier given, if any. - NestedNameSpecifier *Qualifier; - - /// The source range of the nested name specifier. - SourceRange QualifierRange; - - /// The location of the name. - SourceLocation NameLoc; - +class UnresolvedLookupExpr : public OverloadExpr { /// True if these lookup results should be extended by /// argument-dependent lookup if this is the operand of a function /// call. @@ -1172,19 +1255,20 @@ class UnresolvedLookupExpr : public Expr { /// trivially rederivable if we urgently need to kill this field. bool Overloaded; - /// True if the name looked up had explicit template arguments. - /// This requires all the results to be function templates. - bool HasExplicitTemplateArgs; + /// The naming class (C++ [class.access.base]p5) of the lookup, if + /// any. This can generally be recalculated from the context chain, + /// but that can be fairly expensive for unqualified lookups. If we + /// want to improve memory use here, this could go in a union + /// against the qualified-lookup bits. + CXXRecordDecl *NamingClass; UnresolvedLookupExpr(QualType T, bool Dependent, CXXRecordDecl *NamingClass, NestedNameSpecifier *Qualifier, SourceRange QRange, DeclarationName Name, SourceLocation NameLoc, bool RequiresADL, bool Overloaded, bool HasTemplateArgs) - : Expr(UnresolvedLookupExprClass, T, Dependent, Dependent), - Name(Name), NamingClass(NamingClass), - Qualifier(Qualifier), QualifierRange(QRange), - NameLoc(NameLoc), RequiresADL(RequiresADL), Overloaded(Overloaded), - HasExplicitTemplateArgs(HasTemplateArgs) + : OverloadExpr(UnresolvedLookupExprClass, T, Dependent, Qualifier, QRange, + Name, NameLoc, HasTemplateArgs), + RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass) {} public: @@ -1212,23 +1296,6 @@ public: bool ADL, const TemplateArgumentListInfo &Args); - /// Computes whether an unresolved lookup on the given declarations - /// and optional template arguments is type- and value-dependent. - static bool ComputeDependence(UnresolvedSetImpl::const_iterator Begin, - UnresolvedSetImpl::const_iterator End, - const TemplateArgumentListInfo *Args); - - void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) { - Results.append(Begin, End); - } - - typedef UnresolvedSetImpl::iterator decls_iterator; - decls_iterator decls_begin() const { return Results.begin(); } - decls_iterator decls_end() const { return Results.end(); } - - /// Retrieves the decls as an unresolved set. - const UnresolvedSetImpl &getDecls() { return Results; } - /// True if this declaration should be extended by /// argument-dependent lookup. bool requiresADL() const { return RequiresADL; } @@ -1236,30 +1303,20 @@ public: /// True if this lookup is overloaded. bool isOverloaded() const { return Overloaded; } - /// Fetches the name looked up. - DeclarationName getName() const { return Name; } - - /// Gets the location of the name. - SourceLocation getNameLoc() const { return NameLoc; } - /// Gets the 'naming class' (in the sense of C++0x /// [class.access.base]p5) of the lookup. This is the scope /// that was looked in to find these results. CXXRecordDecl *getNamingClass() const { return NamingClass; } - /// Fetches the nested-name qualifier, if one was given. - NestedNameSpecifier *getQualifier() const { return Qualifier; } - - /// Fetches the range of the nested-name qualifier. - SourceRange getQualifierRange() const { return QualifierRange; } - - /// Determines whether this lookup had explicit template arguments. - bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } - // Note that, inconsistently with the explicit-template-argument AST // nodes, users are *forbidden* from calling these methods on objects // without explicit template arguments. + ExplicitTemplateArgumentList &getExplicitTemplateArgs() { + assert(hasExplicitTemplateArgs()); + return *reinterpret_cast(this + 1); + } + /// Gets a reference to the explicit template argument list. const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { assert(hasExplicitTemplateArgs()); @@ -1289,8 +1346,8 @@ public: } virtual SourceRange getSourceRange() const { - SourceRange Range(NameLoc); - if (Qualifier) Range.setBegin(QualifierRange.getBegin()); + SourceRange Range(getNameLoc()); + if (getQualifier()) Range.setBegin(getQualifierRange().getBegin()); if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc()); return Range; } @@ -1802,10 +1859,14 @@ public: /// In the final AST, an explicit access always becomes a MemberExpr. /// An implicit access may become either a MemberExpr or a /// DeclRefExpr, depending on whether the member is static. -class UnresolvedMemberExpr : public Expr { - /// The results. These are undesugared, which is to say, they may - /// include UsingShadowDecls. - UnresolvedSet<4> Results; +class UnresolvedMemberExpr : public OverloadExpr { + /// \brief Whether this member expression used the '->' operator or + /// the '.' operator. + bool IsArrow : 1; + + /// \brief Whether the lookup results contain an unresolved using + /// declaration. + bool HasUnresolvedUsing : 1; /// \brief The expression for the base pointer or class reference, /// e.g., the \c x in x.f. This can be null if this is an 'unbased' @@ -1815,47 +1876,9 @@ class UnresolvedMemberExpr : public Expr { /// \brief The type of the base expression; never null. QualType BaseType; - /// \brief Whether this member expression used the '->' operator or - /// the '.' operator. - bool IsArrow : 1; - - /// \brief Whether the lookup results contain an unresolved using - /// declaration. - bool HasUnresolvedUsing : 1; - - /// \brief Whether this member expression has explicitly-specified template - /// arguments. - bool HasExplicitTemplateArgs : 1; - /// \brief The location of the '->' or '.' operator. SourceLocation OperatorLoc; - /// \brief The nested-name-specifier that precedes the member name, if any. - NestedNameSpecifier *Qualifier; - - /// \brief The source range covering the nested name specifier. - SourceRange QualifierRange; - - /// \brief The member to which this member expression refers, which - /// can be a name or an overloaded operator. - DeclarationName MemberName; - - /// \brief The location of the member name. - SourceLocation MemberLoc; - - /// \brief Retrieve the explicit template argument list that followed the - /// member template name. - ExplicitTemplateArgumentList *getExplicitTemplateArgs() { - assert(HasExplicitTemplateArgs); - return reinterpret_cast(this + 1); - } - - /// \brief Retrieve the explicit template argument list that followed the - /// member template name, if any. - const ExplicitTemplateArgumentList *getExplicitTemplateArgs() const { - return const_cast(this)->getExplicitTemplateArgs(); - } - UnresolvedMemberExpr(QualType T, bool Dependent, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, @@ -1877,22 +1900,6 @@ public: SourceLocation MemberLoc, const TemplateArgumentListInfo *TemplateArgs); - /// Adds a declaration to the unresolved set. By assumption, all of - /// these happen at initialization time and properties like - /// 'Dependent' and 'HasUnresolvedUsing' take them into account. - void addDecls(UnresolvedSetIterator Begin, UnresolvedSetIterator End) { - Results.append(Begin, End); - } - - typedef UnresolvedSetImpl::iterator decls_iterator; - decls_iterator decls_begin() const { return Results.begin(); } - decls_iterator decls_end() const { return Results.end(); } - - unsigned getNumDecls() const { return Results.size(); } - - /// Retrieves the decls as an unresolved set. - const UnresolvedSetImpl &getDecls() { return Results; } - /// \brief True if this is an implicit access, i.e. one in which the /// member being accessed was not written in the source. The source /// location of the operator is invalid in this case. @@ -1917,60 +1924,60 @@ public: SourceLocation getOperatorLoc() const { return OperatorLoc; } void setOperatorLoc(SourceLocation L) { OperatorLoc = L; } - /// \brief Retrieve the nested-name-specifier that qualifies the member - /// name. - NestedNameSpecifier *getQualifier() const { return Qualifier; } - - /// \brief Retrieve the source range covering the nested-name-specifier - /// that qualifies the member name. - SourceRange getQualifierRange() const { return QualifierRange; } - /// \brief Retrieves the naming class of this lookup. CXXRecordDecl *getNamingClass() const; /// \brief Retrieve the name of the member that this expression /// refers to. - DeclarationName getMemberName() const { return MemberName; } - void setMemberName(DeclarationName N) { MemberName = N; } + DeclarationName getMemberName() const { return getName(); } + void setMemberName(DeclarationName N) { setName(N); } // \brief Retrieve the location of the name of the member that this // expression refers to. - SourceLocation getMemberLoc() const { return MemberLoc; } - void setMemberLoc(SourceLocation L) { MemberLoc = L; } + SourceLocation getMemberLoc() const { return getNameLoc(); } + void setMemberLoc(SourceLocation L) { setNameLoc(L); } - /// \brief Determines whether this member expression actually had a C++ - /// template argument list explicitly specified, e.g., x.f. - bool hasExplicitTemplateArgs() const { - return HasExplicitTemplateArgs; + /// \brief Retrieve the explicit template argument list that followed the + /// member template name. + ExplicitTemplateArgumentList &getExplicitTemplateArgs() { + assert(hasExplicitTemplateArgs()); + return *reinterpret_cast(this + 1); + } + + /// \brief Retrieve the explicit template argument list that followed the + /// member template name, if any. + const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + assert(hasExplicitTemplateArgs()); + return *reinterpret_cast(this + 1); } /// \brief Copies the template arguments into the given structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { - getExplicitTemplateArgs()->copyInto(List); + getExplicitTemplateArgs().copyInto(List); } /// \brief Retrieve the location of the left angle bracket following /// the member name ('<'). SourceLocation getLAngleLoc() const { - return getExplicitTemplateArgs()->LAngleLoc; + return getExplicitTemplateArgs().LAngleLoc; } /// \brief Retrieve the template arguments provided as part of this /// template-id. const TemplateArgumentLoc *getTemplateArgs() const { - return getExplicitTemplateArgs()->getTemplateArgs(); + return getExplicitTemplateArgs().getTemplateArgs(); } /// \brief Retrieve the number of template arguments provided as /// part of this template-id. unsigned getNumTemplateArgs() const { - return getExplicitTemplateArgs()->NumTemplateArgs; + return getExplicitTemplateArgs().NumTemplateArgs; } /// \brief Retrieve the location of the right angle bracket /// following the template arguments ('>'). SourceLocation getRAngleLoc() const { - return getExplicitTemplateArgs()->RAngleLoc; + return getExplicitTemplateArgs().RAngleLoc; } virtual SourceRange getSourceRange() const { @@ -1980,12 +1987,12 @@ public: else if (getQualifier()) Range.setBegin(getQualifierRange().getBegin()); else - Range.setBegin(MemberLoc); + Range.setBegin(getMemberLoc()); if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc()); else - Range.setEnd(MemberLoc); + Range.setEnd(getMemberLoc()); return Range; } @@ -1999,6 +2006,13 @@ public: virtual child_iterator child_end(); }; +inline ExplicitTemplateArgumentList &OverloadExpr::getExplicitTemplateArgs() { + if (isa(this)) + return cast(this)->getExplicitTemplateArgs(); + else + return cast(this)->getExplicitTemplateArgs(); +} + } // end namespace clang #endif diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 70d0891023..7c68290551 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -137,10 +137,9 @@ UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent, return ULE; } -bool UnresolvedLookupExpr:: - ComputeDependence(UnresolvedSetImpl::const_iterator Begin, - UnresolvedSetImpl::const_iterator End, - const TemplateArgumentListInfo *Args) { +bool OverloadExpr::ComputeDependence(UnresolvedSetIterator Begin, + UnresolvedSetIterator End, + const TemplateArgumentListInfo *Args) { for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) if ((*I)->getDeclContext()->isDependentContext()) return true; @@ -646,15 +645,13 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(QualType T, bool Dependent, DeclarationName MemberName, SourceLocation MemberLoc, const TemplateArgumentListInfo *TemplateArgs) - : Expr(UnresolvedMemberExprClass, T, Dependent, Dependent), - Base(Base), BaseType(BaseType), IsArrow(IsArrow), - HasUnresolvedUsing(HasUnresolvedUsing), - HasExplicitTemplateArgs(TemplateArgs != 0), - OperatorLoc(OperatorLoc), - Qualifier(Qualifier), QualifierRange(QualifierRange), - MemberName(MemberName), MemberLoc(MemberLoc) { + : OverloadExpr(UnresolvedMemberExprClass, T, Dependent, + Qualifier, QualifierRange, MemberName, MemberLoc, + TemplateArgs != 0), + IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing), + Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) { if (TemplateArgs) - getExplicitTemplateArgs()->initializeFrom(*TemplateArgs); + getExplicitTemplateArgs().initializeFrom(*TemplateArgs); } UnresolvedMemberExpr * @@ -686,8 +683,8 @@ CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const { // It can't be dependent: after all, we were actually able to do the // lookup. const RecordType *RT; - if (Qualifier) { - Type *T = Qualifier->getAsType(); + if (getQualifier()) { + Type *T = getQualifier()->getAsType(); assert(T && "qualifier in member expression does not name type"); RT = T->getAs(); assert(RT && "qualifier in member expression does not name record"); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 75be50fc0f..20d62decf0 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2546,7 +2546,7 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType, bool Dependent = BaseExprType->isDependentType() || R.isUnresolvableResult() || - UnresolvedLookupExpr::ComputeDependence(R.begin(), R.end(), TemplateArgs); + OverloadExpr::ComputeDependence(R.begin(), R.end(), TemplateArgs); // Suppress any lookup-related diagnostics; we'll do these when we // pick a member. diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 83cbce7226..033cbfd459 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -4455,11 +4455,7 @@ void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) { Expr *E = FromExpr->IgnoreParens(); if (isa(E)) E = cast(E)->getSubExpr()->IgnoreParens(); - DeclarationName Name; - if (isa(E)) - Name = cast(E)->getName(); - else - Name = cast(E)->getMemberName(); + DeclarationName Name = cast(E)->getName(); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_overload) << (unsigned) FnKind << FnDesc @@ -4950,7 +4946,7 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet, } } -static bool CheckUnresolvedAccess(Sema &S, Expr *E, NamedDecl *D, +static bool CheckUnresolvedAccess(Sema &S, OverloadExpr *E, NamedDecl *D, AccessSpecifier AS) { if (isa(E)) return S.CheckUnresolvedLookupAccess(cast(E), D, AS); @@ -4994,50 +4990,28 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, return 0; // Find the actual overloaded function declaration. + if (From->getType() != Context.OverloadTy) + return 0; // C++ [over.over]p1: // [...] [Note: any redundant set of parentheses surrounding the // overloaded function name is ignored (5.1). ] - Expr *OvlExpr = From->IgnoreParens(); - // C++ [over.over]p1: // [...] The overloaded function name can be preceded by the & // operator. - if (UnaryOperator *UnOp = dyn_cast(OvlExpr)) { - if (UnOp->getOpcode() == UnaryOperator::AddrOf) - OvlExpr = UnOp->getSubExpr()->IgnoreParens(); + OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer(); + TemplateArgumentListInfo ETABuffer, *ExplicitTemplateArgs = 0; + if (OvlExpr->hasExplicitTemplateArgs()) { + OvlExpr->getExplicitTemplateArgs().copyInto(ETABuffer); + ExplicitTemplateArgs = &ETABuffer; } - bool HasExplicitTemplateArgs = false; - TemplateArgumentListInfo ExplicitTemplateArgs; - const UnresolvedSetImpl *Fns; - - // Look into the overloaded expression. - if (UnresolvedLookupExpr *UL - = dyn_cast(OvlExpr)) { - Fns = &UL->getDecls(); - if (UL->hasExplicitTemplateArgs()) { - HasExplicitTemplateArgs = true; - UL->copyTemplateArgumentsInto(ExplicitTemplateArgs); - } - } else if (UnresolvedMemberExpr *ME - = dyn_cast(OvlExpr)) { - Fns = &ME->getDecls(); - if (ME->hasExplicitTemplateArgs()) { - HasExplicitTemplateArgs = true; - ME->copyTemplateArgumentsInto(ExplicitTemplateArgs); - } - } else return 0; - - // If we didn't actually find anything, we're done. - if (Fns->empty()) - return 0; - // Look through all of the overloaded functions, searching for one // whose type matches exactly. UnresolvedSet<4> Matches; // contains only FunctionDecls bool FoundNonTemplateFunction = false; - for (UnresolvedSetIterator I = Fns->begin(), E = Fns->end(); I != E; ++I) { + for (UnresolvedSetIterator I = OvlExpr->decls_begin(), + E = OvlExpr->decls_end(); I != E; ++I) { // Look through any using declarations to find the underlying function. NamedDecl *Fn = (*I)->getUnderlyingDecl(); @@ -5069,8 +5043,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, FunctionDecl *Specialization = 0; TemplateDeductionInfo Info(Context); if (TemplateDeductionResult Result - = DeduceTemplateArguments(FunctionTemplate, - (HasExplicitTemplateArgs ? &ExplicitTemplateArgs : 0), + = DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs, FunctionType, Specialization, Info)) { // FIXME: make a note of the failed deduction for diagnostics. (void)Result; @@ -5093,7 +5066,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, continue; // If we have explicit template arguments, skip non-templates. - if (HasExplicitTemplateArgs) + if (OvlExpr->hasExplicitTemplateArgs()) continue; } else if (IsMember) continue; @@ -5192,45 +5165,27 @@ FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(Expr *From) { // C++ [over.over]p1: // [...] [Note: any redundant set of parentheses surrounding the // overloaded function name is ignored (5.1). ] - Expr *OvlExpr = From->IgnoreParens(); - // C++ [over.over]p1: // [...] The overloaded function name can be preceded by the & // operator. - if (UnaryOperator *UnOp = dyn_cast(OvlExpr)) { - if (UnOp->getOpcode() == UnaryOperator::AddrOf) - OvlExpr = UnOp->getSubExpr()->IgnoreParens(); - } - - bool HasExplicitTemplateArgs = false; - TemplateArgumentListInfo ExplicitTemplateArgs; - const UnresolvedSetImpl *Fns; - - // Look into the overloaded expression. - if (UnresolvedLookupExpr *UL - = dyn_cast(OvlExpr)) { - Fns = &UL->getDecls(); - if (UL->hasExplicitTemplateArgs()) { - HasExplicitTemplateArgs = true; - UL->copyTemplateArgumentsInto(ExplicitTemplateArgs); - } - } else if (UnresolvedMemberExpr *ME - = dyn_cast(OvlExpr)) { - Fns = &ME->getDecls(); - if (ME->hasExplicitTemplateArgs()) { - HasExplicitTemplateArgs = true; - ME->copyTemplateArgumentsInto(ExplicitTemplateArgs); - } - } else return 0; + + if (From->getType() != Context.OverloadTy) + return 0; + + OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer(); // If we didn't actually find any template-ids, we're done. - if (Fns->empty() || !HasExplicitTemplateArgs) + if (!OvlExpr->hasExplicitTemplateArgs()) return 0; + + TemplateArgumentListInfo ExplicitTemplateArgs; + OvlExpr->getExplicitTemplateArgs().copyInto(ExplicitTemplateArgs); // Look through all of the overloaded functions, searching for one // whose type matches exactly. FunctionDecl *Matched = 0; - for (UnresolvedSetIterator I = Fns->begin(), E = Fns->end(); I != E; ++I) { + for (UnresolvedSetIterator I = OvlExpr->decls_begin(), + E = OvlExpr->decls_end(); I != E; ++I) { // C++0x [temp.arg.explicit]p3: // [...] In contexts where deduction is done and fails, or in contexts // where deduction is not done, if a template argument list is diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index de13b664fe..984aa6bb61 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -1324,34 +1324,19 @@ static QualType GetTypeOfFunction(ASTContext &Context, static QualType ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, Expr *Arg, QualType ParamType) { - bool isAddressOfOperand = false; + llvm::PointerIntPair R = OverloadExpr::find(Arg); - Arg = Arg->IgnoreParens(); - if (UnaryOperator *UnOp = dyn_cast(Arg)) { - assert(UnOp->getOpcode() == UnaryOperator::AddrOf); - isAddressOfOperand = true; - Arg = UnOp->getSubExpr()->IgnoreParens(); - } - - const UnresolvedSetImpl *Decls; - bool HasExplicitArgs; - if (UnresolvedLookupExpr *ULE = dyn_cast(Arg)) { - Decls = &ULE->getDecls(); - HasExplicitArgs = ULE->hasExplicitTemplateArgs(); - } else { - UnresolvedMemberExpr *UME = cast(Arg); - Decls = &UME->getDecls(); - HasExplicitArgs = ULE->hasExplicitTemplateArgs(); - } + bool isAddressOfOperand = bool(R.getInt()); + OverloadExpr *Ovl = R.getPointer(); // If there were explicit template arguments, we can only find // something via C++ [temp.arg.explicit]p3, i.e. if the arguments // unambiguously name a full specialization. - if (HasExplicitArgs) { + if (Ovl->hasExplicitTemplateArgs()) { // But we can still look for an explicit specialization. if (FunctionDecl *ExplicitSpec - = S.ResolveSingleFunctionTemplateSpecialization(Arg)) - return GetTypeOfFunction(S.Context, isAddressOfOperand, ExplicitSpec); + = S.ResolveSingleFunctionTemplateSpecialization(Ovl)) + return GetTypeOfFunction(S.Context, isAddressOfOperand, ExplicitSpec); return QualType(); } @@ -1365,8 +1350,8 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams, return QualType(); QualType Match; - for (UnresolvedSetIterator I = Decls->begin(), - E = Decls->end(); I != E; ++I) { + for (UnresolvedSetIterator I = Ovl->decls_begin(), + E = Ovl->decls_end(); I != E; ++I) { NamedDecl *D = (*I)->getUnderlyingDecl(); // - If the argument is an overload set containing one or more