[cfe-commits] r95072 - in /cfe/trunk: include/clang/AST/ExprCXX.h lib/AST/ExprCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplateDeduction.cpp
John McCall
rjmccall at apple.com
Mon Feb 1 22:20:04 PST 2010
Author: rjmccall
Date: Tue Feb 2 00:20:04 2010
New Revision: 95072
URL: http://llvm.org/viewvc/llvm-project?rev=95072&view=rev
Log:
Extract a common base class between UnresolvedLookupExpr and
UnresolvedMemberExpr and employ it in a few places where it's useful.
Modified:
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/lib/AST/ExprCXX.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=95072&r1=95071&r2=95072&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Tue Feb 2 00:20:04 2010
@@ -1129,40 +1129,123 @@
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 @@
/// 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 @@
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 @@
/// 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 @@
}
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 @@
/// 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 @@
/// 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 @@
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 @@
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 @@
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 @@
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
Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=95072&r1=95071&r2=95072&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Tue Feb 2 00:20:04 2010
@@ -137,10 +137,9 @@
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 @@
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 @@
// 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");
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=95072&r1=95071&r2=95072&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Feb 2 00:20:04 2010
@@ -2546,7 +2546,7 @@
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.
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=95072&r1=95071&r2=95072&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Feb 2 00:20:04 2010
@@ -4455,11 +4455,7 @@
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 @@
}
}
-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 @@
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 @@
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 @@
continue;
// If we have explicit template arguments, skip non-templates.
- if (HasExplicitTemplateArgs)
+ if (OvlExpr->hasExplicitTemplateArgs())
continue;
} else if (IsMember)
continue;
@@ -5192,45 +5165,27 @@
// 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
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=95072&r1=95071&r2=95072&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Tue Feb 2 00:20:04 2010
@@ -1324,34 +1324,19 @@
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 @@
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
More information about the cfe-commits
mailing list