diff options
author | John McCall <rjmccall@apple.com> | 2010-02-02 06:20:04 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-02-02 06:20:04 +0000 |
commit | 1acbbb5a4c6e646afc5753327dccee5cc9f90ebc (patch) | |
tree | 4eb9e508602dcf273ddff3853df7da8afa32ce11 /clang | |
parent | c4c7db6b714169e505939ac0db73c02de5742a53 (diff) | |
download | bcm5719-llvm-1acbbb5a4c6e646afc5753327dccee5cc9f90ebc.tar.gz bcm5719-llvm-1acbbb5a4c6e646afc5753327dccee5cc9f90ebc.zip |
Extract a common base class between UnresolvedLookupExpr and
UnresolvedMemberExpr and employ it in a few places where it's useful.
llvm-svn: 95072
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/AST/ExprCXX.h | 306 | ||||
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 25 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 93 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 31 |
5 files changed, 204 insertions, 253 deletions
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index a2b9f400120..3ff9f4a6014 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -1129,40 +1129,123 @@ public: virtual child_iterator child_end(); }; -/// \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: -/// * we might be waiting for argument-dependent lookup -/// * the name might resolve to an overloaded function -/// and eventually: -/// * the lookup might have included a function template -/// These never include UnresolvedUsingValueDecls, which are always -/// class members and therefore appear only in -/// UnresolvedMemberLookupExprs. -class UnresolvedLookupExpr : public Expr { +/// \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. + /// include UsingShadowDecls. Access is relative to the naming + /// class. UnresolvedSet<4> Results; - /// The name declared. + /// The common name of these declarations. 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. + /// The scope specifier, if any. NestedNameSpecifier *Qualifier; - - /// The source range of the nested name specifier. + + /// 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<OverloadExpr*,1> find(Expr *E) { + assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload)); + + bool op = false; + E = E->IgnoreParens(); + if (isa<UnaryOperator>(E)) + op = true, E = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens(); + return llvm::PointerIntPair<OverloadExpr*,1>(cast<OverloadExpr>(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<int>. + bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } + + ExplicitTemplateArgumentList &getExplicitTemplateArgs(); // defined far below + + const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { + return const_cast<OverloadExpr*>(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: +/// * we might be waiting for argument-dependent lookup +/// * the name might resolve to an overloaded function +/// and eventually: +/// * the lookup might have included a function template +/// These never include UnresolvedUsingValueDecls, which are always +/// class members and therefore appear only in +/// UnresolvedMemberLookupExprs. +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<ExplicitTemplateArgumentList*>(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,19 +1859,7 @@ 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; - - /// \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' - /// member expression - Stmt *Base; - - /// \brief The type of the base expression; never null. - QualType BaseType; - +class UnresolvedMemberExpr : public OverloadExpr { /// \brief Whether this member expression used the '->' operator or /// the '.' operator. bool IsArrow : 1; @@ -1823,39 +1868,17 @@ class UnresolvedMemberExpr : public Expr { /// declaration. bool HasUnresolvedUsing : 1; - /// \brief Whether this member expression has explicitly-specified template - /// arguments. - bool HasExplicitTemplateArgs : 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' + /// member expression + Stmt *Base; + + /// \brief The type of the base expression; never null. + QualType BaseType; /// \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<ExplicitTemplateArgumentList *>(this + 1); - } - - /// \brief Retrieve the explicit template argument list that followed the - /// member template name, if any. - const ExplicitTemplateArgumentList *getExplicitTemplateArgs() const { - return const_cast<UnresolvedMemberExpr*>(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<int>. - 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<ExplicitTemplateArgumentList *>(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<const ExplicitTemplateArgumentList *>(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<UnresolvedLookupExpr>(this)) + return cast<UnresolvedLookupExpr>(this)->getExplicitTemplateArgs(); + else + return cast<UnresolvedMemberExpr>(this)->getExplicitTemplateArgs(); +} + } // end namespace clang #endif diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 70d08910239..7c68290551d 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/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<RecordType>(); assert(RT && "qualifier in member expression does not name record"); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 75be50fc0fd..20d62decf03 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 83cbce72261..033cbfd459f 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -4455,11 +4455,7 @@ void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) { Expr *E = FromExpr->IgnoreParens(); if (isa<UnaryOperator>(E)) E = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens(); - DeclarationName Name; - if (isa<UnresolvedLookupExpr>(E)) - Name = cast<UnresolvedLookupExpr>(E)->getName(); - else - Name = cast<UnresolvedMemberExpr>(E)->getMemberName(); + DeclarationName Name = cast<OverloadExpr>(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<UnresolvedLookupExpr>(E)) return S.CheckUnresolvedLookupAccess(cast<UnresolvedLookupExpr>(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<UnaryOperator>(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<UnresolvedLookupExpr>(OvlExpr)) { - Fns = &UL->getDecls(); - if (UL->hasExplicitTemplateArgs()) { - HasExplicitTemplateArgs = true; - UL->copyTemplateArgumentsInto(ExplicitTemplateArgs); - } - } else if (UnresolvedMemberExpr *ME - = dyn_cast<UnresolvedMemberExpr>(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<UnaryOperator>(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<UnresolvedLookupExpr>(OvlExpr)) { - Fns = &UL->getDecls(); - if (UL->hasExplicitTemplateArgs()) { - HasExplicitTemplateArgs = true; - UL->copyTemplateArgumentsInto(ExplicitTemplateArgs); - } - } else if (UnresolvedMemberExpr *ME - = dyn_cast<UnresolvedMemberExpr>(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/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index de13b664fe6..984aa6bb61b 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/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<OverloadExpr*,1> R = OverloadExpr::find(Arg); - Arg = Arg->IgnoreParens(); - if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) { - assert(UnOp->getOpcode() == UnaryOperator::AddrOf); - isAddressOfOperand = true; - Arg = UnOp->getSubExpr()->IgnoreParens(); - } - - const UnresolvedSetImpl *Decls; - bool HasExplicitArgs; - if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg)) { - Decls = &ULE->getDecls(); - HasExplicitArgs = ULE->hasExplicitTemplateArgs(); - } else { - UnresolvedMemberExpr *UME = cast<UnresolvedMemberExpr>(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 |